2 * Test sharing of texture objects by two rendering contexts.
3 * In particular, test that changing a texture object in one context
4 * effects the texture in the second context.
9 * Copyright (C) 2008 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.
37 #include <X11/keysym.h>
40 #define MAX_CONTEXTS 2
44 static const char *DisplayName
= NULL
;
46 static XVisualInfo
*VisInfo
;
48 static GLXContext Contexts
[MAX_CONTEXTS
];
49 static int WinWidth
= 300, WinHeight
= 300;
51 static int DrawContext
= 0, TexContext
= 1;
53 static GLuint TexObj
= 0;
54 static GLboolean NewTexture
= GL_FALSE
;
58 Error(const char *msg
)
60 fprintf(stderr
, "sharedtex error: %s\n", msg
);
66 CreateWindow(const char *name
)
68 int attrib
[] = { GLX_RGBA
,
75 XSetWindowAttributes attr
;
78 int xpos
= 0, ypos
= 0;
81 scrnum
= DefaultScreen(Dpy
);
82 root
= RootWindow(Dpy
, scrnum
);
84 VisInfo
= glXChooseVisual(Dpy
, scrnum
, attrib
);
86 Error("Unable to find RGB, double-buffered visual");
89 /* window attributes */
90 xpos
= (n
% 10) * 100;
91 ypos
= (n
/ 10) * 100;
94 attr
.background_pixel
= 0;
95 attr
.border_pixel
= 0;
96 attr
.colormap
= XCreateColormap(Dpy
, root
, VisInfo
->visual
, AllocNone
);
97 attr
.event_mask
= StructureNotifyMask
| ExposureMask
| KeyPressMask
;
98 mask
= CWBackPixel
| CWBorderPixel
| CWColormap
| CWEventMask
;
100 Win
= XCreateWindow(Dpy
, root
, xpos
, ypos
, WinWidth
, WinHeight
,
101 0, VisInfo
->depth
, InputOutput
,
102 VisInfo
->visual
, mask
, &attr
);
104 Error("Couldn't create window");
108 XSizeHints sizehints
;
111 sizehints
.width
= WinWidth
;
112 sizehints
.height
= WinHeight
;
113 sizehints
.flags
= USSize
| USPosition
;
114 XSetNormalHints(Dpy
, Win
, &sizehints
);
115 XSetStandardProperties(Dpy
, Win
, name
, name
,
116 None
, (char **)NULL
, 0, &sizehints
);
119 XMapWindow(Dpy
, Win
);
124 * Change texture image, using TexContext
129 GLuint tex
[TEX_SIZE
][TEX_SIZE
];
133 if (Win
&& !glXMakeCurrent(Dpy
, Win
, Contexts
[TexContext
])) {
134 Error("glXMakeCurrent failed");
137 /* choose two random colors */
138 c0
= rand() & 0xffffffff;
139 c1
= rand() & 0xffffffff;
141 for (i
= 0; i
< TEX_SIZE
; i
++) {
142 for (j
= 0; j
< TEX_SIZE
; j
++) {
143 if (((i
/ 4) ^ (j
/ 4)) & 1) {
152 glBindTexture(GL_TEXTURE_2D
, TexObj
);
153 glTexImage2D(GL_TEXTURE_2D
, 0, GL_RGBA
, TEX_SIZE
, TEX_SIZE
, 0,
154 GL_RGBA
, GL_UNSIGNED_BYTE
, tex
);
156 NewTexture
= GL_TRUE
;
163 glGenTextures(1, &TexObj
);
165 glBindTexture(GL_TEXTURE_2D
, TexObj
);
166 glTexParameteri(GL_TEXTURE_2D
, GL_TEXTURE_MIN_FILTER
, GL_LINEAR
);
167 glTexParameteri(GL_TEXTURE_2D
, GL_TEXTURE_MAG_FILTER
, GL_LINEAR
);
168 glEnable(GL_TEXTURE_2D
);
170 printf("GL_RENDERER = %s\n", (char*) glGetString(GL_RENDERER
));
179 Dpy
= XOpenDisplay(DisplayName
);
181 Error("Unable to open display");
184 CreateWindow("sharedtex");
186 for (i
= 0; i
< MAX_CONTEXTS
; i
++) {
187 GLXContext share
= i
> 0 ? Contexts
[0] : 0;
189 Contexts
[i
] = glXCreateContext(Dpy
, VisInfo
, share
, True
);
191 Error("Unable to create GLX context");
194 if (!glXMakeCurrent(Dpy
, Win
, Contexts
[i
])) {
195 Error("glXMakeCurrent failed");
206 * Redraw window, using DrawContext
211 static float rot
= 0.0;
216 if (Win
&& !glXMakeCurrent(Dpy
, Win
, Contexts
[DrawContext
])) {
217 Error("glXMakeCurrent failed");
220 glViewport(0, 0, WinWidth
, WinHeight
);
221 ar
= (float) WinWidth
/ (float) WinHeight
;
222 glMatrixMode(GL_PROJECTION
);
224 glOrtho(-ar
, ar
, -1.0, 1.0, -1.0, 1.0);
225 glMatrixMode(GL_MODELVIEW
);
227 glShadeModel(GL_FLAT
);
228 glClearColor(0.5, 0.5, 0.5, 1.0);
229 glClear(GL_COLOR_BUFFER_BIT
);
232 glRotatef(rot
, 0, 0, 1);
233 glScalef(0.7, 0.7, 0.7);
236 /* rebind to get new contents */
237 glBindTexture(GL_TEXTURE_2D
, TexObj
);
238 NewTexture
= GL_FALSE
;
241 /* draw textured quad */
243 glTexCoord2f( 0.0, 0.0 ); glVertex2f( -1.0, -1.0 );
244 glTexCoord2f( 1.0, 0.0 ); glVertex2f( 1.0, -1.0 );
245 glTexCoord2f( 1.0, 1.0 ); glVertex2f( 1.0, 1.0 );
246 glTexCoord2f( 0.0, 1.0 ); glVertex2f( -1.0, 1.0 );
252 glXSwapBuffers(Dpy
, Win
);
260 while (XPending(Dpy
) > 0) {
262 XNextEvent(Dpy
, &event
);
264 switch (event
.type
) {
268 case ConfigureNotify
:
269 WinWidth
= event
.xconfigure
.width
;
270 WinHeight
= event
.xconfigure
.height
;
277 XLookupString(&event
.xkey
, buf
, sizeof(buf
), &keySym
, &stat
);
306 main(int argc
, char *argv
[])
310 for (i
= 1; i
< argc
; i
++) {
311 if (strcmp(argv
[i
], "-display") == 0 && i
< argc
) {
312 DisplayName
= argv
[i
+1];
319 printf("Press 't' to change texture image/colors\n");