public static int InitShader(ShaderType shaderType, string source)
        {
            int logLength;
            int status = 0;
            int shader = GL.CreateShader(shaderType);

            if (shader != 0)
            {
                unsafe {
                    GL.ShaderSource(shader, source);
                    GL.CompileShader(shader);
                    GL.GetShader(shader, ShaderParameter.InfoLogLength, &logLength);

                    if (logLength > 0)
                    {
                        StringBuilder log = new StringBuilder();
                        GL.GetShaderInfoLog(shader, logLength, (int *)null, log);
                        Console.WriteLine("Vtx Shader compile log: {0}\n", log);
                    }
                    GL.GetShader(shader, ShaderParameter.CompileStatus, &status);
                    if (status == 0)
                    {
                        Console.WriteLine("Failed to compile vtx shader: {0}\n", source);
                    }
                }
            }
            RenderUtils.CheckGLError();

            return(shader);
        }
        /*
         * glEnable(GLenum(GL_DEPTH_TEST));
         * glDisable(GLenum(GL_CULL_FACE));
         *
         * glUseProgram(_Program_GL_ID);
         *
         * RenderUtils.checkGLError()
         *
         * let vertexHandle = glGetAttribLocation(_Program_GL_ID, "vertexPosition");
         * let textureCoordHandle = glGetAttribLocation(_Program_GL_ID, "vertexTexCoord");
         * let mvpMatrixHandle = glGetUniformLocation(_Program_GL_ID, "modelViewProjectionMatrix");
         * let texSampler2DHandle = glGetUniformLocation(_Program_GL_ID, "texSampler2D");
         *
         * RenderUtils.checkGLError()
         *
         *
         * glVertexAttribPointer(GLuint(vertexHandle), 3, GLenum(GL_FLOAT), GLboolean(GL_FALSE), 0, _vertices_buffer);
         * glVertexAttribPointer(GLuint(textureCoordHandle), 2, GLenum(GL_FLOAT), GLboolean(GL_FALSE), 0, _tex_vertices_buffer);
         *
         * glEnableVertexAttribArray(GLuint(vertexHandle));
         * glEnableVertexAttribArray(GLuint(textureCoordHandle));
         *
         * RenderUtils.checkGLError()
         *
         * // activate texture 0, bind it, and pass to shader
         * glActiveTexture(GLenum(GL_TEXTURE0));
         * glBindTexture(GLenum(GL_TEXTURE_2D), _Texture_GL_ID);
         * glUniform1i(texSampler2DHandle, 0);
         * RenderUtils.checkGLError()
         *
         * // pass the model view matrix to the shader
         * glUniformMatrix4fv(mvpMatrixHandle, 1, GLboolean(GL_FALSE), modelViewProjection);
         *
         * RenderUtils.checkGLError()
         *
         * // finally draw the monkey
         * glDrawElements(GLenum(GL_TRIANGLES), GLsizei(_indexes_number), GLenum(GL_UNSIGNED_SHORT), _indexes_buffer);
         *
         * RenderUtils.checkGLError()
         *
         * glDisableVertexAttribArray(GLuint(vertexHandle));
         * glDisableVertexAttribArray(GLuint(textureCoordHandle));
         *
         * RenderUtils.checkGLError()
         */
        public void DrawMesh(ref float[] mvpMatrix)
        {
            GL.Enable(EnableCap.DepthTest);
            GL.Disable(EnableCap.CullFace);

            GL.UseProgram(mKeyframe_Program_GL_ID);

            RenderUtils.CheckGLError();

            var vertexHandle       = GL.GetAttribLocation(mKeyframe_Program_GL_ID, "vertexPosition");
            var textureCoordHandle = GL.GetAttribLocation(mKeyframe_Program_GL_ID, "vertexTexCoord");
            var mvpMatrixHandle    = GL.GetUniformLocation(mKeyframe_Program_GL_ID, "modelViewProjectionMatrix");
            var texSampler2DHandle = GL.GetUniformLocation(mKeyframe_Program_GL_ID, "texSampler2D");

            RenderUtils.CheckGLError();

            GL.VertexAttribPointer(vertexHandle, 3, VertexAttribPointerType.Float, false, 0, mVertices);
            GL.VertexAttribPointer(textureCoordHandle, 2, VertexAttribPointerType.Float, false, 0, mTexCoords);


            GL.EnableVertexAttribArray(vertexHandle);
            GL.EnableVertexAttribArray(textureCoordHandle);

            RenderUtils.CheckGLError();

            GL.ActiveTexture(TextureUnit.Texture0);
            GL.BindTexture(TextureTarget.Texture2D, mTexture_GL_ID);
            GL.Uniform1(texSampler2DHandle, 0);

            RenderUtils.CheckGLError();

            GL.Ext.PushGroupMarker(0, "Draw Pikkart KeyFrame");

            GL.UniformMatrix4(mvpMatrixHandle, 1, false, mvpMatrix);

            GL.DrawElements(BeginMode.Triangles, mIndices_Number, DrawElementsType.UnsignedShort, mIndex);

            GL.Ext.PopGroupMarker();

            RenderUtils.CheckGLError();

            GL.DisableVertexAttribArray(vertexHandle);
            GL.DisableVertexAttribArray(textureCoordHandle);

            RenderUtils.CheckGLError();
        }
        internal static int BuildTexture(demoImage image)
        {
            int texName = 0;

            // Create a texture object to apply to model
            unsafe  {
                GL.GenTextures(1, &texName);
                GL.BindTexture(TextureTarget.Texture2D, texName);

                // Set up filter and wrap modes for this texture object
                GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (float)All.Nearest);


                // Allocate and load image data into texture
                GL.TexImage2D(TextureTarget.Texture2D, 0, (PixelInternalFormat)image.format,
                              (int)image.width, (int)image.height, 0,
                              image.format, image.type, Marshal.UnsafeAddrOfPinnedArrayElement(image.data, 0));
                RenderUtils.CheckGLError();
            }

            return(texName);
        }
        public override void DrawInRect(GLKView view, CoreGraphics.CGRect rect)
        {
            if (!isActive())
            {
                return;
            }

            UIInterfaceOrientation orientation = UIApplication.SharedApplication.StatusBarOrientation;
            CGSize size = new CGSize(ViewportWidth, ViewportHeight);

            GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit);

            if (firstGLUpdate == false)
            {
                ApplyCameraGlOrientation(orientation);
                firstGLUpdate = true;
            }

            RenderCamera(size, Angle);

            if (isTracking())
            {
                if (CurrentMarker != null)
                {
                    if (CurrentMarker.Id == "3_1836")
                    {
                        float[] mvpMatrix = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
                        if (computeModelViewProjectionMatrix(ref mvpMatrix))
                        {
                            mMonkeyMesh.DrawMesh(ref mvpMatrix);
                            RenderUtils.CheckGLError();
                        }
                    }
                }
            }
            GL.Finish();
        }