132001f49Smrg/* 232001f49Smrg * Mesa 3-D graphics library 332001f49Smrg * Version: 7.1 432001f49Smrg * 532001f49Smrg * Copyright (C) 1999-2007 Brian Paul All Rights Reserved. 632001f49Smrg * 732001f49Smrg * Permission is hereby granted, free of charge, to any person obtaining a 832001f49Smrg * copy of this software and associated documentation files (the "Software"), 932001f49Smrg * to deal in the Software without restriction, including without limitation 1032001f49Smrg * the rights to use, copy, modify, merge, publish, distribute, sublicense, 1132001f49Smrg * and/or sell copies of the Software, and to permit persons to whom the 1232001f49Smrg * Software is furnished to do so, subject to the following conditions: 1332001f49Smrg * 1432001f49Smrg * The above copyright notice and this permission notice shall be included 1532001f49Smrg * in all copies or substantial portions of the Software. 1632001f49Smrg * 1732001f49Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 1832001f49Smrg * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 1932001f49Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 2032001f49Smrg * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 2132001f49Smrg * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 2232001f49Smrg * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 2332001f49Smrg */ 2432001f49Smrg 2532001f49Smrg 2632001f49Smrg/* 2732001f49Smrg * Test the GLX_EXT_texture_from_pixmap extension 2832001f49Smrg * Brian Paul 2932001f49Smrg * 19 May 2007 3032001f49Smrg */ 3132001f49Smrg 3232001f49Smrg 3332001f49Smrg#define GL_GLEXT_PROTOTYPES 3432001f49Smrg#define GLX_GLXEXT_PROTOTYPES 3532001f49Smrg#include <GL/gl.h> 3632001f49Smrg#include <GL/glx.h> 3732001f49Smrg#include <X11/keysym.h> 3832001f49Smrg#include <stdio.h> 3932001f49Smrg#include <stdlib.h> 4032001f49Smrg#include <string.h> 4132001f49Smrg#include <unistd.h> 4232001f49Smrg 4332001f49Smrg 4432001f49Smrgstatic float top, bottom; 4532001f49Smrg 4632001f49Smrgstatic PFNGLXBINDTEXIMAGEEXTPROC glXBindTexImageEXT_func = NULL; 4732001f49Smrgstatic PFNGLXRELEASETEXIMAGEEXTPROC glXReleaseTexImageEXT_func = NULL; 4832001f49Smrg 4932001f49Smrg 5032001f49Smrgstatic Display * 5132001f49SmrgOpenDisplay(void) 5232001f49Smrg{ 5332001f49Smrg int screen; 5432001f49Smrg Display *dpy; 5532001f49Smrg const char *ext; 5632001f49Smrg 5732001f49Smrg dpy = XOpenDisplay(NULL); 5832001f49Smrg if (!dpy) { 5932001f49Smrg printf("Couldn't open default display!\n"); 6032001f49Smrg exit(1); 6132001f49Smrg } 6232001f49Smrg 6332001f49Smrg screen = DefaultScreen(dpy); 6432001f49Smrg ext = glXQueryExtensionsString(dpy, screen); 6532001f49Smrg if (!strstr(ext, "GLX_EXT_texture_from_pixmap")) { 6632001f49Smrg fprintf(stderr, "GLX_EXT_texture_from_pixmap not supported.\n"); 6732001f49Smrg exit(1); 6832001f49Smrg } 6932001f49Smrg 7032001f49Smrg glXBindTexImageEXT_func = (PFNGLXBINDTEXIMAGEEXTPROC) 7132001f49Smrg glXGetProcAddress((GLubyte *) "glXBindTexImageEXT"); 7232001f49Smrg glXReleaseTexImageEXT_func = (PFNGLXRELEASETEXIMAGEEXTPROC) 7332001f49Smrg glXGetProcAddress((GLubyte*) "glXReleaseTexImageEXT"); 7432001f49Smrg 7532001f49Smrg if (!glXBindTexImageEXT_func || !glXReleaseTexImageEXT_func) { 7632001f49Smrg fprintf(stderr, "glXGetProcAddress failed!\n"); 7732001f49Smrg exit(1); 7832001f49Smrg } 7932001f49Smrg 8032001f49Smrg return dpy; 8132001f49Smrg} 8232001f49Smrg 8332001f49Smrg 8432001f49Smrgstatic GLXFBConfig 8532001f49SmrgChoosePixmapFBConfig(Display *display) 8632001f49Smrg{ 8732001f49Smrg int screen = DefaultScreen(display); 8832001f49Smrg GLXFBConfig *fbconfigs; 8932001f49Smrg int i, nfbconfigs = 0, value; 9032001f49Smrg 9132001f49Smrg fbconfigs = glXGetFBConfigs(display, screen, &nfbconfigs); 9232001f49Smrg for (i = 0; i < nfbconfigs; i++) { 9332001f49Smrg 9432001f49Smrg glXGetFBConfigAttrib(display, fbconfigs[i], GLX_DRAWABLE_TYPE, &value); 9532001f49Smrg if (!(value & GLX_PIXMAP_BIT)) 9632001f49Smrg continue; 9732001f49Smrg 9832001f49Smrg glXGetFBConfigAttrib(display, fbconfigs[i], 9932001f49Smrg GLX_BIND_TO_TEXTURE_TARGETS_EXT, &value); 10032001f49Smrg if (!(value & GLX_TEXTURE_2D_BIT_EXT)) 10132001f49Smrg continue; 10232001f49Smrg 10332001f49Smrg glXGetFBConfigAttrib(display, fbconfigs[i], 10432001f49Smrg GLX_BIND_TO_TEXTURE_RGBA_EXT, &value); 10532001f49Smrg if (value == False) { 10632001f49Smrg glXGetFBConfigAttrib(display, fbconfigs[i], 10732001f49Smrg GLX_BIND_TO_TEXTURE_RGB_EXT, &value); 10832001f49Smrg if (value == False) 10932001f49Smrg continue; 11032001f49Smrg } 11132001f49Smrg 11232001f49Smrg glXGetFBConfigAttrib(display, fbconfigs[i], 11332001f49Smrg GLX_Y_INVERTED_EXT, &value); 11432001f49Smrg if (value == True) { 11532001f49Smrg top = 0.0f; 11632001f49Smrg bottom = 1.0f; 11732001f49Smrg } 11832001f49Smrg else { 11932001f49Smrg top = 1.0f; 12032001f49Smrg bottom = 0.0f; 12132001f49Smrg } 12232001f49Smrg 12332001f49Smrg break; 12432001f49Smrg } 12532001f49Smrg 12632001f49Smrg if (i == nfbconfigs) { 12732001f49Smrg printf("Unable to find FBconfig for texturing\n"); 12832001f49Smrg exit(1); 12932001f49Smrg } 13032001f49Smrg 13132001f49Smrg return fbconfigs[i]; 13232001f49Smrg} 13332001f49Smrg 13432001f49Smrg 13532001f49Smrgstatic GLXPixmap 13632001f49SmrgCreatePixmap(Display *dpy, GLXFBConfig config, int w, int h, Pixmap *p) 13732001f49Smrg{ 13832001f49Smrg GLXPixmap gp; 13932001f49Smrg const int pixmapAttribs[] = { 14032001f49Smrg GLX_TEXTURE_TARGET_EXT, GLX_TEXTURE_2D_EXT, 14132001f49Smrg GLX_TEXTURE_FORMAT_EXT, GLX_TEXTURE_FORMAT_RGB_EXT, 14232001f49Smrg None 14332001f49Smrg }; 14432001f49Smrg Window root = RootWindow(dpy, 0); 14532001f49Smrg 14632001f49Smrg *p = XCreatePixmap(dpy, root, w, h, 24); 14732001f49Smrg XSync(dpy, 0); 14832001f49Smrg gp = glXCreatePixmap(dpy, config, *p, pixmapAttribs); 14932001f49Smrg XSync(dpy, 0); 15032001f49Smrg 15132001f49Smrg return gp; 15232001f49Smrg} 15332001f49Smrg 15432001f49Smrg 15532001f49Smrgstatic void 15632001f49SmrgDrawPixmapImage(Display *dpy, Pixmap pm, int w, int h) 15732001f49Smrg{ 15832001f49Smrg XGCValues gcvals; 15932001f49Smrg GC gc; 16032001f49Smrg 16132001f49Smrg gcvals.background = 0; 16232001f49Smrg gc = XCreateGC(dpy, pm, GCBackground, &gcvals); 16332001f49Smrg 16432001f49Smrg XSetForeground(dpy, gc, 0x0); 16532001f49Smrg XFillRectangle(dpy, pm, gc, 0, 0, w, h); 16632001f49Smrg 16732001f49Smrg XSetForeground(dpy, gc, 0xff0000); 16832001f49Smrg XFillRectangle(dpy, pm, gc, 0, 0, 50, 50); 16932001f49Smrg 17032001f49Smrg XSetForeground(dpy, gc, 0x00ff00); 17132001f49Smrg XFillRectangle(dpy, pm, gc, w - 50, 0, 50, 50); 17232001f49Smrg 17332001f49Smrg XSetForeground(dpy, gc, 0x0000ff); 17432001f49Smrg XFillRectangle(dpy, pm, gc, 0, h - 50, 50, 50); 17532001f49Smrg 17632001f49Smrg XSetForeground(dpy, gc, 0xffffff); 17732001f49Smrg XFillRectangle(dpy, pm, gc, h - 50, h - 50, 50, 50); 17832001f49Smrg 17932001f49Smrg XSetForeground(dpy, gc, 0xffff00); 18032001f49Smrg XSetLineAttributes(dpy, gc, 3, LineSolid, CapButt, JoinBevel); 18132001f49Smrg XDrawLine(dpy, pm, gc, 0, 0, w, h); 18232001f49Smrg XDrawLine(dpy, pm, gc, 0, h, w, 0); 18332001f49Smrg 18432001f49Smrg XFreeGC(dpy, gc); 18532001f49Smrg} 18632001f49Smrg 18732001f49Smrg 18832001f49Smrgstatic XVisualInfo * 18932001f49SmrgChooseWindowVisual(Display *dpy) 19032001f49Smrg{ 19132001f49Smrg int screen = DefaultScreen(dpy); 19232001f49Smrg XVisualInfo *visinfo; 19332001f49Smrg int attribs[] = { 19432001f49Smrg GLX_RGBA, 19532001f49Smrg GLX_RED_SIZE, 1, 19632001f49Smrg GLX_GREEN_SIZE, 1, 19732001f49Smrg GLX_BLUE_SIZE, 1, 19832001f49Smrg GLX_DOUBLEBUFFER, 19932001f49Smrg None 20032001f49Smrg }; 20132001f49Smrg 20232001f49Smrg visinfo = glXChooseVisual(dpy, screen, attribs); 20332001f49Smrg if (!visinfo) { 20432001f49Smrg printf("Unable to find RGB, double-buffered visual\n"); 20532001f49Smrg exit(1); 20632001f49Smrg } 20732001f49Smrg 20832001f49Smrg return visinfo; 20932001f49Smrg} 21032001f49Smrg 21132001f49Smrg 21232001f49Smrgstatic Window 21332001f49SmrgCreateWindow(Display *dpy, XVisualInfo *visinfo, 21432001f49Smrg int width, int height, const char *name) 21532001f49Smrg{ 21632001f49Smrg int screen = DefaultScreen(dpy); 21732001f49Smrg Window win; 21832001f49Smrg XSetWindowAttributes attr; 21932001f49Smrg unsigned long mask; 22032001f49Smrg Window root; 22132001f49Smrg 22232001f49Smrg root = RootWindow(dpy, screen); 22332001f49Smrg 22432001f49Smrg /* window attributes */ 22532001f49Smrg attr.background_pixel = 0; 22632001f49Smrg attr.border_pixel = 0; 22732001f49Smrg attr.colormap = XCreateColormap(dpy, root, visinfo->visual, AllocNone); 22832001f49Smrg attr.event_mask = StructureNotifyMask | ExposureMask | KeyPressMask; 22932001f49Smrg mask = CWBackPixel | CWBorderPixel | CWColormap | CWEventMask; 23032001f49Smrg 23132001f49Smrg win = XCreateWindow(dpy, root, 0, 0, width, height, 23232001f49Smrg 0, visinfo->depth, InputOutput, 23332001f49Smrg visinfo->visual, mask, &attr); 23432001f49Smrg if (win) { 23532001f49Smrg XSizeHints sizehints; 23632001f49Smrg sizehints.width = width; 23732001f49Smrg sizehints.height = height; 23832001f49Smrg sizehints.flags = USSize; 23932001f49Smrg XSetNormalHints(dpy, win, &sizehints); 24032001f49Smrg XSetStandardProperties(dpy, win, name, name, 24132001f49Smrg None, (char **)NULL, 0, &sizehints); 24232001f49Smrg 24332001f49Smrg XMapWindow(dpy, win); 24432001f49Smrg } 24532001f49Smrg return win; 24632001f49Smrg} 24732001f49Smrg 24832001f49Smrg 24932001f49Smrgstatic void 25032001f49SmrgBindPixmapTexture(Display *dpy, GLXPixmap gp) 25132001f49Smrg{ 25232001f49Smrg GLuint texture; 25332001f49Smrg 25432001f49Smrg glGenTextures(1, &texture); 25532001f49Smrg glBindTexture(GL_TEXTURE_2D, texture); 25632001f49Smrg 25732001f49Smrg glXBindTexImageEXT_func(dpy, gp, GLX_FRONT_LEFT_EXT, NULL); 25832001f49Smrg 25932001f49Smrg glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 26032001f49Smrg glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 26132001f49Smrg 26232001f49Smrg glEnable(GL_TEXTURE_2D); 26332001f49Smrg /* 26432001f49Smrg glXReleaseTexImageEXT_func(display, glxpixmap, GLX_FRONT_LEFT_EXT); 26532001f49Smrg */ 26632001f49Smrg} 26732001f49Smrg 26832001f49Smrg 26932001f49Smrgstatic void 27032001f49SmrgResize(Window win, unsigned int width, unsigned int height) 27132001f49Smrg{ 27232001f49Smrg float sz = 1.5; 27332001f49Smrg glViewport(0, 0, width, height); 27432001f49Smrg glMatrixMode(GL_PROJECTION); 27532001f49Smrg glLoadIdentity(); 27632001f49Smrg glOrtho(-sz, sz, -sz, sz, -1.0, 1.0); 27732001f49Smrg glMatrixMode(GL_MODELVIEW); 27832001f49Smrg} 27932001f49Smrg 28032001f49Smrg 28132001f49Smrgstatic void 28232001f49SmrgRedraw(Display *dpy, Window win, float rot) 28332001f49Smrg{ 28432001f49Smrg glClearColor(0.25, 0.25, 0.25, 0.0); 28532001f49Smrg glClear(GL_COLOR_BUFFER_BIT); 28632001f49Smrg glPushMatrix(); 28732001f49Smrg glRotatef(rot, 0, 0, 1); 28832001f49Smrg glRotatef(2.0 * rot, 1, 0, 0); 28932001f49Smrg 29032001f49Smrg glBegin(GL_QUADS); 29132001f49Smrg glTexCoord2d(0.0, bottom); 29232001f49Smrg glVertex2f(-1, -1); 29332001f49Smrg glTexCoord2d(1.0, bottom); 29432001f49Smrg glVertex2f( 1, -1); 29532001f49Smrg glTexCoord2d(1.0, top); 29632001f49Smrg glVertex2d(1.0, 1.0); 29732001f49Smrg glTexCoord2d(0.0, top); 29832001f49Smrg glVertex2f(-1.0, 1.0); 29932001f49Smrg glEnd(); 30032001f49Smrg 30132001f49Smrg glPopMatrix(); 30232001f49Smrg 30332001f49Smrg glXSwapBuffers(dpy, win); 30432001f49Smrg} 30532001f49Smrg 30632001f49Smrg 30732001f49Smrgstatic void 30832001f49SmrgEventLoop(Display *dpy, Window win) 30932001f49Smrg{ 31032001f49Smrg GLfloat rot = 0.0; 31132001f49Smrg int anim = 0; 31232001f49Smrg 31332001f49Smrg while (1) { 31432001f49Smrg if (!anim || XPending(dpy) > 0) { 31532001f49Smrg XEvent event; 31632001f49Smrg XNextEvent(dpy, &event); 31732001f49Smrg 31832001f49Smrg switch (event.type) { 31932001f49Smrg case Expose: 32032001f49Smrg Redraw(dpy, win, rot); 32132001f49Smrg break; 32232001f49Smrg case ConfigureNotify: 32332001f49Smrg Resize(event.xany.window, 32432001f49Smrg event.xconfigure.width, 32532001f49Smrg event.xconfigure.height); 32632001f49Smrg break; 32732001f49Smrg case KeyPress: 32832001f49Smrg { 32932001f49Smrg char buf[100]; 33032001f49Smrg KeySym keySym; 33132001f49Smrg XComposeStatus stat; 33232001f49Smrg XLookupString(&event.xkey, buf, sizeof(buf), &keySym, &stat); 33332001f49Smrg if (keySym == XK_Escape) { 33432001f49Smrg return; /* exit */ 33532001f49Smrg } 33632001f49Smrg else if (keySym == XK_r) { 33732001f49Smrg rot += 1.0; 33832001f49Smrg Redraw(dpy, win, rot); 33932001f49Smrg } 34032001f49Smrg else if (keySym == XK_a) { 34132001f49Smrg anim = !anim; 34232001f49Smrg } 34332001f49Smrg else if (keySym == XK_R) { 34432001f49Smrg rot -= 1.0; 34532001f49Smrg Redraw(dpy, win, rot); 34632001f49Smrg } 34732001f49Smrg } 34832001f49Smrg break; 34932001f49Smrg default: 35032001f49Smrg ; /*no-op*/ 35132001f49Smrg } 35232001f49Smrg } 35332001f49Smrg else { 35432001f49Smrg /* animate */ 35532001f49Smrg rot += 1.0; 35632001f49Smrg Redraw(dpy, win, rot); 35732001f49Smrg } 35832001f49Smrg } 35932001f49Smrg} 36032001f49Smrg 36132001f49Smrg 36232001f49Smrg 36332001f49Smrgint 36432001f49Smrgmain(int argc, char *argv[]) 36532001f49Smrg{ 36632001f49Smrg Display *dpy; 36732001f49Smrg GLXFBConfig pixmapConfig; 36832001f49Smrg XVisualInfo *windowVis; 36932001f49Smrg GLXPixmap gp; 37032001f49Smrg Window win; 37132001f49Smrg GLXContext ctx; 37232001f49Smrg Pixmap p; 37332001f49Smrg 37432001f49Smrg dpy = OpenDisplay(); 37532001f49Smrg 37632001f49Smrg pixmapConfig = ChoosePixmapFBConfig(dpy); 37732001f49Smrg windowVis = ChooseWindowVisual(dpy); 37832001f49Smrg win = CreateWindow(dpy, windowVis, 500, 500, "Texture From Pixmap"); 37932001f49Smrg 38032001f49Smrg gp = CreatePixmap(dpy, pixmapConfig, 512, 512, &p); 38132001f49Smrg DrawPixmapImage(dpy, p, 512, 512); 38232001f49Smrg 38332001f49Smrg ctx = glXCreateContext(dpy, windowVis, NULL, True); 38432001f49Smrg if (!ctx) { 38532001f49Smrg printf("Couldn't create GLX context\n"); 38632001f49Smrg exit(1); 38732001f49Smrg } 38832001f49Smrg 38932001f49Smrg glXMakeCurrent(dpy, win, ctx); 39032001f49Smrg 39132001f49Smrg BindPixmapTexture(dpy, gp); 39232001f49Smrg 39332001f49Smrg EventLoop(dpy, win); 39432001f49Smrg 39532001f49Smrg return 0; 39632001f49Smrg} 397