1 /* $Id: sharedtex.c,v 1.2 2002/01/16 14:32:46 joukj Exp $ */
4 * Test sharing of display lists and texture objects between GLX contests.
9 * Copyright (C) 2000 Brian Paul All Rights Reserved.
11 * Permission is hereby granted, free of charge, to any person obtaining a
12 * copy of this software and associated documentation files (the "Software"),
13 * to deal in the Software without restriction, including without limitation
14 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
15 * and/or sell copies of the Software, and to permit persons to whom the
16 * Software is furnished to do so, subject to the following conditions:
18 * The above copyright notice and this permission notice shall be included
19 * in all copies or substantial portions of the Software.
21 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
22 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
24 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
25 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
26 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
39 char DisplayName
[1000];
48 #define MAX_WINDOWS 20
49 static struct window Windows
[MAX_WINDOWS
];
50 static int NumWindows
= 0;
53 static GLuint Textures
[3];
54 static GLuint CubeList
;
59 Error(const char *display
, const char *msg
)
61 fprintf(stderr
, "Error on display %s - %s\n", display
, msg
);
66 static struct window
*
67 AddWindow(const char *displayName
, int xpos
, int ypos
,
68 const struct window
*shareWindow
)
73 int attrib
[] = { GLX_RGBA
,
81 XSetWindowAttributes attr
;
85 int width
= 300, height
= 300;
87 if (NumWindows
>= MAX_WINDOWS
)
90 dpy
= XOpenDisplay(displayName
);
92 Error(displayName
, "Unable to open display");
96 scrnum
= DefaultScreen(dpy
);
97 root
= RootWindow(dpy
, scrnum
);
99 visinfo
= glXChooseVisual(dpy
, scrnum
, attrib
);
101 Error(displayName
, "Unable to find RGB, double-buffered visual");
105 /* window attributes */
106 attr
.background_pixel
= 0;
107 attr
.border_pixel
= 0;
108 attr
.colormap
= XCreateColormap(dpy
, root
, visinfo
->visual
, AllocNone
);
109 attr
.event_mask
= StructureNotifyMask
| ExposureMask
| KeyPressMask
;
110 mask
= CWBackPixel
| CWBorderPixel
| CWColormap
| CWEventMask
;
112 win
= XCreateWindow(dpy
, root
, xpos
, ypos
, width
, height
,
113 0, visinfo
->depth
, InputOutput
,
114 visinfo
->visual
, mask
, &attr
);
116 Error(displayName
, "Couldn't create window");
121 XSizeHints sizehints
;
124 sizehints
.width
= width
;
125 sizehints
.height
= height
;
126 sizehints
.flags
= USSize
| USPosition
;
127 XSetNormalHints(dpy
, win
, &sizehints
);
128 XSetStandardProperties(dpy
, win
, displayName
, displayName
,
129 None
, (char **)NULL
, 0, &sizehints
);
133 ctx
= glXCreateContext(dpy
, visinfo
,
134 shareWindow
? shareWindow
->Context
: NULL
,
137 Error(displayName
, "Couldn't create GLX context");
141 XMapWindow(dpy
, win
);
143 if (!glXMakeCurrent(dpy
, win
, ctx
)) {
144 Error(displayName
, "glXMakeCurrent failed");
145 printf("glXMakeCurrent failed in Redraw()\n");
149 /* save the info for this window */
152 struct window
*h
= &Windows
[NumWindows
];
153 strcpy(h
->DisplayName
, displayName
);
160 return &Windows
[NumWindows
-1];
167 InitGLstuff(struct window
*h
)
169 if (!glXMakeCurrent(h
->Dpy
, h
->Win
, h
->Context
)) {
170 Error(h
->DisplayName
, "glXMakeCurrent failed in InitGLstuff");
174 glGenTextures(3, Textures
);
176 /* setup first texture object */
178 GLubyte image
[16][16][4];
180 glBindTexture(GL_TEXTURE_2D
, Textures
[0]);
182 /* red/white checkerboard */
183 for (i
= 0; i
< 16; i
++) {
184 for (j
= 0; j
< 16; j
++) {
186 image
[i
][j
][0] = 255;
187 image
[i
][j
][1] = 255;
188 image
[i
][j
][2] = 255;
189 image
[i
][j
][3] = 255;
192 image
[i
][j
][0] = 255;
195 image
[i
][j
][3] = 255;
200 glPixelStorei(GL_UNPACK_ALIGNMENT
, 1);
201 glTexImage2D(GL_TEXTURE_2D
, 0, GL_RGBA
, 16, 16, 0, GL_RGBA
,
202 GL_UNSIGNED_BYTE
, image
);
203 glTexParameteri(GL_TEXTURE_2D
, GL_TEXTURE_MIN_FILTER
, GL_NEAREST
);
204 glTexParameteri(GL_TEXTURE_2D
, GL_TEXTURE_MAG_FILTER
, GL_NEAREST
);
207 /* setup second texture object */
209 GLubyte image
[8][8][3];
211 glBindTexture(GL_TEXTURE_2D
, Textures
[1]);
213 /* green/yellow checkerboard */
214 for (i
= 0; i
< 8; i
++) {
215 for (j
= 0; j
< 8; j
++) {
218 image
[i
][j
][1] = 255;
222 image
[i
][j
][0] = 255;
223 image
[i
][j
][1] = 255;
229 glPixelStorei(GL_UNPACK_ALIGNMENT
, 2);
230 glTexImage2D(GL_TEXTURE_2D
, 0, GL_RGB
, 8, 8, 0, GL_RGB
,
231 GL_UNSIGNED_BYTE
, image
);
232 glTexParameteri(GL_TEXTURE_2D
, GL_TEXTURE_MIN_FILTER
, GL_NEAREST
);
233 glTexParameteri(GL_TEXTURE_2D
, GL_TEXTURE_MAG_FILTER
, GL_NEAREST
);
236 /* setup second texture object */
238 GLubyte image
[4][4][3];
240 glBindTexture(GL_TEXTURE_2D
, Textures
[2]);
242 /* blue/gray checkerboard */
243 for (i
= 0; i
< 4; i
++) {
244 for (j
= 0; j
< 4; j
++) {
248 image
[i
][j
][2] = 255;
251 image
[i
][j
][0] = 200;
252 image
[i
][j
][1] = 200;
253 image
[i
][j
][2] = 200;
258 glPixelStorei(GL_UNPACK_ALIGNMENT
, 2);
259 glTexImage2D(GL_TEXTURE_2D
, 0, GL_RGB
, 4, 4, 0, GL_RGB
,
260 GL_UNSIGNED_BYTE
, image
);
261 glTexParameteri(GL_TEXTURE_2D
, GL_TEXTURE_MIN_FILTER
, GL_NEAREST
);
262 glTexParameteri(GL_TEXTURE_2D
, GL_TEXTURE_MAG_FILTER
, GL_NEAREST
);
265 /* Now make the cube object display list */
266 CubeList
= glGenLists(1);
267 glNewList(CubeList
, GL_COMPILE
);
269 glBindTexture(GL_TEXTURE_2D
, Textures
[0]);
271 glTexCoord2f(0, 0); glVertex3f(-1, -1, -1);
272 glTexCoord2f(1, 0); glVertex3f(-1, 1, -1);
273 glTexCoord2f(1, 1); glVertex3f(-1, 1, 1);
274 glTexCoord2f(0, 1); glVertex3f(-1, -1, 1);
277 glTexCoord2f(0, 0); glVertex3f(1, -1, -1);
278 glTexCoord2f(1, 0); glVertex3f(1, 1, -1);
279 glTexCoord2f(1, 1); glVertex3f(1, 1, 1);
280 glTexCoord2f(0, 1); glVertex3f(1, -1, 1);
283 glBindTexture(GL_TEXTURE_2D
, Textures
[1]);
285 glTexCoord2f(0, 0); glVertex3f(-1, -1, -1);
286 glTexCoord2f(1, 0); glVertex3f( 1, -1, -1);
287 glTexCoord2f(1, 1); glVertex3f( 1, -1, 1);
288 glTexCoord2f(0, 1); glVertex3f(-1, -1, 1);
291 glTexCoord2f(0, 0); glVertex3f(-1, 1, -1);
292 glTexCoord2f(1, 0); glVertex3f( 1, 1, -1);
293 glTexCoord2f(1, 1); glVertex3f( 1, 1, 1);
294 glTexCoord2f(0, 1); glVertex3f(-1, 1, 1);
297 glBindTexture(GL_TEXTURE_2D
, Textures
[2]);
299 glTexCoord2f(0, 0); glVertex3f(-1, -1, -1);
300 glTexCoord2f(1, 0); glVertex3f( 1, -1, -1);
301 glTexCoord2f(1, 1); glVertex3f( 1, 1, -1);
302 glTexCoord2f(0, 1); glVertex3f(-1, 1, -1);
305 glTexCoord2f(0, 0); glVertex3f(-1, -1, 1);
306 glTexCoord2f(1, 0); glVertex3f( 1, -1, 1);
307 glTexCoord2f(1, 1); glVertex3f( 1, 1, 1);
308 glTexCoord2f(0, 1); glVertex3f(-1, 1, 1);
313 printf("GL_RENDERER: %s\n", (char *) glGetString(GL_RENDERER
));
314 printf("GL_VERSION: %s\n", (char *) glGetString(GL_VERSION
));
315 printf("GL_VENDOR: %s\n", (char *) glGetString(GL_VENDOR
));
321 Redraw(struct window
*h
)
323 if (!glXMakeCurrent(h
->Dpy
, h
->Win
, h
->Context
)) {
324 Error(h
->DisplayName
, "glXMakeCurrent failed");
325 printf("glXMakeCurrent failed in Redraw()\n");
331 glShadeModel(GL_FLAT
);
332 glClearColor(0.25, 0.25, 0.25, 1.0);
333 glClear(GL_COLOR_BUFFER_BIT
| GL_DEPTH_BUFFER_BIT
);
335 glEnable(GL_TEXTURE_2D
);
336 glEnable(GL_DEPTH_TEST
);
337 glTexEnvi(GL_TEXTURE_ENV
, GL_TEXTURE_ENV_MODE
, GL_REPLACE
);
343 glRotatef(h
->Angle
, 0, 1, -1);
345 glRotatef(-(h
->Angle
), 0, 1, -1);
347 glRotatef(h
->Angle
, 0, 1, 1);
349 glRotatef(-(h
->Angle
), 0, 1, 1);
350 glCallList(CubeList
);
353 glXSwapBuffers(h
->Dpy
, h
->Win
);
359 Resize(const struct window
*h
, unsigned int width
, unsigned int height
)
361 if (!glXMakeCurrent(h
->Dpy
, h
->Win
, h
->Context
)) {
362 Error(h
->DisplayName
, "glXMakeCurrent failed in Resize()");
365 glViewport(0, 0, width
, height
);
366 glMatrixMode(GL_PROJECTION
);
368 glFrustum(-1, 1, -1, 1, 2, 10);
369 glMatrixMode(GL_MODELVIEW
);
371 glTranslatef(0, 0, -3.5);
381 for (i
= 0; i
< NumWindows
; i
++) {
382 struct window
*h
= &Windows
[i
];
383 while (XPending(h
->Dpy
) > 0) {
385 XNextEvent(h
->Dpy
, &event
);
386 if (event
.xany
.window
== h
->Win
) {
387 switch (event
.type
) {
391 case ConfigureNotify
:
392 Resize(h
, event
.xconfigure
.width
, event
.xconfigure
.height
);
401 printf("window mismatch\n");
413 PrintInfo(const struct window
*h
)
415 printf("Name: %s\n", h
->DisplayName
);
416 printf(" Display: 0x%x\n", h
->Dpy
);
417 printf(" Window: 0x%x\n", h
->Win
);
418 printf(" Context: 0x%x\n", h
->Context
);
423 main(int argc
, char *argv
[])
426 struct window
*h0
, *h1
, *h2
, *h3
;
428 /* four windows and contexts sharing display lists and texture objects */
429 h0
= AddWindow(":0", 10, 10, NULL
);
430 h1
= AddWindow(":0", 330, 10, h0
);
431 h2
= AddWindow(":0", 10, 350, h0
);
432 h3
= AddWindow(":0", 330, 350, h0
);