New nVidia Drivers! Pbuffers?

New nVidia Drivers for Linux. I’m testing out pbuffers. If someone gets them to work please post here! Thanks.

Originally posted by jackryan:
New nVidia Drivers for Linux. I’m testing out pbuffers. If someone gets them to work please post here! Thanks.

I have an example which works … The are some problems regarding stability and I have not been able to make a single successful call to glXDestroyPbuffer [glXDestroyPbuffer results in a core dump]. I also experience XServer crashes with pbuffers.

I you want I can post an example which works.

What exactly are you using pbuffers for?

– Niels

EDIT:

Just tried with the NVIDIA-1.0-28.02 drivers - they also seem to have the same stability problems … hmmf!

[This message has been edited by Niels Husted Kjaer (edited 03-07-2002).]

Please post an example…thanks!

Originally posted by Niels Husted Kjaer:
[b] I have an example which works … The are some problems regarding stability and I have not been able to make a single successful call to glXDestroyPbuffer [glXDestroyPbuffer results in a core dump]. I also experience XServer crashes with pbuffers.

I you want I can post an example which works.

What exactly are you using pbuffers for?

– Niels

EDIT:

Just tried with the NVIDIA-1.0-28.02 drivers - they also seem to have the same stability problems … hmmf!

[This message has been edited by Niels Husted Kjaer (edited 03-07-2002).][/b]

I did some hacking on a program for creating eps files from OpenGL rendered pixmaps. Instead of a pixmap did I use a pbuffer and it seems to work. Here is the changed main function.

int main(int argc, char **argv)
{
Display *dpy;
GLXContext cx;
GLXPbuffer pbuff;
GLXFBConfigSGIX *fb_conf;
int nr_elements;
int ch_attr =
{ GLX_RENDER_TYPE_SGIX, GLX_RGBA_BIT_SGIX, GLX_DRAWABLE_TYPE_SGIX,
GLX_PBUFFER_BIT_SGIX, GLX_DOUBLEBUFFER, True, GLX_DEPTH_SIZE, 16,
GLX_RED_SIZE, 1, GLX_GREEN_SIZE, 1, GLX_BLUE_SIZE, 1, None
};
int pattribs = { None };
int imageWidth = 400, imageHeight = 400;

dpy = XOpenDisplay(NULL);
if (dpy == NULL)
    fatalError("could not open display");

if (!glXQueryExtension(dpy, NULL, NULL))
    fatalError("X server has no OpenGL GLX extension");

fb_conf =
    glXChooseFBConfigSGIX(dpy, DefaultScreen(dpy), ch_attr,
                          &nr_elements);
if (!fb_conf) {
    perror("glXChooseFBConfigSGIX failed");
    exit(1);
}
printf("

nr_elements is %d
", nr_elements);

pbuff =
    glXCreateGLXPbufferSGIX(dpy, fb_conf[0], imageWidth, imageHeight,
                            pattribs);
if (!pbuff) {
    perror("glXCreateGLXPbufferSGIX failed");
    exit(1);
}

cx = glXCreateContextWithConfigSGIX(dpy, fb_conf[0],
                                    GLX_RGBA_TYPE_SGIX, NULL, True);
if (!cx) {
    perror("glXCreateContextWithConfigSGIX failed");
    exit(1);
}

if (glXMakeCurrent(dpy, pbuff, cx) != True) {
    perror("glXMakeCurrent failed");
    exit(1);
}

contextInit();
makeDinosaur();
glViewport(0, 0, imageWidth, imageHeight);
redraw();

generateEPS("dino.rgb.eps", /* color */ 1, imageWidth, imageHeight);
generateEPS("dino.bw.eps", /* black&white */ 0, imageWidth,
            imageHeight);
return 0;

}

Some information about the extension on SGI machines http://techpubs.sgi.com:80/library/dynaw…okTextView/6865
Manpages http://www.sun.com/software/graphics/OpenGL/manpages/

Here is an example which works on Linux… The example above will not work on Linux as it requires GLX 1.3

Jack: Could you please inform me what you using Pbuffers for? I suspect that we are trying use it for the same thing…

– Niels

#include <stdio.h>
#include <stdlib.h>

#include <X11/Xlib.h>
#include <X11/keysym.h>

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

#define WIN_WIDTH 320
#define WIN_HEIGHT 240

static Display *dpy = NULL;

static GLXPbuffer pbuf = 0;
static GLXContext pbuf_ctx;

static Window win = 0;
static GLXContext win_ctx;

/* ----------------------------------------------------------- /
/
Read Pixels /
/
----------------------------------------------------------- */

static void
readPixels (int x, int y, int width, int height, void buffer) {
/
setup pixel transfer mode */
glPixelStorei (GL_PACK_ALIGNMENT, 1);

glReadBuffer (GL_BACK);
glReadPixels (x, y, width, height, GL_RGB, GL_UNSIGNED_BYTE, buffer);
}

/* ----------------------------------------------------------- /
/
Write Pixels /
/
----------------------------------------------------------- */

static void
writePixels (int x, int y, int width, int height, void buffer) {
/
setup matrix stack */
glMatrixMode (GL_MODELVIEW);
glPushMatrix ();
glLoadIdentity ();

glMatrixMode (GL_PROJECTION);
glPushMatrix ();
glLoadIdentity ();

/* setup state */
glDepthMask (GL_FALSE);
glDisable (GL_DEPTH_TEST);

/* setup pixel transfer mode */
glPixelStorei (GL_UNPACK_ALIGNMENT, 1);

/* draw pixels */
glRasterPos2f (-1.0f, -1.0f);

glDrawBuffer (GL_BACK);
glDrawPixels (width, height, GL_RGB, GL_UNSIGNED_BYTE, buffer);

/* restore state */
glEnable (GL_DEPTH_TEST);
glDepthMask (GL_TRUE);

/* restore matrix stack */
glMatrixMode (GL_PROJECTION);
glPopMatrix ();

glMatrixMode (GL_MODELVIEW);
glPopMatrix ();
}

/* ----------------------------------------------------------- /
/
Redraw Function /
/
----------------------------------------------------------- */

void
redraw (void) {
static unsigned char *buffer = NULL;

/* clear pbuffer */
glXMakeCurrent (dpy, pbuf, pbuf_ctx);

glClearColor (0.0f, 0.0f, 0.0f, 0.0f);
glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

/* setup matrix stack */
glMatrixMode (GL_PROJECTION);
glPushMatrix ();
glLoadIdentity ();

glMatrixMode (GL_MODELVIEW);
glPushMatrix ();
glLoadIdentity ();

/* render white wireframe rectangle */
glColor3f (1.0f, 1.0f, 1.0f);

glBegin (GL_LINE_LOOP);
glVertex2f (-0.75f, 0.75f);
glVertex2f ( 0.75f, 0.75f);
glVertex2f ( 0.75f,-0.75f);
glVertex2f (-0.75f,-0.75f);
glEnd ();

/* restore matrix stack */
glMatrixMode (GL_PROJECTION);
glPopMatrix ();

glMatrixMode (GL_MODELVIEW);
glPopMatrix ();

/* allocate readback buffer? /
if (buffer == NULL)
buffer = (unsigned char )malloc (3WIN_WIDTH
WIN_HEIGHT);

/* readback pbuffer [GLX 1.2] /
/
obs: NVIDIA please add support for GLX 1.3!!! */
glXMakeCurrent (dpy, pbuf, pbuf_ctx);

readPixels (0, 0, WIN_WIDTH, WIN_HEIGHT, buffer);

/* render readback buffer to window */
glXMakeCurrent (dpy, win, win_ctx);

writePixels (0, 0, WIN_WIDTH, WIN_HEIGHT, buffer);

glXSwapBuffers (dpy, win);
glFlush ();
}

/* ----------------------------------------------------------- /
/
Reshape Function /
/
----------------------------------------------------------- */

void
reshape (XConfigureEvent *event) {
float aspect;

/* redefine window viewport */
glXMakeCurrent (dpy, win, win_ctx);

glViewport (0, 0, (GLint)event->width, (GLint)event->height);

/* setup projection matrix */
glMatrixMode (GL_PROJECTION);
glLoadIdentity ();

aspect = 0.5f*(float)event->height/event->width;
glFrustum (-1.0f, 1.0f, -1.0faspect, 1.0faspect, 1.0f, 5000.0f);
}

/* ----------------------------------------------------------- /
/
Keyboard Function /
/
----------------------------------------------------------- */

void
key (XKeyEvent *event) {
KeySym key;

key = XLookupKeysym (event, 0);
switch (key) {
case XK_Escape:
exit (0);
break;
}
}

/* ----------------------------------------------------------- /
/
Window Map Notify Predicate /
/
----------------------------------------------------------- */

static Bool
mapNotifyPredicate (Display *dpy, XEvent *event, XPointer arg) {
return event->type == MapNotify && event->xmap.window == (Window)arg;
}

/* ----------------------------------------------------------- /
/
Main /
/
----------------------------------------------------------- */

static int fb_attrs = {
GLX_RED_SIZE, 1,
GLX_GREEN_SIZE, 1,
GLX_BLUE_SIZE, 1,
GLX_ALPHA_SIZE, 1,
GLX_DEPTH_SIZE, 1,
GLX_DRAWABLE_TYPE, GLX_WINDOW_BIT | GLX_PBUFFER_BIT,
None
};

static int pbuf_attrs = {
GLX_PBUFFER_WIDTH, WIN_WIDTH,
GLX_PBUFFER_HEIGHT, WIN_HEIGHT,
GLX_PRESERVED_CONTENTS, True,
None
};

int
main (int argc, char *argv) {
XSetWindowAttributes win_attrs;
XVisualInfo *vi;
XEvent event;
Colormap cmap;
GLXFBConfig *fb_config;
int request_redraw, no_configs;

/* open display */
dpy = XOpenDisplay (NULL);
if (dpy == NULL) {
fprintf (stderr, "Error: unable to open display.
");
exit (-1);
}

/* query for glx extension */
if (!glXQueryExtension (dpy, NULL, NULL)) {
fprintf (stderr, "Error: display does not support GLX extension.
");
exit (-1);
}

/* choose frame buffer configuration */
fb_config = glXChooseFBConfig (dpy, DefaultScreen (dpy),
fb_attrs, &no_configs);

if (no_configs == 0) {
fprintf (stderr, "Error: no suitable frame buffer configuration found.
");
exit (-1);
}

/* create colormap */
vi = glXGetVisualFromFBConfig (dpy, fb_config[0]);

cmap = XCreateColormap (dpy, RootWindow (dpy,vi->screen),
vi->visual, AllocNone);

/* create window */
win_attrs.border_pixel = 0;
win_attrs.colormap = cmap;
win_attrs.event_mask = ExposureMask | KeyPressMask | StructureNotifyMask;

win = XCreateWindow (dpy, RootWindow (dpy, vi->screen),
0, 0, WIN_WIDTH, WIN_HEIGHT, 0,
vi->depth, InputOutput, vi->visual,
CWBorderPixel | CWColormap | CWEventMask, &win_attrs);

/* create window rendering context */
win_ctx = glXCreateContext (dpy, vi, NULL, True);

/* map window and wait for map notify event */
XMapWindow (dpy, win);

XIfEvent (dpy, &event, mapNotifyPredicate, (XPointer)win);

/* create pbuffer */
pbuf = glXCreatePbuffer (dpy, fb_config[0], pbuf_attrs);

/* create pbuffer rendering context (shared) */
pbuf_ctx = glXCreateContext (dpy, vi, win_ctx, True);

request_redraw = 1;
while (90210) {

/* process pending events */
while (XPending (dpy) > 0) {
  XNextEvent (dpy, &event);
  
  switch (event.type) {
  case ConfigureNotify:

reshape (&event.xconfigure);

request_redraw = 1;
break;

  case Expose:

request_redraw = 1;
break;

  case KeyPress:

key (&event.xkey);
break;
}
}

/* redraw requested? */
if (request_redraw) {
  redraw ();

  request_redraw = 0;
}

}

return 0;
}

The code I posted above is for GLX 1.2 with the SGI extensions. The rest of the source is from Mark Kilgards book and can be found here
ftp://ftp.sgi.com/opengl/OLD/opengl_for_x/

Replace the main function in the pixmap2eps example with the one above.

Niels, I tested your example but got a crash. I think that you should do something like this:

  1. Create a normal OpenGL window and a pbuffer and enable sharing of display lists and textures.
  2. Create a shared texture
  3. Render to the pbuffer and copy the result to the shared texture

[b]

  1. Create a normal OpenGL window and a pbuffer and enable sharing of display lists and textures.
  2. Create a shared texture
  3. Render to the pbuffer and copy the result to the shared texture[/b]

I doubt that copying the pbuffer to a shared texture, and rendering that texture should get rid of the crash - although it may speed up things.

Is it possible to talk you into tracing the crash on your system? I do not get any problems here on this system (Redhat 7.2, kernel 2.4.7-10, NVIDIA-1.0-28.0.2).

– Niels

I traced it before and if I remember right was the crash on the line with glDrawPixels
in writePixels. You do not ask for double buffers but are rendering to the backbuffer. I am not sure that your init code is correct.

If you are satisfied with the format of the window is it better to use the backbuffer than a pbuffer.

I would also like to use pbuffers under Linux, but I am working on a Dell PC with the SuSE distribution. Is it possible to use pbuffers on this, or only on an SGI machine?

Thanks very much for your help.

The code I posted above works for NVidias cards with the driver from NVidias site. You can download the code and test it yourself. The .eps can be viewed with ghostview or kghostview. The postscript files can also be transformed to pdf format with ps2pdf.

I do not know If pbuffers is supported under linux for cards others than NVidia. The code for GLX 1.3 would be different than the above.

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