blob: e3516e152299ea7dd8cf3c60c1369be80402c5ab [file] [log] [blame]
Brian Paulb5e4a161999-11-25 17:41:51 +00001/*
2 * Mesa 3-D graphics library
Brian Paul68b38d22004-03-26 14:17:31 +00003 * Version: 6.1
Brian Paulb5e4a161999-11-25 17:41:51 +00004 *
Brian Paul68b38d22004-03-26 14:17:31 +00005 * Copyright (C) 1999-2004 Brian Paul All Rights Reserved.
Brian Paulb5e4a161999-11-25 17:41:51 +00006 *
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 * This program opens two GLX windows, renders into one and uses
28 * glCopyPixels to copy the image from the first window into the
29 * second by means of the GLX 1.3 function glxMakeContextCurrent().
30 * This function works just like the glXMakeCurrentReadSGI() function
31 * in the GLX_SGI_make_current_read extension.
32 */
33
34
35
36#include <GL/gl.h>
37#include <GL/glx.h>
Brian Paul15f7f4e2003-12-05 00:39:48 +000038#include <X11/keysym.h>
Brian Paulb5e4a161999-11-25 17:41:51 +000039#include <stdio.h>
40#include <stdlib.h>
Brian Paul68b38d22004-03-26 14:17:31 +000041#include <string.h>
Brian Paulb5e4a161999-11-25 17:41:51 +000042#include <unistd.h>
43
44
45#ifdef GLX_VERSION_1_3
46
47
48static Display *Dpy;
49static int ScrNum;
50static GLXContext Context;
51static Window Win[2]; /* Win[0] = source, Win[1] = dest */
52static GLint Width[2], Height[2];
53
54static GLfloat Angle = 0.0;
55
Brian Paul15f7f4e2003-12-05 00:39:48 +000056static GLboolean DrawFront = GL_FALSE;
57
Brian Paulb5e4a161999-11-25 17:41:51 +000058
59
60static Window
61CreateWindow(Display *dpy, int scrnum, XVisualInfo *visinfo,
62 int xpos, int ypos, int width, int height,
63 const char *name)
64{
65 Window win;
66 XSetWindowAttributes attr;
67 unsigned long mask;
68 Window root;
69
70 root = RootWindow(dpy, scrnum);
71
72 /* window attributes */
73 attr.background_pixel = 0;
74 attr.border_pixel = 0;
75 attr.colormap = XCreateColormap(dpy, root, visinfo->visual, AllocNone);
76 attr.event_mask = StructureNotifyMask | ExposureMask | KeyPressMask;
77 mask = CWBackPixel | CWBorderPixel | CWColormap | CWEventMask;
78
79 win = XCreateWindow(dpy, root, xpos, ypos, width, height,
80 0, visinfo->depth, InputOutput,
81 visinfo->visual, mask, &attr);
82 if (win) {
83 XSizeHints sizehints;
84 sizehints.x = xpos;
85 sizehints.y = ypos;
86 sizehints.width = width;
87 sizehints.height = height;
88 sizehints.flags = USSize | USPosition;
89 XSetNormalHints(dpy, win, &sizehints);
90 XSetStandardProperties(dpy, win, name, name,
91 None, (char **)NULL, 0, &sizehints);
92
93 XMapWindow(dpy, win);
94 }
95 return win;
96}
97
98
99static void
100Redraw(void)
101{
102 /* make the first window the current one */
103 if (!glXMakeContextCurrent(Dpy, Win[0], Win[0], Context)) {
104 printf("glXMakeContextCurrent failed in Redraw()\n");
105 return;
106 }
107
108 Angle += 1.0;
109
Brian Paul15f7f4e2003-12-05 00:39:48 +0000110 if (DrawFront) {
111 glDrawBuffer(GL_FRONT);
112 glReadBuffer(GL_FRONT);
113 }
114 else {
115 glDrawBuffer(GL_BACK);
116 glReadBuffer(GL_BACK);
117 }
118
Brian Paulb5e4a161999-11-25 17:41:51 +0000119 glViewport(0, 0, Width[0], Height[0]);
120 glMatrixMode(GL_PROJECTION);
121 glLoadIdentity();
122 glOrtho(-1.0, 1.0, -1.0, 1.0, -1.0, 1.0);
123 glMatrixMode(GL_MODELVIEW);
124
125 glShadeModel(GL_FLAT);
126 glClearColor(0.5, 0.5, 0.5, 1.0);
127 glClear(GL_COLOR_BUFFER_BIT);
128
129 /* draw blue quad */
130 glColor3f(0.3, 0.3, 1.0);
131 glPushMatrix();
132 glRotatef(Angle, 0, 0, 1);
133 glBegin(GL_POLYGON);
134 glVertex2f(-0.5, -0.25);
135 glVertex2f( 0.5, -0.25);
136 glVertex2f( 0.5, 0.25);
137 glVertex2f(-0.5, 0.25);
138 glEnd();
139 glPopMatrix();
140
Brian Paul15f7f4e2003-12-05 00:39:48 +0000141 if (DrawFront)
142 glFinish();
143 else
144 glXSwapBuffers(Dpy, Win[0]);
Brian Paulb5e4a161999-11-25 17:41:51 +0000145
146
147 /* copy image from window 0 to window 1 */
148 if (!glXMakeContextCurrent(Dpy, Win[1], Win[0], Context)) {
149 printf("glXMakeContextCurrent failed in Redraw()\n");
150 return;
151 }
152
153 /* raster pos setup */
154 glViewport(0, 0, Width[1], Height[1]);
155 glPushMatrix();
156 glLoadIdentity();
157 glMatrixMode(GL_PROJECTION);
158 glPushMatrix();
159 glLoadIdentity();
160 glOrtho(-1, 1, -1, 1, -1, 1);
161 glRasterPos2f(-1, -1);
162
163 /* copy the image between windows */
Brian Paulb5e4a161999-11-25 17:41:51 +0000164 glCopyPixels(0, 0, Width[0], Height[0], GL_COLOR);
Brian Paulb5e4a161999-11-25 17:41:51 +0000165
166 glPopMatrix();
167 glMatrixMode(GL_MODELVIEW);
168 glPopMatrix();
Brian Paul15f7f4e2003-12-05 00:39:48 +0000169
170 if (DrawFront)
171 glFinish();
172 else
173 glXSwapBuffers(Dpy, Win[1]);
Brian Paulb5e4a161999-11-25 17:41:51 +0000174}
175
176
177
178static void
179Resize(Window win, unsigned int width, unsigned int height)
180{
181 int i;
182 if (win == Win[0]) {
183 i = 0;
184 }
185 else {
186 i = 1;
187 }
188 Width[i] = width;
189 Height[i] = height;
190 if (!glXMakeCurrent(Dpy, Win[i], Context)) {
191 printf("glXMakeCurrent failed in Resize()\n");
192 return;
193 }
194}
195
196
197
198static void
199EventLoop(void)
200{
201 XEvent event;
202 while (1) {
203 if (XPending(Dpy) > 0) {
204 XNextEvent( Dpy, &event );
205 switch (event.type) {
206 case Expose:
207 Redraw();
208 break;
209 case ConfigureNotify:
210 Resize(event.xany.window, event.xconfigure.width, event.xconfigure.height);
211 break;
212 case KeyPress:
Brian Paul15f7f4e2003-12-05 00:39:48 +0000213 {
214 char buf[100];
215 KeySym keySym;
216 XComposeStatus stat;
217 XLookupString(&event.xkey, buf, sizeof(buf), &keySym, &stat);
218 if (keySym == XK_Escape) {
219 /* exit */
220 return;
221 }
222 else if (buf[0] == 'f') {
223 DrawFront = !DrawFront;
224 printf("Drawing to %s buffer\n",
225 DrawFront ? "GL_FRONT" : "GL_BACK");
226 }
227 }
228 break;
Brian Paulb5e4a161999-11-25 17:41:51 +0000229 default:
230 /*no-op*/ ;
231 }
232 }
233 else {
234 /* animate */
235 Redraw();
236 }
237 }
238}
239
240
241static void
242Init(void)
243{
244 XVisualInfo *visinfo;
245 int attrib[] = { GLX_RGBA,
246 GLX_RED_SIZE, 1,
247 GLX_GREEN_SIZE, 1,
248 GLX_BLUE_SIZE, 1,
249 GLX_DOUBLEBUFFER,
250 None };
Brian Paul68b38d22004-03-26 14:17:31 +0000251 int major, minor;
Brian Paulb5e4a161999-11-25 17:41:51 +0000252
253 Dpy = XOpenDisplay(NULL);
254 if (!Dpy) {
255 printf("Couldn't open default display!\n");
256 exit(1);
257 }
258
259 ScrNum = DefaultScreen(Dpy);
260
Brian Paul68b38d22004-03-26 14:17:31 +0000261 glXQueryVersion(Dpy, &major, &minor);
262 if (major * 100 + minor < 103) {
263 fprintf(stderr, "Sorry, this program requires GLX 1.3\n");
264 exit(1);
265 }
266
Brian Paulb5e4a161999-11-25 17:41:51 +0000267 visinfo = glXChooseVisual(Dpy, ScrNum, attrib);
268 if (!visinfo) {
269 printf("Unable to find RGB, double-buffered visual\n");
270 exit(1);
271 }
272
273 Context = glXCreateContext(Dpy, visinfo, NULL, True);
274 if (!Context) {
275 printf("Couldn't create GLX context\n");
276 exit(1);
277 }
278
279
280 Win[0] = CreateWindow(Dpy, ScrNum, visinfo,
281 0, 0, 300, 300, "source window");
282
283 Win[1] = CreateWindow(Dpy, ScrNum, visinfo,
284 350, 0, 300, 300, "dest window");
285
Brian Paul15f7f4e2003-12-05 00:39:48 +0000286 printf("Press Esc to exit\n");
287 printf("Press 'f' to toggle front/back buffer drawing\n");
Brian Paulb5e4a161999-11-25 17:41:51 +0000288}
289
290
291int
292main(int argc, char *argv[])
293{
294 Init();
295 EventLoop();
296 return 0;
297}
298
299
300#else
301
302
303int
304main(int argc, char *argv[])
305{
306 printf("This program requires GLX 1.3!\n");
307 return 0;
308}
309
310
311#endif /* GLX_VERSION_1_3 */