blob: 3093553d5de070ef7f0db2a77238314b860b39e3 [file] [log] [blame]
Brian Paulb5e4a161999-11-25 17:41:51 +00001/*
2 * Mesa 3-D graphics library
Brian Paul15f7f4e2003-12-05 00:39:48 +00003 * Version: 5.1
Brian Paulb5e4a161999-11-25 17:41:51 +00004 *
Brian Paul15f7f4e2003-12-05 00:39:48 +00005 * Copyright (C) 1999-2003 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>
41#include <unistd.h>
42
43
44#ifdef GLX_VERSION_1_3
45
46
47static Display *Dpy;
48static int ScrNum;
49static GLXContext Context;
50static Window Win[2]; /* Win[0] = source, Win[1] = dest */
51static GLint Width[2], Height[2];
52
53static GLfloat Angle = 0.0;
54
Brian Paul15f7f4e2003-12-05 00:39:48 +000055static GLboolean DrawFront = GL_FALSE;
56
Brian Paulb5e4a161999-11-25 17:41:51 +000057
58
59static Window
60CreateWindow(Display *dpy, int scrnum, XVisualInfo *visinfo,
61 int xpos, int ypos, int width, int height,
62 const char *name)
63{
64 Window win;
65 XSetWindowAttributes attr;
66 unsigned long mask;
67 Window root;
68
69 root = RootWindow(dpy, scrnum);
70
71 /* window attributes */
72 attr.background_pixel = 0;
73 attr.border_pixel = 0;
74 attr.colormap = XCreateColormap(dpy, root, visinfo->visual, AllocNone);
75 attr.event_mask = StructureNotifyMask | ExposureMask | KeyPressMask;
76 mask = CWBackPixel | CWBorderPixel | CWColormap | CWEventMask;
77
78 win = XCreateWindow(dpy, root, xpos, ypos, width, height,
79 0, visinfo->depth, InputOutput,
80 visinfo->visual, mask, &attr);
81 if (win) {
82 XSizeHints sizehints;
83 sizehints.x = xpos;
84 sizehints.y = ypos;
85 sizehints.width = width;
86 sizehints.height = height;
87 sizehints.flags = USSize | USPosition;
88 XSetNormalHints(dpy, win, &sizehints);
89 XSetStandardProperties(dpy, win, name, name,
90 None, (char **)NULL, 0, &sizehints);
91
92 XMapWindow(dpy, win);
93 }
94 return win;
95}
96
97
98static void
99Redraw(void)
100{
101 /* make the first window the current one */
102 if (!glXMakeContextCurrent(Dpy, Win[0], Win[0], Context)) {
103 printf("glXMakeContextCurrent failed in Redraw()\n");
104 return;
105 }
106
107 Angle += 1.0;
108
Brian Paul15f7f4e2003-12-05 00:39:48 +0000109 if (DrawFront) {
110 glDrawBuffer(GL_FRONT);
111 glReadBuffer(GL_FRONT);
112 }
113 else {
114 glDrawBuffer(GL_BACK);
115 glReadBuffer(GL_BACK);
116 }
117
Brian Paulb5e4a161999-11-25 17:41:51 +0000118 glViewport(0, 0, Width[0], Height[0]);
119 glMatrixMode(GL_PROJECTION);
120 glLoadIdentity();
121 glOrtho(-1.0, 1.0, -1.0, 1.0, -1.0, 1.0);
122 glMatrixMode(GL_MODELVIEW);
123
124 glShadeModel(GL_FLAT);
125 glClearColor(0.5, 0.5, 0.5, 1.0);
126 glClear(GL_COLOR_BUFFER_BIT);
127
128 /* draw blue quad */
129 glColor3f(0.3, 0.3, 1.0);
130 glPushMatrix();
131 glRotatef(Angle, 0, 0, 1);
132 glBegin(GL_POLYGON);
133 glVertex2f(-0.5, -0.25);
134 glVertex2f( 0.5, -0.25);
135 glVertex2f( 0.5, 0.25);
136 glVertex2f(-0.5, 0.25);
137 glEnd();
138 glPopMatrix();
139
Brian Paul15f7f4e2003-12-05 00:39:48 +0000140 if (DrawFront)
141 glFinish();
142 else
143 glXSwapBuffers(Dpy, Win[0]);
Brian Paulb5e4a161999-11-25 17:41:51 +0000144
145
146 /* copy image from window 0 to window 1 */
147 if (!glXMakeContextCurrent(Dpy, Win[1], Win[0], Context)) {
148 printf("glXMakeContextCurrent failed in Redraw()\n");
149 return;
150 }
151
152 /* raster pos setup */
153 glViewport(0, 0, Width[1], Height[1]);
154 glPushMatrix();
155 glLoadIdentity();
156 glMatrixMode(GL_PROJECTION);
157 glPushMatrix();
158 glLoadIdentity();
159 glOrtho(-1, 1, -1, 1, -1, 1);
160 glRasterPos2f(-1, -1);
161
162 /* copy the image between windows */
Brian Paulb5e4a161999-11-25 17:41:51 +0000163 glCopyPixels(0, 0, Width[0], Height[0], GL_COLOR);
Brian Paulb5e4a161999-11-25 17:41:51 +0000164
165 glPopMatrix();
166 glMatrixMode(GL_MODELVIEW);
167 glPopMatrix();
Brian Paul15f7f4e2003-12-05 00:39:48 +0000168
169 if (DrawFront)
170 glFinish();
171 else
172 glXSwapBuffers(Dpy, Win[1]);
Brian Paulb5e4a161999-11-25 17:41:51 +0000173}
174
175
176
177static void
178Resize(Window win, unsigned int width, unsigned int height)
179{
180 int i;
181 if (win == Win[0]) {
182 i = 0;
183 }
184 else {
185 i = 1;
186 }
187 Width[i] = width;
188 Height[i] = height;
189 if (!glXMakeCurrent(Dpy, Win[i], Context)) {
190 printf("glXMakeCurrent failed in Resize()\n");
191 return;
192 }
193}
194
195
196
197static void
198EventLoop(void)
199{
200 XEvent event;
201 while (1) {
202 if (XPending(Dpy) > 0) {
203 XNextEvent( Dpy, &event );
204 switch (event.type) {
205 case Expose:
206 Redraw();
207 break;
208 case ConfigureNotify:
209 Resize(event.xany.window, event.xconfigure.width, event.xconfigure.height);
210 break;
211 case KeyPress:
Brian Paul15f7f4e2003-12-05 00:39:48 +0000212 {
213 char buf[100];
214 KeySym keySym;
215 XComposeStatus stat;
216 XLookupString(&event.xkey, buf, sizeof(buf), &keySym, &stat);
217 if (keySym == XK_Escape) {
218 /* exit */
219 return;
220 }
221 else if (buf[0] == 'f') {
222 DrawFront = !DrawFront;
223 printf("Drawing to %s buffer\n",
224 DrawFront ? "GL_FRONT" : "GL_BACK");
225 }
226 }
227 break;
Brian Paulb5e4a161999-11-25 17:41:51 +0000228 default:
229 /*no-op*/ ;
230 }
231 }
232 else {
233 /* animate */
234 Redraw();
235 }
236 }
237}
238
239
240static void
241Init(void)
242{
243 XVisualInfo *visinfo;
244 int attrib[] = { GLX_RGBA,
245 GLX_RED_SIZE, 1,
246 GLX_GREEN_SIZE, 1,
247 GLX_BLUE_SIZE, 1,
248 GLX_DOUBLEBUFFER,
249 None };
250
251 Dpy = XOpenDisplay(NULL);
252 if (!Dpy) {
253 printf("Couldn't open default display!\n");
254 exit(1);
255 }
256
257 ScrNum = DefaultScreen(Dpy);
258
259 visinfo = glXChooseVisual(Dpy, ScrNum, attrib);
260 if (!visinfo) {
261 printf("Unable to find RGB, double-buffered visual\n");
262 exit(1);
263 }
264
265 Context = glXCreateContext(Dpy, visinfo, NULL, True);
266 if (!Context) {
267 printf("Couldn't create GLX context\n");
268 exit(1);
269 }
270
271
272 Win[0] = CreateWindow(Dpy, ScrNum, visinfo,
273 0, 0, 300, 300, "source window");
274
275 Win[1] = CreateWindow(Dpy, ScrNum, visinfo,
276 350, 0, 300, 300, "dest window");
277
Brian Paul15f7f4e2003-12-05 00:39:48 +0000278 printf("Press Esc to exit\n");
279 printf("Press 'f' to toggle front/back buffer drawing\n");
Brian Paulb5e4a161999-11-25 17:41:51 +0000280}
281
282
283int
284main(int argc, char *argv[])
285{
286 Init();
287 EventLoop();
288 return 0;
289}
290
291
292#else
293
294
295int
296main(int argc, char *argv[])
297{
298 printf("This program requires GLX 1.3!\n");
299 return 0;
300}
301
302
303#endif /* GLX_VERSION_1_3 */