2 * Create several OpenGL rendering contexts, sharing textures, display
3 * lists, etc. Exercise binding, deleting, etc.
17 #include <X11/keysym.h>
21 * Each display/window/context:
24 char DisplayName
[1000];
31 #define MAX_CONTEXTS 200
32 static struct context Contexts
[MAX_CONTEXTS
];
33 static int NumContexts
= 0;
37 Error(const char *display
, const char *msg
)
39 fprintf(stderr
, "Error on display %s - %s\n", display
, msg
);
44 static struct context
*
45 CreateContext(const char *displayName
, const char *name
)
50 int attrib
[] = { GLX_RGBA
,
57 XSetWindowAttributes attr
;
61 int width
= 90, height
= 90;
62 int xpos
= 0, ypos
= 0;
64 if (NumContexts
>= MAX_CONTEXTS
)
67 dpy
= XOpenDisplay(displayName
);
69 Error(displayName
, "Unable to open display");
73 scrnum
= DefaultScreen(dpy
);
74 root
= RootWindow(dpy
, scrnum
);
76 visinfo
= glXChooseVisual(dpy
, scrnum
, attrib
);
78 Error(displayName
, "Unable to find RGB, double-buffered visual");
82 /* window attributes */
83 xpos
= (NumContexts
% 10) * 100;
84 ypos
= (NumContexts
/ 10) * 100;
85 attr
.background_pixel
= 0;
86 attr
.border_pixel
= 0;
87 attr
.colormap
= XCreateColormap(dpy
, root
, visinfo
->visual
, AllocNone
);
88 attr
.event_mask
= StructureNotifyMask
| ExposureMask
| KeyPressMask
;
89 mask
= CWBackPixel
| CWBorderPixel
| CWColormap
| CWEventMask
;
91 win
= XCreateWindow(dpy
, root
, xpos
, ypos
, width
, height
,
92 0, visinfo
->depth
, InputOutput
,
93 visinfo
->visual
, mask
, &attr
);
95 Error(displayName
, "Couldn't create window");
100 XSizeHints sizehints
;
103 sizehints
.width
= width
;
104 sizehints
.height
= height
;
105 sizehints
.flags
= USSize
| USPosition
;
106 XSetNormalHints(dpy
, win
, &sizehints
);
107 XSetStandardProperties(dpy
, win
, name
, name
,
108 None
, (char **)NULL
, 0, &sizehints
);
111 if (NumContexts
== 0) {
112 ctx
= glXCreateContext(dpy
, visinfo
, NULL
, True
);
115 /* share textures & dlists with 0th context */
116 ctx
= glXCreateContext(dpy
, visinfo
, Contexts
[0].Context
, True
);
119 Error(displayName
, "Couldn't create GLX context");
123 XMapWindow(dpy
, win
);
125 if (!glXMakeCurrent(dpy
, win
, ctx
)) {
126 Error(displayName
, "glXMakeCurrent failed");
130 if (NumContexts
== 0) {
131 printf("GL_RENDERER = %s\n", (char *) glGetString(GL_RENDERER
));
134 /* save the info for this context */
136 struct context
*h
= &Contexts
[NumContexts
];
137 strcpy(h
->DisplayName
, name
);
142 return &Contexts
[NumContexts
-1];
150 if (!glXMakeCurrent(Contexts
[i
].Dpy
, Contexts
[i
].Win
, Contexts
[i
].Context
)) {
151 fprintf(stderr
, "glXMakeCurrent failed!\n");
158 DestroyContext(int i
)
160 XDestroyWindow(Contexts
[i
].Dpy
, Contexts
[i
].Win
);
161 glXDestroyContext(Contexts
[i
].Dpy
, Contexts
[i
].Context
);
162 XCloseDisplay(Contexts
[i
].Dpy
);
167 main(int argc
, char *argv
[])
169 char *dpyName
= NULL
;
174 for (i
= 0; i
< 2; i
++) {
175 CreateContext(dpyName
, "context");
178 /* Create texture and bind it in context 0 */
180 glGenTextures(1, &t
);
181 printf("Generated texture ID %u\n", t
);
182 assert(!glIsTexture(t
));
183 glBindTexture(GL_TEXTURE_2D
, t
);
184 assert(glIsTexture(t
));
185 glGetIntegerv(GL_TEXTURE_BINDING_2D
, &tb
);
188 /* Bind texture in context 1 */
190 assert(glIsTexture(t
));
191 glBindTexture(GL_TEXTURE_2D
, t
);
192 glGetIntegerv(GL_TEXTURE_BINDING_2D
, &tb
);
195 /* Delete texture from context 0 */
197 glDeleteTextures(1, &t
);
198 assert(!glIsTexture(t
));
199 glGetIntegerv(GL_TEXTURE_BINDING_2D
, &tb
);
200 printf("After delete, binding = %d\n", tb
);
202 /* Check texture state from context 1 */
204 assert(!glIsTexture(t
));
205 glGetIntegerv(GL_TEXTURE_BINDING_2D
, &tb
);
206 printf("In second context, binding = %d\n", tb
);
207 glBindTexture(GL_TEXTURE_2D
, 0);
208 glGetIntegerv(GL_TEXTURE_BINDING_2D
, &tb
);
212 for (i
= 0; i
< NumContexts
; i
++) {
216 printf("Success!\n");