jdaniel7's picture

ReadPixels() method for OpenTK.GLControl returns a blank image when GLCOntrol is not visible on screen

Project:The Open Toolkit library
Version:all versions
Component:Code
Category:support request
Priority:normal
Assigned:Unassigned
Status:closed
Description

This request is a continuation of an old request which was resolved over a year ago. If can be found at:
http://www.opentk.com/node/2151

I have been tasked with now printing the GLControl without it being visible on-screen. What is happening is thereis a series of renders occuring (printing a series of drawings) and the user does not want to see the GLControl flashing onscreen as it creates the graphics and saves the bitmap. The user would like to continue using his/her computer while the drawings are being generated (batch mode). What I did was set an option to not display the control - it still exists and is rendering but since it is the user control it is contained in is not shown, I am getting a blank bitmap. If I understand correctly, I need to use a FBO to render off-screen and save that to the bitmap. I have tried to follow along with the link:

www.opentk.com/doc/graphics/frame-buffer-objects

but I get confused and I can't get it to work. My image is still blank. Can someone tell me what I need to change to render off-screen?

Here is my method that draws the graphics to the GLControl:

        public void Draw()
        {
                otkViewport.MakeCurrent(); //GLControl
 
                GL.ClearColor(Color.Black.R, Color.Black.G, Color.Black.B, Color.Black.A);
 
                GL.DepthMask(true);
                GL.Clear(ClearBufferMask.ColorBufferBit);
                GL.Clear(ClearBufferMask.DepthBufferBit);
 
                DrawBackground(); //Creates a gradient background
 
                GL.PushMatrix();
 
                GL.MultMatrix(Configuration.ViewCamera.viewMat.array);
 
                GL.Enable(EnableCap.PolygonStipple);
                GL.ShadeModel(ShadingModel.Smooth);
                GL.Disable(EnableCap.Blend);
 
                RenderDisplayables(); //Makes the call to GL.CallList for all the objects to display 
 
                GL.Flush();
 
                otkViewport.SwapBuffers();
        }

And this is my method to get the bitmap:

        public Bitmap GrabScreenshot()
        {
            this.otkViewport.MakeCurrent(); //GLControl
 
            GL.DrawBuffer( DrawBufferMode.Back);
            GL.ReadBuffer(ReadBufferMode.Back);
 
            Bitmap bmp = new Bitmap(this.otkViewport.Width, this.otkViewport.Height);
            System.Drawing.Imaging.BitmapData data =
                bmp.LockBits(otkViewport.ClientRectangle, System.Drawing.Imaging.ImageLockMode.WriteOnly,
                             System.Drawing.Imaging.PixelFormat.Format24bppRgb);
 
            GL.Finish();
            GL.ReadPixels(0, 0, this.otkViewport.Width, this.otkViewport.Height, PixelFormat.Bgr, PixelType.UnsignedByte,  data.Scan0);
            bmp.UnlockBits(data);
            bmp.RotateFlip(RotateFlipType.RotateNoneFlipY);
            return bmp;
        }

Thanks


Comments

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.
jdaniel7's picture

#1

Status:open» closed

I was able to resolve the issue. I was restoring the Viewport prior to capturing the bitmap.