Inheritance: GLTexture
Ejemplo n.º 1
0
        public DissolveProcessor(GraphicsInterface gi, int width, int height, float noiseScale)
        {
            fGI = gi;

            fWidth = width;
            fHeight = height;
            fNoiseScale = noiseScale;

            // Create the texture objects that will receive the output
            fOutputTexture = new GLTexture2D(GI, width, height, TextureInternalFormat.Rgba, TexturePixelFormat.Bgr, PixelComponentType.Byte, IntPtr.Zero, false);
            // Setup the render target that has 3 color channels for Multi Render Target
            // output in a shader using gl_FragData[n]
            fOutputTarget = new GLRenderTarget(GI);
            fOutputTarget.AttachColorBuffer(fOutputTexture, ColorBufferAttachPoint.Position0);
            fOutputTarget.Unbind();

            // Create the shader program that does the actual separation
            fDissolveShader = GLSLShaderProgram.CreateUsingVertexAndFragmentStrings(GI, FixedVert, Dissolve_Frag);
        }
Ejemplo n.º 2
0
        /// <summary>
        /// This is the easiest constructor to use when you already have a texture, and you
        /// want to draw into it.  Just pass the texture in, and the RenderTarget will be
        /// constructed to match the size.
        /// </summary>
        /// <param name="gi"></param>
        /// <param name="texture"></param>
        public GLRenderTarget(GLTexture2D texture)
            : this(texture.GI)
        {
            fWidth = texture.Width;
            fHeight = texture.Height;

            FrameBuffer.Bind();

            // Create the render buffer to be attached as a depth
            // buffer.
            fDepthBuffer = new GLRenderBuffer(fGI);
            fDepthBuffer.Bind();
            fDepthBuffer.AllocateStorage(fWidth, fHeight, gl.GL_DEPTH_COMPONENT);
            
            fFrameBuffer.AttachDepthBuffer(fDepthBuffer);

            // Create the texture object to be attached as color buffer    
            AttachColorBuffer(texture, ColorBufferAttachPoint.Position0);

            FrameBuffer.Unbind();
        }
Ejemplo n.º 3
0
        public YCrCbProcessor(GraphicsInterface gi, int width, int height)
        {
            fGI = gi;

            fWidth = width;
            fHeight = height;

            // Create the texture objects that will receive the output
            fYTexture = new GLTexture2D(GI, width, height, TextureInternalFormat.Luminance, TexturePixelFormat.Luminance, PixelType.Byte, IntPtr.Zero, false);
            fCrTexture = new GLTexture2D(GI, width, height, TextureInternalFormat.Luminance, TexturePixelFormat.Luminance, PixelType.Byte, IntPtr.Zero, false);
            fCbTexture = new GLTexture2D(GI, width, height, TextureInternalFormat.Luminance, TexturePixelFormat.Luminance, PixelType.Byte, IntPtr.Zero, false);

            // Setup the render target that has 3 color channels for Multi Render Target
            // output in a shader using gl_FragData[n]
            fYCrCbTarget = new GLRenderTarget(GI);
            fYCrCbTarget.AttachColorBuffer(fYTexture, ColorBufferAttachPoint.Position0);
            fYCrCbTarget.AttachColorBuffer(fCrTexture, ColorBufferAttachPoint.Position1);
            fYCrCbTarget.AttachColorBuffer(fCbTexture, ColorBufferAttachPoint.Position2);
            fYCrCbTarget.Unbind();

            // Create the shader program that does the actual separation
            fYCrCbChannelSep = GLSLShaderProgram.CreateUsingVertexAndFragmentStrings(GI, FixedVert, YCrCb_Frag);
        }
Ejemplo n.º 4
0
        public void AttachColorBuffer(GLTexture2D colorbuffer, ColorBufferAttachPoint attachPosition)
        {
            fWidth = colorbuffer.Width;
            fHeight = colorbuffer.Height;

            Bind();
            colorbuffer.Bind();

            fFrameBuffer.AttachColorBuffer(colorbuffer, attachPosition);
            fColorBuffers.Add(attachPosition, colorbuffer);
        }
Ejemplo n.º 5
0
 public virtual void AssignTexture(GLTexture2D aTexture)
 {
     Bind();
     aTexture.Bind();
 }
Ejemplo n.º 6
0
        public static void DrawTextureImageUnrotatedAndOrthographically(GraphicsInterface gi, int clientWidth, int clientHeight, GLTexture2D texture,
          int drawX, int drawYTextMode, // i.e., 0 == draw TOP of image at TOP of viewport, Y-axis points DOWN
          int drawWidth, int drawHeight)
        {
            // Change rendering conditions
            gi.Features.DepthTest.Disable();
            gi.Features.CullFace.Disable();

            // Preserve current matrices, and switch to an orthographic view, and 
            //   do scaling and translation as necessary.
            gi.MatrixMode(MatrixMode.Projection);
            gi.PushMatrix();
            gi.MatrixMode(MatrixMode.Modelview);
            gi.PushMatrix();


            gi.MatrixMode(MatrixMode.Projection);
            gi.LoadIdentity();
            gi.Ortho(0, (clientWidth - 1), 0, (clientHeight - 1), -1.0, 1.0);

            gi.MatrixMode(MatrixMode.Modelview);
            gi.LoadIdentity();



            if (null != texture)
            {
                // Enable texture
                texture.Bind();
            }

            // Enable blending
            gi.Features.Blend.Enable();
            gi.BlendFunc(BlendingFactorSrc.SrcAlpha, BlendingFactorDest.OneMinusSrcAlpha);


            // Draw a quad

            gi.Drawing.Quads.Begin();

            // TOP-LEFT
            gi.TexCoord(0.0f, 1.0f);
            gi.Color(ColorRGBA.White);
            gi.Vertex((drawX), ((clientHeight - 1) - drawYTextMode), 0.0f);

            // BOTTOM-LEFT
            gi.TexCoord(0.0f, 0.0f);
            gi.Color(1.0f, 1.0f, 1.0f, 1.0f);
            gi.Vertex(drawX, ((clientHeight - 1) - (drawYTextMode + drawHeight)), 0.0f);

            // BOTTOM-RIGHT
            gi.TexCoord(1.0f, 0.0f);
            gi.Color(1.0f, 1.0f, 1.0f, 1.0f);
            gi.Vertex((drawX + (drawWidth)), ((clientHeight - 1) - (drawYTextMode + drawHeight)), 0.0f);

            // TOP-RIGHT
            gi.TexCoord(1.0f, 1.0f);
            gi.Color(1.0f, 1.0f, 1.0f, 1.0f);
            gi.Vertex((drawX + (drawWidth)), ((clientHeight - 1) - drawYTextMode), 0.0f);

            gi.Drawing.Quads.End();


            // Disable blending
            gi.Features.Blend.Disable();

            if (null != texture)
            {
                // Disable texture
                gi.Features.Texturing2D.Disable();
                gi.BindTexture(TextureBindTarget.Texture2d, 0);
            }


            // Restore original matrices.
            gi.MatrixMode(MatrixMode.Modelview);
            gi.PopMatrix();
            gi.MatrixMode(MatrixMode.Projection);
            gi.PopMatrix();


            // Restore rendering conditions
            gi.FrontFace(FrontFaceDirection.Ccw); // MUST DO AFTER USING wglUseFontOutlines LISTS!!!
            gi.Features.DepthTest.Enable();
            gi.Features.CullFace.Enable();
        }
Ejemplo n.º 7
0
        //public bool UpdateTextureWithBitmapData(GraphicsInterface gr, Bitmap bitmap)
        //{
        //    if (null == bitmap)
        //    {
        //        return (false);
        //    }

        //    bool result;

        //    if ((fPixelData.Width != bitmap.Width) || (fPixelData.Height != bitmap.Height))
        //    {
        //        // Uh, oh!  User submitted a bitmap which has dimensions different from the
        //        // original dimensions!  Create a new texture!
        //        result = CreateTextureFromBitmap(gr, bitmap, fUseMipMaps);
        //        return (result);
        //    }

        //    // Okay, the supplied bitmap is compatible with the current texture dimensions.
        //    // Copy bitmap data to our already-allocated byte buffer.
        //    result = GLImage.FillInAllocatedRGBADataWithBitmapData(bitmap, fPixelData.Data);
        //    if (false == result)
        //    {
        //        return (false);
        //    }

        //    SubmitModifiedInternalRGBADataToTexture(gr);

        //    return (true);
        //}

        //public bool TransferOpenGLTextureDataBackToHostMemoryAndCopyToCompatibleBitmap(GraphicsInterface gr, Bitmap bitmap)
        //{
        //    if (null == fPixelData.Data)
        //    {
        //        return (false);
        //    }

        //    TransferTextureDataBackToHostMemory(gr);

        //    if (null == bitmap)
        //    {
        //        return (false);
        //    }

        //    if ((fPixelData.Width != bitmap.Width) || (fPixelData.Height != bitmap.Height))
        //    {
        //        // Uh, oh!  User submitted a bitmap which has dimensions different from the
        //        // texture dimensions!  Give up!
        //        return (false);
        //    }

        //    bool result = GLImage.CopyRGBABufferToCompatibleBitmap(fPixelData.Data, bitmap);

        //    return (result);
        //}


        //public void SubmitModifiedInternalRGBADataToTexture(GraphicsInterface gr)
        //{
        //    if (null == fPixelData.Data)
        //    {
        //        return;
        //    }

        //    // Make sure total bytes matches RGBA * width * height.
        //    int totalBytes = ((4 * fPixelData.Width) * fPixelData.Height);
        //    if (totalBytes != fPixelData.Data.Length)
        //    {
        //        return;
        //    }


        //    gl.glBindTexture(gl.GL_TEXTURE_2D, fTextureID);



        //    if (fUseMipMaps)
        //    {
        //        // Will this work?
        //        //glu.gluBuild2DMipmaps
        //        //(
        //        //    gl.GL_TEXTURE_2D,      // target                    
        //        //    gl.GL_RGBA,            // internalFormat
        //        //    fWidth,           // width
        //        //    fHeight,          // height
        //        //    gl.GL_RGBA,            // format
        //        //    gl.GL_UNSIGNED_BYTE,   // type
        //        //    fRGBAData         // data
        //        //);
        //    }
        //    else
        //    {
        //        gl.glTexSubImage2D
        //        (
        //            gl.GL_TEXTURE_2D,      // target
        //            0,                     // level
        //            0,                     // xoffset
        //            0,                     // yoffset
        //            fPixelData.Width,           // width
        //            fPixelData.Height,          // height
        //            gl.GL_RGBA,            // format
        //            gl.GL_UNSIGNED_BYTE,   // type
        //            fPixelData.Data         // pixels
        //        );
        //    }

        //}
        #endregion

        #region Static Methods
        public static GLTexture2D CreateTextureFromPixelData(GraphicsInterface gi, GLPixelData pixeldata, bool createMipMaps)
        {
            GLTexture2D tex = new GLTexture2D(gi, pixeldata, createMipMaps);

            return tex;
        }
Ejemplo n.º 8
0
        //public void TransferTextureDataBackToHostMemory(GraphicsInterface gr)
        //{
        //    if (null == RGBAData)
        //    {
        //        return;
        //    }

        //    try
        //    {
        //        gl.glGetTexImage
        //          (
        //          gl.GL_TEXTURE_2D,     // target
        //          0,                    // level (0 == top-most mip-map level)
        //          gl.GL_RGBA,           // internalFormat
        //          gl.GL_UNSIGNED_BYTE,  // type
        //          RGBAData        // data
        //          );
        //    }
        //    catch
        //    {
        //    }
        //}

        public static GLTexture2D CreateCheckerboardTexture(GraphicsInterface gi, int width, int height, int blockSize)
        {
            int totalBytes = ((width * 4) * height);
            byte[] databytes = new byte[totalBytes];
            //bool useMipMaps = true;

            int x = 0;
            int y = 0;
            int k = 0;
            byte val = 0;

            for (y = 0; y < height; y++)
            {
                for (x = 0; x < width; x++)
                {
                    k = ((width * 4) * y) + (x * 4);

                    val = 0;
                    if (0 == (((x / blockSize) + (y / blockSize)) % 2))
                        val = 255;

                    databytes[k + 0] = val; // red
                    databytes[k + 1] = val; // green
                    databytes[k + 2] = val; // blue
                    databytes[k + 3] = 255; // opacity (255 == opaque)
                }
            }

            GLPixelData pixMap = new GLPixelData(width, height, TextureInternalFormat.Rgba8, PixelLayout.Rgba, PixelComponentType.UnsignedByte, databytes);
            GLTexture2D tex = new GLTexture2D(gi, pixMap, false);
            
            //GCHandle data_ptr = GCHandle.Alloc(databytes, GCHandleType.Pinned);
            //IntPtr fDataPtr = (IntPtr)data_ptr.AddrOfPinnedObject();
            //GLTexture2D tex = new GLTexture2D(gi, width, height, TextureInternalFormat.Rgba8, TexturePixelFormat.Rgba, PixelComponentType.UnsignedByte, fDataPtr, false);
            //data_ptr.Free();

            return tex;
        }
Ejemplo n.º 9
0
        /// <summary>
        /// This is called by the rendering system automatically.
        /// 
        /// We want to do the channel separation, and then the drawing
        /// of the quads.
        /// </summary>
        protected override void  DrawContent()
        {
            GLTexture finalImage = null;

            //GLTexture finalImage = fCamera1;
            finalImage = fGrayConverter.ProcessTexture(fCamera1);

           // GLTexture grayImage = fGrayConverter.ProcessTexture(fCamera1);
            //GLTexture finalImage = fPixellate.ProcessTexture(fCamera1);

            //GLTexture finalImage = fGammaCorrection.ProcessTexture(processedImge);

            //GLTexture finalImage = fLuminanceThreshold.ProcessTexture(fGrayConverter.ProcessTexture(fCamera1));
            //GLTexture finalImage = fLuminanceBinarizer.ProcessTexture(fCamera1);
            //GLTexture finalImage = fLuminanceThreshold.ProcessTexture(fCamera1);
            //GLTexture finalImage =  fEdgeEnhance.ProcessTexture(fCamera1);
            //GLTexture finalImage = fGrayConverter.ProcessTexture(fEdgeEnhance.ProcessTexture(fCamera1));
            //GLTexture finalImage = fSobell.ProcessTexture(fSoften.ProcessTexture(fGrayConverter.ProcessTexture(fCamera1)));
            finalImage = fSobell.ProcessTexture(fGrayConverter.ProcessTexture(fCamera1)); // Scary
            //GLTexture finalImage = fSobell.ProcessTexture(fCamera1); // Scary
            //GLTexture finalImage = fLuminanceThreshold.ProcessTexture(fPixellate.ProcessTexture(fCamera1));
            //GLTexture finalImage = fPixellate.ProcessTexture(fGrayConverter.ProcessTexture(fCamera1));
            //GLTexture finalImage = fSoften.ProcessTexture(fCamera1);
            //GLTexture finalImage = fLaplacian.ProcessTexture(fGrayConverter.ProcessTexture(fCamera1));
            //GLTexture finalImage = fBlocker.ProcessTexture(fCamera1);

            // Get 30 snapshots before proceeding so we don't start from
            // a blank image.
            if (null == fBackgroundFrame)
            {
                fBackgroundCount++;
                    if (fBackgroundCount < 30)
                        return;

                    fBackgroundFrame = fBackgroundCopier.ProcessTexture(fCamera1);
            }

            //DoMorph();

            //// Get the current image from the camera
            //finalImage = fSobell.ProcessTexture(fPixellate.ProcessTexture(fGrayConverter.ProcessTexture(fCamera1)));

            //finalImage = fDifference.ProcessTwoTextures(fBackgroundFrame, fCamera1);


            fGrayMesh.Texture = finalImage;
            fGrayMesh.Render(GI);

            //fPointMesh.Texture = fCamera1;
            //fPointMesh.Render(GI);
        }
Ejemplo n.º 10
0
        /// <summary>
        /// Perform Color separation in one pass.  There are a total of 4 texture
        /// objects involved, a RenderTarget, and fragment shader.
        /// 
        /// The source texture, is assumed to be the video texture.  That is what
        /// will be rendered as a quad into the RenderTarget.
        /// 
        /// The Y, Cr, and Cb textures have been attached to the color buffer attachment
        /// points of the RenderTarget.
        /// 
        /// The shader program simply takes the source fragment, and performs the
        /// Y, Cr, Cb separation calculations and places the output into the appropriate
        /// color buffers.
        /// 
        /// And the end, the Y, Cr, Cb texture objects contain the results.
        /// 
        /// All done in one pass, using a shader program, in the time that it takes to 
        /// render a single quad into an offscreen buffer.
        /// </summary>
        public void SeparateChannels(GLTexture2D currentTexture)
        {
            GLSLShaderProgram currentProgram = fYCrCbChannelSep;
            GLRenderTarget currentTarget = fYCrCbTarget;

            int[] buffers = { gl.GL_COLOR_ATTACHMENT0_EXT, 
		     gl.GL_COLOR_ATTACHMENT1_EXT, 
		     gl.GL_COLOR_ATTACHMENT2_EXT};

            // First draw the current texture into an offscreen buffer
            // just so we can do the color separation.
            currentTarget.Bind();
            {
                GI.DrawBuffers(3, buffers);


                GI.Features.Texturing2D.Enable();

                // We want replace mode because we don't care about
                // the values that are currently in place, we just want
                // to replace them.
                GI.TexEnv(TextureEnvModeParam.Replace);


                // Set the viewport to be the whole texture
                GI.Viewport(0, 0, currentTexture.Width, currentTexture.Height);

                GI.MatrixMode(MatrixMode.Projection);
                GI.LoadIdentity();

                GI.Ortho(0, currentTexture.Width, 0, currentTexture.Height, -1.0, 1.0);
                //GI.FrontFace(FrontFaceDirection.Cw);

                // The current program is the channel separation program.  it will change
                // depending on which channel we are currently separating.
                currentProgram.Bind();
                {
                    // We want to turn off filtering.  We do that by using 'nearest'
                    // we also clamp the coordinates instead of replicating at the edges
                    currentTexture.Bind();
                    GI.TexParameter(TextureParameterTarget.Texture2d, TextureParameterName.TextureMinFilter, TextureMinFilter.Nearest);
                    GI.TexParameter(TextureParameterTarget.Texture2d, TextureParameterName.TextureMagFilter, TextureMagFilter.Nearest);
                    GI.TexParameter(TextureParameterTarget.Texture2d, TextureParameterName.TextureWrapS, TextureWrapMode.Clamp);
                    GI.TexParameter(TextureParameterTarget.Texture2d, TextureParameterName.TextureWrapT, TextureWrapMode.Clamp);

                    currentProgram["tex0"].Set((int)0);

                    GI.Drawing.Quads.Begin();
                    {
                        float left = 0;
                        float bottom = 0;
                        float right = currentTexture.Width;
                        float top = currentTexture.Height;

                        // Left bottom
                        GI.TexCoord(0.0f, 0.0f);
                        GI.Vertex(left, bottom, 0.0f);

                        // Left top
                        GI.TexCoord(0.0f, 1.0f);
                        GI.Vertex(left, top, 0.0f);

                        // Right top
                        GI.TexCoord(1.0f, 1.0f);
                        GI.Vertex(right, top, 0.0f);

                        // Right bottom
                        GI.TexCoord(1.0f, 0.0f);
                        GI.Vertex(right, bottom, 0.0f);
                    }
                    GI.Drawing.Quads.End();

                    currentTexture.Unbind();
                }
                currentProgram.Unbind();

            }
            currentTarget.Unbind();

        }
Ejemplo n.º 11
0
 public void Attach1DTexture(ColorBufferAttachPoint attachType, GLTexture2D tex)
 {
     GI.FramebufferTexture1D(gl.GL_FRAMEBUFFER_EXT, attachType, gl.GL_TEXTURE_1D, (int)tex.TextureID, 0);
 }
Ejemplo n.º 12
0
 public void AttachColorBuffer(GLTexture2D colorbuffer, ColorBufferAttachPoint attachPosition)
 {
     GI.FramebufferTexture2D(gl.GL_FRAMEBUFFER_EXT, attachPosition, gl.GL_TEXTURE_2D, (int)colorbuffer.TextureID, 0);
 }
Ejemplo n.º 13
0
 public void Attach3DTexture(GLTexture2D tex)
 {
     GI.FramebufferTexture3D(gl.GL_FRAMEBUFFER_EXT, ColorBufferAttachPoint.Position0, gl.GL_TEXTURE_3D, (int)tex.TextureID, 0, 0);
 }
Ejemplo n.º 14
0
 public void Attach3DTexture(GLTexture2D tex, ColorBufferAttachPoint attachType)
 {
     GI.FramebufferTexture3D(gl.GL_FRAMEBUFFER_EXT, attachType, gl.GL_TEXTURE_3D, (int)tex.TextureID, 0, 0);
 }
Ejemplo n.º 15
0
 public void Attach3DTexture(GLTexture2D tex, ColorBufferAttachPoint attachType, int mipLevel, int zOffset)
 {
     GI.FramebufferTexture3D(gl.GL_FRAMEBUFFER_EXT, attachType, gl.GL_TEXTURE_3D, (int)tex.TextureID, mipLevel, zOffset);
 }
Ejemplo n.º 16
0
 public void Attach2DTexture(ColorBufferAttachPoint attachType, GLTexture2D tex, int mipLevel)
 {
     GI.FramebufferTexture2D(gl.GL_FRAMEBUFFER_EXT, attachType, gl.GL_TEXTURE_2D, (int)tex.TextureID, mipLevel);
 }
Ejemplo n.º 17
0
        /// <summary>
        /// Create a render target with the specified width and height in pixels.
        /// A color buffer and depth buffer will be attached.
        /// </summary>
        /// <param name="gi">The graphics interface used to construct the components.</param>
        /// <param name="width">The width of the RenderTarget in pixels.</param>
        /// <param name="height">The height of the RenderTarget in pixels.</param>
        public GLRenderTarget(GraphicsInterface gi, int width, int height)
            : this(gi)
        {
            fGI = gi;

            fWidth = width;
            fHeight = height;

            FrameBuffer.Bind();

            CreateDepthBuffer(width, height);

            // Create the texture object to be attached as color buffer            
            GLTexture2D colorbuffer = new GLTexture2D(fGI, width, height);
            AttachColorBuffer(colorbuffer, ColorBufferAttachPoint.Position0);

            FrameBuffer.Unbind();
        }
Ejemplo n.º 18
0
        /// <summary>
        /// Perform a dissolve between a 'base' image and a 'blend' image.
        /// </summary>
        /// <param name="currentTexture"></param>
        public void ProcessImages(GLTexture2D baseImage, GLTexture2D blendImage, float opacity)
        {
            GI.Features.Texturing2D.Enable();

            // Bind the inputs to the texture units
            GLTextureUnit baseUnit = GLTextureUnit.GetTextureUnit(fGI, TextureUnitID.Unit1);
            GLTextureUnit blendUnit = GLTextureUnit.GetTextureUnit(fGI, TextureUnitID.Unit2);

            baseUnit.AssignTexture(baseImage);
            blendUnit.AssignTexture(blendImage);
            //blendUnit.Unbind();


                // We want replace mode because we don't care about
                // the values that are currently in place, we just want
                // to replace them.
                GI.TexEnv(TextureEnvModeParam.Replace);


                // Set the viewport to be the whole texture
                GI.Viewport(0, 0, fWidth, fHeight);

                GI.MatrixMode(MatrixMode.Projection);
                GI.LoadIdentity();

                GI.Ortho(0, fWidth, 0, fHeight, -1.0, 1.0);
                //GI.FrontFace(FrontFaceDirection.Cw);

                // The current program is the channel separation program.  it will change
                // depending on which channel we are currently separating.
                Program.Bind();
                {
                    // set the program's input textures
                    Program["Base"].Set((int)baseUnit.OrdinalForShaders);
                    Program["Blend"].Set((int)blendUnit.OrdinalForShaders);
                    //Program["NoiseScale"].Set((float)fNoiseScale);
                    Program["Opacity"].Set((float)opacity);

                    // We want to turn off filtering.  We do that by using 'nearest'
                    // we also clamp the coordinates instead of replicating at the edges
                    GI.Features.Texturing2D.Enable();
                    //blendImage.Bind();
                    //GI.TexParameter(TextureParameterTarget.Texture2d, TextureParameterName.TextureMinFilter, TextureMinFilter.Linear);
                    //GI.TexParameter(TextureParameterTarget.Texture2d, TextureParameterName.TextureMagFilter, TextureMagFilter.Linear);
                    //GI.TexParameter(TextureParameterTarget.Texture2d, TextureParameterName.TextureWrapS, TextureWrapMode.Clamp);
                    //GI.TexParameter(TextureParameterTarget.Texture2d, TextureParameterName.TextureWrapT, TextureWrapMode.Clamp);

                    GI.Drawing.Quads.Begin();
                    {
                        float left = 0;
                        float bottom = 0;
                        float right = blendImage.Width;
                        float top = blendImage.Height;

                        // Left bottom
                        GI.TexCoord(0.0f, 0.0f);
                        GI.Vertex(left, bottom, 0.0f);

                        // Left top
                        GI.TexCoord(0.0f, 1.0f);
                        GI.Vertex(left, top, 0.0f);

                        // Right top
                        GI.TexCoord(1.0f, 1.0f);
                        GI.Vertex(right, top, 0.0f);

                        // Right bottom
                        GI.TexCoord(1.0f, 0.0f);
                        GI.Vertex(right, bottom, 0.0f);
                    }
                    GI.Drawing.Quads.End();

                    //blendImage.Unbind();
                }
                Program.Unbind();

        }