Destroying PBuffers?!

Hi,

I have an application that uses pixel buffers for off-screen rendering. The application needs the size of the pbuffer to match the window size. Unfortunately, when resizing the pbuffer - by calling glXDestroyPbuffer () followed by a call to glXCreatePbuffer () - the NVIDIA drivers craches the Xserver.

The application run on a NVIDIA GeForce 4 Ti 4600 with the 1.0-29.60 drivers, P4 with Red Hat 7.3 [2.4.18-3custom kernel]

Any one had luck with destroying pbuffers with preserved contents?

– Niels

Hi Niels,

have you tried destroying and re-creating the associated rendering context as well?

Andy

The entire XServer restarts whenever I invoke glXDestroyPbuffer. I’m not reaaly sure that it make that much sense to destroy the rendering context before destroying the pbuffer. I would anyhow like to preserve the rendering context as this context is shared with a window in my application.

– Niels

OK, I’ve just tried it out: destroying and re-creating a pbuffer works fine in my application, even without destroying the associated context. (BTW, I’m using the same NVIDIA drivers.)

Hi,

Could you send me a (minimal) example where this works… I’ve been playing with my code and I can’t get it to work. Have tried this on serveral cards (NV15, NV17, NV20, and NV25) as serveral different drivers…

– Niels

Hi Niels,

this is a simple example program. It just copies a sub-image from the pbuffer into a texture. Every time the window is resized, the pbuffer will be destroyed and re-created with the same size as the window.

Hope it helps!

#include <GL/glut.h>
#include <GL/glx.h>

int sbAttrib = { GLX_DOUBLEBUFFER, 0,
GLX_RED_SIZE, 8,
GLX_GREEN_SIZE, 8,
GLX_BLUE_SIZE, 8,
None };

int pbAttrib = { GLX_PBUFFER_WIDTH, 100,
GLX_PBUFFER_HEIGHT, 100,
GLX_PRESERVED_CONTENTS, True,
None };

Display *dpy;
GLXFBConfig *fbc;
GLXPbuffer pbuf;
GLXDrawable currdraw;
GLXContext currctx, pbufctx;
GLuint texture;

void init()
{
int i, j, c, n;
GLubyte texImage[64][64][4];

// Create a texture

glClearColor(0.5, 0.5, 0.5, 0.0);
glEnable(GL_TEXTURE_2D);
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_2D, texture);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
for (i=0; i<64; i++) {
for (j=0; j<64; j++) {
c = ((((i&0x8)==0)^((j&0x8))==0))*255;
texImage[i][j][0] = (GLubyte) c;
texImage[i][j][1] = (GLubyte) c;
texImage[i][j][2] = (GLubyte) c;
texImage[i][j][3] = (GLubyte) 255;
}
}
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 64, 64, 0, GL_RGBA, GL_UNSIGNED_BYTE, texImage);

// Create the pbuffer
// (Texture objects are shared between the two contexts)

dpy = glXGetCurrentDisplay();
currctx = glXGetCurrentContext();
currdraw = glXGetCurrentDrawable();

fbc = glXChooseFBConfig(dpy, DefaultScreen(dpy), sbAttrib, &n);
pbuf = glXCreatePbuffer(dpy, fbc[0], pbAttrib);
pbufctx = glXCreateNewContext(dpy, fbc[0], GLX_RGBA_TYPE, currctx, True);
}

void paint()
{
glXMakeCurrent(dpy, pbuf, pbufctx);
glClearColor(1.0, 0.0, 0.0, 0.0);
glClear(GL_COLOR_BUFFER_BIT);
glBindTexture(GL_TEXTURE_2D, texture);
glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 20, 20, 0, 0, 30, 30);

glXMakeCurrent(dpy, currdraw, currctx);
glClear(GL_COLOR_BUFFER_BIT);
glEnable(GL_TEXTURE_2D);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
glBindTexture(GL_TEXTURE_2D, texture);
glBegin(GL_QUADS);
glTexCoord2f(0.0, 0.0); glVertex2f(-5.0, -5.0);
glTexCoord2f(1.0, 0.0); glVertex2f(5.0, -5.0);
glTexCoord2f(1.0, 1.0); glVertex2f(5.0, 5.0);
glTexCoord2f(0.0, 1.0); glVertex2f(-5.0, 5.0);
glEnd();
glDisable(GL_TEXTURE_2D);

glFlush();
}

void reshape(int w, int h)
{
glViewport(0, 0, (GLsizei)w, (GLsizei)h);

glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(-10.0, 10.0, -10.0, 10.0);

glMatrixMode(GL_MODELVIEW);
glLoadIdentity();

// Now destroy the pbuffer and create a new one

pbAttrib[1] = w;
pbAttrib[3] = h;
glXDestroyPbuffer(dpy, pbuf);
pbuf = glXCreatePbuffer(dpy, fbc[0], pbAttrib);
}

int main( int argc, char **argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
glutInitWindowSize(500, 500);
glutInitWindowPosition(100, 100);
glutCreateWindow(“PBuffer Test”);

init();

glutDisplayFunc(paint);
glutReshapeFunc(reshape);
glutMainLoop();

return 1;
}

[This message has been edited by andy1 (edited 06-04-2002).]

Hi,

I’ll give it a try tonight. I’ll drop a line to let you know how it went. Thanks once again.

– Niels

Hi,

You example works - I still haven’t had the time to verify what difference there is between you code and mine.

– Niels

This topic was automatically closed 183 days after the last reply. New replies are no longer allowed.