2 * Copyright (C) 2008 Brian Paul All Rights Reserved.
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
11 * The above copyright notice and this permission notice shall be included
12 * in all copies or substantial portions of the Software.
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
18 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
19 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23 * Test MSAA with X/EGL and OpenGL ES 1.x
37 #include <X11/Xutil.h>
38 #include <X11/keysym.h>
40 #include "gl_wrap.h" /* use full OpenGL */
42 #include <GLES/gl.h> /* use OpenGL ES 1.x */
43 #include <GLES/glext.h>
49 static GLfloat view_rotx
= 0.0, view_roty
= 0.0, view_rotz
= 0.0;
50 static GLboolean AA
= 0*GL_TRUE
;
58 static const GLfloat verts
[4][2] = {
64 static const GLfloat colors
[4][4] = {
72 printf("MSAA enabled\n");
73 glEnable(GL_MULTISAMPLE
);
76 printf("MSAA disabled\n");
77 glDisable(GL_MULTISAMPLE
);
80 glClear(GL_COLOR_BUFFER_BIT
| GL_DEPTH_BUFFER_BIT
);
83 glRotatef(view_rotx
, 1, 0, 0);
84 glRotatef(view_roty
, 0, 1, 0);
85 glRotatef(view_rotz
, 0, 0, 1);
88 glVertexPointer(2, GL_FLOAT
, 0, verts
);
89 glColorPointer(4, GL_FLOAT
, 0, colors
);
91 glEnableClientState(GL_VERTEX_ARRAY
);
92 glEnableClientState(GL_COLOR_ARRAY
);
94 for (a
= 0; a
< 360; a
+= 20.0) {
97 glRotatef(a
, 0, 0, 1);
98 glTranslatef(1.5, 0, 0);
101 glDrawArrays(GL_TRIANGLE_STRIP
, 0, 4);
106 glDisableClientState(GL_VERTEX_ARRAY
);
107 glDisableClientState(GL_COLOR_ARRAY
);
114 /* new window size or exposure */
116 reshape(int width
, int height
)
119 GLfloat arx
= ary
* (GLfloat
) width
/ (GLfloat
) height
;
121 glViewport(0, 0, (GLint
) width
, (GLint
) height
);
123 glMatrixMode(GL_PROJECTION
);
125 #ifdef GL_VERSION_ES_CM_1_0
126 glOrthof(-arx
, arx
, -ary
, ary
, -1.0, 1.0);
128 glOrtho(-arx
, arx
, -ary
, ary
, -1.0, 1.0);
131 glMatrixMode(GL_MODELVIEW
);
140 printf("Press 'a' to toggle multisample antialiasing\n");
141 printf("Press 'Esc' to exit\n");
146 * Create an RGB, double-buffered X window.
147 * Return the window and context handles.
150 make_x_window(Display
*x_dpy
, EGLDisplay egl_dpy
,
152 int x
, int y
, int width
, int height
,
157 static const EGLint attribs
[] = {
163 EGL_SAMPLE_BUFFERS
, 1,
168 XSetWindowAttributes attr
;
172 XVisualInfo
*visInfo
, visTemplate
;
179 scrnum
= DefaultScreen( x_dpy
);
180 root
= RootWindow( x_dpy
, scrnum
);
182 if (!eglChooseConfig( egl_dpy
, attribs
, &config
, 1, &num_configs
)) {
183 printf("Error: couldn't get an EGL visual config\n");
187 if (num_configs
< 1) {
188 printf("Error: Unable to find multisample pixel format.\n");
189 printf("Try running glxinfo to see if your server supports MSAA.\n");
193 if (!eglGetConfigAttrib(egl_dpy
, config
, EGL_NATIVE_VISUAL_ID
, &vid
)) {
194 printf("Error: eglGetConfigAttrib() failed\n");
198 /* The X window visual must match the EGL config */
199 visTemplate
.visualid
= vid
;
200 visInfo
= XGetVisualInfo(x_dpy
, VisualIDMask
, &visTemplate
, &num_visuals
);
202 printf("Error: couldn't get X visual\n");
206 /* window attributes */
207 attr
.background_pixel
= 0;
208 attr
.border_pixel
= 0;
209 attr
.colormap
= XCreateColormap( x_dpy
, root
, visInfo
->visual
, AllocNone
);
210 attr
.event_mask
= StructureNotifyMask
| ExposureMask
| KeyPressMask
;
211 mask
= CWBackPixel
| CWBorderPixel
| CWColormap
| CWEventMask
;
213 win
= XCreateWindow( x_dpy
, root
, 0, 0, width
, height
,
214 0, visInfo
->depth
, InputOutput
,
215 visInfo
->visual
, mask
, &attr
);
217 /* set hints and properties */
219 XSizeHints sizehints
;
222 sizehints
.width
= width
;
223 sizehints
.height
= height
;
224 sizehints
.flags
= USSize
| USPosition
;
225 XSetNormalHints(x_dpy
, win
, &sizehints
);
226 XSetStandardProperties(x_dpy
, win
, name
, name
,
227 None
, (char **)NULL
, 0, &sizehints
);
231 eglBindAPI(EGL_OPENGL_API
);
233 eglBindAPI(EGL_OPENGL_ES_API
);
236 ctx
= eglCreateContext(egl_dpy
, config
, EGL_NO_CONTEXT
, NULL
);
238 printf("Error: eglCreateContext failed\n");
242 *surfRet
= eglCreateWindowSurface(egl_dpy
, config
, win
, NULL
);
245 printf("Error: eglCreateWindowSurface failed\n");
257 event_loop(Display
*dpy
, Window win
,
258 EGLDisplay egl_dpy
, EGLSurface egl_surf
)
264 XNextEvent(dpy
, &event
);
266 switch (event
.type
) {
270 case ConfigureNotify
:
271 reshape(event
.xconfigure
.width
, event
.xconfigure
.height
);
277 code
= XLookupKeysym(&event
.xkey
, 0);
278 if (code
== XK_Left
) {
281 else if (code
== XK_Right
) {
284 else if (code
== XK_Up
) {
287 else if (code
== XK_Down
) {
291 r
= XLookupString(&event
.xkey
, buffer
, sizeof(buffer
),
293 if (buffer
[0] == 'a') {
297 else if (buffer
[0] == 27) {
311 eglSwapBuffers(egl_dpy
, egl_surf
);
321 printf(" -display <displayname> set the display to run on\n");
322 printf(" -info display OpenGL renderer info\n");
327 main(int argc
, char *argv
[])
329 const int winWidth
= 600, winHeight
= 600;
335 char *dpyName
= NULL
;
336 GLboolean printInfo
= GL_FALSE
;
337 EGLint egl_major
, egl_minor
;
344 enum {GetString
, GetInteger
} type
;
346 {"GL_RENDERER", GL_RENDERER
, GetString
},
347 {"GL_VERSION", GL_VERSION
, GetString
},
348 {"GL_VENDOR", GL_VENDOR
, GetString
},
349 {"GL_EXTENSIONS", GL_EXTENSIONS
, GetString
},
350 {"GL_MAX_PALETTE_MATRICES_OES", GL_MAX_PALETTE_MATRICES_OES
, GetInteger
},
351 {"GL_MAX_VERTEX_UNITS_OES", GL_MAX_VERTEX_UNITS_OES
, GetInteger
},
354 for (i
= 1; i
< argc
; i
++) {
355 if (strcmp(argv
[i
], "-display") == 0) {
359 else if (strcmp(argv
[i
], "-info") == 0) {
368 x_dpy
= XOpenDisplay(dpyName
);
370 printf("Error: couldn't open display %s\n",
371 dpyName
? dpyName
: getenv("DISPLAY"));
375 egl_dpy
= eglGetDisplay(x_dpy
);
377 printf("Error: eglGetDisplay() failed\n");
381 if (!eglInitialize(egl_dpy
, &egl_major
, &egl_minor
)) {
382 printf("Error: eglInitialize() failed\n");
386 s
= eglQueryString(egl_dpy
, EGL_VERSION
);
387 printf("EGL_VERSION = %s\n", s
);
389 s
= eglQueryString(egl_dpy
, EGL_VENDOR
);
390 printf("EGL_VENDOR = %s\n", s
);
392 s
= eglQueryString(egl_dpy
, EGL_EXTENSIONS
);
393 printf("EGL_EXTENSIONS = %s\n", s
);
395 s
= eglQueryString(egl_dpy
, EGL_CLIENT_APIS
);
396 printf("EGL_CLIENT_APIS = %s\n", s
);
398 make_x_window(x_dpy
, egl_dpy
,
399 "msaa", 0, 0, winWidth
, winHeight
,
400 &win
, &egl_ctx
, &egl_surf
);
402 XMapWindow(x_dpy
, win
);
403 if (!eglMakeCurrent(egl_dpy
, egl_surf
, egl_surf
, egl_ctx
)) {
404 printf("Error: eglMakeCurrent() failed\n");
409 for (i
= 0; i
< sizeof(info_items
)/sizeof(info_items
[0]); i
++) {
410 switch (info_items
[i
].type
) {
412 printf("%s = %s\n", info_items
[i
].name
, (char *)glGetString(info_items
[i
].value
));
416 glGetIntegerv(info_items
[i
].value
, &rv
);
417 printf("%s = %d\n", info_items
[i
].name
, rv
);
425 /* Set initial projection/viewing transformation.
426 * We can't be sure we'll get a ConfigureNotify event when the window
429 reshape(winWidth
, winHeight
);
431 event_loop(x_dpy
, win
, egl_dpy
, egl_surf
);
433 eglDestroyContext(egl_dpy
, egl_ctx
);
434 eglDestroySurface(egl_dpy
, egl_surf
);
435 eglTerminate(egl_dpy
);
438 XDestroyWindow(x_dpy
, win
);
439 XCloseDisplay(x_dpy
);