diff options
author | Dave Airlie <[email protected]> | 2009-04-22 21:41:57 +1000 |
---|---|---|
committer | Dave Airlie <[email protected]> | 2009-04-22 21:41:57 +1000 |
commit | 466c78c93538f2853449124c06274d538830cd5a (patch) | |
tree | a6bd88060ba328d8bed1ff2ea1a37ee741a90a17 /progs/tests | |
parent | 65fe0c86ffcff99f9f09606d462bf3731ea0c308 (diff) | |
parent | f057f6543da469f231d551cb5728d98df8add4fa (diff) |
Merge remote branch 'origin/master' into radeon-rewrite
Diffstat (limited to 'progs/tests')
-rw-r--r-- | progs/tests/Makefile | 13 | ||||
-rw-r--r-- | progs/tests/SConscript | 9 | ||||
-rw-r--r-- | progs/tests/afsmultiarb.c | 2 | ||||
-rw-r--r-- | progs/tests/dinoshade.c | 912 | ||||
-rw-r--r-- | progs/tests/fbotexture.c | 621 | ||||
-rw-r--r-- | progs/tests/glutfx.c | 189 | ||||
-rw-r--r-- | progs/tests/jkrahntest.c | 2 | ||||
-rw-r--r-- | progs/tests/mipmap_view.c | 15 | ||||
-rw-r--r-- | progs/tests/occlude.c | 234 | ||||
-rw-r--r-- | progs/tests/projtex.c | 1030 | ||||
-rw-r--r-- | progs/tests/shader_api.c | 8 | ||||
-rw-r--r-- | progs/tests/streaming_rect.c | 327 | ||||
-rw-r--r-- | progs/tests/texcompress2.c | 23 | ||||
-rw-r--r-- | progs/tests/texdown.c | 477 | ||||
-rw-r--r-- | progs/tests/texobj.c | 284 | ||||
-rw-r--r-- | progs/tests/vparray.c | 2 | ||||
-rw-r--r-- | progs/tests/vptest1.c | 2 |
17 files changed, 1569 insertions, 2581 deletions
diff --git a/progs/tests/Makefile b/progs/tests/Makefile index 58ea5690df6..f5fbf374f7a 100644 --- a/progs/tests/Makefile +++ b/progs/tests/Makefile @@ -37,19 +37,18 @@ SOURCES = \ copypixrate.c \ crossbar.c \ cva.c \ - dinoshade.c \ drawbuffers.c \ exactrast.c \ floattex.c \ fbotest1.c \ fbotest2.c \ - fbotexture.c \ fillrate.c \ fog.c \ fogcoord.c \ fptest1.c \ fptexture.c \ getprocaddress.c \ + glutfx \ interleave.c \ invert.c \ jkrahntest.c \ @@ -66,7 +65,6 @@ SOURCES = \ packedpixels.c \ pbo.c \ prog_parameter.c \ - projtex.c \ quads.c \ random.c \ readrate.c \ @@ -77,12 +75,15 @@ SOURCES = \ stencil_twoside.c \ stencilwrap.c \ stencil_wrap.c \ + streaming_rect \ subtex \ subtexrate.c \ tex1d.c \ texcompress2.c \ + texdown \ texfilt.c \ texline.c \ + texobj.c \ texobjshare.c \ texrect.c \ texwrap.c \ @@ -201,10 +202,10 @@ fillrate.o: fillrate.c readtex.h floattex: floattex.o readtex.o shaderutil.o - $(CC) $(CFLAGS) $(LDFLAGS) floattex.o readtex.o shaderutil.o $(LIBS) -o $@ + $(APP_CC) $(CFLAGS) $(LDFLAGS) floattex.o readtex.o shaderutil.o $(LIBS) -o $@ floattex.o: floattex.c readtex.h shaderutil.h - $(CC) -c $(INCLUDES) $(CFLAGS) $(DEFINES) floattex.c -o $@ + $(APP_CC) -c $(INCLUDES) $(CFLAGS) $(DEFINES) floattex.c -o $@ readtex.o: readtex.c @@ -230,7 +231,7 @@ shaderutil.h: $(TOP)/progs/util/shaderutil.h cp $< . shaderutil.o: shaderutil.c shaderutil.h - $(CC) -c -I$(INCDIR) $(CFLAGS) shaderutil.c + $(APP_CC) -c -I$(INCDIR) $(INCLUDES) $(CFLAGS) shaderutil.c diff --git a/progs/tests/SConscript b/progs/tests/SConscript index bf1e7f8a7d8..4f22ca735c1 100644 --- a/progs/tests/SConscript +++ b/progs/tests/SConscript @@ -42,8 +42,8 @@ progs = [ 'arbfptest1', 'arbfptexture', 'arbfptrig', - 'arbnpot-mipmap', 'arbnpot', + 'arbnpot-mipmap', 'arbvptest1', 'arbvptest3', 'arbvptorus', @@ -61,19 +61,18 @@ progs = [ 'copypixrate', 'crossbar', 'cva', - 'dinoshade', 'drawbuffers', 'exactrast', 'ext422square', 'fbotest1', 'fbotest2', - 'fbotexture', 'fillrate', 'floattex', 'fog', 'fogcoord', 'fptest1', 'fptexture', + 'glutfx', 'interleave', 'invert', 'lineclip', @@ -91,7 +90,6 @@ progs = [ 'packedpixels', 'pbo', 'prog_parameter', - 'projtex', 'quads', 'random', 'readrate', @@ -101,14 +99,17 @@ progs = [ 'stencil_twoside', 'stencil_wrap', 'stencilwrap', + 'streaming_rect', 'subtex', 'subtexrate', 'tex1d', 'texcmp', 'texcompress2', + 'texdown', 'texfilt', 'texgenmix', 'texline', + 'texobj', 'texrect', 'texwrap', 'unfilledclip', diff --git a/progs/tests/afsmultiarb.c b/progs/tests/afsmultiarb.c index 162ab19493c..ca25a4d75bf 100644 --- a/progs/tests/afsmultiarb.c +++ b/progs/tests/afsmultiarb.c @@ -442,8 +442,8 @@ int main( int argc, char *argv[] ) glutInitWindowSize( 300, 300 ); glutInitWindowPosition( 0, 0 ); glutInitDisplayMode( GLUT_RGB | GLUT_DOUBLE ); - glewInit(); glutCreateWindow(argv[0] ); + glewInit(); Init( argc, argv ); diff --git a/progs/tests/dinoshade.c b/progs/tests/dinoshade.c deleted file mode 100644 index fb7c3f4535c..00000000000 --- a/progs/tests/dinoshade.c +++ /dev/null @@ -1,912 +0,0 @@ - -/* Copyright (c) Mark J. Kilgard, 1994, 1997. */ - -/* This program is freely distributable without licensing fees - and is provided without guarantee or warrantee expressed or - implied. This program is -not- in the public domain. */ - -/* Example for PC game developers to show how to *combine* texturing, - reflections, and projected shadows all in real-time with OpenGL. - Robust reflections use stenciling. Robust projected shadows - use both stenciling and polygon offset. PC game programmers - should realize that neither stenciling nor polygon offset are - supported by Direct3D, so these real-time rendering algorithms - are only really viable with OpenGL. - - The program has modes for disabling the stenciling and polygon - offset uses. It is worth running this example with these features - toggled off so you can see the sort of artifacts that result. - - Notice that the floor texturing, reflections, and shadowing - all co-exist properly. */ - -/* When you run this program: Left mouse button controls the - view. Middle mouse button controls light position (left & - right rotates light around dino; up & down moves light - position up and down). Right mouse button pops up menu. */ - -/* Check out the comments in the "redraw" routine to see how the - reflection blending and surface stenciling is done. You can - also see in "redraw" how the projected shadows are rendered, - including the use of stenciling and polygon offset. */ - -/* This program is derived from glutdino.c */ - -/* Compile: cc -o dinoshade dinoshade.c -lglut -lGLU -lGL -lXmu -lXext -lX11 -lm */ - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <math.h> /* for cos(), sin(), and sqrt() */ -#include <stddef.h> /* for ptrdiff_t, referenced by GL.h when GL_GLEXT_LEGACY defined */ -#ifdef _WIN32 -#include <windows.h> -#endif -#define GL_GLEXT_LEGACY -#include <GL/glew.h> /* OpenGL Utility Toolkit header */ -#include <GL/glut.h> /* OpenGL Utility Toolkit header */ - -/* Some <math.h> files do not define M_PI... */ -#ifndef M_PI -#define M_PI 3.14159265358979323846 -#endif - -/* Variable controlling various rendering modes. */ -static int stencilReflection = 1, stencilShadow = 1, offsetShadow = 1; -static int renderShadow = 1, renderDinosaur = 1, renderReflection = 1; -static int linearFiltering = 0, useMipmaps = 0, useTexture = 1; -static int reportSpeed = 0; -static int animation = 1; -static GLboolean lightSwitch = GL_TRUE; -static int directionalLight = 1; -static int forceExtension = 0; - -/* Time varying or user-controled variables. */ -static float jump = 0.0; -static float lightAngle = 0.0, lightHeight = 20; -GLfloat angle = -150; /* in degrees */ -GLfloat angle2 = 30; /* in degrees */ - -int moving, startx, starty; -int lightMoving = 0, lightStartX, lightStartY; - -enum { - MISSING, EXTENSION, ONE_DOT_ONE -}; -int polygonOffsetVersion; - -static GLdouble bodyWidth = 3.0; -/* *INDENT-OFF* */ -static GLfloat body[][2] = { {0, 3}, {1, 1}, {5, 1}, {8, 4}, {10, 4}, {11, 5}, - {11, 11.5}, {13, 12}, {13, 13}, {10, 13.5}, {13, 14}, {13, 15}, {11, 16}, - {8, 16}, {7, 15}, {7, 13}, {8, 12}, {7, 11}, {6, 6}, {4, 3}, {3, 2}, - {1, 2} }; -static GLfloat arm[][2] = { {8, 10}, {9, 9}, {10, 9}, {13, 8}, {14, 9}, {16, 9}, - {15, 9.5}, {16, 10}, {15, 10}, {15.5, 11}, {14.5, 10}, {14, 11}, {14, 10}, - {13, 9}, {11, 11}, {9, 11} }; -static GLfloat leg[][2] = { {8, 6}, {8, 4}, {9, 3}, {9, 2}, {8, 1}, {8, 0.5}, {9, 0}, - {12, 0}, {10, 1}, {10, 2}, {12, 4}, {11, 6}, {10, 7}, {9, 7} }; -static GLfloat eye[][2] = { {8.75, 15}, {9, 14.7}, {9.6, 14.7}, {10.1, 15}, - {9.6, 15.25}, {9, 15.25} }; -static GLfloat lightPosition[4]; -static GLfloat lightColor[] = {0.8, 1.0, 0.8, 1.0}; /* green-tinted */ -static GLfloat skinColor[] = {0.1, 1.0, 0.1, 1.0}, eyeColor[] = {1.0, 0.2, 0.2, 1.0}; -/* *INDENT-ON* */ - -/* Nice floor texture tiling pattern. */ -static char *circles[] = { - "....xxxx........", - "..xxxxxxxx......", - ".xxxxxxxxxx.....", - ".xxx....xxx.....", - "xxx......xxx....", - "xxx......xxx....", - "xxx......xxx....", - "xxx......xxx....", - ".xxx....xxx.....", - ".xxxxxxxxxx.....", - "..xxxxxxxx......", - "....xxxx........", - "................", - "................", - "................", - "................", -}; - -static void -makeFloorTexture(void) -{ - GLubyte floorTexture[16][16][3]; - GLubyte *loc; - int s, t; - - /* Setup RGB image for the texture. */ - loc = (GLubyte*) floorTexture; - for (t = 0; t < 16; t++) { - for (s = 0; s < 16; s++) { - if (circles[t][s] == 'x') { - /* Nice green. */ - loc[0] = 0x1f; - loc[1] = 0x8f; - loc[2] = 0x1f; - } else { - /* Light gray. */ - loc[0] = 0xaa; - loc[1] = 0xaa; - loc[2] = 0xaa; - } - loc += 3; - } - } - - glPixelStorei(GL_UNPACK_ALIGNMENT, 1); - - if (useMipmaps) { - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, - GL_LINEAR_MIPMAP_LINEAR); - gluBuild2DMipmaps(GL_TEXTURE_2D, 3, 16, 16, - GL_RGB, GL_UNSIGNED_BYTE, floorTexture); - } else { - if (linearFiltering) { - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - } else { - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - } - glTexImage2D(GL_TEXTURE_2D, 0, 3, 16, 16, 0, - GL_RGB, GL_UNSIGNED_BYTE, floorTexture); - } -} - -enum { - X, Y, Z, W -}; -enum { - A, B, C, D -}; - -/* Create a matrix that will project the desired shadow. */ -void -shadowMatrix(GLfloat shadowMat[4][4], - GLfloat groundplane[4], - GLfloat lightpos[4]) -{ - GLfloat dot; - - /* Find dot product between light position vector and ground plane normal. */ - dot = groundplane[X] * lightpos[X] + - groundplane[Y] * lightpos[Y] + - groundplane[Z] * lightpos[Z] + - groundplane[W] * lightpos[W]; - - shadowMat[0][0] = dot - lightpos[X] * groundplane[X]; - shadowMat[1][0] = 0.f - lightpos[X] * groundplane[Y]; - shadowMat[2][0] = 0.f - lightpos[X] * groundplane[Z]; - shadowMat[3][0] = 0.f - lightpos[X] * groundplane[W]; - - shadowMat[X][1] = 0.f - lightpos[Y] * groundplane[X]; - shadowMat[1][1] = dot - lightpos[Y] * groundplane[Y]; - shadowMat[2][1] = 0.f - lightpos[Y] * groundplane[Z]; - shadowMat[3][1] = 0.f - lightpos[Y] * groundplane[W]; - - shadowMat[X][2] = 0.f - lightpos[Z] * groundplane[X]; - shadowMat[1][2] = 0.f - lightpos[Z] * groundplane[Y]; - shadowMat[2][2] = dot - lightpos[Z] * groundplane[Z]; - shadowMat[3][2] = 0.f - lightpos[Z] * groundplane[W]; - - shadowMat[X][3] = 0.f - lightpos[W] * groundplane[X]; - shadowMat[1][3] = 0.f - lightpos[W] * groundplane[Y]; - shadowMat[2][3] = 0.f - lightpos[W] * groundplane[Z]; - shadowMat[3][3] = dot - lightpos[W] * groundplane[W]; - -} - -/* Find the plane equation given 3 points. */ -void -findPlane(GLfloat plane[4], - GLfloat v0[3], GLfloat v1[3], GLfloat v2[3]) -{ - GLfloat vec0[3], vec1[3]; - - /* Need 2 vectors to find cross product. */ - vec0[X] = v1[X] - v0[X]; - vec0[Y] = v1[Y] - v0[Y]; - vec0[Z] = v1[Z] - v0[Z]; - - vec1[X] = v2[X] - v0[X]; - vec1[Y] = v2[Y] - v0[Y]; - vec1[Z] = v2[Z] - v0[Z]; - - /* find cross product to get A, B, and C of plane equation */ - plane[A] = vec0[Y] * vec1[Z] - vec0[Z] * vec1[Y]; - plane[B] = -(vec0[X] * vec1[Z] - vec0[Z] * vec1[X]); - plane[C] = vec0[X] * vec1[Y] - vec0[Y] * vec1[X]; - - plane[D] = -(plane[A] * v0[X] + plane[B] * v0[Y] + plane[C] * v0[Z]); -} - -void -extrudeSolidFromPolygon(GLfloat data[][2], unsigned int dataSize, - GLdouble thickness, GLuint side, GLuint edge, GLuint whole) -{ - static GLUtriangulatorObj *tobj = NULL; - GLdouble vertex[3], dx, dy, len; - int i; - int count = (int) (dataSize / (2 * sizeof(GLfloat))); - - if (tobj == NULL) { - tobj = gluNewTess(); /* create and initialize a GLU - polygon tesselation object */ - gluTessCallback(tobj, GLU_BEGIN, glBegin); - gluTessCallback(tobj, GLU_VERTEX, glVertex2fv); /* semi-tricky */ - gluTessCallback(tobj, GLU_END, glEnd); - } - glNewList(side, GL_COMPILE); - glShadeModel(GL_SMOOTH); /* smooth minimizes seeing - tessellation */ - gluBeginPolygon(tobj); - for (i = 0; i < count; i++) { - vertex[0] = data[i][0]; - vertex[1] = data[i][1]; - vertex[2] = 0; - gluTessVertex(tobj, vertex, data[i]); - } - gluEndPolygon(tobj); - glEndList(); - glNewList(edge, GL_COMPILE); - glShadeModel(GL_FLAT); /* flat shade keeps angular hands - from being "smoothed" */ - glBegin(GL_QUAD_STRIP); - for (i = 0; i <= count; i++) { -#if 1 /* weird, but seems to be legal */ - /* mod function handles closing the edge */ - glVertex3f(data[i % count][0], data[i % count][1], 0.0); - glVertex3f(data[i % count][0], data[i % count][1], thickness); - /* Calculate a unit normal by dividing by Euclidean - distance. We * could be lazy and use - glEnable(GL_NORMALIZE) so we could pass in * arbitrary - normals for a very slight performance hit. */ - dx = data[(i + 1) % count][1] - data[i % count][1]; - dy = data[i % count][0] - data[(i + 1) % count][0]; - len = sqrt(dx * dx + dy * dy); - glNormal3f(dx / len, dy / len, 0.0); -#else /* the nice way of doing it */ - /* Calculate a unit normal by dividing by Euclidean - distance. We * could be lazy and use - glEnable(GL_NORMALIZE) so we could pass in * arbitrary - normals for a very slight performance hit. */ - dx = data[i % count][1] - data[(i - 1 + count) % count][1]; - dy = data[(i - 1 + count) % count][0] - data[i % count][0]; - len = sqrt(dx * dx + dy * dy); - glNormal3f(dx / len, dy / len, 0.0); - /* mod function handles closing the edge */ - glVertex3f(data[i % count][0], data[i % count][1], 0.0); - glVertex3f(data[i % count][0], data[i % count][1], thickness); -#endif - } - glEnd(); - glEndList(); - glNewList(whole, GL_COMPILE); - glFrontFace(GL_CW); - glCallList(edge); - glNormal3f(0.0, 0.0, -1.0); /* constant normal for side */ - glCallList(side); - glPushMatrix(); - glTranslatef(0.0, 0.0, thickness); - glFrontFace(GL_CCW); - glNormal3f(0.0, 0.0, 1.0); /* opposite normal for other side */ - glCallList(side); - glPopMatrix(); - glEndList(); -} - -/* Enumerants for refering to display lists. */ -typedef enum { - RESERVED, BODY_SIDE, BODY_EDGE, BODY_WHOLE, ARM_SIDE, ARM_EDGE, ARM_WHOLE, - LEG_SIDE, LEG_EDGE, LEG_WHOLE, EYE_SIDE, EYE_EDGE, EYE_WHOLE -} displayLists; - -static void -makeDinosaur(void) -{ - extrudeSolidFromPolygon(body, sizeof(body), bodyWidth, - BODY_SIDE, BODY_EDGE, BODY_WHOLE); - extrudeSolidFromPolygon(arm, sizeof(arm), bodyWidth / 4, - ARM_SIDE, ARM_EDGE, ARM_WHOLE); - extrudeSolidFromPolygon(leg, sizeof(leg), bodyWidth / 2, - LEG_SIDE, LEG_EDGE, LEG_WHOLE); - extrudeSolidFromPolygon(eye, sizeof(eye), bodyWidth + 0.2, - EYE_SIDE, EYE_EDGE, EYE_WHOLE); -} - -static void -drawDinosaur(void) - -{ - glPushMatrix(); - /* Translate the dinosaur to be at (0,8,0). */ - glTranslatef(-8, 0, -bodyWidth / 2); - glTranslatef(0.0, jump, 0.0); - glMaterialfv(GL_FRONT, GL_DIFFUSE, skinColor); - glCallList(BODY_WHOLE); - glTranslatef(0.0, 0.0, bodyWidth); - glCallList(ARM_WHOLE); - glCallList(LEG_WHOLE); - glTranslatef(0.0, 0.0, -bodyWidth - bodyWidth / 4); - glCallList(ARM_WHOLE); - glTranslatef(0.0, 0.0, -bodyWidth / 4); - glCallList(LEG_WHOLE); - glTranslatef(0.0, 0.0, bodyWidth / 2 - 0.1); - glMaterialfv(GL_FRONT, GL_DIFFUSE, eyeColor); - glCallList(EYE_WHOLE); - glPopMatrix(); -} - -static GLfloat floorVertices[4][3] = { - { -20.0, 0.0, 20.0 }, - { 20.0, 0.0, 20.0 }, - { 20.0, 0.0, -20.0 }, - { -20.0, 0.0, -20.0 }, -}; - -/* Draw a floor (possibly textured). */ -static void -drawFloor(void) -{ - glDisable(GL_LIGHTING); - - if (useTexture) { - glEnable(GL_TEXTURE_2D); - } - - glBegin(GL_QUADS); - glTexCoord2f(0.0, 0.0); - glVertex3fv(floorVertices[0]); - glTexCoord2f(0.0, 16.0); - glVertex3fv(floorVertices[1]); - glTexCoord2f(16.0, 16.0); - glVertex3fv(floorVertices[2]); - glTexCoord2f(16.0, 0.0); - glVertex3fv(floorVertices[3]); - glEnd(); - - if (useTexture) { - glDisable(GL_TEXTURE_2D); - } - - glEnable(GL_LIGHTING); -} - -static GLfloat floorPlane[4]; -static GLfloat floorShadow[4][4]; - -static void -redraw(void) -{ - int start, end; - - if (reportSpeed) { - start = glutGet(GLUT_ELAPSED_TIME); - } - - /* Clear; default stencil clears to zero. */ - if ((stencilReflection && renderReflection) || (stencilShadow && renderShadow)) { - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); - } else { - /* Avoid clearing stencil when not using it. */ - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - } - - /* Reposition the light source. */ - lightPosition[0] = 12*cos(lightAngle); - lightPosition[1] = lightHeight; - lightPosition[2] = 12*sin(lightAngle); - if (directionalLight) { - lightPosition[3] = 0.0; - } else { - lightPosition[3] = 1.0; - } - - shadowMatrix(floorShadow, floorPlane, lightPosition); - - glPushMatrix(); - /* Perform scene rotations based on user mouse input. */ - glRotatef(angle2, 1.0, 0.0, 0.0); - glRotatef(angle, 0.0, 1.0, 0.0); - - /* Tell GL new light source position. */ - glLightfv(GL_LIGHT0, GL_POSITION, lightPosition); - - if (renderReflection) { - if (stencilReflection) { - /* We can eliminate the visual "artifact" of seeing the "flipped" - dinosaur underneath the floor by using stencil. The idea is - draw the floor without color or depth update but so that - a stencil value of one is where the floor will be. Later when - rendering the dinosaur reflection, we will only update pixels - with a stencil value of 1 to make sure the reflection only - lives on the floor, not below the floor. */ - - /* Don't update color or depth. */ - glDisable(GL_DEPTH_TEST); - glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); - - /* Draw 1 into the stencil buffer. */ - glEnable(GL_STENCIL_TEST); - glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE); - glStencilFunc(GL_ALWAYS, 1, 0xffffffff); - - /* Now render floor; floor pixels just get their stencil set to 1. */ - drawFloor(); - - /* Re-enable update of color and depth. */ - glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); - glEnable(GL_DEPTH_TEST); - - /* Now, only render where stencil is set to 1. */ - glStencilFunc(GL_EQUAL, 1, 0xffffffff); /* draw if ==1 */ - glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP); - } - - glPushMatrix(); - - /* The critical reflection step: Reflect dinosaur through the floor - (the Y=0 plane) to make a relection. */ - glScalef(1.0, -1.0, 1.0); - - /* Reflect the light position. */ - glLightfv(GL_LIGHT0, GL_POSITION, lightPosition); - - /* To avoid our normals getting reversed and hence botched lighting - on the reflection, turn on normalize. */ - glEnable(GL_NORMALIZE); - glCullFace(GL_FRONT); - - /* Draw the reflected dinosaur. */ - drawDinosaur(); - - /* Disable noramlize again and re-enable back face culling. */ - glDisable(GL_NORMALIZE); - glCullFace(GL_BACK); - - glPopMatrix(); - - /* Switch back to the unreflected light position. */ - glLightfv(GL_LIGHT0, GL_POSITION, lightPosition); - - if (stencilReflection) { - glDisable(GL_STENCIL_TEST); - } - } - - /* Back face culling will get used to only draw either the top or the - bottom floor. This let's us get a floor with two distinct - appearances. The top floor surface is reflective and kind of red. - The bottom floor surface is not reflective and blue. */ - - /* Draw "bottom" of floor in blue. */ - glFrontFace(GL_CW); /* Switch face orientation. */ - glColor4f(0.1, 0.1, 0.7, 1.0); - drawFloor(); - glFrontFace(GL_CCW); - - if (renderShadow) { - if (stencilShadow) { - /* Draw the floor with stencil value 3. This helps us only - draw the shadow once per floor pixel (and only on the - floor pixels). */ - glEnable(GL_STENCIL_TEST); - glStencilFunc(GL_ALWAYS, 3, 0xffffffff); - glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE); - } - } - - /* Draw "top" of floor. Use blending to blend in reflection. */ - glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - glColor4f(0.7, 0.0, 0.0, 0.3); - glColor4f(1.0, 1.0, 1.0, 0.3); - drawFloor(); - glDisable(GL_BLEND); - - if (renderDinosaur) { - /* Draw "actual" dinosaur, not its reflection. */ - drawDinosaur(); - } - - if (renderShadow) { - - /* Render the projected shadow. */ - - if (stencilShadow) { - - /* Now, only render where stencil is set above 2 (ie, 3 where - the top floor is). Update stencil with 2 where the shadow - gets drawn so we don't redraw (and accidently reblend) the - shadow). */ - glStencilFunc(GL_LESS, 2, 0xffffffff); /* draw if ==1 */ - glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE); - } - - /* To eliminate depth buffer artifacts, we use polygon offset - to raise the depth of the projected shadow slightly so - that it does not depth buffer alias with the floor. */ - if (offsetShadow) { - switch (polygonOffsetVersion) { - case EXTENSION: -#ifdef GL_EXT_polygon_offset - glEnable(GL_POLYGON_OFFSET_EXT); - break; -#endif -#ifdef GL_VERSION_1_1 - case ONE_DOT_ONE: - glEnable(GL_POLYGON_OFFSET_FILL); - break; -#endif - case MISSING: - /* Oh well. */ - break; - } - } - - /* Render 50% black shadow color on top of whatever the - floor appareance is. */ - glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - glDisable(GL_LIGHTING); /* Force the 50% black. */ - glColor4f(0.0, 0.0, 0.0, 0.5); - - glPushMatrix(); - /* Project the shadow. */ - glMultMatrixf((GLfloat *) floorShadow); - drawDinosaur(); - glPopMatrix(); - - glDisable(GL_BLEND); - glEnable(GL_LIGHTING); - - if (offsetShadow) { - switch (polygonOffsetVersion) { -#ifdef GL_EXT_polygon_offset - case EXTENSION: - glDisable(GL_POLYGON_OFFSET_EXT); - break; -#endif -#ifdef GL_VERSION_1_1 - case ONE_DOT_ONE: - glDisable(GL_POLYGON_OFFSET_FILL); - break; -#endif - case MISSING: - /* Oh well. */ - break; - } - } - if (stencilShadow) { - glDisable(GL_STENCIL_TEST); - } - } - - glPushMatrix(); - glDisable(GL_LIGHTING); - glColor3f(1.0, 1.0, 0.0); - if (directionalLight) { - /* Draw an arrowhead. */ - glDisable(GL_CULL_FACE); - glTranslatef(lightPosition[0], lightPosition[1], lightPosition[2]); - glRotatef(lightAngle * -180.0 / M_PI, 0, 1, 0); - glRotatef(atan(lightHeight/12) * 180.0 / M_PI, 0, 0, 1); - glBegin(GL_TRIANGLE_FAN); - glVertex3f(0, 0, 0); - glVertex3f(2, 1, 1); - glVertex3f(2, -1, 1); - glVertex3f(2, -1, -1); - glVertex3f(2, 1, -1); - glVertex3f(2, 1, 1); - glEnd(); - /* Draw a white line from light direction. */ - glColor3f(1.0, 1.0, 1.0); - glBegin(GL_LINES); - glVertex3f(0, 0, 0); - glVertex3f(5, 0, 0); - glEnd(); - glEnable(GL_CULL_FACE); - } else { - /* Draw a yellow ball at the light source. */ - glTranslatef(lightPosition[0], lightPosition[1], lightPosition[2]); - glutSolidSphere(1.0, 5, 5); - } - glEnable(GL_LIGHTING); - glPopMatrix(); - - glPopMatrix(); - - if (reportSpeed) { - glFinish(); - end = glutGet(GLUT_ELAPSED_TIME); - printf("Speed %.3g frames/sec (%d ms)\n", 1000.0/(end-start), end-start); - } - - glutSwapBuffers(); -} - -/* ARGSUSED2 */ -static void -mouse(int button, int state, int x, int y) -{ - if (button == GLUT_LEFT_BUTTON) { - if (state == GLUT_DOWN) { - moving = 1; - startx = x; - starty = y; - } - if (state == GLUT_UP) { - moving = 0; - } - } - if (button == GLUT_MIDDLE_BUTTON) { - if (state == GLUT_DOWN) { - lightMoving = 1; - lightStartX = x; - lightStartY = y; - } - if (state == GLUT_UP) { - lightMoving = 0; - } - } -} - -/* ARGSUSED1 */ -static void -motion(int x, int y) -{ - if (moving) { - angle = angle + (x - startx); - angle2 = angle2 + (y - starty); - startx = x; - starty = y; - glutPostRedisplay(); - } - if (lightMoving) { - lightAngle += (x - lightStartX)/40.0; - lightHeight += (lightStartY - y)/20.0; - lightStartX = x; - lightStartY = y; - glutPostRedisplay(); - } -} - -/* Advance time varying state when idle callback registered. */ -static void -idle(void) -{ - static float time = 0.0; - - time = glutGet(GLUT_ELAPSED_TIME) / 500.0; - - jump = 4.0 * fabs(sin(time)*0.5); - if (!lightMoving) { - lightAngle += 0.03; - } - glutPostRedisplay(); -} - -enum { - M_NONE, M_MOTION, M_LIGHT, M_TEXTURE, M_SHADOWS, M_REFLECTION, M_DINOSAUR, - M_STENCIL_REFLECTION, M_STENCIL_SHADOW, M_OFFSET_SHADOW, - M_POSITIONAL, M_DIRECTIONAL, M_PERFORMANCE -}; - -static void -controlLights(int value) -{ - switch (value) { - case M_NONE: - return; - case M_MOTION: - animation = 1 - animation; - if (animation) { - glutIdleFunc(idle); - } else { - glutIdleFunc(NULL); - } - break; - case M_LIGHT: - lightSwitch = !lightSwitch; - if (lightSwitch) { - glEnable(GL_LIGHT0); - } else { - glDisable(GL_LIGHT0); - } - break; - case M_TEXTURE: - useTexture = !useTexture; - break; - case M_SHADOWS: - renderShadow = 1 - renderShadow; - break; - case M_REFLECTION: - renderReflection = 1 - renderReflection; - break; - case M_DINOSAUR: - renderDinosaur = 1 - renderDinosaur; - break; - case M_STENCIL_REFLECTION: - stencilReflection = 1 - stencilReflection; - break; - case M_STENCIL_SHADOW: - stencilShadow = 1 - stencilShadow; - break; - case M_OFFSET_SHADOW: - offsetShadow = 1 - offsetShadow; - break; - case M_POSITIONAL: - directionalLight = 0; - break; - case M_DIRECTIONAL: - directionalLight = 1; - break; - case M_PERFORMANCE: - reportSpeed = 1 - reportSpeed; - break; - } - glutPostRedisplay(); -} - -/* When not visible, stop animating. Restart when visible again. */ -static void -visible(int vis) -{ - if (vis == GLUT_VISIBLE) { - if (animation) - glutIdleFunc(idle); - } else { - if (!animation) - glutIdleFunc(NULL); - } -} - -/* Press any key to redraw; good when motion stopped and - performance reporting on. */ -/* ARGSUSED */ -static void -key(unsigned char c, int x, int y) -{ - if (c == 27) { - exit(0); /* IRIS GLism, Escape quits. */ - } - glutPostRedisplay(); -} - -/* Press any key to redraw; good when motion stopped and - performance reporting on. */ -/* ARGSUSED */ -static void -special(int k, int x, int y) -{ - glutPostRedisplay(); -} - -static int -supportsOneDotOne(void) -{ - const char *version; - int major, minor; - - version = (char *) glGetString(GL_VERSION); - if (sscanf(version, "%d.%d", &major, &minor) == 2) - return major * 10 + minor >= 11; - return 0; /* OpenGL version string malformed! */ -} - -int -main(int argc, char **argv) -{ - int i; - - glutInit(&argc, argv); - - for (i=1; i<argc; i++) { - if (!strcmp("-linear", argv[i])) { - linearFiltering = 1; - } else if (!strcmp("-mipmap", argv[i])) { - useMipmaps = 1; - } else if (!strcmp("-ext", argv[i])) { - forceExtension = 1; - } - } - - glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH | GLUT_STENCIL); - -#if 0 - /* In GLUT 4.0, you'll be able to do this an be sure to - get 2 bits of stencil if the machine has it for you. */ - glutInitDisplayString("samples stencil>=2 rgb double depth"); -#endif - - glutCreateWindow("Shadowy Leapin' Lizards"); - glewInit(); - - if (glutGet(GLUT_WINDOW_STENCIL_SIZE) <= 1) { - printf("dinoshade: Sorry, I need at least 2 bits of stencil.\n"); - exit(1); - } - - /* Register GLUT callbacks. */ - glutDisplayFunc(redraw); - glutMouseFunc(mouse); - glutMotionFunc(motion); - glutVisibilityFunc(visible); - glutKeyboardFunc(key); - glutSpecialFunc(special); - - glutCreateMenu(controlLights); - - glutAddMenuEntry("Toggle motion", M_MOTION); - glutAddMenuEntry("-----------------------", M_NONE); - glutAddMenuEntry("Toggle light", M_LIGHT); - glutAddMenuEntry("Toggle texture", M_TEXTURE); - glutAddMenuEntry("Toggle shadows", M_SHADOWS); - glutAddMenuEntry("Toggle reflection", M_REFLECTION); - glutAddMenuEntry("Toggle dinosaur", M_DINOSAUR); - glutAddMenuEntry("-----------------------", M_NONE); - glutAddMenuEntry("Toggle reflection stenciling", M_STENCIL_REFLECTION); - glutAddMenuEntry("Toggle shadow stenciling", M_STENCIL_SHADOW); - glutAddMenuEntry("Toggle shadow offset", M_OFFSET_SHADOW); - glutAddMenuEntry("----------------------", M_NONE); - glutAddMenuEntry("Positional light", M_POSITIONAL); - glutAddMenuEntry("Directional light", M_DIRECTIONAL); - glutAddMenuEntry("-----------------------", M_NONE); - glutAddMenuEntry("Toggle performance", M_PERFORMANCE); - glutAttachMenu(GLUT_RIGHT_BUTTON); - makeDinosaur(); - -#ifdef GL_VERSION_1_1 - if (supportsOneDotOne() && !forceExtension) { - polygonOffsetVersion = ONE_DOT_ONE; - glPolygonOffset(-2.0, -9.0); - } else -#endif - { -#ifdef GL_EXT_polygon_offset - /* check for the polygon offset extension */ - if (glutExtensionSupported("GL_EXT_polygon_offset")) { - polygonOffsetVersion = EXTENSION; - glPolygonOffsetEXT(-2.0, -0.002); - } else -#endif - { - polygonOffsetVersion = MISSING; - printf("\ndinoshine: Missing polygon offset.\n"); - printf(" Expect shadow depth aliasing artifacts.\n\n"); - } - } - - glEnable(GL_CULL_FACE); - glEnable(GL_DEPTH_TEST); - glEnable(GL_TEXTURE_2D); - glLineWidth(3.0); - - glMatrixMode(GL_PROJECTION); - gluPerspective( /* field of view in degree */ 40.0, - /* aspect ratio */ 1.0, - /* Z near */ 20.0, /* Z far */ 100.0); - glMatrixMode(GL_MODELVIEW); - gluLookAt(0.0, 8.0, 60.0, /* eye is at (0,8,60) */ - 0.0, 8.0, 0.0, /* center is at (0,8,0) */ - 0.0, 1.0, 0.); /* up is in postivie Y direction */ - - glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, 1); - glLightfv(GL_LIGHT0, GL_DIFFUSE, lightColor); - glLightf(GL_LIGHT0, GL_CONSTANT_ATTENUATION, 0.1); - glLightf(GL_LIGHT0, GL_LINEAR_ATTENUATION, 0.05); - glEnable(GL_LIGHT0); - glEnable(GL_LIGHTING); - - makeFloorTexture(); - - /* Setup floor plane for projected shadow calculations. */ - findPlane(floorPlane, floorVertices[1], floorVertices[2], floorVertices[3]); - - glutMainLoop(); - return 0; /* ANSI C requires main to return int. */ -} diff --git a/progs/tests/fbotexture.c b/progs/tests/fbotexture.c deleted file mode 100644 index 50a4b00afce..00000000000 --- a/progs/tests/fbotexture.c +++ /dev/null @@ -1,621 +0,0 @@ -/* - * Test GL_EXT_framebuffer_object render-to-texture - * - * Draw a teapot into a texture image with stenciling. - * Then draw a textured quad using that texture. - * - * Brian Paul - * 18 Apr 2005 - */ - - -#include <GL/glew.h> -#include <GL/glut.h> -#include <assert.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <math.h> - -/* For debug */ -#define DEPTH 1 -#define STENCIL 1 -#define DRAW 1 - - -static int Win = 0; -static int Width = 400, Height = 400; - -#if 1 -static GLenum TexTarget = GL_TEXTURE_2D; -static int TexWidth = 512, TexHeight = 512; -static GLenum TexIntFormat = GL_RGB; /* either GL_RGB or GL_RGBA */ -#else -static GLenum TexTarget = GL_TEXTURE_RECTANGLE_ARB; -static int TexWidth = 200, TexHeight = 200; -static GLenum TexIntFormat = GL_RGB5; /* either GL_RGB or GL_RGBA */ -#endif -static GLuint TextureLevel = 0; /* which texture level to render to */ - -static GLuint MyFB; -static GLuint TexObj; -static GLuint DepthRB = 0, StencilRB = 0; -static GLboolean Anim = GL_FALSE; -static GLfloat Rot = 0.0; -static GLboolean UsePackedDepthStencil = GL_FALSE; -static GLboolean UsePackedDepthStencilBoth = GL_FALSE; -static GLboolean Use_ARB_fbo = GL_FALSE; -static GLboolean Cull = GL_FALSE; -static GLboolean Wireframe = GL_FALSE; - - -static void -CheckError(int line) -{ - GLenum err = glGetError(); - if (err) { - printf("GL Error 0x%x at line %d\n", (int) err, line); - } -} - - -static void -Idle(void) -{ - Rot = glutGet(GLUT_ELAPSED_TIME) * 0.1; - glutPostRedisplay(); -} - - -static void -RenderTexture(void) -{ - GLenum status; - - glMatrixMode(GL_PROJECTION); - glLoadIdentity(); - glOrtho(-1.0, 1.0, -1.0, 1.0, 5.0, 25.0); - glMatrixMode(GL_MODELVIEW); - glLoadIdentity(); - glTranslatef(0.0, 0.0, -15.0); - - /* draw to texture image */ - glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, MyFB); - - status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT); - if (status != GL_FRAMEBUFFER_COMPLETE_EXT) { - printf("Framebuffer incomplete!!!\n"); - } - - glViewport(0, 0, TexWidth, TexHeight); - - glClearColor(0.5, 0.5, 1.0, 0.0); - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); - CheckError(__LINE__); - -#if DEPTH - glEnable(GL_DEPTH_TEST); -#endif - -#if STENCIL - glEnable(GL_STENCIL_TEST); - glStencilFunc(GL_NEVER, 1, ~0); - glStencilOp(GL_REPLACE, GL_KEEP, GL_REPLACE); -#endif - - CheckError(__LINE__); - -#if DEPTH || STENCIL - /* draw diamond-shaped stencil pattern */ - glColor3f(0, 1, 0); - glBegin(GL_POLYGON); - glVertex2f(-0.2, 0.0); - glVertex2f( 0.0, -0.2); - glVertex2f( 0.2, 0.0); - glVertex2f( 0.0, 0.2); - glEnd(); -#endif - - /* draw teapot where stencil != 1 */ -#if STENCIL - glStencilFunc(GL_NOTEQUAL, 1, ~0); - glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP); -#endif - - CheckError(__LINE__); - - if (Wireframe) { - glPolygonMode(GL_FRONT, GL_LINE); - } - else { - glPolygonMode(GL_FRONT, GL_FILL); - } - - if (Cull) { - /* cull back */ - glCullFace(GL_BACK); - glEnable(GL_CULL_FACE); - } - else { - glDisable(GL_CULL_FACE); - } - -#if 0 - glBegin(GL_POLYGON); - glColor3f(1, 0, 0); - glVertex2f(-1, -1); - glColor3f(0, 1, 0); - glVertex2f(1, -1); - glColor3f(0, 0, 1); - glVertex2f(0, 1); - glEnd(); -#else - glEnable(GL_LIGHTING); - glEnable(GL_LIGHT0); - glPushMatrix(); - glRotatef(0.5 * Rot, 1.0, 0.0, 0.0); - glFrontFace(GL_CW); /* Teapot patches backward */ - glutSolidTeapot(0.5); - glFrontFace(GL_CCW); - glPopMatrix(); - glDisable(GL_LIGHTING); - /* - PrintStencilHistogram(TexWidth, TexHeight); - */ -#endif - - glDisable(GL_DEPTH_TEST); - glDisable(GL_STENCIL_TEST); - glDisable(GL_CULL_FACE); - glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); - -#if DRAW - /* Bind normal framebuffer */ - glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); -#endif - - CheckError(__LINE__); -} - - - -static void -Display(void) -{ - float ar = (float) Width / (float) Height; - - RenderTexture(); - - /* draw textured quad in the window */ -#if DRAW - glMatrixMode(GL_PROJECTION); - glLoadIdentity(); - glFrustum(-ar, ar, -1.0, 1.0, 5.0, 25.0); - glMatrixMode(GL_MODELVIEW); - glLoadIdentity(); - glTranslatef(0.0, 0.0, -7.0); - - glViewport(0, 0, Width, Height); - - glClearColor(0.25, 0.25, 0.25, 0); - glClear(GL_COLOR_BUFFER_BIT); - - glPushMatrix(); - glRotatef(Rot, 0, 1, 0); - glEnable(TexTarget); - glBindTexture(TexTarget, TexObj); - glBegin(GL_POLYGON); - glColor3f(0.25, 0.25, 0.25); - if (TexTarget == GL_TEXTURE_2D) { - glTexCoord2f(0, 0); - glVertex2f(-1, -1); - glTexCoord2f(1, 0); - glVertex2f(1, -1); - glColor3f(1.0, 1.0, 1.0); - glTexCoord2f(1, 1); - glVertex2f(1, 1); - glTexCoord2f(0, 1); - glVertex2f(-1, 1); - } - else { - assert(TexTarget == GL_TEXTURE_RECTANGLE_ARB); - glTexCoord2f(0, 0); - glVertex2f(-1, -1); - glTexCoord2f(TexWidth, 0); - glVertex2f(1, -1); - glColor3f(1.0, 1.0, 1.0); - glTexCoord2f(TexWidth, TexHeight); - glVertex2f(1, 1); - glTexCoord2f(0, TexHeight); - glVertex2f(-1, 1); - } - glEnd(); - glPopMatrix(); - glDisable(TexTarget); -#endif - - glutSwapBuffers(); - CheckError(__LINE__); -} - - -static void -Reshape(int width, int height) -{ - glViewport(0, 0, width, height); - Width = width; - Height = height; -} - - -static void -CleanUp(void) -{ -#if DEPTH - glDeleteRenderbuffersEXT(1, &DepthRB); -#endif -#if STENCIL - glDeleteRenderbuffersEXT(1, &StencilRB); -#endif - glDeleteFramebuffersEXT(1, &MyFB); - - glDeleteTextures(1, &TexObj); - - glutDestroyWindow(Win); - - exit(0); -} - - -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 'c': - Cull = !Cull; - break; - case 'w': - Wireframe = !Wireframe; - break; - case 's': - Rot += 2.0; - break; - case 'S': - Rot -= 2.0; - break; - case 27: - CleanUp(); - break; - } - glutPostRedisplay(); -} - - -/** - * Attach depth and stencil renderbuffer(s) to the given framebuffer object. - * \param tryDepthStencil if true, try to use a combined depth+stencil buffer - * \param bindDepthStencil if true, and tryDepthStencil is true, bind with - * the GL_DEPTH_STENCIL_ATTACHMENT target. - * \return GL_TRUE for success, GL_FALSE for failure - */ -static GLboolean -AttachDepthAndStencilBuffers(GLuint fbo, - GLsizei width, GLsizei height, - GLboolean tryDepthStencil, - GLboolean bindDepthStencil, - GLuint *depthRbOut, GLuint *stencilRbOut) -{ - GLenum status; - - *depthRbOut = *stencilRbOut = 0; - - glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo); - - if (tryDepthStencil) { - GLuint rb; - - glGenRenderbuffersEXT(1, &rb); - glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, rb); - glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, - GL_DEPTH24_STENCIL8_EXT, - width, height); - if (glGetError()) - return GL_FALSE; - - if (bindDepthStencil) { - /* attach to both depth and stencil at once */ - glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, - GL_DEPTH_STENCIL_ATTACHMENT, - GL_RENDERBUFFER_EXT, rb); - if (glGetError()) - return GL_FALSE; - } - else { - /* attach to depth attachment point */ - glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, - GL_DEPTH_ATTACHMENT_EXT, - GL_RENDERBUFFER_EXT, rb); - if (glGetError()) - return GL_FALSE; - - /* and attach to stencil attachment point */ - glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, - GL_STENCIL_ATTACHMENT_EXT, - GL_RENDERBUFFER_EXT, rb); - if (glGetError()) - return GL_FALSE; - } - - status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT); - if (status != GL_FRAMEBUFFER_COMPLETE_EXT) - return GL_FALSE; - - *depthRbOut = *stencilRbOut = rb; - return GL_TRUE; - } - - /* just depth renderbuffer */ - { - GLuint rb; - - glGenRenderbuffersEXT(1, &rb); - glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, rb); - glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, - GL_DEPTH_COMPONENT, - width, height); - if (glGetError()) - return GL_FALSE; - - /* attach to depth attachment point */ - glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, - GL_DEPTH_ATTACHMENT_EXT, - GL_RENDERBUFFER_EXT, rb); - if (glGetError()) - return GL_FALSE; - - status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT); - if (status != GL_FRAMEBUFFER_COMPLETE_EXT) - return GL_FALSE; - - *depthRbOut = rb; - } - - /* just stencil renderbuffer */ - { - GLuint rb; - - glGenRenderbuffersEXT(1, &rb); - glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, rb); - glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, - GL_STENCIL_INDEX, - width, height); - if (glGetError()) - return GL_FALSE; - - /* attach to depth attachment point */ - glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, - GL_STENCIL_ATTACHMENT_EXT, - GL_RENDERBUFFER_EXT, rb); - if (glGetError()) - return GL_FALSE; - - status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT); - if (status != GL_FRAMEBUFFER_COMPLETE_EXT) { - glDeleteRenderbuffersEXT(1, depthRbOut); - *depthRbOut = 0; - glDeleteRenderbuffersEXT(1, &rb); - return GL_FALSE; - } - - *stencilRbOut = rb; - } - - return GL_TRUE; -} - - -static void -ParseArgs(int argc, char *argv[]) -{ - GLint i; - for (i = 1; i < argc; i++) { - if (strcmp(argv[i], "-ds") == 0) { - if (!glutExtensionSupported("GL_EXT_packed_depth_stencil")) { - printf("GL_EXT_packed_depth_stencil not found!\n"); - exit(0); - } - UsePackedDepthStencil = GL_TRUE; - printf("Using GL_EXT_packed_depth_stencil\n"); - } - else if (strcmp(argv[i], "-ds2") == 0) { - if (!glutExtensionSupported("GL_EXT_packed_depth_stencil")) { - printf("GL_EXT_packed_depth_stencil not found!\n"); - exit(0); - } - if (!glutExtensionSupported("GL_ARB_framebuffer_object")) { - printf("GL_ARB_framebuffer_object not found!\n"); - exit(0); - } - UsePackedDepthStencilBoth = GL_TRUE; - printf("Using GL_EXT_packed_depth_stencil and GL_DEPTH_STENCIL attachment point\n"); - } - else if (strcmp(argv[i], "-arb") == 0) { - if (!glutExtensionSupported("GL_ARB_framebuffer_object")) { - printf("Sorry, GL_ARB_framebuffer object not supported!\n"); - } - else { - Use_ARB_fbo = GL_TRUE; - } - } - else { - printf("Unknown option: %s\n", argv[i]); - } - } -} - - -/* - * Make FBO to render into given texture. - */ -static GLuint -MakeFBO_RenderTexture(GLuint TexObj) -{ - GLuint fb; - GLint sizeFudge = 0; - - glGenFramebuffersEXT(1, &fb); - glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fb); - /* Render color to texture */ - glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, - TexTarget, TexObj, TextureLevel); - - if (Use_ARB_fbo) { - /* use a smaller depth buffer to see what happens */ - sizeFudge = 90; - } - - /* Setup depth and stencil buffers */ - { - GLboolean b; - b = AttachDepthAndStencilBuffers(fb, - TexWidth - sizeFudge, - TexHeight - sizeFudge, - UsePackedDepthStencil, - UsePackedDepthStencilBoth, - &DepthRB, &StencilRB); - if (!b) { - /* try !UsePackedDepthStencil */ - b = AttachDepthAndStencilBuffers(fb, - TexWidth - sizeFudge, - TexHeight - sizeFudge, - !UsePackedDepthStencil, - UsePackedDepthStencilBoth, - &DepthRB, &StencilRB); - } - if (!b) { - printf("Unable to create/attach depth and stencil renderbuffers " - " to FBO!\n"); - exit(1); - } - } - - /* queries */ - { - GLint bits, w, h; - - glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, DepthRB); - glGetRenderbufferParameterivEXT(GL_RENDERBUFFER_EXT, - GL_RENDERBUFFER_WIDTH_EXT, &w); - glGetRenderbufferParameterivEXT(GL_RENDERBUFFER_EXT, - GL_RENDERBUFFER_HEIGHT_EXT, &h); - printf("Color/Texture size: %d x %d\n", TexWidth, TexHeight); - printf("Depth buffer size: %d x %d\n", w, h); - - glGetRenderbufferParameterivEXT(GL_RENDERBUFFER_EXT, - GL_RENDERBUFFER_DEPTH_SIZE_EXT, &bits); - printf("Depth renderbuffer size = %d bits\n", bits); - - glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, StencilRB); - glGetRenderbufferParameterivEXT(GL_RENDERBUFFER_EXT, - GL_RENDERBUFFER_STENCIL_SIZE_EXT, &bits); - printf("Stencil renderbuffer size = %d bits\n", bits); - } - - /* bind the regular framebuffer */ - glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); - - return fb; -} - - -static void -Init(void) -{ - if (!glutExtensionSupported("GL_EXT_framebuffer_object")) { - printf("GL_EXT_framebuffer_object not found!\n"); - exit(0); - } - - printf("GL_RENDERER = %s\n", (char *) glGetString(GL_RENDERER)); - - /* lighting */ - { - static const GLfloat mat[4] = { 1.0, 0.5, 0.5, 1.0 }; - glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, mat); - } - - /* - * Make texture object/image (we'll render into this texture) - */ - { - glGenTextures(1, &TexObj); - glBindTexture(TexTarget, TexObj); - - /* make two image levels */ - glTexImage2D(TexTarget, 0, TexIntFormat, TexWidth, TexHeight, 0, - GL_RGBA, GL_UNSIGNED_BYTE, NULL); - if (TexTarget == GL_TEXTURE_2D) { - glTexImage2D(TexTarget, 1, TexIntFormat, TexWidth/2, TexHeight/2, 0, - GL_RGBA, GL_UNSIGNED_BYTE, NULL); - TexWidth = TexWidth >> TextureLevel; - TexHeight = TexHeight >> TextureLevel; - glTexParameteri(TexTarget, GL_TEXTURE_MAX_LEVEL, TextureLevel); - } - - glTexParameteri(TexTarget, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(TexTarget, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glTexParameteri(TexTarget, GL_TEXTURE_BASE_LEVEL, TextureLevel); - glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); - } - - MyFB = MakeFBO_RenderTexture(TexObj); -} - - -static void -Usage(void) -{ - printf("Usage:\n"); - printf(" -ds Use combined depth/stencil renderbuffer\n"); - printf(" -arb Try GL_ARB_framebuffer_object's mismatched buffer sizes\n"); - printf(" -ds2 Try GL_ARB_framebuffer_object's GL_DEPTH_STENCIL_ATTACHMENT\n"); - printf("Keys:\n"); - printf(" a Toggle animation\n"); - printf(" s/s Step/rotate\n"); - printf(" c Toggle back-face culling\n"); - printf(" w Toggle wireframe mode (front-face only)\n"); - printf(" Esc Exit\n"); -} - - -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 (Anim) - glutIdleFunc(Idle); - - ParseArgs(argc, argv); - Init(); - Usage(); - - glutMainLoop(); - return 0; -} diff --git a/progs/tests/glutfx.c b/progs/tests/glutfx.c new file mode 100644 index 00000000000..8bf55823897 --- /dev/null +++ b/progs/tests/glutfx.c @@ -0,0 +1,189 @@ + +/* + * Example of how one might use GLUT with the 3Dfx driver in full-screen mode. + * Note: this only works with X since we're using Mesa's GLX "hack" for + * using Glide. + * + * Goals: + * easy setup and input event handling with GLUT + * use 3Dfx hardware + * automatically set MESA environment variables + * don't lose mouse input focus + * + * Brian Paul This file is in the public domain. + */ + + +#include <stdio.h> +#include <stdlib.h> +#include <math.h> +#include <GL/glut.h> + + +#define WIDTH 640 +#define HEIGHT 480 + + +static int Window = 0; +static int ScreenWidth, ScreenHeight; +static GLuint Torus = 0; +static GLfloat Xrot = 0.0, Yrot = 0.0; + + + +static void Display( void ) +{ + static GLfloat blue[4] = {0.2, 0.2, 1.0, 1.0}; + static GLfloat red[4] = {1.0, 0.2, 0.2, 1.0}; + static GLfloat green[4] = {0.2, 1.0, 0.2, 1.0}; + + glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ); + + glPushMatrix(); + glRotatef(Xrot, 1, 0, 0); + glRotatef(Yrot, 0, 1, 0); + + glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, blue); + glCallList(Torus); + + glRotatef(90.0, 1, 0, 0); + glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, red); + glCallList(Torus); + + glRotatef(90.0, 0, 1, 0); + glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, green); + glCallList(Torus); + + glPopMatrix(); + + glutSwapBuffers(); +} + + +static void Reshape( int width, int height ) +{ + float ratio = (float) width / (float) height; + + ScreenWidth = width; + ScreenHeight = height; + + /* + * The 3Dfx driver is limited to 640 x 480 but the X window may be larger. + * Enforce that here. + */ + if (width > WIDTH) + width = WIDTH; + if (height > HEIGHT) + height = HEIGHT; + + glViewport( 0, 0, width, height ); + glMatrixMode( GL_PROJECTION ); + glLoadIdentity(); + glFrustum( -ratio, ratio, -1.0, 1.0, 5.0, 30.0 ); + glMatrixMode( GL_MODELVIEW ); + glLoadIdentity(); + glTranslatef( 0.0, 0.0, -20.0 ); +} + + +static void Key( unsigned char key, int x, int y ) +{ + (void) x; + (void) y; + switch (key) { + case 27: + glutDestroyWindow(Window); + exit(0); + break; + } + glutPostRedisplay(); +} + + +static void SpecialKey( int key, int x, int y ) +{ + (void) x; + (void) y; + switch (key) { + case GLUT_KEY_UP: + break; + case GLUT_KEY_DOWN: + break; + case GLUT_KEY_LEFT: + break; + case GLUT_KEY_RIGHT: + break; + } + glutPostRedisplay(); +} + + +static void MouseMove( int x, int y ) +{ + Xrot = y - ScreenWidth / 2; + Yrot = x - ScreenHeight / 2; + glutPostRedisplay(); +} + + +static void Init( void ) +{ + Torus = glGenLists(1); + glNewList(Torus, GL_COMPILE); + glutSolidTorus(0.5, 2.0, 10, 20); + glEndList(); + + glEnable(GL_LIGHTING); + glEnable(GL_LIGHT0); + + glEnable(GL_DEPTH_TEST); + glEnable(GL_CULL_FACE); +} + + +int main( int argc, char *argv[] ) +{ +#ifndef _WIN32 + printf("NOTE: if you've got 3Dfx VooDoo hardware you must run this"); + printf(" program as root.\n\n"); + printf("Move the mouse. Press ESC to exit.\n\n"); +#endif + + /* Tell Mesa GLX to use 3Dfx driver in fullscreen mode. */ + putenv("MESA_GLX_FX=fullscreen"); + + /* Disable 3Dfx Glide splash screen */ + putenv("FX_GLIDE_NO_SPLASH="); + + /* Give an initial size and position so user doesn't have to place window */ + glutInitWindowPosition(0, 0); + glutInitWindowSize(WIDTH, HEIGHT); + glutInit( &argc, argv ); + + glutInitDisplayMode( GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH ); + + Window = glutCreateWindow(argv[0]); + if (!Window) { + printf("Error, couldn't open window\n"); + exit(1); + } + + /* + * Want the X window to fill the screen so that we don't have to + * worry about losing the mouse input focus. + * Note that we won't actually see the X window since we never draw + * to it, hence, the original X screen's contents aren't disturbed. + */ + glutFullScreen(); + + Init(); + + glutReshapeFunc( Reshape ); + glutKeyboardFunc( Key ); + glutSpecialFunc( SpecialKey ); + glutDisplayFunc( Display ); + glutPassiveMotionFunc( MouseMove ); + + glutMainLoop(); + return 0; +} diff --git a/progs/tests/jkrahntest.c b/progs/tests/jkrahntest.c index 08660b8932e..3fef105fc2c 100644 --- a/progs/tests/jkrahntest.c +++ b/progs/tests/jkrahntest.c @@ -45,7 +45,7 @@ int main(int argc, char **argv) if (argc < 2) { fprintf(stderr, "This program tests GLX context switching.\n"); - fprintf(stderr, "Usage: cxbug <n>\n"); + fprintf(stderr, "Usage: jkrahntest <n>\n"); fprintf(stderr, "Where n is:\n"); fprintf(stderr, "\t1) Use two contexts and swap only when the context is current (typical case).\n"); fprintf(stderr, "\t2) Use two contexts and swap at the same time.\n"); diff --git a/progs/tests/mipmap_view.c b/progs/tests/mipmap_view.c index 16f3584f703..85fc67ac79f 100644 --- a/progs/tests/mipmap_view.c +++ b/progs/tests/mipmap_view.c @@ -22,6 +22,7 @@ static int TexWidth = 256, TexHeight = 256; static int WinWidth = 1044, WinHeight = 900; static GLfloat Bias = 0.0; static GLboolean ScaleQuads = GL_FALSE; +static GLboolean Linear = GL_FALSE; static GLint Win = 0; @@ -53,6 +54,15 @@ Display(void) glColor3f(1,1,1); + if (Linear) { + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + } + else { + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + } + y = WinHeight - 300; x = 4; @@ -132,6 +142,9 @@ Key(unsigned char key, int x, int y) case 'B': Bias += 10; break; + case 'l': + Linear = !Linear; + break; case '0': case '1': case '2': @@ -222,8 +235,6 @@ Init(void) /* mipmapping required for this extension */ - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); glGetFloatv(GL_MAX_TEXTURE_LOD_BIAS_EXT, &maxBias); diff --git a/progs/tests/occlude.c b/progs/tests/occlude.c new file mode 100644 index 00000000000..8f7b90984e0 --- /dev/null +++ b/progs/tests/occlude.c @@ -0,0 +1,234 @@ +/* + * GL_HP_occlustion_test demo + * + * Brian Paul + * 31 March 2000 + * + * Copyright (C) 2000 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 <math.h> +#include <GL/glut.h> +#include <GL/glext.h> + + +static GLfloat Xpos = 0; +static GLboolean Anim = GL_TRUE; + + +static void +PrintString(const char *s) +{ + while (*s) { + glutBitmapCharacter(GLUT_BITMAP_8_BY_13, (int) *s); + s++; + } +} + + + +static void Idle(void) +{ + static int lastTime = 0; + static int sign = +1; + int time = glutGet(GLUT_ELAPSED_TIME); + float step; + + if (lastTime == 0) + lastTime = time; + else if (time - lastTime < 20) /* 50Hz update */ + return; + + step = (time - lastTime) / 1000.0 * sign; + lastTime = time; + + Xpos += step; + + if (Xpos > 2.5) { + Xpos = 2.5; + sign = -1; + } + else if (Xpos < -2.5) { + Xpos = -2.5; + sign = +1; + } + glutPostRedisplay(); +} + + +static void Display( void ) +{ + GLboolean result; + + glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ); + + 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 ); + + /* draw the occluding polygons */ + glColor3f(0, 0.6, 0.8); + glBegin(GL_QUADS); + glVertex2f(-1.6, -1.5); + glVertex2f(-0.4, -1.5); + glVertex2f(-0.4, 1.5); + glVertex2f(-1.6, 1.5); + + glVertex2f( 0.4, -1.5); + glVertex2f( 1.6, -1.5); + glVertex2f( 1.6, 1.5); + glVertex2f( 0.4, 1.5); + glEnd(); + + /* draw the test polygon with occlusion testing */ + glPushMatrix(); + glTranslatef(Xpos, 0, -0.5); + glScalef(0.3, 0.3, 1.0); + glRotatef(-90.0 * Xpos, 0, 0, 1); + + glEnable(GL_OCCLUSION_TEST_HP); /* NOTE: enabling the occlusion test */ + /* doesn't clear the result flag! */ + glColorMask(0, 0, 0, 0); + glDepthMask(GL_FALSE); + /* this call clear's the result flag. Not really needed for this demo. */ + glGetBooleanv(GL_OCCLUSION_TEST_RESULT_HP, &result); + + glBegin(GL_POLYGON); + glVertex3f(-1, -1, 0); + glVertex3f( 1, -1, 0); + glVertex3f( 1, 1, 0); + glVertex3f(-1, 1, 0); + glEnd(); + + glGetBooleanv(GL_OCCLUSION_TEST_RESULT_HP, &result); + /* turn off occlusion testing */ + glDisable(GL_OCCLUSION_TEST_HP); + glColorMask(1, 1, 1, 1); + glDepthMask(GL_TRUE); + + /* draw the green rect, so we can see what's going on */ + glColor3f(0.8, 0.5, 0); + glBegin(GL_POLYGON); + glVertex3f(-1, -1, 0); + glVertex3f( 1, -1, 0); + glVertex3f( 1, 1, 0); + glVertex3f(-1, 1, 0); + glEnd(); + + glPopMatrix(); + + + /* Print result message */ + glMatrixMode( GL_PROJECTION ); + glLoadIdentity(); + glOrtho( -1.0, 1.0, -1.0, 1.0, -1.0, 1.0 ); + glMatrixMode( GL_MODELVIEW ); + glLoadIdentity(); + + glColor3f(1, 1, 1); + glRasterPos3f(-0.25, -0.7, 0); + + if (result) + PrintString(" Visible"); + else + PrintString("Fully Occluded"); + + glutSwapBuffers(); +} + + +static void Reshape( int width, int height ) +{ + glViewport( 0, 0, width, height ); +} + + +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: + exit(0); + break; + } + glutPostRedisplay(); +} + + +static void SpecialKey( int key, int x, int y ) +{ + const GLfloat step = 0.1; + (void) x; + (void) y; + switch (key) { + case GLUT_KEY_LEFT: + Xpos -= step; + break; + case GLUT_KEY_RIGHT: + Xpos += step; + break; + } + glutPostRedisplay(); +} + + +static void Init( void ) +{ + const char *ext = (const char *) glGetString(GL_EXTENSIONS); + if (!strstr(ext, "GL_HP_occlusion_test")) { + printf("Sorry, this demo requires the GL_HP_occlusion_test extension\n"); + exit(-1); + } + + glEnable(GL_DEPTH_TEST); +} + + +int main( int argc, char *argv[] ) +{ + glutInit( &argc, argv ); + glutInitWindowPosition( 0, 0 ); + glutInitWindowSize( 400, 400 ); + glutInitDisplayMode( GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH ); + glutCreateWindow(argv[0]); + glutReshapeFunc( Reshape ); + glutKeyboardFunc( Key ); + glutSpecialFunc( SpecialKey ); + glutIdleFunc( Idle ); + glutDisplayFunc( Display ); + Init(); + glutMainLoop(); + return 0; +} diff --git a/progs/tests/projtex.c b/progs/tests/projtex.c deleted file mode 100644 index 800d81ecd67..00000000000 --- a/progs/tests/projtex.c +++ /dev/null @@ -1,1030 +0,0 @@ - -/* projtex.c - by David Yu and David Blythe, SGI */ - -/** - ** Demonstrates simple projective texture mapping. - ** - ** Button1 changes view, Button2 moves texture. - ** - ** (See: Segal, Korobkin, van Widenfelt, Foran, and Haeberli - ** "Fast Shadows and Lighting Effects Using Texture Mapping", SIGGRAPH '92) - ** - ** 1994,1995 -- David G Yu - ** - ** cc -o projtex projtex.c texture.c -lglut -lGLU -lGL -lX11 -lm - **/ - -#include <assert.h> -#include <stdio.h> -#include <stdlib.h> -#include <math.h> -#include <GL/glew.h> -#include <GL/glut.h> -#if 0 -#include "texture.h" -#else -#include "../util/readtex.c" -#endif - - -/* Some <math.h> files do not define M_PI... */ -#ifndef M_PI -#define M_PI 3.14159265358979323846 -#endif - -#define MAX_TEX 4 -int NumTextures = 1; - -int winWidth, winHeight; - -GLboolean redrawContinuously = GL_FALSE; - -float angle, axis[3]; -enum MoveModes { - MoveNone, MoveView, MoveObject, MoveTexture -}; -enum MoveModes mode = MoveNone; - -GLfloat objectXform[4][4]; -GLfloat textureXform[MAX_TEX][4][4]; - -void (*drawObject) (void); -void (*loadTexture) (void); -GLboolean textureEnabled = GL_TRUE; -GLboolean showProjection = GL_TRUE; -GLboolean linearFilter = GL_TRUE; - -char *texFilename[MAX_TEX] = { - "../images/girl.rgb", - "../images/tile.rgb", - "../images/bw.rgb", - "../images/reflect.rgb" -}; - - -GLfloat zoomFactor = 1.0; - -/*****************************************************************/ - - -void ActiveTexture(int i) -{ - glActiveTextureARB(i); -} - - -/* matrix = identity */ -void -matrixIdentity(GLfloat matrix[16]) -{ - matrix[0] = 1.0; - matrix[1] = 0.0; - matrix[2] = 0.0; - matrix[3] = 0.0; - matrix[4] = 0.0; - matrix[5] = 1.0; - matrix[6] = 0.0; - matrix[7] = 0.0; - matrix[8] = 0.0; - matrix[9] = 0.0; - matrix[10] = 1.0; - matrix[11] = 0.0; - matrix[12] = 0.0; - matrix[13] = 0.0; - matrix[14] = 0.0; - matrix[15] = 1.0; -} - -/* matrix2 = transpose(matrix1) */ -void -matrixTranspose(GLfloat matrix2[16], GLfloat matrix1[16]) -{ - matrix2[0] = matrix1[0]; - matrix2[1] = matrix1[4]; - matrix2[2] = matrix1[8]; - matrix2[3] = matrix1[12]; - - matrix2[4] = matrix1[1]; - matrix2[5] = matrix1[5]; - matrix2[6] = matrix1[9]; - matrix2[7] = matrix1[13]; - - matrix2[8] = matrix1[2]; - matrix2[9] = matrix1[6]; - matrix2[10] = matrix1[10]; - matrix2[11] = matrix1[14]; - - matrix2[12] = matrix1[3]; - matrix2[13] = matrix1[7]; - matrix2[14] = matrix1[14]; - matrix2[15] = matrix1[15]; -} - -/*****************************************************************/ - -/* load SGI .rgb image (pad with a border of the specified width and color) */ -#if 0 -static void -imgLoad(char *filenameIn, int borderIn, GLfloat borderColorIn[4], - int *wOut, int *hOut, GLubyte ** imgOut) -{ - int border = borderIn; - int width, height; - int w, h; - GLubyte *image, *img, *p; - int i, j, components; - - image = (GLubyte *) read_texture(filenameIn, &width, &height, &components); - w = width + 2 * border; - h = height + 2 * border; - img = (GLubyte *) calloc(w * h, 4 * sizeof(unsigned char)); - - p = img; - for (j = -border; j < height + border; ++j) { - for (i = -border; i < width + border; ++i) { - if (0 <= j && j <= height - 1 && 0 <= i && i <= width - 1) { - p[0] = image[4 * (j * width + i) + 0]; - p[1] = image[4 * (j * width + i) + 1]; - p[2] = image[4 * (j * width + i) + 2]; - p[3] = 0xff; - } else { - p[0] = borderColorIn[0] * 0xff; - p[1] = borderColorIn[1] * 0xff; - p[2] = borderColorIn[2] * 0xff; - p[3] = borderColorIn[3] * 0xff; - } - p += 4; - } - } - free(image); - *wOut = w; - *hOut = h; - *imgOut = img; -} -#endif - - -/*****************************************************************/ - -/* Load the image file specified on the command line as the current texture */ -void -loadImageTextures(void) -{ - GLfloat borderColor[4] = - {1.0, 1.0, 1.0, 1.0}; - int tex; - - for (tex = 0; tex < NumTextures; tex++) { - GLubyte *image, *texData3, *texData4; - GLint imgWidth, imgHeight; - GLenum imgFormat; - int i, j; - - printf("loading %s\n", texFilename[tex]); - image = LoadRGBImage(texFilename[tex], &imgWidth, &imgHeight, &imgFormat); - if (!image) { - printf("can't find %s\n", texFilename[tex]); - exit(1); - } - assert(imgFormat == GL_RGB); - - /* scale to 256x256 */ - texData3 = malloc(256 * 256 * 4); - texData4 = malloc(256 * 256 * 4); - assert(texData3); - assert(texData4); - gluScaleImage(imgFormat, imgWidth, imgHeight, GL_UNSIGNED_BYTE, image, - 256, 256, GL_UNSIGNED_BYTE, texData3); - - /* convert to rgba */ - for (i = 0; i < 256 * 256; i++) { - texData4[i*4+0] = texData3[i*3+0]; - texData4[i*4+1] = texData3[i*3+1]; - texData4[i*4+2] = texData3[i*3+2]; - texData4[i*4+3] = 128; - } - - /* put transparent border around image */ - for (i = 0; i < 256; i++) { - texData4[i*4+0] = 255; - texData4[i*4+1] = 255; - texData4[i*4+2] = 255; - texData4[i*4+3] = 0; - } - j = 256 * 255 * 4; - for (i = 0; i < 256; i++) { - texData4[j + i*4+0] = 255; - texData4[j + i*4+1] = 255; - texData4[j + i*4+2] = 255; - texData4[j + i*4+3] = 0; - } - for (i = 0; i < 256; i++) { - j = i * 256 * 4; - texData4[j+0] = 255; - texData4[j+1] = 255; - texData4[j+2] = 255; - texData4[j+3] = 0; - } - for (i = 0; i < 256; i++) { - j = i * 256 * 4 + 255 * 4; - texData4[j+0] = 255; - texData4[j+1] = 255; - texData4[j+2] = 255; - texData4[j+3] = 0; - } - - ActiveTexture(GL_TEXTURE0_ARB + tex); - glBindTexture(GL_TEXTURE_2D, tex + 1); - - glPixelStorei(GL_UNPACK_ALIGNMENT, 1); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 256, 256, 0, - GL_RGBA, GL_UNSIGNED_BYTE, texData4); - - if (linearFilter) { - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - } else { - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - } - glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, borderColor); - } -} - -/* Create a simple spotlight pattern and make it the current texture */ -void -loadSpotlightTexture(void) -{ - static int texWidth = 64, texHeight = 64; - static GLubyte *texData; - GLfloat borderColor[4] = - {0.1, 0.1, 0.1, 1.0}; - - if (!texData) { - GLubyte *p; - int i, j; - - texData = (GLubyte *) malloc(texWidth * texHeight * 4 * sizeof(GLubyte)); - - p = texData; - for (j = 0; j < texHeight; ++j) { - float dy = (texHeight * 0.5 - j + 0.5) / (texHeight * 0.5); - - for (i = 0; i < texWidth; ++i) { - float dx = (texWidth * 0.5 - i + 0.5) / (texWidth * 0.5); - float r = cos(M_PI / 2.0 * sqrt(dx * dx + dy * dy)); - float c; - - r = (r < 0) ? 0 : r * r; - c = 0xff * (r + borderColor[0]); - p[0] = (c <= 0xff) ? c : 0xff; - c = 0xff * (r + borderColor[1]); - p[1] = (c <= 0xff) ? c : 0xff; - c = 0xff * (r + borderColor[2]); - p[2] = (c <= 0xff) ? c : 0xff; - c = 0xff * (r + borderColor[3]); - p[3] = (c <= 0xff) ? c : 0xff; - p += 4; - } - } - } - if (linearFilter) { - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - } else { - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - } - glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, borderColor); - gluBuild2DMipmaps(GL_TEXTURE_2D, 4, texWidth, texHeight, - GL_RGBA, GL_UNSIGNED_BYTE, texData); -} - -/*****************************************************************/ - -void -checkErrors(void) -{ - GLenum error; - while ((error = glGetError()) != GL_NO_ERROR) { - fprintf(stderr, "Error: %s\n", (char *) gluErrorString(error)); - } -} - -void -drawCube(void) -{ - glBegin(GL_QUADS); - - glNormal3f(-1.0, 0.0, 0.0); - glColor3f(0.80, 0.50, 0.50); - glVertex3f(-0.5, -0.5, -0.5); - glVertex3f(-0.5, -0.5, 0.5); - glVertex3f(-0.5, 0.5, 0.5); - glVertex3f(-0.5, 0.5, -0.5); - - glNormal3f(1.0, 0.0, 0.0); - glColor3f(0.50, 0.80, 0.50); - glVertex3f(0.5, 0.5, 0.5); - glVertex3f(0.5, -0.5, 0.5); - glVertex3f(0.5, -0.5, -0.5); - glVertex3f(0.5, 0.5, -0.5); - - glNormal3f(0.0, -1.0, 0.0); - glColor3f(0.50, 0.50, 0.80); - glVertex3f(-0.5, -0.5, -0.5); - glVertex3f(0.5, -0.5, -0.5); - glVertex3f(0.5, -0.5, 0.5); - glVertex3f(-0.5, -0.5, 0.5); - - glNormal3f(0.0, 1.0, 0.0); - glColor3f(0.50, 0.80, 0.80); - glVertex3f(0.5, 0.5, 0.5); - glVertex3f(0.5, 0.5, -0.5); - glVertex3f(-0.5, 0.5, -0.5); - glVertex3f(-0.5, 0.5, 0.5); - - glNormal3f(0.0, 0.0, -1.0); - glColor3f(0.80, 0.50, 0.80); - glVertex3f(-0.5, -0.5, -0.5); - glVertex3f(-0.5, 0.5, -0.5); - glVertex3f(0.5, 0.5, -0.5); - glVertex3f(0.5, -0.5, -0.5); - - glNormal3f(0.0, 0.0, 1.0); - glColor3f(1.00, 0.80, 0.50); - glVertex3f(0.5, 0.5, 0.5); - glVertex3f(-0.5, 0.5, 0.5); - glVertex3f(-0.5, -0.5, 0.5); - glVertex3f(0.5, -0.5, 0.5); - glEnd(); -} - -void -drawDodecahedron(void) -{ -#define A (0.5 * 1.61803) /* (sqrt(5) + 1) / 2 */ -#define B (0.5 * 0.61803) /* (sqrt(5) - 1) / 2 */ -#define C (0.5 * 1.0) - GLfloat vertexes[20][3] = - { - {-A, 0.0, B}, - {-A, 0.0, -B}, - {A, 0.0, -B}, - {A, 0.0, B}, - {B, -A, 0.0}, - {-B, -A, 0.0}, - {-B, A, 0.0}, - {B, A, 0.0}, - {0.0, B, -A}, - {0.0, -B, -A}, - {0.0, -B, A}, - {0.0, B, A}, - {-C, -C, C}, - {-C, -C, -C}, - {C, -C, -C}, - {C, -C, C}, - {-C, C, C}, - {-C, C, -C}, - {C, C, -C}, - {C, C, C}, - }; -#undef A -#undef B -#undef C - GLint polygons[12][5] = - { - {0, 12, 10, 11, 16}, - {1, 17, 8, 9, 13}, - {2, 14, 9, 8, 18}, - {3, 19, 11, 10, 15}, - {4, 14, 2, 3, 15}, - {5, 12, 0, 1, 13}, - {6, 17, 1, 0, 16}, - {7, 19, 3, 2, 18}, - {8, 17, 6, 7, 18}, - {9, 14, 4, 5, 13}, - {10, 12, 5, 4, 15}, - {11, 19, 7, 6, 16}, - }; - int i; - - glColor3f(0.75, 0.75, 0.75); - for (i = 0; i < 12; ++i) { - GLfloat *p0, *p1, *p2, d; - GLfloat u[3], v[3], n[3]; - - p0 = &vertexes[polygons[i][0]][0]; - p1 = &vertexes[polygons[i][1]][0]; - p2 = &vertexes[polygons[i][2]][0]; - - u[0] = p2[0] - p1[0]; - u[1] = p2[1] - p1[1]; - u[2] = p2[2] - p1[2]; - - v[0] = p0[0] - p1[0]; - v[1] = p0[1] - p1[1]; - v[2] = p0[2] - p1[2]; - - n[0] = u[1] * v[2] - u[2] * v[1]; - n[1] = u[2] * v[0] - u[0] * v[2]; - n[2] = u[0] * v[1] - u[1] * v[0]; - - d = 1.0 / sqrt(n[0] * n[0] + n[1] * n[1] + n[2] * n[2]); - n[0] *= d; - n[1] *= d; - n[2] *= d; - - glBegin(GL_POLYGON); - glNormal3fv(n); - glVertex3fv(p0); - glVertex3fv(p1); - glVertex3fv(p2); - glVertex3fv(vertexes[polygons[i][3]]); - glVertex3fv(vertexes[polygons[i][4]]); - glEnd(); - } -} - -void -drawSphere(void) -{ - int numMajor = 24; - int numMinor = 32; - float radius = 0.8; - double majorStep = (M_PI / numMajor); - double minorStep = (2.0 * M_PI / numMinor); - int i, j; - - glColor3f(0.50, 0.50, 0.50); - for (i = 0; i < numMajor; ++i) { - double a = i * majorStep; - double b = a + majorStep; - double r0 = radius * sin(a); - double r1 = radius * sin(b); - GLfloat z0 = radius * cos(a); - GLfloat z1 = radius * cos(b); - - glBegin(GL_TRIANGLE_STRIP); - for (j = 0; j <= numMinor; ++j) { - double c = j * minorStep; - GLfloat x = cos(c); - GLfloat y = sin(c); - - glNormal3f((x * r0) / radius, (y * r0) / radius, z0 / radius); - glTexCoord2f(j / (GLfloat) numMinor, i / (GLfloat) numMajor); - glVertex3f(x * r0, y * r0, z0); - - glNormal3f((x * r1) / radius, (y * r1) / radius, z1 / radius); - glTexCoord2f(j / (GLfloat) numMinor, (i + 1) / (GLfloat) numMajor); - glVertex3f(x * r1, y * r1, z1); - } - glEnd(); - } -} - -/*****************************************************************/ - -float xmin = -0.035, xmax = 0.035; -float ymin = -0.035, ymax = 0.035; -float nnear = 0.1; -float ffar = 1.9; -float distance = -1.0; - -static void -loadTextureProjection(int texUnit, GLfloat m[16]) -{ - GLfloat mInverse[4][4]; - - /* Should use true inverse, but since m consists only of rotations, we can - just use the transpose. */ - matrixTranspose((GLfloat *) mInverse, m); - - ActiveTexture(GL_TEXTURE0_ARB + texUnit); - glMatrixMode(GL_TEXTURE); - glLoadIdentity(); - glTranslatef(0.5, 0.5, 0.0); - glScalef(0.5, 0.5, 1.0); - glFrustum(xmin, xmax, ymin, ymax, nnear, ffar); - glTranslatef(0.0, 0.0, distance); - glMultMatrixf((GLfloat *) mInverse); - glMatrixMode(GL_MODELVIEW); -} - -static void -drawTextureProjection(void) -{ - float t = ffar / nnear; - GLfloat n[4][3]; - GLfloat f[4][3]; - - n[0][0] = xmin; - n[0][1] = ymin; - n[0][2] = -(nnear + distance); - - n[1][0] = xmax; - n[1][1] = ymin; - n[1][2] = -(nnear + distance); - - n[2][0] = xmax; - n[2][1] = ymax; - n[2][2] = -(nnear + distance); - - n[3][0] = xmin; - n[3][1] = ymax; - n[3][2] = -(nnear + distance); - - f[0][0] = xmin * t; - f[0][1] = ymin * t; - f[0][2] = -(ffar + distance); - - f[1][0] = xmax * t; - f[1][1] = ymin * t; - f[1][2] = -(ffar + distance); - - f[2][0] = xmax * t; - f[2][1] = ymax * t; - f[2][2] = -(ffar + distance); - - f[3][0] = xmin * t; - f[3][1] = ymax * t; - f[3][2] = -(ffar + distance); - - glColor3f(1.0, 1.0, 0.0); - glBegin(GL_LINE_LOOP); - glVertex3fv(n[0]); - glVertex3fv(n[1]); - glVertex3fv(n[2]); - glVertex3fv(n[3]); - glVertex3fv(f[3]); - glVertex3fv(f[2]); - glVertex3fv(f[1]); - glVertex3fv(f[0]); - glVertex3fv(n[0]); - glVertex3fv(n[1]); - glVertex3fv(f[1]); - glVertex3fv(f[0]); - glVertex3fv(f[3]); - glVertex3fv(f[2]); - glVertex3fv(n[2]); - glVertex3fv(n[3]); - glEnd(); -} - -/*****************************************************************/ - -void -initialize(void) -{ - GLfloat light0Pos[4] = - {0.3, 0.3, 0.0, 1.0}; - GLfloat matAmb[4] = - {0.01, 0.01, 0.01, 1.00}; - GLfloat matDiff[4] = - {0.65, 0.65, 0.65, 1.00}; - GLfloat matSpec[4] = - {0.30, 0.30, 0.30, 1.00}; - GLfloat matShine = 10.0; - GLfloat eyePlaneS[] = - {1.0, 0.0, 0.0, 0.0}; - GLfloat eyePlaneT[] = - {0.0, 1.0, 0.0, 0.0}; - GLfloat eyePlaneR[] = - {0.0, 0.0, 1.0, 0.0}; - GLfloat eyePlaneQ[] = - {0.0, 0.0, 0.0, 1.0}; - int i; - - /* Setup Misc. */ - glClearColor(0.41, 0.41, 0.31, 0.0); - - glEnable(GL_DEPTH_TEST); - - /* glLineWidth(2.0);*/ - - glCullFace(GL_FRONT); - glEnable(GL_CULL_FACE); - - glMatrixMode(GL_PROJECTION); - glFrustum(-0.5, 0.5, -0.5, 0.5, 1, 3); - glMatrixMode(GL_MODELVIEW); - glTranslatef(0, 0, -2); - - matrixIdentity((GLfloat *) objectXform); - for (i = 0; i < NumTextures; i++) { - matrixIdentity((GLfloat *) textureXform[i]); - } - - glMatrixMode(GL_PROJECTION); - glPushMatrix(); - glLoadIdentity(); - glOrtho(0, 1, 0, 1, -1, 1); - glMatrixMode(GL_MODELVIEW); - glPushMatrix(); - glLoadIdentity(); - - glRasterPos2i(0, 0); - - glPopMatrix(); - glMatrixMode(GL_PROJECTION); - glPopMatrix(); - glMatrixMode(GL_MODELVIEW); - - /* Setup Lighting */ - glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, matAmb); - glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, matDiff); - glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, matSpec); - glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, matShine); - - glEnable(GL_COLOR_MATERIAL); - - glLightfv(GL_LIGHT0, GL_POSITION, light0Pos); - glEnable(GL_LIGHT0); - - glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE); - glEnable(GL_LIGHTING); - - /* Setup Texture */ - - (*loadTexture) (); - - - for (i = 0; i < NumTextures; i++) { - ActiveTexture(GL_TEXTURE0_ARB + i); - - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); - glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); - - glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR); - glTexGenfv(GL_S, GL_EYE_PLANE, eyePlaneS); - - glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR); - glTexGenfv(GL_T, GL_EYE_PLANE, eyePlaneT); - - glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR); - glTexGenfv(GL_R, GL_EYE_PLANE, eyePlaneR); - - glTexGeni(GL_Q, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR); - glTexGenfv(GL_Q, GL_EYE_PLANE, eyePlaneQ); - } -} - -void -display(void) -{ - int i; - - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - - if (textureEnabled) { - if (mode == MoveTexture || mode == MoveView) { - /* Have OpenGL compute the new transformation (simple but slow). */ - for (i = 0; i < NumTextures; i++) { - glPushMatrix(); - glLoadIdentity(); -#if 0 - if (i & 1) - glRotatef(angle, axis[0], axis[1], axis[2]); - else -#endif - glRotatef(angle*(i+1), axis[0], axis[1], axis[2]); - - glMultMatrixf((GLfloat *) textureXform[i]); - glGetFloatv(GL_MODELVIEW_MATRIX, (GLfloat *) textureXform[i]); - glPopMatrix(); - } - } - for (i = 0; i < NumTextures; i++) { - loadTextureProjection(i, (GLfloat *) textureXform[i]); - } - - if (showProjection) { - for (i = 0; i < NumTextures; i++) { - ActiveTexture(GL_TEXTURE0_ARB + i); - glPushMatrix(); - glMultMatrixf((GLfloat *) textureXform[i]); - glDisable(GL_LIGHTING); - drawTextureProjection(); - glEnable(GL_LIGHTING); - glPopMatrix(); - } - } - for (i = 0; i < NumTextures; i++) { - ActiveTexture(GL_TEXTURE0_ARB + i); - glEnable(GL_TEXTURE_2D); - glEnable(GL_TEXTURE_GEN_S); - glEnable(GL_TEXTURE_GEN_T); - glEnable(GL_TEXTURE_GEN_R); - glEnable(GL_TEXTURE_GEN_Q); - } - } - if (mode == MoveObject || mode == MoveView) { - /* Have OpenGL compute the new transformation (simple but slow). */ - glPushMatrix(); - glLoadIdentity(); - glRotatef(angle, axis[0], axis[1], axis[2]); - glMultMatrixf((GLfloat *) objectXform); - glGetFloatv(GL_MODELVIEW_MATRIX, (GLfloat *) objectXform); - glPopMatrix(); - } - glPushMatrix(); - glMultMatrixf((GLfloat *) objectXform); - (*drawObject) (); - glPopMatrix(); - - for (i = 0; i < NumTextures; i++) { - ActiveTexture(GL_TEXTURE0_ARB + i); - glDisable(GL_TEXTURE_2D); - glDisable(GL_TEXTURE_GEN_S); - glDisable(GL_TEXTURE_GEN_T); - glDisable(GL_TEXTURE_GEN_R); - glDisable(GL_TEXTURE_GEN_Q); - } - - if (zoomFactor > 1.0) { - glDisable(GL_DEPTH_TEST); - glCopyPixels(0, 0, winWidth / zoomFactor, winHeight / zoomFactor, GL_COLOR); - glEnable(GL_DEPTH_TEST); - } - glFlush(); - glutSwapBuffers(); - checkErrors(); -} - -/*****************************************************************/ - -/* simple trackball-like motion control */ -float lastPos[3]; -int lastTime; - -void -ptov(int x, int y, int width, int height, float v[3]) -{ - float d, a; - - /* project x,y onto a hemi-sphere centered within width, height */ - v[0] = (2.0 * x - width) / width; - v[1] = (height - 2.0 * y) / height; - d = sqrt(v[0] * v[0] + v[1] * v[1]); - v[2] = cos((M_PI / 2.0) * ((d < 1.0) ? d : 1.0)); - a = 1.0 / sqrt(v[0] * v[0] + v[1] * v[1] + v[2] * v[2]); - v[0] *= a; - v[1] *= a; - v[2] *= a; -} - -void -startMotion(int x, int y, int but, int time) -{ - if (but == GLUT_LEFT_BUTTON) { - mode = MoveView; - } else if (but == GLUT_MIDDLE_BUTTON) { - mode = MoveTexture; - } else { - return; - } - - lastTime = time; - ptov(x, y, winWidth, winHeight, lastPos); -} - -void -animate(void) -{ - glutPostRedisplay(); -} - -void -vis(int visible) -{ - if (visible == GLUT_VISIBLE) { - if (redrawContinuously) - glutIdleFunc(animate); - } else { - if (redrawContinuously) - glutIdleFunc(NULL); - } -} - -void -stopMotion(int but, int time) -{ - if ((but == GLUT_LEFT_BUTTON && mode == MoveView) || - (but == GLUT_MIDDLE_BUTTON && mode == MoveTexture)) { - } else { - return; - } - - if (time == lastTime) { - /* redrawContinuously = GL_TRUE;*/ - glutIdleFunc(animate); - } else { - angle = 0.0; - redrawContinuously = GL_FALSE; - glutIdleFunc(0); - } - if (!redrawContinuously) { - mode = MoveNone; - } -} - -void -trackMotion(int x, int y) -{ - float curPos[3], dx, dy, dz; - - ptov(x, y, winWidth, winHeight, curPos); - - dx = curPos[0] - lastPos[0]; - dy = curPos[1] - lastPos[1]; - dz = curPos[2] - lastPos[2]; - angle = 90.0 * sqrt(dx * dx + dy * dy + dz * dz); - - axis[0] = lastPos[1] * curPos[2] - lastPos[2] * curPos[1]; - axis[1] = lastPos[2] * curPos[0] - lastPos[0] * curPos[2]; - axis[2] = lastPos[0] * curPos[1] - lastPos[1] * curPos[0]; - - lastTime = glutGet(GLUT_ELAPSED_TIME); - lastPos[0] = curPos[0]; - lastPos[1] = curPos[1]; - lastPos[2] = curPos[2]; - glutPostRedisplay(); -} - -/*****************************************************************/ - -void -object(void) -{ - static int object; - - object++; - object %= 3; - switch (object) { - case 0: - drawObject = drawCube; - break; - case 1: - drawObject = drawDodecahedron; - break; - case 2: - drawObject = drawSphere; - break; - default: - break; - } -} - -static void -nop(void) -{ -} - -void -texture(void) -{ - static int texture = 0; - - texture++; - texture %= 3; - if (texture == 1 && texFilename == NULL) { - /* Skip file texture if not loaded. */ - texture++; - } - switch (texture) { - case 0: - loadTexture = nop; - textureEnabled = GL_FALSE; - break; - case 1: - loadTexture = loadImageTextures; - (*loadTexture) (); - textureEnabled = GL_TRUE; - break; - case 2: - loadTexture = loadSpotlightTexture; - (*loadTexture) (); - textureEnabled = GL_TRUE; - break; - default: - break; - } -} - -void -help(void) -{ - printf("'h' - help\n"); - printf("'l' - toggle linear/nearest filter\n"); - printf("'s' - toggle projection frustum\n"); - printf("'t' - toggle projected texture\n"); - printf("'o' - toggle object\n"); - printf("'z' - increase zoom factor\n"); - printf("'Z' - decrease zoom factor\n"); - printf("left mouse - move view\n"); - printf("middle mouse - move projection\n"); -} - -/* ARGSUSED1 */ -void -key(unsigned char key, int x, int y) -{ - switch (key) { - case '\033': - exit(0); - break; - case 'l': - linearFilter = !linearFilter; - (*loadTexture) (); - break; - case 's': - showProjection = !showProjection; - break; - case 't': - texture(); - break; - case 'o': - object(); - break; - case 'z': - zoomFactor += 1.0; - glPixelZoom(zoomFactor, zoomFactor); - glViewport(0, 0, winWidth / zoomFactor, winHeight / zoomFactor); - break; - case 'Z': - zoomFactor -= 1.0; - if (zoomFactor < 1.0) - zoomFactor = 1.0; - glPixelZoom(zoomFactor, zoomFactor); - glViewport(0, 0, winWidth / zoomFactor, winHeight / zoomFactor); - break; - case 'h': - help(); - break; - } - glutPostRedisplay(); -} - -void -mouse(int button, int state, int x, int y) -{ - if (state == GLUT_DOWN) - startMotion(x, y, button, glutGet(GLUT_ELAPSED_TIME)); - else if (state == GLUT_UP) - stopMotion(button, glutGet(GLUT_ELAPSED_TIME)); - glutPostRedisplay(); -} - -void -reshape(int w, int h) -{ - winWidth = w; - winHeight = h; - glViewport(0, 0, w / zoomFactor, h / zoomFactor); -} - - -void -menu(int selection) -{ - if (selection == 666) { - exit(0); - } - key((unsigned char) selection, 0, 0); -} - -int -main(int argc, char **argv) -{ - glutInit(&argc, argv); - - if (argc > 1) { - NumTextures = atoi(argv[1]); - } - assert(NumTextures <= MAX_TEX); - - glutInitDisplayMode(GLUT_RGBA | GLUT_DEPTH | GLUT_DOUBLE); - (void) glutCreateWindow("projtex"); - glewInit(); - - loadTexture = loadImageTextures; - drawObject = drawCube; - initialize(); - glutDisplayFunc(display); - glutKeyboardFunc(key); - glutReshapeFunc(reshape); - glutMouseFunc(mouse); - glutMotionFunc(trackMotion); - glutVisibilityFunc(vis); - glutCreateMenu(menu); - glutAddMenuEntry("Toggle showing projection", 's'); - glutAddMenuEntry("Switch texture", 't'); - glutAddMenuEntry("Switch object", 'o'); - glutAddMenuEntry("Toggle filtering", 'l'); - glutAddMenuEntry("Quit", 666); - glutAttachMenu(GLUT_RIGHT_BUTTON); - texture(); - glutMainLoop(); - return 0; /* ANSI C requires main to return int. */ -} diff --git a/progs/tests/shader_api.c b/progs/tests/shader_api.c index a513ca6ba1f..6453856345c 100644 --- a/progs/tests/shader_api.c +++ b/progs/tests/shader_api.c @@ -321,10 +321,18 @@ static void run_test(const char *name, void (*callback)(void)) int main(int argc, char **argv) { + const char *version; + glutInit(&argc, argv); glutCreateWindow("Mesa bug demo"); glewInit(); + version = (const char *) glGetString(GL_VERSION); + if (version[0] == '1') { + printf("Sorry, this test requires OpenGL 2.x GLSL support\n"); + exit(0); + } + RUN_TEST(test_uniform_size_type); RUN_TEST(test_attrib_size_type); RUN_TEST(test_uniform_array_overflow); diff --git a/progs/tests/streaming_rect.c b/progs/tests/streaming_rect.c new file mode 100644 index 00000000000..f65ac4ce36c --- /dev/null +++ b/progs/tests/streaming_rect.c @@ -0,0 +1,327 @@ +/* + * GL_ARB_pixel_buffer_object test + * + * Command line options: + * -w WIDTH -h HEIGHT sets window size + * + */ + +#include <math.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <GL/glew.h> +#include <GL/glut.h> + +#include "readtex.h" + + +#define ANIMATE 10 +#define PBO 11 +#define QUIT 100 + +static GLuint DrawPBO; + +static GLboolean Animate = GL_TRUE; +static GLboolean use_pbo = 1; +static GLboolean whole_rect = 1; + +static GLfloat Drift = 0.0; +static GLfloat drift_increment = 1/255.0; +static GLfloat Xrot = 20.0, Yrot = 30.0; + +static GLuint Width = 1024; +static GLuint Height = 512; + + +static void Idle( void ) +{ + if (Animate) { + + Drift += drift_increment; + if (Drift >= 1.0) + Drift = 0.0; + + glutPostRedisplay(); + } +} + +/*static int max( int a, int b ) { return a > b ? a : b; }*/ + +#ifndef min +static int min( int a, int b ) { return a < b ? a : b; } +#endif + +static void DrawObject() +{ + GLint size = Width * Height * 4; + + if (use_pbo) { + /* XXX: This is extremely important - semantically makes the buffer + * contents undefined, but in practice means that the driver can + * release the old copy of the texture and allocate a new one + * without waiting for outstanding rendering to complete. + */ + glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_EXT, DrawPBO); + glBufferDataARB(GL_PIXEL_UNPACK_BUFFER_EXT, size, NULL, GL_STREAM_DRAW_ARB); + + { + char *image = glMapBufferARB(GL_PIXEL_UNPACK_BUFFER_EXT, GL_WRITE_ONLY_ARB); + + printf("char %d\n", (unsigned char)(Drift * 255)); + + memset(image, (unsigned char)(Drift * 255), size); + + glUnmapBufferARB(GL_PIXEL_UNPACK_BUFFER_EXT); + } + + + /* BGRA is required for most hardware paths: + */ + glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA, Width, Height, 0, + GL_BGRA, GL_UNSIGNED_BYTE, NULL); + } + else { + static char *image = NULL; + + if (image == NULL) + image = malloc(size); + + glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_EXT, 0); + + memset(image, (unsigned char)(Drift * 255), size); + + /* BGRA should be the fast path for regular uploads as well. + */ + glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA, Width, Height, 0, + GL_BGRA, GL_UNSIGNED_BYTE, image); + } + + { + int x,y,w,h; + + if (whole_rect) { + x = y = 0; + w = Width; + h = Height; + } + else { + x = y = 0; + w = min(10, Width); + h = min(10, Height); + } + + glBegin(GL_QUADS); + + glTexCoord2f( x, y); + glVertex2f( x, y ); + + glTexCoord2f( x, y + h); + glVertex2f( x, y + h); + + glTexCoord2f( x + w + .5, y + h); + glVertex2f( x + w, y + h ); + + glTexCoord2f( x + w, y + .5); + glVertex2f( x + w, y ); + + glEnd(); + } +} + + + +static void Display( void ) +{ + static GLint T0 = 0; + static GLint Frames = 0; + GLint t; + + glClear( GL_COLOR_BUFFER_BIT ); + + glPushMatrix(); + DrawObject(); + glPopMatrix(); + + glutSwapBuffers(); + + Frames++; + + t = glutGet(GLUT_ELAPSED_TIME); + if (t - T0 >= 1000) { + GLfloat seconds = (t - T0) / 1000.0; + + GLfloat fps = Frames / seconds; + printf("%d frames in %6.3f seconds = %6.3f FPS\n", Frames, seconds, fps); + fflush(stdout); + + drift_increment = 2.2 * seconds / Frames; + T0 = t; + Frames = 0; + } +} + + +static void Reshape( int width, int height ) +{ + glViewport( 0, 0, width, height ); + glMatrixMode( GL_PROJECTION ); + glLoadIdentity(); +/* glFrustum( -1.0, 1.0, -1.0, 1.0, 10.0, 100.0 ); */ + gluOrtho2D( 0, width, height, 0 ); + glMatrixMode( GL_MODELVIEW ); + glLoadIdentity(); + glTranslatef(0.375, 0.375, 0); +} + + +static void ModeMenu(int entry) +{ + if (entry==ANIMATE) { + Animate = !Animate; + } + else if (entry==PBO) { + use_pbo = !use_pbo; + } + else if (entry==QUIT) { + exit(0); + } + + glutPostRedisplay(); +} + + +static void Key( unsigned char key, int x, int y ) +{ + (void) x; + (void) y; + switch (key) { + case 27: + exit(0); + break; + } + glutPostRedisplay(); +} + + +static void SpecialKey( int key, int x, int y ) +{ + float 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 Init( int argc, char *argv[] ) +{ + const char *exten = (const char *) glGetString(GL_EXTENSIONS); + GLuint texObj; + GLint size; + + + if (!strstr(exten, "GL_ARB_pixel_buffer_object")) { + printf("Sorry, GL_ARB_pixel_buffer_object not supported by this renderer.\n"); + exit(1); + } + + glGetIntegerv(GL_MAX_TEXTURE_SIZE, &size); + printf("%d x %d max texture size\n", size, size); + + glPixelStorei(GL_UNPACK_ALIGNMENT, 1); + + /* allocate two texture objects */ + glGenTextures(1, &texObj); + + /* setup the texture objects */ + glActiveTextureARB(GL_TEXTURE0_ARB); + glBindTexture(GL_TEXTURE_RECTANGLE_ARB, texObj); + + glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + + glGenBuffersARB(1, &DrawPBO); + + glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_EXT, DrawPBO); + glBufferDataARB(GL_PIXEL_UNPACK_BUFFER_EXT, + Width * Height * 4, NULL, GL_STREAM_DRAW); + + glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); + + glEnable(GL_TEXTURE_RECTANGLE_ARB); + + glShadeModel(GL_SMOOTH); + glClearColor(0.3, 0.3, 0.4, 1.0); + + if (argc > 1 && strcmp(argv[1], "-info")==0) { + 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)); + } +} + + +int main( int argc, char *argv[] ) +{ + GLint i; + + glutInit( &argc, argv ); + + for (i = 1; i < argc; i++) { + if (strcmp(argv[i], "-w") == 0) { + Width = atoi(argv[i+1]); + if (Width <= 0) { + printf("Error, bad width\n"); + exit(1); + } + i++; + } + else if (strcmp(argv[i], "-h") == 0) { + Height = atoi(argv[i+1]); + if (Height <= 0) { + printf("Error, bad height\n"); + exit(1); + } + i++; + } + } + + glutInitWindowSize( Width, Height ); + glutInitWindowPosition( 0, 0 ); + glutInitDisplayMode( GLUT_RGB | GLUT_DOUBLE ); + glutCreateWindow(argv[0] ); + glewInit(); + + Init( argc, argv ); + + glutReshapeFunc( Reshape ); + glutKeyboardFunc( Key ); + glutSpecialFunc( SpecialKey ); + glutDisplayFunc( Display ); + glutIdleFunc( Idle ); + + glutCreateMenu(ModeMenu); + glutAddMenuEntry("Toggle Animation", ANIMATE); + glutAddMenuEntry("Toggle PBO", PBO); + glutAddMenuEntry("Quit", QUIT); + glutAttachMenu(GLUT_RIGHT_BUTTON); + + glutMainLoop(); + return 0; +} diff --git a/progs/tests/texcompress2.c b/progs/tests/texcompress2.c index cbb8f1d3a22..b95aca9fb98 100644 --- a/progs/tests/texcompress2.c +++ b/progs/tests/texcompress2.c @@ -51,7 +51,6 @@ TestSubTex(void) GLboolean all = 0*GL_TRUE; GLubyte *buffer; GLint size, fmt; - int i; glGetTexLevelParameteriv(Target, 0, GL_TEXTURE_COMPRESSED_IMAGE_SIZE_ARB, &size); @@ -83,6 +82,23 @@ TestSubTex(void) static void +TestGetTex(void) +{ + GLubyte *buffer; + + buffer = (GLubyte *) malloc(3 * ImgWidth * ImgHeight); + + glGetTexImage(GL_TEXTURE_2D, + 0, + GL_RGB, + GL_UNSIGNED_BYTE, + buffer); + + free(buffer); +} + + +static void LoadCompressedImage(const char *file) { const GLenum filter = GL_LINEAR; @@ -146,7 +162,10 @@ LoadCompressedImage(const char *file) glTexParameteri(Target, GL_TEXTURE_MIN_FILTER, filter); glTexParameteri(Target, GL_TEXTURE_MAG_FILTER, filter); - TestSubTex(); + if (0) + TestSubTex(); + else + TestGetTex(); } diff --git a/progs/tests/texdown.c b/progs/tests/texdown.c new file mode 100644 index 00000000000..7e460458325 --- /dev/null +++ b/progs/tests/texdown.c @@ -0,0 +1,477 @@ + +/* + * Copyright (C) 1999 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. + */ + + +/* + * texdown + * + * Measure texture download speed. + * Use keyboard to change texture size, format, datatype, scale/bias, + * subimageload, etc. + * + * Brian Paul 28 January 2000 + */ + + +#include <stdio.h> +#include <stdlib.h> +#include <math.h> +#include <GL/glut.h> + + +static GLsizei MaxSize = 2048; +static GLsizei TexWidth = 1024, TexHeight = 1024, TexBorder = 0; +static GLboolean ScaleAndBias = GL_FALSE; +static GLboolean SubImage = GL_FALSE; +static GLdouble DownloadRate = 0.0; /* texels/sec */ + +static GLuint Mode = 0; + + +/* Try and avoid L2 cache effects by cycling through a small number of + * textures. + * + * At the initial size of 1024x1024x4 == 4mbyte, say 8 textures will + * keep us out of most caches at 32mb total. + * + * This turns into a fairly interesting question of what exactly you + * expect to be in cache in normal usage, and what you think should be + * outside. There's no rules for this, no reason to favour one usage + * over another except what the application you care about happens to + * resemble most closely. + * + * - Should the client texture image be in L2 cache? Has it just been + * generated or read from disk? + * - Does the application really use >1 texture, or is it constantly + * updating one image in-place? + * + * Different answers will favour different texture upload mechanisms. + * To upload an image that is purely outside of cache, a DMA-based + * upload will probably win, whereas for small, in-cache textures, + * copying looks good. + */ +#define NR_TEXOBJ 4 +static GLuint TexObj[NR_TEXOBJ]; + + +struct FormatRec { + GLenum Format; + GLenum Type; + GLenum IntFormat; + GLint TexelSize; +}; + + +static const struct FormatRec FormatTable[] = { + /* Format Type IntFormat TexelSize */ + { GL_BGRA, GL_UNSIGNED_BYTE, GL_RGBA, 4 }, + { GL_RGB, GL_UNSIGNED_BYTE, GL_RGB, 3 }, + { GL_RGBA, GL_UNSIGNED_BYTE, GL_RGBA, 4 }, + { GL_RGBA, GL_UNSIGNED_BYTE, GL_RGB, 4 }, + { GL_RGB, GL_UNSIGNED_SHORT_5_6_5, GL_RGB, 2 }, + { GL_LUMINANCE, GL_UNSIGNED_BYTE, GL_LUMINANCE, 1 }, + { GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, GL_LUMINANCE_ALPHA, 2 }, + { GL_ALPHA, GL_UNSIGNED_BYTE, GL_ALPHA, 1 }, +}; +static GLint Format; + +#define NUM_FORMATS (sizeof(FormatTable)/sizeof(FormatTable[0])) + +static int +BytesPerTexel(GLint format) +{ + return FormatTable[format].TexelSize; +} + + +static const char * +FormatStr(GLenum format) +{ + switch (format) { + case GL_RGB: + return "GL_RGB"; + case GL_RGBA: + return "GL_RGBA"; + case GL_BGRA: + return "GL_BGRA"; + case GL_LUMINANCE: + return "GL_LUMINANCE"; + case GL_LUMINANCE_ALPHA: + return "GL_LUMINANCE_ALPHA"; + case GL_ALPHA: + return "GL_ALPHA"; + default: + return ""; + } +} + + +static const char * +TypeStr(GLenum type) +{ + switch (type) { + case GL_UNSIGNED_BYTE: + return "GL_UNSIGNED_BYTE"; + case GL_UNSIGNED_SHORT: + return "GL_UNSIGNED_SHORT"; + case GL_UNSIGNED_SHORT_5_6_5: + return "GL_UNSIGNED_SHORT_5_6_5"; + case GL_UNSIGNED_SHORT_5_6_5_REV: + return "GL_UNSIGNED_SHORT_5_6_5_REV"; + default: + return ""; + } +} + +/* On x86, there is a performance cliff for memcpy to texture memory + * for sources below 64 byte alignment. We do our best with this in + * the driver, but it is better if the images are correctly aligned to + * start with: + */ +#define ALIGN (1<<12) + +static unsigned long align(unsigned long value, unsigned long a) +{ + return (value + a - 1) & ~(a-1); +} + +static void +MeasureDownloadRate(void) +{ + const int w = TexWidth + 2 * TexBorder; + const int h = TexHeight + 2 * TexBorder; + const int image_bytes = align(w * h * BytesPerTexel(Format), ALIGN); + const int bytes = image_bytes * NR_TEXOBJ; + GLubyte *orig_texImage, *orig_getImage; + GLubyte *texImage, *getImage; + GLdouble t0, t1, time; + int count; + int i; + int offset = 0; + GLdouble total = 0; /* ints will tend to overflow */ + + printf("allocating %d bytes for %d %dx%d images\n", + bytes, NR_TEXOBJ, w, h); + + orig_texImage = (GLubyte *) malloc(bytes + ALIGN); + orig_getImage = (GLubyte *) malloc(image_bytes + ALIGN); + if (!orig_texImage || !orig_getImage) { + DownloadRate = 0.0; + return; + } + + printf("alloc %p %p\n", orig_texImage, orig_getImage); + + texImage = (GLubyte *)align((unsigned long)orig_texImage, ALIGN); + getImage = (GLubyte *)align((unsigned long)orig_getImage, ALIGN); + + for (i = 1; !(((unsigned long)texImage) & i); i<<=1) + ; + printf("texture image alignment: %d bytes (%p)\n", i, texImage); + + for (i = 0; i < bytes; i++) { + texImage[i] = i & 0xff; + } + + glPixelStorei(GL_UNPACK_ALIGNMENT, 1); + glPixelStorei(GL_PACK_ALIGNMENT, 1); + + if (ScaleAndBias) { + glPixelTransferf(GL_RED_SCALE, 0.5); + glPixelTransferf(GL_GREEN_SCALE, 0.5); + glPixelTransferf(GL_BLUE_SCALE, 0.5); + glPixelTransferf(GL_RED_BIAS, 0.5); + glPixelTransferf(GL_GREEN_BIAS, 0.5); + glPixelTransferf(GL_BLUE_BIAS, 0.5); + } + else { + glPixelTransferf(GL_RED_SCALE, 1.0); + glPixelTransferf(GL_GREEN_SCALE, 1.0); + glPixelTransferf(GL_BLUE_SCALE, 1.0); + glPixelTransferf(GL_RED_BIAS, 0.0); + glPixelTransferf(GL_GREEN_BIAS, 0.0); + glPixelTransferf(GL_BLUE_BIAS, 0.0); + } + + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glEnable(GL_TEXTURE_2D); + + count = 0; + t0 = glutGet(GLUT_ELAPSED_TIME) * 0.001; + do { + int img = count%NR_TEXOBJ; + GLubyte *img_ptr = texImage + img * image_bytes; + + glBindTexture(GL_TEXTURE_2D, TexObj[img]); + + if (SubImage && count > 0) { + /* Only update a portion of the image each iteration. This + * is presumably why you'd want to use texsubimage, otherwise + * you may as well just call teximage again. + * + * A bigger question is whether to use a pointer that moves + * with each call, ie does the incoming data come from L2 + * cache under normal circumstances, or is it pulled from + * uncached memory? + * + * There's a good argument to say L2 cache, ie you'd expect + * the data to have been recently generated. It's possible + * that it could have come from a file read, which may or may + * not have gone through the cpu. + */ + glTexSubImage2D(GL_TEXTURE_2D, 0, + -TexBorder, + -TexBorder + offset * h/8, + w, + h/8, + FormatTable[Format].Format, + FormatTable[Format].Type, +#if 1 + texImage /* likely in L2$ */ +#else + img_ptr + offset * bytes/8 /* unlikely in L2$ */ +#endif + ); + offset += 1; + offset %= 8; + total += w * h / 8; + } + else { + glTexImage2D(GL_TEXTURE_2D, 0, + FormatTable[Format].IntFormat, w, h, TexBorder, + FormatTable[Format].Format, + FormatTable[Format].Type, + img_ptr); + total += w*h; + } + + /* draw a tiny polygon to force texture into texram */ + glBegin(GL_TRIANGLES); + glTexCoord2f(0, 0); glVertex2f(1, 1); + glTexCoord2f(1, 0); glVertex2f(3, 1); + glTexCoord2f(0.5, 1); glVertex2f(2, 3); + glEnd(); + + t1 = glutGet(GLUT_ELAPSED_TIME) * 0.001; + time = t1 - t0; + count++; + } while (time < 3.0); + + glDisable(GL_TEXTURE_2D); + + printf("total texels=%f time=%f\n", total, time); + DownloadRate = total / time; + + + free(orig_texImage); + free(orig_getImage); + + { + GLint err = glGetError(); + if (err) + printf("GL error %d\n", err); + } +} + + +static void +PrintString(const char *s) +{ + while (*s) { + glutBitmapCharacter(GLUT_BITMAP_8_BY_13, (int) *s); + s++; + } +} + + +static void +Display(void) +{ + const int w = TexWidth + 2 * TexBorder; + const int h = TexHeight + 2 * TexBorder; + char s[1000]; + + glClear(GL_COLOR_BUFFER_BIT); + + glRasterPos2i(10, 80); + sprintf(s, "Texture size[cursor]: %d x %d Border[b]: %d", w, h, TexBorder); + PrintString(s); + + glRasterPos2i(10, 65); + sprintf(s, "Format[f]: %s Type: %s IntFormat: %s", + FormatStr(FormatTable[Format].Format), + TypeStr( FormatTable[Format].Type), + FormatStr(FormatTable[Format].IntFormat)); + PrintString(s); + + glRasterPos2i(10, 50); + sprintf(s, "Pixel Scale&Bias[p]: %s TexSubImage[s]: %s", + ScaleAndBias ? "Yes" : "No", + SubImage ? "Yes" : "No"); + PrintString(s); + + if (Mode == 0) { + glRasterPos2i(200, 10); + sprintf(s, "...Measuring..."); + PrintString(s); + glutSwapBuffers(); + glutPostRedisplay(); + Mode++; + } + else if (Mode == 1) { + MeasureDownloadRate(); + glutPostRedisplay(); + Mode++; + } + else { + /* show results */ + glRasterPos2i(10, 10); + sprintf(s, "Download rate: %g Mtexels/second %g MB/second", + DownloadRate / 1000000.0, + DownloadRate * BytesPerTexel(Format) / 1000000.0); + PrintString(s); + { + GLint r, g, b, a, l, i; + glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_RED_SIZE, &r); + glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_GREEN_SIZE, &g); + glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_BLUE_SIZE, &b); + glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_ALPHA_SIZE, &a); + glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_LUMINANCE_SIZE, &l); + glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_INTENSITY_SIZE, &i); + sprintf(s, "TexelBits: R=%d G=%d B=%d A=%d L=%d I=%d", r, g, b, a, l, i); + glRasterPos2i(10, 25); + PrintString(s); + } + + glutSwapBuffers(); + } +} + + +static void +Reshape(int width, int height) +{ + glViewport( 0, 0, width, height ); + glMatrixMode( GL_PROJECTION ); + glLoadIdentity(); + glOrtho(0, width, 0, height, -1, 1); + glMatrixMode( GL_MODELVIEW ); + glLoadIdentity(); +} + + + +static void +Key(unsigned char key, int x, int y) +{ + (void) x; + (void) y; + switch (key) { + case ' ': + Mode = 0; + break; + case 'b': + /* toggle border */ + TexBorder = 1 - TexBorder; + Mode = 0; + break; + case 'f': + /* change format */ + Format = (Format + 1) % NUM_FORMATS; + Mode = 0; + break; + case 'F': + /* change format */ + Format = (Format - 1) % NUM_FORMATS; + Mode = 0; + break; + case 'p': + /* toggle border */ + ScaleAndBias = !ScaleAndBias; + Mode = 0; + break; + case 's': + SubImage = !SubImage; + Mode = 0; + break; + case 27: + exit(0); + break; + } + glutPostRedisplay(); +} + + +static void +SpecialKey(int key, int x, int y) +{ + (void) x; + (void) y; + switch (key) { + case GLUT_KEY_UP: + if (TexHeight < MaxSize) + TexHeight *= 2; + break; + case GLUT_KEY_DOWN: + if (TexHeight > 1) + TexHeight /= 2; + break; + case GLUT_KEY_LEFT: + if (TexWidth > 1) + TexWidth /= 2; + break; + case GLUT_KEY_RIGHT: + if (TexWidth < MaxSize) + TexWidth *= 2; + break; + } + Mode = 0; + glutPostRedisplay(); +} + + +static void +Init(void) +{ + printf("GL_VENDOR = %s\n", (const char *) glGetString(GL_VENDOR)); + printf("GL_VERSION = %s\n", (const char *) glGetString(GL_VERSION)); + printf("GL_RENDERER = %s\n", (const char *) glGetString(GL_RENDERER)); +} + + +int +main(int argc, char *argv[]) +{ + glutInit( &argc, argv ); + glutInitWindowPosition( 0, 0 ); + glutInitWindowSize( 600, 100 ); + glutInitDisplayMode( GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH ); + glutCreateWindow(argv[0]); + glutReshapeFunc( Reshape ); + glutKeyboardFunc( Key ); + glutSpecialFunc( SpecialKey ); + glutDisplayFunc( Display ); + Init(); + glutMainLoop(); + return 0; +} diff --git a/progs/tests/texobj.c b/progs/tests/texobj.c new file mode 100644 index 00000000000..40bce6e5695 --- /dev/null +++ b/progs/tests/texobj.c @@ -0,0 +1,284 @@ + +/* + * Example of using the 1.1 texture object functions. + * Also, this demo utilizes Mesa's fast texture map path. + * + * Brian Paul June 1996 This file is in the public domain. + */ + +#include <assert.h> +#include <math.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include "GL/glut.h" + +static GLuint Window = 0; + +static GLuint TexObj[2]; +static GLfloat Angle = 0.0f; +static GLboolean UseObj = GL_FALSE; + + +#if defined(GL_VERSION_1_1) || defined(GL_VERSION_1_2) +# define TEXTURE_OBJECT 1 +#elif defined(GL_EXT_texture_object) +# define TEXTURE_OBJECT 1 +# define glBindTexture(A,B) glBindTextureEXT(A,B) +# define glGenTextures(A,B) glGenTexturesEXT(A,B) +# define glDeleteTextures(A,B) glDeleteTexturesEXT(A,B) +#endif + + + + +static void draw( void ) +{ + glClear( GL_COLOR_BUFFER_BIT ); + + glColor3f( 1.0, 1.0, 1.0 ); + + /* draw first polygon */ + glPushMatrix(); + glTranslatef( -1.0, 0.0, 0.0 ); + glRotatef( Angle, 0.0, 0.0, 1.0 ); + if (UseObj) { +#ifdef TEXTURE_OBJECT + glBindTexture( GL_TEXTURE_2D, TexObj[0] ); +#endif + } + else { + glCallList( TexObj[0] ); + } + glBegin( GL_POLYGON ); + glTexCoord2f( 0.0, 0.0 ); glVertex2f( -1.0, -1.0 ); + glTexCoord2f( 1.0, 0.0 ); glVertex2f( 1.0, -1.0 ); + glTexCoord2f( 1.0, 1.0 ); glVertex2f( 1.0, 1.0 ); + glTexCoord2f( 0.0, 1.0 ); glVertex2f( -1.0, 1.0 ); + glEnd(); + glPopMatrix(); + + /* draw second polygon */ + glPushMatrix(); + glTranslatef( 1.0, 0.0, 0.0 ); + glRotatef( Angle-90.0, 0.0, 1.0, 0.0 ); + if (UseObj) { +#ifdef TEXTURE_OBJECT + glBindTexture( GL_TEXTURE_2D, TexObj[1] ); +#endif + } + else { + glCallList( TexObj[1] ); + } + glBegin( GL_POLYGON ); + glTexCoord2f( 0.0, 0.0 ); glVertex2f( -1.0, -1.0 ); + glTexCoord2f( 1.0, 0.0 ); glVertex2f( 1.0, -1.0 ); + glTexCoord2f( 1.0, 1.0 ); glVertex2f( 1.0, 1.0 ); + glTexCoord2f( 0.0, 1.0 ); glVertex2f( -1.0, 1.0 ); + glEnd(); + glPopMatrix(); + + glutSwapBuffers(); +} + + + +static void idle( void ) +{ + static double t0 = -1.; + double dt, t = glutGet(GLUT_ELAPSED_TIME) / 1000.0; + if (t0 < 0.0) + t0 = t; + dt = t - t0; + t0 = t; + Angle += 120.0*dt; + glutPostRedisplay(); +} + + + +/* change view Angle, exit upon ESC */ +static void key(unsigned char k, int x, int y) +{ + (void) x; + (void) y; + switch (k) { + case 27: +#ifdef TEXTURE_OBJECT + glDeleteTextures( 2, TexObj ); +#endif + glutDestroyWindow(Window); + exit(0); + } +} + + + +/* new window size or exposure */ +static void reshape( int width, int height ) +{ + glViewport(0, 0, (GLint)width, (GLint)height); + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + /* glOrtho( -3.0, 3.0, -3.0, 3.0, -10.0, 10.0 );*/ + glFrustum( -2.0, 2.0, -2.0, 2.0, 6.0, 20.0 ); + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + glTranslatef( 0.0, 0.0, -8.0 ); +} + + +static void init( void ) +{ + static int width=8, height=8; + static GLubyte tex1[] = { + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 0, 0, 0, + 0, 0, 0, 1, 1, 0, 0, 0, + 0, 0, 0, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 1, 0, 0, 0, + 0, 0, 0, 1, 1, 1, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0 }; + + static GLubyte tex2[] = { + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 2, 2, 0, 0, 0, + 0, 0, 2, 0, 0, 2, 0, 0, + 0, 0, 0, 0, 0, 2, 0, 0, + 0, 0, 0, 0, 2, 0, 0, 0, + 0, 0, 0, 2, 0, 0, 0, 0, + 0, 0, 2, 2, 2, 2, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0 }; + + GLubyte tex[64][3]; + GLint i, j; + + + glDisable( GL_DITHER ); + + /* Setup texturing */ + glEnable( GL_TEXTURE_2D ); + glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL ); + glHint( GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST ); + + + /* generate texture object IDs */ + if (UseObj) { +#ifdef TEXTURE_OBJECT + glGenTextures( 2, TexObj ); +#endif + } + else { + TexObj[0] = glGenLists(2); + TexObj[1] = TexObj[0]+1; + } + + /* setup first texture object */ + if (UseObj) { +#ifdef TEXTURE_OBJECT + glBindTexture( GL_TEXTURE_2D, TexObj[0] ); + assert(glIsTexture(TexObj[0])); +#endif + } + else { + glNewList( TexObj[0], GL_COMPILE ); + } + /* red on white */ + for (i=0;i<height;i++) { + for (j=0;j<width;j++) { + int p = i*width+j; + if (tex1[(height-i-1)*width+j]) { + tex[p][0] = 255; tex[p][1] = 0; tex[p][2] = 0; + } + else { + tex[p][0] = 255; tex[p][1] = 255; tex[p][2] = 255; + } + } + } + + glTexImage2D( GL_TEXTURE_2D, 0, 3, width, height, 0, + GL_RGB, GL_UNSIGNED_BYTE, tex ); + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST ); + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST ); + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT ); + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT ); + if (!UseObj) { + glEndList(); + } + /* end of texture object */ + + /* setup second texture object */ + if (UseObj) { +#ifdef TEXTURE_OBJECT + glBindTexture( GL_TEXTURE_2D, TexObj[1] ); + assert(glIsTexture(TexObj[1])); +#endif + assert(!glIsTexture(TexObj[1] + 999)); + } + else { + glNewList( TexObj[1], GL_COMPILE ); + } + /* green on blue */ + for (i=0;i<height;i++) { + for (j=0;j<width;j++) { + int p = i*width+j; + if (tex2[(height-i-1)*width+j]) { + tex[p][0] = 0; tex[p][1] = 255; tex[p][2] = 0; + } + else { + tex[p][0] = 0; tex[p][1] = 0; tex[p][2] = 255; + } + } + } + glTexImage2D( GL_TEXTURE_2D, 0, 3, width, height, 0, + GL_RGB, GL_UNSIGNED_BYTE, tex ); + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST ); + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST ); + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT ); + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT ); + if (!UseObj) { + glEndList(); + } + /* end texture object */ + +} + + + +int main( int argc, char *argv[] ) +{ + glutInit(&argc, argv); + glutInitWindowPosition(0, 0); + glutInitWindowSize(300, 300); + glutInitDisplayMode( GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE ); + + Window = glutCreateWindow("Texture Objects"); + if (!Window) { + exit(1); + } + + /* check that renderer has the GL_EXT_texture_object extension + * or supports OpenGL 1.1 + */ +#ifdef TEXTURE_OBJECT + { + char *exten = (char *) glGetString( GL_EXTENSIONS ); + char *version = (char *) glGetString( GL_VERSION ); + if ( strstr( exten, "GL_EXT_texture_object" ) + || strncmp( version, "1.1", 3 )==0 + || strncmp( version, "1.2", 3 )==0 ) { + UseObj = GL_TRUE; + } + } +#endif + + init(); + + glutReshapeFunc( reshape ); + glutKeyboardFunc( key ); + glutIdleFunc( idle ); + glutDisplayFunc( draw ); + glutMainLoop(); + return 0; +} diff --git a/progs/tests/vparray.c b/progs/tests/vparray.c index 9c2fad97d9d..af9b62d33e6 100644 --- a/progs/tests/vparray.c +++ b/progs/tests/vparray.c @@ -280,9 +280,9 @@ int main(int argc, char **argv) glutInitWindowPosition(0, 0); glutInitWindowSize(400, 400); if (glutCreateWindow("Isosurface") <= 0) { - glewInit(); exit(0); } + glewInit(); glutReshapeFunc(Reshape); glutKeyboardFunc(Key); glutSpecialFunc(SpecialKey); diff --git a/progs/tests/vptest1.c b/progs/tests/vptest1.c index 51629192923..6e32b033468 100644 --- a/progs/tests/vptest1.c +++ b/progs/tests/vptest1.c @@ -128,7 +128,7 @@ static void Init( void ) glLoadProgramNV(GL_VERTEX_PROGRAM_NV, 1, strlen(prog1), (const GLubyte *) prog1); - assert(!glIsProgramNV(1)); + assert(glIsProgramNV(1)); glLoadProgramNV(GL_VERTEX_PROGRAM_NV, 2, strlen(prog2), |