public override void DrawDecal(DecalInstance decal)
        {
            SetDecalMode(decal.mode);
            if (decal.decal == null)
            {
                GL.BindTexture(TextureTarget.Texture2D, rendBlankQuad.Decal().id);
            }
            else
            {
                GL.BindTexture(TextureTarget.Texture2D, decal.decal.id);
            }

            GL.BindBuffer(BufferTarget.ArrayBuffer, m_vbQuad);
            Bvert[] pVertexMem = new Bvert[decal.points];

            for (int i = 0; i < decal.points; i++)
            {
                pVertexMem[i] = new Bvert(new float[3] {
                    decal.pos[i].x, decal.pos[i].y, decal.w[i]
                }, new vf2d(decal.uv[i].x, decal.uv[i].y), decal.tint[i]);
            }

            int vertexSize = Marshal.SizeOf(typeof(Bvert));

            GL.BufferData(BufferTarget.ArrayBuffer, (int)(vertexSize * decal.points), pVertexMem, BufferUsageHint.StreamDraw);

            if (nDecalMode == DecalMode.WIREFRAME)
            {
                GL.DrawArrays(PrimitiveType.LineLoop, 0, (int)decal.points);
            }
            else
            {
                GL.DrawArrays(PrimitiveType.TriangleFan, 0, (int)decal.points);
            }
        }
        public override void DrawLayerQuad(vf2d offset, vf2d scale, Pixel tint)
        {
            GL.BindBuffer(BufferTarget.ArrayBuffer, m_vbQuad);
            const int   numVerts = 4;
            const float voffset  = 1f;

            Bvert[] verts =
                new Bvert[numVerts] {
                new Bvert(new float[5] {
                    -voffset, -voffset, 1.0f, 0.0f * scale.x + offset.x, 1.0f * scale.y + offset.y
                }, tint),
                new Bvert(new float[5] {
                    +voffset, -voffset, 1.0f, 1.0f * scale.x + offset.x, 1.0f * scale.y + offset.y
                }, tint),
                new Bvert(new float[5] {
                    -voffset, +voffset, 1.0f, 0.0f * scale.x + offset.x, 0.0f * scale.y + offset.y
                }, tint),
                new Bvert(new float[5] {
                    +voffset, +voffset, 1.0f, 1.0f * scale.x + offset.x, 0.0f * scale.y + offset.y
                }, tint)
            };
            GL.BufferData(BufferTarget.ArrayBuffer, sizeof(Bvert) * numVerts, verts, BufferUsageHint.StreamDraw);

            GL.DrawArrays(PrimitiveType.TriangleStrip, 0, 4);
        }
        public override Const.rcode CreateDevice(List <IntPtr> parameters, bool bFullScreen, bool bVSYNC)
        {
            GLFW.MakeContextCurrent((OpenTK.Windowing.GraphicsLibraryFramework.Window *)window);

            GL.LoadBindings(new GLFWBindingsContext());

            int vertexShader = GL.CreateShader(ShaderType.VertexShader);

            GL.ShaderSource(vertexShader, vertexShaderSource);
            GL.CompileShader(vertexShader);

            string infoLog = "";

            infoLog = GL.GetShaderInfoLog(vertexShader);

            if (infoLog.Length > 0)
            {
                Console.WriteLine("ERROR::SHADER::VERTEX::COMPILATION_FAILED " + infoLog);
            }

            // FRAGMENT SHADER
            int fragmentShader = GL.CreateShader(ShaderType.FragmentShader);

            GL.ShaderSource(fragmentShader, fragmentShaderSource);
            GL.CompileShader(fragmentShader);


            infoLog = GL.GetShaderInfoLog(fragmentShader);

            if (infoLog.Length > 0)
            {
                Console.WriteLine("ERROR::SHADER::FRAGMENT::COMPILATION_FAILED " + infoLog);
            }


            // SHADER PROGRAM
            shaderProgram = GL.CreateProgram();
            GL.AttachShader(shaderProgram, vertexShader);
            GL.AttachShader(shaderProgram, fragmentShader);
            GL.LinkProgram(shaderProgram);
            infoLog = GL.GetProgramInfoLog(shaderProgram);
            if (infoLog.Length > 0)
            {
                Console.WriteLine("ERROR::PROGRAM::LINK_FAILED " + infoLog);
            }



            bSync = bVSYNC;
            if (!bSync)
            {
                GLFW.SwapInterval(0);
            }

            // Create Quad
            m_vbQuad = GL.GenBuffer();
            m_vaQuad = GL.GenVertexArray();
            GL.BindVertexArray(m_vaQuad);
            GL.BindBuffer(BufferTarget.ArrayBuffer, m_vbQuad);

            Bvert[] verts    = new Bvert[OLC_MAX_VERTS];
            int     vertsize = sizeof(Bvert);

            GL.BufferData(BufferTarget.ArrayBuffer, verts.Length * sizeof(float), verts, BufferUsageHint.StaticDraw);

            GL.VertexAttribPointer(0, 3, VertexAttribPointerType.Float, false, vertsize, 0); GL.EnableVertexAttribArray(0);
            GL.VertexAttribPointer(1, 2, VertexAttribPointerType.Float, false, vertsize, (3 * sizeof(float))); GL.EnableVertexAttribArray(1);
            //GL.VertexAttribPointer(2, 4, VertexAttribPointerType.UnsignedByte, false, vertsize, (4 * sizeof(byte))); GL.EnableVertexAttribArray(1);

            GL.BindBuffer(BufferTarget.ArrayBuffer, 0);
            GL.BindVertexArray(0);

            // Create blank texture for spriteless decals

            rendBlankQuad.Create(1, 1);
            rendBlankQuad.Sprite().GetData()[0] = Pixel.BLACK;
            rendBlankQuad.Decal().Update();


            return(Const.rcode.OK);
        }