Clone of mesa.
選択できるのは25トピックまでです。 トピックは、先頭が英数字で、英数字とダッシュ('-')を使用した35文字以内のものにしてください。

msaa.c 11KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442
  1. /*
  2. * Copyright (C) 2008 Brian Paul All Rights Reserved.
  3. *
  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:
  10. *
  11. * The above copyright notice and this permission notice shall be included
  12. * in all copies or substantial portions of the Software.
  13. *
  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.
  20. */
  21. /*
  22. * Test MSAA with X/EGL and OpenGL ES 1.x
  23. * Brian Paul
  24. * 15 September 2008
  25. */
  26. #define USE_FULL_GL 0
  27. #include <assert.h>
  28. #include <math.h>
  29. #include <stdlib.h>
  30. #include <stdio.h>
  31. #include <string.h>
  32. #include <X11/Xlib.h>
  33. #include <X11/Xutil.h>
  34. #include <X11/keysym.h>
  35. #if USE_FULL_GL
  36. #include <GL/gl.h> /* use full OpenGL */
  37. #else
  38. #include <GLES/gl.h> /* use OpenGL ES 1.x */
  39. #include <GLES/glext.h>
  40. #endif
  41. #include <EGL/egl.h>
  42. static GLfloat view_rotx = 0.0, view_roty = 0.0, view_rotz = 0.0;
  43. static GLboolean AA = 0*GL_TRUE;
  44. static void
  45. draw(void)
  46. {
  47. float a;
  48. static const GLfloat verts[4][2] = {
  49. { -1, -.1 },
  50. { 1, -.1 },
  51. { -1, .1 },
  52. { 1, .1 }
  53. };
  54. static const GLfloat colors[4][4] = {
  55. { 1, 0, 0, 1 },
  56. { 0, 1, 0, 1 },
  57. { 0, 0, 1, 1 },
  58. { 1, 0, 1, 1 }
  59. };
  60. if (AA) {
  61. printf("MSAA enabled\n");
  62. glEnable(GL_MULTISAMPLE);
  63. }
  64. else {
  65. printf("MSAA disabled\n");
  66. glDisable(GL_MULTISAMPLE);
  67. }
  68. glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  69. glPushMatrix();
  70. glRotatef(view_rotx, 1, 0, 0);
  71. glRotatef(view_roty, 0, 1, 0);
  72. glRotatef(view_rotz, 0, 0, 1);
  73. {
  74. glVertexPointer(2, GL_FLOAT, 0, verts);
  75. glColorPointer(4, GL_FLOAT, 0, colors);
  76. glEnableClientState(GL_VERTEX_ARRAY);
  77. glEnableClientState(GL_COLOR_ARRAY);
  78. for (a = 0; a < 360; a += 20.0) {
  79. glPushMatrix();
  80. glRotatef(a, 0, 0, 1);
  81. glTranslatef(1.5, 0, 0);
  82. /* draw triangle */
  83. glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
  84. glPopMatrix();
  85. }
  86. glDisableClientState(GL_VERTEX_ARRAY);
  87. glDisableClientState(GL_COLOR_ARRAY);
  88. }
  89. glPopMatrix();
  90. }
  91. /* new window size or exposure */
  92. static void
  93. reshape(int width, int height)
  94. {
  95. GLfloat ary = 3.0;
  96. GLfloat arx = ary * (GLfloat) width / (GLfloat) height;
  97. glViewport(0, 0, (GLint) width, (GLint) height);
  98. glMatrixMode(GL_PROJECTION);
  99. glLoadIdentity();
  100. #ifdef GL_VERSION_ES_CM_1_0
  101. glOrthof(-arx, arx, -ary, ary, -1.0, 1.0);
  102. #else
  103. glOrtho(-arx, arx, -ary, ary, -1.0, 1.0);
  104. #endif
  105. glMatrixMode(GL_MODELVIEW);
  106. glLoadIdentity();
  107. }
  108. static void
  109. init(void)
  110. {
  111. printf("Press 'a' to toggle multisample antialiasing\n");
  112. printf("Press 'Esc' to exit\n");
  113. }
  114. /*
  115. * Create an RGB, double-buffered X window.
  116. * Return the window and context handles.
  117. */
  118. static void
  119. make_x_window(Display *x_dpy, EGLDisplay egl_dpy,
  120. const char *name,
  121. int x, int y, int width, int height,
  122. Window *winRet,
  123. EGLContext *ctxRet,
  124. EGLSurface *surfRet)
  125. {
  126. static const EGLint attribs[] = {
  127. EGL_RED_SIZE, 1,
  128. EGL_GREEN_SIZE, 1,
  129. EGL_BLUE_SIZE, 1,
  130. EGL_DEPTH_SIZE, 1,
  131. EGL_SAMPLES, 1,
  132. EGL_SAMPLE_BUFFERS, 1,
  133. EGL_NONE
  134. };
  135. int scrnum;
  136. XSetWindowAttributes attr;
  137. unsigned long mask;
  138. Window root;
  139. Window win;
  140. XVisualInfo *visInfo, visTemplate;
  141. int num_visuals;
  142. EGLContext ctx;
  143. EGLConfig config;
  144. EGLint num_configs;
  145. EGLint vid;
  146. scrnum = DefaultScreen( x_dpy );
  147. root = RootWindow( x_dpy, scrnum );
  148. if (!eglChooseConfig( egl_dpy, attribs, &config, 1, &num_configs)) {
  149. printf("Error: couldn't get an EGL visual config\n");
  150. exit(1);
  151. }
  152. if (num_configs < 1) {
  153. printf("Error: Unable to find multisample pixel format.\n");
  154. printf("Try running glxinfo to see if your server supports MSAA.\n");
  155. exit(1);
  156. }
  157. if (!eglGetConfigAttrib(egl_dpy, config, EGL_NATIVE_VISUAL_ID, &vid)) {
  158. printf("Error: eglGetConfigAttrib() failed\n");
  159. exit(1);
  160. }
  161. /* The X window visual must match the EGL config */
  162. visTemplate.visualid = vid;
  163. visInfo = XGetVisualInfo(x_dpy, VisualIDMask, &visTemplate, &num_visuals);
  164. if (!visInfo) {
  165. printf("Error: couldn't get X visual\n");
  166. exit(1);
  167. }
  168. /* window attributes */
  169. attr.background_pixel = 0;
  170. attr.border_pixel = 0;
  171. attr.colormap = XCreateColormap( x_dpy, root, visInfo->visual, AllocNone);
  172. attr.event_mask = StructureNotifyMask | ExposureMask | KeyPressMask;
  173. mask = CWBackPixel | CWBorderPixel | CWColormap | CWEventMask;
  174. win = XCreateWindow( x_dpy, root, 0, 0, width, height,
  175. 0, visInfo->depth, InputOutput,
  176. visInfo->visual, mask, &attr );
  177. /* set hints and properties */
  178. {
  179. XSizeHints sizehints;
  180. sizehints.x = x;
  181. sizehints.y = y;
  182. sizehints.width = width;
  183. sizehints.height = height;
  184. sizehints.flags = USSize | USPosition;
  185. XSetNormalHints(x_dpy, win, &sizehints);
  186. XSetStandardProperties(x_dpy, win, name, name,
  187. None, (char **)NULL, 0, &sizehints);
  188. }
  189. #if USE_FULL_GL
  190. eglBindAPI(EGL_OPENGL_API);
  191. #else
  192. eglBindAPI(EGL_OPENGL_ES_API);
  193. #endif
  194. ctx = eglCreateContext(egl_dpy, config, EGL_NO_CONTEXT, NULL );
  195. if (!ctx) {
  196. printf("Error: eglCreateContext failed\n");
  197. exit(1);
  198. }
  199. *surfRet = eglCreateWindowSurface(egl_dpy, config, win, NULL);
  200. if (!*surfRet) {
  201. printf("Error: eglCreateWindowSurface failed\n");
  202. exit(1);
  203. }
  204. XFree(visInfo);
  205. *winRet = win;
  206. *ctxRet = ctx;
  207. }
  208. static void
  209. event_loop(Display *dpy, Window win,
  210. EGLDisplay egl_dpy, EGLSurface egl_surf)
  211. {
  212. while (1) {
  213. int redraw = 0;
  214. XEvent event;
  215. XNextEvent(dpy, &event);
  216. switch (event.type) {
  217. case Expose:
  218. redraw = 1;
  219. break;
  220. case ConfigureNotify:
  221. reshape(event.xconfigure.width, event.xconfigure.height);
  222. break;
  223. case KeyPress:
  224. {
  225. char buffer[10];
  226. int r, code;
  227. code = XLookupKeysym(&event.xkey, 0);
  228. if (code == XK_Left) {
  229. view_roty += 5.0;
  230. }
  231. else if (code == XK_Right) {
  232. view_roty -= 5.0;
  233. }
  234. else if (code == XK_Up) {
  235. view_rotx += 5.0;
  236. }
  237. else if (code == XK_Down) {
  238. view_rotx -= 5.0;
  239. }
  240. else {
  241. r = XLookupString(&event.xkey, buffer, sizeof(buffer),
  242. NULL, NULL);
  243. if (buffer[0] == 'a') {
  244. AA = !AA;
  245. redraw = 1;
  246. }
  247. else if (buffer[0] == 27) {
  248. /* escape */
  249. return;
  250. }
  251. }
  252. }
  253. redraw = 1;
  254. break;
  255. default:
  256. ; /*no-op*/
  257. }
  258. if (redraw) {
  259. draw();
  260. eglSwapBuffers(egl_dpy, egl_surf);
  261. }
  262. }
  263. }
  264. static void
  265. usage(void)
  266. {
  267. printf("Usage:\n");
  268. printf(" -display <displayname> set the display to run on\n");
  269. printf(" -info display OpenGL renderer info\n");
  270. }
  271. int
  272. main(int argc, char *argv[])
  273. {
  274. const int winWidth = 600, winHeight = 600;
  275. Display *x_dpy;
  276. Window win;
  277. EGLSurface egl_surf;
  278. EGLContext egl_ctx;
  279. EGLDisplay egl_dpy;
  280. char *dpyName = NULL;
  281. GLboolean printInfo = GL_FALSE;
  282. EGLint egl_major, egl_minor;
  283. int i;
  284. const char *s;
  285. static struct {
  286. char *name;
  287. GLenum value;
  288. enum {GetString, GetInteger} type;
  289. } info_items[] = {
  290. {"GL_RENDERER", GL_RENDERER, GetString},
  291. {"GL_VERSION", GL_VERSION, GetString},
  292. {"GL_VENDOR", GL_VENDOR, GetString},
  293. {"GL_EXTENSIONS", GL_EXTENSIONS, GetString},
  294. {"GL_MAX_PALETTE_MATRICES_OES", GL_MAX_PALETTE_MATRICES_OES, GetInteger},
  295. {"GL_MAX_VERTEX_UNITS_OES", GL_MAX_VERTEX_UNITS_OES, GetInteger},
  296. };
  297. for (i = 1; i < argc; i++) {
  298. if (strcmp(argv[i], "-display") == 0) {
  299. dpyName = argv[i+1];
  300. i++;
  301. }
  302. else if (strcmp(argv[i], "-info") == 0) {
  303. printInfo = GL_TRUE;
  304. }
  305. else {
  306. usage();
  307. return -1;
  308. }
  309. }
  310. x_dpy = XOpenDisplay(dpyName);
  311. if (!x_dpy) {
  312. printf("Error: couldn't open display %s\n",
  313. dpyName ? dpyName : getenv("DISPLAY"));
  314. return -1;
  315. }
  316. egl_dpy = eglGetDisplay(x_dpy);
  317. if (!egl_dpy) {
  318. printf("Error: eglGetDisplay() failed\n");
  319. return -1;
  320. }
  321. if (!eglInitialize(egl_dpy, &egl_major, &egl_minor)) {
  322. printf("Error: eglInitialize() failed\n");
  323. return -1;
  324. }
  325. s = eglQueryString(egl_dpy, EGL_VERSION);
  326. printf("EGL_VERSION = %s\n", s);
  327. s = eglQueryString(egl_dpy, EGL_VENDOR);
  328. printf("EGL_VENDOR = %s\n", s);
  329. s = eglQueryString(egl_dpy, EGL_EXTENSIONS);
  330. printf("EGL_EXTENSIONS = %s\n", s);
  331. s = eglQueryString(egl_dpy, EGL_CLIENT_APIS);
  332. printf("EGL_CLIENT_APIS = %s\n", s);
  333. make_x_window(x_dpy, egl_dpy,
  334. "msaa", 0, 0, winWidth, winHeight,
  335. &win, &egl_ctx, &egl_surf);
  336. XMapWindow(x_dpy, win);
  337. if (!eglMakeCurrent(egl_dpy, egl_surf, egl_surf, egl_ctx)) {
  338. printf("Error: eglMakeCurrent() failed\n");
  339. return -1;
  340. }
  341. if (printInfo) {
  342. for (i = 0; i < sizeof(info_items)/sizeof(info_items[0]); i++) {
  343. switch (info_items[i].type) {
  344. case GetString:
  345. printf("%s = %s\n", info_items[i].name, (char *)glGetString(info_items[i].value));
  346. break;
  347. case GetInteger: {
  348. GLint rv = -1;
  349. glGetIntegerv(info_items[i].value, &rv);
  350. printf("%s = %d\n", info_items[i].name, rv);
  351. break;
  352. }
  353. }
  354. }
  355. };
  356. init();
  357. /* Set initial projection/viewing transformation.
  358. * We can't be sure we'll get a ConfigureNotify event when the window
  359. * first appears.
  360. */
  361. reshape(winWidth, winHeight);
  362. event_loop(x_dpy, win, egl_dpy, egl_surf);
  363. eglDestroyContext(egl_dpy, egl_ctx);
  364. eglDestroySurface(egl_dpy, egl_surf);
  365. eglTerminate(egl_dpy);
  366. XDestroyWindow(x_dpy, win);
  367. XCloseDisplay(x_dpy);
  368. return 0;
  369. }