st/mesa: fix incorrect RowStride computation
[mesa.git] / progs / egl / demo3.c
1 /*
2 * Exercise EGL API functions
3 */
4
5 #define EGL_EGLEXT_PROTOTYPES
6
7 #include <EGL/egl.h>
8 #include <EGL/eglext.h>
9 #include <GL/gl.h>
10 #include <assert.h>
11 #include <stdio.h>
12 #include <stdlib.h>
13 #include <string.h>
14 #include <unistd.h>
15
16
17
18 #define PIXEL_CENTER(x) ((long)(x) + 0.5)
19
20 #define GAP 10
21 #define ROWS 3
22 #define COLS 4
23
24 #define OPENGL_WIDTH 48
25 #define OPENGL_HEIGHT 13
26
27
28 GLenum rgb, doubleBuffer, windType;
29 GLint windW, windH;
30
31 GLenum mode1, mode2;
32 GLint boxW, boxH;
33 GLubyte OpenGL_bits[] = {
34 0x00, 0x03, 0x00, 0x00, 0x00, 0x00,
35 0x7f, 0xfb, 0xff, 0xff, 0xff, 0x01,
36 0x7f, 0xfb, 0xff, 0xff, 0xff, 0x01,
37 0x00, 0x03, 0x00, 0x00, 0x00, 0x00,
38 0x3e, 0x8f, 0xb7, 0xf9, 0xfc, 0x01,
39 0x63, 0xdb, 0xb0, 0x8d, 0x0d, 0x00,
40 0x63, 0xdb, 0xb7, 0x8d, 0x0d, 0x00,
41 0x63, 0xdb, 0xb6, 0x8d, 0x0d, 0x00,
42 0x63, 0x8f, 0xf3, 0xcc, 0x0d, 0x00,
43 0x63, 0x00, 0x00, 0x0c, 0x4c, 0x0a,
44 0x63, 0x00, 0x00, 0x0c, 0x4c, 0x0e,
45 0x63, 0x00, 0x00, 0x8c, 0xed, 0x0e,
46 0x3e, 0x00, 0x00, 0xf8, 0x0c, 0x00,
47 };
48
49
50 static void Init(void)
51 {
52
53 mode1 = GL_TRUE;
54 mode2 = GL_TRUE;
55 }
56
57 static void Reshape(int width, int height)
58 {
59
60 windW = (GLint)width;
61 windH = (GLint)height;
62 }
63
64 #if 0
65 static void RotateColorMask(void)
66 {
67 static GLint rotation = 0;
68
69 rotation = (rotation + 1) & 0x3;
70 switch (rotation) {
71 case 0:
72 glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
73 glIndexMask( 0xff );
74 break;
75 case 1:
76 glColorMask(GL_FALSE, GL_TRUE, GL_TRUE, GL_TRUE);
77 glIndexMask(0xFE);
78 break;
79 case 2:
80 glColorMask(GL_TRUE, GL_FALSE, GL_TRUE, GL_TRUE);
81 glIndexMask(0xFD);
82 break;
83 case 3:
84 glColorMask(GL_TRUE, GL_TRUE, GL_FALSE, GL_TRUE);
85 glIndexMask(0xFB);
86 break;
87 }
88 }
89 #endif
90
91 static void Viewport(GLint row, GLint column)
92 {
93 GLint x, y;
94
95 boxW = (windW - (COLS + 1) * GAP) / COLS;
96 boxH = (windH - (ROWS + 1) * GAP) / ROWS;
97
98 x = GAP + column * (boxW + GAP);
99 y = GAP + row * (boxH + GAP);
100
101 glViewport(x, y, boxW, boxH);
102
103 glMatrixMode(GL_PROJECTION);
104 glLoadIdentity();
105 glOrtho(-boxW/2, boxW/2, -boxH/2, boxH/2, 0.0, 1.0);
106 glMatrixMode(GL_MODELVIEW);
107
108 glEnable(GL_SCISSOR_TEST);
109 glScissor(x, y, boxW, boxH);
110 }
111
112 enum {
113 COLOR_BLACK = 0,
114 COLOR_RED,
115 COLOR_GREEN,
116 COLOR_YELLOW,
117 COLOR_BLUE,
118 COLOR_MAGENTA,
119 COLOR_CYAN,
120 COLOR_WHITE
121 };
122
123 static float RGBMap[9][3] = {
124 {0, 0, 0},
125 {1, 0, 0},
126 {0, 1, 0},
127 {1, 1, 0},
128 {0, 0, 1},
129 {1, 0, 1},
130 {0, 1, 1},
131 {1, 1, 1},
132 {0.5, 0.5, 0.5}
133 };
134
135 static void SetColor(int c)
136 {
137 glColor3fv(RGBMap[c]);
138 }
139
140 static void Point(void)
141 {
142 GLint i;
143
144 glBegin(GL_POINTS);
145 SetColor(COLOR_WHITE);
146 glVertex2i(0, 0);
147 for (i = 1; i < 8; i++) {
148 GLint j = i * 2;
149 SetColor(COLOR_BLACK+i);
150 glVertex2i(-j, -j);
151 glVertex2i(-j, 0);
152 glVertex2i(-j, j);
153 glVertex2i(0, j);
154 glVertex2i(j, j);
155 glVertex2i(j, 0);
156 glVertex2i(j, -j);
157 glVertex2i(0, -j);
158 }
159 glEnd();
160 }
161
162 static void Lines(void)
163 {
164 GLint i;
165
166 glPushMatrix();
167
168 glTranslatef(-12, 0, 0);
169 for (i = 1; i < 8; i++) {
170 SetColor(COLOR_BLACK+i);
171 glBegin(GL_LINES);
172 glVertex2i(-boxW/4, -boxH/4);
173 glVertex2i(boxW/4, boxH/4);
174 glEnd();
175 glTranslatef(4, 0, 0);
176 }
177
178 glPopMatrix();
179
180 glBegin(GL_LINES);
181 glVertex2i(0, 0);
182 glEnd();
183 }
184
185 static void LineStrip(void)
186 {
187
188 glBegin(GL_LINE_STRIP);
189 SetColor(COLOR_RED);
190 glVertex2f(PIXEL_CENTER(-boxW/4), PIXEL_CENTER(-boxH/4));
191 SetColor(COLOR_GREEN);
192 glVertex2f(PIXEL_CENTER(-boxW/4), PIXEL_CENTER(boxH/4));
193 SetColor(COLOR_BLUE);
194 glVertex2f(PIXEL_CENTER(boxW/4), PIXEL_CENTER(boxH/4));
195 SetColor(COLOR_WHITE);
196 glVertex2f(PIXEL_CENTER(boxW/4), PIXEL_CENTER(-boxH/4));
197 glEnd();
198
199 glBegin(GL_LINE_STRIP);
200 glVertex2i(0, 0);
201 glEnd();
202 }
203
204 static void LineLoop(void)
205 {
206
207 glBegin(GL_LINE_LOOP);
208 SetColor(COLOR_RED);
209 glVertex2f(PIXEL_CENTER(-boxW/4), PIXEL_CENTER(-boxH/4));
210 SetColor(COLOR_GREEN);
211 glVertex2f(PIXEL_CENTER(-boxW/4), PIXEL_CENTER(boxH/4));
212 SetColor(COLOR_BLUE);
213 glVertex2f(PIXEL_CENTER(boxW/4), PIXEL_CENTER(boxH/4));
214 SetColor(COLOR_WHITE);
215 glVertex2f(PIXEL_CENTER(boxW/4), PIXEL_CENTER(-boxH/4));
216 glEnd();
217
218 glEnable(GL_LOGIC_OP);
219 glLogicOp(GL_XOR);
220
221 glEnable(GL_BLEND);
222 glBlendFunc(GL_ONE, GL_ONE);
223
224 SetColor(COLOR_MAGENTA);
225 glBegin(GL_LINE_LOOP);
226 glVertex2f(PIXEL_CENTER(-boxW/8), PIXEL_CENTER(-boxH/8));
227 glVertex2f(PIXEL_CENTER(-boxW/8), PIXEL_CENTER(boxH/8));
228 glEnd();
229 glBegin(GL_LINE_LOOP);
230 glVertex2f(PIXEL_CENTER(-boxW/8), PIXEL_CENTER(boxH/8+5));
231 glVertex2f(PIXEL_CENTER(boxW/8), PIXEL_CENTER(boxH/8+5));
232 glEnd();
233 glDisable(GL_LOGIC_OP);
234 glDisable(GL_BLEND);
235
236 SetColor(COLOR_GREEN);
237 glBegin(GL_POINTS);
238 glVertex2i(0, 0);
239 glEnd();
240
241 glBegin(GL_LINE_LOOP);
242 glVertex2i(0, 0);
243 glEnd();
244 }
245
246 static void Bitmap(void)
247 {
248
249 glBegin(GL_LINES);
250 SetColor(COLOR_GREEN);
251 glVertex2i(-boxW/2, 0);
252 glVertex2i(boxW/2, 0);
253 glVertex2i(0, -boxH/2);
254 glVertex2i(0, boxH/2);
255 SetColor(COLOR_RED);
256 glVertex2i(0, -3);
257 glVertex2i(0, -3+OPENGL_HEIGHT);
258 SetColor(COLOR_BLUE);
259 glVertex2i(0, -3);
260 glVertex2i(OPENGL_WIDTH, -3);
261 glEnd();
262
263 SetColor(COLOR_GREEN);
264
265 glPixelStorei(GL_UNPACK_LSB_FIRST, GL_TRUE);
266 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
267
268 glRasterPos2i(0, 0);
269 glBitmap(OPENGL_WIDTH, OPENGL_HEIGHT, 0, 3, 0.0, 0.0, OpenGL_bits);
270 }
271
272 static void Triangles(void)
273 {
274
275 glBegin(GL_TRIANGLES);
276 SetColor(COLOR_GREEN);
277 glVertex2i(-boxW/4, -boxH/4);
278 SetColor(COLOR_RED);
279 glVertex2i(-boxW/8, -boxH/16);
280 SetColor(COLOR_BLUE);
281 glVertex2i(boxW/8, -boxH/16);
282
283 SetColor(COLOR_GREEN);
284 glVertex2i(-boxW/4, boxH/4);
285 SetColor(COLOR_RED);
286 glVertex2i(-boxW/8, boxH/16);
287 SetColor(COLOR_BLUE);
288 glVertex2i(boxW/8, boxH/16);
289 glEnd();
290
291 glBegin(GL_TRIANGLES);
292 glVertex2i(0, 0);
293 glVertex2i(-100, 100);
294 glEnd();
295 }
296
297 static void TriangleStrip(void)
298 {
299
300 glBegin(GL_TRIANGLE_STRIP);
301 SetColor(COLOR_GREEN);
302 glVertex2i(-boxW/4, -boxH/4);
303 SetColor(COLOR_RED);
304 glVertex2i(-boxW/4, boxH/4);
305 SetColor(COLOR_BLUE);
306 glVertex2i(0, -boxH/4);
307 SetColor(COLOR_WHITE);
308 glVertex2i(0, boxH/4);
309 SetColor(COLOR_CYAN);
310 glVertex2i(boxW/4, -boxH/4);
311 SetColor(COLOR_YELLOW);
312 glVertex2i(boxW/4, boxH/4);
313 glEnd();
314
315 glBegin(GL_TRIANGLE_STRIP);
316 glVertex2i(0, 0);
317 glVertex2i(-100, 100);
318 glEnd();
319 }
320
321 static void TriangleFan(void)
322 {
323 GLint vx[8][2];
324 GLint x0, y0, x1, y1, x2, y2, x3, y3;
325 GLint i;
326
327 y0 = -boxH/4;
328 y1 = y0 + boxH/2/3;
329 y2 = y1 + boxH/2/3;
330 y3 = boxH/4;
331 x0 = -boxW/4;
332 x1 = x0 + boxW/2/3;
333 x2 = x1 + boxW/2/3;
334 x3 = boxW/4;
335
336 vx[0][0] = x0; vx[0][1] = y1;
337 vx[1][0] = x0; vx[1][1] = y2;
338 vx[2][0] = x1; vx[2][1] = y3;
339 vx[3][0] = x2; vx[3][1] = y3;
340 vx[4][0] = x3; vx[4][1] = y2;
341 vx[5][0] = x3; vx[5][1] = y1;
342 vx[6][0] = x2; vx[6][1] = y0;
343 vx[7][0] = x1; vx[7][1] = y0;
344
345 glBegin(GL_TRIANGLE_FAN);
346 SetColor(COLOR_WHITE);
347 glVertex2i(0, 0);
348 for (i = 0; i < 8; i++) {
349 SetColor(COLOR_WHITE-i);
350 glVertex2iv(vx[i]);
351 }
352 glEnd();
353
354 glBegin(GL_TRIANGLE_FAN);
355 glVertex2i(0, 0);
356 glVertex2i(-100, 100);
357 glEnd();
358 }
359
360 static void Rect(void)
361 {
362
363 SetColor(COLOR_GREEN);
364 glRecti(-boxW/4, -boxH/4, boxW/4, boxH/4);
365 }
366
367 static void PolygonFunc(void)
368 {
369 GLint vx[8][2];
370 GLint x0, y0, x1, y1, x2, y2, x3, y3;
371 GLint i;
372
373 y0 = -boxH/4;
374 y1 = y0 + boxH/2/3;
375 y2 = y1 + boxH/2/3;
376 y3 = boxH/4;
377 x0 = -boxW/4;
378 x1 = x0 + boxW/2/3;
379 x2 = x1 + boxW/2/3;
380 x3 = boxW/4;
381
382 vx[0][0] = x0; vx[0][1] = y1;
383 vx[1][0] = x0; vx[1][1] = y2;
384 vx[2][0] = x1; vx[2][1] = y3;
385 vx[3][0] = x2; vx[3][1] = y3;
386 vx[4][0] = x3; vx[4][1] = y2;
387 vx[5][0] = x3; vx[5][1] = y1;
388 vx[6][0] = x2; vx[6][1] = y0;
389 vx[7][0] = x1; vx[7][1] = y0;
390
391 glBegin(GL_POLYGON);
392 for (i = 0; i < 8; i++) {
393 SetColor(COLOR_WHITE-i);
394 glVertex2iv(vx[i]);
395 }
396 glEnd();
397
398 glBegin(GL_POLYGON);
399 glVertex2i(0, 0);
400 glVertex2i(100, 100);
401 glEnd();
402 }
403
404 static void Quads(void)
405 {
406
407 glBegin(GL_QUADS);
408 SetColor(COLOR_GREEN);
409 glVertex2i(-boxW/4, -boxH/4);
410 SetColor(COLOR_RED);
411 glVertex2i(-boxW/8, -boxH/16);
412 SetColor(COLOR_BLUE);
413 glVertex2i(boxW/8, -boxH/16);
414 SetColor(COLOR_WHITE);
415 glVertex2i(boxW/4, -boxH/4);
416
417 SetColor(COLOR_GREEN);
418 glVertex2i(-boxW/4, boxH/4);
419 SetColor(COLOR_RED);
420 glVertex2i(-boxW/8, boxH/16);
421 SetColor(COLOR_BLUE);
422 glVertex2i(boxW/8, boxH/16);
423 SetColor(COLOR_WHITE);
424 glVertex2i(boxW/4, boxH/4);
425 glEnd();
426
427 glBegin(GL_QUADS);
428 glVertex2i(0, 0);
429 glVertex2i(100, 100);
430 glVertex2i(-100, 100);
431 glEnd();
432 }
433
434 static void QuadStrip(void)
435 {
436
437 glBegin(GL_QUAD_STRIP);
438 SetColor(COLOR_GREEN);
439 glVertex2i(-boxW/4, -boxH/4);
440 SetColor(COLOR_RED);
441 glVertex2i(-boxW/4, boxH/4);
442 SetColor(COLOR_BLUE);
443 glVertex2i(0, -boxH/4);
444 SetColor(COLOR_WHITE);
445 glVertex2i(0, boxH/4);
446 SetColor(COLOR_CYAN);
447 glVertex2i(boxW/4, -boxH/4);
448 SetColor(COLOR_YELLOW);
449 glVertex2i(boxW/4, boxH/4);
450 glEnd();
451
452 glBegin(GL_QUAD_STRIP);
453 glVertex2i(0, 0);
454 glVertex2i(100, 100);
455 glVertex2i(-100, 100);
456 glEnd();
457 }
458
459 static void Draw(EGLDisplay dpy, EGLSurface surf)
460 {
461
462 glViewport(0, 0, windW, windH);
463 glDisable(GL_SCISSOR_TEST);
464
465 glPushAttrib(GL_COLOR_BUFFER_BIT);
466
467 glColorMask(1, 1, 1, 1);
468 glIndexMask(~0);
469
470 glClearColor(0.0, 0.0, 0.0, 0.0);
471 glClear(GL_COLOR_BUFFER_BIT);
472
473 glPopAttrib();
474
475 if (mode1) {
476 glShadeModel(GL_SMOOTH);
477 } else {
478 glShadeModel(GL_FLAT);
479 }
480
481 if (mode2) {
482 glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
483 } else {
484 glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
485 }
486
487 Viewport(0, 0); Point();
488 Viewport(0, 1); Lines();
489 Viewport(0, 2); LineStrip();
490 Viewport(0, 3); LineLoop();
491
492 Viewport(1, 0); Bitmap();
493
494 Viewport(1, 1); TriangleFan();
495 Viewport(1, 2); Triangles();
496 Viewport(1, 3); TriangleStrip();
497
498 Viewport(2, 0); Rect();
499 Viewport(2, 1); PolygonFunc();
500 Viewport(2, 2); Quads();
501 Viewport(2, 3); QuadStrip();
502
503 glFlush();
504
505 if (doubleBuffer) {
506 eglSwapBuffers(dpy, surf);
507 }
508 }
509
510 static void
511 write_ppm(const char *filename, const GLubyte *buffer, int width, int height)
512 {
513 const int binary = 0;
514 FILE *f = fopen( filename, "w" );
515 if (f) {
516 int i, x, y;
517 const GLubyte *ptr = buffer;
518 if (binary) {
519 fprintf(f,"P6\n");
520 fprintf(f,"# ppm-file created by osdemo.c\n");
521 fprintf(f,"%i %i\n", width,height);
522 fprintf(f,"255\n");
523 fclose(f);
524 f = fopen( filename, "ab" ); /* reopen in binary append mode */
525 for (y=height-1; y>=0; y--) {
526 for (x=0; x<width; x++) {
527 i = (y*width + x) * 4;
528 fputc(ptr[i], f); /* write red */
529 fputc(ptr[i+1], f); /* write green */
530 fputc(ptr[i+2], f); /* write blue */
531 }
532 }
533 }
534 else {
535 /*ASCII*/
536 int counter = 0;
537 fprintf(f,"P3\n");
538 fprintf(f,"# ascii ppm file created by osdemo.c\n");
539 fprintf(f,"%i %i\n", width, height);
540 fprintf(f,"255\n");
541 for (y=height-1; y>=0; y--) {
542 for (x=0; x<width; x++) {
543 i = (y*width + x) * 4;
544 fprintf(f, " %3d %3d %3d", ptr[i], ptr[i+1], ptr[i+2]);
545 counter++;
546 if (counter % 5 == 0)
547 fprintf(f, "\n");
548 }
549 }
550 }
551 fclose(f);
552 }
553 }
554
555 int
556 main(int argc, char *argv[])
557 {
558 int maj, min;
559 EGLContext ctx;
560 EGLSurface screen_surf;
561 EGLConfig configs[10];
562 EGLScreenMESA screen;
563 EGLModeMESA mode;
564 EGLint numConfigs, count;
565 EGLBoolean b;
566 const GLubyte *bitmap;
567 EGLint screenAttribs[32];
568 EGLint i;
569
570 EGLDisplay d = eglGetDisplay(EGL_DEFAULT_DISPLAY);
571 assert(d);
572
573 if (!eglInitialize(d, &maj, &min)) {
574 printf("demo: eglInitialize failed\n");
575 exit(1);
576 }
577
578 printf("EGL version = %d.%d\n", maj, min);
579 printf("EGL_VENDOR = %s\n", eglQueryString(d, EGL_VENDOR));
580 if (!strstr(eglQueryString(d, EGL_EXTENSIONS),
581 "EGL_MESA_screen_surface")) {
582 printf("EGL_MESA_screen_surface is not supported\n");
583 exit(1);
584 }
585
586 eglGetConfigs(d, configs, 10, &numConfigs);
587 eglGetScreensMESA(d, &screen, 1, &count);
588 eglGetModesMESA(d, screen, &mode, 1, &count);
589
590 eglBindAPI(EGL_OPENGL_API);
591 ctx = eglCreateContext(d, configs[0], EGL_NO_CONTEXT, NULL);
592 if (ctx == EGL_NO_CONTEXT) {
593 printf("failed to create context\n");
594 return 0;
595 }
596
597 i = 0;
598 screenAttribs[i++] = EGL_WIDTH;
599 eglGetModeAttribMESA(d, mode, EGL_WIDTH, &screenAttribs[i++]);
600 screenAttribs[i++] = EGL_HEIGHT;
601 eglGetModeAttribMESA(d, mode, EGL_HEIGHT, &screenAttribs[i++]);
602 screenAttribs[i] = EGL_NONE;
603
604 screen_surf = eglCreateScreenSurfaceMESA(d, configs[0], screenAttribs);
605 if (screen_surf == EGL_NO_SURFACE) {
606 printf("failed to create screen surface\n");
607 return 0;
608 }
609
610 eglShowScreenSurfaceMESA(d, screen, screen_surf, mode);
611
612 b = eglMakeCurrent(d, screen_surf, screen_surf, ctx);
613 if (!b) {
614 printf("make current failed\n");
615 return 0;
616 }
617 glViewport(0, 0, 1024, 768);
618
619
620 Init();
621 Reshape(1024, 768);
622
623 /* some drivers crash when rendering to front buffer */
624 #if 0
625 glDrawBuffer( GL_FRONT );
626 glClearColor( 0, 1.0, 0, 1);
627
628 glClear( GL_COLOR_BUFFER_BIT );
629 #endif
630
631 doubleBuffer = 1;
632 glDrawBuffer( GL_BACK );
633
634 Draw(d, screen_surf);
635 sleep(2);
636
637 /* TODO EGL_KHR_lock_surface */
638 bitmap = NULL;
639 if (bitmap)
640 write_ppm("dump.ppm", bitmap, 1024, 768);
641
642 eglDestroySurface(d, screen_surf);
643 eglDestroyContext(d, ctx);
644 eglTerminate(d);
645
646 return 0;
647 }