Grabbing full screen

This is a following to the last glow thread.

I’m trying to test a simple full screen grab, but I can’t seem to make it.

I create a “RenderInto” texture, that is supposed to receive the screen, then I want to generate a mip map level, and then stick that blurred texture on top of the frame.

Method and problems :
1- Creation of the texture : gluBuild2DMipMaps, bilinear filtering, size of 10241024 or 512512
2- My texture is square, and my screen is not (1024768). How am I supposed to get the screen in the texture ? I can’t make glCopyTexSubImage2D working … (yet, it works on a square subpart or the frame buffer)
3- a SGIS mip map thing will generate the desired mip map level (say 256
256), there should be no problem here, but I talk about this just to be sure the method is correct.
4- I need to render the quad on top of the screen with the right mip map level, … I’ll tweak the LODBias lambda to do it, any other solution ?

Thanks,
SeskaPeel.

So I made it grabbing the 1024768 screen in a 10241024 texture. But this is sloooooow, I want to grab directly in the correct mip map level (256256), and not first in 1024, and then sampling all mip maps down to 11, and then using GL_TEXTURE_LOD_BIAS_EXT. Actually, I’d like to generate a 256*256 mip map level directly from the screen, there must be a way to do this … which one ?

If this first method is slow, it may come from my implementation of the grabbing code, here it is :

Texture creation :

glGenTextures(1, &ScreenRenderTexture) ;
glBindTexture(GL_TEXTURE_2D, ScreenRenderTexture) ;
// w and h are 1024 for the working version, Data is an array of 102410244 unsigned byte
gluBuild2DMipmaps(GL_TEXTURE_2D, GL_RGBA, w, h, GL_RGBA, GL_UNSIGNED_BYTE, &Data[0]) ;
// Trilinear to adjust LOD Bias precisely
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR) ; glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR) ;
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE) ;
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE) ;

Rendering :

// Grab screen
glBindTexture(GL_TEXTURE_2D, ScreenRenderTexture) ;
glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, 1024, 1024) ;
glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP_SGIS, GL_TRUE) ;

// Texture LOD bias
float MaxBias ;
glGetFloatv(GL_MAX_TEXTURE_LOD_BIAS_EXT, &MaxBias) ;
GLfloat RealLODBias = 0.18f * MaxBias ;
glTexEnvf(GL_TEXTURE_FILTER_CONTROL_EXT, GL_TEXTURE_LOD_BIAS_EXT, RealLODBias) ;

// Render ortho poly
glBegin(GL_QUADS) ;
glTexCoord2f(1.0f, 768.0f / 1024.0f) ;
glVertex2i(1, 1) ;

glTexCoord2f(0.0f, 768.0f / 1024.0f) ;
glVertex2i(-1, 1) ;

glTexCoord2f(0.0f, 0.0f) ;
glVertex2i(-1, -1) ;

glTexCoord2f(1.0f, 0.0f) ;
glVertex2i(1, -1) ;
glEnd() ;

Pixel format :

// Pixel format descriptor
PIXELFORMATDESCRIPTOR pfd = {
sizeof(PIXELFORMATDESCRIPTOR), 1,
PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER,
PFD_TYPE_RGBA,
BpP,
(BpP == 32) ? 8 : 5, 0, // Red Bits
(BpP == 32) ? 8 : 6, 0, // Green Bits
(BpP == 32) ? 8 : 5, 0, // Blue Bits
8, 0, // Alpha Bits
0, // No Accumulation Buffer
0, 0, 0, 0, // Accumulation Bits Ignored
24, // Z-Buffer
8, // Stencil Buffer
0, // Auxiliary Buffer
PFD_MAIN_PLANE, // Main Drawing Layer
0, // Reserved
0, 0, 0 // Layer Masks Ignored
} ;

It gives really really neat effects, but frame rates goes from 60-90 down to 20-35

SeskaPeel.

  1. You don’t need gluBuild2DMipMaps(), just one single TexImage2D for level 0 will suffice.

  2. You must specify GL_GENERATE_MIPMAP before glTexImage, else it will not run on ATI hardware.

  3. Yes, this technique is slow and requires a card with good fillrate. But rendering directly into a 1024x1024 pbuffer turned out to be even slower.

Thanks for the two first tips.
What about another method that could produce the same effect ?

SeskaPeel.

I dont know exavly what you what to see, but usually you have marked ‘glow spots’ in the texture or material, and that means you want to render the scene with only those spots and perhaps with special colors. In that case, render to a 256*256 area direcly, and copy that to a texture. ( yep requires an extra render, but the materials should be simple, and hopefully the whole scene shouldnt be glowing)

Mazy, I need full screen for my effect. I’ll post screenshots soon, and I’ll explain the trick.

SeskaPeel.

If you want a texture of 256x256 why not just render your image at 256x256, copy it to your texture, then clear the frame buffer and rerender at 1024x768?

Then apply your effect with the texture you’ve created, which doesn’t need scaling/mip mapping and is considerably quicker to copy.

I suppose it will be even slower if I render everything a second time … I should give it a glance though.
Don’t have time to try, demo is shipping in 1 hour.

Thanks,
SeskaPeel.