Merge commit 'origin/master' into gallium-0.2
[mesa.git] / progs / miniglx / miniglxtest.c
1 /*
2 * Test the mini GLX interface.
3 */
4
5
6 #include <stdio.h>
7 #include <stdlib.h>
8 #include <string.h>
9 #include <unistd.h>
10 #include <GL/gl.h>
11 #define USE_MINI_GLX 1
12 #if USE_MINI_GLX
13 #include <GL/miniglx.h>
14 #else
15 #include <GL/glx.h>
16 #endif
17
18 static GLXContext ctx;
19
20 static GLuint NumFrames = 100;
21 static GLuint NumDisplays = 1;
22 static GLboolean Texture = GL_FALSE;
23 static GLboolean SingleBuffer = GL_FALSE;
24 static GLboolean Sleeps = GL_TRUE;
25
26
27 static void
28 rect(GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2)
29 {
30 glBegin(GL_QUADS);
31 glTexCoord2f(0, 0); glColor3f(0, 0, 1); glVertex2f(x1, y1);
32 glTexCoord2f(1, 0); glColor3f(1, 0, 0); glVertex2f(x2, y1);
33 glTexCoord2f(1, 1); glColor3f(0, 1, 0); glVertex2f(x2, y2);
34 glTexCoord2f(0, 1); glColor3f(0, 0, 0); glVertex2f(x1, y2);
35 glEnd();
36 }
37
38
39 static void
40 redraw(Display *dpy, Window w, int rot)
41 {
42 GLfloat a;
43
44 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
45
46 glPushMatrix();
47 glRotatef(rot, 0, 0, 1);
48 glScalef(.5, .5, .5);
49 for (a = 0.0; a < 360.0; a += 30.0) {
50 glPushMatrix();
51 glRotatef(a, 0, 0, 1);
52 glRotatef(40, 1, 0, 0);
53 glColor3f(a / 360.0, 1-a/360.0, 0);
54 rect(0.3, -0.25, 1.5, 0.25);
55 glPopMatrix();
56 }
57 glPopMatrix();
58
59 if (SingleBuffer)
60 glFlush();
61 else
62 glXSwapBuffers(dpy, w);
63 }
64
65
66 static Window
67 make_window(Display *dpy, unsigned int width, unsigned int height)
68 {
69 int attrib_single[] = { GLX_RGBA,
70 GLX_RED_SIZE, 1,
71 GLX_GREEN_SIZE, 1,
72 GLX_BLUE_SIZE, 1,
73 GLX_DEPTH_SIZE, 1,
74 None };
75 int attrib_double[] = { GLX_RGBA,
76 GLX_RED_SIZE, 1,
77 GLX_GREEN_SIZE, 1,
78 GLX_BLUE_SIZE, 1,
79 GLX_DEPTH_SIZE, 1,
80 GLX_DOUBLEBUFFER,
81 None };
82 int *attrib = SingleBuffer ? attrib_single : attrib_double;
83 int scrnum = 0;
84 XSetWindowAttributes attr;
85 unsigned long mask;
86 Window root;
87 Window win;
88 XVisualInfo *visinfo;
89
90 root = RootWindow(dpy, scrnum);
91
92 if (!(visinfo = glXChooseVisual(dpy, scrnum, attrib))) {
93 printf("Error: couldn't get an RGB, Double-buffered visual\n");
94 exit(1);
95 }
96
97 if (!(ctx = glXCreateContext(dpy, visinfo, NULL, True))) {
98 printf("Error: glXCreateContext failed\n");
99 exit(1);
100 }
101
102 /* window attributes */
103 attr.background_pixel = 0;
104 attr.border_pixel = 0;
105 attr.colormap = XCreateColormap(dpy, root, visinfo->visual, AllocNone);
106 attr.event_mask = StructureNotifyMask | ExposureMask;
107 mask = CWBackPixel | CWBorderPixel | CWColormap | CWEventMask;
108
109 win = XCreateWindow(dpy, root, 0, 0, width, height,
110 0, visinfo->depth, InputOutput,
111 visinfo->visual, mask, &attr);
112 if (!win) {
113 printf("Error: XCreateWindow failed\n");
114 exit(1);
115 }
116
117 glXMakeCurrent(dpy, win, ctx);
118
119 glViewport(0, 0, width, height);
120
121 return win;
122 }
123
124
125 static void
126 event_loop(Display *dpy, Window win)
127 {
128 int i;
129
130 printf("Drawing %d frames\n", NumFrames);
131
132 for (i = 0; i < NumFrames; i++) {
133 redraw(dpy, win, -i*2);
134 if (Sleeps) {
135 usleep(20000);
136 }
137 }
138 }
139
140
141 static int
142 runtest(void)
143 {
144 Display *dpy;
145 Window win;
146
147 dpy = XOpenDisplay(NULL);
148 if (!dpy) {
149 printf("Error: XOpenDisplay failed\n");
150 return 1;
151 }
152
153 win = make_window(dpy, 800, 600);
154
155 srand(getpid());
156
157 /* init GL state */
158 glClearColor(0.5, 0.5, 0.5, 1.0);
159 glEnable(GL_DEPTH_TEST);
160 if (Texture) {
161 GLubyte image[16][16][4];
162 GLint i, j;
163 for (i = 0; i < 16; i++) {
164 for (j = 0; j < 16; j++) {
165 if (((i / 2) ^ (j / 2)) & 1) {
166 image[i][j][0] = 255;
167 image[i][j][1] = 255;
168 image[i][j][2] = 255;
169 image[i][j][3] = 255;
170 }
171 else {
172 image[i][j][0] = 128;
173 image[i][j][1] = 128;
174 image[i][j][2] = 128;
175 image[i][j][3] = 128;
176 }
177 }
178 }
179 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0,
180 GL_RGBA, GL_UNSIGNED_BYTE, image);
181 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
182 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
183 glEnable(GL_TEXTURE_2D);
184 }
185 if (SingleBuffer) {
186 glDrawBuffer(GL_FRONT);
187 glReadBuffer(GL_FRONT);
188 }
189 else {
190 glDrawBuffer(GL_BACK);
191 }
192
193 XMapWindow(dpy, win);
194
195 /* wait for window to get mapped */
196 {
197 XEvent e;
198 while (1) {
199 XNextEvent(dpy, &e);
200 if (e.type == MapNotify && e.xmap.window == win) {
201 break;
202 }
203 }
204 }
205
206 event_loop(dpy, win);
207
208 glXDestroyContext(dpy, ctx);
209 XDestroyWindow(dpy, win);
210
211 XCloseDisplay(dpy);
212
213 return 0;
214 }
215
216
217 static void
218 usage(void)
219 {
220 printf("Usage:\n");
221 printf(" -f N render N frames (default %d)\n", NumFrames);
222 printf(" -d N do N display cycles\n");
223 printf(" -t texturing\n");
224 printf(" -s single buffering\n");
225 printf(" -n no usleep() delay\n");
226 }
227
228
229 static void
230 parse_args(int argc, char *argv[])
231 {
232 int i;
233 for (i = 1; i < argc; i++) {
234 if (strcmp(argv[i], "-f") == 0) {
235 NumFrames = atoi(argv[i + 1]);
236 i++;
237 }
238 else if (strcmp(argv[i], "-d") == 0) {
239 NumDisplays = atoi(argv[i + 1]);
240 i++;
241 }
242 else if (strcmp(argv[i], "-n") == 0) {
243 Sleeps = GL_FALSE;
244 }
245 else if (strcmp(argv[i], "-s") == 0) {
246 SingleBuffer = GL_TRUE;
247 }
248 else if (strcmp(argv[i], "-t") == 0) {
249 Texture = GL_TRUE;
250 }
251 else {
252 usage();
253 exit(1);
254 }
255 }
256 }
257
258
259 int
260 main(int argc, char *argv[])
261 {
262 int i;
263
264 parse_args(argc, argv);
265
266 for (i = 0; i < NumDisplays; i++) {
267 if (runtest() != 0)
268 break;
269 }
270
271 return 0;
272 }