1 /* $Id: jkrahntest.c,v 1.2 2006/01/30 17:12:10 brianp Exp $ */
3 /* This is a good test for glXSwapBuffers on non-current windows,
4 * and the glXCopyContext function. Fixed several Mesa/DRI bugs with
5 * this program on 15 June 2002.
7 * Joe's comments follow:
9 * I have tried some different approaches for being able to
10 * draw to multiple windows using one context, or a copied
11 * context. Mesa/indirect rendering works to use one context
12 * for multiple windows, but crashes with glXCopyContext.
13 * DRI is badly broken, at least for ATI.
15 * I also noticed that glXMakeCurrent allows a window and context
16 * from different visuals to be attached (haven't tested recently).
18 * Joe Krahn <jkrahn@nc.rr.com>
33 #define DEGTOR (M_PI/180.0)
35 static int AttributeList
[] = { GLX_RGBA
, GLX_DOUBLEBUFFER
, None
};
37 int main(int argc
, char **argv
)
41 XSetWindowAttributes swa
;
43 GLXContext ctx1
, ctx2
;
48 fprintf(stderr
, "This program tests GLX context switching.\n");
49 fprintf(stderr
, "Usage: cxbug <n>\n");
50 fprintf(stderr
, "Where n is:\n");
51 fprintf(stderr
, "\t1) Use two contexts and swap only when the context is current (typical case).\n");
52 fprintf(stderr
, "\t2) Use two contexts and swap at the same time.\n");
53 fprintf(stderr
, "\t\t Used to crash Mesa & nVidia, and DRI artifacts. Seems OK now.\n");
54 fprintf(stderr
, "\t3) Use one context, but only swap when a context is current.\n");
55 fprintf(stderr
, "\t\t Serious artifacts for DRI at least with ATI.\n");
56 fprintf(stderr
, "\t4) Use one context, swap both windows at the same time, so the left\n");
57 fprintf(stderr
, "\t\t window has no context at swap time. Severe artifacts for DRI.\n");
58 fprintf(stderr
, "\t5) Use two contexts, copying one to the other when switching windows.\n");
59 fprintf(stderr
, "\t\t DRI gives an error, indirect rendering crashes server.\n");
65 /* get a connection */
66 dpy
= XOpenDisplay(NULL
);
68 /* Get an appropriate visual */
69 vi
= glXChooseVisual(dpy
, DefaultScreen(dpy
), AttributeList
);
71 fprintf(stderr
, "No matching visuals found.\n");
75 /* Create two GLX contexts, with list sharing */
76 ctx1
= glXCreateContext(dpy
, vi
, 0, True
);
77 ctx2
= glXCreateContext(dpy
, vi
, ctx1
, True
);
79 /* create a colormap */
80 swa
.colormap
= XCreateColormap(dpy
, RootWindow(dpy
, vi
->screen
),
81 vi
->visual
, AllocNone
);
84 /* Create two windows */
85 win1
= XCreateWindow(dpy
, RootWindow(dpy
, vi
->screen
),
87 0, vi
->depth
, InputOutput
, vi
->visual
,
88 CWBorderPixel
| CWColormap
, &swa
);
89 XStoreName(dpy
, win1
, "Test [L]");
90 XMapWindow(dpy
, win1
);
91 XMoveWindow(dpy
, win1
, 10, 10); /* Initial requested x,y may not be honored */
94 static const char *name
= "window";
97 sizehints
.width
= 200;
98 sizehints
.height
= 200;
99 sizehints
.flags
= USSize
| USPosition
;
100 XSetNormalHints(dpy
, win1
, &sizehints
);
101 XSetStandardProperties(dpy
, win1
, name
, name
,
102 None
, (char **)NULL
, 0, &sizehints
);
106 win2
= XCreateWindow(dpy
, RootWindow(dpy
, vi
->screen
),
108 0, vi
->depth
, InputOutput
, vi
->visual
,
109 CWBorderPixel
| CWColormap
, &swa
);
110 XStoreName(dpy
, win1
, "Test [R]");
111 XMapWindow(dpy
, win2
);
112 XMoveWindow(dpy
, win2
, 260, 10);
114 XSizeHints sizehints
;
115 static const char *name
= "window";
118 sizehints
.width
= 200;
119 sizehints
.height
= 200;
120 sizehints
.flags
= USSize
| USPosition
;
121 XSetNormalHints(dpy
, win2
, &sizehints
);
122 XSetStandardProperties(dpy
, win2
, name
, name
,
123 None
, (char **)NULL
, 0, &sizehints
);
127 /* Now draw some spinning things */
128 for (angle
= 0; angle
< 360*4; angle
+= 10.0) {
129 /* Connect the context to window 1 */
130 glXMakeCurrent(dpy
, win1
, ctx1
);
132 /* Clear and draw in window 1 */
133 glDrawBuffer(GL_BACK
);
134 glClearColor(1, 1, 0, 1);
135 glClear(GL_COLOR_BUFFER_BIT
| GL_DEPTH_BUFFER_BIT
);
137 glBegin(GL_TRIANGLES
);
139 glVertex2f(cos(angle
* DEGTOR
), sin(angle
* DEGTOR
));
140 glVertex2f(cos((angle
+ 20.0) * DEGTOR
),
141 sin((angle
+ 20.0) * DEGTOR
));
145 if (test
== 1 || test
== 3 || test
== 5)
146 glXSwapBuffers(dpy
, win1
);
149 glXCopyContext(dpy
, ctx1
, ctx2
, GL_ALL_ATTRIB_BITS
);
150 /* Connect the context to window 2 */
151 if (test
== 3 || test
== 4) {
152 glXMakeCurrent(dpy
, win2
, ctx1
);
154 glXMakeCurrent(dpy
, win2
, ctx2
);
157 /* Clear and draw in window 2 */
158 glDrawBuffer(GL_BACK
);
159 glClearColor(0, 0, 1, 1);
160 glClear(GL_COLOR_BUFFER_BIT
);
162 glBegin(GL_TRIANGLES
);
164 glVertex2f(cos(angle
* DEGTOR
), sin(angle
* DEGTOR
));
165 glVertex2f(cos((angle
+ 20.0) * DEGTOR
),
166 sin((angle
+ 20.0) * DEGTOR
));
171 if (test
== 2 || test
== 4)
172 glXSwapBuffers(dpy
, win1
);
173 glXSwapBuffers(dpy
, win2
);