diff options
Diffstat (limited to 'progs')
102 files changed, 7808 insertions, 193 deletions
diff --git a/progs/SConscript b/progs/SConscript index 3b180d00bc2..2ec95a282e8 100644 --- a/progs/SConscript +++ b/progs/SConscript @@ -15,38 +15,40 @@ if progs_env['platform'] == 'windows': 'gdi32', ]) -# OpenGL -if progs_env['platform'] == 'windows': - progs_env.Prepend(LIBS = ['glu32', 'opengl32']) -else: - progs_env.Prepend(LIBS = ['GLU', 'GL']) - -# Glut -progs_env.Prepend(LIBS = [glut]) - -# GLEW -progs_env.Prepend(LIBS = [glew]) - -progs_env.Prepend(CPPPATH = [ - '#progs/util', -]) - -progs_env.Prepend(LIBS = [ - util, -]) - -Export('progs_env') - -SConscript([ - 'demos/SConscript', - 'glsl/SConscript', - 'redbook/SConscript', - 'samples/SConscript', - 'tests/SConscript', - 'trivial/SConscript', - 'vp/SConscript', - 'vpglsl/SConscript', - 'fp/SConscript', - 'wgl/SConscript', - 'perf/SConscript', -]) +if platform != 'embedded': + # OpenGL + if progs_env['platform'] == 'windows': + progs_env.Prepend(LIBS = ['glu32', 'opengl32']) + else: + progs_env.Prepend(LIBS = ['GLU', 'GL']) + + # Glut + progs_env.Prepend(LIBPATH = [glut.dir]) + progs_env.Prepend(LIBS = [glut.name]) + + # GLEW + progs_env.Prepend(LIBS = [glew]) + + progs_env.Prepend(CPPPATH = [ + '#progs/util', + ]) + + progs_env.Prepend(LIBS = [ + util, + ]) + + Export('progs_env') + + SConscript([ + 'demos/SConscript', + 'glsl/SConscript', + 'redbook/SConscript', + 'samples/SConscript', + 'tests/SConscript', + 'trivial/SConscript', + 'vp/SConscript', + 'vpglsl/SConscript', + 'fp/SConscript', + 'wgl/SConscript', + 'perf/SConscript', + ]) diff --git a/progs/demos/.gitignore b/progs/demos/.gitignore index 5dd974b63dc..1b31866a850 100644 --- a/progs/demos/.gitignore +++ b/progs/demos/.gitignore @@ -6,6 +6,7 @@ clearspd copypix cubemap dinoshade +dissolve drawpix engine extfuncs.h diff --git a/progs/demos/Makefile b/progs/demos/Makefile index 65fdbaaad8e..5b1d2a0b65b 100644 --- a/progs/demos/Makefile +++ b/progs/demos/Makefile @@ -20,6 +20,7 @@ PROGS = \ copypix \ cubemap \ dinoshade \ + dissolve \ drawpix \ engine \ fbo_firecube \ @@ -124,13 +125,6 @@ reflect.o: reflect.c showbuffer.h $(APP_CC) -c -I$(INCDIR) $(CFLAGS) reflect.c -shadowtex: shadowtex.o showbuffer.o - $(APP_CC) $(CFLAGS) $(LDFLAGS) shadowtex.o showbuffer.o $(LIBS) -o $@ - -shadowtex.o: shadowtex.c showbuffer.h - $(APP_CC) -c -I$(INCDIR) $(CFLAGS) shadowtex.c - - gloss: gloss.o trackball.o readtex.o $(APP_CC) $(CFLAGS) $(LDFLAGS) gloss.o trackball.o readtex.o $(LIBS) -o $@ diff --git a/progs/demos/SConscript b/progs/demos/SConscript index 742dd66f36f..10d53b50bf5 100644 --- a/progs/demos/SConscript +++ b/progs/demos/SConscript @@ -8,6 +8,7 @@ progs = [ 'clearspd', 'copypix', 'cubemap', + 'dissolve', 'drawpix', 'engine', 'fbo_firecube', diff --git a/progs/demos/dissolve.c b/progs/demos/dissolve.c new file mode 100644 index 00000000000..0b8df1bb669 --- /dev/null +++ b/progs/demos/dissolve.c @@ -0,0 +1,158 @@ +/** + * Dissolve between two images using randomized stencil buffer + * and varying stencil ref. + * + * Brian Paul + * 29 Jan 2010 + */ + + +#include <stdio.h> +#include <stdlib.h> +#include <math.h> +#include <GL/glut.h> +#include "readtex.h" + +#define FILE1 "../images/bw.rgb" +#define FILE2 "../images/arch.rgb" + + +static int Win; +static int WinWidth = 400, WinHeight = 400; +static GLboolean Anim = GL_TRUE; + +static int ImgWidth[2], ImgHeight[2]; +static GLenum ImgFormat[2]; +static GLubyte *Image[2]; +static GLfloat ScaleX[2], ScaleY[2]; + +static GLubyte StencilRef = 0; + + +static void +Idle(void) +{ + StencilRef = (GLint) (glutGet(GLUT_ELAPSED_TIME) / 10); + glutPostRedisplay(); +} + + +static void +RandomizeStencilBuffer(void) +{ + GLubyte *b = malloc(WinWidth * WinHeight); + int i; + for (i = 0; i < WinWidth * WinHeight; i++) { + b[i] = rand() & 0xff; + } + + glStencilFunc(GL_ALWAYS, 0, ~0); + glPixelZoom(1.0, 1.0); + glDrawPixels(WinWidth, WinHeight, GL_STENCIL_INDEX, GL_UNSIGNED_BYTE, b); + + free(b); +} + + + +static void +Draw(void) +{ + glClear(GL_COLOR_BUFFER_BIT); + + glPixelZoom(ScaleX[0], ScaleY[0]); + glStencilFunc(GL_LESS, StencilRef, ~0); + glDrawPixels(ImgWidth[0], ImgHeight[0], ImgFormat[0], GL_UNSIGNED_BYTE, Image[0]); + + glPixelZoom(ScaleX[1], ScaleY[1]); + glStencilFunc(GL_GEQUAL, StencilRef, ~0); + glDrawPixels(ImgWidth[1], ImgHeight[1], ImgFormat[1], GL_UNSIGNED_BYTE, Image[1]); + + glutSwapBuffers(); +} + + +static void +Reshape(int width, int height) +{ + WinWidth = width; + WinHeight = height; + glViewport(0, 0, width, height); + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + glFrustum(-1.0, 1.0, -1.0, 1.0, 5.0, 25.0); + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + glTranslatef(0.0, 0.0, -15.0); + + RandomizeStencilBuffer(); + + ScaleX[0] = (float) width / ImgWidth[0]; + ScaleY[0] = (float) height / ImgHeight[0]; + + ScaleX[1] = (float) width / ImgWidth[1]; + ScaleY[1] = (float) height / ImgHeight[1]; +} + + +static void +Key(unsigned char key, int x, int y) +{ + (void) x; + (void) y; + switch (key) { + case 'a': + Anim = !Anim; + if (Anim) + glutIdleFunc(Idle); + else + glutIdleFunc(NULL); + break; + case 27: + glutDestroyWindow(Win); + exit(0); + break; + } + glutPostRedisplay(); +} + + + +static void +Init(void) +{ + Image[0] = LoadRGBImage(FILE1, &ImgWidth[0], &ImgHeight[0], &ImgFormat[0]); + if (!Image[0]) { + printf("Couldn't read %s\n", FILE1); + exit(0); + } + + Image[1] = LoadRGBImage(FILE2, &ImgWidth[1], &ImgHeight[1], &ImgFormat[1]); + if (!Image[1]) { + printf("Couldn't read %s\n", FILE2); + exit(0); + } + + glEnable(GL_STENCIL_TEST); + glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP); + + glPixelStorei(GL_UNPACK_ALIGNMENT, 1); +} + + +int +main(int argc, char *argv[]) +{ + glutInit(&argc, argv); + glutInitWindowSize(WinWidth, WinHeight); + glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH | GLUT_STENCIL); + Win = glutCreateWindow(argv[0]); + glutReshapeFunc(Reshape); + glutKeyboardFunc(Key); + glutDisplayFunc(Draw); + if (Anim) + glutIdleFunc(Idle); + Init(); + glutMainLoop(); + return 0; +} diff --git a/progs/demos/engine.c b/progs/demos/engine.c index c54e3b8fb80..a4148357d49 100644 --- a/progs/demos/engine.c +++ b/progs/demos/engine.c @@ -26,6 +26,8 @@ /* Target engine speed: */ const int RPM = 100.0; +static int Win = 0; + /** * Engine description. @@ -120,7 +122,11 @@ static Engine Engines[NUM_ENGINES] = 0.3, /* CrankJournalRadius */ 0.4, /* CrankJournalLength */ 1.5, /* ConnectingRodLength */ - 0.1 /* ConnectingRodThickness */ + 0.1, /* ConnectingRodThickness */ + 0, /* CrankList */ + 0, /* ConnRodList */ + 0, /* PistonList */ + 0 /* BlockList */ }, { "Inline-4", @@ -136,7 +142,11 @@ static Engine Engines[NUM_ENGINES] = 0.3, /* CrankJournalRadius */ 0.4, /* CrankJournalLength */ 1.5, /* ConnectingRodLength */ - 0.1 /* ConnectingRodThickness */ + 0.1, /* ConnectingRodThickness */ + 0, /* CrankList */ + 0, /* ConnRodList */ + 0, /* PistonList */ + 0 /* BlockList */ }, { "Boxer-6", @@ -152,7 +162,11 @@ static Engine Engines[NUM_ENGINES] = 0.3, /* CrankJournalRadius */ 0.4, /* CrankJournalLength */ 1.5, /* ConnectingRodLength */ - 0.1 /* ConnectingRodThickness */ + 0.1, /* ConnectingRodThickness */ + 0, /* CrankList */ + 0, /* ConnRodList */ + 0, /* PistonList */ + 0 /* BlockList */ } }; @@ -1142,6 +1156,7 @@ OptRotate(void) static void OptExit(void) { + glutDestroyWindow(Win); exit(0); } @@ -1311,7 +1326,7 @@ main(int argc, char *argv[]) glutInitWindowSize(WinWidth, WinHeight); glutInit(&argc, argv); glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH); - glutCreateWindow("OpenGL Engine Demo"); + Win = glutCreateWindow("OpenGL Engine Demo"); glewInit(); glutReshapeFunc(Reshape); glutMouseFunc(Mouse); diff --git a/progs/demos/fbotexture.c b/progs/demos/fbotexture.c index 56482663dc4..46bf1c5f6a2 100644 --- a/progs/demos/fbotexture.c +++ b/progs/demos/fbotexture.c @@ -14,7 +14,6 @@ #include <stdio.h> #include <stdlib.h> #include <string.h> -#include <math.h> #include "extfuncs.h" /* For debug */ diff --git a/progs/demos/fire.c b/progs/demos/fire.c index 9c351e80e51..bb912fb4473 100644 --- a/progs/demos/fire.c +++ b/progs/demos/fire.c @@ -726,8 +726,13 @@ main(int ac, char **av) maxage = 1.0 / dt; - if (ac == 2) + if (ac == 2) { np = atoi(av[1]); + if (np <= 0 || np > 1000000) { + fprintf(stderr, "Invalid input.\n"); + exit(-1); + } + } if (ac == 4) { WIDTH = atoi(av[2]); @@ -761,6 +766,7 @@ main(int ac, char **av) assert(np > 0); p = (part *) malloc(sizeof(part) * np); + assert(p); for (i = 0; i < np; i++) setnewpart(&p[i]); diff --git a/progs/demos/gloss.c b/progs/demos/gloss.c index 578736b4e27..450861e5778 100644 --- a/progs/demos/gloss.c +++ b/progs/demos/gloss.c @@ -41,6 +41,7 @@ /* for convolution */ #define FILTER_SIZE 7 +static GLint Win; static GLint WinWidth = 500, WinHeight = 500; static GLuint CylinderObj = 0; static GLuint TeapotObj = 0; @@ -214,7 +215,11 @@ static void Key( unsigned char key, int x, int y ) case ' ': ToggleAnimate(); break; + case 'n': + Idle(); + break; case 27: + glutDestroyWindow(Win); exit(0); break; } @@ -439,7 +444,7 @@ int main( int argc, char *argv[] ) glutInitWindowSize(WinWidth, WinHeight); glutInit( &argc, argv ); glutInitDisplayMode( GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH ); - glutCreateWindow(argv[0] ); + Win = glutCreateWindow(argv[0] ); glewInit(); glutReshapeFunc( Reshape ); glutKeyboardFunc( Key ); diff --git a/progs/demos/isosurf.c b/progs/demos/isosurf.c index dbe4d8d172a..a5b21ffb5c3 100644 --- a/progs/demos/isosurf.c +++ b/progs/demos/isosurf.c @@ -27,7 +27,6 @@ #include <stdio.h> #include <string.h> #include <stdlib.h> -#include <string.h> #include <math.h> #ifdef _WIN32 #include <windows.h> diff --git a/progs/demos/morph3d.c b/progs/demos/morph3d.c index 0f8ac426f33..07458eb156f 100644 --- a/progs/demos/morph3d.c +++ b/progs/demos/morph3d.c @@ -137,7 +137,6 @@ So the angle is: #endif #include <GL/glut.h> #include <math.h> -#include <string.h> #define Scale 0.3 diff --git a/progs/demos/shadowtex.c b/progs/demos/shadowtex.c index 036f73d40b6..677a42104f8 100644 --- a/progs/demos/shadowtex.c +++ b/progs/demos/shadowtex.c @@ -38,7 +38,6 @@ #include <math.h> #include <GL/glew.h> #include <GL/glut.h> -#include "showbuffer.h" #define DEG_TO_RAD (3.14159 / 180.0) diff --git a/progs/egl/Makefile b/progs/egl/Makefile index ff9a858c569..0ddb2cabb4f 100644 --- a/progs/egl/Makefile +++ b/progs/egl/Makefile @@ -20,7 +20,6 @@ PROGRAMS = \ eglgears \ eglscreen \ peglgears \ - xeglbindtex \ xeglgears \ xeglthreads \ xegl_tri @@ -46,7 +45,7 @@ egltri: egltri.o $(HEADERS) $(LIB_DEP) $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $< $(LIBS) $(LIBDRM_LIB) eglinfo: eglinfo.o $(HEADERS) $(LIB_DEP) - $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $< $(LIBS) $(LIBDRM_LIB) + $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $< $(LIBS) eglgears: eglgears.o $(HEADERS) $(LIB_DEP) $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $< $(LIBS) $(LIBDRM_LIB) @@ -57,9 +56,6 @@ eglscreen: eglscreen.o $(HEADERS) $(LIB_DEP) peglgears: peglgears.o $(HEADERS) $(LIB_DEP) $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $< $(LIBS) $(LIBDRM_LIB) -xeglbindtex: xeglbindtex.o $(HEADERS) $(LIB_DEP) - $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $< $(LIBS) -lX11 - xeglgears: xeglgears.o $(HEADERS) $(LIB_DEP) $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $< $(LIBS) -lX11 diff --git a/progs/egl/demo1.c b/progs/egl/demo1.c index 34a516e72fc..d892734ee55 100644 --- a/progs/egl/demo1.c +++ b/progs/egl/demo1.c @@ -114,6 +114,7 @@ main(int argc, char *argv[]) PrintConfigs(d, configs, numConfigs); + eglBindAPI(EGL_OPENGL_API); ctx = eglCreateContext(d, configs[0], EGL_NO_CONTEXT, NULL); if (ctx == EGL_NO_CONTEXT) { printf("failed to create context\n"); diff --git a/progs/egl/demo2.c b/progs/egl/demo2.c index 3994656721f..b9e92f62ac2 100644 --- a/progs/egl/demo2.c +++ b/progs/egl/demo2.c @@ -111,11 +111,7 @@ main(int argc, char *argv[]) EGL_HEIGHT, 500, EGL_NONE }; - const EGLint screenAttribs[] = { - EGL_WIDTH, 1024, - EGL_HEIGHT, 768, - EGL_NONE - }; + EGLint screenAttribs[32]; EGLModeMESA mode; EGLScreenMESA screen; EGLint count; @@ -149,6 +145,7 @@ main(int argc, char *argv[]) eglGetScreensMESA(d, &screen, 1, &count); eglGetModesMESA(d, screen, &mode, 1, &count); + eglBindAPI(EGL_OPENGL_API); ctx = eglCreateContext(d, configs[0], EGL_NO_CONTEXT, NULL); if (ctx == EGL_NO_CONTEXT) { printf("failed to create context\n"); @@ -169,6 +166,13 @@ main(int argc, char *argv[]) b = eglMakeCurrent(d, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); + i = 0; + screenAttribs[i++] = EGL_WIDTH; + eglGetModeAttribMESA(d, mode, EGL_WIDTH, &screenAttribs[i++]); + screenAttribs[i++] = EGL_HEIGHT; + eglGetModeAttribMESA(d, mode, EGL_HEIGHT, &screenAttribs[i++]); + screenAttribs[i] = EGL_NONE; + screen_surf = eglCreateScreenSurfaceMESA(d, configs[0], screenAttribs); if (screen_surf == EGL_NO_SURFACE) { printf("failed to create screen surface\n"); diff --git a/progs/egl/demo3.c b/progs/egl/demo3.c index 0665fd0516e..64b9ee652cd 100644 --- a/progs/egl/demo3.c +++ b/progs/egl/demo3.c @@ -564,11 +564,8 @@ main(int argc, char *argv[]) EGLint numConfigs, count; EGLBoolean b; const GLubyte *bitmap; - const EGLint screenAttribs[] = { - EGL_WIDTH, 1024, - EGL_HEIGHT, 768, - EGL_NONE - }; + EGLint screenAttribs[32]; + EGLint i; EGLDisplay d = eglGetDisplay(EGL_DEFAULT_DISPLAY); assert(d); @@ -590,12 +587,20 @@ main(int argc, char *argv[]) eglGetScreensMESA(d, &screen, 1, &count); eglGetModesMESA(d, screen, &mode, 1, &count); + eglBindAPI(EGL_OPENGL_API); ctx = eglCreateContext(d, configs[0], EGL_NO_CONTEXT, NULL); if (ctx == EGL_NO_CONTEXT) { printf("failed to create context\n"); return 0; } + i = 0; + screenAttribs[i++] = EGL_WIDTH; + eglGetModeAttribMESA(d, mode, EGL_WIDTH, &screenAttribs[i++]); + screenAttribs[i++] = EGL_HEIGHT; + eglGetModeAttribMESA(d, mode, EGL_HEIGHT, &screenAttribs[i++]); + screenAttribs[i] = EGL_NONE; + screen_surf = eglCreateScreenSurfaceMESA(d, configs[0], screenAttribs); if (screen_surf == EGL_NO_SURFACE) { printf("failed to create screen surface\n"); diff --git a/progs/egl/eglgears.c b/progs/egl/eglgears.c index 2d9b8cac7f7..63490953aee 100644 --- a/progs/egl/eglgears.c +++ b/progs/egl/eglgears.c @@ -426,6 +426,7 @@ main(int argc, char *argv[]) } printf("eglgears: Using screen mode/size %d: %d x %d\n", chosenMode, width, height); + eglBindAPI(EGL_OPENGL_API); ctx = eglCreateContext(d, configs[0], EGL_NO_CONTEXT, NULL); if (ctx == EGL_NO_CONTEXT) { printf("eglgears: failed to create context\n"); diff --git a/progs/egl/eglinfo.c b/progs/egl/eglinfo.c index 4486916e958..9664667a68a 100644 --- a/progs/egl/eglinfo.c +++ b/progs/egl/eglinfo.c @@ -49,16 +49,15 @@ PrintConfigs(EGLDisplay d) eglGetConfigs(d, configs, MAX_CONFIGS, &numConfigs); printf("Configurations:\n"); - printf(" bf lv d st colorbuffer dp st ms vis supported\n"); - printf(" id sz l b ro r g b a th cl ns b id surfaces \n"); - printf("--------------------------------------------------------\n"); + printf(" bf lv colorbuffer dp st ms vis cav bi renderable supported\n"); + printf(" id sz l r g b a th cl ns b id eat nd gl es es2 vg surfaces \n"); + printf("---------------------------------------------------------------------\n"); for (i = 0; i < numConfigs; i++) { EGLint id, size, level; EGLint red, green, blue, alpha; EGLint depth, stencil; - EGLint surfaces; - EGLint doubleBuf = 1, stereo = 0; - EGLint vid; + EGLint renderable, surfaces; + EGLint vid, caveat, bindRgb, bindRgba; EGLint samples, sampleBuffers; char surfString[100] = ""; @@ -73,6 +72,11 @@ PrintConfigs(EGLDisplay d) eglGetConfigAttrib(d, configs[i], EGL_DEPTH_SIZE, &depth); eglGetConfigAttrib(d, configs[i], EGL_STENCIL_SIZE, &stencil); eglGetConfigAttrib(d, configs[i], EGL_NATIVE_VISUAL_ID, &vid); + + eglGetConfigAttrib(d, configs[i], EGL_CONFIG_CAVEAT, &caveat); + eglGetConfigAttrib(d, configs[i], EGL_BIND_TO_TEXTURE_RGB, &bindRgb); + eglGetConfigAttrib(d, configs[i], EGL_BIND_TO_TEXTURE_RGBA, &bindRgba); + eglGetConfigAttrib(d, configs[i], EGL_RENDERABLE_TYPE, &renderable); eglGetConfigAttrib(d, configs[i], EGL_SURFACE_TYPE, &surfaces); eglGetConfigAttrib(d, configs[i], EGL_SAMPLES, &samples); @@ -91,13 +95,19 @@ PrintConfigs(EGLDisplay d) if (strlen(surfString) > 0) surfString[strlen(surfString) - 1] = 0; - printf("0x%02x %2d %2d %c %c %2d %2d %2d %2d %2d %2d %2d%2d 0x%02x %-12s\n", + printf("0x%02x %2d %2d %2d %2d %2d %2d %2d %2d %2d%2d 0x%03x ", id, size, level, - doubleBuf ? 'y' : '.', - stereo ? 'y' : '.', red, green, blue, alpha, depth, stencil, - samples, sampleBuffers, vid, surfString); + samples, sampleBuffers, vid); + printf(" %c %c %c %c %c %c %s\n", + (caveat != EGL_NONE) ? 'y' : ' ', + (bindRgba) ? 'a' : (bindRgb) ? 'y' : ' ', + (renderable & EGL_OPENGL_BIT) ? 'y' : ' ', + (renderable & EGL_OPENGL_ES_BIT) ? 'y' : ' ', + (renderable & EGL_OPENGL_ES2_BIT) ? 'y' : ' ', + (renderable & EGL_OPENVG_BIT) ? 'y' : ' ', + surfString); } } diff --git a/progs/egl/egltri.c b/progs/egl/egltri.c index 9bbc3cddaf1..006e06eb03e 100644 --- a/progs/egl/egltri.c +++ b/progs/egl/egltri.c @@ -208,6 +208,7 @@ int main(int argc, char *argv[]) } printf("egltri: Using screen mode/size %d: %d x %d\n", chosenMode, width, height); + eglBindAPI(EGL_OPENGL_API); ctx = eglCreateContext(d, configs[0], EGL_NO_CONTEXT, NULL); if (ctx == EGL_NO_CONTEXT) { printf("egltri: failed to create context\n"); diff --git a/progs/egl/xegl_tri.c b/progs/egl/xegl_tri.c index 65f352ddfa9..1f1a005a210 100644 --- a/progs/egl/xegl_tri.c +++ b/progs/egl/xegl_tri.c @@ -120,6 +120,7 @@ make_x_window(Display *x_dpy, EGLDisplay egl_dpy, EGL_GREEN_SIZE, 1, EGL_BLUE_SIZE, 1, EGL_DEPTH_SIZE, 1, + EGL_RENDERABLE_TYPE, EGL_OPENGL_BIT, EGL_NONE }; @@ -138,7 +139,8 @@ make_x_window(Display *x_dpy, EGLDisplay egl_dpy, scrnum = DefaultScreen( x_dpy ); root = RootWindow( x_dpy, scrnum ); - if (!eglChooseConfig( egl_dpy, attribs, &config, 1, &num_configs)) { + if (!eglChooseConfig( egl_dpy, attribs, &config, 1, &num_configs) || + !num_configs) { printf("Error: couldn't get an EGL visual config\n"); exit(1); } diff --git a/progs/egl/xeglgears.c b/progs/egl/xeglgears.c index 614a6256037..9fdf4742441 100644 --- a/progs/egl/xeglgears.c +++ b/progs/egl/xeglgears.c @@ -604,7 +604,7 @@ event_loop(struct egl_manager *eman, EGLint surface_type, EGLint w, EGLint h) break; case EGL_PBUFFER_BIT: eglWaitClient(); - if (!eglCopyBuffers(eman->xdpy, eman->pbuf, eman->xpix)) + if (!eglCopyBuffers(eman->dpy, eman->pbuf, eman->xpix)) break; /* fall through */ case EGL_PIXMAP_BIT: diff --git a/progs/egl/xeglthreads.c b/progs/egl/xeglthreads.c index 508dbc09432..5787faecb90 100644 --- a/progs/egl/xeglthreads.c +++ b/progs/egl/xeglthreads.c @@ -467,6 +467,7 @@ create_window(struct winthread *wt, EGLContext shareCtx) EGL_GREEN_SIZE, 1, EGL_BLUE_SIZE, 1, EGL_DEPTH_SIZE, 1, + EGL_RENDERABLE_TYPE, EGL_OPENGL_BIT, EGL_NONE }; EGLConfig config; EGLint num_configs; @@ -484,7 +485,8 @@ create_window(struct winthread *wt, EGLContext shareCtx) scrnum = DefaultScreen(wt->Dpy); root = RootWindow(wt->Dpy, scrnum); - if (!eglChooseConfig(wt->Display, attribs, &config, 1, &num_configs)) { + if (!eglChooseConfig(wt->Display, attribs, &config, 1, &num_configs) || + !num_configs) { Error("Unable to choose an EGL config"); } diff --git a/progs/es1/.gitignore b/progs/es1/.gitignore new file mode 100644 index 00000000000..4f1427531a8 --- /dev/null +++ b/progs/es1/.gitignore @@ -0,0 +1,10 @@ +screen/gears +screen/tri +xegl/drawtex +xegl/es1_info +xegl/msaa +xegl/pbuffer +xegl/render_tex +xegl/torus +xegl/tri +xegl/two_win diff --git a/progs/es1/screen/Makefile b/progs/es1/screen/Makefile new file mode 100644 index 00000000000..4ba2f9a7dc1 --- /dev/null +++ b/progs/es1/screen/Makefile @@ -0,0 +1,32 @@ +# progs/es1/screen/Makefile + +TOP = ../../.. +include $(TOP)/configs/current + +ES1_CFLAGS = -I$(TOP)/include +ES1_LIBS = -L$(TOP)/$(LIB_DIR) -lEGL -lGLESv1_CM + +ES1_LIB_DEPS = \ + $(TOP)/$(LIB_DIR)/libEGL.so \ + $(TOP)/$(LIB_DIR)/libGLESv1_CM.so + +WINSYS_OBJS = winsys.o + +PROGRAMS = \ + gears \ + tri + +.c.o: + $(CC) -c $(ES1_CFLAGS) $(CFLAGS) $< -o $@ + +default: $(PROGRAMS) + +gears: gears.o $(WINSYS_OBJS) $(ES1_LIB_DEPS) + $(CC) $(CFLAGS) -o $@ [email protected] $(WINSYS_OBJS) $(ES1_LIBS) + +tri: tri.o $(WINSYS_OBJS) $(ES1_LIB_DEPS) + $(CC) $(CFLAGS) -o $@ [email protected] $(WINSYS_OBJS) $(ES1_LIBS) + +clean: + -rm -f *.o *~ + -rm -f $(PROGRAMS) diff --git a/progs/es1/screen/gears.c b/progs/es1/screen/gears.c new file mode 100644 index 00000000000..c7625826b97 --- /dev/null +++ b/progs/es1/screen/gears.c @@ -0,0 +1,374 @@ +/* + * Copyright (C) 2009 Chia-I Wu <[email protected]> + * + * Based on eglgears by + * Copyright (C) 1999-2001 Brian Paul All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#include <stdlib.h> +#include <stdio.h> +#include <math.h> +#include <assert.h> + +#include <GLES/gl.h> +#include "winsys.h" + +#ifndef M_PI +#define M_PI 3.14159265 +#endif + + +struct gear { + GLuint vbo; + GLfloat *vertices; + GLsizei stride; + + GLint num_teeth; +}; + +static GLfloat view_rotx = 20.0, view_roty = 30.0, view_rotz = 0.0; +static struct gear gears[3]; +static GLfloat angle = 0.0; + +/* + * Initialize a gear wheel. + * + * Input: gear - gear to initialize + * inner_radius - radius of hole at center + * outer_radius - radius at center of teeth + * width - width of gear + * teeth - number of teeth + * tooth_depth - depth of tooth + */ +static void +init_gear(struct gear *gear, GLfloat inner_radius, GLfloat outer_radius, + GLfloat width, GLint teeth, GLfloat tooth_depth) +{ + GLfloat r0, r1, r2; + GLfloat a0, da; + GLint verts_per_tooth, total_verts, total_size; + GLint count, i; + GLfloat *verts; + + r0 = inner_radius; + r1 = outer_radius - tooth_depth / 2.0; + r2 = outer_radius + tooth_depth / 2.0; + + a0 = 2.0 * M_PI / teeth; + da = a0 / 4.0; + + gear->vbo = 0; + gear->vertices = NULL; + gear->stride = sizeof(GLfloat) * 6; /* XYZ + normal */ + gear->num_teeth = teeth; + + verts_per_tooth = 10 + 4; + total_verts = teeth * verts_per_tooth; + total_size = total_verts * gear->stride; + + verts = malloc(total_size); + if (!verts) { + printf("failed to allocate vertices\n"); + return; + } + +#define GEAR_VERT(r, n, sign) \ + do { \ + verts[count * 6 + 0] = (r) * vx[n]; \ + verts[count * 6 + 1] = (r) * vy[n]; \ + verts[count * 6 + 2] = (sign) * width * 0.5; \ + verts[count * 6 + 3] = normal[0]; \ + verts[count * 6 + 4] = normal[1]; \ + verts[count * 6 + 5] = normal[2]; \ + count++; \ + } while (0) + + count = 0; + for (i = 0; i < teeth; i++) { + GLfloat normal[3]; + GLfloat vx[5], vy[5]; + GLfloat u, v; + + normal[0] = 0.0; + normal[1] = 0.0; + normal[2] = 0.0; + + vx[0] = cos(i * a0 + 0 * da); + vy[0] = sin(i * a0 + 0 * da); + vx[1] = cos(i * a0 + 1 * da); + vy[1] = sin(i * a0 + 1 * da); + vx[2] = cos(i * a0 + 2 * da); + vy[2] = sin(i * a0 + 2 * da); + vx[3] = cos(i * a0 + 3 * da); + vy[3] = sin(i * a0 + 3 * da); + vx[4] = cos(i * a0 + 4 * da); + vy[4] = sin(i * a0 + 4 * da); + + /* outward faces of a tooth, 10 verts */ + normal[0] = vx[0]; + normal[1] = vy[0]; + GEAR_VERT(r1, 0, 1); + GEAR_VERT(r1, 0, -1); + + u = r2 * vx[1] - r1 * vx[0]; + v = r2 * vy[1] - r1 * vy[0]; + normal[0] = v; + normal[1] = -u; + GEAR_VERT(r2, 1, 1); + GEAR_VERT(r2, 1, -1); + + normal[0] = vx[0]; + normal[1] = vy[0]; + GEAR_VERT(r2, 2, 1); + GEAR_VERT(r2, 2, -1); + + u = r1 * vx[3] - r2 * vx[2]; + v = r1 * vy[3] - r2 * vy[2]; + normal[0] = v; + normal[1] = -u; + GEAR_VERT(r1, 3, 1); + GEAR_VERT(r1, 3, -1); + + normal[0] = vx[0]; + normal[1] = vy[0]; + GEAR_VERT(r1, 4, 1); + GEAR_VERT(r1, 4, -1); + + /* inside radius cylinder, 4 verts */ + normal[0] = -vx[4]; + normal[1] = -vy[4]; + GEAR_VERT(r0, 4, 1); + GEAR_VERT(r0, 4, -1); + + normal[0] = -vx[0]; + normal[1] = -vy[0]; + GEAR_VERT(r0, 0, 1); + GEAR_VERT(r0, 0, -1); + + assert(count % verts_per_tooth == 0); + } + assert(count == total_verts); +#undef GEAR_VERT + + gear->vertices = verts; + + /* setup VBO */ + glGenBuffers(1, &gear->vbo); + if (gear->vbo) { + glBindBuffer(GL_ARRAY_BUFFER, gear->vbo); + glBufferData(GL_ARRAY_BUFFER, total_size, verts, GL_STATIC_DRAW); + } +} + + +static void +draw_gear(const struct gear *gear) +{ + GLint i; + + if (!gear->vbo && !gear->vertices) { + printf("nothing to be drawn\n"); + return; + } + + if (gear->vbo) { + glBindBuffer(GL_ARRAY_BUFFER, gear->vbo); + glVertexPointer(3, GL_FLOAT, gear->stride, (const GLvoid *) 0); + glNormalPointer(GL_FLOAT, gear->stride, (const GLvoid *) (sizeof(GLfloat) * 3)); + } else { + glBindBuffer(GL_ARRAY_BUFFER, 0); + glVertexPointer(3, GL_FLOAT, gear->stride, gear->vertices); + glNormalPointer(GL_FLOAT, gear->stride, gear->vertices + 3); + } + + glEnableClientState(GL_VERTEX_ARRAY); + + for (i = 0; i < gear->num_teeth; i++) { + const GLint base = (10 + 4) * i; + GLushort indices[7]; + + glShadeModel(GL_FLAT); + + /* front face */ + indices[0] = base + 12; + indices[1] = base + 0; + indices[2] = base + 2; + indices[3] = base + 4; + indices[4] = base + 6; + indices[5] = base + 8; + indices[6] = base + 10; + + glNormal3f(0.0, 0.0, 1.0); + glDrawElements(GL_TRIANGLE_FAN, 7, GL_UNSIGNED_SHORT, indices); + + /* back face */ + indices[0] = base + 13; + indices[1] = base + 11; + indices[2] = base + 9; + indices[3] = base + 7; + indices[4] = base + 5; + indices[5] = base + 3; + indices[6] = base + 1; + + glNormal3f(0.0, 0.0, -1.0); + glDrawElements(GL_TRIANGLE_FAN, 7, GL_UNSIGNED_SHORT, indices); + + glEnableClientState(GL_NORMAL_ARRAY); + + /* outward face of a tooth */ + glDrawArrays(GL_TRIANGLE_STRIP, base, 10); + + /* inside radius cylinder */ + glShadeModel(GL_SMOOTH); + glDrawArrays(GL_TRIANGLE_STRIP, base + 10, 4); + + glDisableClientState(GL_NORMAL_ARRAY); + } + + glDisableClientState(GL_VERTEX_ARRAY); +} + + +static void +gears_draw(void *data) +{ + static const GLfloat red[4] = { 0.8, 0.1, 0.0, 1.0 }; + static const GLfloat green[4] = { 0.0, 0.8, 0.2, 1.0 }; + static const GLfloat blue[4] = { 0.2, 0.2, 1.0, 1.0 }; + + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + glPushMatrix(); + glRotatef(view_rotx, 1.0, 0.0, 0.0); + glRotatef(view_roty, 0.0, 1.0, 0.0); + glRotatef(view_rotz, 0.0, 0.0, 1.0); + + glPushMatrix(); + glTranslatef(-3.0, -2.0, 0.0); + glRotatef(angle, 0.0, 0.0, 1.0); + + glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, red); + draw_gear(&gears[0]); + + glPopMatrix(); + + glPushMatrix(); + glTranslatef(3.1, -2.0, 0.0); + glRotatef(-2.0 * angle - 9.0, 0.0, 0.0, 1.0); + + glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, green); + draw_gear(&gears[1]); + + glPopMatrix(); + + glPushMatrix(); + glTranslatef(-3.1, 4.2, 0.0); + glRotatef(-2.0 * angle - 25.0, 0.0, 0.0, 1.0); + + glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, blue); + draw_gear(&gears[2]); + + glPopMatrix(); + + glPopMatrix(); + + /* advance rotation for next frame */ + angle += 0.5; /* 0.5 degree per frame */ + if (angle > 3600.0) + angle -= 3600.0; +} + + +static void gears_fini(void) +{ + GLint i; + for (i = 0; i < 3; i++) { + struct gear *gear = &gears[i]; + if (gear->vbo) { + glDeleteBuffers(1, &gear->vbo); + gear->vbo = 0; + } + if (gear->vertices) { + free(gear->vertices); + gear->vertices = NULL; + } + } +} + + +static void gears_init(void) +{ + static const GLfloat pos[4] = { 5.0, 5.0, 10.0, 0.0 }; + + glLightfv(GL_LIGHT0, GL_POSITION, pos); + glEnable(GL_CULL_FACE); + glEnable(GL_LIGHTING); + glEnable(GL_LIGHT0); + glEnable(GL_DEPTH_TEST); + glEnable(GL_NORMALIZE); + + init_gear(&gears[0], 1.0, 4.0, 1.0, 20, 0.7); + init_gear(&gears[1], 0.5, 2.0, 2.0, 10, 0.7); + init_gear(&gears[2], 1.3, 2.0, 0.5, 10, 0.7); +} + + +/* new window size or exposure */ +static void +gears_reshape(int width, int height) +{ + GLfloat h = (GLfloat) height / (GLfloat) width; + + glViewport(0, 0, (GLint) width, (GLint) height); + + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + glFrustumf(-1.0, 1.0, -h, h, 5.0, 60.0); + + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + glTranslatef(0.0, 0.0, -40.0); +} + + +static void gears_run(void) +{ + winsysRun(5.0, gears_draw, NULL); +} + + +int +main(int argc, char *argv[]) +{ + EGLint width, height; + + if (!winsysInitScreen()) + exit(1); + winsysQueryScreenSize(&width, &height); + + gears_init(); + gears_reshape(width, height); + gears_run(); + gears_fini(); + + winsysFiniScreen(); + + return 0; +} diff --git a/progs/es1/screen/tri.c b/progs/es1/screen/tri.c new file mode 100644 index 00000000000..bab9499944b --- /dev/null +++ b/progs/es1/screen/tri.c @@ -0,0 +1,129 @@ +/* + * Copyright (C) 2009 Chia-I Wu <[email protected]> + * + * Based on egltri by + * Copyright (C) 1999-2001 Brian Paul All Rights Reserved. + * Copyright (C) 2008 Brian Paul All Rights Reserved. + * Copyright (C) 2008 Jakob Bornecrantz All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <GLES/gl.h> +#include "winsys.h" + +static GLfloat view_rotx = 0.0, view_roty = 0.0, view_rotz = 0.0; + +static void tri_init() +{ + glClearColor(0.4, 0.4, 0.4, 0.0); +} + +static void tri_reshape(int width, int height) +{ + GLfloat ar = (GLfloat) width / (GLfloat) height; + + glViewport(0, 0, (GLint) width, (GLint) height); + + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + glFrustumf(-ar, ar, -1, 1, 5.0, 60.0); + + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + glTranslatef(0.0, 0.0, -10.0); +} + +static void tri_draw(void *data) +{ + static const GLfloat verts[3][2] = { + { -1, -1 }, + { 1, -1 }, + { 0, 1 } + }; + static const GLfloat colors[3][4] = { + { 1, 0, 0, 1 }, + { 0, 1, 0, 1 }, + { 0, 0, 1, 1 } + }; + + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + glPushMatrix(); + glRotatef(view_rotx, 1, 0, 0); + glRotatef(view_roty, 0, 1, 0); + glRotatef(view_rotz, 0, 0, 1); + + { + glVertexPointer(2, GL_FLOAT, 0, verts); + glColorPointer(4, GL_FLOAT, 0, colors); + glEnableClientState(GL_VERTEX_ARRAY); + glEnableClientState(GL_COLOR_ARRAY); + + glDrawArrays(GL_TRIANGLES, 0, 3); + + glDisableClientState(GL_VERTEX_ARRAY); + glDisableClientState(GL_COLOR_ARRAY); + } + + glPopMatrix(); +} + +static void tri_run(void) +{ + winsysRun(3.0, tri_draw, NULL); +} + +int main(int argc, char *argv[]) +{ + EGLint width, height; + GLboolean printInfo = GL_FALSE; + int i; + + /* parse cmd line args */ + for (i = 1; i < argc; i++) { + if (strcmp(argv[i], "-info") == 0) { + printInfo = GL_TRUE; + } + else { + printf("Warning: unknown parameter: %s\n", argv[i]); + } + } + + if (!winsysInitScreen()) + exit(1); + winsysQueryScreenSize(&width, &height); + + if (printInfo) { + printf("GL_RENDERER = %s\n", (char *) glGetString(GL_RENDERER)); + printf("GL_VERSION = %s\n", (char *) glGetString(GL_VERSION)); + printf("GL_VENDOR = %s\n", (char *) glGetString(GL_VENDOR)); + printf("GL_EXTENSIONS = %s\n", (char *) glGetString(GL_EXTENSIONS)); + } + + tri_init(); + tri_reshape(width, height); + tri_run(); + + winsysFiniScreen(); + + return 0; +} diff --git a/progs/es1/screen/winsys.c b/progs/es1/screen/winsys.c new file mode 100644 index 00000000000..84d00471eba --- /dev/null +++ b/progs/es1/screen/winsys.c @@ -0,0 +1,272 @@ +/* + * Copyright (C) 2009 Chia-I Wu <[email protected]> + * + * Based on eglgears by + * Copyright (C) 1999-2001 Brian Paul All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <assert.h> +#include <sys/time.h> + +#define EGL_EGLEXT_PROTOTYPES + +#include <EGL/egl.h> +#include <EGL/eglext.h> + +#include "winsys.h" + +#define MAX_MODES 100 + +static struct { + EGLBoolean verbose; + + EGLDisplay dpy; + EGLConfig conf; + + EGLScreenMESA screen; + EGLModeMESA mode; + EGLint width, height; + + EGLContext ctx; + EGLSurface surf; +} screen; + + +static EGLBoolean +init_screen(void) +{ + EGLModeMESA modes[MAX_MODES]; + EGLint num_screens, num_modes; + EGLint width, height, best_mode; + EGLint i; + + if (!eglGetScreensMESA(screen.dpy, &screen.screen, 1, &num_screens) || + !num_screens) { + printf("eglGetScreensMESA failed\n"); + return EGL_FALSE; + } + + if (!eglGetModesMESA(screen.dpy, screen.screen, modes, MAX_MODES, + &num_modes) || + !num_modes) { + printf("eglGetModesMESA failed!\n"); + return EGL_FALSE; + } + + printf("Found %d modes:\n", num_modes); + + best_mode = 0; + width = 0; + height = 0; + for (i = 0; i < num_modes; i++) { + EGLint w, h; + eglGetModeAttribMESA(screen.dpy, modes[i], EGL_WIDTH, &w); + eglGetModeAttribMESA(screen.dpy, modes[i], EGL_HEIGHT, &h); + printf("%3d: %d x %d\n", i, w, h); + if (w > width && h > height) { + width = w; + height = h; + best_mode = i; + } + } + + screen.mode = modes[best_mode]; + screen.width = width; + screen.height = height; + + return EGL_TRUE; +} + + +static EGLBoolean +init_display(void) +{ + EGLint maj, min; + const char *exts; + const EGLint attribs[] = { + EGL_SURFACE_TYPE, 0x0, /* should be EGL_SCREEN_BIT_MESA */ + EGL_RENDERABLE_TYPE, 0x0, /* should be EGL_OPENGL_ES_BIT */ + EGL_NONE + }; + EGLint num_configs; + + screen.dpy = eglGetDisplay(EGL_DEFAULT_DISPLAY); + if (!screen.dpy) { + printf("eglGetDisplay failed\n"); + return EGL_FALSE; + } + + if (!eglInitialize(screen.dpy, &maj, &min)) { + printf("eglInitialize failed\n"); + return EGL_FALSE; + } + + printf("EGL_VERSION = %s\n", eglQueryString(screen.dpy, EGL_VERSION)); + printf("EGL_VENDOR = %s\n", eglQueryString(screen.dpy, EGL_VENDOR)); + + exts = eglQueryString(screen.dpy, EGL_EXTENSIONS); + assert(exts); + + if (!strstr(exts, "EGL_MESA_screen_surface")) { + printf("EGL_MESA_screen_surface is not supported\n"); + return EGL_FALSE; + } + + if (!eglChooseConfig(screen.dpy, attribs, &screen.conf, 1, + &num_configs) || + !num_configs) { + printf("eglChooseConfig failed\n"); + return EGL_FALSE; + } + + return EGL_TRUE; +} + + +EGLBoolean +winsysInitScreen(void) +{ + EGLint surf_attribs[20]; + EGLint i; + EGLBoolean ok; + + if (!init_display()) + goto fail; + if (!init_screen()) + goto fail; + + /* create context */ + screen.ctx = eglCreateContext(screen.dpy, screen.conf, + EGL_NO_CONTEXT, NULL); + if (screen.ctx == EGL_NO_CONTEXT) { + printf("eglCreateContext failed\n"); + goto fail; + } + + i = 0; + surf_attribs[i++] = EGL_WIDTH; + surf_attribs[i++] = screen.width; + surf_attribs[i++] = EGL_HEIGHT; + surf_attribs[i++] = screen.height; + surf_attribs[i++] = EGL_NONE; + + /* create surface */ + printf("Using screen size: %d x %d\n", screen.width, screen.height); + screen.surf = eglCreateScreenSurfaceMESA(screen.dpy, screen.conf, + surf_attribs); + if (screen.surf == EGL_NO_SURFACE) { + printf("eglCreateScreenSurfaceMESA failed\n"); + goto fail; + } + + ok = eglMakeCurrent(screen.dpy, screen.surf, screen.surf, screen.ctx); + if (!ok) { + printf("eglMakeCurrent failed\n"); + goto fail; + } + + ok = eglShowScreenSurfaceMESA(screen.dpy, screen.screen, + screen.surf, screen.mode); + if (!ok) { + printf("eglShowScreenSurfaceMESA failed\n"); + goto fail; + } + + return EGL_TRUE; + +fail: + winsysFiniScreen(); + return EGL_FALSE; +} + + +EGLBoolean +winsysQueryScreenSize(EGLint *width, EGLint *height) +{ + if (!screen.dpy) + return EGL_FALSE; + + if (width) + *width = screen.width; + if (height) + *height = screen.height; + + return EGL_TRUE; +} + + +void +winsysFiniScreen(void) +{ + if (screen.dpy) { + eglMakeCurrent(screen.dpy, EGL_NO_SURFACE, EGL_NO_SURFACE, + EGL_NO_CONTEXT); + if (screen.surf != EGL_NO_SURFACE) + eglDestroySurface(screen.dpy, screen.surf); + if (screen.ctx != EGL_NO_CONTEXT) + eglDestroyContext(screen.dpy, screen.ctx); + eglTerminate(screen.dpy); + + memset(&screen, 0, sizeof(screen)); + } +} + + +void +winsysSwapBuffers(void) +{ + eglSwapBuffers(screen.dpy, screen.surf); +} + + +/* return current time (in seconds) */ +double +winsysNow(void) +{ + struct timeval tv; + gettimeofday(&tv, NULL); + return (double) tv.tv_sec + tv.tv_usec / 1000000.0; +} + + +void +winsysRun(double seconds, void (*draw_frame)(void *data), void *data) +{ + double begin, end, last_frame, duration; + EGLint num_frames = 0; + + begin = winsysNow(); + end = begin + seconds; + + last_frame = begin; + while (last_frame < end) { + draw_frame(data); + winsysSwapBuffers(); + last_frame = winsysNow(); + num_frames++; + } + + duration = last_frame - begin; + printf("%d frames in %3.1f seconds = %6.3f FPS\n", + num_frames, duration, (double) num_frames / duration); +} diff --git a/progs/es1/screen/winsys.h b/progs/es1/screen/winsys.h new file mode 100644 index 00000000000..679c7e0bd6d --- /dev/null +++ b/progs/es1/screen/winsys.h @@ -0,0 +1,36 @@ +/* + * Copyright (C) 2009 Chia-I Wu <[email protected]> + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifndef _WINSYS_H_ +#define _WINSYS_H_ + +#include <EGL/egl.h> + +EGLBoolean winsysInitScreen(void); +EGLBoolean winsysQueryScreenSize(EGLint *width, EGLint *height); +void winsysFiniScreen(void); + +void winsysSwapBuffers(void); +double winsysNow(void); + +void winsysRun(double seconds, void (*draw_frame)(void *data), void *data); + +#endif /* _WINSYS_H_ */ diff --git a/progs/es1/xegl/Makefile b/progs/es1/xegl/Makefile new file mode 100644 index 00000000000..6869c443065 --- /dev/null +++ b/progs/es1/xegl/Makefile @@ -0,0 +1,82 @@ +# progs/es1/xegl/Makefile + +TOP = ../../.. +include $(TOP)/configs/current + + +INCLUDE_DIRS = \ + -I$(TOP)/include \ + +HEADERS = $(TOP)/include/GLES/egl.h + + +ES1_LIB_DEPS = \ + $(TOP)/$(LIB_DIR)/libEGL.so \ + $(TOP)/$(LIB_DIR)/libGLESv1_CM.so + + +ES1_LIBS = \ + -L$(TOP)/$(LIB_DIR) -lEGL \ + -L$(TOP)/$(LIB_DIR) -lGLESv1_CM $(LIBDRM_LIB) -lX11 + +PROGRAMS = \ + bindtex \ + drawtex \ + es1_info \ + msaa \ + pbuffer \ + render_tex \ + torus \ + tri \ + two_win + + +.c.o: + $(CC) -c $(INCLUDE_DIRS) $(CFLAGS) $< -o $@ + + + +default: $(PROGRAMS) + + + +bindtex: bindtex.o $(ES1_LIB_DEPS) + $(CC) $(CFLAGS) bindtex.o $(ES1_LIBS) -o $@ + + +drawtex: drawtex.o $(ES1_LIB_DEPS) + $(CC) $(CFLAGS) drawtex.o $(ES1_LIBS) -o $@ + + +es1_info: es1_info.o $(ES1_LIB_DEPS) + $(CC) $(CFLAGS) es1_info.o $(ES1_LIBS) -o $@ + + +msaa: msaa.o $(ES1_LIB_DEPS) + $(CC) $(CFLAGS) msaa.o $(ES1_LIBS) -o $@ + + +pbuffer: pbuffer.o $(ES1_LIB_DEPS) + $(CC) $(CFLAGS) pbuffer.o $(ES1_LIBS) -o $@ + + +render_tex: render_tex.o $(ES1_LIB_DEPS) + $(CC) $(CFLAGS) render_tex.o $(ES1_LIBS) -o $@ + + +torus: torus.o $(ES1_LIB_DEPS) + $(CC) $(CFLAGS) torus.o $(ES1_LIBS) -o $@ + + +two_win: two_win.o $(ES1_LIB_DEPS) + $(CC) $(CFLAGS) two_win.o $(ES1_LIBS) -o $@ + + +tri: tri.o $(ES1_LIB_DEPS) + $(CC) $(CFLAGS) tri.o $(ES1_LIBS) -o $@ + + +clean: + rm -f *.o *~ + rm -f $(PROGRAMS) + diff --git a/progs/egl/xeglbindtex.c b/progs/es1/xegl/bindtex.c index fdd9fe2b87b..c243b5941b7 100644 --- a/progs/egl/xeglbindtex.c +++ b/progs/es1/xegl/bindtex.c @@ -33,7 +33,7 @@ #include <X11/Xlib.h> #include <X11/Xutil.h> #include <X11/keysym.h> -#include <GL/gl.h> +#include <GLES/gl.h> #include <EGL/egl.h> static EGLDisplay dpy; @@ -65,20 +65,18 @@ make_pbuffer(int width, int height) EGLConfig config; EGLint num_configs; - if (!eglChooseConfig(dpy, config_attribs, &config, 1, &num_configs)) { + if (!eglChooseConfig(dpy, config_attribs, &config, 1, &num_configs) || + !num_configs) { printf("Error: couldn't get an EGL visual config for pbuffer\n"); exit(1); } - eglBindAPI(EGL_OPENGL_API); ctx_pbuf = eglCreateContext(dpy, config, EGL_NO_CONTEXT, NULL ); surf_pbuf = eglCreatePbufferSurface(dpy, config, pbuf_attribs); if (surf_pbuf == EGL_NO_SURFACE) { printf("failed to allocate pbuffer\n"); exit(1); } - - glGenTextures(1, &tex_pbuf); } static void @@ -101,7 +99,7 @@ use_pbuffer(void) glMatrixMode(GL_PROJECTION); glLoadIdentity(); - glFrustum(-ar, ar, -1, 1, 1.0, 10.0); + glFrustumf(-ar, ar, -1, 1, 1.0, 10.0); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); @@ -112,6 +110,8 @@ use_pbuffer(void) glTranslatef(0.0, 0.0, -5.0); glClearColor(0.2, 0.2, 0.2, 0.0); + + glGenTextures(1, &tex_pbuf); } } @@ -142,7 +142,8 @@ make_window(Display *x_dpy, const char *name, scrnum = DefaultScreen( x_dpy ); root = RootWindow( x_dpy, scrnum ); - if (!eglChooseConfig(dpy, attribs, &config, 1, &num_configs)) { + if (!eglChooseConfig(dpy, attribs, &config, 1, &num_configs) || + !num_configs) { printf("Error: couldn't get an EGL visual config\n"); exit(1); } @@ -185,10 +186,9 @@ make_window(Display *x_dpy, const char *name, None, (char **)NULL, 0, &sizehints); } - eglBindAPI(EGL_OPENGL_API); ctx_win = eglCreateContext(dpy, config, EGL_NO_CONTEXT, NULL ); if (!ctx_win) { - printf("Error: glXCreateContext failed\n"); + printf("Error: eglCreateContext failed\n"); exit(1); } @@ -223,10 +223,10 @@ draw_triangle(void) { 3, -3 }, { 0, 3 } }; - GLfloat colors[3][3] = { - { 1, 0, 0 }, - { 0, 1, 0 }, - { 0, 0, 1 } + GLfloat colors[3][4] = { + { 1, 0, 0, 1 }, + { 0, 1, 0, 1 }, + { 0, 0, 1, 1 } }; GLint i; @@ -246,7 +246,7 @@ draw_triangle(void) glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glVertexPointer(2, GL_FLOAT, 0, verts); - glColorPointer(3, GL_FLOAT, 0, colors); + glColorPointer(4, GL_FLOAT, 0, colors); glEnableClientState(GL_VERTEX_ARRAY); glEnableClientState(GL_COLOR_ARRAY); @@ -352,7 +352,7 @@ reshape(int width, int height) glMatrixMode(GL_PROJECTION); glLoadIdentity(); - glFrustum(-ar, ar, -1, 1, 5.0, 60.0); + glFrustumf(-ar, ar, -1, 1, 5.0, 60.0); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); diff --git a/progs/es1/xegl/drawtex.c b/progs/es1/xegl/drawtex.c new file mode 100644 index 00000000000..ca0615e267b --- /dev/null +++ b/progs/es1/xegl/drawtex.c @@ -0,0 +1,427 @@ +/* + * Copyright (C) 2008 Tunsgten Graphics,Inc. All Rights Reserved. + */ + +/* + * Test GL_OES_draw_texture + * Brian Paul + * August 2008 + */ + +#define GL_GLEXT_PROTOTYPES + +#include <assert.h> +#include <math.h> +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <X11/Xlib.h> +#include <X11/Xutil.h> +#include <X11/keysym.h> +#include <GLES/gl.h> +#include <GLES/glext.h> +#include <EGL/egl.h> + + + +static GLfloat view_posx = 10.0, view_posy = 20.0; +static GLfloat width = 200, height = 200; + + +static void +draw(void) +{ + glClear(GL_COLOR_BUFFER_BIT); + + glDrawTexfOES(view_posx, view_posy, 0.0, width, height); +} + + +/* new window size or exposure */ +static void +reshape(int width, int height) +{ + GLfloat ar = (GLfloat) width / (GLfloat) height; + + glViewport(0, 0, (GLint) width, (GLint) height); + + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + +#ifdef GL_VERSION_ES_CM_1_0 + glFrustumf(-ar, ar, -1, 1, 5.0, 60.0); +#else + glFrustum(-ar, ar, -1, 1, 5.0, 60.0); +#endif + + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + glTranslatef(0.0, 0.0, -15.0); +} + + +static float +dist(GLuint i, GLuint j, float x, float y) +{ + return sqrt((i-x) * (i-x) + (j-y) * (j-y)); +} + +static void +make_smile_texture(void) +{ +#define SZ 128 + GLenum Filter = GL_LINEAR; + GLubyte image[SZ][SZ][4]; + GLuint i, j; + GLint cropRect[4]; + + for (i = 0; i < SZ; i++) { + for (j = 0; j < SZ; j++) { + GLfloat d_mouth = dist(i, j, SZ/2, SZ/2); + GLfloat d_rt_eye = dist(i, j, SZ*3/4, SZ*3/4); + GLfloat d_lt_eye = dist(i, j, SZ*3/4, SZ*1/4); + if (d_rt_eye < SZ / 8 || d_lt_eye < SZ / 8) { + image[i][j][0] = 20; + image[i][j][1] = 50; + image[i][j][2] = 255; + image[i][j][3] = 255; + } + else if (i < SZ/2 && d_mouth < SZ/3) { + image[i][j][0] = 255; + image[i][j][1] = 20; + image[i][j][2] = 20; + image[i][j][3] = 255; + } + else { + image[i][j][0] = 200; + image[i][j][1] = 200; + image[i][j][2] = 200; + image[i][j][3] = 255; + } + } + } + + glActiveTexture(GL_TEXTURE0); /* unit 0 */ + glBindTexture(GL_TEXTURE_2D, 42); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, SZ, SZ, 0, + GL_RGBA, GL_UNSIGNED_BYTE, image); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, Filter); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, Filter); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); + + cropRect[0] = 0; + cropRect[1] = 0; + cropRect[2] = SZ; + cropRect[3] = SZ; + glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_CROP_RECT_OES, cropRect); +#undef SZ +} + + + +static void +init(void) +{ + const char *ext = (char *) glGetString(GL_EXTENSIONS); + + if (!strstr(ext, "GL_OES_draw_texture")) { + fprintf(stderr, "Sorry, this program requires GL_OES_draw_texture"); + exit(1); + } + + glClearColor(0.4, 0.4, 0.4, 0.0); + + make_smile_texture(); + glEnable(GL_TEXTURE_2D); +} + + +/* + * Create an RGB, double-buffered X window. + * Return the window and context handles. + */ +static void +make_x_window(Display *x_dpy, EGLDisplay egl_dpy, + const char *name, + int x, int y, int width, int height, + Window *winRet, + EGLContext *ctxRet, + EGLSurface *surfRet) +{ + static const EGLint attribs[] = { + EGL_RED_SIZE, 1, + EGL_GREEN_SIZE, 1, + EGL_BLUE_SIZE, 1, + EGL_NONE + }; + + int scrnum; + XSetWindowAttributes attr; + unsigned long mask; + Window root; + Window win; + XVisualInfo *visInfo, visTemplate; + int num_visuals; + EGLContext ctx; + EGLConfig config; + EGLint num_configs; + EGLint vid; + + scrnum = DefaultScreen( x_dpy ); + root = RootWindow( x_dpy, scrnum ); + + if (!eglChooseConfig( egl_dpy, attribs, &config, 1, &num_configs)) { + printf("Error: couldn't get an EGL visual config\n"); + exit(1); + } + + assert(config); + assert(num_configs > 0); + + if (!eglGetConfigAttrib(egl_dpy, config, EGL_NATIVE_VISUAL_ID, &vid)) { + printf("Error: eglGetConfigAttrib() failed\n"); + exit(1); + } + + /* The X window visual must match the EGL config */ + visTemplate.visualid = vid; + visInfo = XGetVisualInfo(x_dpy, VisualIDMask, &visTemplate, &num_visuals); + if (!visInfo) { + printf("Error: couldn't get X visual\n"); + exit(1); + } + + /* window attributes */ + attr.background_pixel = 0; + attr.border_pixel = 0; + attr.colormap = XCreateColormap( x_dpy, root, visInfo->visual, AllocNone); + attr.event_mask = StructureNotifyMask | ExposureMask | KeyPressMask; + mask = CWBackPixel | CWBorderPixel | CWColormap | CWEventMask; + + win = XCreateWindow( x_dpy, root, 0, 0, width, height, + 0, visInfo->depth, InputOutput, + visInfo->visual, mask, &attr ); + + /* set hints and properties */ + { + XSizeHints sizehints; + sizehints.x = x; + sizehints.y = y; + sizehints.width = width; + sizehints.height = height; + sizehints.flags = USSize | USPosition; + XSetNormalHints(x_dpy, win, &sizehints); + XSetStandardProperties(x_dpy, win, name, name, + None, (char **)NULL, 0, &sizehints); + } + + eglBindAPI(EGL_OPENGL_ES_API); + + ctx = eglCreateContext(egl_dpy, config, EGL_NO_CONTEXT, NULL ); + if (!ctx) { + printf("Error: eglCreateContext failed\n"); + exit(1); + } + + *surfRet = eglCreateWindowSurface(egl_dpy, config, win, NULL); + + if (!*surfRet) { + printf("Error: eglCreateWindowSurface failed\n"); + exit(1); + } + + XFree(visInfo); + + *winRet = win; + *ctxRet = ctx; +} + + +static void +event_loop(Display *dpy, Window win, + EGLDisplay egl_dpy, EGLSurface egl_surf) +{ + int anim = 0; + + while (1) { + int redraw = 0; + + if (!anim || XPending(dpy)) { + XEvent event; + XNextEvent(dpy, &event); + + switch (event.type) { + case Expose: + redraw = 1; + break; + case ConfigureNotify: + reshape(event.xconfigure.width, event.xconfigure.height); + break; + case KeyPress: + { + char buffer[10]; + int r, code; + code = XLookupKeysym(&event.xkey, 0); + if (code == XK_Left) { + view_posx -= 1.0; + } + else if (code == XK_Right) { + view_posx += 1.0; + } + else if (code == XK_Up) { + view_posy += 1.0; + } + else if (code == XK_Down) { + view_posy -= 1.0; + } + else { + r = XLookupString(&event.xkey, buffer, sizeof(buffer), + NULL, NULL); + if (buffer[0] == ' ') { + anim = !anim; + } + else if (buffer[0] == 'w') { + width -= 1.0f; + } + else if (buffer[0] == 'W') { + width += 1.0f; + } + else if (buffer[0] == 'h') { + height -= 1.0f; + } + else if (buffer[0] == 'H') { + height += 1.0f; + } + else if (buffer[0] == 27) { + /* escape */ + return; + } + } + } + redraw = 1; + break; + default: + ; /*no-op*/ + } + } + + if (anim) { + view_posx += 1.0; + view_posy += 2.0; + redraw = 1; + } + + if (redraw) { + draw(); + eglSwapBuffers(egl_dpy, egl_surf); + } + } +} + + +static void +usage(void) +{ + printf("Usage:\n"); + printf(" -display <displayname> set the display to run on\n"); + printf(" -info display OpenGL renderer info\n"); +} + + +int +main(int argc, char *argv[]) +{ + const int winWidth = 400, winHeight = 300; + Display *x_dpy; + Window win; + EGLSurface egl_surf; + EGLContext egl_ctx; + EGLDisplay egl_dpy; + char *dpyName = NULL; + GLboolean printInfo = GL_FALSE; + EGLint egl_major, egl_minor; + int i; + const char *s; + + for (i = 1; i < argc; i++) { + if (strcmp(argv[i], "-display") == 0) { + dpyName = argv[i+1]; + i++; + } + else if (strcmp(argv[i], "-info") == 0) { + printInfo = GL_TRUE; + } + else { + usage(); + return -1; + } + } + + x_dpy = XOpenDisplay(dpyName); + if (!x_dpy) { + printf("Error: couldn't open display %s\n", + dpyName ? dpyName : getenv("DISPLAY")); + return -1; + } + + egl_dpy = eglGetDisplay(x_dpy); + if (!egl_dpy) { + printf("Error: eglGetDisplay() failed\n"); + return -1; + } + + if (!eglInitialize(egl_dpy, &egl_major, &egl_minor)) { + printf("Error: eglInitialize() failed\n"); + return -1; + } + + s = eglQueryString(egl_dpy, EGL_VERSION); + printf("EGL_VERSION = %s\n", s); + + s = eglQueryString(egl_dpy, EGL_VENDOR); + printf("EGL_VENDOR = %s\n", s); + + s = eglQueryString(egl_dpy, EGL_EXTENSIONS); + printf("EGL_EXTENSIONS = %s\n", s); + + s = eglQueryString(egl_dpy, EGL_CLIENT_APIS); + printf("EGL_CLIENT_APIS = %s\n", s); + + make_x_window(x_dpy, egl_dpy, + "drawtex", 0, 0, winWidth, winHeight, + &win, &egl_ctx, &egl_surf); + + XMapWindow(x_dpy, win); + if (!eglMakeCurrent(egl_dpy, egl_surf, egl_surf, egl_ctx)) { + printf("Error: eglMakeCurrent() failed\n"); + return -1; + } + + if (printInfo) { + printf("GL_RENDERER = %s\n", (char *) glGetString(GL_RENDERER)); + printf("GL_VERSION = %s\n", (char *) glGetString(GL_VERSION)); + printf("GL_VENDOR = %s\n", (char *) glGetString(GL_VENDOR)); + printf("GL_EXTENSIONS = %s\n", (char *) glGetString(GL_EXTENSIONS)); + } + + init(); + + /* Set initial projection/viewing transformation. + * We can't be sure we'll get a ConfigureNotify event when the window + * first appears. + */ + reshape(winWidth, winHeight); + + event_loop(x_dpy, win, egl_dpy, egl_surf); + + eglDestroyContext(egl_dpy, egl_ctx); + eglDestroySurface(egl_dpy, egl_surf); + eglTerminate(egl_dpy); + + + XDestroyWindow(x_dpy, win); + XCloseDisplay(x_dpy); + + return 0; +} diff --git a/progs/es1/xegl/es1_info.c b/progs/es1/xegl/es1_info.c new file mode 100644 index 00000000000..93816b52150 --- /dev/null +++ b/progs/es1/xegl/es1_info.c @@ -0,0 +1,289 @@ +/* + * Copyright (C) 2008 Tunsgten Graphics,Inc. All Rights Reserved. + */ + +/* + * List OpenGL ES extensions. + * Print ES 1 or ES 2 extensions depending on which library we're + * linked with: libGLESv1_CM.so vs libGLESv2.so + */ + +#define GL_GLEXT_PROTOTYPES + +#include <assert.h> +#include <math.h> +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <X11/Xlib.h> +#include <X11/Xutil.h> +#include <X11/keysym.h> +#include <GLES/gl.h> +#include <GLES/glext.h> +#include <EGL/egl.h> + + +/* + * Print a list of extensions, with word-wrapping. + */ +static void +print_extension_list(const char *ext) +{ + const char *indentString = " "; + const int indent = 4; + const int max = 79; + int width, i, j; + + if (!ext || !ext[0]) + return; + + width = indent; + printf(indentString); + i = j = 0; + while (1) { + if (ext[j] == ' ' || ext[j] == 0) { + /* found end of an extension name */ + const int len = j - i; + if (width + len > max) { + /* start a new line */ + printf("\n"); + width = indent; + printf(indentString); + } + /* print the extension name between ext[i] and ext[j] */ + while (i < j) { + printf("%c", ext[i]); + i++; + } + /* either we're all done, or we'll continue with next extension */ + width += len + 1; + if (ext[j] == 0) { + break; + } + else { + i++; + j++; + if (ext[j] == 0) + break; + printf(", "); + width += 2; + } + } + j++; + } + printf("\n"); +} + + +static void +info(EGLDisplay egl_dpy) +{ + const char *s; + + s = eglQueryString(egl_dpy, EGL_VERSION); + printf("EGL_VERSION = %s\n", s); + + s = eglQueryString(egl_dpy, EGL_VENDOR); + printf("EGL_VENDOR = %s\n", s); + + s = eglQueryString(egl_dpy, EGL_EXTENSIONS); + printf("EGL_EXTENSIONS = %s\n", s); + + s = eglQueryString(egl_dpy, EGL_CLIENT_APIS); + printf("EGL_CLIENT_APIS = %s\n", s); + + printf("GL_VERSION: %s\n", (char *) glGetString(GL_VERSION)); + printf("GL_RENDERER: %s\n", (char *) glGetString(GL_RENDERER)); + printf("GL_EXTENSIONS:\n"); + print_extension_list((char *) glGetString(GL_EXTENSIONS)); +} + + +/* + * Create an RGB, double-buffered X window. + * Return the window and context handles. + */ +static void +make_x_window(Display *x_dpy, EGLDisplay egl_dpy, + const char *name, + int x, int y, int width, int height, int es_ver, + Window *winRet, + EGLContext *ctxRet, + EGLSurface *surfRet) +{ + EGLint attribs[] = { + EGL_RENDERABLE_TYPE, 0x0, + EGL_RED_SIZE, 1, + EGL_GREEN_SIZE, 1, + EGL_BLUE_SIZE, 1, + EGL_NONE + }; + EGLint ctx_attribs[] = { + EGL_CONTEXT_CLIENT_VERSION, 0, + EGL_NONE + }; + + int scrnum; + XSetWindowAttributes attr; + unsigned long mask; + Window root; + Window win; + XVisualInfo *visInfo, visTemplate; + int num_visuals; + EGLContext ctx; + EGLConfig config; + EGLint num_configs; + EGLint vid; + + scrnum = DefaultScreen( x_dpy ); + root = RootWindow( x_dpy, scrnum ); + + if (es_ver == 1) + attribs[1] = EGL_OPENGL_ES_BIT; + else + attribs[1] = EGL_OPENGL_ES2_BIT; + ctx_attribs[1] = es_ver; + + if (!eglChooseConfig( egl_dpy, attribs, &config, 1, &num_configs)) { + printf("Error: couldn't get an EGL visual config\n"); + exit(1); + } + + assert(config); + assert(num_configs > 0); + + if (!eglGetConfigAttrib(egl_dpy, config, EGL_NATIVE_VISUAL_ID, &vid)) { + printf("Error: eglGetConfigAttrib() failed\n"); + exit(1); + } + + /* The X window visual must match the EGL config */ + visTemplate.visualid = vid; + visInfo = XGetVisualInfo(x_dpy, VisualIDMask, &visTemplate, &num_visuals); + if (!visInfo) { + printf("Error: couldn't get X visual\n"); + exit(1); + } + + /* window attributes */ + attr.background_pixel = 0; + attr.border_pixel = 0; + attr.colormap = XCreateColormap( x_dpy, root, visInfo->visual, AllocNone); + attr.event_mask = StructureNotifyMask | ExposureMask | KeyPressMask; + mask = CWBackPixel | CWBorderPixel | CWColormap | CWEventMask; + + win = XCreateWindow( x_dpy, root, 0, 0, width, height, + 0, visInfo->depth, InputOutput, + visInfo->visual, mask, &attr ); + + /* set hints and properties */ + { + XSizeHints sizehints; + sizehints.x = x; + sizehints.y = y; + sizehints.width = width; + sizehints.height = height; + sizehints.flags = USSize | USPosition; + XSetNormalHints(x_dpy, win, &sizehints); + XSetStandardProperties(x_dpy, win, name, name, + None, (char **)NULL, 0, &sizehints); + } + + eglBindAPI(EGL_OPENGL_ES_API); + + ctx = eglCreateContext(egl_dpy, config, EGL_NO_CONTEXT, ctx_attribs ); + if (!ctx) { + printf("Error: eglCreateContext failed\n"); + exit(1); + } + + *surfRet = eglCreateWindowSurface(egl_dpy, config, win, NULL); + + if (!*surfRet) { + printf("Error: eglCreateWindowSurface failed\n"); + exit(1); + } + + XFree(visInfo); + + *winRet = win; + *ctxRet = ctx; +} + + +static void +usage(void) +{ + printf("Usage:\n"); + printf(" -display <displayname> set the display to run on\n"); +} + + +int +main(int argc, char *argv[]) +{ + const int winWidth = 400, winHeight = 300; + Display *x_dpy; + Window win; + EGLSurface egl_surf; + EGLContext egl_ctx; + EGLDisplay egl_dpy; + char *dpyName = NULL; + EGLint egl_major, egl_minor, es_ver; + int i; + + for (i = 1; i < argc; i++) { + if (strcmp(argv[i], "-display") == 0) { + dpyName = argv[i+1]; + i++; + } + else { + usage(); + return -1; + } + } + + x_dpy = XOpenDisplay(dpyName); + if (!x_dpy) { + printf("Error: couldn't open display %s\n", + dpyName ? dpyName : getenv("DISPLAY")); + return -1; + } + + egl_dpy = eglGetDisplay(x_dpy); + if (!egl_dpy) { + printf("Error: eglGetDisplay() failed\n"); + return -1; + } + + if (!eglInitialize(egl_dpy, &egl_major, &egl_minor)) { + printf("Error: eglInitialize() failed\n"); + return -1; + } + + es_ver = 1; + /* decide the version from the executable's name */ + if (argc > 0 && argv[0] && strstr(argv[0], "es2")) + es_ver = 2; + make_x_window(x_dpy, egl_dpy, + "ES info", 0, 0, winWidth, winHeight, es_ver, + &win, &egl_ctx, &egl_surf); + + /*XMapWindow(x_dpy, win);*/ + if (!eglMakeCurrent(egl_dpy, egl_surf, egl_surf, egl_ctx)) { + printf("Error: eglMakeCurrent() failed\n"); + return -1; + } + + info(egl_dpy); + + eglDestroyContext(egl_dpy, egl_ctx); + eglDestroySurface(egl_dpy, egl_surf); + eglTerminate(egl_dpy); + + + XDestroyWindow(x_dpy, win); + XCloseDisplay(x_dpy); + + return 0; +} diff --git a/progs/es1/xegl/msaa.c b/progs/es1/xegl/msaa.c new file mode 100644 index 00000000000..b4c6c632177 --- /dev/null +++ b/progs/es1/xegl/msaa.c @@ -0,0 +1,442 @@ +/* + * Copyright (C) 2008 Brian Paul All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +/* + * Test MSAA with X/EGL and OpenGL ES 1.x + * Brian Paul + * 15 September 2008 + */ + +#define USE_FULL_GL 0 + + +#include <assert.h> +#include <math.h> +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <X11/Xlib.h> +#include <X11/Xutil.h> +#include <X11/keysym.h> +#if USE_FULL_GL +#include <GL/gl.h> /* use full OpenGL */ +#else +#include <GLES/gl.h> /* use OpenGL ES 1.x */ +#include <GLES/glext.h> +#endif +#include <EGL/egl.h> + + + +static GLfloat view_rotx = 0.0, view_roty = 0.0, view_rotz = 0.0; +static GLboolean AA = 0*GL_TRUE; + + +static void +draw(void) +{ + float a; + + static const GLfloat verts[4][2] = { + { -1, -.1 }, + { 1, -.1 }, + { -1, .1 }, + { 1, .1 } + }; + static const GLfloat colors[4][4] = { + { 1, 0, 0, 1 }, + { 0, 1, 0, 1 }, + { 0, 0, 1, 1 }, + { 1, 0, 1, 1 } + }; + + if (AA) { + printf("MSAA enabled\n"); + glEnable(GL_MULTISAMPLE); + } + else { + printf("MSAA disabled\n"); + glDisable(GL_MULTISAMPLE); + } + + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + glPushMatrix(); + glRotatef(view_rotx, 1, 0, 0); + glRotatef(view_roty, 0, 1, 0); + glRotatef(view_rotz, 0, 0, 1); + + { + glVertexPointer(2, GL_FLOAT, 0, verts); + glColorPointer(4, GL_FLOAT, 0, colors); + + glEnableClientState(GL_VERTEX_ARRAY); + glEnableClientState(GL_COLOR_ARRAY); + + for (a = 0; a < 360; a += 20.0) { + glPushMatrix(); + + glRotatef(a, 0, 0, 1); + glTranslatef(1.5, 0, 0); + + /* draw triangle */ + glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); + + glPopMatrix(); + } + + glDisableClientState(GL_VERTEX_ARRAY); + glDisableClientState(GL_COLOR_ARRAY); + } + + glPopMatrix(); +} + + +/* new window size or exposure */ +static void +reshape(int width, int height) +{ + GLfloat ary = 3.0; + GLfloat arx = ary * (GLfloat) width / (GLfloat) height; + + glViewport(0, 0, (GLint) width, (GLint) height); + + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); +#ifdef GL_VERSION_ES_CM_1_0 + glOrthof(-arx, arx, -ary, ary, -1.0, 1.0); +#else + glOrtho(-arx, arx, -ary, ary, -1.0, 1.0); +#endif + + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); +} + + + +static void +init(void) +{ + printf("Press 'a' to toggle multisample antialiasing\n"); + printf("Press 'Esc' to exit\n"); +} + + +/* + * Create an RGB, double-buffered X window. + * Return the window and context handles. + */ +static void +make_x_window(Display *x_dpy, EGLDisplay egl_dpy, + const char *name, + int x, int y, int width, int height, + Window *winRet, + EGLContext *ctxRet, + EGLSurface *surfRet) +{ + static const EGLint attribs[] = { + EGL_RED_SIZE, 1, + EGL_GREEN_SIZE, 1, + EGL_BLUE_SIZE, 1, + EGL_DEPTH_SIZE, 1, + EGL_SAMPLES, 1, + EGL_SAMPLE_BUFFERS, 1, + EGL_NONE + }; + + int scrnum; + XSetWindowAttributes attr; + unsigned long mask; + Window root; + Window win; + XVisualInfo *visInfo, visTemplate; + int num_visuals; + EGLContext ctx; + EGLConfig config; + EGLint num_configs; + EGLint vid; + + scrnum = DefaultScreen( x_dpy ); + root = RootWindow( x_dpy, scrnum ); + + if (!eglChooseConfig( egl_dpy, attribs, &config, 1, &num_configs)) { + printf("Error: couldn't get an EGL visual config\n"); + exit(1); + } + + if (num_configs < 1) { + printf("Error: Unable to find multisample pixel format.\n"); + printf("Try running glxinfo to see if your server supports MSAA.\n"); + exit(1); + } + + if (!eglGetConfigAttrib(egl_dpy, config, EGL_NATIVE_VISUAL_ID, &vid)) { + printf("Error: eglGetConfigAttrib() failed\n"); + exit(1); + } + + /* The X window visual must match the EGL config */ + visTemplate.visualid = vid; + visInfo = XGetVisualInfo(x_dpy, VisualIDMask, &visTemplate, &num_visuals); + if (!visInfo) { + printf("Error: couldn't get X visual\n"); + exit(1); + } + + /* window attributes */ + attr.background_pixel = 0; + attr.border_pixel = 0; + attr.colormap = XCreateColormap( x_dpy, root, visInfo->visual, AllocNone); + attr.event_mask = StructureNotifyMask | ExposureMask | KeyPressMask; + mask = CWBackPixel | CWBorderPixel | CWColormap | CWEventMask; + + win = XCreateWindow( x_dpy, root, 0, 0, width, height, + 0, visInfo->depth, InputOutput, + visInfo->visual, mask, &attr ); + + /* set hints and properties */ + { + XSizeHints sizehints; + sizehints.x = x; + sizehints.y = y; + sizehints.width = width; + sizehints.height = height; + sizehints.flags = USSize | USPosition; + XSetNormalHints(x_dpy, win, &sizehints); + XSetStandardProperties(x_dpy, win, name, name, + None, (char **)NULL, 0, &sizehints); + } + +#if USE_FULL_GL + eglBindAPI(EGL_OPENGL_API); +#else + eglBindAPI(EGL_OPENGL_ES_API); +#endif + + ctx = eglCreateContext(egl_dpy, config, EGL_NO_CONTEXT, NULL ); + if (!ctx) { + printf("Error: eglCreateContext failed\n"); + exit(1); + } + + *surfRet = eglCreateWindowSurface(egl_dpy, config, win, NULL); + + if (!*surfRet) { + printf("Error: eglCreateWindowSurface failed\n"); + exit(1); + } + + XFree(visInfo); + + *winRet = win; + *ctxRet = ctx; +} + + +static void +event_loop(Display *dpy, Window win, + EGLDisplay egl_dpy, EGLSurface egl_surf) +{ + while (1) { + int redraw = 0; + XEvent event; + + XNextEvent(dpy, &event); + + switch (event.type) { + case Expose: + redraw = 1; + break; + case ConfigureNotify: + reshape(event.xconfigure.width, event.xconfigure.height); + break; + case KeyPress: + { + char buffer[10]; + int r, code; + code = XLookupKeysym(&event.xkey, 0); + if (code == XK_Left) { + view_roty += 5.0; + } + else if (code == XK_Right) { + view_roty -= 5.0; + } + else if (code == XK_Up) { + view_rotx += 5.0; + } + else if (code == XK_Down) { + view_rotx -= 5.0; + } + else { + r = XLookupString(&event.xkey, buffer, sizeof(buffer), + NULL, NULL); + if (buffer[0] == 'a') { + AA = !AA; + redraw = 1; + } + else if (buffer[0] == 27) { + /* escape */ + return; + } + } + } + redraw = 1; + break; + default: + ; /*no-op*/ + } + + if (redraw) { + draw(); + eglSwapBuffers(egl_dpy, egl_surf); + } + } +} + + +static void +usage(void) +{ + printf("Usage:\n"); + printf(" -display <displayname> set the display to run on\n"); + printf(" -info display OpenGL renderer info\n"); +} + + +int +main(int argc, char *argv[]) +{ + const int winWidth = 600, winHeight = 600; + Display *x_dpy; + Window win; + EGLSurface egl_surf; + EGLContext egl_ctx; + EGLDisplay egl_dpy; + char *dpyName = NULL; + GLboolean printInfo = GL_FALSE; + EGLint egl_major, egl_minor; + int i; + const char *s; + + static struct { + char *name; + GLenum value; + enum {GetString, GetInteger} type; + } info_items[] = { + {"GL_RENDERER", GL_RENDERER, GetString}, + {"GL_VERSION", GL_VERSION, GetString}, + {"GL_VENDOR", GL_VENDOR, GetString}, + {"GL_EXTENSIONS", GL_EXTENSIONS, GetString}, + {"GL_MAX_PALETTE_MATRICES_OES", GL_MAX_PALETTE_MATRICES_OES, GetInteger}, + {"GL_MAX_VERTEX_UNITS_OES", GL_MAX_VERTEX_UNITS_OES, GetInteger}, + }; + + for (i = 1; i < argc; i++) { + if (strcmp(argv[i], "-display") == 0) { + dpyName = argv[i+1]; + i++; + } + else if (strcmp(argv[i], "-info") == 0) { + printInfo = GL_TRUE; + } + else { + usage(); + return -1; + } + } + + x_dpy = XOpenDisplay(dpyName); + if (!x_dpy) { + printf("Error: couldn't open display %s\n", + dpyName ? dpyName : getenv("DISPLAY")); + return -1; + } + + egl_dpy = eglGetDisplay(x_dpy); + if (!egl_dpy) { + printf("Error: eglGetDisplay() failed\n"); + return -1; + } + + if (!eglInitialize(egl_dpy, &egl_major, &egl_minor)) { + printf("Error: eglInitialize() failed\n"); + return -1; + } + + s = eglQueryString(egl_dpy, EGL_VERSION); + printf("EGL_VERSION = %s\n", s); + + s = eglQueryString(egl_dpy, EGL_VENDOR); + printf("EGL_VENDOR = %s\n", s); + + s = eglQueryString(egl_dpy, EGL_EXTENSIONS); + printf("EGL_EXTENSIONS = %s\n", s); + + s = eglQueryString(egl_dpy, EGL_CLIENT_APIS); + printf("EGL_CLIENT_APIS = %s\n", s); + + make_x_window(x_dpy, egl_dpy, + "msaa", 0, 0, winWidth, winHeight, + &win, &egl_ctx, &egl_surf); + + XMapWindow(x_dpy, win); + if (!eglMakeCurrent(egl_dpy, egl_surf, egl_surf, egl_ctx)) { + printf("Error: eglMakeCurrent() failed\n"); + return -1; + } + + if (printInfo) { + for (i = 0; i < sizeof(info_items)/sizeof(info_items[0]); i++) { + switch (info_items[i].type) { + case GetString: + printf("%s = %s\n", info_items[i].name, (char *)glGetString(info_items[i].value)); + break; + case GetInteger: { + GLint rv = -1; + glGetIntegerv(info_items[i].value, &rv); + printf("%s = %d\n", info_items[i].name, rv); + break; + } + } + } + }; + init(); + + /* Set initial projection/viewing transformation. + * We can't be sure we'll get a ConfigureNotify event when the window + * first appears. + */ + reshape(winWidth, winHeight); + + event_loop(x_dpy, win, egl_dpy, egl_surf); + + eglDestroyContext(egl_dpy, egl_ctx); + eglDestroySurface(egl_dpy, egl_surf); + eglTerminate(egl_dpy); + + + XDestroyWindow(x_dpy, win); + XCloseDisplay(x_dpy); + + return 0; +} diff --git a/progs/es1/xegl/pbuffer.c b/progs/es1/xegl/pbuffer.c new file mode 100644 index 00000000000..011c2af58fe --- /dev/null +++ b/progs/es1/xegl/pbuffer.c @@ -0,0 +1,607 @@ +/* + * Copyright (C) 2008 Tunsgten Graphics,Inc. All Rights Reserved. + */ + +/* + * Test EGL Pbuffers + * Brian Paul + * August 2008 + */ + + +#include <assert.h> +#include <math.h> +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <X11/Xlib.h> +#include <X11/Xutil.h> +#include <X11/keysym.h> +#include <GLES/gl.h> +#include <GLES/glext.h> +#include <EGL/egl.h> + + + +static int WinWidth = 300, WinHeight = 300; + +static GLfloat view_rotx = 0.0, view_roty = 0.0, view_rotz = 0.0; + + +static void +Normal(GLfloat *n, GLfloat nx, GLfloat ny, GLfloat nz) +{ + n[0] = nx; + n[1] = ny; + n[2] = nz; +} + +static void +Vertex(GLfloat *v, GLfloat vx, GLfloat vy, GLfloat vz) +{ + v[0] = vx; + v[1] = vy; + v[2] = vz; +} + +static void +Texcoord(GLfloat *v, GLfloat s, GLfloat t) +{ + v[0] = s; + v[1] = t; +} + + +/* Borrowed from glut, adapted */ +static void +draw_torus(GLfloat r, GLfloat R, GLint nsides, GLint rings) +{ + int i, j; + GLfloat theta, phi, theta1; + GLfloat cosTheta, sinTheta; + GLfloat cosTheta1, sinTheta1; + GLfloat ringDelta, sideDelta; + GLfloat varray[100][3], narray[100][3], tarray[100][2]; + int vcount; + + glVertexPointer(3, GL_FLOAT, 0, varray); + glNormalPointer(GL_FLOAT, 0, narray); + glTexCoordPointer(2, GL_FLOAT, 0, tarray); + glEnableClientState(GL_VERTEX_ARRAY); + glEnableClientState(GL_NORMAL_ARRAY); + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + + ringDelta = 2.0 * M_PI / rings; + sideDelta = 2.0 * M_PI / nsides; + + theta = 0.0; + cosTheta = 1.0; + sinTheta = 0.0; + for (i = rings - 1; i >= 0; i--) { + theta1 = theta + ringDelta; + cosTheta1 = cos(theta1); + sinTheta1 = sin(theta1); + + vcount = 0; /* glBegin(GL_QUAD_STRIP); */ + + phi = 0.0; + for (j = nsides; j >= 0; j--) { + GLfloat s0, s1, t; + GLfloat cosPhi, sinPhi, dist; + + phi += sideDelta; + cosPhi = cos(phi); + sinPhi = sin(phi); + dist = R + r * cosPhi; + + s0 = 20.0 * theta / (2.0 * M_PI); + s1 = 20.0 * theta1 / (2.0 * M_PI); + t = 8.0 * phi / (2.0 * M_PI); + + Normal(narray[vcount], cosTheta1 * cosPhi, -sinTheta1 * cosPhi, sinPhi); + Texcoord(tarray[vcount], s1, t); + Vertex(varray[vcount], cosTheta1 * dist, -sinTheta1 * dist, r * sinPhi); + vcount++; + + Normal(narray[vcount], cosTheta * cosPhi, -sinTheta * cosPhi, sinPhi); + Texcoord(tarray[vcount], s0, t); + Vertex(varray[vcount], cosTheta * dist, -sinTheta * dist, r * sinPhi); + vcount++; + } + + /*glEnd();*/ + assert(vcount <= 100); + glDrawArrays(GL_TRIANGLE_STRIP, 0, vcount); + + theta = theta1; + cosTheta = cosTheta1; + sinTheta = sinTheta1; + } + + glDisableClientState(GL_VERTEX_ARRAY); + glDisableClientState(GL_NORMAL_ARRAY); + glDisableClientState(GL_TEXTURE_COORD_ARRAY); +} + + +static void +draw(void) +{ + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + glPushMatrix(); + glRotatef(view_rotx, 1, 0, 0); + glRotatef(view_roty, 0, 1, 0); + glRotatef(view_rotz, 0, 0, 1); + glScalef(0.5, 0.5, 0.5); + + draw_torus(1.0, 3.0, 30, 60); + + glPopMatrix(); + + glFinish(); +} + + +/** + * Draw to both the window and pbuffer and compare results. + */ +static void +draw_both(EGLDisplay egl_dpy, EGLSurface egl_surf, EGLSurface egl_pbuf, + EGLContext egl_ctx) +{ + unsigned *wbuf, *pbuf; + int x = 100, y = 110; + int i, dif; + + wbuf = (unsigned *) malloc(WinWidth * WinHeight * 4); + pbuf = (unsigned *) malloc(WinWidth * WinHeight * 4); + + glPixelStorei(GL_PACK_ALIGNMENT, 1); + + /* first draw to window */ + if (!eglMakeCurrent(egl_dpy, egl_surf, egl_surf, egl_ctx)) { + printf("Error: eglMakeCurrent(window) failed\n"); + return; + } + draw(); + glReadPixels(0, 0, WinWidth, WinHeight, GL_RGBA, GL_UNSIGNED_BYTE, wbuf); + printf("Window[%d,%d] = 0x%08x\n", x, y, wbuf[y*WinWidth+x]); + + /* then draw to pbuffer */ + if (!eglMakeCurrent(egl_dpy, egl_pbuf, egl_pbuf, egl_ctx)) { + printf("Error: eglMakeCurrent(pbuffer) failed\n"); + return; + } + draw(); + glReadPixels(0, 0, WinWidth, WinHeight, GL_RGBA, GL_UNSIGNED_BYTE, pbuf); + printf("Pbuffer[%d,%d] = 0x%08x\n", x, y, pbuf[y*WinWidth+x]); + + eglSwapBuffers(egl_dpy, egl_surf); + + /* compare renderings */ + for (dif = i = 0; i < WinWidth * WinHeight; i++) { + if (wbuf[i] != pbuf[i]) { + dif = 1; + break; + } + } + + if (dif) + printf("Difference at %d: 0x%08x vs. 0x%08x\n", i, wbuf[i], pbuf[i]); + else + printf("Window rendering matches Pbuffer rendering!\n"); + + free(wbuf); + free(pbuf); +} + + +/* new window size or exposure */ +static void +reshape(int width, int height) +{ + GLfloat ar = (GLfloat) width / (GLfloat) height; + + WinWidth = width; + WinHeight = height; + + glViewport(0, 0, (GLint) width, (GLint) height); + + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + +#ifdef GL_VERSION_ES_CM_1_0 + glFrustumf(-ar, ar, -1, 1, 5.0, 60.0); +#else + glFrustum(-ar, ar, -1, 1, 5.0, 60.0); +#endif + + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + glTranslatef(0.0, 0.0, -15.0); +} + + +static void +make_texture(void) +{ +#define SZ 64 + GLenum Filter = GL_LINEAR; + GLubyte image[SZ][SZ][4]; + GLuint i, j; + + for (i = 0; i < SZ; i++) { + for (j = 0; j < SZ; j++) { + GLfloat d = (i - SZ/2) * (i - SZ/2) + (j - SZ/2) * (j - SZ/2); + d = sqrt(d); + if (d < SZ/3) { + image[i][j][0] = 255; + image[i][j][1] = 255; + image[i][j][2] = 255; + image[i][j][3] = 255; + } + else { + image[i][j][0] = 127; + image[i][j][1] = 127; + image[i][j][2] = 127; + image[i][j][3] = 255; + } + } + } + + glActiveTexture(GL_TEXTURE0); /* unit 0 */ + glBindTexture(GL_TEXTURE_2D, 42); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, SZ, SZ, 0, + GL_RGBA, GL_UNSIGNED_BYTE, image); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, Filter); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, Filter); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); +#undef SZ +} + + + +static void +init(void) +{ + static const GLfloat red[4] = {1, 0, 0, 0}; + static const GLfloat white[4] = {1.0, 1.0, 1.0, 1.0}; + static const GLfloat diffuse[4] = {0.7, 0.7, 0.7, 1.0}; + static const GLfloat specular[4] = {0.001, 0.001, 0.001, 1.0}; + static const GLfloat pos[4] = {20, 20, 50, 1}; + + glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, red); + glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, white); + glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 9.0); + + glEnable(GL_LIGHTING); + glEnable(GL_LIGHT0); + glLightfv(GL_LIGHT0, GL_POSITION, pos); + glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuse); + glLightfv(GL_LIGHT0, GL_SPECULAR, specular); + + glClearColor(0.4, 0.4, 0.4, 0.0); + glEnable(GL_DEPTH_TEST); + + make_texture(); + glEnable(GL_TEXTURE_2D); +} + + +/* + * Create an RGB, double-buffered X window. + * Return the window and context handles. + */ +static void +make_x_window(Display *x_dpy, EGLDisplay egl_dpy, + const char *name, + int x, int y, int width, int height, + Window *winRet, + EGLContext *ctxRet, + EGLSurface *surfRet) +{ + static const EGLint attribs[] = { + EGL_RED_SIZE, 1, + EGL_GREEN_SIZE, 1, + EGL_BLUE_SIZE, 1, + EGL_DEPTH_SIZE, 1, + EGL_NONE + }; + + int scrnum; + XSetWindowAttributes attr; + unsigned long mask; + Window root; + Window win; + XVisualInfo *visInfo, visTemplate; + int num_visuals; + EGLContext ctx; + EGLConfig config; + EGLint num_configs; + EGLint vid; + + scrnum = DefaultScreen( x_dpy ); + root = RootWindow( x_dpy, scrnum ); + + if (!eglChooseConfig( egl_dpy, attribs, &config, 1, &num_configs)) { + printf("Error: couldn't get an EGL visual config\n"); + exit(1); + } + + assert(config); + assert(num_configs > 0); + + if (!eglGetConfigAttrib(egl_dpy, config, EGL_NATIVE_VISUAL_ID, &vid)) { + printf("Error: eglGetConfigAttrib() failed\n"); + exit(1); + } + + /* The X window visual must match the EGL config */ + visTemplate.visualid = vid; + visInfo = XGetVisualInfo(x_dpy, VisualIDMask, &visTemplate, &num_visuals); + if (!visInfo) { + printf("Error: couldn't get X visual\n"); + exit(1); + } + + /* window attributes */ + attr.background_pixel = 0; + attr.border_pixel = 0; + attr.colormap = XCreateColormap( x_dpy, root, visInfo->visual, AllocNone); + attr.event_mask = StructureNotifyMask | ExposureMask | KeyPressMask; + mask = CWBackPixel | CWBorderPixel | CWColormap | CWEventMask; + + win = XCreateWindow( x_dpy, root, 0, 0, width, height, + 0, visInfo->depth, InputOutput, + visInfo->visual, mask, &attr ); + + /* set hints and properties */ + { + XSizeHints sizehints; + sizehints.x = x; + sizehints.y = y; + sizehints.width = width; + sizehints.height = height; + sizehints.flags = USSize | USPosition; + XSetNormalHints(x_dpy, win, &sizehints); + XSetStandardProperties(x_dpy, win, name, name, + None, (char **)NULL, 0, &sizehints); + } + + eglBindAPI(EGL_OPENGL_ES_API); + + ctx = eglCreateContext(egl_dpy, config, EGL_NO_CONTEXT, NULL ); + if (!ctx) { + printf("Error: eglCreateContext failed\n"); + exit(1); + } + + *surfRet = eglCreateWindowSurface(egl_dpy, config, win, NULL); + + if (!*surfRet) { + printf("Error: eglCreateWindowSurface failed\n"); + exit(1); + } + + XFree(visInfo); + + *winRet = win; + *ctxRet = ctx; +} + + +static EGLSurface +make_pbuffer(Display *x_dpy, EGLDisplay egl_dpy, int width, int height) +{ + static const EGLint config_attribs[] = { + EGL_RED_SIZE, 1, + EGL_GREEN_SIZE, 1, + EGL_BLUE_SIZE, 1, + EGL_DEPTH_SIZE, 1, + EGL_NONE + }; + EGLConfig config; + EGLSurface pbuf; + EGLint num_configs; + EGLint pbuf_attribs[5]; + + pbuf_attribs[0] = EGL_WIDTH; + pbuf_attribs[1] = width; + pbuf_attribs[2] = EGL_HEIGHT; + pbuf_attribs[3] = height; + pbuf_attribs[4] = EGL_NONE; + + if (!eglChooseConfig( egl_dpy, config_attribs, &config, 1, &num_configs)) { + printf("Error: couldn't get an EGL config for pbuffer\n"); + exit(1); + } + + pbuf = eglCreatePbufferSurface(egl_dpy, config, pbuf_attribs); + + return pbuf; +} + + +static void +event_loop(Display *dpy, Window win, + EGLDisplay egl_dpy, EGLSurface egl_surf, EGLSurface egl_pbuf, + EGLContext egl_ctx) +{ + int anim = 0; + + while (1) { + int redraw = 0; + + if (!anim || XPending(dpy)) { + XEvent event; + XNextEvent(dpy, &event); + + switch (event.type) { + case Expose: + redraw = 1; + break; + case ConfigureNotify: + if (event.xconfigure.window == win) + reshape(event.xconfigure.width, event.xconfigure.height); + break; + case KeyPress: + { + char buffer[10]; + int r, code; + code = XLookupKeysym(&event.xkey, 0); + if (code == XK_Left) { + view_roty += 5.0; + } + else if (code == XK_Right) { + view_roty -= 5.0; + } + else if (code == XK_Up) { + view_rotx += 5.0; + } + else if (code == XK_Down) { + view_rotx -= 5.0; + } + else { + r = XLookupString(&event.xkey, buffer, sizeof(buffer), + NULL, NULL); + if (buffer[0] == ' ') { + anim = !anim; + } + else if (buffer[0] == 27) { + /* escape */ + return; + } + } + } + redraw = 1; + break; + default: + ; /*no-op*/ + } + } + + if (anim) { + view_rotx += 1.0; + view_roty += 2.0; + redraw = 1; + } + + if (redraw) { + draw_both(egl_dpy, egl_surf, egl_pbuf, egl_ctx); + } + } +} + + +static void +usage(void) +{ + printf("Usage:\n"); + printf(" -display <displayname> set the display to run on\n"); + printf(" -info display OpenGL renderer info\n"); +} + + +int +main(int argc, char *argv[]) +{ + Display *x_dpy; + Window win; + EGLSurface egl_surf, egl_pbuf; + EGLContext egl_ctx; + EGLDisplay egl_dpy; + char *dpyName = NULL; + GLboolean printInfo = GL_FALSE; + EGLint egl_major, egl_minor; + int i; + const char *s; + + for (i = 1; i < argc; i++) { + if (strcmp(argv[i], "-display") == 0) { + dpyName = argv[i+1]; + i++; + } + else if (strcmp(argv[i], "-info") == 0) { + printInfo = GL_TRUE; + } + else { + usage(); + return -1; + } + } + + x_dpy = XOpenDisplay(dpyName); + if (!x_dpy) { + printf("Error: couldn't open display %s\n", + dpyName ? dpyName : getenv("DISPLAY")); + return -1; + } + + egl_dpy = eglGetDisplay(x_dpy); + if (!egl_dpy) { + printf("Error: eglGetDisplay() failed\n"); + return -1; + } + + if (!eglInitialize(egl_dpy, &egl_major, &egl_minor)) { + printf("Error: eglInitialize() failed\n"); + return -1; + } + + s = eglQueryString(egl_dpy, EGL_VERSION); + printf("EGL_VERSION = %s\n", s); + + s = eglQueryString(egl_dpy, EGL_VENDOR); + printf("EGL_VENDOR = %s\n", s); + + s = eglQueryString(egl_dpy, EGL_EXTENSIONS); + printf("EGL_EXTENSIONS = %s\n", s); + + s = eglQueryString(egl_dpy, EGL_CLIENT_APIS); + printf("EGL_CLIENT_APIS = %s\n", s); + + make_x_window(x_dpy, egl_dpy, + "pbuffer", 0, 0, WinWidth, WinHeight, + &win, &egl_ctx, &egl_surf); + + egl_pbuf = make_pbuffer(x_dpy, egl_dpy, WinWidth, WinHeight); + if (!egl_pbuf) { + printf("Error: eglCreatePBufferSurface() failed\n"); + return -1; + } + + XMapWindow(x_dpy, win); + if (!eglMakeCurrent(egl_dpy, egl_surf, egl_surf, egl_ctx)) { + printf("Error: eglMakeCurrent() failed\n"); + return -1; + } + + if (printInfo) { + printf("GL_RENDERER = %s\n", (char *) glGetString(GL_RENDERER)); + printf("GL_VERSION = %s\n", (char *) glGetString(GL_VERSION)); + printf("GL_VENDOR = %s\n", (char *) glGetString(GL_VENDOR)); + printf("GL_EXTENSIONS = %s\n", (char *) glGetString(GL_EXTENSIONS)); + } + + init(); + + /* Set initial projection/viewing transformation. + * We can't be sure we'll get a ConfigureNotify event when the window + * first appears. + */ + reshape(WinWidth, WinHeight); + + event_loop(x_dpy, win, egl_dpy, egl_surf, egl_pbuf, egl_ctx); + + eglDestroyContext(egl_dpy, egl_ctx); + eglDestroySurface(egl_dpy, egl_surf); + eglTerminate(egl_dpy); + + + XDestroyWindow(x_dpy, win); + XCloseDisplay(x_dpy); + + return 0; +} diff --git a/progs/es1/xegl/render_tex.c b/progs/es1/xegl/render_tex.c new file mode 100644 index 00000000000..0200fa4cb06 --- /dev/null +++ b/progs/es1/xegl/render_tex.c @@ -0,0 +1,659 @@ +/* + * Copyright (C) 2008 Tunsgten Graphics,Inc. All Rights Reserved. + */ + +/* + * Test EGL render to texture. + * Brian Paul + * August 2008 + */ + + +#include <assert.h> +#include <math.h> +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <X11/Xlib.h> +#include <X11/Xutil.h> +#include <X11/keysym.h> +#include <GLES/gl.h> +#include <GLES/glext.h> +#include <EGL/egl.h> + + +static int TexWidth = 256, TexHeight = 256; + +static int WinWidth = 300, WinHeight = 300; + +static GLfloat view_rotx = 0.0, view_roty = 0.0, view_rotz = 0.0; + +static GLuint DotTexture, RenderTexture; + + +static void +Normal(GLfloat *n, GLfloat nx, GLfloat ny, GLfloat nz) +{ + n[0] = nx; + n[1] = ny; + n[2] = nz; +} + +static void +Vertex(GLfloat *v, GLfloat vx, GLfloat vy, GLfloat vz) +{ + v[0] = vx; + v[1] = vy; + v[2] = vz; +} + +static void +Texcoord(GLfloat *v, GLfloat s, GLfloat t) +{ + v[0] = s; + v[1] = t; +} + + +/* Borrowed from glut, adapted */ +static void +draw_torus(GLfloat r, GLfloat R, GLint nsides, GLint rings) +{ + int i, j; + GLfloat theta, phi, theta1; + GLfloat cosTheta, sinTheta; + GLfloat cosTheta1, sinTheta1; + GLfloat ringDelta, sideDelta; + GLfloat varray[100][3], narray[100][3], tarray[100][2]; + int vcount; + + glVertexPointer(3, GL_FLOAT, 0, varray); + glNormalPointer(GL_FLOAT, 0, narray); + glTexCoordPointer(2, GL_FLOAT, 0, tarray); + glEnableClientState(GL_VERTEX_ARRAY); + glEnableClientState(GL_NORMAL_ARRAY); + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + + ringDelta = 2.0 * M_PI / rings; + sideDelta = 2.0 * M_PI / nsides; + + theta = 0.0; + cosTheta = 1.0; + sinTheta = 0.0; + for (i = rings - 1; i >= 0; i--) { + theta1 = theta + ringDelta; + cosTheta1 = cos(theta1); + sinTheta1 = sin(theta1); + + vcount = 0; /* glBegin(GL_QUAD_STRIP); */ + + phi = 0.0; + for (j = nsides; j >= 0; j--) { + GLfloat s0, s1, t; + GLfloat cosPhi, sinPhi, dist; + + phi += sideDelta; + cosPhi = cos(phi); + sinPhi = sin(phi); + dist = R + r * cosPhi; + + s0 = 20.0 * theta / (2.0 * M_PI); + s1 = 20.0 * theta1 / (2.0 * M_PI); + t = 8.0 * phi / (2.0 * M_PI); + + Normal(narray[vcount], cosTheta1 * cosPhi, -sinTheta1 * cosPhi, sinPhi); + Texcoord(tarray[vcount], s1, t); + Vertex(varray[vcount], cosTheta1 * dist, -sinTheta1 * dist, r * sinPhi); + vcount++; + + Normal(narray[vcount], cosTheta * cosPhi, -sinTheta * cosPhi, sinPhi); + Texcoord(tarray[vcount], s0, t); + Vertex(varray[vcount], cosTheta * dist, -sinTheta * dist, r * sinPhi); + vcount++; + } + + /*glEnd();*/ + assert(vcount <= 100); + glDrawArrays(GL_TRIANGLE_STRIP, 0, vcount); + + theta = theta1; + cosTheta = cosTheta1; + sinTheta = sinTheta1; + } + + glDisableClientState(GL_VERTEX_ARRAY); + glDisableClientState(GL_NORMAL_ARRAY); + glDisableClientState(GL_TEXTURE_COORD_ARRAY); +} + + +static void +draw_torus_to_texture(void) +{ + glViewport(0, 0, TexWidth, TexHeight); + + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + glFrustumf(-1, 1, -1, 1, 5.0, 60.0); + + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + glTranslatef(0.0, 0.0, -15.0); + + glClearColor(0.4, 0.4, 0.4, 0.0); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + glBindTexture(GL_TEXTURE_2D, DotTexture); + + glEnable(GL_LIGHTING); + + glPushMatrix(); + glRotatef(view_roty, 0, 1, 0); + glScalef(0.5, 0.5, 0.5); + + draw_torus(1.0, 3.0, 30, 60); + + glPopMatrix(); + + glDisable(GL_LIGHTING); + +#if 0 + glBindTexture(GL_TEXTURE_2D, RenderTexture); + glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, TexWidth, TexHeight); +#endif + + glFinish(); +} + + +static void +draw_textured_quad(void) +{ + GLfloat ar = (GLfloat) WinWidth / (GLfloat) WinHeight; + + glViewport(0, 0, WinWidth, WinHeight); + + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + glFrustumf(-ar, ar, -1, 1, 5.0, 60.0); + + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + glTranslatef(0.0, 0.0, -8.0); + + glClearColor(0.4, 0.4, 1.0, 0.0); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + glBindTexture(GL_TEXTURE_2D, RenderTexture); + + glPushMatrix(); + glRotatef(view_rotx, 1, 0, 0); + glRotatef(view_rotz, 0, 0, 1); + + { + static const GLfloat texcoord[4][2] = { + { 0, 0 }, { 1, 0 }, { 0, 1 }, { 1, 1 } + }; + static const GLfloat vertex[4][2] = { + { -1, -1 }, { 1, -1 }, { -1, 1 }, { 1, 1 } + }; + + glVertexPointer(2, GL_FLOAT, 0, vertex); + glTexCoordPointer(2, GL_FLOAT, 0, texcoord); + glEnableClientState(GL_VERTEX_ARRAY); + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + + glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); + + glDisableClientState(GL_VERTEX_ARRAY); + glDisableClientState(GL_TEXTURE_COORD_ARRAY); + } + + glPopMatrix(); +} + + + +static void +draw(EGLDisplay egl_dpy, EGLSurface egl_surf, EGLSurface egl_pbuf, + EGLContext egl_ctx) +{ + /*printf("Begin draw\n");*/ + + /* first draw torus to pbuffer /texture */ +#if 01 + if (!eglMakeCurrent(egl_dpy, egl_pbuf, egl_pbuf, egl_ctx)) { +#else + if (!eglMakeCurrent(egl_dpy, egl_surf, egl_surf, egl_ctx)) { +#endif + printf("Error: eglMakeCurrent(pbuf) failed\n"); + return; + } + draw_torus_to_texture(); + + /* draw textured quad to window */ + if (!eglMakeCurrent(egl_dpy, egl_surf, egl_surf, egl_ctx)) { + printf("Error: eglMakeCurrent(pbuffer) failed\n"); + return; + } + + glBindTexture(GL_TEXTURE_2D, RenderTexture); + eglBindTexImage(egl_dpy, egl_pbuf, EGL_BACK_BUFFER); + draw_textured_quad(); + eglReleaseTexImage(egl_dpy, egl_pbuf, EGL_BACK_BUFFER); + + eglSwapBuffers(egl_dpy, egl_surf); + + /*printf("End draw\n");*/ +} + + + +static void +make_dot_texture(void) +{ +#define SZ 64 + GLenum Filter = GL_LINEAR; + GLubyte image[SZ][SZ][4]; + GLuint i, j; + + for (i = 0; i < SZ; i++) { + for (j = 0; j < SZ; j++) { + GLfloat d = (i - SZ/2) * (i - SZ/2) + (j - SZ/2) * (j - SZ/2); + d = sqrt(d); + if (d < SZ/3) { + image[i][j][0] = 255; + image[i][j][1] = 255; + image[i][j][2] = 255; + image[i][j][3] = 255; + } + else { + image[i][j][0] = 127; + image[i][j][1] = 127; + image[i][j][2] = 127; + image[i][j][3] = 255; + } + } + } + + glGenTextures(1, &DotTexture); + glBindTexture(GL_TEXTURE_2D, DotTexture); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, SZ, SZ, 0, + GL_RGBA, GL_UNSIGNED_BYTE, image); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, Filter); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, Filter); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); +#undef SZ +} + + +static void +make_render_texture(void) +{ + GLenum Filter = GL_LINEAR; + glGenTextures(1, &RenderTexture); + glBindTexture(GL_TEXTURE_2D, RenderTexture); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, TexWidth, TexHeight, 0, + GL_RGBA, GL_UNSIGNED_BYTE, NULL); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, Filter); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, Filter); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); +} + + +static void +init(void) +{ + static const GLfloat red[4] = {1, 0, 0, 0}; + static const GLfloat white[4] = {1.0, 1.0, 1.0, 1.0}; + static const GLfloat diffuse[4] = {0.7, 0.7, 0.7, 1.0}; + static const GLfloat specular[4] = {0.001, 0.001, 0.001, 1.0}; + static const GLfloat pos[4] = {20, 20, 50, 1}; + + glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, red); + glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, white); + glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 9.0); + + glEnable(GL_LIGHT0); + glLightfv(GL_LIGHT0, GL_POSITION, pos); + glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuse); + glLightfv(GL_LIGHT0, GL_SPECULAR, specular); + + glEnable(GL_DEPTH_TEST); + + make_dot_texture(); + make_render_texture(); + + printf("DotTexture=%u RenderTexture=%u\n", DotTexture, RenderTexture); + + glEnable(GL_TEXTURE_2D); +} + + +/* + * Create an RGB, double-buffered X window. + * Return the window and context handles. + */ +static void +make_x_window(Display *x_dpy, EGLDisplay egl_dpy, + const char *name, + int x, int y, int width, int height, + Window *winRet, + EGLContext *ctxRet, + EGLSurface *surfRet) +{ + static const EGLint attribs[] = { + EGL_RED_SIZE, 1, + EGL_GREEN_SIZE, 1, + EGL_BLUE_SIZE, 1, + EGL_DEPTH_SIZE, 1, + EGL_NONE + }; + + int scrnum; + XSetWindowAttributes attr; + unsigned long mask; + Window root; + Window win; + XVisualInfo *visInfo, visTemplate; + int num_visuals; + EGLContext ctx; + EGLConfig config; + EGLint num_configs; + EGLint vid; + + scrnum = DefaultScreen( x_dpy ); + root = RootWindow( x_dpy, scrnum ); + + if (!eglChooseConfig( egl_dpy, attribs, &config, 1, &num_configs)) { + printf("Error: couldn't get an EGL visual config\n"); + exit(1); + } + + assert(config); + assert(num_configs > 0); + + if (!eglGetConfigAttrib(egl_dpy, config, EGL_NATIVE_VISUAL_ID, &vid)) { + printf("Error: eglGetConfigAttrib() failed\n"); + exit(1); + } + + /* The X window visual must match the EGL config */ + visTemplate.visualid = vid; + visInfo = XGetVisualInfo(x_dpy, VisualIDMask, &visTemplate, &num_visuals); + if (!visInfo) { + printf("Error: couldn't get X visual\n"); + exit(1); + } + + /* window attributes */ + attr.background_pixel = 0; + attr.border_pixel = 0; + attr.colormap = XCreateColormap( x_dpy, root, visInfo->visual, AllocNone); + attr.event_mask = StructureNotifyMask | ExposureMask | KeyPressMask; + mask = CWBackPixel | CWBorderPixel | CWColormap | CWEventMask; + + win = XCreateWindow( x_dpy, root, 0, 0, width, height, + 0, visInfo->depth, InputOutput, + visInfo->visual, mask, &attr ); + + /* set hints and properties */ + { + XSizeHints sizehints; + sizehints.x = x; + sizehints.y = y; + sizehints.width = width; + sizehints.height = height; + sizehints.flags = USSize | USPosition; + XSetNormalHints(x_dpy, win, &sizehints); + XSetStandardProperties(x_dpy, win, name, name, + None, (char **)NULL, 0, &sizehints); + } + + eglBindAPI(EGL_OPENGL_ES_API); + + ctx = eglCreateContext(egl_dpy, config, EGL_NO_CONTEXT, NULL ); + if (!ctx) { + printf("Error: eglCreateContext failed\n"); + exit(1); + } + + *surfRet = eglCreateWindowSurface(egl_dpy, config, win, NULL); + + if (!*surfRet) { + printf("Error: eglCreateWindowSurface failed\n"); + exit(1); + } + + XFree(visInfo); + + *winRet = win; + *ctxRet = ctx; +} + + +static EGLSurface +make_pbuffer(Display *x_dpy, EGLDisplay egl_dpy, int width, int height) +{ + static const EGLint config_attribs[] = { + EGL_RED_SIZE, 1, + EGL_GREEN_SIZE, 1, + EGL_BLUE_SIZE, 1, + EGL_DEPTH_SIZE, 1, + EGL_NONE + }; + EGLConfig config; + EGLSurface pbuf; + EGLint num_configs; + EGLint pbuf_attribs[15]; + int i = 0; + + pbuf_attribs[i++] = EGL_WIDTH; + pbuf_attribs[i++] = width; + pbuf_attribs[i++] = EGL_HEIGHT; + pbuf_attribs[i++] = height; + pbuf_attribs[i++] = EGL_TEXTURE_FORMAT; + pbuf_attribs[i++] = EGL_TEXTURE_RGBA; + pbuf_attribs[i++] = EGL_TEXTURE_TARGET; + pbuf_attribs[i++] = EGL_TEXTURE_2D; + pbuf_attribs[i++] = EGL_MIPMAP_TEXTURE; + pbuf_attribs[i++] = EGL_FALSE; + pbuf_attribs[i++] = EGL_NONE; + assert(i <= 15); + + if (!eglChooseConfig( egl_dpy, config_attribs, &config, 1, &num_configs)) { + printf("Error: couldn't get an EGL config for pbuffer\n"); + exit(1); + } + + pbuf = eglCreatePbufferSurface(egl_dpy, config, pbuf_attribs); + + return pbuf; +} + + +static void +event_loop(Display *dpy, Window win, + EGLDisplay egl_dpy, EGLSurface egl_surf, EGLSurface egl_pbuf, + EGLContext egl_ctx) +{ + int anim = 0; + + while (1) { + int redraw = 0; + + if (!anim || XPending(dpy)) { + XEvent event; + XNextEvent(dpy, &event); + + switch (event.type) { + case Expose: + redraw = 1; + break; + case ConfigureNotify: + if (event.xconfigure.window == win) { + WinWidth = event.xconfigure.width; + WinHeight = event.xconfigure.height; + } + break; + case KeyPress: + { + char buffer[10]; + int r, code; + code = XLookupKeysym(&event.xkey, 0); + if (code == XK_Left) { + view_roty += 5.0; + } + else if (code == XK_Right) { + view_roty -= 5.0; + } + else if (code == XK_Up) { + view_rotx += 5.0; + } + else if (code == XK_Down) { + view_rotx -= 5.0; + } + else { + r = XLookupString(&event.xkey, buffer, sizeof(buffer), + NULL, NULL); + if (buffer[0] == ' ') { + anim = !anim; + } + else if (buffer[0] == 'z') { + view_rotz += 5.0; + } + else if (buffer[0] == 'Z') { + view_rotz -= 5.0; + } + else if (buffer[0] == 27) { + /* escape */ + return; + } + } + } + redraw = 1; + break; + default: + ; /*no-op*/ + } + } + + if (anim) { + view_rotx += 1.0; + view_roty += 2.0; + redraw = 1; + } + + if (redraw) { + draw(egl_dpy, egl_surf, egl_pbuf, egl_ctx); + } + } +} + + +static void +usage(void) +{ + printf("Usage:\n"); + printf(" -display <displayname> set the display to run on\n"); + printf(" -info display OpenGL renderer info\n"); +} + + +int +main(int argc, char *argv[]) +{ + Display *x_dpy; + Window win; + EGLSurface egl_surf, egl_pbuf; + EGLContext egl_ctx; + EGLDisplay egl_dpy; + char *dpyName = NULL; + GLboolean printInfo = GL_FALSE; + EGLint egl_major, egl_minor; + int i; + const char *s; + + for (i = 1; i < argc; i++) { + if (strcmp(argv[i], "-display") == 0) { + dpyName = argv[i+1]; + i++; + } + else if (strcmp(argv[i], "-info") == 0) { + printInfo = GL_TRUE; + } + else { + usage(); + return -1; + } + } + + x_dpy = XOpenDisplay(dpyName); + if (!x_dpy) { + printf("Error: couldn't open display %s\n", + dpyName ? dpyName : getenv("DISPLAY")); + return -1; + } + + egl_dpy = eglGetDisplay(x_dpy); + if (!egl_dpy) { + printf("Error: eglGetDisplay() failed\n"); + return -1; + } + + if (!eglInitialize(egl_dpy, &egl_major, &egl_minor)) { + printf("Error: eglInitialize() failed\n"); + return -1; + } + + s = eglQueryString(egl_dpy, EGL_VERSION); + printf("EGL_VERSION = %s\n", s); + + s = eglQueryString(egl_dpy, EGL_VENDOR); + printf("EGL_VENDOR = %s\n", s); + + s = eglQueryString(egl_dpy, EGL_EXTENSIONS); + printf("EGL_EXTENSIONS = %s\n", s); + + s = eglQueryString(egl_dpy, EGL_CLIENT_APIS); + printf("EGL_CLIENT_APIS = %s\n", s); + + make_x_window(x_dpy, egl_dpy, + "render_tex", 0, 0, WinWidth, WinHeight, + &win, &egl_ctx, &egl_surf); + + egl_pbuf = make_pbuffer(x_dpy, egl_dpy, TexWidth, TexHeight); + if (!egl_pbuf) { + printf("Error: eglCreatePBufferSurface() failed\n"); + return -1; + } + + XMapWindow(x_dpy, win); + if (!eglMakeCurrent(egl_dpy, egl_surf, egl_surf, egl_ctx)) { + printf("Error: eglMakeCurrent() failed\n"); + return -1; + } + + if (printInfo) { + printf("GL_RENDERER = %s\n", (char *) glGetString(GL_RENDERER)); + printf("GL_VERSION = %s\n", (char *) glGetString(GL_VERSION)); + printf("GL_VENDOR = %s\n", (char *) glGetString(GL_VENDOR)); + printf("GL_EXTENSIONS = %s\n", (char *) glGetString(GL_EXTENSIONS)); + } + + init(); + + event_loop(x_dpy, win, egl_dpy, egl_surf, egl_pbuf, egl_ctx); + + eglDestroyContext(egl_dpy, egl_ctx); + eglDestroySurface(egl_dpy, egl_surf); + eglTerminate(egl_dpy); + + + XDestroyWindow(x_dpy, win); + XCloseDisplay(x_dpy); + + return 0; +} diff --git a/progs/es1/xegl/torus.c b/progs/es1/xegl/torus.c new file mode 100644 index 00000000000..9438a4fe59b --- /dev/null +++ b/progs/es1/xegl/torus.c @@ -0,0 +1,656 @@ +/* + * Copyright (C) 2008 Tunsgten Graphics,Inc. All Rights Reserved. + */ + +/* + * Draw a lit, textured torus with X/EGL and OpenGL ES 1.x + * Brian Paul + * July 2008 + */ + + +#include <assert.h> +#include <math.h> +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <X11/Xlib.h> +#include <X11/Xutil.h> +#include <X11/keysym.h> +#include <GLES/gl.h> +#include <GLES/glext.h> +#include <EGL/egl.h> + + +static const struct { + GLenum internalFormat; + const char *name; + GLuint num_entries; + GLuint size; +} cpal_formats[] = { + { GL_PALETTE4_RGB8_OES, "GL_PALETTE4_RGB8_OES", 16, 3 }, + { GL_PALETTE4_RGBA8_OES, "GL_PALETTE4_RGBA8_OES", 16, 4 }, + { GL_PALETTE4_R5_G6_B5_OES, "GL_PALETTE4_R5_G6_B5_OES", 16, 2 }, + { GL_PALETTE4_RGBA4_OES, "GL_PALETTE4_RGBA4_OES", 16, 2 }, + { GL_PALETTE4_RGB5_A1_OES, "GL_PALETTE4_RGB5_A1_OES", 16, 2 }, + { GL_PALETTE8_RGB8_OES, "GL_PALETTE8_RGB8_OES", 256, 3 }, + { GL_PALETTE8_RGBA8_OES, "GL_PALETTE8_RGBA8_OES", 256, 4 }, + { GL_PALETTE8_R5_G6_B5_OES, "GL_PALETTE8_R5_G6_B5_OES", 256, 2 }, + { GL_PALETTE8_RGBA4_OES, "GL_PALETTE8_RGBA4_OES", 256, 2 }, + { GL_PALETTE8_RGB5_A1_OES, "GL_PALETTE8_RGB5_A1_OES", 256, 2 } +}; +#define NUM_CPAL_FORMATS (sizeof(cpal_formats) / sizeof(cpal_formats[0])) + +static GLfloat view_rotx = 0.0, view_roty = 0.0, view_rotz = 0.0; +static GLint tex_format = NUM_CPAL_FORMATS; + + +static void +Normal(GLfloat *n, GLfloat nx, GLfloat ny, GLfloat nz) +{ + n[0] = nx; + n[1] = ny; + n[2] = nz; +} + +static void +Vertex(GLfloat *v, GLfloat vx, GLfloat vy, GLfloat vz) +{ + v[0] = vx; + v[1] = vy; + v[2] = vz; +} + +static void +Texcoord(GLfloat *v, GLfloat s, GLfloat t) +{ + v[0] = s; + v[1] = t; +} + + +/* Borrowed from glut, adapted */ +static void +draw_torus(GLfloat r, GLfloat R, GLint nsides, GLint rings) +{ + int i, j; + GLfloat theta, phi, theta1; + GLfloat cosTheta, sinTheta; + GLfloat cosTheta1, sinTheta1; + GLfloat ringDelta, sideDelta; + GLfloat varray[100][3], narray[100][3], tarray[100][2]; + int vcount; + + glVertexPointer(3, GL_FLOAT, 0, varray); + glNormalPointer(GL_FLOAT, 0, narray); + glTexCoordPointer(2, GL_FLOAT, 0, tarray); + glEnableClientState(GL_VERTEX_ARRAY); + glEnableClientState(GL_NORMAL_ARRAY); + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + + ringDelta = 2.0 * M_PI / rings; + sideDelta = 2.0 * M_PI / nsides; + + theta = 0.0; + cosTheta = 1.0; + sinTheta = 0.0; + for (i = rings - 1; i >= 0; i--) { + theta1 = theta + ringDelta; + cosTheta1 = cos(theta1); + sinTheta1 = sin(theta1); + + vcount = 0; /* glBegin(GL_QUAD_STRIP); */ + + phi = 0.0; + for (j = nsides; j >= 0; j--) { + GLfloat s0, s1, t; + GLfloat cosPhi, sinPhi, dist; + + phi += sideDelta; + cosPhi = cos(phi); + sinPhi = sin(phi); + dist = R + r * cosPhi; + + s0 = 20.0 * theta / (2.0 * M_PI); + s1 = 20.0 * theta1 / (2.0 * M_PI); + t = 8.0 * phi / (2.0 * M_PI); + + Normal(narray[vcount], cosTheta1 * cosPhi, -sinTheta1 * cosPhi, sinPhi); + Texcoord(tarray[vcount], s1, t); + Vertex(varray[vcount], cosTheta1 * dist, -sinTheta1 * dist, r * sinPhi); + vcount++; + + Normal(narray[vcount], cosTheta * cosPhi, -sinTheta * cosPhi, sinPhi); + Texcoord(tarray[vcount], s0, t); + Vertex(varray[vcount], cosTheta * dist, -sinTheta * dist, r * sinPhi); + vcount++; + } + + /*glEnd();*/ + assert(vcount <= 100); + glDrawArrays(GL_TRIANGLE_STRIP, 0, vcount); + + theta = theta1; + cosTheta = cosTheta1; + sinTheta = sinTheta1; + } + + glDisableClientState(GL_VERTEX_ARRAY); + glDisableClientState(GL_NORMAL_ARRAY); + glDisableClientState(GL_TEXTURE_COORD_ARRAY); +} + + +static void +draw(void) +{ + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + glPushMatrix(); + glRotatef(view_rotx, 1, 0, 0); + glRotatef(view_roty, 0, 1, 0); + glRotatef(view_rotz, 0, 0, 1); + glScalef(0.5, 0.5, 0.5); + + draw_torus(1.0, 3.0, 30, 60); + + glPopMatrix(); +} + + +/* new window size or exposure */ +static void +reshape(int width, int height) +{ + GLfloat ar = (GLfloat) width / (GLfloat) height; + + glViewport(0, 0, (GLint) width, (GLint) height); + + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + +#ifdef GL_VERSION_ES_CM_1_0 + glFrustumf(-ar, ar, -1, 1, 5.0, 60.0); +#else + glFrustum(-ar, ar, -1, 1, 5.0, 60.0); +#endif + + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + glTranslatef(0.0, 0.0, -15.0); +} + + +static GLint +make_cpal_texture(GLint idx) +{ +#define SZ 64 + GLenum internalFormat = GL_PALETTE4_RGB8_OES + idx; + GLenum Filter = GL_LINEAR; + GLubyte palette[256 * 4 + SZ * SZ]; + GLubyte *indices; + GLsizei image_size; + GLuint i, j; + GLuint packed_indices = 0; + + assert(cpal_formats[idx].internalFormat == internalFormat); + + /* init palette */ + switch (internalFormat) { + case GL_PALETTE4_RGB8_OES: + case GL_PALETTE8_RGB8_OES: + /* first entry */ + palette[0] = 255; + palette[1] = 255; + palette[2] = 255; + /* second entry */ + palette[3] = 127; + palette[4] = 127; + palette[5] = 127; + break; + case GL_PALETTE4_RGBA8_OES: + case GL_PALETTE8_RGBA8_OES: + /* first entry */ + palette[0] = 255; + palette[1] = 255; + palette[2] = 255; + palette[3] = 255; + /* second entry */ + palette[4] = 127; + palette[5] = 127; + palette[6] = 127; + palette[7] = 255; + break; + case GL_PALETTE4_R5_G6_B5_OES: + case GL_PALETTE8_R5_G6_B5_OES: + { + GLushort *pal = (GLushort *) palette; + /* first entry */ + pal[0] = (31 << 11 | 63 << 5 | 31); + /* second entry */ + pal[1] = (15 << 11 | 31 << 5 | 15); + } + break; + case GL_PALETTE4_RGBA4_OES: + case GL_PALETTE8_RGBA4_OES: + { + GLushort *pal = (GLushort *) palette; + /* first entry */ + pal[0] = (15 << 12 | 15 << 8 | 15 << 4 | 15); + /* second entry */ + pal[1] = (7 << 12 | 7 << 8 | 7 << 4 | 15); + } + break; + case GL_PALETTE4_RGB5_A1_OES: + case GL_PALETTE8_RGB5_A1_OES: + { + GLushort *pal = (GLushort *) palette; + /* first entry */ + pal[0] = (31 << 11 | 31 << 6 | 31 << 1 | 1); + /* second entry */ + pal[1] = (15 << 11 | 15 << 6 | 15 << 1 | 1); + } + break; + } + + image_size = cpal_formats[idx].size * cpal_formats[idx].num_entries; + indices = palette + image_size; + for (i = 0; i < SZ; i++) { + for (j = 0; j < SZ; j++) { + GLfloat d; + GLint index; + d = (i - SZ/2) * (i - SZ/2) + (j - SZ/2) * (j - SZ/2); + d = sqrt(d); + index = (d < SZ / 3) ? 0 : 1; + + if (cpal_formats[idx].num_entries == 16) { + /* 4-bit indices packed in GLubyte */ + packed_indices |= index << (4 * (1 - (j % 2))); + if (j % 2) { + *(indices + (i * SZ + j - 1) / 2) = packed_indices & 0xff; + packed_indices = 0; + image_size += 1; + } + } + else { + /* 8-bit indices */ + *(indices + i * SZ + j) = index; + image_size += 1; + } + } + } + + glActiveTexture(GL_TEXTURE0); /* unit 0 */ + glBindTexture(GL_TEXTURE_2D, 42); + glCompressedTexImage2D(GL_TEXTURE_2D, 0, internalFormat, SZ, SZ, 0, + image_size, palette); + + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, Filter); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, Filter); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); +#undef SZ + + return image_size; +} + + +static GLint +make_texture(void) +{ +#define SZ 64 + GLenum Filter = GL_LINEAR; + GLubyte image[SZ][SZ][4]; + GLuint i, j; + + for (i = 0; i < SZ; i++) { + for (j = 0; j < SZ; j++) { + GLfloat d = (i - SZ/2) * (i - SZ/2) + (j - SZ/2) * (j - SZ/2); + d = sqrt(d); + if (d < SZ/3) { + image[i][j][0] = 255; + image[i][j][1] = 255; + image[i][j][2] = 255; + image[i][j][3] = 255; + } + else { + image[i][j][0] = 127; + image[i][j][1] = 127; + image[i][j][2] = 127; + image[i][j][3] = 255; + } + } + } + + glActiveTexture(GL_TEXTURE0); /* unit 0 */ + glBindTexture(GL_TEXTURE_2D, 42); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, SZ, SZ, 0, + GL_RGBA, GL_UNSIGNED_BYTE, image); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, Filter); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, Filter); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); +#undef SZ + + return sizeof(image); +} + + + +static void +init(void) +{ + static const GLfloat red[4] = {1, 0, 0, 0}; + static const GLfloat white[4] = {1.0, 1.0, 1.0, 1.0}; + static const GLfloat diffuse[4] = {0.7, 0.7, 0.7, 1.0}; + static const GLfloat specular[4] = {0.001, 0.001, 0.001, 1.0}; + static const GLfloat pos[4] = {20, 20, 50, 1}; + + glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, red); + glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, white); + glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 9.0); + + glEnable(GL_LIGHTING); + glEnable(GL_LIGHT0); + glLightfv(GL_LIGHT0, GL_POSITION, pos); + glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuse); + glLightfv(GL_LIGHT0, GL_SPECULAR, specular); + + glClearColor(0.4, 0.4, 0.4, 0.0); + glEnable(GL_DEPTH_TEST); + + make_texture(); + glEnable(GL_TEXTURE_2D); +} + + +/* + * Create an RGB, double-buffered X window. + * Return the window and context handles. + */ +static void +make_x_window(Display *x_dpy, EGLDisplay egl_dpy, + const char *name, + int x, int y, int width, int height, + Window *winRet, + EGLContext *ctxRet, + EGLSurface *surfRet) +{ + static const EGLint attribs[] = { + EGL_RED_SIZE, 1, + EGL_GREEN_SIZE, 1, + EGL_BLUE_SIZE, 1, + EGL_DEPTH_SIZE, 1, + EGL_NONE + }; + + int scrnum; + XSetWindowAttributes attr; + unsigned long mask; + Window root; + Window win; + XVisualInfo *visInfo, visTemplate; + int num_visuals; + EGLContext ctx; + EGLConfig config; + EGLint num_configs; + EGLint vid; + + scrnum = DefaultScreen( x_dpy ); + root = RootWindow( x_dpy, scrnum ); + + if (!eglChooseConfig( egl_dpy, attribs, &config, 1, &num_configs)) { + printf("Error: couldn't get an EGL visual config\n"); + exit(1); + } + + assert(config); + assert(num_configs > 0); + + if (!eglGetConfigAttrib(egl_dpy, config, EGL_NATIVE_VISUAL_ID, &vid)) { + printf("Error: eglGetConfigAttrib() failed\n"); + exit(1); + } + + /* The X window visual must match the EGL config */ + visTemplate.visualid = vid; + visInfo = XGetVisualInfo(x_dpy, VisualIDMask, &visTemplate, &num_visuals); + if (!visInfo) { + printf("Error: couldn't get X visual\n"); + exit(1); + } + + /* window attributes */ + attr.background_pixel = 0; + attr.border_pixel = 0; + attr.colormap = XCreateColormap( x_dpy, root, visInfo->visual, AllocNone); + attr.event_mask = StructureNotifyMask | ExposureMask | KeyPressMask; + mask = CWBackPixel | CWBorderPixel | CWColormap | CWEventMask; + + win = XCreateWindow( x_dpy, root, 0, 0, width, height, + 0, visInfo->depth, InputOutput, + visInfo->visual, mask, &attr ); + + /* set hints and properties */ + { + XSizeHints sizehints; + sizehints.x = x; + sizehints.y = y; + sizehints.width = width; + sizehints.height = height; + sizehints.flags = USSize | USPosition; + XSetNormalHints(x_dpy, win, &sizehints); + XSetStandardProperties(x_dpy, win, name, name, + None, (char **)NULL, 0, &sizehints); + } + + eglBindAPI(EGL_OPENGL_ES_API); + + ctx = eglCreateContext(egl_dpy, config, EGL_NO_CONTEXT, NULL ); + if (!ctx) { + printf("Error: eglCreateContext failed\n"); + exit(1); + } + + *surfRet = eglCreateWindowSurface(egl_dpy, config, win, NULL); + + if (!*surfRet) { + printf("Error: eglCreateWindowSurface failed\n"); + exit(1); + } + + XFree(visInfo); + + *winRet = win; + *ctxRet = ctx; +} + + +static void +event_loop(Display *dpy, Window win, + EGLDisplay egl_dpy, EGLSurface egl_surf) +{ + int anim = 1; + + while (1) { + int redraw = 0; + + if (!anim || XPending(dpy)) { + XEvent event; + XNextEvent(dpy, &event); + + switch (event.type) { + case Expose: + redraw = 1; + break; + case ConfigureNotify: + reshape(event.xconfigure.width, event.xconfigure.height); + break; + case KeyPress: + { + char buffer[10]; + int r, code; + code = XLookupKeysym(&event.xkey, 0); + if (code == XK_Left) { + view_roty += 5.0; + } + else if (code == XK_Right) { + view_roty -= 5.0; + } + else if (code == XK_Up) { + view_rotx += 5.0; + } + else if (code == XK_Down) { + view_rotx -= 5.0; + } + else if (code == XK_t) { + GLint size; + tex_format = (tex_format + 1) % (NUM_CPAL_FORMATS + 1); + if (tex_format < NUM_CPAL_FORMATS) { + size = make_cpal_texture(tex_format); + printf("Using %s (%d bytes)\n", + cpal_formats[tex_format].name, size); + } + else { + size = make_texture(); + printf("Using uncompressed texture (%d bytes)\n", size); + } + } + else { + r = XLookupString(&event.xkey, buffer, sizeof(buffer), + NULL, NULL); + if (buffer[0] == ' ') { + anim = !anim; + } + else if (buffer[0] == 27) { + /* escape */ + return; + } + } + } + redraw = 1; + break; + default: + ; /*no-op*/ + } + } + + if (anim) { + view_rotx += 1.0; + view_roty += 2.0; + redraw = 1; + } + + if (redraw) { + draw(); + eglSwapBuffers(egl_dpy, egl_surf); + } + } +} + + +static void +usage(void) +{ + printf("Usage:\n"); + printf(" -display <displayname> set the display to run on\n"); + printf(" -info display OpenGL renderer info\n"); +} + + +int +main(int argc, char *argv[]) +{ + const int winWidth = 300, winHeight = 300; + Display *x_dpy; + Window win; + EGLSurface egl_surf; + EGLContext egl_ctx; + EGLDisplay egl_dpy; + char *dpyName = NULL; + GLboolean printInfo = GL_FALSE; + EGLint egl_major, egl_minor; + int i; + const char *s; + + for (i = 1; i < argc; i++) { + if (strcmp(argv[i], "-display") == 0) { + dpyName = argv[i+1]; + i++; + } + else if (strcmp(argv[i], "-info") == 0) { + printInfo = GL_TRUE; + } + else { + usage(); + return -1; + } + } + + x_dpy = XOpenDisplay(dpyName); + if (!x_dpy) { + printf("Error: couldn't open display %s\n", + dpyName ? dpyName : getenv("DISPLAY")); + return -1; + } + + egl_dpy = eglGetDisplay(x_dpy); + if (!egl_dpy) { + printf("Error: eglGetDisplay() failed\n"); + return -1; + } + + if (!eglInitialize(egl_dpy, &egl_major, &egl_minor)) { + printf("Error: eglInitialize() failed\n"); + return -1; + } + + s = eglQueryString(egl_dpy, EGL_VERSION); + printf("EGL_VERSION = %s\n", s); + + s = eglQueryString(egl_dpy, EGL_VENDOR); + printf("EGL_VENDOR = %s\n", s); + + s = eglQueryString(egl_dpy, EGL_EXTENSIONS); + printf("EGL_EXTENSIONS = %s\n", s); + + s = eglQueryString(egl_dpy, EGL_CLIENT_APIS); + printf("EGL_CLIENT_APIS = %s\n", s); + + make_x_window(x_dpy, egl_dpy, + "torus", 0, 0, winWidth, winHeight, + &win, &egl_ctx, &egl_surf); + + XMapWindow(x_dpy, win); + if (!eglMakeCurrent(egl_dpy, egl_surf, egl_surf, egl_ctx)) { + printf("Error: eglMakeCurrent() failed\n"); + return -1; + } + + if (printInfo) { + printf("GL_RENDERER = %s\n", (char *) glGetString(GL_RENDERER)); + printf("GL_VERSION = %s\n", (char *) glGetString(GL_VERSION)); + printf("GL_VENDOR = %s\n", (char *) glGetString(GL_VENDOR)); + printf("GL_EXTENSIONS = %s\n", (char *) glGetString(GL_EXTENSIONS)); + } + + init(); + + /* Set initial projection/viewing transformation. + * We can't be sure we'll get a ConfigureNotify event when the window + * first appears. + */ + reshape(winWidth, winHeight); + + event_loop(x_dpy, win, egl_dpy, egl_surf); + + eglDestroyContext(egl_dpy, egl_ctx); + eglDestroySurface(egl_dpy, egl_surf); + eglTerminate(egl_dpy); + + + XDestroyWindow(x_dpy, win); + XCloseDisplay(x_dpy); + + return 0; +} diff --git a/progs/es1/xegl/tri.c b/progs/es1/xegl/tri.c new file mode 100644 index 00000000000..42a978207c9 --- /dev/null +++ b/progs/es1/xegl/tri.c @@ -0,0 +1,470 @@ +/* + * Copyright (C) 2008 Brian Paul All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +/* + * Draw a triangle with X/EGL and OpenGL ES 1.x + * Brian Paul + * 5 June 2008 + */ + +#define USE_FULL_GL 0 + +#define USE_FIXED_POINT 0 + + +#include <assert.h> +#include <math.h> +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <X11/Xlib.h> +#include <X11/Xutil.h> +#include <X11/keysym.h> +#if USE_FULL_GL +#include <GL/gl.h> /* use full OpenGL */ +#else +#include <GLES/gl.h> /* use OpenGL ES 1.x */ +#include <GLES/glext.h> +#endif +#include <EGL/egl.h> + + +#define FLOAT_TO_FIXED(X) ((X) * 65535.0) + + + +static GLfloat view_rotx = 0.0, view_roty = 0.0, view_rotz = 0.0; + + +static void +draw(void) +{ +#if USE_FIXED_POINT + static const GLfixed verts[3][2] = { + { -65536, -65536 }, + { 65536, -65536 }, + { 0, 65536 } + }; + static const GLfixed colors[3][4] = { + { 65536, 0, 0, 65536 }, + { 0, 65536, 0 , 65536}, + { 0, 0, 65536 , 65536} + }; +#else + static const GLfloat verts[3][2] = { + { -1, -1 }, + { 1, -1 }, + { 0, 1 } + }; + static const GLfloat colors[3][4] = { + { 1, 0, 0, 1 }, + { 0, 1, 0, 1 }, + { 0, 0, 1, 1 } + }; +#endif + + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + glPushMatrix(); + glRotatef(view_rotx, 1, 0, 0); + glRotatef(view_roty, 0, 1, 0); + glRotatef(view_rotz, 0, 0, 1); + + { +#if USE_FIXED_POINT + glVertexPointer(2, GL_FIXED, 0, verts); + glColorPointer(4, GL_FIXED, 0, colors); +#else + glVertexPointer(2, GL_FLOAT, 0, verts); + glColorPointer(4, GL_FLOAT, 0, colors); +#endif + glEnableClientState(GL_VERTEX_ARRAY); + glEnableClientState(GL_COLOR_ARRAY); + + /* draw triangle */ + glDrawArrays(GL_TRIANGLES, 0, 3); + + /* draw some points */ + glPointSizex(FLOAT_TO_FIXED(15.5)); + glDrawArrays(GL_POINTS, 0, 3); + + glDisableClientState(GL_VERTEX_ARRAY); + glDisableClientState(GL_COLOR_ARRAY); + } + + if (0) { + /* test code */ + GLfixed size; + glGetFixedv(GL_POINT_SIZE, &size); + printf("GL_POINT_SIZE = 0x%x %f\n", size, size / 65536.0); + } + + glPopMatrix(); +} + + +/* new window size or exposure */ +static void +reshape(int width, int height) +{ + GLfloat ar = (GLfloat) width / (GLfloat) height; + + glViewport(0, 0, (GLint) width, (GLint) height); + + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); +#ifdef GL_VERSION_ES_CM_1_0 + glFrustumf(-ar, ar, -1, 1, 5.0, 60.0); +#else + glFrustum(-ar, ar, -1, 1, 5.0, 60.0); +#endif + + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + glTranslatef(0.0, 0.0, -10.0); +} + + +static void +test_query_matrix(void) +{ + PFNGLQUERYMATRIXXOESPROC procQueryMatrixx; + typedef void (*voidproc)(); + GLfixed mantissa[16]; + GLint exponent[16]; + GLbitfield rv; + int i; + + procQueryMatrixx = (PFNGLQUERYMATRIXXOESPROC) eglGetProcAddress("glQueryMatrixxOES"); + assert(procQueryMatrixx); + /* Actually try out this one */ + rv = (*procQueryMatrixx)(mantissa, exponent); + for (i = 0; i < 16; i++) { + if (rv & (1<<i)) { + printf("matrix[%d] invalid\n", i); + } + else { + printf("matrix[%d] = %f * 2^(%d)\n", i, mantissa[i]/65536.0, exponent[i]); + } + } + assert(!eglGetProcAddress("glFoo")); +} + + +static void +init(void) +{ + glClearColor(0.4, 0.4, 0.4, 0.0); + + if (0) + test_query_matrix(); +} + + +/* + * Create an RGB, double-buffered X window. + * Return the window and context handles. + */ +static void +make_x_window(Display *x_dpy, EGLDisplay egl_dpy, + const char *name, + int x, int y, int width, int height, + Window *winRet, + EGLContext *ctxRet, + EGLSurface *surfRet) +{ + static const EGLint attribs[] = { + EGL_RED_SIZE, 1, + EGL_GREEN_SIZE, 1, + EGL_BLUE_SIZE, 1, + EGL_DEPTH_SIZE, 1, + EGL_NONE + }; + + int scrnum; + XSetWindowAttributes attr; + unsigned long mask; + Window root; + Window win; + XVisualInfo *visInfo, visTemplate; + int num_visuals; + EGLContext ctx; + EGLConfig config; + EGLint num_configs; + EGLint vid; + + scrnum = DefaultScreen( x_dpy ); + root = RootWindow( x_dpy, scrnum ); + + if (!eglChooseConfig( egl_dpy, attribs, &config, 1, &num_configs)) { + printf("Error: couldn't get an EGL visual config\n"); + exit(1); + } + + assert(config); + assert(num_configs > 0); + + if (!eglGetConfigAttrib(egl_dpy, config, EGL_NATIVE_VISUAL_ID, &vid)) { + printf("Error: eglGetConfigAttrib() failed\n"); + exit(1); + } + + /* The X window visual must match the EGL config */ + visTemplate.visualid = vid; + visInfo = XGetVisualInfo(x_dpy, VisualIDMask, &visTemplate, &num_visuals); + if (!visInfo) { + printf("Error: couldn't get X visual\n"); + exit(1); + } + + /* window attributes */ + attr.background_pixel = 0; + attr.border_pixel = 0; + attr.colormap = XCreateColormap( x_dpy, root, visInfo->visual, AllocNone); + attr.event_mask = StructureNotifyMask | ExposureMask | KeyPressMask; + mask = CWBackPixel | CWBorderPixel | CWColormap | CWEventMask; + + win = XCreateWindow( x_dpy, root, 0, 0, width, height, + 0, visInfo->depth, InputOutput, + visInfo->visual, mask, &attr ); + + /* set hints and properties */ + { + XSizeHints sizehints; + sizehints.x = x; + sizehints.y = y; + sizehints.width = width; + sizehints.height = height; + sizehints.flags = USSize | USPosition; + XSetNormalHints(x_dpy, win, &sizehints); + XSetStandardProperties(x_dpy, win, name, name, + None, (char **)NULL, 0, &sizehints); + } + +#if USE_FULL_GL + eglBindAPI(EGL_OPENGL_API); +#else + eglBindAPI(EGL_OPENGL_ES_API); +#endif + + ctx = eglCreateContext(egl_dpy, config, EGL_NO_CONTEXT, NULL ); + if (!ctx) { + printf("Error: eglCreateContext failed\n"); + exit(1); + } + + *surfRet = eglCreateWindowSurface(egl_dpy, config, win, NULL); + + if (!*surfRet) { + printf("Error: eglCreateWindowSurface failed\n"); + exit(1); + } + + XFree(visInfo); + + *winRet = win; + *ctxRet = ctx; +} + + +static void +event_loop(Display *dpy, Window win, + EGLDisplay egl_dpy, EGLSurface egl_surf) +{ + while (1) { + int redraw = 0; + XEvent event; + + XNextEvent(dpy, &event); + + switch (event.type) { + case Expose: + redraw = 1; + break; + case ConfigureNotify: + reshape(event.xconfigure.width, event.xconfigure.height); + break; + case KeyPress: + { + char buffer[10]; + int r, code; + code = XLookupKeysym(&event.xkey, 0); + if (code == XK_Left) { + view_roty += 5.0; + } + else if (code == XK_Right) { + view_roty -= 5.0; + } + else if (code == XK_Up) { + view_rotx += 5.0; + } + else if (code == XK_Down) { + view_rotx -= 5.0; + } + else { + r = XLookupString(&event.xkey, buffer, sizeof(buffer), + NULL, NULL); + if (buffer[0] == 27) { + /* escape */ + return; + } + } + } + redraw = 1; + break; + default: + ; /*no-op*/ + } + + if (redraw) { + draw(); + eglSwapBuffers(egl_dpy, egl_surf); + } + } +} + + +static void +usage(void) +{ + printf("Usage:\n"); + printf(" -display <displayname> set the display to run on\n"); + printf(" -info display OpenGL renderer info\n"); +} + + +int +main(int argc, char *argv[]) +{ + const int winWidth = 300, winHeight = 300; + Display *x_dpy; + Window win; + EGLSurface egl_surf; + EGLContext egl_ctx; + EGLDisplay egl_dpy; + char *dpyName = NULL; + GLboolean printInfo = GL_FALSE; + EGLint egl_major, egl_minor; + int i; + const char *s; + + static struct { + char *name; + GLenum value; + enum {GetString, GetInteger} type; + } info_items[] = { + {"GL_RENDERER", GL_RENDERER, GetString}, + {"GL_VERSION", GL_VERSION, GetString}, + {"GL_VENDOR", GL_VENDOR, GetString}, + {"GL_EXTENSIONS", GL_EXTENSIONS, GetString}, + {"GL_MAX_PALETTE_MATRICES_OES", GL_MAX_PALETTE_MATRICES_OES, GetInteger}, + {"GL_MAX_VERTEX_UNITS_OES", GL_MAX_VERTEX_UNITS_OES, GetInteger}, + }; + + for (i = 1; i < argc; i++) { + if (strcmp(argv[i], "-display") == 0) { + dpyName = argv[i+1]; + i++; + } + else if (strcmp(argv[i], "-info") == 0) { + printInfo = GL_TRUE; + } + else { + usage(); + return -1; + } + } + + x_dpy = XOpenDisplay(dpyName); + if (!x_dpy) { + printf("Error: couldn't open display %s\n", + dpyName ? dpyName : getenv("DISPLAY")); + return -1; + } + + egl_dpy = eglGetDisplay(x_dpy); + if (!egl_dpy) { + printf("Error: eglGetDisplay() failed\n"); + return -1; + } + + if (!eglInitialize(egl_dpy, &egl_major, &egl_minor)) { + printf("Error: eglInitialize() failed\n"); + return -1; + } + + s = eglQueryString(egl_dpy, EGL_VERSION); + printf("EGL_VERSION = %s\n", s); + + s = eglQueryString(egl_dpy, EGL_VENDOR); + printf("EGL_VENDOR = %s\n", s); + + s = eglQueryString(egl_dpy, EGL_EXTENSIONS); + printf("EGL_EXTENSIONS = %s\n", s); + + s = eglQueryString(egl_dpy, EGL_CLIENT_APIS); + printf("EGL_CLIENT_APIS = %s\n", s); + + make_x_window(x_dpy, egl_dpy, + "OpenGL ES 1.x tri", 0, 0, winWidth, winHeight, + &win, &egl_ctx, &egl_surf); + + XMapWindow(x_dpy, win); + if (!eglMakeCurrent(egl_dpy, egl_surf, egl_surf, egl_ctx)) { + printf("Error: eglMakeCurrent() failed\n"); + return -1; + } + + if (printInfo) { + for (i = 0; i < sizeof(info_items)/sizeof(info_items[0]); i++) { + switch (info_items[i].type) { + case GetString: + printf("%s = %s\n", info_items[i].name, (char *)glGetString(info_items[i].value)); + break; + case GetInteger: { + GLint rv = -1; + glGetIntegerv(info_items[i].value, &rv); + printf("%s = %d\n", info_items[i].name, rv); + break; + } + } + } + }; + init(); + + /* Set initial projection/viewing transformation. + * We can't be sure we'll get a ConfigureNotify event when the window + * first appears. + */ + reshape(winWidth, winHeight); + + event_loop(x_dpy, win, egl_dpy, egl_surf); + + eglDestroyContext(egl_dpy, egl_ctx); + eglDestroySurface(egl_dpy, egl_surf); + eglTerminate(egl_dpy); + + + XDestroyWindow(x_dpy, win); + XCloseDisplay(x_dpy); + + return 0; +} diff --git a/progs/es1/xegl/two_win.c b/progs/es1/xegl/two_win.c new file mode 100644 index 00000000000..4785e5304d3 --- /dev/null +++ b/progs/es1/xegl/two_win.c @@ -0,0 +1,433 @@ +/* + * Copyright (C) 2008 Brian Paul All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +/* + * Test drawing to two windows. + * Brian Paul + * August 2008 + */ + + +#include <assert.h> +#include <math.h> +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <X11/Xlib.h> +#include <X11/Xutil.h> +#include <X11/keysym.h> +#include <GLES/gl.h> +#include <GLES/glext.h> +#include <EGL/egl.h> + + +static int WinWidth[2] = {150, 300}, WinHeight[2] = {150, 300}; + + +static GLfloat view_rotx = 0.0, view_roty = 0.0, view_rotz = 0.0; + + +/* new window size or exposure */ +static void +reshape(int width, int height) +{ + GLfloat ar = (GLfloat) width / (GLfloat) height; + + glViewport(0, 0, (GLint) width, (GLint) height); + + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); +#ifdef GL_VERSION_ES_CM_1_0 + glFrustumf(-ar, ar, -1, 1, 5.0, 60.0); +#else + glFrustum(-ar, ar, -1, 1, 5.0, 60.0); +#endif + + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + glTranslatef(0.0, 0.0, -10.0); +} + + +static void +draw(int win) +{ + static const GLfloat verts[3][2] = { + { -1, -1 }, + { 1, -1 }, + { 0, 1 } + }; + static const GLfloat colors[3][4] = { + { 1, 0, 0, 1 }, + { 0, 1, 0, 1 }, + { 0, 0, 1, 1 } + }; + + assert(win == 0 || win == 1); + + reshape(WinWidth[win], WinHeight[win]); + + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + glPushMatrix(); + glRotatef(view_rotx, 1, 0, 0); + glRotatef(view_roty, 0, 1, 0); + glRotatef(view_rotz, 0, 0, 1); + + /* draw triangle */ + { + glVertexPointer(2, GL_FLOAT, 0, verts); + glColorPointer(4, GL_FLOAT, 0, colors); + + glEnableClientState(GL_VERTEX_ARRAY); + glEnableClientState(GL_COLOR_ARRAY); + + glDrawArrays(GL_TRIANGLES, 0, 3); + + glDisableClientState(GL_VERTEX_ARRAY); + glDisableClientState(GL_COLOR_ARRAY); + } + + glPopMatrix(); +} + + +static void +init(void) +{ + glClearColor(0.4, 0.4, 0.4, 0.0); +} + + +/* + * Create an RGB, double-buffered X window. + * Return the window and context handles. + */ +static void +make_x_window(Display *x_dpy, EGLDisplay egl_dpy, + const char *name, + int x, int y, int width, int height, + Window *winRet, + EGLContext *ctxRet, + EGLSurface *surfRet) +{ + static const EGLint attribs[] = { + EGL_RED_SIZE, 1, + EGL_GREEN_SIZE, 1, + EGL_BLUE_SIZE, 1, + EGL_DEPTH_SIZE, 1, + EGL_NONE + }; + + int scrnum; + XSetWindowAttributes attr; + unsigned long mask; + Window root; + Window win; + XVisualInfo *visInfo, visTemplate; + int num_visuals; + EGLContext ctx; + EGLConfig config; + EGLint num_configs; + EGLint vid; + + scrnum = DefaultScreen( x_dpy ); + root = RootWindow( x_dpy, scrnum ); + + if (!eglChooseConfig( egl_dpy, attribs, &config, 1, &num_configs)) { + printf("Error: couldn't get an EGL visual config\n"); + exit(1); + } + + assert(config); + assert(num_configs > 0); + + if (!eglGetConfigAttrib(egl_dpy, config, EGL_NATIVE_VISUAL_ID, &vid)) { + printf("Error: eglGetConfigAttrib() failed\n"); + exit(1); + } + + /* The X window visual must match the EGL config */ + visTemplate.visualid = vid; + visInfo = XGetVisualInfo(x_dpy, VisualIDMask, &visTemplate, &num_visuals); + if (!visInfo) { + printf("Error: couldn't get X visual\n"); + exit(1); + } + + /* window attributes */ + attr.background_pixel = 0; + attr.border_pixel = 0; + attr.colormap = XCreateColormap( x_dpy, root, visInfo->visual, AllocNone); + attr.event_mask = StructureNotifyMask | ExposureMask | KeyPressMask; + mask = CWBackPixel | CWBorderPixel | CWColormap | CWEventMask; + + win = XCreateWindow( x_dpy, root, x, y, width, height, + 0, visInfo->depth, InputOutput, + visInfo->visual, mask, &attr ); + + /* set hints and properties */ + { + XSizeHints sizehints; + sizehints.x = x; + sizehints.y = y; + sizehints.width = width; + sizehints.height = height; + sizehints.flags = USSize | USPosition; + XSetNormalHints(x_dpy, win, &sizehints); + XSetStandardProperties(x_dpy, win, name, name, + None, (char **)NULL, 0, &sizehints); + } + +#if USE_FULL_GL + eglBindAPI(EGL_OPENGL_API); +#else + eglBindAPI(EGL_OPENGL_ES_API); +#endif + + if (ctxRet) { + ctx = eglCreateContext(egl_dpy, config, EGL_NO_CONTEXT, NULL ); + if (!ctx) { + printf("Error: eglCreateContext failed\n"); + exit(1); + } + *ctxRet = ctx; + } + + *surfRet = eglCreateWindowSurface(egl_dpy, config, win, NULL); + + if (!*surfRet) { + printf("Error: eglCreateWindowSurface failed\n"); + exit(1); + } + + XFree(visInfo); + + *winRet = win; +} + + +static void +event_loop(Display *dpy, Window win1, Window win2, + EGLDisplay egl_dpy, EGLSurface egl_surf1, EGLSurface egl_surf2, + EGLContext egl_ctx) +{ + while (1) { + int redraw = 0; + int win; + XEvent event; + + XNextEvent(dpy, &event); + + switch (event.type) { + case Expose: + redraw = 1; + break; + case ConfigureNotify: + if (event.xconfigure.window == win1) + win = 0; + else + win = 1; + WinWidth[win] = event.xconfigure.width; + WinHeight[win] = event.xconfigure.height; + break; + case KeyPress: + { + char buffer[10]; + int r, code; + code = XLookupKeysym(&event.xkey, 0); + if (code == XK_Left) { + view_roty += 5.0; + } + else if (code == XK_Right) { + view_roty -= 5.0; + } + else if (code == XK_Up) { + view_rotx += 5.0; + } + else if (code == XK_Down) { + view_rotx -= 5.0; + } + else { + r = XLookupString(&event.xkey, buffer, sizeof(buffer), + NULL, NULL); + if (buffer[0] == 27) { + /* escape */ + return; + } + } + } + redraw = 1; + break; + default: + ; /*no-op*/ + } + + if (redraw) { + /* win 1 */ + if (!eglMakeCurrent(egl_dpy, egl_surf1, egl_surf1, egl_ctx)) { + printf("Error: eglMakeCurrent(1) failed\n"); + return; + } + draw(0); + eglSwapBuffers(egl_dpy, egl_surf1); + + /* win 2 */ + if (!eglMakeCurrent(egl_dpy, egl_surf2, egl_surf2, egl_ctx)) { + printf("Error: eglMakeCurrent(2) failed\n"); + return; + } + draw(1); + eglSwapBuffers(egl_dpy, egl_surf2); + } + } +} + + +static void +usage(void) +{ + printf("Usage:\n"); + printf(" -display <displayname> set the display to run on\n"); + printf(" -info display OpenGL renderer info\n"); +} + + +int +main(int argc, char *argv[]) +{ + Display *x_dpy; + Window win1, win2; + EGLSurface egl_surf1, egl_surf2; + EGLContext egl_ctx; + EGLDisplay egl_dpy; + char *dpyName = NULL; + GLboolean printInfo = GL_FALSE; + EGLint egl_major, egl_minor; + int i; + const char *s; + + static struct { + char *name; + GLenum value; + enum {GetString, GetInteger} type; + } info_items[] = { + {"GL_RENDERER", GL_RENDERER, GetString}, + {"GL_VERSION", GL_VERSION, GetString}, + {"GL_VENDOR", GL_VENDOR, GetString}, + {"GL_EXTENSIONS", GL_EXTENSIONS, GetString}, + {"GL_MAX_PALETTE_MATRICES_OES", GL_MAX_PALETTE_MATRICES_OES, GetInteger}, + {"GL_MAX_VERTEX_UNITS_OES", GL_MAX_VERTEX_UNITS_OES, GetInteger}, + }; + + for (i = 1; i < argc; i++) { + if (strcmp(argv[i], "-display") == 0) { + dpyName = argv[i+1]; + i++; + } + else if (strcmp(argv[i], "-info") == 0) { + printInfo = GL_TRUE; + } + else { + usage(); + return -1; + } + } + + x_dpy = XOpenDisplay(dpyName); + if (!x_dpy) { + printf("Error: couldn't open display %s\n", + dpyName ? dpyName : getenv("DISPLAY")); + return -1; + } + + egl_dpy = eglGetDisplay(x_dpy); + if (!egl_dpy) { + printf("Error: eglGetDisplay() failed\n"); + return -1; + } + + if (!eglInitialize(egl_dpy, &egl_major, &egl_minor)) { + printf("Error: eglInitialize() failed\n"); + return -1; + } + + s = eglQueryString(egl_dpy, EGL_VERSION); + printf("EGL_VERSION = %s\n", s); + + s = eglQueryString(egl_dpy, EGL_VENDOR); + printf("EGL_VENDOR = %s\n", s); + + s = eglQueryString(egl_dpy, EGL_EXTENSIONS); + printf("EGL_EXTENSIONS = %s\n", s); + + s = eglQueryString(egl_dpy, EGL_CLIENT_APIS); + printf("EGL_CLIENT_APIS = %s\n", s); + + make_x_window(x_dpy, egl_dpy, + "xegl_two_win #1", 0, 0, WinWidth[0], WinHeight[0], + &win1, &egl_ctx, &egl_surf1); + + make_x_window(x_dpy, egl_dpy, + "xegl_two_win #2", WinWidth[0] + 50, 0, + WinWidth[1], WinHeight[1], + &win2, NULL, &egl_surf2); + + XMapWindow(x_dpy, win1); + + XMapWindow(x_dpy, win2); + + if (!eglMakeCurrent(egl_dpy, egl_surf1, egl_surf1, egl_ctx)) { + printf("Error: eglMakeCurrent() failed\n"); + return -1; + } + + if (printInfo) { + for (i = 0; i < sizeof(info_items)/sizeof(info_items[0]); i++) { + switch (info_items[i].type) { + case GetString: + printf("%s = %s\n", info_items[i].name, (char *)glGetString(info_items[i].value)); + break; + case GetInteger: { + GLint rv = -1; + glGetIntegerv(info_items[i].value, &rv); + printf("%s = %d\n", info_items[i].name, rv); + break; + } + } + } + }; + + init(); + + event_loop(x_dpy, win1, win2, egl_dpy, egl_surf1, egl_surf2, egl_ctx); + + eglDestroyContext(egl_dpy, egl_ctx); + eglDestroySurface(egl_dpy, egl_surf1); + eglDestroySurface(egl_dpy, egl_surf2); + eglTerminate(egl_dpy); + + XDestroyWindow(x_dpy, win1); + XDestroyWindow(x_dpy, win2); + XCloseDisplay(x_dpy); + + return 0; +} diff --git a/progs/es2/.gitignore b/progs/es2/.gitignore new file mode 100644 index 00000000000..7d5c16936c2 --- /dev/null +++ b/progs/es2/.gitignore @@ -0,0 +1,3 @@ +xegl/es2_info.c +xegl/es2_info +xegl/tri diff --git a/progs/es2/xegl/Makefile b/progs/es2/xegl/Makefile new file mode 100644 index 00000000000..5bb167c1c63 --- /dev/null +++ b/progs/es2/xegl/Makefile @@ -0,0 +1,51 @@ +# progs/es2/xegl/Makefile + +TOP = ../../.. +include $(TOP)/configs/current + + +INCLUDE_DIRS = \ + -I$(TOP)/include \ + +HEADERS = $(TOP)/include/GLES/egl.h + + +ES2_LIB_DEPS = \ + $(TOP)/$(LIB_DIR)/libEGL.so \ + $(TOP)/$(LIB_DIR)/libGLESv2.so + + +ES2_LIBS = \ + -L$(TOP)/$(LIB_DIR) -lEGL \ + -L$(TOP)/$(LIB_DIR) -lGLESv2 $(LIBDRM_LIB) -lX11 + +PROGRAMS = \ + es2_info \ + tri + + +.c.o: + $(CC) -c $(INCLUDE_DIRS) $(CFLAGS) $< -o $@ + + + +default: $(PROGRAMS) + + + +es2_info.c: ../../es1/xegl/es1_info.c + cp -f $^ $@ + +es2_info: es2_info.o $(ES2_LIB_DEPS) + $(CC) $(CFLAGS) es2_info.o $(ES2_LIBS) -o $@ + +tri: tri.o $(ES2_LIB_DEPS) + $(CC) $(CFLAGS) tri.o $(ES2_LIBS) -o $@ + + + +clean: + rm -f *.o *~ + rm -f $(PROGRAMS) + rm -f es2_info.c + diff --git a/progs/es2/xegl/tri.c b/progs/es2/xegl/tri.c new file mode 100644 index 00000000000..8981d8a7e21 --- /dev/null +++ b/progs/es2/xegl/tri.c @@ -0,0 +1,516 @@ +/************************************************************************** + * + * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + **************************************************************************/ + +/* + * Draw a triangle with X/EGL and OpenGL ES 2.x + */ + +#define USE_FULL_GL 0 + + + +#include <assert.h> +#include <math.h> +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <X11/Xlib.h> +#include <X11/Xutil.h> +#include <X11/keysym.h> +#if USE_FULL_GL +#include <GL/gl.h> /* use full OpenGL */ +#else +#include <GLES2/gl2.h> /* use OpenGL ES 2.x */ +#endif +#include <EGL/egl.h> + + +#define FLOAT_TO_FIXED(X) ((X) * 65535.0) + + + +static GLfloat view_rotx = 0.0, view_roty = 0.0; + +static GLint u_matrix = -1; +static GLint attr_pos = 0, attr_color = 1; + + +static void +make_z_rot_matrix(GLfloat angle, GLfloat *m) +{ + float c = cos(angle * M_PI / 180.0); + float s = sin(angle * M_PI / 180.0); + int i; + for (i = 0; i < 16; i++) + m[i] = 0.0; + m[0] = m[5] = m[10] = m[15] = 1.0; + + m[0] = c; + m[1] = s; + m[4] = -s; + m[5] = c; +} + +static void +make_scale_matrix(GLfloat xs, GLfloat ys, GLfloat zs, GLfloat *m) +{ + int i; + for (i = 0; i < 16; i++) + m[i] = 0.0; + m[0] = xs; + m[5] = ys; + m[10] = zs; + m[15] = 1.0; +} + + +static void +mul_matrix(GLfloat *prod, const GLfloat *a, const GLfloat *b) +{ +#define A(row,col) a[(col<<2)+row] +#define B(row,col) b[(col<<2)+row] +#define P(row,col) p[(col<<2)+row] + GLfloat p[16]; + GLint i; + for (i = 0; i < 4; i++) { + const GLfloat ai0=A(i,0), ai1=A(i,1), ai2=A(i,2), ai3=A(i,3); + P(i,0) = ai0 * B(0,0) + ai1 * B(1,0) + ai2 * B(2,0) + ai3 * B(3,0); + P(i,1) = ai0 * B(0,1) + ai1 * B(1,1) + ai2 * B(2,1) + ai3 * B(3,1); + P(i,2) = ai0 * B(0,2) + ai1 * B(1,2) + ai2 * B(2,2) + ai3 * B(3,2); + P(i,3) = ai0 * B(0,3) + ai1 * B(1,3) + ai2 * B(2,3) + ai3 * B(3,3); + } + memcpy(prod, p, sizeof(p)); +#undef A +#undef B +#undef PROD +} + + +static void +draw(void) +{ + static const GLfloat verts[3][2] = { + { -1, -1 }, + { 1, -1 }, + { 0, 1 } + }; + static const GLfloat colors[3][3] = { + { 1, 0, 0 }, + { 0, 1, 0 }, + { 0, 0, 1 } + }; + GLfloat mat[16], rot[16], scale[16]; + + /* Set modelview/projection matrix */ + make_z_rot_matrix(view_rotx, rot); + make_scale_matrix(0.5, 0.5, 0.5, scale); + mul_matrix(mat, rot, scale); + glUniformMatrix4fv(u_matrix, 1, GL_FALSE, mat); + + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + { + glVertexAttribPointer(attr_pos, 2, GL_FLOAT, GL_FALSE, 0, verts); + glVertexAttribPointer(attr_color, 3, GL_FLOAT, GL_FALSE, 0, colors); + glEnableVertexAttribArray(attr_pos); + glEnableVertexAttribArray(attr_color); + + glDrawArrays(GL_TRIANGLES, 0, 3); + + glDisableVertexAttribArray(attr_pos); + glDisableVertexAttribArray(attr_color); + } +} + + +/* new window size or exposure */ +static void +reshape(int width, int height) +{ + glViewport(0, 0, (GLint) width, (GLint) height); +} + + +static void +create_shaders(void) +{ + static const char *fragShaderText = + "varying vec4 v_color;\n" + "void main() {\n" + " gl_FragColor = v_color;\n" + "}\n"; + static const char *vertShaderText = + "uniform mat4 modelviewProjection;\n" + "attribute vec4 pos;\n" + "attribute vec4 color;\n" + "varying vec4 v_color;\n" + "void main() {\n" + " gl_Position = modelviewProjection * pos;\n" + " v_color = color;\n" + "}\n"; + + GLuint fragShader, vertShader, program; + GLint stat; + + fragShader = glCreateShader(GL_FRAGMENT_SHADER); + glShaderSource(fragShader, 1, (const char **) &fragShaderText, NULL); + glCompileShader(fragShader); + glGetShaderiv(fragShader, GL_COMPILE_STATUS, &stat); + if (!stat) { + printf("Error: fragment shader did not compile!\n"); + exit(1); + } + + vertShader = glCreateShader(GL_VERTEX_SHADER); + glShaderSource(vertShader, 1, (const char **) &vertShaderText, NULL); + glCompileShader(vertShader); + glGetShaderiv(vertShader, GL_COMPILE_STATUS, &stat); + if (!stat) { + printf("Error: vertex shader did not compile!\n"); + exit(1); + } + + program = glCreateProgram(); + glAttachShader(program, fragShader); + glAttachShader(program, vertShader); + glLinkProgram(program); + + glGetProgramiv(program, GL_LINK_STATUS, &stat); + if (!stat) { + char log[1000]; + GLsizei len; + glGetProgramInfoLog(program, 1000, &len, log); + printf("Error: linking:\n%s\n", log); + exit(1); + } + + glUseProgram(program); + + if (1) { + /* test setting attrib locations */ + glBindAttribLocation(program, attr_pos, "pos"); + glBindAttribLocation(program, attr_color, "color"); + glLinkProgram(program); /* needed to put attribs into effect */ + } + else { + /* test automatic attrib locations */ + attr_pos = glGetAttribLocation(program, "pos"); + attr_color = glGetAttribLocation(program, "color"); + } + + u_matrix = glGetUniformLocation(program, "modelviewProjection"); + printf("Uniform modelviewProjection at %d\n", u_matrix); + printf("Attrib pos at %d\n", attr_pos); + printf("Attrib color at %d\n", attr_color); +} + + +static void +init(void) +{ + typedef void (*proc)(); + +#if 1 /* test code */ + proc p = eglGetProcAddress("glMapBufferOES"); + assert(p); +#endif + + glClearColor(0.4, 0.4, 0.4, 0.0); + + create_shaders(); +} + + +/* + * Create an RGB, double-buffered X window. + * Return the window and context handles. + */ +static void +make_x_window(Display *x_dpy, EGLDisplay egl_dpy, + const char *name, + int x, int y, int width, int height, + Window *winRet, + EGLContext *ctxRet, + EGLSurface *surfRet) +{ + static const EGLint attribs[] = { + EGL_RED_SIZE, 1, + EGL_GREEN_SIZE, 1, + EGL_BLUE_SIZE, 1, + EGL_DEPTH_SIZE, 1, + EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, + EGL_NONE + }; + static const EGLint ctx_attribs[] = { + EGL_CONTEXT_CLIENT_VERSION, 2, + EGL_NONE + }; + int scrnum; + XSetWindowAttributes attr; + unsigned long mask; + Window root; + Window win; + XVisualInfo *visInfo, visTemplate; + int num_visuals; + EGLContext ctx; + EGLConfig config; + EGLint num_configs; + EGLint vid; + + scrnum = DefaultScreen( x_dpy ); + root = RootWindow( x_dpy, scrnum ); + + if (!eglChooseConfig( egl_dpy, attribs, &config, 1, &num_configs)) { + printf("Error: couldn't get an EGL visual config\n"); + exit(1); + } + + assert(config); + assert(num_configs > 0); + + if (!eglGetConfigAttrib(egl_dpy, config, EGL_NATIVE_VISUAL_ID, &vid)) { + printf("Error: eglGetConfigAttrib() failed\n"); + exit(1); + } + + /* The X window visual must match the EGL config */ + visTemplate.visualid = vid; + visInfo = XGetVisualInfo(x_dpy, VisualIDMask, &visTemplate, &num_visuals); + if (!visInfo) { + printf("Error: couldn't get X visual\n"); + exit(1); + } + + /* window attributes */ + attr.background_pixel = 0; + attr.border_pixel = 0; + attr.colormap = XCreateColormap( x_dpy, root, visInfo->visual, AllocNone); + attr.event_mask = StructureNotifyMask | ExposureMask | KeyPressMask; + mask = CWBackPixel | CWBorderPixel | CWColormap | CWEventMask; + + win = XCreateWindow( x_dpy, root, 0, 0, width, height, + 0, visInfo->depth, InputOutput, + visInfo->visual, mask, &attr ); + + /* set hints and properties */ + { + XSizeHints sizehints; + sizehints.x = x; + sizehints.y = y; + sizehints.width = width; + sizehints.height = height; + sizehints.flags = USSize | USPosition; + XSetNormalHints(x_dpy, win, &sizehints); + XSetStandardProperties(x_dpy, win, name, name, + None, (char **)NULL, 0, &sizehints); + } + +#if USE_FULL_GL /* XXX fix this when eglBindAPI() works */ + eglBindAPI(EGL_OPENGL_API); +#else + eglBindAPI(EGL_OPENGL_ES_API); +#endif + + ctx = eglCreateContext(egl_dpy, config, EGL_NO_CONTEXT, ctx_attribs ); + if (!ctx) { + printf("Error: eglCreateContext failed\n"); + exit(1); + } + + /* test eglQueryContext() */ + { + EGLint val; + eglQueryContext(egl_dpy, ctx, EGL_CONTEXT_CLIENT_VERSION, &val); + assert(val == 2); + } + + *surfRet = eglCreateWindowSurface(egl_dpy, config, win, NULL); + if (!*surfRet) { + printf("Error: eglCreateWindowSurface failed\n"); + exit(1); + } + + /* sanity checks */ + { + EGLint val; + eglQuerySurface(egl_dpy, *surfRet, EGL_WIDTH, &val); + assert(val == width); + eglQuerySurface(egl_dpy, *surfRet, EGL_HEIGHT, &val); + assert(val == height); + assert(eglGetConfigAttrib(egl_dpy, config, EGL_SURFACE_TYPE, &val)); + assert(val & EGL_WINDOW_BIT); + } + + XFree(visInfo); + + *winRet = win; + *ctxRet = ctx; +} + + +static void +event_loop(Display *dpy, Window win, + EGLDisplay egl_dpy, EGLSurface egl_surf) +{ + while (1) { + int redraw = 0; + XEvent event; + + XNextEvent(dpy, &event); + + switch (event.type) { + case Expose: + redraw = 1; + break; + case ConfigureNotify: + reshape(event.xconfigure.width, event.xconfigure.height); + break; + case KeyPress: + { + char buffer[10]; + int r, code; + code = XLookupKeysym(&event.xkey, 0); + if (code == XK_Left) { + view_roty += 5.0; + } + else if (code == XK_Right) { + view_roty -= 5.0; + } + else if (code == XK_Up) { + view_rotx += 5.0; + } + else if (code == XK_Down) { + view_rotx -= 5.0; + } + else { + r = XLookupString(&event.xkey, buffer, sizeof(buffer), + NULL, NULL); + if (buffer[0] == 27) { + /* escape */ + return; + } + } + } + redraw = 1; + break; + default: + ; /*no-op*/ + } + + if (redraw) { + draw(); + eglSwapBuffers(egl_dpy, egl_surf); + } + } +} + + +static void +usage(void) +{ + printf("Usage:\n"); + printf(" -display <displayname> set the display to run on\n"); + printf(" -info display OpenGL renderer info\n"); +} + + +int +main(int argc, char *argv[]) +{ + const int winWidth = 300, winHeight = 300; + Display *x_dpy; + Window win; + EGLSurface egl_surf; + EGLContext egl_ctx; + EGLDisplay egl_dpy; + char *dpyName = NULL; + GLboolean printInfo = GL_FALSE; + EGLint egl_major, egl_minor; + int i; + const char *s; + + for (i = 1; i < argc; i++) { + if (strcmp(argv[i], "-display") == 0) { + dpyName = argv[i+1]; + i++; + } + else if (strcmp(argv[i], "-info") == 0) { + printInfo = GL_TRUE; + } + else { + usage(); + return -1; + } + } + + x_dpy = XOpenDisplay(dpyName); + if (!x_dpy) { + printf("Error: couldn't open display %s\n", + dpyName ? dpyName : getenv("DISPLAY")); + return -1; + } + + egl_dpy = eglGetDisplay(x_dpy); + if (!egl_dpy) { + printf("Error: eglGetDisplay() failed\n"); + return -1; + } + + if (!eglInitialize(egl_dpy, &egl_major, &egl_minor)) { + printf("Error: eglInitialize() failed\n"); + return -1; + } + + s = eglQueryString(egl_dpy, EGL_VERSION); + printf("EGL_VERSION = %s\n", s); + + s = eglQueryString(egl_dpy, EGL_VENDOR); + printf("EGL_VENDOR = %s\n", s); + + s = eglQueryString(egl_dpy, EGL_EXTENSIONS); + printf("EGL_EXTENSIONS = %s\n", s); + + s = eglQueryString(egl_dpy, EGL_CLIENT_APIS); + printf("EGL_CLIENT_APIS = %s\n", s); + + make_x_window(x_dpy, egl_dpy, + "OpenGL ES 2.x tri", 0, 0, winWidth, winHeight, + &win, &egl_ctx, &egl_surf); + + XMapWindow(x_dpy, win); + if (!eglMakeCurrent(egl_dpy, egl_surf, egl_surf, egl_ctx)) { + printf("Error: eglMakeCurrent() failed\n"); + return -1; + } + + if (printInfo) { + printf("GL_RENDERER = %s\n", (char *) glGetString(GL_RENDERER)); + printf("GL_VERSION = %s\n", (char *) glGetString(GL_VERSION)); + printf("GL_VENDOR = %s\n", (char *) glGetString(GL_VENDOR)); + printf("GL_EXTENSIONS = %s\n", (char *) glGetString(GL_EXTENSIONS)); + } + + init(); + + /* Set initial projection/viewing transformation. + * We can't be sure we'll get a ConfigureNotify event when the window + * first appears. + */ + reshape(winWidth, winHeight); + + event_loop(x_dpy, win, egl_dpy, egl_surf); + + eglDestroyContext(egl_dpy, egl_ctx); + eglDestroySurface(egl_dpy, egl_surf); + eglTerminate(egl_dpy); + + + XDestroyWindow(x_dpy, win); + XCloseDisplay(x_dpy); + + return 0; +} diff --git a/progs/fp/position-frc-integer.txt b/progs/fp/position-frc-integer.txt new file mode 100644 index 00000000000..3a634c9b3b8 --- /dev/null +++ b/progs/fp/position-frc-integer.txt @@ -0,0 +1,7 @@ +!!ARBfp1.0 +# expected: black triangle +# brown means the wrong pixel center convention is being used +OPTION ARB_fragment_coord_pixel_center_integer; +MOV result.color, {0}.x; +FRC result.color.xy, fragment.position; +END diff --git a/progs/fp/position-frc.txt b/progs/fp/position-frc.txt new file mode 100644 index 00000000000..35ae3efa10e --- /dev/null +++ b/progs/fp/position-frc.txt @@ -0,0 +1,6 @@ +!!ARBfp1.0 +# expected: brown triangle +# black means the wrong pixel center convention is being used +MOV result.color, {0}.x; +FRC result.color.xy, fragment.position; +END diff --git a/progs/fp/position-upper-left.txt b/progs/fp/position-upper-left.txt new file mode 100644 index 00000000000..ac632dbfb7d --- /dev/null +++ b/progs/fp/position-upper-left.txt @@ -0,0 +1,7 @@ +!!ARBfp1.0 +# expected: the yellow vertex is the bottom one +# if it is the top one, the wrong origin convention is being used +OPTION ARB_fragment_coord_origin_upper_left; +MOV result.color, {0}.x; +MUL result.color.xy, fragment.position, {.005}.x; +END diff --git a/progs/fp/position.txt b/progs/fp/position.txt index 1875897d781..f59d0259c72 100644 --- a/progs/fp/position.txt +++ b/progs/fp/position.txt @@ -1,4 +1,6 @@ !!ARBfp1.0 +# expected: the yellow vertex is the top one +# if it is the bottom one, the wrong origin convention is being used MOV result.color, {0}.x; MUL result.color.xy, fragment.position, {.005}.x; END diff --git a/progs/fpglsl/.gitignore b/progs/fpglsl/.gitignore new file mode 100644 index 00000000000..9fe73ab0678 --- /dev/null +++ b/progs/fpglsl/.gitignore @@ -0,0 +1 @@ +fp-tri diff --git a/progs/fpglsl/Makefile b/progs/fpglsl/Makefile new file mode 100644 index 00000000000..3bf14b4b709 --- /dev/null +++ b/progs/fpglsl/Makefile @@ -0,0 +1,52 @@ +# progs/tests/Makefile + + +# These programs aren't intended to be included with the normal distro. +# They're not too interesting but they're good for testing. + +TOP = ../.. +include $(TOP)/configs/current + +LIBS = -L$(TOP)/$(LIB_DIR) -l$(GLUT_LIB) -l$(GLEW_LIB) -l$(GLU_LIB) -l$(GL_LIB) $(APP_LIB_DEPS) + +SOURCES = \ + fp-tri.c + + + +PROGS = $(SOURCES:%.c=%) + +INCLUDES = -I. -I$(TOP)/include -I../samples + + +##### RULES ##### + +.SUFFIXES: +.SUFFIXES: .c + +.c: + $(CC) $(INCLUDES) $(CFLAGS) $< $(LIBS) -o $@ + +.c.o: + $(CC) -c $(INCLUDES) $(CFLAGS) $(DEFINES) $< -o $@ + +.S.o: + $(CC) -c $(INCLUDES) $(CFLAGS) $(DEFINES) $< -o $@ + + +##### TARGETS ##### + +default: $(PROGS) + +clean: + rm -f $(PROGS) + rm -f *.o + rm -f getproclist.h + + + + + +# Emacs tags +tags: + etags `find . -name \*.[ch]` `find ../include` diff --git a/progs/fpglsl/SConscript b/progs/fpglsl/SConscript new file mode 100644 index 00000000000..e31fa320238 --- /dev/null +++ b/progs/fpglsl/SConscript @@ -0,0 +1,13 @@ +Import('env') + +if not env['GLUT']: + Return() + +env = env.Clone() + +env.Prepend(LIBS = ['$GLUT_LIB']) + +env.Program( + target = 'fp-tri', + source = ['fp-tri.c'], + ) diff --git a/progs/fpglsl/fp-tri.c b/progs/fpglsl/fp-tri.c new file mode 100644 index 00000000000..c9b08fbbad7 --- /dev/null +++ b/progs/fpglsl/fp-tri.c @@ -0,0 +1,415 @@ + +#include <stdio.h> +#include <string.h> +#include <stdlib.h> + +#ifndef WIN32 +#include <unistd.h> +#include <signal.h> +#endif + +#include <GL/glew.h> +#include <GL/glut.h> + +#include "readtex.c" + + +#define TEXTURE_FILE "../images/bw.rgb" + +unsigned show_fps = 0; +unsigned int frame_cnt = 0; +void alarmhandler(int); +static const char *filename = NULL; + +static GLuint fragShader; +static GLuint vertShader; +static GLuint program; + + +static void usage(char *name) +{ + fprintf(stderr, "usage: %s [ options ] shader_filename\n", name); +#ifndef WIN32 + fprintf(stderr, "\n" ); + fprintf(stderr, "options:\n"); + fprintf(stderr, " -fps show frames per second\n"); +#endif +} + +#ifndef WIN32 +void alarmhandler (int sig) +{ + if (sig == SIGALRM) { + printf("%d frames in 5.0 seconds = %.3f FPS\n", frame_cnt, + frame_cnt / 5.0); + + frame_cnt = 0; + } + signal(SIGALRM, alarmhandler); + alarm(5); +} +#endif + + + + +static void load_and_compile_shader(GLuint shader, const char *text) +{ + GLint stat; + + glShaderSource(shader, 1, (const GLchar **) &text, NULL); + + glCompileShader(shader); + + glGetShaderiv(shader, GL_COMPILE_STATUS, &stat); + if (!stat) { + GLchar log[1000]; + GLsizei len; + glGetShaderInfoLog(shader, 1000, &len, log); + fprintf(stderr, "fp-tri: problem compiling shader:\n%s\n", log); + exit(1); + } +} + +static void read_shader(GLuint shader, const char *filename) +{ + const int max = 100*1000; + int n; + char *buffer = (char*) malloc(max); + FILE *f = fopen(filename, "r"); + if (!f) { + fprintf(stderr, "fp-tri: Unable to open shader file %s\n", filename); + exit(1); + } + + n = fread(buffer, 1, max, f); + printf("fp-tri: read %d bytes from shader file %s\n", n, filename); + if (n > 0) { + buffer[n] = 0; + load_and_compile_shader(shader, buffer); + } + + fclose(f); + free(buffer); +} + +static void check_link(GLuint prog) +{ + GLint stat; + glGetProgramiv(prog, GL_LINK_STATUS, &stat); + if (!stat) { + GLchar log[1000]; + GLsizei len; + glGetProgramInfoLog(prog, 1000, &len, log); + fprintf(stderr, "Linker error:\n%s\n", log); + } +} + +static void setup_uniforms() +{ + { + GLint loc1f = glGetUniformLocationARB(program, "Offset1f"); + GLint loc2f = glGetUniformLocationARB(program, "Offset2f"); + GLint loc4f = glGetUniformLocationARB(program, "Offset4f"); + GLfloat vecKer[] = + { 1.0, 0.0, 0.0, 1.0, + 0.0, 1.0, 0.0, 1.0, + 1.0, 0.0, 0.0, 1.0, + 0.0, 0.0, 0.0, 1.0 + }; + if (loc1f >= 0) + glUniform1fv(loc1f, 16, vecKer); + + if (loc2f >= 0) + glUniform2fv(loc2f, 8, vecKer); + + if (loc4f >= 0) + glUniform4fv(loc4f, 4, vecKer); + + } + + { + GLint loc1f = glGetUniformLocationARB(program, "KernelValue1f"); + GLint loc2f = glGetUniformLocationARB(program, "KernelValue2f"); + GLint loc4f = glGetUniformLocationARB(program, "KernelValue4f"); + GLfloat vecKer[] = + { 1.0, 0.0, 0.0, 0.25, + 0.0, 1.0, 0.0, 0.25, + 0.0, 0.0, 1.0, 0.25, + 0.0, 0.0, 0.0, 0.25, + 0.5, 0.0, 0.0, 0.35, + 0.0, 0.5, 0.0, 0.35, + 0.0, 0.0, 0.5, 0.35, + 0.0, 0.0, 0.0, 0.35 + }; + if (loc1f >= 0) + glUniform1fv(loc1f, 16, vecKer); + + if (loc2f >= 0) + glUniform2fv(loc2f, 8, vecKer); + + if (loc4f >= 0) + glUniform4fv(loc4f, 4, vecKer); + } +} + +static void prepare_shaders() +{ + static const char *fragShaderText = + "void main() {\n" + " gl_FragColor = gl_Color;\n" + "}\n"; + static const char *vertShaderText = + "void main() {\n" + " gl_FrontColor = gl_Color;\n" + " gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;\n" + "}\n"; + fragShader = glCreateShader(GL_FRAGMENT_SHADER); + if (filename) + read_shader(fragShader, filename); + else + load_and_compile_shader(fragShader, fragShaderText); + + + vertShader = glCreateShader(GL_VERTEX_SHADER); + load_and_compile_shader(vertShader, vertShaderText); + + program = glCreateProgram(); + glAttachShader(program, fragShader); + glAttachShader(program, vertShader); + glLinkProgram(program); + check_link(program); + glUseProgram(program); + + setup_uniforms(); +} + +#define LEVELS 8 +#define SIZE (1<<LEVELS) +static int TexWidth = SIZE, TexHeight = SIZE; + + +static void +ResetTextureLevel( int i ) +{ + GLubyte tex2d[SIZE*SIZE][4]; + + { + GLint Width = TexWidth / (1 << i); + GLint Height = TexHeight / (1 << i); + GLint s, t; + + for (s = 0; s < Width; s++) { + for (t = 0; t < Height; t++) { + tex2d[t*Width+s][0] = ((s / 16) % 2) ? 0 : 255; + tex2d[t*Width+s][1] = ((t / 16) % 2) ? 0 : 255; + tex2d[t*Width+s][2] = 128; + tex2d[t*Width+s][3] = 255; + } + } + + glPixelStorei(GL_UNPACK_ALIGNMENT, 1); + + glTexImage2D(GL_TEXTURE_2D, i, GL_RGB, Width, Height, 0, + GL_RGBA, GL_UNSIGNED_BYTE, tex2d); + } +} + + +static void +ResetTexture( void ) +{ + int i; + + for (i = 0; i <= LEVELS; i++) + { + ResetTextureLevel(i); + } +} + +static void Init( void ) +{ + GLuint Texture; + + /* Load texture */ + glGenTextures(1, &Texture); + glBindTexture(GL_TEXTURE_2D, Texture); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glPixelStorei(GL_UNPACK_ALIGNMENT, 1); + if (!LoadRGBMipmaps(TEXTURE_FILE, GL_RGB)) { + printf("Error: couldn't load texture image file %s\n", TEXTURE_FILE); + exit(1); + } + + + glGenTextures(1, &Texture); + glActiveTextureARB(GL_TEXTURE0_ARB + 1); + glBindTexture(GL_TEXTURE_2D, Texture); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glPixelStorei(GL_UNPACK_ALIGNMENT, 1); + + { + GLubyte data[32][32]; + int width = 32; + int height = 32; + int i; + int j; + + for (i = 0; i < 32; i++) + for (j = 0; j < 32; j++) + { + /** + ** +-----------+ + ** | W | + ** | +-----+ | + ** | | | | + ** | | B | | + ** | | | | + ** | +-----+ | + ** | | + ** +-----------+ + **/ + int i2 = i - height / 2; + int j2 = j - width / 2; + int h8 = height / 8; + int w8 = width / 8; + if ( -h8 <= i2 && i2 <= h8 && -w8 <= j2 && j2 <= w8 ) { + data[i][j] = 0x00; + } else if ( -2 * h8 <= i2 && i2 <= 2 * h8 && -2 * w8 <= j2 && j2 <= 2 * w8 ) { + data[i][j] = 0x55; + } else if ( -3 * h8 <= i2 && i2 <= 3 * h8 && -3 * w8 <= j2 && j2 <= 3 * w8 ) { + data[i][j] = 0xaa; + } else { + data[i][j] = 0xff; + } + } + + glTexImage2D( GL_TEXTURE_2D, 0, + GL_ALPHA8, + 32, 32, 0, + GL_ALPHA, GL_UNSIGNED_BYTE, data ); + } + + glGenTextures(1, &Texture); + glActiveTextureARB(GL_TEXTURE0_ARB + 2); + glBindTexture(GL_TEXTURE_2D, Texture); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glPixelStorei(GL_UNPACK_ALIGNMENT, 1); + ResetTexture(); + + glClearColor(.1, .3, .5, 0); +} + + + + +static void args(int argc, char *argv[]) +{ + GLint i; + + for (i = 1; i < argc; i++) { + if (strcmp(argv[i], "-fps") == 0) { + show_fps = 1; + } + else if (i == argc - 1) { + filename = argv[i]; + } + else { + usage(argv[0]); + exit(1); + } + } +} + + + + + +static void Reshape(int width, int height) +{ + + glViewport(0, 0, (GLint)width, (GLint)height); + + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + glOrtho(-1.0, 1.0, -1.0, 1.0, -0.5, 1000.0); + glMatrixMode(GL_MODELVIEW); +} + +static void CleanUp(void) +{ + glDeleteShader(fragShader); + glDeleteShader(vertShader); + glDeleteProgram(program); +} + +static void Key(unsigned char key, int x, int y) +{ + + switch (key) { + case 27: + CleanUp(); + exit(1); + default: + break; + } + + glutPostRedisplay(); +} + +static void Display(void) +{ + glClear(GL_COLOR_BUFFER_BIT); + + glUseProgram(program); + glProgramLocalParameter4fARB(GL_FRAGMENT_PROGRAM_ARB, 0, 1.0, 1.0, 0.0, 0.0); + glProgramLocalParameter4fARB(GL_FRAGMENT_PROGRAM_ARB, 1, 0.0, 0.0, 1.0, 1.0); + glBegin(GL_TRIANGLES); + + glColor3f(0,0,1); + glTexCoord3f(1,1,0); + glVertex3f( 0.9, -0.9, -30.0); + + glColor3f(1,0,0); + glTexCoord3f(1,-1,0); + glVertex3f( 0.9, 0.9, -30.0); + + glColor3f(0,1,0); + glTexCoord3f(-1,0,0); + glVertex3f(-0.9, 0.0, -30.0); + glEnd(); + + glFlush(); + if (show_fps) { + ++frame_cnt; + glutPostRedisplay(); + } +} + + +int main(int argc, char **argv) +{ + glutInit(&argc, argv); + glutInitWindowPosition(0, 0); + glutInitWindowSize(250, 250); + glutInitDisplayMode(GLUT_RGB | GLUT_SINGLE | GLUT_DEPTH); + args(argc, argv); + glutCreateWindow(filename ? filename : "fp-tri"); + glewInit(); + glutReshapeFunc(Reshape); + glutKeyboardFunc(Key); + glutDisplayFunc(Display); + prepare_shaders(); + Init(); +#ifndef WIN32 + if (show_fps) { + signal(SIGALRM, alarmhandler); + alarm(5); + } +#endif + glutMainLoop(); + return 0; +} diff --git a/progs/fpglsl/mov-imm.glsl b/progs/fpglsl/mov-imm.glsl new file mode 100644 index 00000000000..cbb75ce342c --- /dev/null +++ b/progs/fpglsl/mov-imm.glsl @@ -0,0 +1,3 @@ +void main() { + gl_FragColor = vec4(1,0,1,1); +} diff --git a/progs/fpglsl/mov.glsl b/progs/fpglsl/mov.glsl new file mode 100644 index 00000000000..4a1f185ba44 --- /dev/null +++ b/progs/fpglsl/mov.glsl @@ -0,0 +1,3 @@ +void main() { + gl_FragColor = gl_Color; +} diff --git a/progs/fpglsl/tex-multi.glsl b/progs/fpglsl/tex-multi.glsl new file mode 100644 index 00000000000..5220b7efaf2 --- /dev/null +++ b/progs/fpglsl/tex-multi.glsl @@ -0,0 +1,15 @@ +// Multi-texture fragment shader +// Brian Paul + +// Composite second texture over first. +// We're assuming the 2nd texture has a meaningful alpha channel. + +uniform sampler2D tex1; +uniform sampler2D tex2; + +void main() +{ + vec4 t1 = texture2D(tex1, gl_Color.xy); + vec4 t2 = texture2D(tex2, gl_Color.yz); + gl_FragColor = mix(t1, t2, t2.w); +} diff --git a/progs/fpglsl/tex.glsl b/progs/fpglsl/tex.glsl new file mode 100644 index 00000000000..4302fabe2d5 --- /dev/null +++ b/progs/fpglsl/tex.glsl @@ -0,0 +1,6 @@ +uniform sampler2D tex1; + +void main() +{ + gl_FragColor = texture2D(tex1, gl_Color.xy); +} diff --git a/progs/glsl/CH11-bumpmaptex.frag b/progs/glsl/CH11-bumpmaptex.frag index b1f93b784d9..b5dabb4c8a8 100644 --- a/progs/glsl/CH11-bumpmaptex.frag +++ b/progs/glsl/CH11-bumpmaptex.frag @@ -17,7 +17,7 @@ uniform float BumpDensity; // = 16.0 uniform float BumpSize; // = 0.15 uniform float SpecularFactor; // = 0.5 -sampler2D Tex; +uniform sampler2D Tex; void main() { diff --git a/progs/glsl/bump.c b/progs/glsl/bump.c index e31afab9392..784596448c5 100644 --- a/progs/glsl/bump.c +++ b/progs/glsl/bump.c @@ -51,7 +51,6 @@ static GLint win = 0; static GLfloat xRot = 20.0f, yRot = 0.0f, zRot = 0.0f; static GLint tangentAttrib; -static GLint tangentAttribTex; static GLuint Texture; diff --git a/progs/glsl/convolutions.c b/progs/glsl/convolutions.c index 350e61bbdc5..fdfaf568a25 100644 --- a/progs/glsl/convolutions.c +++ b/progs/glsl/convolutions.c @@ -182,7 +182,7 @@ static void fillConvolution(GLint *k, static void setupConvolution() { GLint *kernel = (GLint*)malloc(sizeof(GLint) * 9); - GLfloat scale; + GLfloat scale = 0.0; GLfloat *vecKer = (GLfloat*)malloc(sizeof(GLfloat) * 9 * 4); GLuint loc; GLuint i; diff --git a/progs/glsl/samplers.c b/progs/glsl/samplers.c index 87dad5d8575..8f26a5e329d 100644 --- a/progs/glsl/samplers.c +++ b/progs/glsl/samplers.c @@ -41,7 +41,6 @@ #include <string.h> #include <GL/glew.h> #include "GL/glut.h" -#include "readtex.h" #include "shaderutil.h" diff --git a/progs/glsl/shtest.c b/progs/glsl/shtest.c index 7b1917be1ce..520eccfb6d8 100644 --- a/progs/glsl/shtest.c +++ b/progs/glsl/shtest.c @@ -29,7 +29,6 @@ #include <assert.h> -#include <string.h> #include <stdio.h> #include <stdlib.h> #include <string.h> diff --git a/progs/openvg/demos/eglcommon.c b/progs/openvg/demos/eglcommon.c index bacd5685d75..0316e596c69 100644 --- a/progs/openvg/demos/eglcommon.c +++ b/progs/openvg/demos/eglcommon.c @@ -42,6 +42,7 @@ make_x_window(Display *x_dpy, EGLDisplay egl_dpy, EGL_RED_SIZE, 1, EGL_GREEN_SIZE, 1, EGL_BLUE_SIZE, 1, + EGL_RENDERABLE_TYPE, EGL_OPENVG_BIT, EGL_NONE }; @@ -60,13 +61,13 @@ make_x_window(Display *x_dpy, EGLDisplay egl_dpy, scrnum = DefaultScreen( x_dpy ); root = RootWindow( x_dpy, scrnum ); - if (!eglChooseConfig( egl_dpy, attribs, &config, 1, &num_configs)) { + if (!eglChooseConfig( egl_dpy, attribs, &config, 1, &num_configs) || + !num_configs) { printf("Error: couldn't get an EGL visual config\n"); exit(1); } assert(config); - assert(num_configs > 0); if (!eglGetConfigAttrib(egl_dpy, config, EGL_NATIVE_VISUAL_ID, &vid)) { printf("Error: eglGetConfigAttrib() failed\n"); diff --git a/progs/openvg/demos/lion.c b/progs/openvg/demos/lion.c index 7224fed399d..adb269bfd86 100644 --- a/progs/openvg/demos/lion.c +++ b/progs/openvg/demos/lion.c @@ -67,6 +67,7 @@ make_x_window(Display *x_dpy, EGLDisplay egl_dpy, EGL_RED_SIZE, 1, EGL_GREEN_SIZE, 1, EGL_BLUE_SIZE, 1, + EGL_RENDERABLE_TYPE, EGL_OPENVG_BIT, EGL_NONE }; @@ -85,13 +86,13 @@ make_x_window(Display *x_dpy, EGLDisplay egl_dpy, scrnum = DefaultScreen( x_dpy ); root = RootWindow( x_dpy, scrnum ); - if (!eglChooseConfig( egl_dpy, attribs, &config, 1, &num_configs)) { + if (!eglChooseConfig( egl_dpy, attribs, &config, 1, &num_configs) || + !num_configs) { printf("Error: couldn't get an EGL visual config\n"); exit(1); } assert(config); - assert(num_configs > 0); if (!eglGetConfigAttrib(egl_dpy, config, EGL_NATIVE_VISUAL_ID, &vid)) { printf("Error: eglGetConfigAttrib() failed\n"); diff --git a/progs/openvg/trivial/eglcommon.c b/progs/openvg/trivial/eglcommon.c index bacd5685d75..0316e596c69 100644 --- a/progs/openvg/trivial/eglcommon.c +++ b/progs/openvg/trivial/eglcommon.c @@ -42,6 +42,7 @@ make_x_window(Display *x_dpy, EGLDisplay egl_dpy, EGL_RED_SIZE, 1, EGL_GREEN_SIZE, 1, EGL_BLUE_SIZE, 1, + EGL_RENDERABLE_TYPE, EGL_OPENVG_BIT, EGL_NONE }; @@ -60,13 +61,13 @@ make_x_window(Display *x_dpy, EGLDisplay egl_dpy, scrnum = DefaultScreen( x_dpy ); root = RootWindow( x_dpy, scrnum ); - if (!eglChooseConfig( egl_dpy, attribs, &config, 1, &num_configs)) { + if (!eglChooseConfig( egl_dpy, attribs, &config, 1, &num_configs) || + !num_configs) { printf("Error: couldn't get an EGL visual config\n"); exit(1); } assert(config); - assert(num_configs > 0); if (!eglGetConfigAttrib(egl_dpy, config, EGL_NATIVE_VISUAL_ID, &vid)) { printf("Error: eglGetConfigAttrib() failed\n"); diff --git a/progs/redbook/aapoly.c b/progs/redbook/aapoly.c index b7b2b270902..64d06b7b3da 100644 --- a/progs/redbook/aapoly.c +++ b/progs/redbook/aapoly.c @@ -45,7 +45,6 @@ #include <GL/glut.h> #include <stdlib.h> #include <stdio.h> -#include <string.h> GLboolean polySmooth = GL_TRUE; diff --git a/progs/tests/.gitignore b/progs/tests/.gitignore index 3479ff8b33b..8b3e9f35583 100644 --- a/progs/tests/.gitignore +++ b/progs/tests/.gitignore @@ -13,6 +13,7 @@ arbvptest3 arbvptorus arbvpwarpmesh arraytexture +auxbuffer blendminmax blendsquare blendxor @@ -23,10 +24,12 @@ bug_3195 bug_texstore_i8 bumpmap calibrate_rast +condrender copypixrate crossbar cva drawbuffers +drawbuffers2 extfuncs.h exactrast fbotest1 diff --git a/progs/tests/Makefile b/progs/tests/Makefile index 836396b2499..d33415ab052 100644 --- a/progs/tests/Makefile +++ b/progs/tests/Makefile @@ -41,6 +41,7 @@ SOURCES = \ copypixrate.c \ crossbar.c \ cva.c \ + cylwrap.c \ drawbuffers.c \ drawbuffers2.c \ exactrast.c \ @@ -48,6 +49,7 @@ SOURCES = \ floattex.c \ fbotest1.c \ fbotest2.c \ + fbotest3.c \ fillrate.c \ fog.c \ fogcoord.c \ diff --git a/progs/tests/SConscript b/progs/tests/SConscript index e2c65382887..04e4bdf8c22 100644 --- a/progs/tests/SConscript +++ b/progs/tests/SConscript @@ -45,12 +45,14 @@ progs = [ 'copypixrate', 'crossbar', 'cva', + 'cylwrap', 'drawbuffers', 'drawbuffers2', 'exactrast', 'ext422square', 'fbotest1', 'fbotest2', + 'fbotest3', 'fillrate', 'floattex', 'fog', diff --git a/progs/tests/arraytexture.c b/progs/tests/arraytexture.c index 28252a354bf..e4e86b9b4ce 100644 --- a/progs/tests/arraytexture.c +++ b/progs/tests/arraytexture.c @@ -36,7 +36,6 @@ #include <math.h> #include <GL/glew.h> #include <GL/glut.h> -#include <GL/glext.h> #if !defined(GL_EXT_texture_array) && !defined(GL_MESA_texture_array) # error "This demo requires enums for either GL_EXT_texture_array or GL_MESA_texture_array to build." diff --git a/progs/tests/bufferobj.c b/progs/tests/bufferobj.c index d4ca2700160..dc479af0452 100644 --- a/progs/tests/bufferobj.c +++ b/progs/tests/bufferobj.c @@ -29,6 +29,7 @@ struct object GLuint VertexStride; GLuint ColorStride; GLuint NumElements; + GLuint MaxElement; }; static struct object Objects[NUM_OBJECTS]; @@ -58,7 +59,8 @@ static void DrawObject( const struct object *obj ) if (obj->NumElements > 0) { /* indexed arrays */ glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, obj->ElementsBufferID); - glDrawElements(GL_LINE_LOOP, obj->NumElements, GL_UNSIGNED_INT, NULL); + glDrawRangeElements(GL_LINE_LOOP, 0, obj->MaxElement, + obj->NumElements, GL_UNSIGNED_INT, NULL); } else { /* non-indexed arrays */ @@ -300,6 +302,7 @@ static void MakeObject1(struct object *obj) obj->VertexStride = 0; obj->ColorStride = 0; obj->NumElements = 0; + obj->MaxElement = 0; glUnmapBufferARB(GL_ARRAY_BUFFER_ARB); @@ -345,6 +348,7 @@ static void MakeObject2(struct object *obj) obj->ColorStride = 6 * sizeof(GLfloat); obj->NumElements = 0; + obj->MaxElement = 0; glUnmapBufferARB(GL_ARRAY_BUFFER_ARB); @@ -401,6 +405,7 @@ static void MakeObject3(struct object *obj) i[3] = 3; glUnmapBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB); obj->NumElements = 4; + obj->MaxElement = 3; if (Have_ARB_vertex_array_object) { CreateVertexArrayObject(obj); @@ -445,6 +450,7 @@ static void MakeObject4(struct object *obj) /* Setup a buffer of indices to test the ELEMENTS path */ obj->ElementsBufferID = 0; obj->NumElements = 0; + obj->MaxElement = 0; if (Have_ARB_vertex_array_object) { CreateVertexArrayObject(obj); diff --git a/progs/tests/bug_3195.c b/progs/tests/bug_3195.c index a075b94e370..3574c1f7176 100644 --- a/progs/tests/bug_3195.c +++ b/progs/tests/bug_3195.c @@ -38,7 +38,6 @@ #include <math.h> #include <GL/glew.h> #include <GL/glut.h> -#include <GL/glext.h> #include "readtex.h" diff --git a/progs/tests/cva.c b/progs/tests/cva.c index 02d1dcba2ec..b3e041c21e3 100644 --- a/progs/tests/cva.c +++ b/progs/tests/cva.c @@ -17,7 +17,6 @@ #define GL_GLEXT_LEGACY #include <GL/glew.h> #include <GL/glut.h> -#include <GL/glext.h> GLfloat verts[][4] = { { -0.5, -0.5, -2.0, 0.0 }, diff --git a/progs/tests/cylwrap.c b/progs/tests/cylwrap.c new file mode 100644 index 00000000000..2b32f115416 --- /dev/null +++ b/progs/tests/cylwrap.c @@ -0,0 +1,259 @@ +/* + * Test cylindrical texcoord wrapping + */ + + +#include <stdio.h> +#include <stdlib.h> +#include <math.h> +#include <GL/glut.h> + +static int Win; +static int WinWidth = 600, WinHeight = 400; +static GLfloat Xrot = 0, Yrot = 0; +static GLboolean CylWrap = GL_TRUE; +static GLboolean Lines = GL_FALSE; + + + +static void +PrintString(const char *s) +{ + while (*s) { + glutBitmapCharacter(GLUT_BITMAP_8_BY_13, (int) *s); + s++; + } +} + + +static void +DrawSample(GLboolean wrap) +{ + float p; + + glEnable(GL_TEXTURE_2D); + + if (Lines) { + /* texured lines */ + float t; + for (t = 0; t <= 1.0; t += 0.125) { + float y = -1.0 + 2.0 * t; + glBegin(GL_LINE_STRIP); + for (p = 0.0; p <= 1.001; p += 0.05) { + float x = -2.0 + p * 4.0; + float s = p + 0.5; + if (wrap && s > 1.0) + s -= 1.0; + glTexCoord2f(s, t); glVertex2f(x, y); + } + glEnd(); + } + } + else { + /* texured quads */ + glBegin(GL_QUAD_STRIP); + for (p = 0.0; p <= 1.001; p += 0.1) { + float x = -2.0 + p * 4.0; + float s = p + 0.5; + if (wrap && s > 1.0) + s -= 1.0; + glTexCoord2f(s, 0); glVertex2f(x, -1); + glTexCoord2f(s, 1); glVertex2f(x, +1); + } + glEnd(); + } + + glDisable(GL_TEXTURE_2D); + + /* hash marks */ + glColor3f(0,0,0); + glBegin(GL_LINES); + for (p = 0.0; p <= 1.001; p += 0.1) { + float x = -2.0 + p * 4.0; + glVertex2f(x, -1.1); + glVertex2f(x, -0.8); + } + glEnd(); + + /* labels */ + glColor3f(1,1,1); + for (p = 0.0; p <= 1.001; p += 0.1) { + char str[100]; + float x = -2.0 + p * 4.0; + float s = p + 0.5; + + if (wrap && s > 1.0) + s -= 1.0; + + sprintf(str, "%3.1f", s); + glRasterPos2f(x, -1.2); + glBitmap(0, 0, 0, 0, -11, 0, NULL); + PrintString(str); + if (p == 0.0) { + glBitmap(0, 0, 0, 0, -55, 0, NULL); + PrintString("s ="); + } + } +} + + +static void +Draw(void) +{ + glClear(GL_COLOR_BUFFER_BIT); + + glPushMatrix(); + glRotatef(Xrot, 1, 0, 0); + glRotatef(Yrot, 0, 1, 0); + + glPushMatrix(); + glTranslatef(0, +1.2, 0); + DrawSample(GL_FALSE); + glPopMatrix(); + + /* set Mesa back-door state for testing cylindrical wrap mode */ + if (CylWrap) + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_PRIORITY, 0.125); + + glPushMatrix(); + glTranslatef(0, -1.2, 0); + DrawSample(GL_TRUE); + glPopMatrix(); + + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_PRIORITY, 1.0); + + glPopMatrix(); + + glutSwapBuffers(); +} + + +static void +Reshape(int width, int height) +{ + WinWidth = width; + WinHeight = height; + glViewport(0, 0, width, height); + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + glFrustum(-1.0, 1.0, -1.0, 1.0, 3.0, 25.0); + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + glTranslatef(0.0, 0.0, -10.0); +} + + +static void +Key(unsigned char key, int x, int y) +{ + (void) x; + (void) y; + switch (key) { + case 'c': + case 'C': + CylWrap = !CylWrap; + if (CylWrap) + printf("Cylindrical wrap on.\n"); + else + printf("Cylindrical wrap off.\n"); + break; + case 'l': + case 'L': + Lines = !Lines; + break; + case 27: + glutDestroyWindow(Win); + exit(0); + break; + } + glutPostRedisplay(); +} + + +static void +SpecialKey(int key, int x, int y) +{ + const GLfloat step = 3.0; + (void) x; + (void) y; + switch (key) { + case GLUT_KEY_UP: + Xrot -= step; + break; + case GLUT_KEY_DOWN: + Xrot += step; + break; + case GLUT_KEY_LEFT: + Yrot -= step; + break; + case GLUT_KEY_RIGHT: + Yrot += step; + break; + } + glutPostRedisplay(); +} + + +static void +MakeSineWaveTexture(void) +{ + GLubyte tex[128][512][4]; + int i, j; + + for (j = 0; j < 128; j++) { + for (i = 0; i < 512; i++) { + float x = i / 511.0 * 2.0 * M_PI + M_PI * 0.5; + float y0 = sin(x) * 0.5 + 0.5; + int jy0 = y0 * 128; + float y1 = sin(x + M_PI) * 0.5 + 0.5; + int jy1 = y1 * 128; + if (j < jy0) + tex[j][i][0] = 0xff; + else + tex[j][i][0] = 0; + if (j < jy1) + tex[j][i][1] = 0xff; + else + tex[j][i][1] = 0; + tex[j][i][2] = 0; + tex[j][i][3] = 0xff; + } + } + + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 512, 128, 0, + GL_RGBA, GL_UNSIGNED_BYTE, tex); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); +} + + +static void +Init(void) +{ + glBindTexture(GL_TEXTURE_2D, 5); + MakeSineWaveTexture(); + + glClearColor(0.5, 0.5, 0.5, 0.0); + glPointSize(3.0); + + printf("Press 'c' to toggle cylindrical wrap mode.\n"); + printf("Press 'l' to toggle line / quad drawing.\n"); +} + + +int +main(int argc, char *argv[]) +{ + glutInit(&argc, argv); + glutInitWindowSize(WinWidth, WinHeight); + glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE); + Win = glutCreateWindow(argv[0]); + glutReshapeFunc(Reshape); + glutSpecialFunc(SpecialKey); + glutKeyboardFunc(Key); + glutDisplayFunc(Draw); + Init(); + glutMainLoop(); + return 0; +} diff --git a/progs/tests/fbotest3.c b/progs/tests/fbotest3.c new file mode 100644 index 00000000000..8e288b38b83 --- /dev/null +++ b/progs/tests/fbotest3.c @@ -0,0 +1,231 @@ +/* + * Test GL_EXT_framebuffer_object + * Like fbotest2.c but use a texture for the Z buffer / renderbuffer. + * Note: the Z texture is never resized so that limits what can be + * rendered if the window is resized. + * + * This tests a bug reported by Christoph Bumiller on 1 Feb 2010 + * on mesa3d-dev. + * + * XXX this should be made into a piglit test. + * + * Brian Paul + * 1 Feb 2010 + */ + + +#include <assert.h> +#include <stdio.h> +#include <stdlib.h> +#include <math.h> +#include <GL/glew.h> +#include <GL/glut.h> + + +static int Win = 0; +static int Width = 400, Height = 400; +static GLuint Tex = 0; +static GLuint MyFB, ColorRb, DepthRb; +static GLboolean Animate = GL_FALSE; +static GLfloat Rotation = 0.0; + + +static void +CheckError(int line) +{ + GLenum err = glGetError(); + if (err) { + printf("fbotest3: GL Error 0x%x at line %d\n", (int) err, line); + } +} + + +static void +Display( void ) +{ + GLubyte *buffer = malloc(Width * Height * 4); + GLenum status; + + CheckError(__LINE__); + + /* draw to user framebuffer */ + glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, MyFB); + glDrawBuffer(GL_COLOR_ATTACHMENT1_EXT); + glReadBuffer(GL_COLOR_ATTACHMENT1_EXT); + + status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT); + if (status != GL_FRAMEBUFFER_COMPLETE_EXT) { + printf("fbotest3: Error: Framebuffer is incomplete!!!\n"); + } + + CheckError(__LINE__); + + glClearColor(0.5, 0.5, 1.0, 0.0); + glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ); + + glEnable(GL_DEPTH_TEST); + glEnable(GL_LIGHTING); + glEnable(GL_LIGHT0); + + glPushMatrix(); + glRotatef(30.0, 1, 0, 0); + glRotatef(Rotation, 0, 1, 0); + glutSolidTeapot(2.0); + glPopMatrix(); + + /* read from user framebuffer */ + glReadPixels(0, 0, Width, Height, GL_RGBA, GL_UNSIGNED_BYTE, buffer); + + /* draw to window */ + glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); + glDisable(GL_DEPTH_TEST); /* in case window has depth buffer */ + glWindowPos2iARB(0, 0); + glDrawPixels(Width, Height, GL_RGBA, GL_UNSIGNED_BYTE, buffer); + + free(buffer); + glutSwapBuffers(); + CheckError(__LINE__); +} + + +static void +Reshape( int width, int height ) +{ + float ar = (float) width / (float) height; + + glViewport( 0, 0, width, height ); + glMatrixMode( GL_PROJECTION ); + glLoadIdentity(); + glFrustum( -ar, ar, -1.0, 1.0, 5.0, 25.0 ); + + glMatrixMode( GL_MODELVIEW ); + glLoadIdentity(); + glTranslatef( 0.0, 0.0, -15.0 ); + + glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, ColorRb); + glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_RGB, width, height); + + Width = width; + Height = height; +} + + +static void +CleanUp(void) +{ + glDeleteFramebuffersEXT(1, &MyFB); + glDeleteRenderbuffersEXT(1, &ColorRb); + glDeleteRenderbuffersEXT(1, &DepthRb); + glDeleteTextures(1, &Tex); + assert(!glIsFramebufferEXT(MyFB)); + assert(!glIsRenderbufferEXT(ColorRb)); + assert(!glIsRenderbufferEXT(DepthRb)); + glutDestroyWindow(Win); + exit(0); +} + + +static void +Idle(void) +{ + Rotation = glutGet(GLUT_ELAPSED_TIME) * 0.1; + glutPostRedisplay(); +} + + +static void +Key( unsigned char key, int x, int y ) +{ + (void) x; + (void) y; + switch (key) { + case 'a': + Animate = !Animate; + if (Animate) + glutIdleFunc(Idle); + else + glutIdleFunc(NULL); + break; + case 27: + CleanUp(); + break; + } + glutPostRedisplay(); +} + + +static void +Init( void ) +{ + if (!glutExtensionSupported("GL_EXT_framebuffer_object")) { + printf("fbotest3: GL_EXT_framebuffer_object not found!\n"); + exit(0); + } + printf("fbotest3: GL_RENDERER = %s\n", (char *) glGetString(GL_RENDERER)); + + /* create initial tex obj as an RGBA texture */ + glGenTextures(1, &Tex); + glBindTexture(GL_TEXTURE_2D, Tex); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 256, 256, 0, + GL_RGBA, GL_UNSIGNED_BYTE, NULL); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); + glEnable(GL_TEXTURE_2D); + + /* draw something to make sure the texture is used */ + glBegin(GL_POINTS); + glVertex2f(0, 0); + glEnd(); + + /* done w/ texturing */ + glDisable(GL_TEXTURE_2D); + + /* Create my Framebuffer Object */ + glGenFramebuffersEXT(1, &MyFB); + glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, MyFB); + assert(glIsFramebufferEXT(MyFB)); + + /* Setup color renderbuffer */ + glGenRenderbuffersEXT(1, &ColorRb); + glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, ColorRb); + assert(glIsRenderbufferEXT(ColorRb)); + glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT1_EXT, + GL_RENDERBUFFER_EXT, ColorRb); + glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_RGB, Width, Height); + + /* Setup depth renderbuffer (a texture) */ + glGenRenderbuffersEXT(1, &DepthRb); + glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, DepthRb); + assert(glIsRenderbufferEXT(DepthRb)); + /* replace RGBA texture with Z texture */ + glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, Width, Height, 0, + GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, NULL); + glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, + GL_TEXTURE_2D, Tex, 0); + + CheckError(__LINE__); + + /* restore to default */ + glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); + CheckError(__LINE__); +} + + +int +main( int argc, char *argv[] ) +{ + glutInit( &argc, argv ); + glutInitWindowPosition( 0, 0 ); + glutInitWindowSize(Width, Height); + glutInitDisplayMode( GLUT_RGB | GLUT_DOUBLE ); + Win = glutCreateWindow(argv[0]); + glewInit(); + glutReshapeFunc( Reshape ); + glutKeyboardFunc( Key ); + glutDisplayFunc( Display ); + if (Animate) + glutIdleFunc(Idle); + Init(); + glutMainLoop(); + return 0; +} diff --git a/progs/tests/getprocaddress.c b/progs/tests/getprocaddress.c index e699baf44bc..38ca7000df2 100644 --- a/progs/tests/getprocaddress.c +++ b/progs/tests/getprocaddress.c @@ -660,8 +660,8 @@ exercise_CompressedTextures(GLenum dimension) glGetTexLevelParameteriv(dimension, 0, GL_TEXTURE_COMPRESSED_IMAGE_SIZE_ARB, &queryCompressedSize); if (queryCompressedSize != sizeof(compressedTexture)) { - fprintf(stderr, "%s: compressed 3D texture changed size: expected %d, actual %d\n", - __FUNCTION__, sizeof(compressedTexture), queryCompressedSize); + fprintf(stderr, "%s: compressed 3D texture changed size: expected %lu, actual %d\n", + __FUNCTION__, (unsigned long) sizeof(compressedTexture), queryCompressedSize); return GL_FALSE; } (*GetCompressedTexImageARB)(dimension, 0, queryCompressedData); diff --git a/progs/tests/interleave.c b/progs/tests/interleave.c index 47bf9dfbe5e..acf67d02c12 100644 --- a/progs/tests/interleave.c +++ b/progs/tests/interleave.c @@ -105,7 +105,7 @@ static const unsigned indicies[12] = { 1, 4, 2 }; -#define NONE { NULL, 0, 0, 0 } +#define NONE { NULL, 0, 0, 0, sizeof( NULL ) } #define V2F { v, 2, 2 * sizeof( GLfloat ), GL_FLOAT, sizeof( v[0] ) } #define V3F { v, 3, 3 * sizeof( GLfloat ), GL_FLOAT, sizeof( v[0] ) } #define V4F { v, 4, 4 * sizeof( GLfloat ), GL_FLOAT, sizeof( v[0] ) } diff --git a/progs/tests/mipgen.c b/progs/tests/mipgen.c index 088f643215c..48e52c9c315 100644 --- a/progs/tests/mipgen.c +++ b/progs/tests/mipgen.c @@ -48,8 +48,6 @@ #include <GL/glew.h> #include <GL/glut.h> -#include "readtex.h" - static GLfloat LodBias = 6.0; /* make smallest miplevel visible */ static GLuint texImage; diff --git a/progs/tests/mipmap_comp.c b/progs/tests/mipmap_comp.c index dd2232113b6..122d157949a 100644 --- a/progs/tests/mipmap_comp.c +++ b/progs/tests/mipmap_comp.c @@ -48,8 +48,6 @@ #include <GL/glew.h> #include <GL/glut.h> -#include "readtex.h" - #define SIZE 16 /* not larger then 16 */ static GLint BaseLevel = 0, MaxLevel = 9; diff --git a/progs/tests/mipmap_comp_tests.c b/progs/tests/mipmap_comp_tests.c index e865b30ad0f..b93a5c61393 100644 --- a/progs/tests/mipmap_comp_tests.c +++ b/progs/tests/mipmap_comp_tests.c @@ -48,8 +48,6 @@ #include <GL/glew.h> #include <GL/glut.h> -#include "readtex.h" - #define SIZE 16 /* not larger then 16 */ static GLint BaseLevel = 0, MaxLevel ; diff --git a/progs/tests/mipmap_view.c b/progs/tests/mipmap_view.c index 808d348699c..eb521970524 100644 --- a/progs/tests/mipmap_view.c +++ b/progs/tests/mipmap_view.c @@ -12,7 +12,6 @@ #include <math.h> #include <GL/glew.h> #include <GL/glut.h> -#include <GL/glext.h> #include "readtex.h" diff --git a/progs/tests/no_s3tc.c b/progs/tests/no_s3tc.c index 31cfb40b9d3..c4132cd956a 100644 --- a/progs/tests/no_s3tc.c +++ b/progs/tests/no_s3tc.c @@ -40,7 +40,6 @@ #include <string.h> #include <GL/glew.h> #include <GL/glut.h> -#include <GL/glext.h> static unsigned data[16]; diff --git a/progs/tests/streaming_rect.c b/progs/tests/streaming_rect.c index f65ac4ce36c..3b016e55af9 100644 --- a/progs/tests/streaming_rect.c +++ b/progs/tests/streaming_rect.c @@ -13,8 +13,6 @@ #include <GL/glew.h> #include <GL/glut.h> -#include "readtex.h" - #define ANIMATE 10 #define PBO 11 diff --git a/progs/tests/texwrap.c b/progs/tests/texwrap.c index 92c8a2f14c2..39c55919dd2 100644 --- a/progs/tests/texwrap.c +++ b/progs/tests/texwrap.c @@ -71,7 +71,7 @@ static struct wrap_mode modes[] = { WRAP_EXT ( GL_MIRROR_CLAMP_TO_EDGE_EXT, "GL_ATI_texture_mirror_once", "GL_EXT_texture_mirror_clamp", 999.0 ), - { 0 } + { 0, NULL, GL_FALSE, 0.0, { NULL, NULL } } }; static void diff --git a/progs/tests/vparray.c b/progs/tests/vparray.c index fe168c6cd56..75160afd463 100644 --- a/progs/tests/vparray.c +++ b/progs/tests/vparray.c @@ -8,7 +8,6 @@ #include <assert.h> #include <stdio.h> -#include <string.h> #include <stdlib.h> #include <string.h> #include <math.h> @@ -183,7 +182,7 @@ static void init_program(void) static const GLfloat bias[4] = {1.0, 1.0, 1.0, 0.0}; if (!glutExtensionSupported("GL_NV_vertex_program")) { - printf("Sorry, this program requires GL_NV_vertex_program"); + printf("Sorry, this program requires GL_NV_vertex_program\n"); exit(1); } diff --git a/progs/tests/zcomp.c b/progs/tests/zcomp.c index 15e35f17b09..d6b9c070223 100644 --- a/progs/tests/zcomp.c +++ b/progs/tests/zcomp.c @@ -7,7 +7,6 @@ #include <math.h> #include <GL/glew.h> #include <GL/glut.h> -#include "../util/showbuffer.c" static int Win; diff --git a/progs/trivial/Makefile b/progs/trivial/Makefile index e15ec33ab59..6c78ae90a96 100644 --- a/progs/trivial/Makefile +++ b/progs/trivial/Makefile @@ -90,6 +90,8 @@ SOURCES = \ quadstrip-flat.c \ quadstrip.c \ readpixels.c \ + sub-tex.c \ + tex-quads.c \ tri-alpha.c \ tri-alpha-tex.c \ tri-array-interleaved.c \ @@ -119,6 +121,7 @@ SOURCES = \ tri-lit-material.c \ tri-mask-tri.c \ tri-orig.c \ + tri-point-line-clipped.c \ tri-query.c \ tri-repeat.c \ tri-scissor-tri.c \ @@ -159,6 +162,7 @@ SOURCES = \ vbo-drawelements.c \ vbo-drawrange.c \ vp-array.c \ + vp-array-hf.c \ vp-array-int.c \ vp-clip.c \ vp-line-clip.c \ diff --git a/progs/trivial/SConscript b/progs/trivial/SConscript index 613383c77b1..87a4d2164bd 100644 --- a/progs/trivial/SConscript +++ b/progs/trivial/SConscript @@ -70,6 +70,8 @@ progs = [ 'quadstrip-cont', 'quadstrip-flat', 'quadstrip', + 'sub-tex', + 'tex-quads', 'tri-alpha', 'tri-blend-color', 'tri-blend-max', @@ -96,6 +98,7 @@ progs = [ 'tri-logicop-xor', 'tri-mask-tri', 'tri-orig', + 'tri-point-line-clipped', 'tri-query', 'tri-repeat', 'tri-scissor-tri', diff --git a/progs/trivial/sub-tex.c b/progs/trivial/sub-tex.c new file mode 100644 index 00000000000..0b8bb28182e --- /dev/null +++ b/progs/trivial/sub-tex.c @@ -0,0 +1,137 @@ +/** + * Draw a series of textured quads after each quad, use glTexSubImage() + * to change one row of the texture image. + */ + +#include <stdio.h> +#include <string.h> +#include <stdlib.h> +#include <GL/glew.h> +#include <GL/glut.h> + + +static GLint Win = 0; +static GLuint Tex = 0; + + +static void Init(void) +{ + fprintf(stderr, "GL_RENDERER = %s\n", (char *) glGetString(GL_RENDERER)); + fflush(stderr); + + glGenTextures(1, &Tex); + glBindTexture(GL_TEXTURE_2D, Tex); + + glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); +} + + +static void Reshape(int width, int height) +{ + float ar = (float) width / height; + glViewport(0, 0, width, height); + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + glOrtho(-ar, ar, -1.0, 1.0, -1.0, 1.0); + glMatrixMode(GL_MODELVIEW); +} + + +static void Key(unsigned char key, int x, int y) +{ + if (key == 27) { + glDeleteTextures(1, &Tex); + glutDestroyWindow(Win); + exit(1); + } + glutPostRedisplay(); +} + + +static void Draw(void) +{ + GLubyte tex[16][16][4]; + GLubyte row[16][4]; + int i, j; + + for (i = 0; i < 16; i++) { + for (j = 0; j < 16; j++) { + if ((i + j) & 1) { + tex[i][j][0] = 128; + tex[i][j][1] = 128; + tex[i][j][2] = 128; + tex[i][j][3] = 255; + } + else { + tex[i][j][0] = 255; + tex[i][j][1] = 255; + tex[i][j][2] = 255; + tex[i][j][3] = 255; + } + } + } + + for (i = 0; i < 16; i++) { + row[i][0] = 255; + row[i][1] = 0; + row[i][2] = 0; + row[i][3] = 255; + } + + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0, + GL_RGBA, GL_UNSIGNED_BYTE, tex); + glEnable(GL_TEXTURE_2D); + + glClear(GL_COLOR_BUFFER_BIT); + + for (i = 0; i < 9; i++) { + + glPushMatrix(); + glTranslatef(-4.0 + i, 0, 0); + glScalef(0.5, 0.5, 1.0); + + glBegin(GL_QUADS); + glTexCoord2f(1,0); + glVertex3f( 0.9, -0.9, 0.0); + glTexCoord2f(1,1); + glVertex3f( 0.9, 0.9, 0.0); + glTexCoord2f(0,1); + glVertex3f(-0.9, 0.9, 0.0); + glTexCoord2f(0,0); + glVertex3f(-0.9, -0.9, 0.0); + glEnd(); + + glPopMatrix(); + + /* replace a row of the texture image with red texels */ + if (i * 2 < 16) + glTexSubImage2D(GL_TEXTURE_2D, 0, 0, i*2, 16, 1, + GL_RGBA, GL_UNSIGNED_BYTE, row); + } + + + glutSwapBuffers(); +} + + +int main(int argc, char **argv) +{ + glutInit(&argc, argv); + glutInitWindowSize(900, 200); + glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE); + Win = glutCreateWindow(*argv); + if (!Win) { + exit(1); + } + glewInit(); + Init(); + glutReshapeFunc(Reshape); + glutKeyboardFunc(Key); + glutDisplayFunc(Draw); + glutMainLoop(); + return 0; +} diff --git a/progs/trivial/tex-quads.c b/progs/trivial/tex-quads.c new file mode 100644 index 00000000000..626e178b873 --- /dev/null +++ b/progs/trivial/tex-quads.c @@ -0,0 +1,143 @@ +/** + * Draw a series of quads, each with a different texture. + */ + +#include <stdio.h> +#include <string.h> +#include <stdlib.h> +#include <GL/glew.h> +#include <GL/glut.h> + +#define NUM_TEX 10 + +static GLint Win = 0; +static GLuint Tex[NUM_TEX]; + + +static void Init(void) +{ + int i; + + fprintf(stderr, "GL_RENDERER = %s\n", (char *) glGetString(GL_RENDERER)); + fflush(stderr); + + glGenTextures(NUM_TEX, Tex); + + for (i = 0; i < NUM_TEX; i++) { + glBindTexture(GL_TEXTURE_2D, Tex[i]); + + glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + } +} + + +static void Reshape(int width, int height) +{ + float ar = (float) width / height; + glViewport(0, 0, width, height); + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + glOrtho(-ar, ar, -1.0, 1.0, -1.0, 1.0); + glMatrixMode(GL_MODELVIEW); +} + + +static void Key(unsigned char key, int x, int y) +{ + if (key == 27) { + glDeleteTextures(NUM_TEX, Tex); + glutDestroyWindow(Win); + exit(1); + } + glutPostRedisplay(); +} + + +static void Draw(void) +{ + GLubyte tex[16][16][4]; + int t, i, j; + + for (t = 0; t < NUM_TEX; t++) { + + for (i = 0; i < 16; i++) { + for (j = 0; j < 16; j++) { + if (i < t) { + /* red row */ + tex[i][j][0] = 255; + tex[i][j][1] = 0; + tex[i][j][2] = 0; + tex[i][j][3] = 255; + } + else if ((i + j) & 1) { + tex[i][j][0] = 128; + tex[i][j][1] = 128; + tex[i][j][2] = 128; + tex[i][j][3] = 255; + } + else { + tex[i][j][0] = 255; + tex[i][j][1] = 255; + tex[i][j][2] = 255; + tex[i][j][3] = 255; + } + } + } + + glBindTexture(GL_TEXTURE_2D, Tex[t]); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0, + GL_RGBA, GL_UNSIGNED_BYTE, tex); + } + + glEnable(GL_TEXTURE_2D); + + glClear(GL_COLOR_BUFFER_BIT); + + for (i = 0; i < NUM_TEX; i++) { + + glBindTexture(GL_TEXTURE_2D, Tex[i]); + + glPushMatrix(); + glTranslatef(-4.0 + i, 0, 0); + glScalef(0.5, 0.5, 1.0); + + glBegin(GL_QUADS); + glTexCoord2f(1,0); + glVertex3f( 0.9, -0.9, 0.0); + glTexCoord2f(1,1); + glVertex3f( 0.9, 0.9, 0.0); + glTexCoord2f(0,1); + glVertex3f(-0.9, 0.9, 0.0); + glTexCoord2f(0,0); + glVertex3f(-0.9, -0.9, 0.0); + glEnd(); + + glPopMatrix(); + } + + + glutSwapBuffers(); +} + + +int main(int argc, char **argv) +{ + glutInit(&argc, argv); + glutInitWindowSize(900, 200); + glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE); + Win = glutCreateWindow(*argv); + if (!Win) { + exit(1); + } + glewInit(); + Init(); + glutReshapeFunc(Reshape); + glutKeyboardFunc(Key); + glutDisplayFunc(Draw); + glutMainLoop(); + return 0; +} diff --git a/progs/trivial/tri-fbo-tex-mip.c b/progs/trivial/tri-fbo-tex-mip.c index 07443695011..2e8fb74a00b 100644 --- a/progs/trivial/tri-fbo-tex-mip.c +++ b/progs/trivial/tri-fbo-tex-mip.c @@ -6,8 +6,6 @@ #include <assert.h> #include <stdio.h> #include <stdlib.h> -#include <string.h> -#include <math.h> /* For debug */ diff --git a/progs/trivial/tri-fbo-tex.c b/progs/trivial/tri-fbo-tex.c index 8d1f871328d..eacb7d577be 100644 --- a/progs/trivial/tri-fbo-tex.c +++ b/progs/trivial/tri-fbo-tex.c @@ -6,8 +6,6 @@ #include <assert.h> #include <stdio.h> #include <stdlib.h> -#include <string.h> -#include <math.h> /* For debug */ diff --git a/progs/trivial/tri-point-line-clipped.c b/progs/trivial/tri-point-line-clipped.c new file mode 100644 index 00000000000..f8c1015f5f4 --- /dev/null +++ b/progs/trivial/tri-point-line-clipped.c @@ -0,0 +1,116 @@ +/** + * Test frustum/user clipping w/ glPolygonMode LINE/POINT. + * + * The bottom/left and bottom/right verts are outside the frustum and clipped. + * The top vertex is clipped by a user clipping plane. + * + * A filled gray reference triangle is shown underneath the points/lines. + */ + +#include <stdio.h> +#include <stdlib.h> +#include <GL/glut.h> + + +static int win; + + +static void +ColorTri(void) +{ + glBegin(GL_TRIANGLES); + glColor3f(1, 0, 0); glVertex3f(-1.5, -0.8, 0.0); + glColor3f(0, 1, 0); glVertex3f( 1.5, -0.8, 0.0); + glColor3f(0, 0, 1); glVertex3f( 0.0, 0.9, 0.0); + glEnd(); +} + + +static void +GrayTri(void) +{ + glColor3f(0.3, 0.3, 0.3); + glBegin(GL_TRIANGLES); + glVertex3f(-1.5, -0.8, 0.0); + glVertex3f( 1.5, -0.8, 0.0); + glVertex3f( 0.0, 0.9, 0.0); + glEnd(); +} + + +static void +Draw(void) +{ + static const GLdouble plane[4] = { 0, -1.0, 0, 0.5 }; + + glClear(GL_COLOR_BUFFER_BIT); + + glPointSize(13.0); + glLineWidth(5.0); + + glClipPlane(GL_CLIP_PLANE0, plane); + glEnable(GL_CLIP_PLANE0); + + glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); + GrayTri(); + + glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); + ColorTri(); + + glPolygonMode(GL_FRONT_AND_BACK, GL_POINT); + ColorTri(); + + glutSwapBuffers(); +} + + +static void Reshape(int width, int height) +{ + glViewport(0, 0, (GLint)width, (GLint)height); + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + glOrtho(-1.0, 1.0, -1.0, 1.0, -1.0, 1.0); + glMatrixMode(GL_MODELVIEW); +} + + +static void +Key(unsigned char key, int x, int y) +{ + if (key == 27) { + glutDestroyWindow(win); + exit(0); + } + else { + glutPostRedisplay(); + } +} + + +static void +Init(void) +{ + fprintf(stderr, "GL_RENDERER = %s\n", (char *) glGetString(GL_RENDERER)); + fprintf(stderr, "GL_VERSION = %s\n", (char *) glGetString(GL_VERSION)); + fprintf(stderr, "GL_VENDOR = %s\n", (char *) glGetString(GL_VENDOR)); + fflush(stderr); +} + + +int +main(int argc, char **argv) +{ + glutInitWindowSize(300, 300); + glutInit(&argc, argv); + glutInitDisplayMode(GLUT_DOUBLE | GLUT_DEPTH); + win = glutCreateWindow(*argv); + if (!win) { + return 1; + } + Init(); + glutReshapeFunc(Reshape); + glutKeyboardFunc(Key); + glutDisplayFunc(Draw); + glutMainLoop(); + return 0; +} diff --git a/progs/trivial/tri-scissor-tri.c b/progs/trivial/tri-scissor-tri.c index d65502d91b9..1bb15501bbd 100644 --- a/progs/trivial/tri-scissor-tri.c +++ b/progs/trivial/tri-scissor-tri.c @@ -31,10 +31,14 @@ #define CI_OFFSET_1 16 #define CI_OFFSET_2 32 -GLint Width = 250, Height = 250; +GLint Width = 300, Height = 300; GLenum doubleBuffer; +/* scissor bounds */ +static GLint Left, Right, Bottom, Top; + + static void Init(void) { fprintf(stderr, "GL_RENDERER = %s\n", (char *) glGetString(GL_RENDERER)); @@ -47,26 +51,57 @@ static void Init(void) static void Reshape(int width, int height) { - glViewport(0, 0, (GLint)width, (GLint)height); glMatrixMode(GL_PROJECTION); glLoadIdentity(); glOrtho(-1.0, 1.0, -1.0, 1.0, -0.5, 1000.0); glMatrixMode(GL_MODELVIEW); + + Width = width; + Height = height; + + Left = Width / 4; + Right = Width * 3 / 4; + Bottom = Height / 4; + Top = Height * 3 / 4; } static void Key(unsigned char key, int x, int y) { + int step = 2; + switch (key) { + case 'l': + Left -= step; + break; + case 'L': + Left += step; + break; + case 'r': + Right -= step; + break; + case 'R': + Right += step; + break; + case 'b': + Bottom -= step; + break; + case 'B': + Bottom += step; + break; + case 't': + Top -= step; + break; + case 'T': + Top += step; + break; + case 27: + exit(1); + default: + ; + } - switch (key) { - case 27: - exit(1); - default: - break; - } - - glutPostRedisplay(); + glutPostRedisplay(); } static void Draw(void) @@ -82,7 +117,8 @@ static void Draw(void) glVertex3f(-0.9, 0.0, -30.0); glEnd(); - glScissor(Width / 4, Height / 4, Width / 2, Height / 2); + printf("Scissor %d, %d .. %d, %d\n", Left, Bottom, Right, Top); + glScissor(Left, Bottom, Right-Left, Top-Bottom); glEnable(GL_SCISSOR_TEST); glBegin(GL_TRIANGLES); diff --git a/progs/trivial/tri-z-eq.c b/progs/trivial/tri-z-eq.c index 6bdac474196..c04ffae7f1a 100644 --- a/progs/trivial/tri-z-eq.c +++ b/progs/trivial/tri-z-eq.c @@ -69,6 +69,8 @@ static void Key(unsigned char key, int x, int y) static void Draw(void) { + float z = 1.0; + glClearColor(0.0, 0.0, 1.0, 0.0); glClearDepth(1.0); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); @@ -77,15 +79,21 @@ static void Draw(void) glBegin(GL_TRIANGLES); glColor3f(0,0,.7); - glVertex3f( 0.9, -0.9, 1.0); + glVertex3f( 0.9, -0.9, z); glColor3f(.8,0,0); - glVertex3f( 0.9, 0.9, 1.0); + glVertex3f( 0.9, 0.9, z); glColor3f(0,.9,0); - glVertex3f(-0.9, 0.0, 1.0); + glVertex3f(-0.9, 0.0, z); glEnd(); glFlush(); + { + GLfloat z; + glReadPixels(125, 125, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &z); + printf("Z at (125, 125) = %f\n", z); + } + if (doubleBuffer) { glutSwapBuffers(); } diff --git a/progs/trivial/vp-array-hf.c b/progs/trivial/vp-array-hf.c new file mode 100644 index 00000000000..f812436437f --- /dev/null +++ b/progs/trivial/vp-array-hf.c @@ -0,0 +1,215 @@ +/* Test glGenProgramsNV(), glIsProgramNV(), glLoadProgramNV() */ + +#include <assert.h> +#include <string.h> +#include <stdio.h> +#include <stdlib.h> +#include <math.h> +#include <GL/glew.h> +#include <GL/glut.h> + +typedef union { GLfloat f; GLint i; } fi_type; +/** + * Convert a 4-byte float to a 2-byte half float. + * Based on code from: + * http://www.opengl.org/discussion_boards/ubb/Forum3/HTML/008786.html + */ +static GLhalf +_mesa_float_to_half(GLfloat val) +{ + + const fi_type fi = {val}; + const int flt_m = fi.i & 0x7fffff; + const int flt_e = (fi.i >> 23) & 0xff; + const int flt_s = (fi.i >> 31) & 0x1; + int s, e, m = 0; + GLhalf result; + + /* sign bit */ + s = flt_s; + + /* handle special cases */ + if ((flt_e == 0) && (flt_m == 0)) { + /* zero */ + /* m = 0; - already set */ + e = 0; + } + else if ((flt_e == 0) && (flt_m != 0)) { + /* denorm -- denorm float maps to 0 half */ + /* m = 0; - already set */ + e = 0; + } + else if ((flt_e == 0xff) && (flt_m == 0)) { + /* infinity */ + /* m = 0; - already set */ + e = 31; + } + else if ((flt_e == 0xff) && (flt_m != 0)) { + /* NaN */ + m = 1; + e = 31; + } + else { + /* regular number */ + const int new_exp = flt_e - 127; + if (new_exp < -24) { + /* this maps to 0 */ + /* m = 0; - already set */ + e = 0; + } + else if (new_exp < -14) { + /* this maps to a denorm */ + unsigned int exp_val = (unsigned int) (-14 - new_exp); /* 2^-exp_val*/ + e = 0; + switch (exp_val) { + case 0: + /* m = 0; - already set */ + break; + case 1: m = 512 + (flt_m >> 14); break; + case 2: m = 256 + (flt_m >> 15); break; + case 3: m = 128 + (flt_m >> 16); break; + case 4: m = 64 + (flt_m >> 17); break; + case 5: m = 32 + (flt_m >> 18); break; + case 6: m = 16 + (flt_m >> 19); break; + case 7: m = 8 + (flt_m >> 20); break; + case 8: m = 4 + (flt_m >> 21); break; + case 9: m = 2 + (flt_m >> 22); break; + case 10: m = 1; break; + } + } + else if (new_exp > 15) { + /* map this value to infinity */ + /* m = 0; - already set */ + e = 31; + } + else { + /* regular */ + e = new_exp + 15; + m = flt_m >> 13; + } + } + + result = (s << 15) | (e << 10) | m; + return result; +} + + +GLfloat verts[][4] = { + { 0.9, -0.9, 0.0, 1.0 }, + { 0.9, 0.9, 0.0, 1.0 }, + { -0.9, 0.9, 0.0, 1.0 }, + { -0.9, -0.9, 0.0, 1.0 }, +}; + +GLhalf hverts[16]; + +GLubyte color[][4] = { + { 0x00, 0x00, 0xff, 0x00 }, + { 0x00, 0xff, 0x00, 0x00 }, + { 0xff, 0x00, 0x00, 0x00 }, + { 0xff, 0xff, 0xff, 0x00 }, +}; + +GLuint indices[] = { 0, 1, 2, 3 }; + +static void Init( void ) +{ + GLint errno; + GLuint prognum; + GLuint i, j; + + static const char *prog1 = + "!!ARBvp1.0\n" + "MOV result.color, vertex.color;\n" + "MOV result.position, vertex.position;\n" + "END\n"; + + if (!glutExtensionSupported("GL_ARB_half_float_vertex")) { + printf("GL_ARB_half_float_vertex not found!\n"); + exit(0); + } + + glGenProgramsARB(1, &prognum); + glBindProgramARB(GL_VERTEX_PROGRAM_ARB, prognum); + glProgramStringARB(GL_VERTEX_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB, + strlen(prog1), (const GLubyte *) prog1); + + assert(glIsProgramARB(prognum)); + errno = glGetError(); + printf("glGetError = %d\n", errno); + if (errno != GL_NO_ERROR) + { + GLint errorpos; + + glGetIntegerv(GL_PROGRAM_ERROR_POSITION_ARB, &errorpos); + printf("errorpos: %d\n", errorpos); + printf("%s\n", (char *)glGetString(GL_PROGRAM_ERROR_STRING_ARB)); + } + + for (i = 0; i < 4; i++) + for (j = 0; j < 4; j++) + hverts[i * 4 + j] = _mesa_float_to_half(verts[i][j]); + + glEnableClientState( GL_VERTEX_ARRAY ); + glEnableClientState( GL_COLOR_ARRAY ); + glVertexPointer( 4, GL_HALF_FLOAT, 8, hverts ); + glColorPointer( 4, GL_UNSIGNED_BYTE, 0, color ); + +} + + + +static void Display( void ) +{ + glClearColor(0.3, 0.3, 0.3, 1); + glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ); + + glEnable(GL_VERTEX_PROGRAM_NV); + glDrawElements( GL_TRIANGLES, 3, GL_UNSIGNED_INT, indices ); + + glFlush(); +} + + +static void Reshape( int width, int height ) +{ + glViewport( 0, 0, width, height ); + glMatrixMode( GL_PROJECTION ); + glLoadIdentity(); + glOrtho(-1.0, 1.0, -1.0, 1.0, -0.5, 1000.0); + glMatrixMode( GL_MODELVIEW ); + glLoadIdentity(); + /*glTranslatef( 0.0, 0.0, -15.0 );*/ +} + + +static void Key( unsigned char key, int x, int y ) +{ + (void) x; + (void) y; + switch (key) { + case 27: + exit(0); + break; + } + glutPostRedisplay(); +} + + + + +int main( int argc, char *argv[] ) +{ + glutInit( &argc, argv ); + glutInitWindowPosition( 0, 0 ); + glutInitWindowSize( 250, 250 ); + glutInitDisplayMode( GLUT_RGB | GLUT_SINGLE | GLUT_DEPTH ); + glutCreateWindow(argv[0]); + glewInit(); + glutReshapeFunc( Reshape ); + glutKeyboardFunc( Key ); + glutDisplayFunc( Display ); + Init(); + glutMainLoop(); + return 0; +} diff --git a/progs/xdemos/.gitignore b/progs/xdemos/.gitignore index 1b9b3a87c01..5ae0f5a0627 100644 --- a/progs/xdemos/.gitignore +++ b/progs/xdemos/.gitignore @@ -26,3 +26,4 @@ xdemo xfont xrotfontdemo yuvrect_client +msctest diff --git a/progs/xdemos/Makefile b/progs/xdemos/Makefile index 77f667978ce..f866a328656 100644 --- a/progs/xdemos/Makefile +++ b/progs/xdemos/Makefile @@ -29,6 +29,7 @@ PROGS = \ glxsnoop \ glxswapcontrol \ manywin \ + msctest \ multictx \ offset \ overlay \ diff --git a/progs/xdemos/corender.c b/progs/xdemos/corender.c index 640c902c136..e706f4b3da5 100644 --- a/progs/xdemos/corender.c +++ b/progs/xdemos/corender.c @@ -20,7 +20,6 @@ #include <math.h> #include <stdio.h> #include <stdlib.h> -#include <string.h> #include <X11/keysym.h> #include <unistd.h> #include "ipc.h" diff --git a/progs/xdemos/glsync.c b/progs/xdemos/glsync.c index 9d4b0f1ce20..c00ba9e4687 100644 --- a/progs/xdemos/glsync.c +++ b/progs/xdemos/glsync.c @@ -59,6 +59,7 @@ void (*video_sync_get)(); void (*video_sync)(); +void (*swap_interval)(); static int GLXExtensionSupported(Display *dpy, const char *extension) { @@ -84,7 +85,7 @@ static int GLXExtensionSupported(Display *dpy, const char *extension) extern char *optarg; extern int optind, opterr, optopt; -static char optstr[] = "w:h:s:v"; +static char optstr[] = "w:h:s:vi:"; enum sync_type { none = 0, @@ -100,6 +101,7 @@ static void usage(char *name) printf("\t\tn: none\n"); printf("\t\ts: SGI video sync extension\n"); printf("\t\tb: buffer swap\n"); + printf("\t-i<swap interval>\n"); printf("\t-v: verbose (print count)\n"); exit(-1); } @@ -109,16 +111,28 @@ int main(int argc, char *argv[]) Display *disp; XVisualInfo *pvi; XSetWindowAttributes swa; - int attrib[14]; GLint last_val = -1, count = 0; Window winGL; GLXContext context; int dummy; Atom wmDelete; enum sync_type waitforsync = none; - int width = 500, height = 500, verbose = 0, - countonly = 0; + int width = 500, height = 500, verbose = 0, interval = 1; int c, i = 1; + int ret; + int attribs[] = { GLX_RGBA, + GLX_RED_SIZE, 1, + GLX_GREEN_SIZE, 1, + GLX_BLUE_SIZE, 1, + None }; + int db_attribs[] = { GLX_RGBA, + GLX_RED_SIZE, 1, + GLX_GREEN_SIZE, 1, + GLX_BLUE_SIZE, 1, + GLX_DOUBLEBUFFER, + GLX_DEPTH_SIZE, 1, + None }; + XSizeHints sizehints; opterr = 0; while ((c = getopt(argc, argv, optstr)) != -1) { @@ -148,6 +162,9 @@ int main(int argc, char *argv[]) case 'v': verbose = 1; break; + case 'i': + interval = atoi(optarg); + break; default: usage(argv[0]); break; @@ -170,34 +187,17 @@ int main(int argc, char *argv[]) return -1; } - attrib[0] = GLX_RGBA; - attrib[1] = 1; - attrib[2] = GLX_RED_SIZE; - attrib[3] = 1; - attrib[4] = GLX_GREEN_SIZE; - attrib[5] = 1; - attrib[6] = GLX_BLUE_SIZE; - attrib[7] = 1; - if (waitforsync != buffer_swap) - attrib[8] = None; - else { - attrib[8] = GLX_DOUBLEBUFFER; - attrib[9] = 1; - attrib[10] = None; + if (waitforsync != buffer_swap) { + pvi = glXChooseVisual(disp, DefaultScreen(disp), attribs); + } else { + pvi = glXChooseVisual(disp, DefaultScreen(disp), db_attribs); } - pvi = glXChooseVisual(disp, DefaultScreen(disp), attrib); if (!pvi) { fprintf(stderr, "failed to choose visual, exiting\n"); return -1; } - context = glXCreateContext(disp, pvi, None, GL_TRUE); - if (!context) { - fprintf(stderr, "failed to create glx context\n"); - return -1; - } - pvi->screen = DefaultScreen(disp); swa.colormap = XCreateColormap(disp, RootWindow(disp, pvi->screen), @@ -217,24 +217,58 @@ int main(int argc, char *argv[]) wmDelete = XInternAtom(disp, "WM_DELETE_WINDOW", True); XSetWMProtocols(disp, winGL, &wmDelete, 1); + sizehints.x = 0; + sizehints.y = 0; + sizehints.width = width; + sizehints.height = height; + sizehints.flags = USSize | USPosition; + + XSetNormalHints(disp, winGL, &sizehints); XSetStandardProperties(disp, winGL, "glsync test", "glsync text", - None, NULL, 0, NULL); + None, NULL, 0, &sizehints); - XMapRaised(disp, winGL); + context = glXCreateContext(disp, pvi, NULL, GL_TRUE); + if (!context) { + fprintf(stderr, "failed to create glx context\n"); + return -1; + } - glXMakeCurrent(disp, winGL, context); + XMapWindow(disp, winGL); + ret = glXMakeCurrent(disp, winGL, context); + if (ret) { + fprintf(stderr, "failed to make context current: %d\n", ret); + } video_sync_get = glXGetProcAddress((unsigned char *)"glXGetVideoSyncSGI"); video_sync = glXGetProcAddress((unsigned char *)"glXWaitVideoSyncSGI"); - if (!video_sync_get || !video_sync) { + swap_interval = glXGetProcAddress((unsigned char *)"glXSwapIntervalSGI"); + + if (!video_sync_get || !video_sync || !swap_interval) { fprintf(stderr, "failed to get sync functions\n"); return -1; } + if (waitforsync == buffer_swap) { + swap_interval(interval); + fprintf(stderr, "set swap interval to %d\n", interval); + } video_sync_get(&count); count++; + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); while (i++) { + /* Alternate colors to make tearing obvious */ + if (i & 1) { + glClearColor(1.0f, 1.0f, 1.0f, 1.0f); + glColor3f(1.0f, 1.0f, 1.0f); + } else { + glClearColor(1.0f, 0.0f, 0.0f, 0.0f); + glColor3f(1.0f, 0.0f, 0.0f); + } + + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + glRectf(0, 0, width, height); + /* Wait for vsync */ if (waitforsync == sgi_video_sync) { if (verbose) @@ -245,24 +279,19 @@ int main(int argc, char *argv[]) if (count == last_val) fprintf(stderr, "error: count didn't change: %d\n", count); last_val = count; + glFlush(); } else if (waitforsync == buffer_swap) { glXSwapBuffers(disp, winGL); + } else { + video_sync_get(&count); + sleep(1); + glFinish(); } - if (countonly) { - video_sync(2, 1, &count); + if (verbose) { + video_sync_get(&count); fprintf(stderr, "current count: %d\n", count); - sleep(1); - continue; } - - /* Alternate colors to make tearing obvious */ - if (i & 1) - glClearColor(1.0f, 1.0f, 1.0f, 1.0f); - else - glClearColor(1.0f, 0.0f, 0.0f, 0.0f); - glClear(GL_COLOR_BUFFER_BIT); - glFlush(); } XDestroyWindow(disp, winGL); diff --git a/progs/xdemos/glxgears.c b/progs/xdemos/glxgears.c index 088f25a357a..92c75caa5e6 100644 --- a/progs/xdemos/glxgears.c +++ b/progs/xdemos/glxgears.c @@ -35,6 +35,7 @@ #include <X11/keysym.h> #include <GL/gl.h> #include <GL/glx.h> +#include <GL/glxext.h> #ifndef GLX_MESA_swap_control #define GLX_MESA_swap_control 1 @@ -586,11 +587,17 @@ is_glx_extension_supported(Display *dpy, const char *query) * Attempt to determine whether or not the display is synched to vblank. */ static void -query_vsync(Display *dpy) +query_vsync(Display *dpy, GLXDrawable drawable) { int interval = 0; - +#if defined(GLX_EXT_swap_control) + if (is_glx_extension_supported(dpy, "GLX_EXT_swap_control")) { + unsigned int tmp = -1; + glXQueryDrawable(dpy, drawable, GLX_SWAP_INTERVAL_EXT, &tmp); + interval = tmp; + } else +#endif if (is_glx_extension_supported(dpy, "GLX_MESA_swap_control")) { PFNGLXGETSWAPINTERVALMESAPROC pglXGetSwapIntervalMESA = (PFNGLXGETSWAPINTERVALMESAPROC) @@ -749,7 +756,7 @@ main(int argc, char *argv[]) make_window(dpy, "glxgears", x, y, winWidth, winHeight, &win, &ctx); XMapWindow(dpy, win); glXMakeCurrent(dpy, win, ctx); - query_vsync(dpy); + query_vsync(dpy, win); if (printInfo) { printf("GL_RENDERER = %s\n", (char *) glGetString(GL_RENDERER)); @@ -771,6 +778,7 @@ main(int argc, char *argv[]) glDeleteLists(gear1, 1); glDeleteLists(gear2, 1); glDeleteLists(gear3, 1); + glXMakeCurrent(dpy, None, NULL); glXDestroyContext(dpy, ctx); XDestroyWindow(dpy, win); XCloseDisplay(dpy); diff --git a/progs/xdemos/glxinfo.c b/progs/xdemos/glxinfo.c index 30cd5680642..d8710882102 100644 --- a/progs/xdemos/glxinfo.c +++ b/progs/xdemos/glxinfo.c @@ -963,7 +963,7 @@ print_visual_info(Display *dpy, int scrnum, InfoMode mode) static void print_fbconfig_info(Display *dpy, int scrnum, InfoMode mode) { - int numFBConfigs; + int numFBConfigs = 0; struct visual_attribs attribs; GLXFBConfig *fbconfigs; int i; diff --git a/progs/xdemos/manywin.c b/progs/xdemos/manywin.c index 3b0810b2e54..8ad5c4fe49f 100644 --- a/progs/xdemos/manywin.c +++ b/progs/xdemos/manywin.c @@ -400,6 +400,8 @@ main(int argc, char *argv[]) } if (n < 1) n = 1; + if (n > MAX_HEADS) + n = MAX_HEADS; printf("%d windows\n", n); for (i = 0; i < n; i++) { diff --git a/progs/xdemos/msctest.c b/progs/xdemos/msctest.c new file mode 100644 index 00000000000..001ecf04d6c --- /dev/null +++ b/progs/xdemos/msctest.c @@ -0,0 +1,202 @@ +/* + * Copyright © 2009 Intel Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + * + * Authors: + * Jesse Barnes <[email protected]> + * + */ + +/** @file msctest.c + * Simple test for MSC functionality. + */ +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> +#include <GL/gl.h> +#include <GL/glu.h> +#include <GL/glx.h> +#include <GL/glxext.h> +#include <X11/X.h> +#include <X11/Xlib.h> +#include <X11/Xutil.h> + +void (*get_sync_values)(Display *dpy, Window winGL, int64_t *ust, int64_t *msc, int64_t *sbc); +void (*wait_sync)(Display *dpy, Window winGL, int64_t target_msc, int64_t divisor, int64_t remainder, int64_t *ust, int64_t *msc, int64_t *sbc); + +static int GLXExtensionSupported(Display *dpy, const char *extension) +{ + const char *extensionsString, *client_extensions, *pos; + + extensionsString = glXQueryExtensionsString(dpy, DefaultScreen(dpy)); + client_extensions = glXGetClientString(dpy, GLX_EXTENSIONS); + + pos = strstr(extensionsString, extension); + + if (pos != NULL && (pos == extensionsString || pos[-1] == ' ') && + (pos[strlen(extension)] == ' ' || pos[strlen(extension)] == '\0')) + return 1; + + pos = strstr(client_extensions, extension); + + if (pos != NULL && (pos == extensionsString || pos[-1] == ' ') && + (pos[strlen(extension)] == ' ' || pos[strlen(extension)] == '\0')) + return 1; + + return 0; +} + +extern char *optarg; +extern int optind, opterr, optopt; +static char optstr[] = "v"; + +static void usage(char *name) +{ + printf("usage: %s\n", name); + exit(-1); +} + +int main(int argc, char *argv[]) +{ + Display *disp; + XVisualInfo *pvi; + XSetWindowAttributes swa; + int attrib[14]; + Window winGL; + GLXContext context; + int dummy; + Atom wmDelete; + int verbose = 0, width = 200, height = 200; + int c, i = 1; + int64_t ust, msc, sbc; + + opterr = 0; + while ((c = getopt(argc, argv, optstr)) != -1) { + switch (c) { + case 'v': + verbose = 1; + break; + default: + usage(argv[0]); + break; + } + } + + disp = XOpenDisplay(NULL); + if (!disp) { + fprintf(stderr, "failed to open display\n"); + return -1; + } + + if (!glXQueryExtension(disp, &dummy, &dummy)) { + fprintf(stderr, "glXQueryExtension failed\n"); + return -1; + } + + if (!GLXExtensionSupported(disp, "GLX_OML_sync_control")) { + fprintf(stderr, "GLX_OML_sync_control not supported, exiting\n"); + return -1; + } + + attrib[0] = GLX_RGBA; + attrib[1] = 1; + attrib[2] = GLX_RED_SIZE; + attrib[3] = 1; + attrib[4] = GLX_GREEN_SIZE; + attrib[5] = 1; + attrib[6] = GLX_BLUE_SIZE; + attrib[7] = 1; + attrib[8] = GLX_DOUBLEBUFFER; + attrib[9] = 1; + attrib[10] = None; + + pvi = glXChooseVisual(disp, DefaultScreen(disp), attrib); + if (!pvi) { + fprintf(stderr, "failed to choose visual, exiting\n"); + return -1; + } + + context = glXCreateContext(disp, pvi, None, GL_TRUE); + if (!context) { + fprintf(stderr, "failed to create glx context\n"); + return -1; + } + + pvi->screen = DefaultScreen(disp); + + swa.colormap = XCreateColormap(disp, RootWindow(disp, pvi->screen), + pvi->visual, AllocNone); + swa.border_pixel = 0; + swa.event_mask = ExposureMask | KeyPressMask | ButtonPressMask | + StructureNotifyMask; + winGL = XCreateWindow(disp, RootWindow(disp, pvi->screen), + 0, 0, + width, height, + 0, pvi->depth, InputOutput, pvi->visual, + CWBorderPixel | CWColormap | CWEventMask, &swa); + if (!winGL) { + fprintf(stderr, "window creation failed\n"); + return -1; + } + wmDelete = XInternAtom(disp, "WM_DELETE_WINDOW", True); + XSetWMProtocols(disp, winGL, &wmDelete, 1); + + XSetStandardProperties(disp, winGL, "msc test", "msc text", + None, NULL, 0, NULL); + + XMapRaised(disp, winGL); + + glXMakeCurrent(disp, winGL, context); + + get_sync_values = glXGetProcAddress((unsigned char *)"glXGetSyncValuesOML"); + wait_sync = glXGetProcAddress((unsigned char *)"glXWaitForMscOML"); + + if (!get_sync_values || !wait_sync) { + fprintf(stderr, "failed to get sync values function\n"); + return -1; + } + + while (i++) { + get_sync_values(disp, winGL, &ust, &msc, &sbc); + fprintf(stderr, "ust: %llu, msc: %llu, sbc: %llu\n", ust, msc, + sbc); + + /* Alternate colors to make tearing obvious */ + if (i & 1) + glClearColor(1.0f, 1.0f, 1.0f, 1.0f); + else + glClearColor(1.0f, 0.0f, 0.0f, 0.0f); + glClear(GL_COLOR_BUFFER_BIT); + glXSwapBuffers(disp, winGL); + wait_sync(disp, winGL, 0, 60, 0, &ust, &msc, &sbc); + fprintf(stderr, + "wait returned ust: %llu, msc: %llu, sbc: %llu\n", + ust, msc, sbc); + sleep(1); + } + + XDestroyWindow(disp, winGL); + glXDestroyContext(disp, context); + XCloseDisplay(disp); + + return 0; +} diff --git a/progs/xdemos/offset.c b/progs/xdemos/offset.c index 314a4fcdd17..3858a5b8020 100644 --- a/progs/xdemos/offset.c +++ b/progs/xdemos/offset.c @@ -94,6 +94,9 @@ static int attributeList[] = { GLX_RGBA, GLX_RED_SIZE, 1, GLX_GREEN_SIZE, 1, static int dimension = 3; +static float Scale = 1.0; + + int main(int argc, char** argv) { Display *dpy; XVisualInfo *vi; @@ -182,6 +185,7 @@ draw_scene(int mx, int my) { #else glEnable(GL_POLYGON_OFFSET_FILL); #endif + glScalef(Scale, Scale, Scale); cubes(mx, my, HIDDEN_LINE); #ifdef GL_EXT_polygon_offset glDisable(GL_POLYGON_OFFSET_EXT); @@ -289,6 +293,12 @@ process_input(Display *dpy, Window win) { case KeyPress: (void) XLookupString(&event.xkey, buf, sizeof(buf), &keysym, NULL); switch (keysym) { + case 'Z': + Scale *= 1.1; + break; + case 'z': + Scale *= 0.9; + break; case XK_Escape: exit(EXIT_SUCCESS); default: diff --git a/progs/xdemos/texture_from_pixmap.c b/progs/xdemos/texture_from_pixmap.c index ab215b0ac30..5f2fbc3f129 100644 --- a/progs/xdemos/texture_from_pixmap.c +++ b/progs/xdemos/texture_from_pixmap.c @@ -86,7 +86,7 @@ ChoosePixmapFBConfig(Display *display) { int screen = DefaultScreen(display); GLXFBConfig *fbconfigs; - int i, nfbconfigs, value; + int i, nfbconfigs = 0, value; fbconfigs = glXGetFBConfigs(display, screen, &nfbconfigs); for (i = 0; i < nfbconfigs; i++) { |