• Advertisement
Sign in to follow this  

pixel buffer problem

This topic is 4348 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi, I have used codesampler's example of pixel buffers to make my own program to render to a texture but I have a problem. What my program does at the moment is select the pBuffer RC, draw a piece of geometry to it, select the windows RC, bind the pBuffer as a texture then texture a quad with the pBuffer. What appears on the screen is a blank background (my windows RC clear colour), and a black square (the quad with the pBuffer texture). The clear colour of the pBuffer is white. What I was expecting was my geometry in the quad. I have called wglShareLists() with the 1st argument as the windows RC and the second as the pBuffer RC. Am I doing something wrong (well, I obviuously am)? Can anyone help me please? Thanks in advance!

Share this post


Link to post
Share on other sites
Advertisement
Your logic sounds correct, but you'll have to post some code in order for me to help you debug it. You said you've used the CodeSampler's example, though, so you must have set something up wrong somewhere.

Share this post


Link to post
Share on other sites
Well this is my initialisation code.

void initPixBuffer(int width)
{
// Texture to render to
glGenTextures(1, &renderTex);
glBindTexture(GL_TEXTURE_2D, renderTex);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, width, 0, GL_RGB, GL_FLOAT, 0);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);

// Check for extensions
if (WGLEW_ARB_pbuffer && WGLEW_ARB_pixel_format && WGLEW_ARB_render_texture)
printf("Ready touse pixel buffers\n");
else
{
printf("No pixel buffer support\n");
exit(1);
}

// Setup pixel buffer
pixBuff.hPBuffer = NULL;
pixBuff.nWidth = width;
pixBuff.nHeight = width;

// Set pixel format for pixel buffer
int pf_attr[] =
{
WGL_SUPPORT_OPENGL_ARB, TRUE, // P-buffer will be used with OpenGL
WGL_DRAW_TO_PBUFFER_ARB, TRUE, // Enable render to p-buffer
WGL_BIND_TO_TEXTURE_RGBA_ARB, TRUE, // P-buffer will be used as a texture
WGL_RED_BITS_ARB, 8, // At least 8 bits for RED channel
WGL_GREEN_BITS_ARB, 8, // At least 8 bits for GREEN channel
WGL_BLUE_BITS_ARB, 8, // At least 8 bits for BLUE channel
WGL_ALPHA_BITS_ARB, 8, // At least 8 bits for ALPHA channel
WGL_DEPTH_BITS_ARB, 16, // At least 16 bits for depth buffer
WGL_DOUBLE_BUFFER_ARB, TRUE, // We don't require double buffering
0 // Zero terminates the list
};

unsigned int count = 0;
int pixelFormat;
wglChoosePixelFormatARB( hDC,(const int*)pf_attr, NULL, 1, &pixelFormat, &count);

if( count == 0 )
{
MessageBox(NULL,"Could not find an acceptable pixel format!",
"ERROR",MB_OK|MB_ICONEXCLAMATION);
exit(-1);
}

// Set to use RGBA
int pb_attr[] =
{
WGL_TEXTURE_FORMAT_ARB, WGL_TEXTURE_RGBA_ARB, // Our p-buffer will have a texture format of RGBA
WGL_TEXTURE_TARGET_ARB, WGL_TEXTURE_2D_ARB, // Of texture target will be GL_TEXTURE_2D
0 // Zero terminates the list
};

pixBuff.hPBuffer = wglCreatePbufferARB( hDC, pixelFormat, pixBuff.nWidth, pixBuff.nHeight, pb_attr );
pixBuff.hDC = wglGetPbufferDCARB( pixBuff.hPBuffer );
pixBuff.hRC = wglCreateContext( pixBuff.hDC );

if( !pixBuff.hPBuffer )
{
MessageBox(NULL,"Could not create the p-buffer",
"ERROR",MB_OK|MB_ICONEXCLAMATION);
exit(-1);
}

int h;
int w;
wglQueryPbufferARB( pixBuff.hPBuffer, WGL_PBUFFER_WIDTH_ARB, &h );
wglQueryPbufferARB( pixBuff.hPBuffer, WGL_PBUFFER_WIDTH_ARB, &w );

if( h != pixBuff.nHeight || w != pixBuff.nWidth )
{
MessageBox(NULL,"The width and height of the created p-buffer don't match the requirements!",
"ERROR",MB_OK|MB_ICONEXCLAMATION);
exit(-1);
}

if( !wglMakeCurrent( pixBuff.hDC, pixBuff.hRC ) )
{
MessageBox(NULL,"Could not make the p-buffer's context current!",
"ERROR",MB_OK|MB_ICONEXCLAMATION);
exit(-1);
}

// Success in creating a pbuffer!
glClearColor( 1.0f, 1.0f, 1.0f, 1.0f );
glEnable(GL_TEXTURE_2D);
glEnable(GL_DEPTH_TEST);

//glViewport(0, 0, width, width); // Reset current Viewport

glMatrixMode(GL_PROJECTION); // Select the projection matrix
glLoadIdentity(); // Reset projection matrix

// Calculate The Aspect Ratio Of The Window
gluPerspective(75.0f,pixBuff.nWidth/pixBuff.nHeight,1.0f,1000.0f);

glMatrixMode(GL_MODELVIEW); // Select Model View matrix
glLoadIdentity(); // Reset Model View matrix

wglShareLists(hRC, pixBuff.hRC);

} // end initPixBuffer()




It's a bit long but I think most of it is the same as codesampler's but I made a few tiny changes. Main change is that I use glew to get to the extensions. The render to texture is also made a lot bigger (1440x1440, for my screen resolution). Finally I have a global for the render texture width instead of a #define.

At the start of my render function I have:

int flag = 0;
wglQueryPbufferARB( pixBuff.hPBuffer, WGL_PBUFFER_LOST_ARB, &flag );

if( flag != 0 )
{
MessageBox(NULL,"The p-buffer was lost!",
"ERROR",MB_OK|MB_ICONEXCLAMATION);
exit(-1);
}

if( !wglMakeCurrent( pixBuff.hDC, pixBuff.hRC ) )
{
MessageBox(NULL,"Could not make the p-buffer's context current!",
"ERROR",MB_OK|MB_ICONEXCLAMATION);
exit(-1);
}

glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
glMatrixMode( GL_MODELVIEW );
glLoadIdentity(); // Reset The Current Modelview Matrix



I then render an object. I then switch to my windows RC like this:

if( !wglMakeCurrent( hDC, hRC ) )
{
MessageBox(NULL,"Could not make the window's context current!",
"ERROR",MB_OK|MB_ICONEXCLAMATION);
exit(-1);
}

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Clear The Screen And The Depth Buffer
// Store projection matrix
glMatrixMode(GL_PROJECTION);
glPushMatrix();

// Set ortho mode
glLoadIdentity(); // Reset projection matrix
glOrtho(0, xRes, 0, yRes, -1, 1); // Set ortho mode

// Store and setup modelview matrix
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glLoadIdentity();

//glUseProgramObjectARB(0);
glActiveTexture(GL_TEXTURE0); // Set active texture unit

glBindTexture( GL_TEXTURE_2D, renderTex );

//glBindTexture(GL_TEXTURE_2D, g_texID[TESTCHAR_TEX]);

if( !wglBindTexImageARB( pixBuff.hPBuffer, WGL_FRONT_LEFT_ARB ) )
{
MessageBox(NULL,"Could not bind p-buffer to render texture!",
"ERROR",MB_OK|MB_ICONEXCLAMATION);
exit(-1);
}

// TEST DRAW
glBegin(GL_TRIANGLE_STRIP);
glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
glNormal3f(0, 0, 1);
glMultiTexCoord2fARB(GL_TEXTURE0_ARB, 0,1);
glVertex3f(200, 500, 0.0f);
glMultiTexCoord2fARB(GL_TEXTURE0_ARB, 0,0);
glVertex3f(200, 200, 0.0f);
glMultiTexCoord2fARB(GL_TEXTURE0_ARB, 1,1);
glVertex3f(500, 500, 0.0f);
glMultiTexCoord2fARB(GL_TEXTURE0_ARB, 1,0);
glVertex3f(500, 200, 0.0f);
glEnd();
//
// Before we forget, we need to make sure that the p-buffer has been
// released from the dynamic "render-to" texture.
//

if( !wglReleaseTexImageARB( pixBuff.hPBuffer, WGL_FRONT_LEFT_ARB ) )
{
MessageBox(NULL,"Could not release p-buffer from render texture!",
"ERROR",MB_OK|MB_ICONEXCLAMATION);
exit(-1);
}

Share this post


Link to post
Share on other sites
From a quick glance at the code, two things look wrong.

First, you set WGL_DOUBLE_BUFFER_ARB to TRUE even though your comment says "We don't require double buffering". If you use double buffering, you will need to call SwapBuffers to bring the back buffer to the front.

Second, does your hardware support the ARB_texture_non_power_of_two extention? If not, a size of 1440x1440 will not work -- you will need to make the texture a power of two size.

Share this post


Link to post
Share on other sites
Aha! You have a good eye! I did set double buffering to TRUE. I wanted to have double buffering since my main window was double buffered. I turned it off and it worked!! Thanks a lot!! All is fine and dandy now!

Share this post


Link to post
Share on other sites
just as a note, you should probably make your textures power of 2 anyways. Not doing so can cause performance issues

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement