2 * Simple demo for eglBindTexImage. Based on xegl_tri.c by
4 * Copyright (C) 2008 Brian Paul All Rights Reserved.
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the "Software"),
8 * to deal in the Software without restriction, including without limitation
9 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10 * and/or sell copies of the Software, and to permit persons to whom the
11 * Software is furnished to do so, subject to the following conditions:
13 * The above copyright notice and this permission notice shall be included
14 * in all copies or substantial portions of the Software.
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
17 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
20 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
21 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25 * The spec says that eglBindTexImage supports only OpenGL ES context, but this
26 * demo uses OpenGL context. Keep in mind that this is non-standard.
34 #include <X11/Xutil.h>
35 #include <X11/keysym.h>
39 static EGLDisplay dpy
;
40 static EGLContext ctx_win
, ctx_pbuf
;
41 static EGLSurface surf_win
, surf_pbuf
;
42 static GLuint tex_pbuf
;
44 static GLfloat view_rotx
= 0.0, view_roty
= 0.0, view_rotz
= 0.0;
45 static GLboolean blend
= GL_TRUE
;
46 static GLuint color_flow
;
49 make_pbuffer(int width
, int height
)
51 static const EGLint config_attribs
[] = {
55 EGL_BIND_TO_TEXTURE_RGB
, EGL_TRUE
,
58 EGLint pbuf_attribs
[] = {
61 EGL_TEXTURE_FORMAT
, EGL_TEXTURE_RGB
,
62 EGL_TEXTURE_TARGET
, EGL_TEXTURE_2D
,
68 if (!eglChooseConfig(dpy
, config_attribs
, &config
, 1, &num_configs
)) {
69 printf("Error: couldn't get an EGL visual config for pbuffer\n");
73 eglBindAPI(EGL_OPENGL_API
);
74 ctx_pbuf
= eglCreateContext(dpy
, config
, EGL_NO_CONTEXT
, NULL
);
75 surf_pbuf
= eglCreatePbufferSurface(dpy
, config
, pbuf_attribs
);
76 if (surf_pbuf
== EGL_NO_SURFACE
) {
77 printf("failed to allocate pbuffer\n");
81 glGenTextures(1, &tex_pbuf
);
87 static int initialized
;
89 eglMakeCurrent(dpy
, surf_pbuf
, surf_pbuf
, ctx_pbuf
);
96 eglQuerySurface(dpy
, surf_pbuf
, EGL_WIDTH
, &width
);
97 eglQuerySurface(dpy
, surf_pbuf
, EGL_WIDTH
, &height
);
98 ar
= (GLfloat
) width
/ (GLfloat
) height
;
100 glViewport(0, 0, (GLint
) width
, (GLint
) height
);
102 glMatrixMode(GL_PROJECTION
);
104 glFrustum(-ar
, ar
, -1, 1, 1.0, 10.0);
106 glMatrixMode(GL_MODELVIEW
);
110 glScalef(1.0, -1.0, 1.0);
112 glTranslatef(0.0, 0.0, -5.0);
114 glClearColor(0.2, 0.2, 0.2, 0.0);
119 make_window(Display
*x_dpy
, const char *name
,
120 int x
, int y
, int width
, int height
,
123 static const EGLint attribs
[] = {
133 XSetWindowAttributes attr
;
137 XVisualInfo
*visInfo
, visTemplate
;
140 EGLint num_configs
, vid
;
142 scrnum
= DefaultScreen( x_dpy
);
143 root
= RootWindow( x_dpy
, scrnum
);
145 if (!eglChooseConfig(dpy
, attribs
, &config
, 1, &num_configs
)) {
146 printf("Error: couldn't get an EGL visual config\n");
150 if (!eglGetConfigAttrib(dpy
, config
, EGL_NATIVE_VISUAL_ID
, &vid
)) {
151 printf("Error: eglGetConfigAttrib() failed\n");
155 /* The X window visual must match the EGL config */
156 visTemplate
.visualid
= vid
;
157 visInfo
= XGetVisualInfo(x_dpy
, VisualIDMask
, &visTemplate
, &num_visuals
);
159 printf("Error: couldn't get X visual\n");
163 /* window attributes */
164 attr
.background_pixel
= 0;
165 attr
.border_pixel
= 0;
166 attr
.colormap
= XCreateColormap( x_dpy
, root
, visInfo
->visual
, AllocNone
);
167 attr
.event_mask
= StructureNotifyMask
| ExposureMask
| KeyPressMask
;
168 attr
.override_redirect
= 0;
169 mask
= CWBackPixel
| CWBorderPixel
| CWColormap
| CWEventMask
| CWOverrideRedirect
;
171 win
= XCreateWindow( x_dpy
, root
, 0, 0, width
, height
,
172 0, visInfo
->depth
, InputOutput
,
173 visInfo
->visual
, mask
, &attr
);
175 /* set hints and properties */
177 XSizeHints sizehints
;
180 sizehints
.width
= width
;
181 sizehints
.height
= height
;
182 sizehints
.flags
= USSize
| USPosition
;
183 XSetNormalHints(x_dpy
, win
, &sizehints
);
184 XSetStandardProperties(x_dpy
, win
, name
, name
,
185 None
, (char **)NULL
, 0, &sizehints
);
188 eglBindAPI(EGL_OPENGL_API
);
189 ctx_win
= eglCreateContext(dpy
, config
, EGL_NO_CONTEXT
, NULL
);
191 printf("Error: glXCreateContext failed\n");
195 surf_win
= eglCreateWindowSurface(dpy
, config
, win
, NULL
);
205 static int initialized
;
207 eglMakeCurrent(dpy
, surf_win
, surf_win
, ctx_win
);
210 glEnable(GL_TEXTURE_2D
);
211 glBindTexture(GL_TEXTURE_2D
, tex_pbuf
);
212 glTexParameteri(GL_TEXTURE_2D
, GL_TEXTURE_MIN_FILTER
, GL_NEAREST
);
214 glBlendFunc(GL_SRC_ALPHA
, GL_ONE_MINUS_SRC_ALPHA
);
221 static const GLfloat verts
[3][2] = {
226 GLfloat colors
[3][3] = {
234 for (i
= 0; i
< 3; i
++) {
235 GLint first
= (i
+ color_flow
/ 256) % 3;
236 GLint second
= (first
+ 1) % 3;
237 GLint third
= (second
+ 1) % 3;
238 GLfloat c
= (color_flow
% 256) / 256.0f
;
241 colors
[i
][first
] = 1.0f
- c
;
242 colors
[i
][second
] = c
;
243 colors
[i
][third
] = 0.0f
;
246 glClear(GL_COLOR_BUFFER_BIT
| GL_DEPTH_BUFFER_BIT
);
248 glVertexPointer(2, GL_FLOAT
, 0, verts
);
249 glColorPointer(3, GL_FLOAT
, 0, colors
);
250 glEnableClientState(GL_VERTEX_ARRAY
);
251 glEnableClientState(GL_COLOR_ARRAY
);
253 glDrawArrays(GL_TRIANGLES
, 0, 3);
255 glDisableClientState(GL_VERTEX_ARRAY
);
256 glDisableClientState(GL_COLOR_ARRAY
);
260 draw_textured_cube(void)
262 static const GLfloat verts
[][2] = {
268 static const GLfloat colors
[][4] = {
274 static const GLfloat texs
[][2] = {
280 static const GLfloat xforms
[6][4] = {
290 glClear(GL_COLOR_BUFFER_BIT
| GL_DEPTH_BUFFER_BIT
);
293 glDisable(GL_DEPTH_TEST
);
296 glEnable(GL_DEPTH_TEST
);
300 glVertexPointer(2, GL_FLOAT
, 0, verts
);
301 glColorPointer(4, GL_FLOAT
, 0, colors
);
302 glTexCoordPointer(2, GL_FLOAT
, 0, texs
);
304 glEnableClientState(GL_VERTEX_ARRAY
);
305 glEnableClientState(GL_COLOR_ARRAY
);
306 glEnableClientState(GL_TEXTURE_COORD_ARRAY
);
308 for (i
= 0; i
< 6; i
++) {
310 glRotatef(xforms
[i
][0], xforms
[i
][1], xforms
[i
][2], xforms
[i
][3]);
311 glTranslatef(0, 0, 4.1);
312 glDrawArrays(GL_TRIANGLE_FAN
, 0, 4);
316 glDisableClientState(GL_VERTEX_ARRAY
);
317 glDisableClientState(GL_COLOR_ARRAY
);
318 glDisableClientState(GL_TEXTURE_COORD_ARRAY
);
329 eglBindTexImage(dpy
, surf_pbuf
, EGL_BACK_BUFFER
);
332 glRotatef(view_rotx
, 1, 0, 0);
333 glRotatef(view_roty
, 0, 1, 0);
334 glRotatef(view_rotz
, 0, 0, 1);
336 draw_textured_cube();
340 eglReleaseTexImage(dpy
, surf_pbuf
, EGL_BACK_BUFFER
);
343 /* new window size or exposure */
345 reshape(int width
, int height
)
347 GLfloat ar
= (GLfloat
) width
/ (GLfloat
) height
;
351 glViewport(0, 0, (GLint
) width
, (GLint
) height
);
353 glMatrixMode(GL_PROJECTION
);
355 glFrustum(-ar
, ar
, -1, 1, 5.0, 60.0);
357 glMatrixMode(GL_MODELVIEW
);
359 glTranslatef(0.0, 0.0, -40.0);
363 event_loop(Display
*x_dpy
, Window win
)
368 if (XPending(x_dpy
) > 0) {
370 XNextEvent(x_dpy
, &event
);
372 switch (event
.type
) {
376 case ConfigureNotify
:
377 reshape(event
.xconfigure
.width
, event
.xconfigure
.height
);
383 code
= XLookupKeysym(&event
.xkey
, 0);
384 if (code
== XK_Left
) {
387 else if (code
== XK_Right
) {
390 else if (code
== XK_Up
) {
393 else if (code
== XK_Down
) {
396 else if (code
== XK_b
) {
400 r
= XLookupString(&event
.xkey
, buffer
, sizeof(buffer
),
402 if (buffer
[0] == 27) {
421 eglSwapBuffers(dpy
, surf_win
);
427 main(int argc
, char *argv
[])
429 const int winWidth
= 300, winHeight
= 300;
432 char *dpyName
= NULL
;
433 EGLint egl_major
, egl_minor
;
436 x_dpy
= XOpenDisplay(dpyName
);
438 printf("Error: couldn't open display %s\n",
439 dpyName
? dpyName
: getenv("DISPLAY"));
443 dpy
= eglGetDisplay(x_dpy
);
445 printf("Error: eglGetDisplay() failed\n");
449 if (!eglInitialize(dpy
, &egl_major
, &egl_minor
)) {
450 printf("Error: eglInitialize() failed\n");
454 s
= eglQueryString(dpy
, EGL_VERSION
);
455 printf("EGL_VERSION = %s\n", s
);
457 make_window(x_dpy
, "color flow", 0, 0, winWidth
, winHeight
, &win
);
458 make_pbuffer(winWidth
, winHeight
);
460 XMapWindow(x_dpy
, win
);
462 reshape(winWidth
, winHeight
);
463 event_loop(x_dpy
, win
);
465 glDeleteTextures(1, &tex_pbuf
);
467 eglMakeCurrent(dpy
, EGL_NO_SURFACE
, EGL_NO_SURFACE
, EGL_NO_CONTEXT
);
470 XDestroyWindow(x_dpy
, win
);
471 XCloseDisplay(x_dpy
);