VBOs, finally...

hi folks,

<some> time ago i posted a topic concerning VBOs in linux, because i couldn’t get them running. i did
not get a helping answer, so i dropped the topic and used display lists/vertex arrays as before.

now, i’ve finally found out what the problem was: when creating the GL context, it has to look like this:

Display *dpy;
XVisualInfo *vi;

glXCreateContext(dpy, vi, NULL, GL_TRUE);

the last parameter has to be GL_TRUE, otherwise it doesn’t work. according to the manual page, this parameter
“Specifies whether rendering is to be done with a direct connection to the graphics system if possible (True) or through the X server (False).”
small change, big effect…so- to whom it concerns, here’s a small snippet which uses VBOs. take it compile it, have fun, it’s free.

 #include<stdio.h>
 #include<stdlib.h>
 #include<math.h>
 #include<X11/Xlib.h>
 #include<GL/gl.h>
 #include<GL/glx.h>
 #include<GL/glext.h>
 #include<GL/glu.h>
 
Display			*dpy	= XOpenDisplay(NULL);
Window			root	= DefaultRootWindow(dpy), win;
int			att[]	= { GLX_RGBA, GLX_DEPTH_SIZE, 24, GLX_DOUBLEBUFFER, true, None };
XVisualInfo		*vi	= glXChooseVisual(dpy, 0, att);
Colormap		cmap	= XCreateColormap(dpy, root, vi->visual, AllocNone);
GLXContext		glc	= glXCreateContext(dpy, vi, NULL, GL_TRUE);
XWindowAttributes	gwa;

#define 		GL_ARRAY_BUFFER_ARB 		0x8892
#define 		GL_STATIC_DRAW_ARB 		0x88E4

unsigned int 		VBOid[2] = { 0, 0 };

typedef void (APIENTRY * PFNGLBINDBUFFERARBPROC)    (GLenum, GLuint);
typedef void (APIENTRY * PFNGLDELETEBUFFERSARBPROC) (GLsizei, const GLuint *);
typedef void (APIENTRY * PFNGLGENBUFFERSARBPROC)    (GLsizei, GLuint *);
typedef void (APIENTRY * PFNGLBUFFERDATAARBPROC)    (GLenum, int, const GLvoid *, GLenum);

PFNGLGENBUFFERSARBPROC 		glGenBuffersARB = NULL;      
PFNGLBINDBUFFERARBPROC 		glBindBufferARB = NULL;      
PFNGLBUFFERDATAARBPROC 		glBufferDataARB = NULL;      
PFNGLDELETEBUFFERSARBPROC	glDeleteBuffersARB = NULL;

//////////////////////////////////////////////////////////////////////////////////////////
//					EXPOSE FUNC					//
//////////////////////////////////////////////////////////////////////////////////////////
void ExposeFunc() {
 XGetWindowAttributes(dpy, win, &gwa);			// ADJUST VIEWPORT
 glViewport(0, 0, gwa.width, gwa.height);		// TO WINDOW SIZE
 
 glClearColor(0.0, 0.0, 0.2, 1.0); 			// SET CLEAR COLOR
 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);	// CLEAR BUFFERS

 glMatrixMode(GL_PROJECTION);				//
 glLoadIdentity();					// ORTHOGONAL PROJECTION
 glOrtho(-2., 2., -2., 2., 1., 100.);			//

 glMatrixMode(GL_MODELVIEW);				//
 glLoadIdentity();					// VIEW DIRECTION : -Z
 gluLookAt(0., 0., 50., 0., 0., 0., 0., 1., 0.);	//

 glBindBufferARB(GL_ARRAY_BUFFER_ARB, VBOid[0] ); 	// BIND VERTEX BUFFER
 glVertexPointer( 3, GL_FLOAT, 0, (char *) NULL );	// SETUP VERTEX POINTER

 glBindBufferARB(GL_ARRAY_BUFFER_ARB, VBOid[1] ); 	// BIND COLOR BUFFER
 glColorPointer( 3, GL_FLOAT, 0, (char *) NULL );	// SETUP COLOR POINTER

 glDrawArrays(GL_QUADS, 0, 4);				// DRAW QUAD WITH 4 VERTICES
   
 glXSwapBuffers(dpy, (GLXDrawable)win); }		// SWAP BUFFERS
//////////////////////////////////////////////////////////////////////////////////////////
//					INIT VBO					//
//////////////////////////////////////////////////////////////////////////////////////////
void InitVBO() {
 float	vert[][3] = { {-1., -1., 0.} , {1., -1., 0.} , {1., 1., 0.} , {-1., 1., 0.} };
 float	col[][3]  = { { 1.,  0., 0.} , {0.,  1., 0.} , {1., 1., 0.} , { 1., 1., 1.} };

 glGenBuffersARB    = (PFNGLGENBUFFERSARBPROC) glXGetProcAddressARB((const GLubyte*)"glGenBuffersARB");
 glBindBufferARB    = (PFNGLBINDBUFFERARBPROC) glXGetProcAddressARB((const GLubyte*)"glBindBufferARB");
 glBufferDataARB    = (PFNGLBUFFERDATAARBPROC) glXGetProcAddressARB((const GLubyte*)"glBufferDataARB");
 glDeleteBuffersARB = (PFNGLDELETEBUFFERSARBPROC) glXGetProcAddressARB((const GLubyte*)"glDeleteBuffersARB");

 if(glGenBuffersARB == NULL)
	printf("	VBO extension not available
");

 glGenBuffersARB(2, VBOid); 
 printf("
	vertex buffer id : %8i
	color buffer id  : %8i

", VBOid[0], VBOid[1]); 

 glBindBufferARB(GL_ARRAY_BUFFER_ARB, VBOid[0] ); 
 glBufferDataARB( GL_ARRAY_BUFFER_ARB, 4*3*sizeof(float), vert, GL_STATIC_DRAW_ARB);

 glBindBufferARB(GL_ARRAY_BUFFER_ARB, VBOid[1] ); 
 glBufferDataARB( GL_ARRAY_BUFFER_ARB, 4*3*sizeof(float), col, GL_STATIC_DRAW_ARB);

 glEnableClientState(GL_COLOR_ARRAY);
 glEnableClientState(GL_VERTEX_ARRAY); }
//////////////////////////////////////////////////////////////////////////////////////////
//											//
//					MAIN PROG					//
//											//
//////////////////////////////////////////////////////////////////////////////////////////
void main(int argc, char *argv[]) {
 XSetWindowAttributes	swa;
 unsigned long		cmask = CWColormap | CWBorderPixel | CWEventMask;
 XEvent			xev;
 
 swa.colormap     = cmap;
 swa.event_mask   = ExposureMask | ButtonPressMask;
 swa.border_pixel = 0;
 win  = XCreateWindow(dpy, root, 0, 0, 500, 500, 0, vi->depth, 1, vi->visual, cmask, &swa);

 glXMakeCurrent (dpy, win, glc);
 XMapWindow(dpy, win);
 XStoreName(dpy, win, "VBO TEST");

 InitVBO();

 while(true) {
	XNextEvent(dpy, &xev);

	if(xev.type == Expose) {		// EXPOSE EVENT
		ExposeFunc(); }

	else if(xev.type == ButtonPress) {	// EXIT ON MOUSE BUTTON CLICK
		glDeleteBuffersARB(2, VBOid);
		exit(0); } } }
//
// 	 gcc -O3 -o vbo vbo.cc -lGL -lGLU -lX11 -lm -lstdc++
//  
  

I’d like to give a good answer to why direct rendering is necessary for VBO to run, but I’m afraid I haven’t. I would have thought that it could have run but with less performance only.

Generally when you do not have direct rendering enabled, one can’t expect any acceleration at all.

I’d like to give a good answer to why direct rendering is necessary for VBO to run, but I’m afraid I haven’t.
well, maybe if you try to think really hard… :smiley:

anyway, two observations:

  1. if direct rendering is not enabled, glGenBuffersARB(2, VBOid) will not modify the contents of VBOid.

  2. if direct rendering is enabled, it works, but not if the app is running over the network. even not if the
    VBO extension is available on the client.

concerning the acceleration- i tried a small prog with and without direct rendering. no difference in frames/s…

What do you explicitly mean with running over the network ? Do you mean an X client connected to a remote X server ? Doing so disables direct rendering but I can’t give much information, I’m so used to do simple single applications.
But as you stippled that direct rendering acceleration, so whether I’m wrong or whether you was meaning another thing.

About the last point (acceleration), I still cannot give any good points but the fact that, without direct rendering, calls generally must go threw one more layer, that might be very very difficult to notice on our recent hardwares.

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