russell's picture

GraphicsContext CurrentContext

I want to render content to the hidden window and when rendering is finished swap buffers and show content at the main window.

I use following code to render content to the hidden window:

OpenTK.Platform.IWindowInfo m_wi;
			IGraphicsContext m_context;
			m_wi = OpenTK.Platform.Utilities.CreateWindowsWindowInfo(HiddenWindowHandle);
			// Construct a new IGraphicsContext using the IWindowInfo from above.
			m_context = new GraphicsContext(GraphicsMode.Default, m_wi);
			m_context.MakeCurrent(m_wi);
			(m_context as IGraphicsContextInternal).LoadAll();
			GL.Clear(ClearBufferMask.ColorBufferBit);
			GL.MatrixMode(MatrixMode.Projection);
			GL.LoadIdentity();
			GL.Ortho(0, Width, Height, 0, -1, 1);
			DrawLine(new Point(10, 10), new Point(100,100));
			OpenTK.Graphics.GraphicsContext.CurrentContext.SwapBuffers();

How can I render content from hidden window to main window?


Comments

Comment viewing options

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

Unfortunately, OpenGL does not work like that:

Quote:

If a window is obscured by another window, it doesn't have to store pixel data for the obscured region. Therefore, a glReadPixels() call can return undefined data for the obscured region.

This applies to both obscured and hidden windows.

If you need to perform off-screen rendering, you need to use a framebuffer object and render into a texture (which can then be bound and displayed as any other texture object). FBOs are supported by all Ati and Nvidia cards, plus modern Intel IGPs and don't require you to create a second window or context.

russell's picture

I need to perform off-screen rendering at old laptops which does not support framebuffer object. In your link I find following: "An approach that might work for some applications is to render into a nonvisible window, such as a Pixmap under X Windows. This type of drawing surface can't be obscured by the user, and its contents should always pass the pixel ownership test. Reading from such a drawing surface should always yield valid pixel data. Unfortunately, rendering to such drawing surfaces is often not accelerated by graphics hardware." So I try to do it. But don't undestand how to copy pixels from hidden window to main window.

the Fiddler's picture

In that case, HiddenWindowHandle should be a handle to a GDI bitmap rather than a window. You can read back the results of the rendering with GL.ReadPixels(), which you can then display on the main window via GL.DrawPixels() or GL.TexSubImage2D.

Continuing from your code above:

OpenTK.Graphics.GraphicsContext.CurrentContext.SwapBuffers();
 
// Read back the pixel data of the hidden window
byte[] pixel_data = new byte[hidden_window_width * hidden_window_height * GraphicsMode.Default.Color.BitsPerPixel);
GL.ReadPixels(0, 0, hidden_window_width, hidden_window_height, PixelFormat.Bgra, PixelType.UnsignedByte, pixel_data);
 
// Display pixel_data to the main window. The exact process depends on the toolkit, i.e. WinForms, WPF, GTK#, OpenTK, ...
// For example, on WinForms you can create/update a System.Drawing.Bitmap and display that directly.