Loosing textures after rendering in DIBSection --- The solution.

On this forum I posted the following problem. Nobody had an answer, so I had to think about myself.

Problem:
After rendering to DIB-Section all textures are lost !?

Solution:
You have to reload all the textures for each rendering-context, even if you use the same display-list.
This is because texture-binding (with glBindTexture) in OpenGL is local for each rendering-context.
The documentation says: ‘Texture names and the corresponding texture contents are local to the shared display-list space of the current OpenGL rendering context; two rendering contexts share texture names only if they also share display lists.’
The last statement seems not to be true.

Maybe it helps someone.
Robert

Other solution is to render to the back buffer and reading it to a bitmap afterwards without flipping.
I heard this can be slower on certain cards but it runs smoothly on my TNT2 ultra.
And you don’t need to reload the textures

Tes, the statement is true. But it is only valid if you use the same pixel format in both your DCs/RCs…

When you render to a DIB, you use Microsoft OpenGL implementation while when you render on the screen, you use your graphics card vendor implementation. They have two different pixel formats so they can’t share display lists / textures.

Paddy, your solution should run as long as you want your snapshot being the same size as your screen/window. If you want a 527x333 snapshot while your window is 689x543, then you would have to resize the window, render, read pixels back, resize back… I prefer the DIB method.

Another thing to note is that as rendering to a DIB uses the MS Generic Implementation, you can’t use all those fancy OGL extensions (they hardly implement any !).

Last thing, if someone knows (Paddy ?) how to use this backbuffer rendering + glReadPixels with any size (without the hassle of resizing everything !), I am interested !

Regards.

Eric

I use following method (but my case is special) :
I create an invisible OpenGl compliant window :
CreateWindow (any size), and then
ShowWindow(hwnd, SW_HIDE);

Then in the rendering function :

SetWindowPos(rd->data->hwnd,HWND_TOPMOST,0,0,dst->Width,dst->Height,SWP_NOACTIVATE);
Makes this invisible window topmost and right sized without activating it so it will not be clipped and your other windows don’t lose focus.

DO RENDER STUFF HERE
Then :
glReadBuffer(GL_BACK);
glReadPixels(0,0,dst->Width,dst->Height,GL_RGBA,GL_UNSIGNED_BYTE,dst->Data);

Got it !

It looks tricky but works perfectly. The window is only here to give a base, OpenGL doen’t really need it. And rendering uses hardware here.
Hope this helps.

Thanks to paddy and Eric. I use the DIB-Rendering for printing on Win95/98 (with StretchDIBits).

To Eric: I use the same pixelformat for screen and DIB (PFD_DRAW_TO_WINDOW Or PFD_DRAW_TO_BITMAP) !?

Robert

Originally posted by paddy:
[b]I use following method (but my case is special) :
I create an invisible OpenGl compliant window :
CreateWindow (any size), and then
ShowWindow(hwnd, SW_HIDE);

Then in the rendering function :

SetWindowPos(rd->data->hwnd,HWND_TOPMOST,0,0,dst->Width,dst->Height,SWP_NOACTIVATE);
Makes this invisible window topmost and right sized without activating it so it will not be clipped and your other windows don’t lose focus.

DO RENDER STUFF HERE
Then :
glReadBuffer(GL_BACK);
glReadPixels(0,0,dst->Width,dst->Height,GL_RGBA,GL_UNSIGNED_BYTE,dst->Data);

Got it !

It looks tricky but works perfectly. The window is only here to give a base, OpenGL doen’t really need it. And rendering uses hardware here.
Hope this helps.[/b]

Have you tested it on the 3D cards with shared double-buffered framebuffer?
(like NVIDIA Quadro, 3Dlabs GLINT MX / R3 / R4, E&S, Wildcat … etc.)

Can anyone just send me the cards so i can test it ?

Hmm, no…

But if you can sent me your sample,
I’ll test it on ELSA GLoria L/MX (GLINT MX), ELSA GLoria II (Quadro), Oxigen GVX210 (GLINT R3) and Fire GL1.