// gcc -std=c99 makecurrent.c -o makecurrent -lGL -lGLU -lglut -lm -W -Wall -Wextra -ggdb #include #include #include #include #include #define GL_GLEXT_PROTOTYPES #include #include #include #include static int width = 800; static int height = 400; GLuint tex0; GLuint tex1; GLboolean enableMakeCurrent = GL_TRUE; int pbuffer; static void initTextures(void) { float scratch[32*32*3], *ptr; // tex0: chessboard ptr = scratch; for (int i=0; i<32; ++i) { for (int j=0; j<32; ++j) { int ii = (i>>1)&1; int jj = (j>>1)&1; float val = ii==jj ? 1.0f : 0.0f; ptr[0] = val; ptr[1] = val; ptr[2] = val; ptr += 3; } } glGenTextures(1, &tex0); glBindTexture(GL_TEXTURE_2D, tex0); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 32, 32, 0, GL_RGB, GL_FLOAT, (void*)scratch); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); // tex1: rainbow ptr = scratch; for (int i=0; i<32; ++i) { for (int j=0; j<32; ++j) { ptr[0] = 1.0f*i/32.0f; ptr[1] = 1.0f*j/32.0f; ptr[2] = (32-i-j)/32.0f; ptr += 3; } } glGenTextures(1, &tex1); glBindTexture(GL_TEXTURE_2D, tex1); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 32, 32, 0, GL_RGB, GL_FLOAT, (void*)scratch); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); } static void display(void) { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glActiveTextureARB(GL_TEXTURE0); glEnable(GL_TEXTURE_2D); glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); glBindTexture(GL_TEXTURE_2D, tex0); glBegin(GL_QUADS); glMultiTexCoord2f(GL_TEXTURE0, 0.0, 0.0); glVertex3f(0.0, 0.0, -0.0); glMultiTexCoord2f(GL_TEXTURE0, 1.0, 0.0); glVertex3f(1.0, 0.0, -0.5); glMultiTexCoord2f(GL_TEXTURE0, 1.0, 1.0); glVertex3f(1.0, 1.0, -1.0); glMultiTexCoord2f(GL_TEXTURE0, 0.0, 1.0); glVertex3f(0.0, 1.0, -0.5); glEnd(); if (enableMakeCurrent) { Display *dpy = glXGetCurrentDisplay(); int current_drawable = glXGetCurrentDrawable(); GLXContext context = glXGetCurrentContext(); glXMakeCurrent(dpy, pbuffer, context); // Issue #1: Mesa warning: MakeCurrent: incompatible visuals for context and drawbuffer (pbuffer has no depth or stencil) glColor3f(1.0f, 0.0f, 1.0f); // this is no-op because of the above glXMakeCurrent(dpy, current_drawable, context); // Issue #2: depth buffer is now lost (so is stencil), subsequent rendering fails depth test // because the newly allocated depth buffer is all zeros // (with DRI3 the already drawn image is partially overwritten with noise, DRI2 only looses the non-color buffers) } glBindTexture(GL_TEXTURE_2D, tex1); glBegin(GL_QUADS); glMultiTexCoord2f(GL_TEXTURE0, 0.0, 0.0); glVertex3f(0.0, 0.0, -1.0); glMultiTexCoord2f(GL_TEXTURE0, 1.0, 0.0); glVertex3f(1.0, 0.0, -0.5); glMultiTexCoord2f(GL_TEXTURE0, 1.0, 1.0); glVertex3f(1.0, 1.0, -0.0); glMultiTexCoord2f(GL_TEXTURE0, 0.0, 1.0); glVertex3f(0.0, 1.0, -0.5); glEnd(); glutSwapBuffers(); } static void reshape(int w, int h) { glViewport (0, 0, (GLsizei) w, (GLsizei) h); glMatrixMode(GL_PROJECTION); glLoadIdentity(); glOrtho(0.0, 1.0, 0.0, 1.0, 0.0, 1.0); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); } static void keyboard(unsigned char key, int x, int y) { (void)x; (void)y; if (key == ' ') { enableMakeCurrent = !enableMakeCurrent; printf("MakeCurrent is now %sabled\n", enableMakeCurrent?"en":"dis"); glutPostRedisplay(); } else if (key == 'q' || key == 27 /* ESC */) { exit(0); } } static const int attrib_list[] = { GLX_RED_SIZE, 8, GLX_GREEN_SIZE, 8, GLX_BLUE_SIZE, 8, GLX_ALPHA_SIZE, 8, /*GLX_DEPTH_SIZE, 24, GLX_STENCIL_SIZE, 8,*/ GLX_DOUBLEBUFFER, GL_FALSE, GLX_DRAWABLE_TYPE, GLX_PBUFFER_BIT, GLX_RENDER_TYPE, GLX_RGBA_BIT, 0}; static const int fb_size[] = { GLX_PBUFFER_WIDTH, 512, GLX_PBUFFER_HEIGHT, 512, 0}; static void init(void) { glColor3f(0.0f, 1.0f, 0.0f); glEnable(GL_DEPTH_TEST); initTextures(); Display *dpy = glXGetCurrentDisplay(); int nelements = 0; GLXFBConfig *configs = glXChooseFBConfig(dpy, 0, attrib_list, &nelements); printf("got %d configs\n", nelements); for (int i=0; i