public override void Render(Mesh mesh, Camera camera, Matrix4x4[] matrices)
        {
            Bind();
            VertexArray.Bind();

            PositionBuffer.Bind();
            PositionBuffer.SetData(mesh.Attributes["POSITION"].BufferData);

            NormalBuffer.Bind();
            NormalBuffer.SetData(mesh.Attributes["NORMAL"].BufferData);

            MatrixBuffer.Bind();
            MatrixBuffer.SetData(matrices);

            var projectionCast         = camera.GetComponent <CameraComponent>().Projection().Cast();
            var projectionViewLocation = GL.GetUniformLocation(ProgramId, "uViewProjection");

            GL.ProgramUniformMatrix4(ProgramId, projectionViewLocation, false, ref projectionCast);

            var colorLocation = GL.GetUniformLocation(ProgramId, "uColor");
            var colorCast     = Color.CastRendering();

            GL.ProgramUniform3(ProgramId, colorLocation, ref colorCast);

            GL.DrawElementsInstancedBaseInstance(PrimitiveType.Triangles, mesh.Attributes["INDEX"].BufferData.Length / 2, DrawElementsType.UnsignedShort, mesh.Attributes["INDEX"].BufferData, matrices.Length, 0);
        }
        public override void Render(Mesh mesh, Camera camera, Matrix4x4[] matrices)
        {
            Bind();
            VertexArray.Bind();

            PositionBuffer.Bind();
            PositionBuffer.SetData(mesh.Attributes["POSITION"].BufferData);

            NormalBuffer.Bind();
            NormalBuffer.SetData(mesh.Attributes["NORMAL"].BufferData);

            ColorBuffer.Bind();
            ColorBuffer.SetData(mesh.Attributes["COLOR_0"].BufferData);

            MatrixBuffer.Bind();
            MatrixBuffer.SetData(matrices);

            Vector3 lightInvDir = new Vector3(0.5f, 2, 2);

            // Compute the MVP matrix from the light's point of view
            Matrix4x4 depthProjectionMatrix = Matrix4x4.CreateOrthographicOffCenter(-10, 10, -10, 10, -10, 20);
            Matrix4x4 depthViewMatrix       = Matrix4x4.CreateLookAt(lightInvDir, new Vector3(0, 0, 0), Vector3.UnitY);
            Matrix4x4 depthModelMatrix      = Matrix4x4.Identity;;
            Matrix4x4 depthMVP = depthProjectionMatrix * depthViewMatrix * depthModelMatrix;

            var projectionCast         = camera.GetComponent <CameraComponent>().Projection().Cast();
            var projectionViewLocation = GL.GetUniformLocation(ProgramId, "uViewProjection");

            GL.ProgramUniformMatrix4(ProgramId, projectionViewLocation, false, ref projectionCast);

            var depthProjectionCast         = depthMVP.Cast();
            var depthProjectionViewLocation = GL.GetUniformLocation(ProgramId, "uDepthMVP");

            GL.ProgramUniformMatrix4(ProgramId, depthProjectionViewLocation, false, ref depthProjectionCast);

            Matrix4x4 biasMatrix = new Matrix4x4(
                0.5f, 0.0f, 0.0f, 0.0f,
                0.0f, 0.5f, 0.0f, 0.0f,
                0.0f, 0.0f, 0.5f, 0.0f,
                0.5f, 0.5f, 0.5f, 1.0f
                );
            Matrix4x4 depthBiasMVP = biasMatrix * depthMVP;

            var depthBiasCast     = depthBiasMVP.Cast();
            var depthBiasLocation = GL.GetUniformLocation(ProgramId, "uDepthBias");

            GL.ProgramUniformMatrix4(ProgramId, depthBiasLocation, false, ref depthBiasCast);

            var colorLocation = GL.GetUniformLocation(ProgramId, "uColor");
            var colorCast     = Color.CastRendering();

            GL.ProgramUniform3(ProgramId, colorLocation, ref colorCast);

            GL.DrawElementsInstancedBaseInstance(PrimitiveType.Triangles, mesh.Attributes["INDEX"].BufferData.Length / 2, DrawElementsType.UnsignedShort, mesh.Attributes["INDEX"].BufferData, matrices.Length, 0);
        }
        public BasicShadedColoredMaterial()
        {
            var vertexShader = new GlShader(ShaderType.VertexShader);

            vertexShader.LoadSource(VertexShaderSource);

            var fragmentShader = new GlShader(ShaderType.FragmentShader);

            fragmentShader.LoadSource(FragmentShaderSource);

            Bind();
            LoadShader(vertexShader);
            LoadShader(fragmentShader);
            Link();

            PositionBuffer = new GlBuffer(BufferTarget.ArrayBuffer);
            PositionBuffer.Bind();

            NormalBuffer = new GlBuffer(BufferTarget.ArrayBuffer);
            NormalBuffer.Bind();

            ColorBuffer = new GlBuffer(BufferTarget.ArrayBuffer);
            ColorBuffer.Bind();

            MatrixBuffer = new GlBuffer(BufferTarget.ArrayBuffer);
            MatrixBuffer.Bind();

            var positionBufferLayout = new GlBufferLayout();

            positionBufferLayout.Add(VertexAttribPointerType.Float, 3); //Vector3 3 floats

            var normalBufferLayout = new GlBufferLayout();

            normalBufferLayout.Add(VertexAttribPointerType.Float, 3);

            var colorBufferLayout = new GlBufferLayout();

            colorBufferLayout.Add(VertexAttribPointerType.Float, 4);

            var matrixBufferLayout = new GlBufferLayout();

            matrixBufferLayout.Add(VertexAttribPointerType.Float, 4, divisor: 1); //Matrix 16 floats
            matrixBufferLayout.Add(VertexAttribPointerType.Float, 4, divisor: 1);
            matrixBufferLayout.Add(VertexAttribPointerType.Float, 4, divisor: 1);
            matrixBufferLayout.Add(VertexAttribPointerType.Float, 4, divisor: 1);

            VertexArray = new GlVertexArray();
            VertexArray.AddBuffer(PositionBuffer, positionBufferLayout);
            VertexArray.AddBuffer(NormalBuffer, normalBufferLayout);
            VertexArray.AddBuffer(ColorBuffer, colorBufferLayout);
            VertexArray.AddBuffer(MatrixBuffer, matrixBufferLayout);
        }