PDA

View Full Version : offscreen rendering of single frame



whites11
01-15-2010, 09:40 AM
hi all.
i need to draw in an offscreen buffer a gl (simple) scene and to retrieve the result pixel data.
to retrieve the data i use glReadPixels.
i don't need any window at all, so my wish is not to use glut.
i'd like to have something simple like:


init_buffer(GL_AUX0, width, height);
glDrawBuffer(GL_AUX0);
glReadBuffer(GL_AUX0);

Draw(); //function ususally passed to glutDisplayFunc

//initialization of data array
glReadPixels(0, 0, width, height, GL_RGB, GL_FLOAT, &data);


i haven't found a way to do this, because i'm not able to initialize the buffer size and the
contents of data array are totally wrong.
any help, please?

kowal
01-15-2010, 11:02 AM
You need window to initialize valid OpenGL context.
If You don't want to see the window just don't show/map it. You can use wgl (Windows), or glx(Linux) instead of glut.

(BTW. glut is probably layered on top of glx/wgl , but I'm not sure).

Stephen A
01-15-2010, 11:03 AM
Did you request an auxiliary buffer when creating the context?

Additionally, you should use FBOs instead (framebuffer objects) - I don't know whether buffers are even supported anymore.

Dark Photon
01-15-2010, 12:00 PM
You need window to initialize valid OpenGL context.
I don't think that's been true for a long time. I believe you can also get there with a PBuffer or an X Pixmap (in glX-land, can't speak to wgl) -- both off-screen targets. Google GLX_DRAWABLE_TYPE. Also google glXMakeCurrent, and note that PBuffer is a valid drawable too.


If You don't want to see the window just don't show/map it.
That's an option too. And just render to an framebuffer object (http://www.songho.ca/opengl/gl_fbo.html) or something.


(BTW. glut is probably layered on top of glx/wgl , but I'm not sure).
Sure is. Has to be.

To the OP: if you decide you want some glX code, let me know and I'll post it.

Alfonse Reinheart
01-15-2010, 12:47 PM
I believe you can also get there with a PBuffer or an X Pixmap (in glX-land, can't speak to wgl)

On Windows, you have to initialize OpenGL with a HWND in order to get access to WGL extensions. Once you've done this, you can delete the window's rendering context and destroy the HWND. Once you have the WGL extension function pointers, you can use them to create a PBUFFER rendering context without a HWND.

OpenGL 3.x has provisions for creating a context with no HDC. However, I don't know if it actually works; I recall reading something in one of the ARB_create_context specs about how some internal windows thing for OpenGL needs a HDC.

kowal
01-15-2010, 12:50 PM
I googled around GLX_DRAWABLE_TYPE, and according to this:
http://www.opengl.org/sdk/docs/man/xhtml/glXIntro.xml
I can render to GLX Pixmaps, and Pbuffers. I didn't know that it is possible. Thanks for clarification :)

It seems that in wgl You can't render to ofscreen buffer without window (but this info may be quite outdated)
from OpenGL SuperBible (p. 654):



(...)
You create an OpenGL rendering context by calling the wglCreateContext function. This function takes one parameter: the device context of a window with a valid pixel format.

(...)// some not-really-useful code here

A rendering context is created that is compatible with the window for which it was created.


and afaik only way of obtaining HDC is calling GetDC(hWnd);
so You can't create HGLRC (GL rendering context) without window.

whites11
01-16-2010, 06:02 AM
Hi guys and thanks a lot for all the responses.
i used your responses for finding material to read on google.
anyway, a code snippet would be greatly appreciated.

i'm working on linux

thanks again

EDIT

here is a snippet of code i wrote:


GLuint a[1];
glGenRenderbuffersEXT(1, a);

glBindRenderbufferEXT(GL_FRAMEBUFFER_EXT, a);

glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_RGB, 300, 300);

Init();
Draw();

//read back data from the buffer
glReadBuffer(GL_RENDERBUFFER_EXT);

//evaluate the result
glReadPixels(0, 0, 300, 300, GL_RGB, GL_FLOAT, &data);

//DATA CONTAINS UNEXPECTED CONTENTS

//delete the created framebuffer
glDeleteRenderbuffersEXT(1, a);

but it doesn't work as expected. what am i doing wrong?