예제 #1
0
파일: Shader.cs 프로젝트: Mete0/anki-OpenRA
        public Shader(string name)
        {
            var vertexShader   = CompileShaderObject(OpenGL.GL_VERTEX_SHADER, name);
            var fragmentShader = CompileShaderObject(OpenGL.GL_FRAGMENT_SHADER, name);

            // Assemble program
            program = OpenGL.glCreateProgram();
            OpenGL.CheckGLError();

            OpenGL.glBindAttribLocation(program, VertexPosAttributeIndex, "aVertexPosition");
            OpenGL.CheckGLError();
            OpenGL.glBindAttribLocation(program, TexCoordAttributeIndex, "aVertexTexCoord");
            OpenGL.CheckGLError();
            OpenGL.glBindAttribLocation(program, TexMetadataAttributeIndex, "aVertexTexMetadata");
            OpenGL.CheckGLError();

            if (OpenGL.Profile != GLProfile.Legacy)
            {
                OpenGL.glBindFragDataLocation(program, 0, "fragColor");
                OpenGL.CheckGLError();
            }

            OpenGL.glAttachShader(program, vertexShader);
            OpenGL.CheckGLError();
            OpenGL.glAttachShader(program, fragmentShader);
            OpenGL.CheckGLError();

            OpenGL.glLinkProgram(program);
            OpenGL.CheckGLError();
            int success;

            OpenGL.glGetProgramiv(program, OpenGL.GL_LINK_STATUS, out success);
            OpenGL.CheckGLError();
            if (success == OpenGL.GL_FALSE)
            {
                int len;
                OpenGL.glGetProgramiv(program, OpenGL.GL_INFO_LOG_LENGTH, out len);

                var log = new StringBuilder(len);
                int length;
                OpenGL.glGetProgramInfoLog(program, len, out length, log);
                Log.Write("graphics", "GL Info Log:\n{0}", log.ToString());
                throw new InvalidProgramException("Link error in shader program '{0}'".F(name));
            }

            OpenGL.glUseProgram(program);
            OpenGL.CheckGLError();

            int numUniforms;

            OpenGL.glGetProgramiv(program, OpenGL.GL_ACTIVE_UNIFORMS, out numUniforms);

            OpenGL.CheckGLError();

            var nextTexUnit = 0;

            for (var i = 0; i < numUniforms; i++)
            {
                int length, size;
                int type;
                var sb = new StringBuilder(128);
                OpenGL.glGetActiveUniform(program, i, 128, out length, out size, out type, sb);
                var sampler = sb.ToString();
                OpenGL.CheckGLError();

                if (type == OpenGL.GL_SAMPLER_2D)
                {
                    samplers.Add(sampler, nextTexUnit);

                    var loc = OpenGL.glGetUniformLocation(program, sampler);
                    OpenGL.CheckGLError();
                    OpenGL.glUniform1i(loc, nextTexUnit);
                    OpenGL.CheckGLError();

                    if (OpenGL.Profile == GLProfile.Legacy)
                    {
                        var sizeLoc = OpenGL.glGetUniformLocation(program, sampler + "Size");
                        if (sizeLoc >= 0)
                        {
                            legacySizeUniforms.Add(nextTexUnit, sizeLoc);
                        }
                    }

                    nextTexUnit++;
                }
            }
        }