示例#1
0
        public Shader(string[] vs, string[] fs)
        {
            if (!compile(ref verterxId_, ShaderType.VertexShader, vs))
            {
                Console.WriteLine("ERROR: while compiling vertex shader");
            }
            if (!compile(ref fragmentId_, ShaderType.FragmentShader, fs))
            {
                Console.WriteLine("ERROR: while compiling fragment shader");
            }

            programId_ = Gl.CreateProgram();

            Gl.AttachShader(programId_, verterxId_);
            Gl.AttachShader(programId_, fragmentId_);

            Gl.BindAttribLocation(programId_, ATTRIB_VERTICES_POS, "in_vertex");

            Gl.LinkProgram(programId_);

            int errorlk = 0;

            Gl.GetProgram(programId_, ProgramProperty.LinkStatus, out errorlk);
            if (errorlk != Gl.TRUE)
            {
                Console.WriteLine("ERROR: while linking Shader :");
                int errorSize = 0;
                Gl.GetProgram(programId_, ProgramProperty.InfoLogLength, out errorSize);
                StringBuilder error = new StringBuilder(1024);
                Gl.GetShaderInfoLog(programId_, errorSize, out errorSize, error);
                Console.WriteLine(error.ToString());
                error.Clear();
                Gl.DeleteProgram(programId_);
            }
        }
示例#2
0
        /// <summary>
        /// Create a shader program by linking compiled shaders.
        /// </summary>
        /// <param name="vertShader">The vert shader to attach.</param>
        /// <param name="fragShader">The frag shader to attach.</param>
        /// <returns></returns>
        public static ShaderProgram CreateFromShaders(uint vertShader, uint fragShader)
        {
            Debug.Assert(GLThread.IsGLThread());

            uint pointer = Gl.CreateProgram();

            Gl.AttachShader(pointer, vertShader);
            Gl.AttachShader(pointer, fragShader);

            // Set default parameter locations.
            Gl.BindAttribLocation(pointer, VertexLocation, "vertPos");
            Gl.BindAttribLocation(pointer, UvLocation, "uv");
            Gl.BindAttribLocation(pointer, ColorLocation, "color");

            Gl.LinkProgram(pointer);
            if (Engine.Configuration.GlDebugMode)
            {
                Gl.ValidateProgram(pointer);
            }

            // Check linking status.
            var programCompileStatusReader = new StringBuilder(1024);

            Gl.GetProgramInfoLog(pointer, 1024, out int length, programCompileStatusReader);
            if (length > 0)
            {
                var programStatus = programCompileStatusReader.ToString(0, length);
                if (programStatus != "")
                {
                    Engine.Log.Warning($"Log for linking shaders (v:{vertShader} f:{fragShader}) is {programStatus}", MessageSource.GL);
                }
            }

            var valid = false;

            Gl.GetProgram(pointer, ProgramProperty.LinkStatus, out int state);
            if (state == 0)
            {
                Engine.Log.Warning($"Couldn't link shader program {pointer}.", MessageSource.GL);
            }
            else
            {
                valid = true;
            }

            var newProgram = new ShaderProgram
            {
                Pointer = pointer,
                Valid   = valid
            };

            return(newProgram);
        }
        public ShaderProgram(uint vertShader, uint fragShader)
        {
            Pointer = Gl.CreateProgram();
            Gl.AttachShader(Pointer, vertShader);
            Gl.AttachShader(Pointer, fragShader);

            // Set default parameter locations.
            Gl.BindAttribLocation(Pointer, VertexLocation, "vertPos");
            Gl.BindAttribLocation(Pointer, UvLocation, "uv");
            Gl.BindAttribLocation(Pointer, TidLocation, "tid");
            Gl.BindAttribLocation(Pointer, ColorLocation, "color");

            Gl.LinkProgram(Pointer);

            // Check linking status.
            var programCompileStatusReader = new StringBuilder(1024);

            Gl.GetProgramInfoLog(Pointer, 1024, out int length, programCompileStatusReader);
            if (length > 0)
            {
                var programStatus = programCompileStatusReader.ToString(0, length);
                if (programStatus != "")
                {
                    Engine.Log.Warning($"Log for linking shader {Pointer} is {programStatus}", MessageSource.GL);
                }
            }

            Gl.GetProgram(Pointer, ProgramProperty.LinkStatus, out int state);
            if (state == 0)
            {
                Engine.Log.Warning($"Couldn't link shader program {Pointer}.", MessageSource.GL);
            }
            else
            {
                Valid = true;
            }

            if (!Valid)
            {
                return;
            }

            // Set default uniforms - this requires binding, so save the currently bound.
            uint previouslyBound = Bound;

            EnsureBound(Pointer);
            SetUniformIntArray("textures", Enumerable.Range(0, Engine.Renderer.TextureArrayLimit).ToArray());
            SetUniformFloat("iTime", 0);
            EnsureBound(previouslyBound);
        }
示例#4
0
        internal GlShaderProgram(uint vertPointer, uint fragPointer)
        {
            try
            {
                _uniformLocationsMap = new Dictionary <string, uint>();

                // Create and link the program with the vert and fragment shaders.
                Id = Gl.CreateProgram();
                Gl.AttachShader(Id, vertPointer);
                Gl.AttachShader(Id, fragPointer);

                Gl.BindAttribLocation(Id, Engine.GraphicsManager.VertexLocation, "vertPos");
                Gl.BindAttribLocation(Id, Engine.GraphicsManager.UvLocation, "uv");
                Gl.BindAttribLocation(Id, Engine.GraphicsManager.TidLocation, "tid");
                Gl.BindAttribLocation(Id, Engine.GraphicsManager.ColorLocation, "color");

                Engine.GraphicsManager.CheckError("setting locations");

                Gl.LinkProgram(Id);

                Gl.GetProgram(Id, ProgramProperty.LinkStatus, out int state);
                if (state == 0)
                {
                    Engine.Log.Warning($"Couldn't link shader - {vertPointer} / {fragPointer}.", MessageSource.GL);
                    Broken = true;
                }

                // Check linking status.
                StringBuilder compileStatusReader = new StringBuilder(1024);
                Gl.GetProgramInfoLog(Id, 1024, out int length, compileStatusReader);
                string programStatus = compileStatusReader.ToString(0, length);
                if (programStatus != "")
                {
                    Engine.Log.Warning($"Log for linking shader {Id} is {programStatus}", MessageSource.GL);
                }

                Gl.DetachShader(Id, vertPointer);
                Gl.DetachShader(Id, fragPointer);

                Gl.ValidateProgram(Id);

                Engine.GraphicsManager.CheckError("making program and shaders");
            }
            catch (Exception ex)
            {
                ErrorHandler.SubmitError(ex);
            }
        }
示例#5
0
 protected void bindAttribute(uint attribute, string variableName)
 {
     Gl.BindAttribLocation(programID, attribute, variableName);
 }
示例#6
0
    public void Initialize(uint[] indices, string shader)
    {
        VertexArray = Gl.GenVertexArray();
        Gl.BindVertexArray(VertexArray);

        // Allocate a vertex buffer that is big enough to hold 'MaxVerticies' number of vertices.
        // The draw hint 'DynamicDraw' indicades, that the data may be changed every frame.
        VertexBuffer = Gl.GenBuffer();
        Gl.BindBuffer(BufferTarget.ArrayBuffer, VertexBuffer);
        Gl.BufferData(BufferTarget.ArrayBuffer, (uint)(Renderer.MaxVerticies * Marshal.SizeOf <Vertex>()), IntPtr.Zero, BufferUsage.DynamicDraw);
        Gl.EnableVertexAttribArray(0);
        // The vertex position is a 4-component vector that is not normalized.
        Gl.VertexAttribPointer(0, 4, VertexAttribType.Float, false, Marshal.SizeOf <Vertex>(), Marshal.OffsetOf <Vertex>("Position"));
        Gl.EnableVertexAttribArray(1);
        // The vertex color is a 4-component vector that is normalized.
        Gl.VertexAttribPointer(1, 4, VertexAttribType.Float, true, Marshal.SizeOf <Vertex>(), Marshal.OffsetOf <Vertex>("Color"));
        Gl.EnableVertexAttribArray(2);
        // The vertex texture coordinates is a 2-component vector that is not normalized.
        Gl.VertexAttribPointer(2, 2, VertexAttribType.Float, false, Marshal.SizeOf <Vertex>(), Marshal.OffsetOf <Vertex>("TexCoord"));
        Gl.EnableVertexAttribArray(3);
        // The vertex texture index is a 1-component vector that is not normalized.
        Gl.VertexAttribPointer(3, 1, VertexAttribType.Float, false, Marshal.SizeOf <Vertex>(), Marshal.OffsetOf <Vertex>("TexIndex"));

        // Allocate an index buffer that is big enough to hold 'MaxIndices' number of indices.
        // The draw hint 'StaticDraw' indicades, that the data will not be changed.
        IndexBuffer = Gl.GenBuffer();
        Gl.BindBuffer(BufferTarget.ElementArrayBuffer, IndexBuffer);
        Gl.BufferData(BufferTarget.ElementArrayBuffer, (uint)(indices.Length * sizeof(uint)), indices, BufferUsage.StaticDraw);

        // Load the shader source.
        string shaderText = File.ReadAllText(shader);
        // The shader source is split into a vertex shader and a fragment shader via preprocessor statements.
        string vertexShaderText   = "#version " + ShaderVersion + "\n#define VS_BUILD\n" + shaderText;
        string fragmentShaderText = "#version " + ShaderVersion + "\n#define FS_BUILD\n" + shaderText;

        // Create a new shader program and compile the vertex shader and fragment shader.
        ShaderProgram  = Gl.CreateProgram();
        VertexShader   = CompileShader(ShaderType.VertexShader, vertexShaderText);
        FragmentShader = CompileShader(ShaderType.FragmentShader, fragmentShaderText);

        // Attach the shaders to the program and link.
        Gl.AttachShader(ShaderProgram, VertexShader);
        Gl.AttachShader(ShaderProgram, FragmentShader);
        Gl.LinkProgram(ShaderProgram);
        Gl.ValidateProgram(ShaderProgram);

        Gl.UseProgram(ShaderProgram);

        // Find and bind the attribute locations.
        Gl.GetProgram(ShaderProgram, ProgramProperty.ActiveAttributes, out int numActiveAttribs);
        Gl.GetProgram(ShaderProgram, ProgramProperty.ActiveAttributeMaxLength, out int maxAttribNameLength);
        StringBuilder nameData = new StringBuilder(maxAttribNameLength);

        for (uint attrib = 0; attrib < numActiveAttribs; attrib++)
        {
            Gl.GetActiveAttrib(ShaderProgram, attrib, nameData.Capacity, out _, out _, out _, nameData);
            Gl.BindAttribLocation(ShaderProgram, attrib, nameData.ToString());
        }

        // Query the uniform locations.
        Gl.GetProgram(ShaderProgram, ProgramProperty.ActiveUniforms, out int numActiveUniforms);
        Gl.GetProgram(ShaderProgram, ProgramProperty.ActiveUniformMaxLength, out int maxUniformNameLength);
        Uniforms = new Dictionary <string, int>();
        nameData = new StringBuilder(maxUniformNameLength);
        for (uint uniform = 0, samplerCount = 0; uniform < numActiveUniforms; uniform++)
        {
            Gl.GetActiveUniform(ShaderProgram, uniform, nameData.Capacity, out _, out int arraySize, out int type, nameData);
            string uniformName = nameData.ToString();
            if (arraySize > 1)
            {
                uniformName = uniformName.Substring(0, uniformName.IndexOf("["));
            }
            for (int i = 0; i < arraySize; i++)
            {
                string name     = arraySize == 1 ? uniformName : uniformName + "[" + i + "]";
                int    location = Gl.GetUniformLocation(ShaderProgram, name);
                Uniforms[name] = location;
                // Additionally bind the sampler2D uniforms to the OpenGL texture slots in order of appearence.
                if (type == Gl.SAMPLER_2D)
                {
                    Gl.Uniform1(location, (int)(samplerCount++));
                }
            }
        }
    }