diff options
Diffstat (limited to 'progs/demos')
-rw-r--r-- | progs/demos/.gitignore | 3 | ||||
-rw-r--r-- | progs/demos/Makefile | 36 | ||||
-rw-r--r-- | progs/demos/copypix.c | 248 | ||||
-rw-r--r-- | progs/demos/cubemap.c | 51 | ||||
-rw-r--r-- | progs/demos/descrip.mms | 90 | ||||
-rw-r--r-- | progs/demos/engine.c | 23 | ||||
-rw-r--r-- | progs/demos/fbo_firecube.c | 1041 | ||||
-rw-r--r-- | progs/demos/gearbox.c | 16 | ||||
-rw-r--r--[-rwxr-xr-x] | progs/demos/glslnoise.c | 0 | ||||
-rw-r--r-- | progs/demos/multiarb.c | 123 | ||||
-rw-r--r-- | progs/demos/rain.cxx | 3 | ||||
-rw-r--r-- | progs/demos/shadowtex.c | 63 | ||||
-rw-r--r-- | progs/demos/textures.c | 374 |
13 files changed, 1972 insertions, 99 deletions
diff --git a/progs/demos/.gitignore b/progs/demos/.gitignore index d9e488189b..f033a0505d 100644 --- a/progs/demos/.gitignore +++ b/progs/demos/.gitignore @@ -3,10 +3,12 @@ arbfslight arbocclude bounce clearspd +copypix cubemap drawpix engine extfuncs.h +fbo_firecube fire fogcoord fplight @@ -30,6 +32,7 @@ osdemo paltex pixeltex pointblast +rain ray readpix readtex.c diff --git a/progs/demos/Makefile b/progs/demos/Makefile index fe0e0fbd91..467dbc5cdf 100644 --- a/progs/demos/Makefile +++ b/progs/demos/Makefile @@ -11,7 +11,11 @@ OSMESA16_LIBS = -L$(TOP)/$(LIB_DIR) -lglut -lOSMesa16 -lGLU -lGL $(APP_LIB_DEPS) OSMESA32_LIBS = -L$(TOP)/$(LIB_DIR) -lglut -lOSMesa32 -lGLU -lGL $(APP_LIB_DEPS) -LIB_DEP = $(TOP)/$(LIB_DIR)/$(GL_LIB_NAME) $(TOP)/$(LIB_DIR)/$(GLU_LIB_NAME) $(TOP)/$(LIB_DIR)/$(GLUT_LIB_NAME) +LIB_DEP = $(TOP)/$(LIB_DIR)/$(GL_LIB_NAME) $(TOP)/$(LIB_DIR)/$(GLU_LIB_NAME) \ + $(TOP)/$(LIB_DIR)/$(GLUT_LIB_NAME) + +LIBS = -L$(TOP)/$(LIB_DIR) -l$(GLUT_LIB) -l$(GLU_LIB) -l$(GL_LIB) \ + $(APP_LIB_DEPS) PROGS = \ arbfplight \ @@ -19,9 +23,11 @@ PROGS = \ arbocclude \ bounce \ clearspd \ + copypix \ cubemap \ drawpix \ engine \ + fbo_firecube \ fire \ fogcoord \ fplight \ @@ -42,6 +48,7 @@ PROGS = \ multiarb \ paltex \ pointblast \ + rain \ ray \ readpix \ reflect \ @@ -59,6 +66,7 @@ PROGS = \ texdown \ texenv \ texobj \ + textures \ trispd \ tunnel \ tunnel2 \ @@ -70,11 +78,11 @@ PROGS = \ .SUFFIXES: .SUFFIXES: .c - +.SUFFIXES: .cxx # make executable from .c file: .c: $(LIB_DEP) readtex.o - $(APP_CC) -I$(INCDIR) $(CFLAGS) $< readtex.o $(APP_LIB_DEPS) -o $@ + $(APP_CC) -I$(INCDIR) $(CFLAGS) $(LDFLAGS) $< readtex.o $(LIBS) -o $@ ##### TARGETS ##### @@ -118,39 +126,51 @@ extfuncs.h: $(TOP)/progs/util/extfuncs.h reflect: reflect.o showbuffer.o readtex.o - $(APP_CC) reflect.o showbuffer.o readtex.o $(APP_LIB_DEPS) $(ARCH_FLAGS) -o $@ + $(APP_CC) $(CFLAGS) $(LDFLAGS) reflect.o showbuffer.o readtex.o $(LIBS) -o $@ reflect.o: reflect.c showbuffer.h $(APP_CC) -c -I$(INCDIR) $(CFLAGS) reflect.c shadowtex: shadowtex.o showbuffer.o - $(APP_CC) shadowtex.o showbuffer.o $(APP_LIB_DEPS) $(ARCH_FLAGS) -o $@ + $(APP_CC) $(CFLAGS) $(LDFLAGS) shadowtex.o showbuffer.o $(LIBS) -o $@ shadowtex.o: shadowtex.c showbuffer.h $(APP_CC) -c -I$(INCDIR) $(CFLAGS) shadowtex.c gloss: gloss.o trackball.o readtex.o - $(APP_CC) gloss.o trackball.o readtex.o $(APP_LIB_DEPS) $(ARCH_FLAGS) -o $@ + $(APP_CC) $(CFLAGS) $(LDFLAGS) gloss.o trackball.o readtex.o $(LIBS) -o $@ gloss.o: gloss.c trackball.h $(APP_CC) -c -I$(INCDIR) $(CFLAGS) gloss.c engine: engine.o trackball.o readtex.o - $(APP_CC) engine.o trackball.o readtex.o $(APP_LIB_DEPS) $(ARCH_FLAGS) -o $@ + $(APP_CC) $(CFLAGS) $(LDFLAGS) engine.o trackball.o readtex.o $(LIBS) -o $@ engine.o: engine.c trackball.h $(APP_CC) -c -I$(INCDIR) $(CFLAGS) engine.c fslight: fslight.o - $(APP_CC) fslight.o $(APP_LIB_DEPS) $(ARCH_FLAGS) -o $@ + $(APP_CC) $(CFLAGS) $(LDFLAGS) fslight.o $(LIBS) -o $@ fslight.o: fslight.c extfuncs.h $(APP_CC) -c -I$(INCDIR) $(CFLAGS) fslight.c +rain: particles.o rain.o readtex.o + $(CXX) $(CXXFLAGS) $(LDFLAGS) $^ $(LIBS) -o $@ + +rain.o: rain.cxx readtex.h + $(CXX) -c -I$(INCDIR) $(CXXFLAGS) $< + +particles.o: particles.cxx + $(CXX) -c -I$(INCDIR) $(CXXFLAGS) $< + + +viewdds: viewdds.c + $(CC) -I$(INCDIR) $(CFLAGS) $< readtex.o $(LIBS) -L. -lgltc -o $@ clean: diff --git a/progs/demos/copypix.c b/progs/demos/copypix.c new file mode 100644 index 0000000000..15001e851b --- /dev/null +++ b/progs/demos/copypix.c @@ -0,0 +1,248 @@ +/** + * glCopyPixels test + * + * Brian Paul + * 14 Sep 2007 + */ + + +#define GL_GLEXT_PROTOTYPES + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <GL/glut.h> + +#include "readtex.h" + +#define IMAGE_FILE "../images/arch.rgb" + +static int ImgWidth, ImgHeight; +static GLenum ImgFormat; +static GLubyte *Image = NULL; + +static int WinWidth = 800, WinHeight = 800; +static int Xpos, Ypos; +static int Scissor = 0; +static float Xzoom, Yzoom; +static GLboolean DrawFront = GL_FALSE; +static GLboolean Dither = GL_TRUE; + + +static void Reset( void ) +{ + Xpos = Ypos = 20; + Scissor = 0; + Xzoom = Yzoom = 1.0; +} + + +static void Display( void ) +{ + const int dx = (WinWidth - ImgWidth) / 2; + const int dy = (WinHeight - ImgHeight) / 2; + + if (DrawFront) { + glDrawBuffer(GL_FRONT); + glReadBuffer(GL_FRONT); + } + else { + glDrawBuffer(GL_BACK); + glReadBuffer(GL_BACK); + } + + glClear( GL_COLOR_BUFFER_BIT ); + + /* draw original image */ + glWindowPos2iARB(dx, dy); + glDrawPixels(ImgWidth, ImgHeight, ImgFormat, GL_UNSIGNED_BYTE, Image); + + if (Scissor) + glEnable(GL_SCISSOR_TEST); + + /* draw copy */ + glPixelZoom(Xzoom, Yzoom); + glWindowPos2iARB(Xpos, Ypos); + glCopyPixels(dx, dy, ImgWidth, ImgHeight, GL_COLOR); + glPixelZoom(1, 1); + + glDisable(GL_SCISSOR_TEST); + + if (DrawFront) + glFinish(); + else + glutSwapBuffers(); +} + + +static void Reshape( int width, int height ) +{ + WinWidth = width; + WinHeight = height; + + glViewport( 0, 0, width, height ); + glMatrixMode( GL_PROJECTION ); + glLoadIdentity(); + glOrtho( 0.0, width, 0.0, height, 0.0, 2.0 ); + glMatrixMode( GL_MODELVIEW ); + glLoadIdentity(); + + glScissor(width/4, height/4, width/2, height/2); +} + + +static void Key( unsigned char key, int x, int y ) +{ + (void) x; + (void) y; + switch (key) { + case ' ': + Reset(); + break; + case 'd': + Dither = !Dither; + if (Dither) + glEnable(GL_DITHER); + else + glDisable(GL_DITHER); + break; + case 's': + Scissor = !Scissor; + break; + case 'x': + Xzoom -= 0.1; + break; + case 'X': + Xzoom += 0.1; + break; + case 'y': + Yzoom -= 0.1; + break; + case 'Y': + Yzoom += 0.1; + break; + case 'f': + DrawFront = !DrawFront; + printf("glDrawBuffer(%s)\n", DrawFront ? "GL_FRONT" : "GL_BACK"); + break; + case 27: + exit(0); + break; + } + glutPostRedisplay(); +} + + +static void SpecialKey( int key, int x, int y ) +{ + const int step = (glutGetModifiers() & GLUT_ACTIVE_SHIFT) ? 10 : 1; + (void) x; + (void) y; + switch (key) { + case GLUT_KEY_UP: + Ypos += step; + break; + case GLUT_KEY_DOWN: + Ypos -= step; + break; + case GLUT_KEY_LEFT: + Xpos -= step; + break; + case GLUT_KEY_RIGHT: + Xpos += step; + break; + } + glutPostRedisplay(); +} + + +static void Init( GLboolean ciMode, const char *filename ) +{ + printf("GL_VERSION = %s\n", (char *) glGetString(GL_VERSION)); + printf("GL_RENDERER = %s\n", (char *) glGetString(GL_RENDERER)); + + Image = LoadRGBImage( filename, &ImgWidth, &ImgHeight, &ImgFormat ); + if (!Image) { + printf("Couldn't read %s\n", filename); + exit(0); + } + + if (ciMode) { + /* Convert RGB image to grayscale */ + GLubyte *indexImage = (GLubyte *) malloc( ImgWidth * ImgHeight ); + GLint i; + for (i=0; i<ImgWidth*ImgHeight; i++) { + int gray = Image[i*3] + Image[i*3+1] + Image[i*3+2]; + indexImage[i] = gray / 3; + } + free(Image); + Image = indexImage; + ImgFormat = GL_COLOR_INDEX; + + for (i=0;i<255;i++) { + float g = i / 255.0; + glutSetColor(i, g, g, g); + } + } + + printf("Loaded %d by %d image\n", ImgWidth, ImgHeight ); + + glPixelStorei(GL_UNPACK_ALIGNMENT, 1); + glPixelStorei(GL_UNPACK_ROW_LENGTH, ImgWidth); + + Reset(); +} + + +static void Usage(void) +{ + printf("Keys:\n"); + printf(" SPACE Reset Parameters\n"); + printf(" Up/Down Move image up/down (SHIFT for large step)\n"); + printf(" Left/Right Move image left/right (SHIFT for large step)\n"); + printf(" x Decrease X-axis PixelZoom\n"); + printf(" X Increase X-axis PixelZoom\n"); + printf(" y Decrease Y-axis PixelZoom\n"); + printf(" Y Increase Y-axis PixelZoom\n"); + printf(" s Toggle GL_SCISSOR_TEST\n"); + printf(" f Toggle front/back buffer drawing\n"); + printf(" ESC Exit\n"); +} + + +int main( int argc, char *argv[] ) +{ + GLboolean ciMode = GL_FALSE; + const char *filename = IMAGE_FILE; + int i = 1; + + if (argc > i && strcmp(argv[i], "-ci")==0) { + ciMode = GL_TRUE; + i++; + } + if (argc > i) { + filename = argv[i]; + } + + glutInit( &argc, argv ); + glutInitWindowPosition( 0, 0 ); + glutInitWindowSize( WinWidth, WinHeight ); + + if (ciMode) + glutInitDisplayMode( GLUT_INDEX | GLUT_DOUBLE ); + else + glutInitDisplayMode( GLUT_RGB | GLUT_DOUBLE); + + glutCreateWindow(argv[0]); + + Init(ciMode, filename); + Usage(); + + glutReshapeFunc( Reshape ); + glutKeyboardFunc( Key ); + glutSpecialFunc( SpecialKey ); + glutDisplayFunc( Display ); + + glutMainLoop(); + return 0; +} diff --git a/progs/demos/cubemap.c b/progs/demos/cubemap.c index ef5d235550..b3bdd64f68 100644 --- a/progs/demos/cubemap.c +++ b/progs/demos/cubemap.c @@ -47,6 +47,8 @@ static GLfloat Xrot = 0, Yrot = 0; static GLfloat EyeDist = 10; static GLboolean use_vertex_arrays = GL_FALSE; static GLboolean anim = GL_TRUE; +static GLboolean NoClear = GL_FALSE; +static GLint FrameParity = 0; #define eps1 0.99 #define br 20.0 /* box radius */ @@ -156,7 +158,30 @@ static void draw_skybox( void ) static void draw( void ) { - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + if (NoClear) { + /* This demonstrates how we can avoid calling glClear. + * This method only works if every pixel in the window is painted for + * every frame. + * We can simply skip clearing of the color buffer in this case. + * For the depth buffer, we alternately use a different subrange of + * the depth buffer for each frame. For the odd frame use the range + * [0, 0.5] with GL_LESS. For the even frames, use the range [1, 0.5] + * with GL_GREATER. + */ + FrameParity = 1 - FrameParity; + if (FrameParity) { + glDepthRange(0.0, 0.5); + glDepthFunc(GL_LESS); + } + else { + glDepthRange(1.0, 0.5); + glDepthFunc(GL_GREATER); + } + } + else { + /* ordinary clearing */ + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + } glPushMatrix(); /*MODELVIEW*/ glTranslatef( 0.0, 0.0, -EyeDist ); @@ -452,6 +477,24 @@ static void usage(void) } +static void parse_args(int argc, char *argv[]) +{ + int initFlag = 0; + int i; + + for (i = 1; i < argc; i++) { + if (strcmp(argv[i], "-i") == 0) + initFlag = 1; + else if (strcmp(argv[i], "--noclear") == 0) + NoClear = GL_TRUE; + else { + fprintf(stderr, "Bad option: %s\n", argv[i]); + exit(1); + } + } + init (initFlag); +} + int main( int argc, char *argv[] ) { glutInit(&argc, argv); @@ -459,17 +502,13 @@ int main( int argc, char *argv[] ) glutInitWindowSize(600, 500); glutInitDisplayMode( GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE ); glutCreateWindow("Texture Cube Mapping"); - - if (argc > 1 && strcmp(argv[1] , "-i") == 0) - init( 1 ); - else - init( 0 ); glutReshapeFunc( reshape ); glutKeyboardFunc( key ); glutSpecialFunc( specialkey ); glutDisplayFunc( draw ); if (anim) glutIdleFunc(idle); + parse_args(argc, argv); usage(); glutMainLoop(); return 0; diff --git a/progs/demos/descrip.mms b/progs/demos/descrip.mms new file mode 100644 index 0000000000..d7a912133a --- /dev/null +++ b/progs/demos/descrip.mms @@ -0,0 +1,90 @@ +# Makefile for GLUT-based demo programs for VMS +# contributed by Jouk Jansen joukj@hrem.nano.tudelft.nl +# Last update : 30 November 2007 + +.first + define gl [--.include.gl] + +.include [--]mms-config. + +##### MACROS ##### + +INCDIR = ([--.include],[-.util]) +CFLAGS =/include=$(INCDIR)/prefix=all/name=(as_is,short)/float=ieee/ieee=denorm + +.ifdef SHARE +GL_LIBS = $(XLIBS) +LIB_DEP = [--.lib]$(GL_SHAR) [--.lib]$(GLU_SHAR) [--.lib]$(GLUT_SHAR) +.else +GL_LIBS = [--.lib]libGLUT/l,libMesaGLU/l,libMesaGL/l,$(XLIBS) +LIB_DEP = [--.lib]$(GL_LIB) [--.lib]$(GLU_LIB) [--.lib]$(GLUT_LIB) +.endif + + +PROGS = bounce.exe,clearspd.exe,drawpix.exe,gamma.exe,gears.exe,\ + glinfo.exe,glutfx.exe,isosurf.exe,morph3d.exe,\ + paltex.exe,pointblast.exe,reflect.exe,spectex.exe,stex3d.exe,\ + tessdemo.exe,texcyl.exe,texobj.exe,trispd.exe,winpos.exe + + +##### RULES ##### +.obj.exe : + cxxlink $(MMS$TARGET_NAME),$(GL_LIBS) + +##### TARGETS ##### +default : + $(MMS)$(MMSQUALIFIERS) $(PROGS) + +clean : + delete *.obj;* + +realclean : + delete *.exe;* + delete *.obj;* + +bounce.exe : bounce.obj $(LIB_DEP) +clearspd.exe : clearspd.obj $(LIB_DEP) +drawpix.exe : drawpix.obj $(LIB_DEP) [-.util]readtex.obj + cxxlink $(MMS$TARGET_NAME),[-.util]readtex.obj,$(GL_LIBS) +gamma.exe : gamma.obj $(LIB_DEP) +gears.exe : gears.obj $(LIB_DEP) +glinfo.exe : glinfo.obj $(LIB_DEP) +glutfx.exe : glutfx.obj $(LIB_DEP) +isosurf.exe : isosurf.obj $(LIB_DEP) [-.util]readtex.obj + cxxlink $(MMS$TARGET_NAME),[-.util]readtex.obj,$(GL_LIBS) +morph3d.exe : morph3d.obj $(LIB_DEP) +paltex.exe : paltex.obj $(LIB_DEP) +pointblast.exe : pointblast.obj $(LIB_DEP) +reflect.exe : reflect.obj [-.util]readtex.obj [-.util]showbuffer.obj\ + $(LIB_DEP) + cxxlink $(MMS$TARGET_NAME),[-.util]readtex,showbuffer,$(GL_LIBS) +spectex.exe : spectex.obj $(LIB_DEP) +stex3d.exe : stex3d.obj $(LIB_DEP) +tessdemo.exe : tessdemo.obj $(LIB_DEP) +texcyl.exe : texcyl.obj [-.util]readtex.obj $(LIB_DEP) + cxxlink $(MMS$TARGET_NAME),[-.util]readtex.obj,$(GL_LIBS) +texobj.exe : texobj.obj $(LIB_DEP) +trispd.exe : trispd.obj $(LIB_DEP) +winpos.exe : winpos.obj [-.util]readtex.obj $(LIB_DEP) + cxxlink $(MMS$TARGET_NAME),[-.util]readtex.obj,$(GL_LIBS) + + +bounce.obj : bounce.c +clearspd.obj : clearspd.c +drawpix.obj : drawpix.c +gamma.obj : gamma.c +gears.obj : gears.c +glinfo.obj : glinfo.c +glutfx.obj : glutfx.c +isosurf.obj : isosurf.c +morph3d.obj : morph3d.c +paltex.obj : paltex.c +pointblast.obj : pointblast.c +reflect.obj : reflect.c +spectex.obj : spectex.c +stex3d.obj : stex3d.c +tessdemo.obj : tessdemo.c +texcyl.obj : texcyl.c +texobj.obj : texobj.c +trispd.obj : trispd.c +winpos.obj : winpos.c diff --git a/progs/demos/engine.c b/progs/demos/engine.c index 143b02a889..6040a2f103 100644 --- a/progs/demos/engine.c +++ b/progs/demos/engine.c @@ -16,6 +16,10 @@ #include "trackball.h" +#ifndef M_PI +#define M_PI 3.14159265358979323846 +#endif + #define DEG_TO_RAD(DEG) ((DEG) * M_PI / 180.0) #define TEXTURE_FILE "../images/reflect.rgb" @@ -441,8 +445,8 @@ DrawConnector(float length, float thickness, for (i = 0; i <= 36; i++) { const int j = i % 36; glNormal3f(normals[j][0], normals[j][1], 0); - glVertex3f(points[j][0], points[j][1], z0); glVertex3f(points[j][0], points[j][1], z1); + glVertex3f(points[j][0], points[j][1], z0); } glEnd(); } @@ -741,7 +745,7 @@ DrawEngine(const Engine *eng, float crankAngle) glTranslatef(0, 0, -0.5 * crankLen); /* crankshaft */ - glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, CrankshaftColor); + glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, CrankshaftColor); glColor4fv(CrankshaftColor); DrawPositionedCrankshaft(eng, crankAngle); @@ -760,12 +764,12 @@ DrawEngine(const Engine *eng, float crankAngle) rot += k * eng->V_Angle; /* piston */ - glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, PistonColor); + glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, PistonColor); glColor4fv(PistonColor); DrawPositionedPiston(eng, rot); /* connecting rod */ - glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, ConnRodColor); + glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, ConnRodColor); glColor4fv(ConnRodColor); DrawPositionedConnectingRod(eng, rot); glPopMatrix(); @@ -780,7 +784,7 @@ DrawEngine(const Engine *eng, float crankAngle) } glEnable(GL_CULL_FACE); - glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, BlockColor); + glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, BlockColor); glColor4fv(BlockColor); if (eng->CrankList) glCallList(eng->BlockList); @@ -1250,6 +1254,7 @@ Init(void) { const GLfloat lightColor[4] = { 0.7, 0.7, 0.7, 1.0 }; const GLfloat specular[4] = { 0.8, 0.8, 0.8, 1.0 }; + const GLfloat backColor[4] = { 1, 1, 0, 0 }; Q = gluNewQuadric(); gluQuadricNormals(Q, GLU_SMOOTH); @@ -1261,10 +1266,14 @@ Init(void) glEnable(GL_LIGHTING); glEnable(GL_LIGHT0); glLightfv(GL_LIGHT0, GL_DIFFUSE, lightColor); - glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 40); - glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, specular); + glMaterialf(GL_FRONT, GL_SHININESS, 40); + glMaterialfv(GL_FRONT, GL_SPECULAR, specular); glEnable(GL_NORMALIZE); + glMaterialfv(GL_BACK, GL_DIFFUSE, backColor); +#if 0 + glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, 1); +#endif glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); InitViewInfo(&View); diff --git a/progs/demos/fbo_firecube.c b/progs/demos/fbo_firecube.c new file mode 100644 index 0000000000..ed87dd133c --- /dev/null +++ b/progs/demos/fbo_firecube.c @@ -0,0 +1,1041 @@ +/* + * Draw the "fire" test program on the six faces of a cube using + * fbo render-to-texture. + * + * Much of the code comes from David Bucciarelli's "fire" + * test program. The rest basically from Brian Paul's "gearbox" and + * fbotexture programs. + * + * By pressing the 'q' key, you can make the driver choose different + * internal texture RGBA formats by giving it different "format" and "type" + * arguments to the glTexImage2D function that creates the texture + * image being rendered to. If the driver doesn't support a texture image + * format as a render target, it will usually fall back to software when + * drawing the "fire" image, and frame-rate should drop considerably. + * + * Performance: + * The rendering speed of this program is usually dictated by fill rate + * and the fact that software fallbacks for glBitMap makes the driver + * operate synchronously. Low-end UMA hardware will probably see around + * 35 fps with the help screen disabled and 32bpp window- and user + * frame-buffers (2008). + * + * This program is released under GPL, following the "fire" licensing. + * + * Authors: + * David Bucciarelli ("fire") + * Brian Paul ("gearbox", "fbotexture") + * Thomas Hellstrom (Putting it together) + * + */ + +#define GL_GLEXT_PROTOTYPES +#include <math.h> +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <GL/glut.h> +#include "readtex.h" + + +/* + * Format of texture we render to. + */ + +#define TEXINTFORMAT GL_RGBA + +static GLuint texTypes[] = + {GL_UNSIGNED_BYTE, + GL_UNSIGNED_INT_8_8_8_8_REV, + GL_UNSIGNED_SHORT_1_5_5_5_REV, + GL_UNSIGNED_SHORT_4_4_4_4_REV, + GL_UNSIGNED_INT_8_8_8_8, + GL_UNSIGNED_SHORT_5_5_5_1, + GL_UNSIGNED_SHORT_4_4_4_4, + GL_UNSIGNED_INT_8_8_8_8_REV, + GL_UNSIGNED_SHORT_1_5_5_5_REV, + GL_UNSIGNED_SHORT_4_4_4_4_REV, + GL_UNSIGNED_INT_8_8_8_8, + GL_UNSIGNED_SHORT_5_5_5_1, + GL_UNSIGNED_SHORT_4_4_4_4, + GL_UNSIGNED_SHORT_5_6_5, + GL_UNSIGNED_SHORT_5_6_5_REV, + GL_UNSIGNED_SHORT_5_6_5, + GL_UNSIGNED_SHORT_5_6_5_REV}; + +static GLuint texFormats[] = + {GL_RGBA, + GL_RGBA, + GL_RGBA, + GL_RGBA, + GL_RGBA, + GL_RGBA, + GL_RGBA, + GL_BGRA, + GL_BGRA, + GL_BGRA, + GL_BGRA, + GL_BGRA, + GL_BGRA, + GL_RGB, + GL_RGB, + GL_BGR, + GL_BGR}; + +static const char *texNames[] = + {"GL_RGBA GL_UNSIGNED_BYTE", + "GL_RGBA GL_UNSIGNED_INT_8_8_8_8_REV", + "GL_RGBA GL_UNSIGNED_SHORT_1_5_5_5_REV", + "GL_RGBA GL_UNSIGNED_SHORT_4_4_4_4_REV", + "GL_RGBA GL_UNSIGNED_INT_8_8_8_8", + "GL_RGBA GL_UNSIGNED_INT_5_5_5_1", + "GL_RGBA GL_UNSIGNED_INT_4_4_4_4", + "GL_BGRA GL_UNSIGNED_INT_8_8_8_8_REV", + "GL_BGRA GL_UNSIGNED_SHORT_1_5_5_5_REV", + "GL_BGRA GL_UNSIGNED_SHORT_4_4_4_4_REV", + "GL_BGRA GL_UNSIGNED_INT_8_8_8_8", + "GL_BGRA GL_UNSIGNED_INT_5_5_5_1", + "GL_BGRA GL_UNSIGNED_INT_4_4_4_4", + "GL_RGB GL_UNSIGNED_INT_5_6_5", + "GL_RGB GL_UNSIGNED_INT_5_6_5_REV", + "GL_BGR GL_UNSIGNED_INT_5_6_5", + "GL_BGR GL_UNSIGNED_INT_5_6_5_REV"}; + + + + +#ifndef M_PI +#define M_PI 3.1415926535 +#endif + +#define vinit(a,i,j,k) { \ + (a)[0]=i; \ + (a)[1]=j; \ + (a)[2]=k; \ + } + +#define vinit4(a,i,j,k,w) { \ + (a)[0]=i; \ + (a)[1]=j; \ + (a)[2]=k; \ + (a)[3]=w; \ + } + + +#define vadds(a,dt,b) { \ + (a)[0]+=(dt)*(b)[0]; \ + (a)[1]+=(dt)*(b)[1]; \ + (a)[2]+=(dt)*(b)[2]; \ + } + +#define vequ(a,b) { \ + (a)[0]=(b)[0]; \ + (a)[1]=(b)[1]; \ + (a)[2]=(b)[2]; \ + } + +#define vinter(a,dt,b,c) { \ + (a)[0]=(dt)*(b)[0]+(1.0-dt)*(c)[0]; \ + (a)[1]=(dt)*(b)[1]+(1.0-dt)*(c)[1]; \ + (a)[2]=(dt)*(b)[2]+(1.0-dt)*(c)[2]; \ + } + +#define clamp(a) ((a) < 0.0 ? 0.0 : ((a) < 1.0 ? (a) : 1.0)) + +#define vclamp(v) { \ + (v)[0]=clamp((v)[0]); \ + (v)[1]=clamp((v)[1]); \ + (v)[2]=clamp((v)[2]); \ + } + +static GLint WinWidth = 800, WinHeight = 800; +static GLint TexWidth, TexHeight; +static GLuint TexObj; +static GLuint MyFB; +static GLuint DepthRB; +static GLboolean WireFrame = GL_FALSE; +static GLint texType = 0; + +static GLint T0 = 0; +static GLint Frames = 0; +static GLint Win = 0; + +static GLfloat ViewRotX = 20.0, ViewRotY = 30.0, ViewRotZ = 0.0; +static GLfloat CubeRot = 0.0; + +static void +CheckError(int line) +{ + GLenum err = glGetError(); + if (err) { + printf("GL Error 0x%x at line %d\n", (int) err, line); + exit(1); + } +} + + +static void +cleanup(void) +{ + glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); + glDeleteFramebuffersEXT(1, &MyFB); + glDeleteRenderbuffersEXT(1, &DepthRB); + glDeleteTextures(1, &TexObj); + glutDestroyWindow(Win); +} + +static GLint NiceFog = 1; + +#define DIMP 20.0 +#define DIMTP 16.0 + +#define RIDCOL 0.4 + +#define NUMTREE 50 +#define TREEINR 2.5 +#define TREEOUTR 8.0 + +#define AGRAV -9.8 + +typedef struct +{ + int age; + float p[3][3]; + float v[3]; + float c[3][4]; +} + part; + +static float treepos[NUMTREE][3]; + +static float black[3] = { 0.0, 0.0, 0.0 }; +static float blu[3] = { 1.0, 0.2, 0.0 }; +static float blu2[3] = { 1.0, 1.0, 0.0 }; + +static float fogcolor[4] = { 1.0, 1.0, 1.0, 1.0 }; + +static float q[4][3] = { + {-DIMP, 0.0, -DIMP}, + {DIMP, 0.0, -DIMP}, + {DIMP, 0.0, DIMP}, + {-DIMP, 0.0, DIMP} +}; + +static float qt[4][2] = { + {-DIMTP, -DIMTP}, + {DIMTP, -DIMTP}, + {DIMTP, DIMTP}, + {-DIMTP, DIMTP} +}; + +static int np; +static float eject_r, dt, maxage, eject_vy, eject_vl; +static short shadows; +static float ridtri; +static int fog = 0; +static int help = 1; + +static part *p; + +static GLuint groundid; +static GLuint treeid; + +static float obs[3] = { 2.0, 1.0, 0.0 }; +static float dir[3]; +static float v = 0.0; +static float alpha = -84.0; +static float beta = 90.0; + +static float +vrnd(void) +{ + return (((float) rand()) / RAND_MAX); +} + +static void +setnewpart(part * p) +{ + float a, v[3], *c; + + p->age = 0; + + a = vrnd() * 3.14159265359 * 2.0; + + vinit(v, sin(a) * eject_r * vrnd(), 0.15, cos(a) * eject_r * vrnd()); + vinit(p->p[0], v[0] + vrnd() * ridtri, v[1] + vrnd() * ridtri, + v[2] + vrnd() * ridtri); + vinit(p->p[1], v[0] + vrnd() * ridtri, v[1] + vrnd() * ridtri, + v[2] + vrnd() * ridtri); + vinit(p->p[2], v[0] + vrnd() * ridtri, v[1] + vrnd() * ridtri, + v[2] + vrnd() * ridtri); + + vinit(p->v, v[0] * eject_vl / (eject_r / 2), + vrnd() * eject_vy + eject_vy / 2, v[2] * eject_vl / (eject_r / 2)); + + c = blu; + + vinit4(p->c[0], c[0] * ((1.0 - RIDCOL) + vrnd() * RIDCOL), + c[1] * ((1.0 - RIDCOL) + vrnd() * RIDCOL), + c[2] * ((1.0 - RIDCOL) + vrnd() * RIDCOL), 1.0); + vinit4(p->c[1], c[0] * ((1.0 - RIDCOL) + vrnd() * RIDCOL), + c[1] * ((1.0 - RIDCOL) + vrnd() * RIDCOL), + c[2] * ((1.0 - RIDCOL) + vrnd() * RIDCOL), 1.0); + vinit4(p->c[2], c[0] * ((1.0 - RIDCOL) + vrnd() * RIDCOL), + c[1] * ((1.0 - RIDCOL) + vrnd() * RIDCOL), + c[2] * ((1.0 - RIDCOL) + vrnd() * RIDCOL), 1.0); +} + +static void +setpart(part * p) +{ + float fact; + + if (p->p[0][1] < 0.1) { + setnewpart(p); + return; + } + + p->v[1] += AGRAV * dt; + + vadds(p->p[0], dt, p->v); + vadds(p->p[1], dt, p->v); + vadds(p->p[2], dt, p->v); + + p->age++; + + if ((p->age) > maxage) { + vequ(p->c[0], blu2); + vequ(p->c[1], blu2); + vequ(p->c[2], blu2); + } + else { + fact = 1.0 / maxage; + vadds(p->c[0], fact, blu2); + vclamp(p->c[0]); + p->c[0][3] = fact * (maxage - p->age); + + vadds(p->c[1], fact, blu2); + vclamp(p->c[1]); + p->c[1][3] = fact * (maxage - p->age); + + vadds(p->c[2], fact, blu2); + vclamp(p->c[2]); + p->c[2][3] = fact * (maxage - p->age); + } +} + +static void +drawtree(float x, float y, float z) +{ + glBegin(GL_QUADS); + glTexCoord2f(0.0, 0.0); + glVertex3f(x - 1.5, y + 0.0, z); + + glTexCoord2f(1.0, 0.0); + glVertex3f(x + 1.5, y + 0.0, z); + + glTexCoord2f(1.0, 1.0); + glVertex3f(x + 1.5, y + 3.0, z); + + glTexCoord2f(0.0, 1.0); + glVertex3f(x - 1.5, y + 3.0, z); + + + glTexCoord2f(0.0, 0.0); + glVertex3f(x, y + 0.0, z - 1.5); + + glTexCoord2f(1.0, 0.0); + glVertex3f(x, y + 0.0, z + 1.5); + + glTexCoord2f(1.0, 1.0); + glVertex3f(x, y + 3.0, z + 1.5); + + glTexCoord2f(0.0, 1.0); + glVertex3f(x, y + 3.0, z - 1.5); + + glEnd(); + +} + +static void +calcposobs(void) +{ + dir[0] = sin(alpha * M_PI / 180.0); + dir[2] = cos(alpha * M_PI / 180.0) * sin(beta * M_PI / 180.0); + dir[1] = cos(beta * M_PI / 180.0); + + if (dir[0] < 1.0e-5 && dir[0] > -1.0e-5) + dir[0] = 0; + if (dir[1] < 1.0e-5 && dir[1] > -1.0e-5) + dir[1] = 0; + if (dir[2] < 1.0e-5 && dir[2] > -1.0e-5) + dir[2] = 0; + + obs[0] += v * dir[0]; + obs[1] += v * dir[1]; + obs[2] += v * dir[2]; +} + +static void +printstring(void *font, const char *string) +{ + int len, i; + + len = (int) strlen(string); + for (i = 0; i < len; i++) + glutBitmapCharacter(font, string[i]); +} + + +static void +printhelp(void) +{ + glColor4f(0.0, 0.0, 0.0, 0.5); + glRecti(40, 40, 600, 440); + + glColor3f(1.0, 0.0, 0.0); + glRasterPos2i(300, 420); + printstring(GLUT_BITMAP_TIMES_ROMAN_24, "Help"); + + glRasterPos2i(60, 390); + printstring(GLUT_BITMAP_TIMES_ROMAN_24, "h - Toggle Help"); + + glRasterPos2i(60, 360); + printstring(GLUT_BITMAP_TIMES_ROMAN_24, "t - Increase particle size"); + glRasterPos2i(60, 330); + printstring(GLUT_BITMAP_TIMES_ROMAN_24, "T - Decrease particle size"); + + glRasterPos2i(60, 300); + printstring(GLUT_BITMAP_TIMES_ROMAN_24, "r - Increase emission radius"); + glRasterPos2i(60, 270); + printstring(GLUT_BITMAP_TIMES_ROMAN_24, "R - Decrease emission radius"); + + glRasterPos2i(60, 240); + printstring(GLUT_BITMAP_TIMES_ROMAN_24, "f - Toggle Fog"); + glRasterPos2i(60, 210); + printstring(GLUT_BITMAP_TIMES_ROMAN_24, "s - Toggle shadows"); + glRasterPos2i(60, 180); + printstring(GLUT_BITMAP_TIMES_ROMAN_24, "q - Toggle texture format & type"); + glRasterPos2i(60, 150); + printstring(GLUT_BITMAP_TIMES_ROMAN_24, "a - Increase velocity"); + glRasterPos2i(60, 120); + printstring(GLUT_BITMAP_TIMES_ROMAN_24, "z - Decrease velocity"); + glRasterPos2i(60, 90); + printstring(GLUT_BITMAP_TIMES_ROMAN_24, "Arrow Keys - Rotate"); +} + + +static void +drawfire(void) +{ + static char frbuf[80] = ""; + int j; + static double t0 = -1.; + double t = glutGet(GLUT_ELAPSED_TIME) / 1000.0; + if (t0 < 0.0) + t0 = t; + dt = (t - t0) * 1.0; + t0 = t; + + glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, MyFB); + + glDisable(GL_LIGHTING); + + glShadeModel(GL_FLAT); + + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + + glEnable(GL_FOG); + glFogi(GL_FOG_MODE, GL_EXP); + glFogfv(GL_FOG_COLOR, fogcolor); + glFogf(GL_FOG_DENSITY, 0.1); + + + glViewport(0, 0, (GLint) TexWidth, (GLint) TexHeight); + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + gluPerspective(70.0, TexWidth/ (float) TexHeight, 0.1, 30.0); + + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + + if (NiceFog) + glHint(GL_FOG_HINT, GL_NICEST); + else + glHint(GL_FOG_HINT, GL_DONT_CARE); + + glEnable(GL_DEPTH_TEST); + + if (fog) + glEnable(GL_FOG); + else + glDisable(GL_FOG); + + glDepthMask(GL_TRUE); + glClearColor(1.0, 1.0, 1.0, 1.0); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + + glPushMatrix(); + calcposobs(); + gluLookAt(obs[0], obs[1], obs[2], + obs[0] + dir[0], obs[1] + dir[1], obs[2] + dir[2], + 0.0, 1.0, 0.0); + + glColor4f(1.0, 1.0, 1.0, 1.0); + + glEnable(GL_TEXTURE_2D); + + glBindTexture(GL_TEXTURE_2D, groundid); + glBegin(GL_QUADS); + glTexCoord2fv(qt[0]); + glVertex3fv(q[0]); + glTexCoord2fv(qt[1]); + glVertex3fv(q[1]); + glTexCoord2fv(qt[2]); + glVertex3fv(q[2]); + glTexCoord2fv(qt[3]); + glVertex3fv(q[3]); + glEnd(); + + glEnable(GL_ALPHA_TEST); + glAlphaFunc(GL_GEQUAL, 0.9); + + glBindTexture(GL_TEXTURE_2D, treeid); + for (j = 0; j < NUMTREE; j++) + drawtree(treepos[j][0], treepos[j][1], treepos[j][2]); + + glDisable(GL_TEXTURE_2D); + glDepthMask(GL_FALSE); + glDisable(GL_ALPHA_TEST); + + if (shadows) { + glBegin(GL_TRIANGLES); + for (j = 0; j < np; j++) { + glColor4f(black[0], black[1], black[2], p[j].c[0][3]); + glVertex3f(p[j].p[0][0], 0.1, p[j].p[0][2]); + + glColor4f(black[0], black[1], black[2], p[j].c[1][3]); + glVertex3f(p[j].p[1][0], 0.1, p[j].p[1][2]); + + glColor4f(black[0], black[1], black[2], p[j].c[2][3]); + glVertex3f(p[j].p[2][0], 0.1, p[j].p[2][2]); + } + glEnd(); + } + + glBegin(GL_TRIANGLES); + for (j = 0; j < np; j++) { + glColor4fv(p[j].c[0]); + glVertex3fv(p[j].p[0]); + + glColor4fv(p[j].c[1]); + glVertex3fv(p[j].p[1]); + + glColor4fv(p[j].c[2]); + glVertex3fv(p[j].p[2]); + + setpart(&p[j]); + } + glEnd(); + + + glDisable(GL_TEXTURE_2D); + glDisable(GL_ALPHA_TEST); + glDisable(GL_DEPTH_TEST); + glDisable(GL_FOG); + + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + glOrtho(-0.5, 639.5, -0.5, 479.5 + , -1.0, 1.0); + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + + glColor3f(1.0, 0.0, 0.0); + glRasterPos2i(10, 10); + printstring(GLUT_BITMAP_HELVETICA_18, frbuf); + glColor3f(0.0, 0.0, 1.0); + glRasterPos2i(10, 450); + printstring(GLUT_BITMAP_HELVETICA_18, texNames[texType]); + glColor3f(1.0, 0.0, 0.0); + glRasterPos2i(10, 470); + printstring(GLUT_BITMAP_HELVETICA_10, + "Fire V1.5 Written by David Bucciarelli (tech.hmw@plus.it)"); + + if (help) + printhelp(); + + glPopMatrix(); + glDepthMask(GL_TRUE); + glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); + Frames++; + + { + GLint t = glutGet(GLUT_ELAPSED_TIME); + if (t - T0 >= 2000) { + GLfloat seconds = (t - T0) / 1000.0; + GLfloat fps = Frames / seconds; + sprintf(frbuf, "Frame rate: %f", fps); + T0 = t; + Frames = 0; + } + } + +} + +static void +regen_texImage(void) +{ + glBindTexture(GL_TEXTURE_2D, TexObj); + glTexImage2D(GL_TEXTURE_2D, 0, TEXINTFORMAT, TexWidth, TexHeight, 0, + texFormats[texType], texTypes[texType], NULL); + glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, MyFB); + glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, + GL_TEXTURE_2D, TexObj, 0); + glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); +} + +static void +key(unsigned char key, int x, int y) +{ + switch (key) { + case 27: + cleanup(); + exit(0); + break; + + case 'a': + v += 0.0005; + break; + case 'z': + v -= 0.0005; + break; + case 'h': + help = (!help); + break; + case 'f': + fog = (!fog); + break; + case 's': + shadows = !shadows; + break; + case 'R': + eject_r -= 0.03; + break; + case 'r': + eject_r += 0.03; + break; + case 't': + ridtri += 0.005; + break; + case 'T': + ridtri -= 0.005; + break; + case 'v': + ViewRotZ += 5.0; + break; + case 'V': + ViewRotZ -= 5.0; + break; + case 'w': + WireFrame = !WireFrame; + break; + case 'q': + if (++texType > 16) + texType = 0; + regen_texImage(); + break; + case 'n': + NiceFog = !NiceFog; + printf("NiceFog %d\n", NiceFog); + break; + } + glutPostRedisplay(); +} + +static void +inittextures(void) +{ + GLenum gluerr; + GLubyte tex[128][128][4]; + + glGenTextures(1, &groundid); + glBindTexture(GL_TEXTURE_2D, groundid); + + glPixelStorei(GL_UNPACK_ALIGNMENT, 4); + if (!LoadRGBMipmaps("../images/s128.rgb", GL_RGB)) { + fprintf(stderr, "Error reading a texture.\n"); + exit(-1); + } + + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); + + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, + GL_LINEAR_MIPMAP_LINEAR); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + + glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL); + + glGenTextures(1, &treeid); + glBindTexture(GL_TEXTURE_2D, treeid); + + if (1) + { + int w, h; + GLenum format; + int x, y; + GLubyte *image = LoadRGBImage("../images/tree3.rgb", &w, &h, &format); + + if (!image) { + fprintf(stderr, "Error reading a texture.\n"); + exit(-1); + } + + for (y = 0; y < 128; y++) + for (x = 0; x < 128; x++) { + tex[x][y][0] = image[(y + x * 128) * 3]; + tex[x][y][1] = image[(y + x * 128) * 3 + 1]; + tex[x][y][2] = image[(y + x * 128) * 3 + 2]; + if ((tex[x][y][0] == tex[x][y][1]) && + (tex[x][y][1] == tex[x][y][2]) && (tex[x][y][2] == 255)) + tex[x][y][3] = 0; + else + tex[x][y][3] = 255; + } + + if ((gluerr = gluBuild2DMipmaps(GL_TEXTURE_2D, 4, 128, 128, GL_RGBA, + GL_UNSIGNED_BYTE, (GLvoid *) (tex)))) { + fprintf(stderr, "GLULib%s\n", (char *) gluErrorString(gluerr)); + exit(-1); + } + } + else { + if (!LoadRGBMipmaps("../images/tree2.rgba", GL_RGBA)) { + fprintf(stderr, "Error reading a texture.\n"); + exit(-1); + } + } + + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); + + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, + GL_LINEAR_MIPMAP_LINEAR); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + + glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); +} + +static void +inittree(void) +{ + int i; + float dist; + + for (i = 0; i < NUMTREE; i++) + do { + treepos[i][0] = vrnd() * TREEOUTR * 2.0 - TREEOUTR; + treepos[i][1] = 0.0; + treepos[i][2] = vrnd() * TREEOUTR * 2.0 - TREEOUTR; + dist = + sqrt(treepos[i][0] * treepos[i][0] + + treepos[i][2] * treepos[i][2]); + } while ((dist < TREEINR) || (dist > TREEOUTR)); +} + +static int +init_fire(int ac, char *av[]) +{ + int i; + + np = 800; + eject_r = -0.65; + dt = 0.015; + eject_vy = 4; + eject_vl = 1; + shadows = 1; + ridtri = 0.25; + + maxage = 1.0 / dt; + + if (ac == 2) + np = atoi(av[1]); + + + inittextures(); + + p = (part *) malloc(sizeof(part) * np); + + for (i = 0; i < np; i++) + setnewpart(&p[i]); + + inittree(); + + return (0); +} + + + + + + +static void +DrawCube(void) +{ + static const GLfloat texcoords[4][2] = { + { 0, 0 }, { 1, 0 }, { 1, 1 }, { 0, 1 } + }; + static const GLfloat vertices[4][2] = { + { -1, -1 }, { 1, -1 }, { 1, 1 }, { -1, 1 } + }; + static const GLfloat xforms[6][4] = { + { 0, 0, 1, 0 }, + { 90, 0, 1, 0 }, + { 180, 0, 1, 0 }, + { 270, 0, 1, 0 }, + { 90, 1, 0, 0 }, + { -90, 1, 0, 0 } + }; + static const GLfloat mat[4] = { 1.0, 1.0, 0.5, 1.0 }; + GLint i, j; + + glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, mat); + glEnable(GL_TEXTURE_2D); + + glPushMatrix(); + glRotatef(ViewRotX, 1.0, 0.0, 0.0); + glRotatef(15, 1, 0, 0); + glRotatef(CubeRot, 0, 1, 0); + glScalef(4, 4, 4); + + for (i = 0; i < 6; i++) { + glPushMatrix(); + glRotatef(xforms[i][0], xforms[i][1], xforms[i][2], xforms[i][3]); + glTranslatef(0, 0, 1.1); + glBegin(GL_POLYGON); + glNormal3f(0, 0, 1); + for (j = 0; j < 4; j++) { + glTexCoord2fv(texcoords[j]); + glVertex2fv(vertices[j]); + } + glEnd(); + glPopMatrix(); + } + glPopMatrix(); + + glDisable(GL_TEXTURE_2D); +} + + +static void +draw(void) +{ + float ar; + static GLfloat pos[4] = {5.0, 5.0, 10.0, 0.0}; + + drawfire(); + + glLightfv(GL_LIGHT0, GL_POSITION, pos); + glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL, + GL_SEPARATE_SPECULAR_COLOR); + + glEnable(GL_LIGHTING); + glEnable(GL_LIGHT0); + glEnable(GL_DEPTH_TEST); + glEnable(GL_NORMALIZE); + glDisable(GL_BLEND); + glDisable(GL_FOG); + + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + glTranslatef(0.0, 0.0, -40.0); + + glClear(GL_DEPTH_BUFFER_BIT); + + /* draw textured cube */ + + glViewport(0, 0, WinWidth, WinHeight); + glClearColor(0.5, 0.5, 0.8, 0.0); + glClear(GL_COLOR_BUFFER_BIT); + + ar = (float) (WinWidth) / WinHeight; + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + glFrustum(-ar, ar, -1.0, 1.0, 5.0, 60.0); + glMatrixMode(GL_MODELVIEW); + glBindTexture(GL_TEXTURE_2D, TexObj); + + DrawCube(); + + /* finish up */ + 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; + + CubeRot = fmod(CubeRot + 15.0 * dt, 360.0); /* 15 deg/sec */ + + glutPostRedisplay(); +} + + +/* change view angle */ +static void +special(int k, int x, int y) +{ + (void) x; + (void) y; + switch (k) { + case GLUT_KEY_UP: + ViewRotX += 5.0; + break; + case GLUT_KEY_DOWN: + ViewRotX -= 5.0; + break; + case GLUT_KEY_LEFT: + ViewRotY += 5.0; + break; + case GLUT_KEY_RIGHT: + ViewRotY -= 5.0; + break; + default: + return; + } + glutPostRedisplay(); +} + + +/* new window size or exposure */ +static void +reshape(int width, int height) +{ + WinWidth = width; + WinHeight = height; +} + + +static void +init_fbotexture() +{ + GLint i; + + /* gen framebuffer id, delete it, do some assertions, just for testing */ + glGenFramebuffersEXT(1, &MyFB); + glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, MyFB); + glGetIntegerv(GL_FRAMEBUFFER_BINDING_EXT, &i); + + /* Make texture object/image */ + glGenTextures(1, &TexObj); + glBindTexture(GL_TEXTURE_2D, TexObj); + /* make one image level. */ + glTexImage2D(GL_TEXTURE_2D, 0, TEXINTFORMAT, TexWidth, TexHeight, 0, + texFormats[texType], texTypes[texType], NULL); + + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0); + + CheckError(__LINE__); + + /* Render color to texture */ + glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, + GL_TEXTURE_2D, TexObj, 0); + CheckError(__LINE__); + + + /* make depth renderbuffer */ + glGenRenderbuffersEXT(1, &DepthRB); + glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, DepthRB); + glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT16, + TexWidth, TexHeight); + CheckError(__LINE__); + glGetRenderbufferParameterivEXT(GL_RENDERBUFFER_EXT, + GL_RENDERBUFFER_DEPTH_SIZE_EXT, &i); + CheckError(__LINE__); + printf("Depth renderbuffer size = %d bits\n", i); + + /* attach DepthRB to MyFB */ + glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, + GL_RENDERBUFFER_EXT, DepthRB); + CheckError(__LINE__); + glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); + + /* + * Check for completeness. + */ + +} + + +static void +init(int argc, char *argv[]) +{ + GLint i; + + if (!glutExtensionSupported("GL_EXT_framebuffer_object")) { + fprintf(stderr, "Sorry, GL_EXT_framebuffer_object is required!\n"); + exit(1); + } + + TexWidth = 512; + TexHeight = 512; + + init_fbotexture(); + init_fire(argc, argv); + + + for ( i=1; i<argc; i++ ) { + if (strcmp(argv[i], "-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)); + } + } +} + + +static void +visible(int vis) +{ + if (vis == GLUT_VISIBLE) + glutIdleFunc(idle); + else + glutIdleFunc(NULL); +} + + +int +main(int argc, char *argv[]) +{ + glutInit(&argc, argv); + + glutInitDisplayMode(GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE); + + glutInitWindowSize(WinWidth, WinHeight); + Win = glutCreateWindow("fbo_firecube"); + init(argc, argv); + + glutDisplayFunc(draw); + glutReshapeFunc(reshape); + glutKeyboardFunc(key); + glutSpecialFunc(special); + glutVisibilityFunc(visible); + + glutMainLoop(); + return 0; /* ANSI C requires main to return int. */ +} diff --git a/progs/demos/gearbox.c b/progs/demos/gearbox.c index 3a1662cd62..35bde04417 100644 --- a/progs/demos/gearbox.c +++ b/progs/demos/gearbox.c @@ -264,38 +264,44 @@ draw(void) glLoadIdentity(); glTranslatef(0.0, 0.0, -40.0); + /* clear whole depth buffer */ glDisable(GL_SCISSOR_TEST); glClear(GL_DEPTH_BUFFER_BIT); glEnable(GL_SCISSOR_TEST); - /* draw gears */ + /* clear upper-left corner of color buffer (unused space) */ + glScissor(0, TexHeight, TexWidth, WinHeight - TexHeight); + glClearColor(0.0, 0.0, 0.0, 0.0); + glClear(GL_COLOR_BUFFER_BIT); + + /* clear lower-left corner of color buffer */ glViewport(0, 0, TexWidth, TexHeight); glScissor(0, 0, TexWidth, TexHeight); - glClearColor(0.5, 0.5, 0.8, 0.0); glClearColor(1, 1, 1, 0); glClear(GL_COLOR_BUFFER_BIT); + /* draw gears in lower-left corner */ glMatrixMode(GL_PROJECTION); glLoadIdentity(); glFrustum(-1.0, 1.0, -1.0, 1.0, 5.0, 60.0); glMatrixMode(GL_MODELVIEW); - DrawGears(); + /* copy color buffer to texture */ glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, TexWidth, TexHeight); - /* draw textured cube */ + /* clear right half of color buffer */ glViewport(TexWidth, 0, WinWidth - TexWidth, WinHeight); glScissor(TexWidth, 0, WinWidth - TexWidth, WinHeight); glClearColor(0.5, 0.5, 0.8, 0.0); glClear(GL_COLOR_BUFFER_BIT); + /* draw textured cube in right half of window */ ar = (float) (WinWidth - TexWidth) / WinHeight; glMatrixMode(GL_PROJECTION); glLoadIdentity(); glFrustum(-ar, ar, -1.0, 1.0, 5.0, 60.0); glMatrixMode(GL_MODELVIEW); - DrawCube(); /* finish up */ diff --git a/progs/demos/glslnoise.c b/progs/demos/glslnoise.c index 4ee1292816..4ee1292816 100755..100644 --- a/progs/demos/glslnoise.c +++ b/progs/demos/glslnoise.c diff --git a/progs/demos/multiarb.c b/progs/demos/multiarb.c index d963985c69..451fd11efe 100644 --- a/progs/demos/multiarb.c +++ b/progs/demos/multiarb.c @@ -1,4 +1,3 @@ - /* * GL_ARB_multitexture demo * @@ -32,7 +31,6 @@ static GLint NumUnits = 1; static GLboolean TexEnabled[8]; static GLfloat Drift = 0.0; -static GLfloat drift_increment = 0.005; static GLfloat Xrot = 20.0, Yrot = 30.0, Zrot = 0.0; @@ -41,9 +39,7 @@ static void Idle( void ) if (Animate) { GLint i; - Drift += drift_increment; - if (Drift >= 1.0) - Drift = 0.0; + Drift = glutGet(GLUT_ELAPSED_TIME) * 0.001; for (i = 0; i < NumUnits; i++) { glActiveTextureARB(GL_TEXTURE0_ARB + i); @@ -57,10 +53,11 @@ static void Idle( void ) glTranslatef(0.0, Drift, 0.0); } else { - glTranslatef(0.5, 0.5, 0.0); + float tx = 0.5, ty = 0.5; + glTranslatef(tx, ty, 0.0); glRotatef(180.0 * Drift, 0, 0, 1); glScalef(1.0/i, 1.0/i, 1.0/i); - glTranslatef(-0.5, -0.5, 0.0); + glTranslatef(-tx, -ty + i * 0.1, 0.0); } } glMatrixMode(GL_MODELVIEW); @@ -72,10 +69,9 @@ static void Idle( void ) static void DrawObject(void) { - GLint i; - GLint j; - static const GLfloat tex_coords[] = { 0.0, 0.0, 1.0, 1.0, 0.0 }; - static const GLfloat vtx_coords[] = { -1.0, -1.0, 1.0, 1.0, -1.0 }; + static const GLfloat tex_coords[] = { 0.0, 0.0, 1.0, 1.0, 0.0 }; + static const GLfloat vtx_coords[] = { -1.0, -1.0, 1.0, 1.0, -1.0 }; + GLint i, j; if (!TexEnabled[0] && !TexEnabled[1]) glColor3f(0.1, 0.1, 0.1); /* add onto this */ @@ -83,37 +79,20 @@ static void DrawObject(void) glColor3f(1, 1, 1); /* modulate this */ glBegin(GL_QUADS); - - /* Toggle between the vector and scalar entry points. This is done purely - * to hit multiple paths in the driver. - */ - if ( Drift > 0.49 ) { - for (j = 0; j < 4; j++ ) { - for (i = 0; i < NumUnits; i++) - glMultiTexCoord2fARB(GL_TEXTURE0_ARB + i, - tex_coords[j], tex_coords[j+1]); - glVertex2f( vtx_coords[j], vtx_coords[j+1] ); - } - } - else { - for (j = 0; j < 4; j++ ) { - for (i = 0; i < NumUnits; i++) - glMultiTexCoord2fvARB(GL_TEXTURE0_ARB + i, & tex_coords[j]); - glVertex2fv( & vtx_coords[j] ); + for (j = 0; j < 4; j++ ) { + for (i = 0; i < NumUnits; i++) { + if (TexEnabled[i]) + glMultiTexCoord2fARB(GL_TEXTURE0_ARB + i, + tex_coords[j], tex_coords[j+1]); } + glVertex2f( vtx_coords[j], vtx_coords[j+1] ); } - glEnd(); } - static void Display( void ) { - static GLint T0 = 0; - static GLint Frames = 0; - GLint t; - glClear( GL_COLOR_BUFFER_BIT ); glPushMatrix(); @@ -125,16 +104,6 @@ static void Display( void ) glPopMatrix(); glutSwapBuffers(); - - Frames++; - - t = glutGet(GLUT_ELAPSED_TIME); - if (t - T0 >= 250) { - GLfloat seconds = (t - T0) / 1000.0; - drift_increment = 2.2 * seconds / Frames; - T0 = t; - Frames = 0; - } } @@ -151,24 +120,34 @@ static void Reshape( int width, int height ) } +static void ToggleUnit(int unit) +{ + TexEnabled[unit] = !TexEnabled[unit]; + glActiveTextureARB(GL_TEXTURE0_ARB + unit); + if (TexEnabled[unit]) + glEnable(GL_TEXTURE_2D); + else + glDisable(GL_TEXTURE_2D); + printf("Enabled: "); + for (unit = 0; unit < NumUnits; unit++) + printf("%d ", (int) TexEnabled[unit]); + printf("\n"); +} + + static void ModeMenu(int entry) { if (entry >= TEX0 && entry <= TEX7) { /* toggle */ GLint i = entry - TEX0; - TexEnabled[i] = !TexEnabled[i]; - glActiveTextureARB(GL_TEXTURE0_ARB + i); - if (TexEnabled[i]) - glEnable(GL_TEXTURE_2D); - else - glDisable(GL_TEXTURE_2D); - printf("Enabled: "); - for (i = 0; i < NumUnits; i++) - printf("%d ", (int) TexEnabled[i]); - printf("\n"); + ToggleUnit(i); } else if (entry==ANIMATE) { Animate = !Animate; + if (Animate) + glutIdleFunc(Idle); + else + glutIdleFunc(NULL); } else if (entry==QUIT) { exit(0); @@ -183,9 +162,36 @@ static void Key( unsigned char key, int x, int y ) (void) x; (void) y; switch (key) { - case 27: - exit(0); - break; + case 'a': + Animate = !Animate; + break; + case '0': + ToggleUnit(0); + break; + case '1': + ToggleUnit(1); + break; + case '2': + ToggleUnit(2); + break; + case '3': + ToggleUnit(3); + break; + case '4': + ToggleUnit(4); + break; + case '5': + ToggleUnit(5); + break; + case '6': + ToggleUnit(6); + break; + case '7': + ToggleUnit(7); + break; + case 27: + exit(0); + break; } glutPostRedisplay(); } @@ -327,7 +333,8 @@ int main( int argc, char *argv[] ) glutKeyboardFunc( Key ); glutSpecialFunc( SpecialKey ); glutDisplayFunc( Display ); - glutIdleFunc( Idle ); + if (Animate) + glutIdleFunc(Idle); glutCreateMenu(ModeMenu); diff --git a/progs/demos/rain.cxx b/progs/demos/rain.cxx index d19f049c5f..59b6471ef8 100644 --- a/progs/demos/rain.cxx +++ b/progs/demos/rain.cxx @@ -8,6 +8,7 @@ #include <stdio.h> #include <stdlib.h> +#include <string.h> #include <math.h> #include <time.h> #include <GL/glut.h> @@ -113,7 +114,7 @@ static void calcposobs(void) rainParticle::setRainingArea(obs[0]-7.0f,-0.2f,obs[2]-7.0f,obs[0]+7.0f,8.0f,obs[2]+7.0f); } -static void printstring(void *font, char *string) +static void printstring(void *font, const char *string) { int len,i; diff --git a/progs/demos/shadowtex.c b/progs/demos/shadowtex.c index 0574175935..4787f0f29d 100644 --- a/progs/demos/shadowtex.c +++ b/progs/demos/shadowtex.c @@ -84,6 +84,7 @@ static const char *FragProgNames[] = { "program with \"OPTION ARB_fragment_program_shadow\"", }; +static GLboolean HaveShadow = GL_FALSE; static GLboolean HaveFBO = GL_FALSE; static GLboolean UseFBO = GL_FALSE; static GLboolean HaveVP = GL_FALSE; @@ -529,7 +530,10 @@ ShowShadowMap(void) DisableTexgen(); /* interpret texture's depth values as luminance values */ - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE_ARB, GL_NONE); + if (HaveShadow) { + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE_ARB, GL_NONE); + } + glTexParameteri(GL_TEXTURE_2D, GL_DEPTH_TEXTURE_MODE_ARB, GL_LUMINANCE); glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); @@ -596,7 +600,9 @@ Display(void) } if (DisplayMode == SHOW_DEPTH_MAPPING) { - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE_ARB, GL_NONE); + if (HaveShadow) { + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE_ARB, GL_NONE); + } glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); glEnable(GL_TEXTURE_2D); @@ -614,8 +620,10 @@ Display(void) } else { assert(DisplayMode == SHOW_SHADOWS); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE_ARB, - GL_COMPARE_R_TO_TEXTURE_ARB); + if (HaveShadow) { + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE_ARB, + GL_COMPARE_R_TO_TEXTURE_ARB); + } if (curr_frag > 0) { glEnable(GL_FRAGMENT_PROGRAM_ARB); @@ -724,6 +732,10 @@ Key(unsigned char key, int x, int y) break; case 'M': curr_frag = (1 + curr_frag) % max_frag; + if (!HaveShadow && (curr_frag == 0)) { + curr_frag = 1; + } + printf("Using fragment %s\n", FragProgNames[curr_frag]); if (HaveFP) { @@ -741,8 +753,10 @@ Key(unsigned char key, int x, int y) if (Operator >= 8) Operator = 0; printf("Operator: %s\n", OperatorName[Operator]); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC_ARB, - OperatorFunc[Operator]); + if (HaveShadow) { + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC_ARB, + OperatorFunc[Operator]); + } } break; case 'p': @@ -859,17 +873,31 @@ Init(void) { static const GLfloat borderColor[4] = {1.0, 0.0, 0.0, 0.0}; - if (!glutExtensionSupported("GL_ARB_depth_texture") || - !glutExtensionSupported("GL_ARB_shadow")) { - printf("Sorry, this demo requires the GL_ARB_depth_texture and GL_ARB_shadow extensions\n"); + if (!glutExtensionSupported("GL_ARB_depth_texture")) { + printf("Sorry, this demo requires the GL_ARB_depth_texture extension\n"); exit(1); } - printf("Using GL_ARB_depth_texture and GL_ARB_shadow\n"); + HaveShadow = glutExtensionSupported("GL_ARB_shadow"); HaveVP = glutExtensionSupported("GL_ARB_vertex_program"); HaveFP = glutExtensionSupported("GL_ARB_fragment_program"); HaveFP_Shadow = glutExtensionSupported("GL_ARB_fragment_program_shadow"); + if (!HaveShadow && !HaveFP) { + printf("Sorry, this demo requires either the GL_ARB_shadow extension " + "or the GL_ARB_fragment_program extension\n"); + exit(1); + } + + printf("Using GL_ARB_depth_texture\n"); + if (HaveShadow) { + printf("and GL_ARB_shadow\n"); + } + + if (HaveFP) { + printf("and GL_ARB_fragment_program\n"); + } + HaveShadowAmbient = glutExtensionSupported("GL_ARB_shadow_ambient"); if (HaveShadowAmbient) { printf("and GL_ARB_shadow_ambient\n"); @@ -896,9 +924,12 @@ Init(void) glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, borderColor); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE_ARB, - GL_COMPARE_R_TO_TEXTURE_ARB); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC_ARB, GL_LEQUAL); + + if (HaveShadow) { + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE_ARB, + GL_COMPARE_R_TO_TEXTURE_ARB); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC_ARB, GL_LEQUAL); + } if (HaveShadowAmbient) { glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FAIL_VALUE_ARB, 0.3); @@ -924,7 +955,6 @@ Init(void) glGenTextures(1, &GrayTexture); glBindTexture(GL_TEXTURE_1D, GrayTexture); glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_WRAP_S, GL_CLAMP); - glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_WRAP_T, GL_CLAMP); glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); { @@ -955,6 +985,11 @@ Init(void) max_frag = 3; } + if (!HaveShadow) { + curr_frag = 1; + glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, frag_progs[curr_frag]); + } + glEnable(GL_DEPTH_TEST); glEnable(GL_LIGHTING); glEnable(GL_LIGHT0); diff --git a/progs/demos/textures.c b/progs/demos/textures.c new file mode 100644 index 0000000000..b7bf135d21 --- /dev/null +++ b/progs/demos/textures.c @@ -0,0 +1,374 @@ +/* + * Simple test of multiple textures + */ + + +#include <stdio.h> +#include <stdlib.h> +#include <math.h> +#include <GL/glut.h> +#include "readtex.h" + +#define TEST_CLAMP 0 +#define TEST_MIPMAPS 0 + +#define MAX_TEXTURES 8 + + +static int Win; +static GLfloat Xrot = 0, Yrot = 0, Zrot = 0; +static GLboolean Anim = GL_TRUE; +static GLboolean Blend = GL_FALSE; +static GLuint Filter = 0; +static GLboolean Clamp = GL_FALSE; + +static GLuint NumTextures; +static GLuint Textures[MAX_TEXTURES]; +static float TexRot[MAX_TEXTURES][3]; +static float TexPos[MAX_TEXTURES][3]; +static float TexAspect[MAX_TEXTURES]; + +static const char *DefaultFiles[] = { + "../images/arch.rgb", + "../images/reflect.rgb", + "../images/tree2.rgba", + "../images/tile.rgb" +}; + + +#define NUM_FILTERS 5 +static +struct filter { + GLenum min, mag; + const char *name; +} FilterModes[NUM_FILTERS] = { + { GL_NEAREST, GL_NEAREST, "Nearest,Nearest" }, + { GL_LINEAR, GL_LINEAR, "Linear,Linear" }, + { GL_NEAREST_MIPMAP_NEAREST, GL_NEAREST, "NearestMipmapNearest,Nearest" }, + { GL_LINEAR_MIPMAP_NEAREST, GL_LINEAR, "LinearMipmapNearest,Linear" }, + { GL_LINEAR_MIPMAP_LINEAR, GL_LINEAR, "LinearMipmapLinear,Linear" } +}; + + + + +static void +Idle(void) +{ + Xrot = glutGet(GLUT_ELAPSED_TIME) * 0.02; + Yrot = glutGet(GLUT_ELAPSED_TIME) * 0.04; + //Zrot += 2.0; + glutPostRedisplay(); +} + + +static void +DrawTextures(void) +{ + GLuint i; + + for (i = 0; i < NumTextures; i++) { + GLfloat ar = TexAspect[i]; + + glPushMatrix(); + glTranslatef(TexPos[i][0], TexPos[i][1], TexPos[i][2]); + glRotatef(TexRot[i][0], 1, 0, 0); + glRotatef(TexRot[i][1], 0, 1, 0); + glRotatef(TexRot[i][2], 0, 0, 1); + + glBindTexture(GL_TEXTURE_2D, Textures[i]); + glBegin(GL_POLYGON); +#if TEST_CLAMP + glTexCoord2f( -0.5, -0.5 ); glVertex2f( -ar, -1.0 ); + glTexCoord2f( 1.5, -0.5 ); glVertex2f( ar, -1.0 ); + glTexCoord2f( 1.5, 1.5 ); glVertex2f( ar, 1.0 ); + glTexCoord2f( -0.5, 1.5 ); glVertex2f( -ar, 1.0 ); +#else + glTexCoord2f( 0.0, 0.0 ); glVertex2f( -ar, -1.0 ); + glTexCoord2f( 1.0, 0.0 ); glVertex2f( ar, -1.0 ); + glTexCoord2f( 1.0, 1.0 ); glVertex2f( ar, 1.0 ); + glTexCoord2f( 0.0, 1.0 ); glVertex2f( -ar, 1.0 ); +#endif + glEnd(); + + glPopMatrix(); + } +} + +static void +Draw(void) +{ + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + if (Blend) { + glEnable(GL_BLEND); + glDisable(GL_DEPTH_TEST); + } + else { + glDisable(GL_BLEND); + glEnable(GL_DEPTH_TEST); + } + + glPushMatrix(); + glRotatef(Xrot, 1, 0, 0); + glRotatef(Yrot, 0, 1, 0); + glRotatef(Zrot, 0, 0, 1); + + DrawTextures(); + + glPopMatrix(); + + glutSwapBuffers(); +} + + +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, 5.0, 50.0); + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + glTranslatef(0.0, 0.0, -10.0); +} + + +static GLfloat +RandFloat(float min, float max) +{ + float x = (float) (rand() % 1000) * 0.001; + x = x * (max - min) + min; + return x; +} + + +static void +Randomize(void) +{ + GLfloat k = 1.0; + GLuint i; + + srand(glutGet(GLUT_ELAPSED_TIME)); + + for (i = 0; i < NumTextures; i++) { + TexRot[i][0] = RandFloat(0.0, 360); + TexRot[i][1] = RandFloat(0.0, 360); + TexRot[i][2] = RandFloat(0.0, 360); + TexPos[i][0] = RandFloat(-k, k); + TexPos[i][1] = RandFloat(-k, k); + TexPos[i][2] = RandFloat(-k, k); + } +} + + +static void +SetTexParams(void) +{ + GLuint i; + for (i = 0; i < NumTextures; i++) { + glBindTexture(GL_TEXTURE_2D, Textures[i]); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, + FilterModes[Filter].min); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, + FilterModes[Filter].mag); + + if (Clamp) { + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + } + else { + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); + } + } +} + + +static void +Key(unsigned char key, int x, int y) +{ + const GLfloat step = 3.0; + (void) x; + (void) y; + switch (key) { + case 'a': + case ' ': + Anim = !Anim; + if (Anim) + glutIdleFunc(Idle); + else + glutIdleFunc(NULL); + break; + case 'b': + Blend = !Blend; + break; + case 'f': + Filter = (Filter + 1) % NUM_FILTERS; + SetTexParams(); + break; + case 'r': + Randomize(); + break; +#if TEST_CLAMP + case 'c': + Clamp = !Clamp; + SetTexParams(); + break; +#endif + case 'z': + Zrot -= step; + break; + case 'Z': + Zrot += step; + break; + case 27: + glutDestroyWindow(Win); + exit(0); + break; + } + + printf("Blend=%s Filter=%s\n", + Blend ? "Y" : "n", + FilterModes[Filter].name); + + glutPostRedisplay(); +} + + +static void +SpecialKey(int key, int x, int y) +{ + const GLfloat step = 3.0; + (void) x; + (void) y; + switch (key) { + case GLUT_KEY_UP: + Xrot -= step; + break; + case GLUT_KEY_DOWN: + Xrot += step; + break; + case GLUT_KEY_LEFT: + Yrot -= step; + break; + case GLUT_KEY_RIGHT: + Yrot += step; + break; + } + glutPostRedisplay(); +} + + +static void +LoadTextures(GLuint n, const char *files[]) +{ + GLuint i; + + NumTextures = n < MAX_TEXTURES ? n : MAX_TEXTURES; + + glGenTextures(n, Textures); + + SetTexParams(); + + for (i = 0; i < n; i++) { + GLint w, h; + glBindTexture(GL_TEXTURE_2D, Textures[i]); +#if TEST_MIPMAPS + { + static const GLubyte color[9][4] = { + {255, 0, 0}, + {0, 255, 0}, + {0, 0, 255}, + {0, 255, 255}, + {255, 0, 255}, + {255, 255, 0}, + {255, 128, 255}, + {128, 128, 128}, + {64, 64, 64} + }; + + GLubyte image[256*256*4]; + int i, level; + w = h = 256; + for (level = 0; level <= 8; level++) { + for (i = 0; i < w * h; i++) { + image[i*4+0] = color[level][0]; + image[i*4+1] = color[level][1]; + image[i*4+2] = color[level][2]; + image[i*4+3] = color[level][3]; + } + printf("Load level %d: %d x %d\n", level, w>>level, h>>level); + glTexImage2D(GL_TEXTURE_2D, level, GL_RGBA, w>>level, h>>level, 0, + GL_RGBA, GL_UNSIGNED_BYTE, image); + } + } +#else + if (!LoadRGBMipmaps2(files[i], GL_TEXTURE_2D, GL_RGB, &w, &h)) { + printf("Error: couldn't load %s\n", files[i]); + exit(1); + } +#endif + TexAspect[i] = (float) w / (float) h; + printf("Loaded %s\n", files[i]); + } +} + + +static void +Init(int argc, const char *argv[]) +{ + if (argc == 1) + LoadTextures(4, DefaultFiles); + else + LoadTextures(argc - 1, argv + 1); + + Randomize(); + + glEnable(GL_TEXTURE_2D); + + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glColor4f(1, 1, 1, 0.5); + +#if 0 + /* setup lighting, etc */ + glEnable(GL_LIGHTING); + glEnable(GL_LIGHT0); +#endif +} + + +static void +Usage(void) +{ + printf("Usage:\n"); + printf(" textures [file.rgb] ...\n"); + printf("Keys:\n"); + printf(" a - toggle animation\n"); + printf(" b - toggle blending\n"); + printf(" f - change texture filter mode\n"); + printf(" r - randomize\n"); + printf(" ESC - exit\n"); +} + + +int +main(int argc, char *argv[]) +{ + glutInit(&argc, argv); + glutInitWindowPosition(0, 0); + glutInitWindowSize(700, 700); + glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH); + Win = glutCreateWindow(argv[0]); + glutReshapeFunc(Reshape); + glutKeyboardFunc(Key); + glutSpecialFunc(SpecialKey); + glutDisplayFunc(Draw); + if (Anim) + glutIdleFunc(Idle); + Init(argc, (const char **) argv); + Usage(); + glutMainLoop(); + return 0; +} |