summaryrefslogtreecommitdiff
path: root/progs/demos
diff options
context:
space:
mode:
Diffstat (limited to 'progs/demos')
-rw-r--r--progs/demos/.gitignore3
-rw-r--r--progs/demos/Makefile36
-rw-r--r--progs/demos/copypix.c248
-rw-r--r--progs/demos/cubemap.c51
-rw-r--r--progs/demos/descrip.mms90
-rw-r--r--progs/demos/engine.c23
-rw-r--r--progs/demos/fbo_firecube.c1041
-rw-r--r--progs/demos/gearbox.c16
-rw-r--r--[-rwxr-xr-x]progs/demos/glslnoise.c0
-rw-r--r--progs/demos/multiarb.c123
-rw-r--r--progs/demos/rain.cxx3
-rw-r--r--progs/demos/shadowtex.c63
-rw-r--r--progs/demos/textures.c374
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;
+}