# GLX\_EXT\_texture\_from\_pixmap

**URL:** <https://community.khronos.org/t/glx-ext-texture-from-pixmap/47290>\
**Category:** OpenGL\
**Tags:** linux\
**Created:** [April 28, 2006, 7:02pm UTC](https://community.khronos.org/t/glx-ext-texture-from-pixmap/47290 "2006-04-28T19:02:00Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![bobGL](https://community.khronos.org/letter_avatar_proxy/v4/letter/b/df705f/32.png) [@bobGL](https://community.khronos.org/u/bobGL)\
**Post date:** [April 28, 2006, 7:02pm UTC](https://community.khronos.org/t/glx-ext-texture-from-pixmap/47290/1 "2006-04-28T19:02:00Z")

</div>

Im trying to use this new extension, I found this sweet little example that show how to use it:

```auto
/*
gcc $(pkg-config --cflags --libs cairo) -lGL -o tex-test tex-test.c
*/

#define GLX_GLXEXT_PROTOTYPES 1

#include <assert.h>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "/usr/include/GL/gl.h"
#include "/usr/include/GL/glx.h"
#include "/usr/include/GL/glxext.h"
#include <X11/Xlib.h>
#include <cairo.h>
#include <cairo-xlib.h>

static GLuint TexObj[2];
static GLfloat Angle = 0.0f;
static const int texture_width = 30, texture_height = 77;

static void
make_window(Display *dpy, const char *name,
	    int x, int y, int width, int height,
	    Window *winRet, GLXContext *ctxRet)
{
  static const int attribs[] = {
    GLX_DRAWABLE_TYPE, GLX_WINDOW_BIT,
    GLX_RENDER_TYPE, GLX_RGBA_BIT,
    GLX_RED_SIZE, 1,
    GLX_GREEN_SIZE, 1,
    GLX_BLUE_SIZE, 1,
    GLX_DOUBLEBUFFER, GL_TRUE,
    GLX_DEPTH_SIZE, 1,
    None
  };

  int scrnum;
  XSetWindowAttributes attr;
  unsigned long mask;
  Window root;
  Window win;
  GLXContext ctx;
  XVisualInfo *visinfo;
  GLXFBConfig *fbconfig;
  int num_configs;

  scrnum = DefaultScreen(dpy);
  root = RootWindow(dpy, scrnum);

  fbconfig = glXChooseFBConfig(dpy, scrnum, attribs, &num_configs);
  if (fbconfig == NULL) {
    printf("Error: couldn't get an RGB, Double-buffered visual
");
    exit(1);
  }

  /* window attributes */
  visinfo = glXGetVisualFromFBConfig(dpy, fbconfig[0]);
  if (!visinfo) {
    printf("Error: couldn't get an RGB, Double-buffered visual
");
    exit(1);
  }

  /* window attributes */
  attr.background_pixel = 0;
  attr.border_pixel = 0;
  attr.colormap = XCreateColormap( dpy, root, visinfo->visual, AllocNone);
  attr.event_mask = StructureNotifyMask | ExposureMask | KeyPressMask;
  mask = CWBackPixel | CWBorderPixel | CWColormap | CWEventMask;
  win = XCreateWindow( dpy, root, 0, 0, width, height,
		       0, visinfo->depth, InputOutput,
		       visinfo->visual, mask, &attr );

  /* set hints and properties */
  {
    XSizeHints sizehints;
    sizehints.x = x;
    sizehints.y = y;
    sizehints.width = width;
    sizehints.height = height;
    sizehints.flags = USSize | USPosition;
    XSetNormalHints(dpy, win, &sizehints);
    XSetStandardProperties(dpy, win, name, name,
			   None, (char **)NULL, 0, &sizehints);
  }

  ctx = glXCreateContext( dpy, visinfo, NULL, False );
  if (!ctx) {
    printf("Error: glXCreateContext failed
");
    exit(1);
  }

  XFree(visinfo);

  *winRet = win;
  *ctxRet = ctx;
}

static void draw( void )
{
   glClear( GL_COLOR_BUFFER_BIT );

   glColor3f( 1.0, 1.0, 1.0 );

   /* draw first polygon */
   glPushMatrix();
   glTranslatef( -1.0, 0.0, 0.0 );
   glRotatef( Angle, 0.0, 0.0, 1.0 );
   glBindTexture( GL_TEXTURE_RECTANGLE_ARB, TexObj[0] );
   glBegin( GL_POLYGON );
   glTexCoord2i( 0, 0 ); glVertex2f( -1.0, -1.0 );
   glTexCoord2i( texture_width, 0 ); glVertex2f( 1.0, -1.0 );
   glTexCoord2i( texture_width, texture_height ); glVertex2f( 1.0, 1.0 );
   glTexCoord2i( 0, texture_height ); glVertex2f( -1.0, 1.0 );
   glEnd();
   glPopMatrix();

   /* draw second polygon */
   glPushMatrix();
   glTranslatef( 1.0, 0.0, 0.0 );
   glRotatef( Angle-90.0, 0.0, 1.0, 0.0 );
   glBindTexture( GL_TEXTURE_RECTANGLE_ARB, TexObj[1] );
   glBegin( GL_POLYGON );
   glTexCoord2i( 0, 0 ); glVertex2f( -1.0, -1.0 );
   glTexCoord2i( texture_width, 0 ); glVertex2f( 1.0, -1.0 );
   glTexCoord2i( texture_width, texture_height ); glVertex2f( 1.0, 1.0 );
   glTexCoord2i( 0, texture_height ); glVertex2f( -1.0, 1.0 );
   glEnd();
   glPopMatrix();
}

/* new window size or exposure */
static void reshape( int width, int height )
{
   glViewport(0, 0, (GLint)width, (GLint)height);
   glMatrixMode(GL_PROJECTION);
   glLoadIdentity();
   /* glOrtho( -3.0, 3.0, -3.0, 3.0, -10.0, 10.0 );*/
   glFrustum( -2.0, 2.0, -2.0, 2.0, 6.0, 20.0 );
   glMatrixMode(GL_MODELVIEW);
   glLoadIdentity();
   glTranslatef( 0.0, 0.0, -8.0 );
}

static void draw_texture(cairo_surface_t *surface,
			 const char *text, int width, int height)
{
  cairo_t *cr;
  cairo_pattern_t *gradient;

  cr = cairo_create(surface);

  gradient = cairo_pattern_create_linear(width / 4, 0,
					 3 * width / 4, height);
  cairo_pattern_add_color_stop_rgb(gradient, 0, 0, 0, 0);
  cairo_pattern_add_color_stop_rgb(gradient, 1, 0.2, 0.2, 0.5);
  cairo_set_source(cr, gradient);
  cairo_pattern_destroy(gradient);
  cairo_paint(cr);
  cairo_set_source_rgb(cr, 1, 0, 0);
  cairo_move_to(cr, 0, 0);
  cairo_line_to(cr, width, 0);
  cairo_line_to(cr, width, height);
  cairo_line_to(cr, 0, height);
  cairo_close_path(cr);
  cairo_stroke(cr);
  cairo_move_to(cr, width / 10, height / 2);
  cairo_set_font_size (cr, width / 3);
  cairo_select_font_face (cr, "sans",
			  CAIRO_FONT_SLANT_NORMAL,
			  CAIRO_FONT_WEIGHT_NORMAL);
  cairo_show_text(cr, text);
  cairo_destroy(cr);
}

static void create_image_texture(GLuint name, const char *text)
{
  GLuint tex[texture_width * texture_height];
  cairo_surface_t *surface;

  glBindTexture( GL_TEXTURE_RECTANGLE_ARB, name );
  assert(glIsTexture(name));

  surface = cairo_image_surface_create_for_data ((unsigned char *) tex,
						 CAIRO_FORMAT_ARGB32,
						 texture_width,
						 texture_height,
						 texture_width * 4);
  draw_texture(surface, text, texture_width, texture_height);
  glTexImage2D( GL_TEXTURE_RECTANGLE_ARB, 0, 3,
		texture_width, texture_height, 0,
		GL_BGRA, GL_UNSIGNED_BYTE, tex );
  glTexParameteri( GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
  glTexParameteri( GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
  glTexParameteri( GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_S, GL_REPEAT );
  glTexParameteri( GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_T, GL_REPEAT );
  cairo_surface_destroy(surface);
}

static void create_pixmap_texture(Display *dpy, Window win,
				  GLuint name, const char *text)
{
  static const int attribs[] = {
    //GLX_DRAWABLE_TYPE, GLX_PIXMAP_BIT,
    GLX_RENDER_TYPE, GLX_RGBA_BIT,
    GLX_RED_SIZE, 1,
    GLX_GREEN_SIZE, 1,
    GLX_BLUE_SIZE, 1,
    GLX_DEPTH_SIZE, 1,
#if 0
    GLX_BIND_TO_TEXTURE_TARGETS_EXT, GLX_TEXTURE_2D_BIT_EXT,
    GLX_BIND_TO_TEXTURE_RGBA_EXT, TRUE
#endif

    None
  };

  static const int pixmap_attribs[] = {
#if 0
    GLX_TEXTURE_TARGET_ARB, GLX_TEXTURE_2D_EXT,
#endif
    None
  };

  cairo_surface_t *surface;
  GLXPixmap glxpixmap;
  Pixmap pixmap;
  XVisualInfo *visinfo;
  GLXFBConfig *fbconfig;
  int num_configs;
  int scrnum;
  Bool status;

  glBindTexture( GL_TEXTURE_RECTANGLE_ARB, name );
  assert(glIsTexture(name));

  scrnum = DefaultScreen(dpy);
  fbconfig = glXChooseFBConfig(dpy, scrnum, attribs, &num_configs);
  if (fbconfig == NULL) {
    printf("Error: couldn't get an RGB, Double-buffered fb config
");
    exit(1);
  }

  /* window attributes */
  visinfo = glXGetVisualFromFBConfig(dpy, fbconfig[0]);

  if (!visinfo) {
    printf("Error: couldn't get an RGB, Double-buffered visual
");
    exit(1);
  }

  pixmap = XCreatePixmap(dpy, win, texture_width, texture_height, 24);

  surface = cairo_xlib_surface_create (dpy, pixmap, visinfo->visual,
				       texture_width, texture_height);

  draw_texture(surface, text, texture_width, texture_height);

  glxpixmap = glXCreatePixmap (dpy, fbconfig[0], pixmap, pixmap_attribs);
  status = glXBindTexImageEXT (dpy, glxpixmap, GLX_FRONT_LEFT_EXT, NULL);
  //if (status != GL_TRUE) {
  // printf("Error: couldn't bind pixmap to texture
");
  // exit(1);
  //}
    
  glTexParameteri( GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
  glTexParameteri( GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
  glTexParameteri( GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_S, GL_REPEAT );
  glTexParameteri( GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_T, GL_REPEAT );
  cairo_surface_destroy(surface);
}

static void init(Display *dpy, Window win)
{
   glDisable( GL_DITHER );

   /* Setup texturing */
   glEnable( GL_TEXTURE_RECTANGLE_ARB );
   glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL );
   glHint( GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST );

   /* generate texture object IDs */
   glGenTextures( 2, TexObj );

#if 0
   //create_image_texture(TexObj[0], "A");
   //create_image_texture(TexObj[1], "B");
#else
   create_pixmap_texture(dpy, win, TexObj[0], "OKI");
   create_pixmap_texture(dpy, win, TexObj[1], "DOKI");
#endif
}

static void
event_loop(Display *dpy, Window win)
{
   while (1) {
      while (XPending(dpy) > 0) {
         XEvent event;
         XNextEvent(dpy, &event);
         switch (event.type) {
	 case Expose:
            /* we'll redraw below */
	    break;
	 case ConfigureNotify:
	    reshape(event.xconfigure.width, event.xconfigure.height);
	 }
      }

      draw();
      glXSwapBuffers(dpy, win);
      Angle += 0.05;
   }
}

int main( int argc, char *argv[] )
{
   Display *dpy;
   Window win;
   GLXContext ctx;

   dpy = XOpenDisplay(NULL);
   if (!dpy) {
      printf("Error: couldn't open display %s
", getenv("DISPLAY"));
      return -1;
   }

   make_window(dpy, "tex-test", 0, 0, 300, 300, &win, &ctx);
   XMapWindow(dpy, win);
   glXMakeCurrent(dpy, win, ctx);

   //printf("GL_RENDERER = %s
", (char *) glGetString(GL_RENDERER));
   //printf("GL_VERSION = %s
", (char *) glGetString(GL_VERSION));
   //printf("GL_VENDOR = %s
", (char *) glGetString(GL_VENDOR));
   //printf("GL_EXTENSIONS = %s
", (char *) glGetString(GL_EXTENSIONS));

   init(dpy, win);
   event_loop(dpy, win);

   glXDestroyContext(dpy, ctx);
   XDestroyWindow(dpy, win);
   XCloseDisplay(dpy);

   return 0;
}

```

I can compile it fine but when I run it I got the following error (runtime):

X Error of failed request: GLXUnsupportedPrivateRequest  
Major opcode of failed request: 145 (GLX)  
Minor opcode of failed request: 16 (X\_GLXVendorPrivate)  
Serial number of failed request: 65  
Current serial number in output stream: 68

After some digging I found that the problem comes from this call:

glXBindTexImageEXT

Is there a way to fix this problem? I even recompile MESA from CVS to make sure… still the same problem…

Someone have an idea?

Tks,

---

<div class="post-metadata">

**Author:** ![sijuober](https://community.khronos.org/user_avatar/community.khronos.org/sijuober/32/4064_2.png) [@sijuober](https://community.khronos.org/u/sijuober)\
**Post date:** [April 29, 2006, 12:52am UTC](https://community.khronos.org/t/glx-ext-texture-from-pixmap/47290/2 "2006-04-29T00:52:00Z")

</div>

Are you sure you have a recent XServer which supports this extension?

---

<div class="post-metadata">

**Author:** ![bobGL](https://community.khronos.org/letter_avatar_proxy/v4/letter/b/df705f/32.png) [@bobGL](https://community.khronos.org/u/bobGL)\
**Post date:** [April 29, 2006, 4:05am UTC](https://community.khronos.org/t/glx-ext-texture-from-pixmap/47290/3 "2006-04-29T04:05:00Z")

</div>

Good question, Im running:

Display 0:0 [The [X.Org](http://X.Org) Foundation 11.0 70000000]

That’s the latest one…

---

<div class="post-metadata">

**Author:** ![PkK](https://community.khronos.org/letter_avatar_proxy/v4/letter/p/ecb155/32.png) [@PkK](https://community.khronos.org/u/PkK)\
**Post date:** [April 29, 2006, 4:12am UTC](https://community.khronos.org/t/glx-ext-texture-from-pixmap/47290/4 "2006-04-29T04:12:00Z")

</div>

Just use “glxinfo”. It lists all supported extensions.

Philipp

---

<div class="post-metadata">

**Author:** ![bobGL](https://community.khronos.org/letter_avatar_proxy/v4/letter/b/df705f/32.png) [@bobGL](https://community.khronos.org/u/bobGL)\
**Post date:** [April 29, 2006, 4:17am UTC](https://community.khronos.org/t/glx-ext-texture-from-pixmap/47290/5 "2006-04-29T04:17:00Z")

</div>

When I do glxinfo, I cannot see GLX\_EXT\_texture\_from\_pixmap, but if I use:

DISPLAY=:0 LD\_LIBRARY\_PATH=/usr/lib/ glxinfo

I can see it in the GLX extensions, and when I run my test prog I use:

DISPLAY=:0 LD\_LIBRARY\_PATH=/usr/lib/ ./tex-test

Same thing happen:

X Error of failed request: GLXUnsupportedPrivateRequest  
Major opcode of failed request: 145 (GLX)  
Minor opcode of failed request: 16 (X\_GLXVendorPrivate)  
Serial number of failed request: 65  
Current serial number in output stream: 68

---

<div class="post-metadata">

**Author:** ![sijuober](https://community.khronos.org/user_avatar/community.khronos.org/sijuober/32/4064_2.png) [@sijuober](https://community.khronos.org/u/sijuober)\
**Post date:** [April 30, 2006, 1:59pm UTC](https://community.khronos.org/t/glx-ext-texture-from-pixmap/47290/6 "2006-04-30T13:59:00Z")

</div>

It don’t seems that your XServer has this extension. If you call glxinfo like the way you do, I think it uses the extensions from the recompiled Mesa Library. I think you will also have to recompile your XServer (fetching the newest from cvs which has this extension).

---

<div class="post-metadata">

**Author:** ![system](https://community.khronos.org/uploads/default/original/2X/b/ba89cb49313a0e869198c8be354afde8bcae027e.png) [@system](https://community.khronos.org/u/system)\
**Post date:** [October 19, 2021, 6:44pm UTC](https://community.khronos.org/t/glx-ext-texture-from-pixmap/47290/7 "2021-10-19T18:44:26Z")

</div>

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