blob: 222295670361f6e54c020b93cdfc405dceebcafb [file] [log] [blame]
Brian44653772007-05-19 08:28:41 -06001/*
2 * Mesa 3-D graphics library
3 * Version: 7.1
4 *
5 * Copyright (C) 1999-2007 Brian Paul All Rights Reserved.
6 *
7 * Permission is hereby granted, free of charge, to any person obtaining a
8 * copy of this software and associated documentation files (the "Software"),
9 * to deal in the Software without restriction, including without limitation
10 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
11 * and/or sell copies of the Software, and to permit persons to whom the
12 * Software is furnished to do so, subject to the following conditions:
13 *
14 * The above copyright notice and this permission notice shall be included
15 * in all copies or substantial portions of the Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
18 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
21 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23 */
24
25
26/*
27 * Test the GLX_EXT_texture_from_pixmap extension
28 * Brian Paul
29 * 19 May 2007
30 */
31
32
33#define GL_GLEXT_PROTOTYPES
34#define GLX_GLXEXT_PROTOTYPES
35#include <GL/gl.h>
36#include <GL/glx.h>
37#include <X11/keysym.h>
38#include <stdio.h>
39#include <stdlib.h>
40#include <string.h>
41#include <unistd.h>
42
43
44static Display *
45OpenDisplay(void)
46{
47 int screen;
48 Display *dpy;
49 const char *ext;
50
51 dpy = XOpenDisplay(NULL);
52 if (!dpy) {
53 printf("Couldn't open default display!\n");
54 exit(1);
55 }
56
57 screen = DefaultScreen(dpy);
58 ext = glXQueryExtensionsString(dpy, screen);
59 if (!strstr(ext, "GLX_EXT_texture_from_pixmap")) {
60 printf("GLX_EXT_texture_from_pixmap not supported by GLX\n");
61 exit(1);
62 }
63
64 return dpy;
65}
66
67
68static GLXFBConfig
69ChoosePixmapFBConfig(Display *display)
70{
71 int screen = DefaultScreen(display);
72 GLXFBConfig *fbconfigs;
73 int i, nfbconfigs, value;
74 float top, bottom;
75
76 fbconfigs = glXGetFBConfigs(display, screen, &nfbconfigs);
77 for (i = 0; i < nfbconfigs; i++) {
78
79 glXGetFBConfigAttrib(display, fbconfigs[i], GLX_DRAWABLE_TYPE, &value);
80 if (!(value & GLX_PIXMAP_BIT))
81 continue;
82
83 glXGetFBConfigAttrib(display, fbconfigs[i],
84 GLX_BIND_TO_TEXTURE_TARGETS_EXT, &value);
85 if (!(value & GLX_TEXTURE_2D_BIT_EXT))
86 continue;
87
88 glXGetFBConfigAttrib(display, fbconfigs[i],
89 GLX_BIND_TO_TEXTURE_RGBA_EXT, &value);
90 if (value == False) {
91 glXGetFBConfigAttrib(display, fbconfigs[i],
92 GLX_BIND_TO_TEXTURE_RGB_EXT, &value);
93 if (value == False)
94 continue;
95 }
96
97 glXGetFBConfigAttrib(display, fbconfigs[i],
98 GLX_Y_INVERTED_EXT, &value);
99 if (value == True) {
100 top = 0.0f;
101 bottom = 1.0f;
102 }
103 else {
104 top = 1.0f;
105 bottom = 0.0f;
106 }
107
108 break;
109 }
110
111 if (i == nfbconfigs) {
112 printf("Unable to find FBconfig for texturing\n");
113 exit(1);
114 }
115
116 return fbconfigs[i];
117}
118
119
120static GLXPixmap
121CreatePixmap(Display *dpy, GLXFBConfig config, int w, int h, Pixmap *p)
122{
123 GLXPixmap gp;
124 const int pixmapAttribs[] = {
125 GLX_TEXTURE_TARGET_EXT, GLX_TEXTURE_2D_EXT,
126 GLX_TEXTURE_FORMAT_EXT, GLX_TEXTURE_FORMAT_RGB_EXT,
127 None
128 };
129 Window root = RootWindow(dpy, 0);
130
131 *p = XCreatePixmap(dpy, root, w, h, 24);
132 XSync(dpy, 0);
133 gp = glXCreatePixmap(dpy, config, *p, pixmapAttribs);
134 XSync(dpy, 0);
135
136 return gp;
137}
138
139
140static void
141DrawPixmapImage(Display *dpy, Pixmap pm, int w, int h)
142{
143 XGCValues gcvals;
144 GC gc;
145
146 gcvals.background = 0;
147 gc = XCreateGC(dpy, pm, GCBackground, &gcvals);
148
149 XSetForeground(dpy, gc, 0x0);
150 XFillRectangle(dpy, pm, gc, 0, 0, w, h);
151
152 XSetForeground(dpy, gc, 0xff0000);
153 XFillRectangle(dpy, pm, gc, 0, 0, 50, 50);
154
155 XSetForeground(dpy, gc, 0x00ff00);
156 XFillRectangle(dpy, pm, gc, w - 50, 0, 50, 50);
157
158 XSetForeground(dpy, gc, 0x0000ff);
159 XFillRectangle(dpy, pm, gc, 0, h - 50, 50, 50);
160
161 XSetForeground(dpy, gc, 0xffffff);
162 XFillRectangle(dpy, pm, gc, h - 50, h - 50, 50, 50);
163
164 XSetForeground(dpy, gc, 0xffff00);
165 XSetLineAttributes(dpy, gc, 3, LineSolid, CapButt, JoinBevel);
166 XDrawLine(dpy, pm, gc, 0, 0, w, h);
167 XDrawLine(dpy, pm, gc, 0, h, w, 0);
168
169 XFreeGC(dpy, gc);
170}
171
172
173static XVisualInfo *
174ChooseWindowVisual(Display *dpy)
175{
176 int screen = DefaultScreen(dpy);
177 XVisualInfo *visinfo;
178 int attribs[] = {
179 GLX_RGBA,
180 GLX_RED_SIZE, 1,
181 GLX_GREEN_SIZE, 1,
182 GLX_BLUE_SIZE, 1,
183 GLX_DOUBLEBUFFER,
184 None
185 };
186
187 visinfo = glXChooseVisual(dpy, screen, attribs);
188 if (!visinfo) {
189 printf("Unable to find RGB, double-buffered visual\n");
190 exit(1);
191 }
192
193 return visinfo;
194}
195
196
197static Window
198CreateWindow(Display *dpy, XVisualInfo *visinfo,
199 int width, int height, const char *name)
200{
201 int screen = DefaultScreen(dpy);
202 Window win;
203 XSetWindowAttributes attr;
204 unsigned long mask;
205 Window root;
206
207 root = RootWindow(dpy, screen);
208
209 /* window attributes */
210 attr.background_pixel = 0;
211 attr.border_pixel = 0;
212 attr.colormap = XCreateColormap(dpy, root, visinfo->visual, AllocNone);
213 attr.event_mask = StructureNotifyMask | ExposureMask | KeyPressMask;
214 mask = CWBackPixel | CWBorderPixel | CWColormap | CWEventMask;
215
216 win = XCreateWindow(dpy, root, 0, 0, width, height,
217 0, visinfo->depth, InputOutput,
218 visinfo->visual, mask, &attr);
219 if (win) {
220 XSizeHints sizehints;
221 sizehints.width = width;
222 sizehints.height = height;
223 sizehints.flags = USSize;
224 XSetNormalHints(dpy, win, &sizehints);
225 XSetStandardProperties(dpy, win, name, name,
226 None, (char **)NULL, 0, &sizehints);
227
228 XMapWindow(dpy, win);
229 }
230 return win;
231}
232
233
234static void
235BindPixmapTexture(Display *dpy, GLXPixmap gp)
236{
237 GLuint texture;
238
239 glGenTextures(1, &texture);
240 glBindTexture(GL_TEXTURE_2D, texture);
241
242 glXBindTexImageEXT(dpy, gp, GLX_FRONT_LEFT_EXT, NULL);
243
244 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
245 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
246
247 glEnable(GL_TEXTURE_2D);
248 /*
249 glXReleaseTexImageEXT (display, glxpixmap, GLX_FRONT_LEFT_EXT);
250 */
251}
252
253
254static void
255Resize(Window win, unsigned int width, unsigned int height)
256{
257 float sz = 1.5;
258 glViewport(0, 0, width, height);
259 glMatrixMode(GL_PROJECTION);
260 glLoadIdentity();
261 glOrtho(-sz, sz, -sz, sz, -1.0, 1.0);
262 glMatrixMode(GL_MODELVIEW);
263}
264
265
266static void
267Redraw(Display *dpy, Window win, float rot)
268{
269 glClearColor(0.25, 0.25, 0.25, 0.0);
270 glClear(GL_COLOR_BUFFER_BIT);
271 glPushMatrix();
272 glRotatef(rot, 0, 0, 1);
273 glRotatef(2.0 * rot, 1, 0, 0);
274
275 glBegin(GL_QUADS);
276 glTexCoord2d(0.0, 0.0);
277 glVertex2f(-1, -1);
278 glTexCoord2d(1.0, 0.0);
279 glVertex2f( 1, -1);
280 glTexCoord2d(1.0, 1.0);
281 glVertex2d(1.0, 1.0);
282 glTexCoord2d(0.0, 1.0);
283 glVertex2f(-1.0, 1.0);
284 glEnd();
285
286 glPopMatrix();
287
288 glXSwapBuffers(dpy, win);
289}
290
291
292static void
293EventLoop(Display *dpy, Window win)
294{
295 GLfloat rot = 0.0;
296 int anim = 0;
297
298 while (1) {
299 if (!anim || XPending(dpy) > 0) {
300 XEvent event;
301 XNextEvent(dpy, &event);
302
303 switch (event.type) {
304 case Expose:
305 Redraw(dpy, win, rot);
306 break;
307 case ConfigureNotify:
308 Resize(event.xany.window,
309 event.xconfigure.width,
310 event.xconfigure.height);
311 break;
312 case KeyPress:
313 {
314 char buf[100];
315 KeySym keySym;
316 XComposeStatus stat;
317 XLookupString(&event.xkey, buf, sizeof(buf), &keySym, &stat);
318 if (keySym == XK_Escape) {
319 return; /* exit */
320 }
321 else if (keySym == XK_r) {
322 rot += 1.0;
323 Redraw(dpy, win, rot);
324 }
325 else if (keySym == XK_a) {
326 anim = !anim;
327 }
328 else if (keySym == XK_R) {
329 rot -= 1.0;
330 Redraw(dpy, win, rot);
331 }
332 }
333 break;
334 default:
335 ; /*no-op*/
336 }
337 }
338 else {
339 /* animate */
340 rot += 1.0;
341 Redraw(dpy, win, rot);
342 }
343 }
344}
345
346
347
348int
349main(int argc, char *argv[])
350{
351 Display *dpy;
352 GLXFBConfig pixmapConfig;
353 XVisualInfo *windowVis;
354 GLXPixmap gp;
355 Window win;
356 GLXContext ctx;
357 Pixmap p;
358
359 dpy = OpenDisplay();
360
361 pixmapConfig = ChoosePixmapFBConfig(dpy);
362 windowVis = ChooseWindowVisual(dpy);
363 win = CreateWindow(dpy, windowVis, 500, 500, "Texture From Pixmap");
364
365 gp = CreatePixmap(dpy, pixmapConfig, 512, 512, &p);
366 DrawPixmapImage(dpy, p, 512, 512);
367
368 ctx = glXCreateContext(dpy, windowVis, NULL, True);
369 if (!ctx) {
370 printf("Couldn't create GLX context\n");
371 exit(1);
372 }
373
374 glXMakeCurrent(dpy, win, ctx);
375
376 BindPixmapTexture(dpy, gp);
377
378 EventLoop(dpy, win);
379
380 return 0;
381}