132001f49Smrg/* 232001f49Smrg * Copyright (C) 2008 Tunsgten Graphics,Inc. All Rights Reserved. 332001f49Smrg */ 432001f49Smrg 532001f49Smrg/* 632001f49Smrg * Test EGL render to texture. 732001f49Smrg * Brian Paul 832001f49Smrg * August 2008 932001f49Smrg */ 1032001f49Smrg 1132001f49Smrg 1232001f49Smrg#include <assert.h> 1332001f49Smrg#include <math.h> 1432001f49Smrg#include <stdlib.h> 1532001f49Smrg#include <stdio.h> 1632001f49Smrg#include <string.h> 1732001f49Smrg#include <X11/Xlib.h> 1832001f49Smrg#include <X11/Xutil.h> 1932001f49Smrg#include <X11/keysym.h> 2032001f49Smrg#include <GLES/gl.h> 2132001f49Smrg#include <GLES/glext.h> 2232001f49Smrg#include <EGL/egl.h> 2332001f49Smrg 2432001f49Smrg 2532001f49Smrgstatic int TexWidth = 256, TexHeight = 256; 2632001f49Smrg 2732001f49Smrgstatic int WinWidth = 300, WinHeight = 300; 2832001f49Smrg 2932001f49Smrgstatic GLfloat view_rotx = 0.0, view_roty = 0.0, view_rotz = 0.0; 3032001f49Smrg 3132001f49Smrgstatic GLuint DotTexture, RenderTexture; 3232001f49Smrg 3332001f49Smrg 3432001f49Smrgstatic void 3532001f49SmrgNormal(GLfloat *n, GLfloat nx, GLfloat ny, GLfloat nz) 3632001f49Smrg{ 3732001f49Smrg n[0] = nx; 3832001f49Smrg n[1] = ny; 3932001f49Smrg n[2] = nz; 4032001f49Smrg} 4132001f49Smrg 4232001f49Smrgstatic void 4332001f49SmrgVertex(GLfloat *v, GLfloat vx, GLfloat vy, GLfloat vz) 4432001f49Smrg{ 4532001f49Smrg v[0] = vx; 4632001f49Smrg v[1] = vy; 4732001f49Smrg v[2] = vz; 4832001f49Smrg} 4932001f49Smrg 5032001f49Smrgstatic void 5132001f49SmrgTexcoord(GLfloat *v, GLfloat s, GLfloat t) 5232001f49Smrg{ 5332001f49Smrg v[0] = s; 5432001f49Smrg v[1] = t; 5532001f49Smrg} 5632001f49Smrg 5732001f49Smrg 5832001f49Smrg/* Borrowed from glut, adapted */ 5932001f49Smrgstatic void 6032001f49Smrgdraw_torus(GLfloat r, GLfloat R, GLint nsides, GLint rings) 6132001f49Smrg{ 6232001f49Smrg int i, j; 6332001f49Smrg GLfloat theta, phi, theta1; 6432001f49Smrg GLfloat cosTheta, sinTheta; 6532001f49Smrg GLfloat cosTheta1, sinTheta1; 6632001f49Smrg GLfloat ringDelta, sideDelta; 6732001f49Smrg GLfloat varray[100][3], narray[100][3], tarray[100][2]; 6832001f49Smrg int vcount; 6932001f49Smrg 7032001f49Smrg glVertexPointer(3, GL_FLOAT, 0, varray); 7132001f49Smrg glNormalPointer(GL_FLOAT, 0, narray); 7232001f49Smrg glTexCoordPointer(2, GL_FLOAT, 0, tarray); 7332001f49Smrg glEnableClientState(GL_VERTEX_ARRAY); 7432001f49Smrg glEnableClientState(GL_NORMAL_ARRAY); 7532001f49Smrg glEnableClientState(GL_TEXTURE_COORD_ARRAY); 7632001f49Smrg 7732001f49Smrg ringDelta = 2.0 * M_PI / rings; 7832001f49Smrg sideDelta = 2.0 * M_PI / nsides; 7932001f49Smrg 8032001f49Smrg theta = 0.0; 8132001f49Smrg cosTheta = 1.0; 8232001f49Smrg sinTheta = 0.0; 8332001f49Smrg for (i = rings - 1; i >= 0; i--) { 8432001f49Smrg theta1 = theta + ringDelta; 8532001f49Smrg cosTheta1 = cos(theta1); 8632001f49Smrg sinTheta1 = sin(theta1); 8732001f49Smrg 8832001f49Smrg vcount = 0; /* glBegin(GL_QUAD_STRIP); */ 8932001f49Smrg 9032001f49Smrg phi = 0.0; 9132001f49Smrg for (j = nsides; j >= 0; j--) { 9232001f49Smrg GLfloat s0, s1, t; 9332001f49Smrg GLfloat cosPhi, sinPhi, dist; 9432001f49Smrg 9532001f49Smrg phi += sideDelta; 9632001f49Smrg cosPhi = cos(phi); 9732001f49Smrg sinPhi = sin(phi); 9832001f49Smrg dist = R + r * cosPhi; 9932001f49Smrg 10032001f49Smrg s0 = 20.0 * theta / (2.0 * M_PI); 10132001f49Smrg s1 = 20.0 * theta1 / (2.0 * M_PI); 10232001f49Smrg t = 8.0 * phi / (2.0 * M_PI); 10332001f49Smrg 10432001f49Smrg Normal(narray[vcount], cosTheta1 * cosPhi, -sinTheta1 * cosPhi, sinPhi); 10532001f49Smrg Texcoord(tarray[vcount], s1, t); 10632001f49Smrg Vertex(varray[vcount], cosTheta1 * dist, -sinTheta1 * dist, r * sinPhi); 10732001f49Smrg vcount++; 10832001f49Smrg 10932001f49Smrg Normal(narray[vcount], cosTheta * cosPhi, -sinTheta * cosPhi, sinPhi); 11032001f49Smrg Texcoord(tarray[vcount], s0, t); 11132001f49Smrg Vertex(varray[vcount], cosTheta * dist, -sinTheta * dist, r * sinPhi); 11232001f49Smrg vcount++; 11332001f49Smrg } 11432001f49Smrg 11532001f49Smrg /*glEnd();*/ 11632001f49Smrg assert(vcount <= 100); 11732001f49Smrg glDrawArrays(GL_TRIANGLE_STRIP, 0, vcount); 11832001f49Smrg 11932001f49Smrg theta = theta1; 12032001f49Smrg cosTheta = cosTheta1; 12132001f49Smrg sinTheta = sinTheta1; 12232001f49Smrg } 12332001f49Smrg 12432001f49Smrg glDisableClientState(GL_VERTEX_ARRAY); 12532001f49Smrg glDisableClientState(GL_NORMAL_ARRAY); 12632001f49Smrg glDisableClientState(GL_TEXTURE_COORD_ARRAY); 12732001f49Smrg} 12832001f49Smrg 12932001f49Smrg 13032001f49Smrgstatic void 13132001f49Smrgdraw_torus_to_texture(void) 13232001f49Smrg{ 13332001f49Smrg glViewport(0, 0, TexWidth, TexHeight); 13432001f49Smrg 13532001f49Smrg glMatrixMode(GL_PROJECTION); 13632001f49Smrg glLoadIdentity(); 13732001f49Smrg glFrustumf(-1, 1, -1, 1, 5.0, 60.0); 13832001f49Smrg 13932001f49Smrg glMatrixMode(GL_MODELVIEW); 14032001f49Smrg glLoadIdentity(); 14132001f49Smrg glTranslatef(0.0, 0.0, -15.0); 14232001f49Smrg 14332001f49Smrg glClearColor(0.4, 0.4, 0.4, 0.0); 14432001f49Smrg glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 14532001f49Smrg 14632001f49Smrg glBindTexture(GL_TEXTURE_2D, DotTexture); 14732001f49Smrg 14832001f49Smrg glEnable(GL_LIGHTING); 14932001f49Smrg 15032001f49Smrg glPushMatrix(); 15132001f49Smrg glRotatef(view_roty, 0, 1, 0); 15232001f49Smrg glScalef(0.5, 0.5, 0.5); 15332001f49Smrg 15432001f49Smrg draw_torus(1.0, 3.0, 30, 60); 15532001f49Smrg 15632001f49Smrg glPopMatrix(); 15732001f49Smrg 15832001f49Smrg glDisable(GL_LIGHTING); 15932001f49Smrg 16032001f49Smrg#if 0 16132001f49Smrg glBindTexture(GL_TEXTURE_2D, RenderTexture); 16232001f49Smrg glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, TexWidth, TexHeight); 16332001f49Smrg#endif 16432001f49Smrg 16532001f49Smrg glFinish(); 16632001f49Smrg} 16732001f49Smrg 16832001f49Smrg 16932001f49Smrgstatic void 17032001f49Smrgdraw_textured_quad(void) 17132001f49Smrg{ 17232001f49Smrg GLfloat ar = (GLfloat) WinWidth / (GLfloat) WinHeight; 17332001f49Smrg 17432001f49Smrg glViewport(0, 0, WinWidth, WinHeight); 17532001f49Smrg 17632001f49Smrg glMatrixMode(GL_PROJECTION); 17732001f49Smrg glLoadIdentity(); 17832001f49Smrg glFrustumf(-ar, ar, -1, 1, 5.0, 60.0); 17932001f49Smrg 18032001f49Smrg glMatrixMode(GL_MODELVIEW); 18132001f49Smrg glLoadIdentity(); 18232001f49Smrg glTranslatef(0.0, 0.0, -8.0); 18332001f49Smrg 18432001f49Smrg glClearColor(0.4, 0.4, 1.0, 0.0); 18532001f49Smrg glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 18632001f49Smrg 18732001f49Smrg glBindTexture(GL_TEXTURE_2D, RenderTexture); 18832001f49Smrg 18932001f49Smrg glPushMatrix(); 19032001f49Smrg glRotatef(view_rotx, 1, 0, 0); 19132001f49Smrg glRotatef(view_rotz, 0, 0, 1); 19232001f49Smrg 19332001f49Smrg { 19432001f49Smrg static const GLfloat texcoord[4][2] = { 19532001f49Smrg { 0, 0 }, { 1, 0 }, { 0, 1 }, { 1, 1 } 19632001f49Smrg }; 19732001f49Smrg static const GLfloat vertex[4][2] = { 19832001f49Smrg { -1, -1 }, { 1, -1 }, { -1, 1 }, { 1, 1 } 19932001f49Smrg }; 20032001f49Smrg 20132001f49Smrg glVertexPointer(2, GL_FLOAT, 0, vertex); 20232001f49Smrg glTexCoordPointer(2, GL_FLOAT, 0, texcoord); 20332001f49Smrg glEnableClientState(GL_VERTEX_ARRAY); 20432001f49Smrg glEnableClientState(GL_TEXTURE_COORD_ARRAY); 20532001f49Smrg 20632001f49Smrg glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); 20732001f49Smrg 20832001f49Smrg glDisableClientState(GL_VERTEX_ARRAY); 20932001f49Smrg glDisableClientState(GL_TEXTURE_COORD_ARRAY); 21032001f49Smrg } 21132001f49Smrg 21232001f49Smrg glPopMatrix(); 21332001f49Smrg} 21432001f49Smrg 21532001f49Smrg 21632001f49Smrg 21732001f49Smrgstatic void 21832001f49Smrgdraw(EGLDisplay egl_dpy, EGLSurface egl_surf, EGLSurface egl_pbuf, 21932001f49Smrg EGLContext egl_ctx) 22032001f49Smrg{ 22132001f49Smrg /*printf("Begin draw\n");*/ 22232001f49Smrg 22332001f49Smrg /* first draw torus to pbuffer /texture */ 22432001f49Smrg#if 01 22532001f49Smrg if (!eglMakeCurrent(egl_dpy, egl_pbuf, egl_pbuf, egl_ctx)) { 22632001f49Smrg#else 22732001f49Smrg if (!eglMakeCurrent(egl_dpy, egl_surf, egl_surf, egl_ctx)) { 22832001f49Smrg#endif 22932001f49Smrg printf("Error: eglMakeCurrent(pbuf) failed\n"); 23032001f49Smrg return; 23132001f49Smrg } 23232001f49Smrg draw_torus_to_texture(); 23332001f49Smrg 23432001f49Smrg /* draw textured quad to window */ 23532001f49Smrg if (!eglMakeCurrent(egl_dpy, egl_surf, egl_surf, egl_ctx)) { 23632001f49Smrg printf("Error: eglMakeCurrent(pbuffer) failed\n"); 23732001f49Smrg return; 23832001f49Smrg } 23932001f49Smrg 24032001f49Smrg glBindTexture(GL_TEXTURE_2D, RenderTexture); 24132001f49Smrg eglBindTexImage(egl_dpy, egl_pbuf, EGL_BACK_BUFFER); 24232001f49Smrg draw_textured_quad(); 24332001f49Smrg eglReleaseTexImage(egl_dpy, egl_pbuf, EGL_BACK_BUFFER); 24432001f49Smrg 24532001f49Smrg eglSwapBuffers(egl_dpy, egl_surf); 24632001f49Smrg 24732001f49Smrg /*printf("End draw\n");*/ 24832001f49Smrg} 24932001f49Smrg 25032001f49Smrg 25132001f49Smrg 25232001f49Smrgstatic void 25332001f49Smrgmake_dot_texture(void) 25432001f49Smrg{ 25532001f49Smrg#define SZ 64 25632001f49Smrg GLenum Filter = GL_LINEAR; 25732001f49Smrg GLubyte image[SZ][SZ][4]; 25832001f49Smrg GLuint i, j; 25932001f49Smrg 26032001f49Smrg for (i = 0; i < SZ; i++) { 26132001f49Smrg for (j = 0; j < SZ; j++) { 26232001f49Smrg GLfloat d = (i - SZ/2) * (i - SZ/2) + (j - SZ/2) * (j - SZ/2); 26332001f49Smrg d = sqrt(d); 26432001f49Smrg if (d < SZ/3) { 26532001f49Smrg image[i][j][0] = 255; 26632001f49Smrg image[i][j][1] = 255; 26732001f49Smrg image[i][j][2] = 255; 26832001f49Smrg image[i][j][3] = 255; 26932001f49Smrg } 27032001f49Smrg else { 27132001f49Smrg image[i][j][0] = 127; 27232001f49Smrg image[i][j][1] = 127; 27332001f49Smrg image[i][j][2] = 127; 27432001f49Smrg image[i][j][3] = 255; 27532001f49Smrg } 27632001f49Smrg } 27732001f49Smrg } 27832001f49Smrg 27932001f49Smrg glGenTextures(1, &DotTexture); 28032001f49Smrg glBindTexture(GL_TEXTURE_2D, DotTexture); 28132001f49Smrg glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, SZ, SZ, 0, 28232001f49Smrg GL_RGBA, GL_UNSIGNED_BYTE, image); 28332001f49Smrg glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, Filter); 28432001f49Smrg glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, Filter); 28532001f49Smrg glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); 28632001f49Smrg glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); 28732001f49Smrg#undef SZ 28832001f49Smrg} 28932001f49Smrg 29032001f49Smrg 29132001f49Smrgstatic void 29232001f49Smrgmake_render_texture(void) 29332001f49Smrg{ 29432001f49Smrg GLenum Filter = GL_LINEAR; 29532001f49Smrg glGenTextures(1, &RenderTexture); 29632001f49Smrg glBindTexture(GL_TEXTURE_2D, RenderTexture); 29732001f49Smrg glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, TexWidth, TexHeight, 0, 29832001f49Smrg GL_RGBA, GL_UNSIGNED_BYTE, NULL); 29932001f49Smrg glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, Filter); 30032001f49Smrg glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, Filter); 30132001f49Smrg glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); 30232001f49Smrg glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); 30332001f49Smrg} 30432001f49Smrg 30532001f49Smrg 30632001f49Smrgstatic void 30732001f49Smrginit(void) 30832001f49Smrg{ 30932001f49Smrg static const GLfloat red[4] = {1, 0, 0, 0}; 31032001f49Smrg static const GLfloat white[4] = {1.0, 1.0, 1.0, 1.0}; 31132001f49Smrg static const GLfloat diffuse[4] = {0.7, 0.7, 0.7, 1.0}; 31232001f49Smrg static const GLfloat specular[4] = {0.001, 0.001, 0.001, 1.0}; 31332001f49Smrg static const GLfloat pos[4] = {20, 20, 50, 1}; 31432001f49Smrg 31532001f49Smrg glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, red); 31632001f49Smrg glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, white); 31732001f49Smrg glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 9.0); 31832001f49Smrg 31932001f49Smrg glEnable(GL_LIGHT0); 32032001f49Smrg glLightfv(GL_LIGHT0, GL_POSITION, pos); 32132001f49Smrg glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuse); 32232001f49Smrg glLightfv(GL_LIGHT0, GL_SPECULAR, specular); 32332001f49Smrg 32432001f49Smrg glEnable(GL_DEPTH_TEST); 32532001f49Smrg 32632001f49Smrg make_dot_texture(); 32732001f49Smrg make_render_texture(); 32832001f49Smrg 32932001f49Smrg printf("DotTexture=%u RenderTexture=%u\n", DotTexture, RenderTexture); 33032001f49Smrg 33132001f49Smrg glEnable(GL_TEXTURE_2D); 33232001f49Smrg} 33332001f49Smrg 33432001f49Smrg 33532001f49Smrg/* 33632001f49Smrg * Create an RGB, double-buffered X window. 33732001f49Smrg * Return the window and context handles. 33832001f49Smrg */ 33932001f49Smrgstatic void 34032001f49Smrgmake_x_window(Display *x_dpy, EGLDisplay egl_dpy, 34132001f49Smrg const char *name, 34232001f49Smrg int x, int y, int width, int height, 34332001f49Smrg Window *winRet, 34432001f49Smrg EGLContext *ctxRet, 34532001f49Smrg EGLSurface *surfRet) 34632001f49Smrg{ 34732001f49Smrg static const EGLint attribs[] = { 34832001f49Smrg EGL_RED_SIZE, 1, 34932001f49Smrg EGL_GREEN_SIZE, 1, 35032001f49Smrg EGL_BLUE_SIZE, 1, 35132001f49Smrg EGL_DEPTH_SIZE, 1, 35232001f49Smrg EGL_NONE 35332001f49Smrg }; 35432001f49Smrg 35532001f49Smrg int scrnum; 35632001f49Smrg XSetWindowAttributes attr; 35732001f49Smrg unsigned long mask; 35832001f49Smrg Window root; 35932001f49Smrg Window win; 36032001f49Smrg XVisualInfo *visInfo, visTemplate; 36132001f49Smrg int num_visuals; 36232001f49Smrg EGLContext ctx; 36332001f49Smrg EGLConfig config; 36432001f49Smrg EGLint num_configs; 36532001f49Smrg EGLint vid; 36632001f49Smrg 36732001f49Smrg scrnum = DefaultScreen( x_dpy ); 36832001f49Smrg root = RootWindow( x_dpy, scrnum ); 36932001f49Smrg 37032001f49Smrg if (!eglChooseConfig( egl_dpy, attribs, &config, 1, &num_configs)) { 37132001f49Smrg printf("Error: couldn't get an EGL visual config\n"); 37232001f49Smrg exit(1); 37332001f49Smrg } 37432001f49Smrg 37532001f49Smrg assert(config); 37632001f49Smrg assert(num_configs > 0); 37732001f49Smrg 37832001f49Smrg if (!eglGetConfigAttrib(egl_dpy, config, EGL_NATIVE_VISUAL_ID, &vid)) { 37932001f49Smrg printf("Error: eglGetConfigAttrib() failed\n"); 38032001f49Smrg exit(1); 38132001f49Smrg } 38232001f49Smrg 38332001f49Smrg /* The X window visual must match the EGL config */ 38432001f49Smrg visTemplate.visualid = vid; 38532001f49Smrg visInfo = XGetVisualInfo(x_dpy, VisualIDMask, &visTemplate, &num_visuals); 38632001f49Smrg if (!visInfo) { 38732001f49Smrg printf("Error: couldn't get X visual\n"); 38832001f49Smrg exit(1); 38932001f49Smrg } 39032001f49Smrg 39132001f49Smrg /* window attributes */ 39232001f49Smrg attr.background_pixel = 0; 39332001f49Smrg attr.border_pixel = 0; 39432001f49Smrg attr.colormap = XCreateColormap( x_dpy, root, visInfo->visual, AllocNone); 39532001f49Smrg attr.event_mask = StructureNotifyMask | ExposureMask | KeyPressMask; 39632001f49Smrg mask = CWBackPixel | CWBorderPixel | CWColormap | CWEventMask; 39732001f49Smrg 39832001f49Smrg win = XCreateWindow( x_dpy, root, 0, 0, width, height, 39932001f49Smrg 0, visInfo->depth, InputOutput, 40032001f49Smrg visInfo->visual, mask, &attr ); 40132001f49Smrg 40232001f49Smrg /* set hints and properties */ 40332001f49Smrg { 40432001f49Smrg XSizeHints sizehints; 40532001f49Smrg sizehints.x = x; 40632001f49Smrg sizehints.y = y; 40732001f49Smrg sizehints.width = width; 40832001f49Smrg sizehints.height = height; 40932001f49Smrg sizehints.flags = USSize | USPosition; 41032001f49Smrg XSetNormalHints(x_dpy, win, &sizehints); 41132001f49Smrg XSetStandardProperties(x_dpy, win, name, name, 41232001f49Smrg None, (char **)NULL, 0, &sizehints); 41332001f49Smrg } 41432001f49Smrg 41532001f49Smrg eglBindAPI(EGL_OPENGL_ES_API); 41632001f49Smrg 41732001f49Smrg ctx = eglCreateContext(egl_dpy, config, EGL_NO_CONTEXT, NULL ); 41832001f49Smrg if (!ctx) { 41932001f49Smrg printf("Error: eglCreateContext failed\n"); 42032001f49Smrg exit(1); 42132001f49Smrg } 42232001f49Smrg 42332001f49Smrg *surfRet = eglCreateWindowSurface(egl_dpy, config, win, NULL); 42432001f49Smrg 42532001f49Smrg if (!*surfRet) { 42632001f49Smrg printf("Error: eglCreateWindowSurface failed\n"); 42732001f49Smrg exit(1); 42832001f49Smrg } 42932001f49Smrg 43032001f49Smrg XFree(visInfo); 43132001f49Smrg 43232001f49Smrg *winRet = win; 43332001f49Smrg *ctxRet = ctx; 43432001f49Smrg} 43532001f49Smrg 43632001f49Smrg 43732001f49Smrgstatic EGLSurface 43832001f49Smrgmake_pbuffer(Display *x_dpy, EGLDisplay egl_dpy, int width, int height) 43932001f49Smrg{ 44032001f49Smrg static const EGLint config_attribs[] = { 44132001f49Smrg EGL_RED_SIZE, 1, 44232001f49Smrg EGL_GREEN_SIZE, 1, 44332001f49Smrg EGL_BLUE_SIZE, 1, 44432001f49Smrg EGL_DEPTH_SIZE, 1, 44532001f49Smrg EGL_NONE 44632001f49Smrg }; 44732001f49Smrg EGLConfig config; 44832001f49Smrg EGLSurface pbuf; 44932001f49Smrg EGLint num_configs; 45032001f49Smrg EGLint pbuf_attribs[15]; 45132001f49Smrg int i = 0; 45232001f49Smrg 45332001f49Smrg pbuf_attribs[i++] = EGL_WIDTH; 45432001f49Smrg pbuf_attribs[i++] = width; 45532001f49Smrg pbuf_attribs[i++] = EGL_HEIGHT; 45632001f49Smrg pbuf_attribs[i++] = height; 45732001f49Smrg pbuf_attribs[i++] = EGL_TEXTURE_FORMAT; 45832001f49Smrg pbuf_attribs[i++] = EGL_TEXTURE_RGBA; 45932001f49Smrg pbuf_attribs[i++] = EGL_TEXTURE_TARGET; 46032001f49Smrg pbuf_attribs[i++] = EGL_TEXTURE_2D; 46132001f49Smrg pbuf_attribs[i++] = EGL_MIPMAP_TEXTURE; 46232001f49Smrg pbuf_attribs[i++] = EGL_FALSE; 46332001f49Smrg pbuf_attribs[i++] = EGL_NONE; 46432001f49Smrg assert(i <= 15); 46532001f49Smrg 46632001f49Smrg if (!eglChooseConfig( egl_dpy, config_attribs, &config, 1, &num_configs)) { 46732001f49Smrg printf("Error: couldn't get an EGL config for pbuffer\n"); 46832001f49Smrg exit(1); 46932001f49Smrg } 47032001f49Smrg 47132001f49Smrg pbuf = eglCreatePbufferSurface(egl_dpy, config, pbuf_attribs); 47232001f49Smrg 47332001f49Smrg return pbuf; 47432001f49Smrg} 47532001f49Smrg 47632001f49Smrg 47732001f49Smrgstatic void 47832001f49Smrgevent_loop(Display *dpy, Window win, 47932001f49Smrg EGLDisplay egl_dpy, EGLSurface egl_surf, EGLSurface egl_pbuf, 48032001f49Smrg EGLContext egl_ctx) 48132001f49Smrg{ 48232001f49Smrg int anim = 0; 48332001f49Smrg 48432001f49Smrg while (1) { 48532001f49Smrg int redraw = 0; 48632001f49Smrg 48732001f49Smrg if (!anim || XPending(dpy)) { 48832001f49Smrg XEvent event; 48932001f49Smrg XNextEvent(dpy, &event); 49032001f49Smrg 49132001f49Smrg switch (event.type) { 49232001f49Smrg case Expose: 49332001f49Smrg redraw = 1; 49432001f49Smrg break; 49532001f49Smrg case ConfigureNotify: 49632001f49Smrg if (event.xconfigure.window == win) { 49732001f49Smrg WinWidth = event.xconfigure.width; 49832001f49Smrg WinHeight = event.xconfigure.height; 49932001f49Smrg } 50032001f49Smrg break; 50132001f49Smrg case KeyPress: 50232001f49Smrg { 50332001f49Smrg char buffer[10]; 50432001f49Smrg int r, code; 50532001f49Smrg code = XLookupKeysym(&event.xkey, 0); 50632001f49Smrg if (code == XK_Left) { 50732001f49Smrg view_roty += 5.0; 50832001f49Smrg } 50932001f49Smrg else if (code == XK_Right) { 51032001f49Smrg view_roty -= 5.0; 51132001f49Smrg } 51232001f49Smrg else if (code == XK_Up) { 51332001f49Smrg view_rotx += 5.0; 51432001f49Smrg } 51532001f49Smrg else if (code == XK_Down) { 51632001f49Smrg view_rotx -= 5.0; 51732001f49Smrg } 51832001f49Smrg else { 51932001f49Smrg r = XLookupString(&event.xkey, buffer, sizeof(buffer), 52032001f49Smrg NULL, NULL); 52132001f49Smrg if (buffer[0] == ' ') { 52232001f49Smrg anim = !anim; 52332001f49Smrg } 52432001f49Smrg else if (buffer[0] == 'z') { 52532001f49Smrg view_rotz += 5.0; 52632001f49Smrg } 52732001f49Smrg else if (buffer[0] == 'Z') { 52832001f49Smrg view_rotz -= 5.0; 52932001f49Smrg } 53032001f49Smrg else if (buffer[0] == 27) { 53132001f49Smrg /* escape */ 53232001f49Smrg return; 53332001f49Smrg } 53432001f49Smrg } 53532001f49Smrg } 53632001f49Smrg redraw = 1; 53732001f49Smrg break; 53832001f49Smrg default: 53932001f49Smrg ; /*no-op*/ 54032001f49Smrg } 54132001f49Smrg } 54232001f49Smrg 54332001f49Smrg if (anim) { 54432001f49Smrg view_rotx += 1.0; 54532001f49Smrg view_roty += 2.0; 54632001f49Smrg redraw = 1; 54732001f49Smrg } 54832001f49Smrg 54932001f49Smrg if (redraw) { 55032001f49Smrg draw(egl_dpy, egl_surf, egl_pbuf, egl_ctx); 55132001f49Smrg } 55232001f49Smrg } 55332001f49Smrg} 55432001f49Smrg 55532001f49Smrg 55632001f49Smrgstatic void 55732001f49Smrgusage(void) 55832001f49Smrg{ 55932001f49Smrg printf("Usage:\n"); 56032001f49Smrg printf(" -display <displayname> set the display to run on\n"); 56132001f49Smrg printf(" -info display OpenGL renderer info\n"); 56232001f49Smrg} 56332001f49Smrg 56432001f49Smrg 56532001f49Smrgint 56632001f49Smrgmain(int argc, char *argv[]) 56732001f49Smrg{ 56832001f49Smrg Display *x_dpy; 56932001f49Smrg Window win; 57032001f49Smrg EGLSurface egl_surf, egl_pbuf; 57132001f49Smrg EGLContext egl_ctx; 57232001f49Smrg EGLDisplay egl_dpy; 57332001f49Smrg char *dpyName = NULL; 57432001f49Smrg GLboolean printInfo = GL_FALSE; 57532001f49Smrg EGLint egl_major, egl_minor; 57632001f49Smrg int i; 57732001f49Smrg const char *s; 57832001f49Smrg 57932001f49Smrg for (i = 1; i < argc; i++) { 58032001f49Smrg if (strcmp(argv[i], "-display") == 0) { 58132001f49Smrg dpyName = argv[i+1]; 58232001f49Smrg i++; 58332001f49Smrg } 58432001f49Smrg else if (strcmp(argv[i], "-info") == 0) { 58532001f49Smrg printInfo = GL_TRUE; 58632001f49Smrg } 58732001f49Smrg else { 58832001f49Smrg usage(); 58932001f49Smrg return -1; 59032001f49Smrg } 59132001f49Smrg } 59232001f49Smrg 59332001f49Smrg x_dpy = XOpenDisplay(dpyName); 59432001f49Smrg if (!x_dpy) { 59532001f49Smrg printf("Error: couldn't open display %s\n", 59632001f49Smrg dpyName ? dpyName : getenv("DISPLAY")); 59732001f49Smrg return -1; 59832001f49Smrg } 59932001f49Smrg 60032001f49Smrg egl_dpy = eglGetDisplay(x_dpy); 60132001f49Smrg if (!egl_dpy) { 60232001f49Smrg printf("Error: eglGetDisplay() failed\n"); 60332001f49Smrg return -1; 60432001f49Smrg } 60532001f49Smrg 60632001f49Smrg if (!eglInitialize(egl_dpy, &egl_major, &egl_minor)) { 60732001f49Smrg printf("Error: eglInitialize() failed\n"); 60832001f49Smrg return -1; 60932001f49Smrg } 61032001f49Smrg 61132001f49Smrg s = eglQueryString(egl_dpy, EGL_VERSION); 61232001f49Smrg printf("EGL_VERSION = %s\n", s); 61332001f49Smrg 61432001f49Smrg s = eglQueryString(egl_dpy, EGL_VENDOR); 61532001f49Smrg printf("EGL_VENDOR = %s\n", s); 61632001f49Smrg 61732001f49Smrg s = eglQueryString(egl_dpy, EGL_EXTENSIONS); 61832001f49Smrg printf("EGL_EXTENSIONS = %s\n", s); 61932001f49Smrg 62032001f49Smrg s = eglQueryString(egl_dpy, EGL_CLIENT_APIS); 62132001f49Smrg printf("EGL_CLIENT_APIS = %s\n", s); 62232001f49Smrg 62332001f49Smrg make_x_window(x_dpy, egl_dpy, 62432001f49Smrg "render_tex", 0, 0, WinWidth, WinHeight, 62532001f49Smrg &win, &egl_ctx, &egl_surf); 62632001f49Smrg 62732001f49Smrg egl_pbuf = make_pbuffer(x_dpy, egl_dpy, TexWidth, TexHeight); 62832001f49Smrg if (!egl_pbuf) { 62932001f49Smrg printf("Error: eglCreatePBufferSurface() failed\n"); 63032001f49Smrg return -1; 63132001f49Smrg } 63232001f49Smrg 63332001f49Smrg XMapWindow(x_dpy, win); 63432001f49Smrg if (!eglMakeCurrent(egl_dpy, egl_surf, egl_surf, egl_ctx)) { 63532001f49Smrg printf("Error: eglMakeCurrent() failed\n"); 63632001f49Smrg return -1; 63732001f49Smrg } 63832001f49Smrg 63932001f49Smrg if (printInfo) { 64032001f49Smrg printf("GL_RENDERER = %s\n", (char *) glGetString(GL_RENDERER)); 64132001f49Smrg printf("GL_VERSION = %s\n", (char *) glGetString(GL_VERSION)); 64232001f49Smrg printf("GL_VENDOR = %s\n", (char *) glGetString(GL_VENDOR)); 64332001f49Smrg printf("GL_EXTENSIONS = %s\n", (char *) glGetString(GL_EXTENSIONS)); 64432001f49Smrg } 64532001f49Smrg 64632001f49Smrg init(); 64732001f49Smrg 64832001f49Smrg event_loop(x_dpy, win, egl_dpy, egl_surf, egl_pbuf, egl_ctx); 64932001f49Smrg 65032001f49Smrg eglDestroyContext(egl_dpy, egl_ctx); 65132001f49Smrg eglDestroySurface(egl_dpy, egl_surf); 65232001f49Smrg eglTerminate(egl_dpy); 65332001f49Smrg 65432001f49Smrg 65532001f49Smrg XDestroyWindow(x_dpy, win); 65632001f49Smrg XCloseDisplay(x_dpy); 65732001f49Smrg 65832001f49Smrg return 0; 65932001f49Smrg} 660