summaryrefslogtreecommitdiffstats
path: root/progs
diff options
context:
space:
mode:
Diffstat (limited to 'progs')
-rw-r--r--progs/Makefile2
-rw-r--r--progs/beos/Makefile14
-rw-r--r--progs/demos/.gitignore2
-rw-r--r--progs/demos/Makefile35
-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.cxx1
-rw-r--r--progs/demos/shadowtex.c63
-rw-r--r--progs/directfb/Makefile4
-rw-r--r--progs/egl/Makefile23
-rw-r--r--progs/fbdev/Makefile7
-rw-r--r--progs/fp/Makefile14
-rw-r--r--progs/glsl/.gitignore7
-rw-r--r--progs/glsl/CH06-brick.frag (renamed from progs/glsl/CH06-brick.frag.txt)0
-rw-r--r--progs/glsl/CH06-brick.vert (renamed from progs/glsl/CH06-brick.vert.txt)0
-rw-r--r--progs/glsl/CH11-bumpmap.frag (renamed from progs/glsl/CH11-bumpmap.frag.txt)0
-rw-r--r--progs/glsl/CH11-bumpmap.vert (renamed from progs/glsl/CH11-bumpmap.vert.txt)0
-rw-r--r--progs/glsl/CH11-toyball.frag (renamed from progs/glsl/CH11-toyball.frag.txt)0
-rw-r--r--progs/glsl/CH11-toyball.vert (renamed from progs/glsl/CH11-toyball.vert.txt)0
-rw-r--r--progs/glsl/CH18-mandel.frag (renamed from progs/glsl/CH18-mandel.frag.txt)0
-rw-r--r--progs/glsl/CH18-mandel.vert (renamed from progs/glsl/CH18-mandel.vert.txt)0
-rw-r--r--progs/glsl/Makefile124
-rw-r--r--progs/glsl/bitmap.c323
-rw-r--r--progs/glsl/brick.c138
-rw-r--r--progs/glsl/bump.c139
-rw-r--r--progs/glsl/convolutions.c16
-rw-r--r--progs/glsl/cubemap.frag (renamed from progs/glsl/cubemap.frag.txt)0
-rw-r--r--progs/glsl/deriv.c90
-rw-r--r--progs/glsl/mandelbrot.c150
-rw-r--r--progs/glsl/multitex.c285
-rw-r--r--progs/glsl/multitex.frag15
-rw-r--r--progs/glsl/multitex.vert10
-rw-r--r--progs/glsl/noise.c102
-rw-r--r--progs/glsl/pointcoord.c205
-rw-r--r--progs/glsl/points.c260
-rw-r--r--progs/glsl/reflect.vert (renamed from progs/glsl/reflect.vert.txt)0
-rw-r--r--progs/glsl/shadowtex.frag (renamed from progs/glsl/shadowtex.frag.txt)0
-rw-r--r--progs/glsl/simple.vert (renamed from progs/glsl/simple.vert.txt)0
-rw-r--r--progs/glsl/texdemo1.c163
-rw-r--r--progs/glsl/toyball.c163
-rw-r--r--progs/glsl/trirast.c259
-rw-r--r--progs/glsl/twoside.c294
-rw-r--r--progs/miniglx/Makefile8
-rw-r--r--progs/osdemos/Makefile24
-rw-r--r--progs/osdemos/ostest1.c7
-rw-r--r--progs/redbook/Makefile4
-rw-r--r--progs/samples/Makefile6
-rw-r--r--progs/samples/Makefile.mgw78
-rw-r--r--progs/samples/blendeq.c97
-rw-r--r--progs/slang/Makefile18
-rw-r--r--progs/tests/.gitignore6
-rw-r--r--progs/tests/Makefile53
-rw-r--r--progs/tests/antialias.c12
-rw-r--r--progs/tests/cva.c8
-rw-r--r--progs/tests/dinoshade.c6
-rw-r--r--progs/tests/exactrast.c200
-rw-r--r--progs/tests/fbotexture.c70
-rw-r--r--progs/tests/lineclip.c175
-rw-r--r--progs/tests/multipal.c6
-rw-r--r--progs/tests/shader_api.c337
-rw-r--r--progs/tests/stencil_twoside.c299
-rw-r--r--progs/tests/texline.c12
-rw-r--r--progs/tests/unfilledclip.c205
-rw-r--r--progs/tools/trace/Makefile4
-rw-r--r--progs/tools/trace/gltrace_support.cc4
-rw-r--r--progs/trivial/Makefile14
-rw-r--r--progs/trivial/point-param.c57
-rw-r--r--progs/trivial/quad-clip-nearplane.c43
-rw-r--r--progs/trivial/tri.c8
-rw-r--r--progs/util/shaderutil.c162
-rw-r--r--progs/util/shaderutil.h34
-rw-r--r--progs/vp/Makefile10
-rw-r--r--progs/xdemos/.gitignore3
-rw-r--r--progs/xdemos/Makefile59
-rw-r--r--progs/xdemos/corender.c400
-rw-r--r--progs/xdemos/glxgears_pixmap.c547
-rw-r--r--progs/xdemos/glxinfo.c294
-rw-r--r--progs/xdemos/glxsnoop.c377
-rw-r--r--progs/xdemos/glxswapcontrol.c5
-rw-r--r--progs/xdemos/ipc.c264
-rw-r--r--progs/xdemos/ipc.h16
-rw-r--r--progs/xdemos/offset.c3
-rw-r--r--progs/xdemos/pbutil.c72
-rw-r--r--progs/xdemos/pbutil.h3
-rw-r--r--progs/xdemos/shape.c1
91 files changed, 7260 insertions, 1251 deletions
diff --git a/progs/Makefile b/progs/Makefile
index 5e705ef..c99f4ee 100644
--- a/progs/Makefile
+++ b/progs/Makefile
@@ -25,7 +25,7 @@ subdirs:
install:
clean:
- @for dir in $(SUBDIRS) tests ; do \
+ -@for dir in $(SUBDIRS) tests ; do \
if [ -d $$dir ] ; then \
(cd $$dir && $(MAKE) clean) ; \
fi \
diff --git a/progs/beos/Makefile b/progs/beos/Makefile
index 45782fb..0dc4cdc 100644
--- a/progs/beos/Makefile
+++ b/progs/beos/Makefile
@@ -10,24 +10,26 @@ include $(TOP)/configs/current
#
# Modified by Philippe Houdoin
-LDFLAGS += -soname=_APP_ $(APP_LIB_DEPS)
+LDFLAGS += -soname=_APP_
+
+LIBS = -L$(TOP)/$(LIB_DIR) -l$(GLUT_LIB) -l$(GLU_LIB) -l$(GL_LIB) $(APP_LIB_DEPS)
INCLUDES = -I. -I- -I../../include
default: demo sample GLInfo
clean:
- rm -f demo sample GLInfo
- rm -f *.o
+ -rm -f demo sample GLInfo
+ -rm -f *.o
demo: demo.o
- $(LD) demo.o $(LDFLAGS) -o $@
+ $(LD) demo.o $(LDFLAGS) $(LIBS) -o $@
sample: sample.o
- $(LD) sample.o $(LDFLAGS) -o $@
+ $(LD) sample.o $(LDFLAGS) $(LIBS) -o $@
GTLInfo: GLInfo.o
- $(LD) GLInfo.o $(INCLUDES) $(LDFLAGS) -o $@
+ $(LD) GLInfo.o $(INCLUDES) $(LDFLAGS) $(LIBS) -o $@
.cpp.o:
$(CC) -c $< $(INCLUDES) $(CFLAGS) -o $@
diff --git a/progs/demos/.gitignore b/progs/demos/.gitignore
index d9e4881..3693faf 100644
--- a/progs/demos/.gitignore
+++ b/progs/demos/.gitignore
@@ -3,6 +3,7 @@ arbfslight
arbocclude
bounce
clearspd
+copypix
cubemap
drawpix
engine
@@ -30,6 +31,7 @@ osdemo
paltex
pixeltex
pointblast
+rain
ray
readpix
readtex.c
diff --git a/progs/demos/Makefile b/progs/demos/Makefile
index 43874ec..81d9ebe 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 \
@@ -70,11 +77,11 @@ PROGS = \
.SUFFIXES:
.SUFFIXES: .c
-
+.SUFFIXES: .cxx
# make executable from .c file:
.c: $(LIB_DEP) readtex.o
- $(CC) -I$(INCDIR) $(CFLAGS) $< readtex.o $(APP_LIB_DEPS) -o $@
+ $(CC) -I$(INCDIR) $(CFLAGS) $(LDFLAGS) $< readtex.o $(LIBS) -o $@
##### TARGETS #####
@@ -118,39 +125,51 @@ extfuncs.h: $(TOP)/progs/util/extfuncs.h
reflect: reflect.o showbuffer.o readtex.o
- $(CC) reflect.o showbuffer.o readtex.o $(APP_LIB_DEPS) $(ARCH_FLAGS) -o $@
+ $(CC) $(CFLAGS) $(LDFLAGS) reflect.o showbuffer.o readtex.o $(LIBS) -o $@
reflect.o: reflect.c showbuffer.h
$(CC) -c -I$(INCDIR) $(CFLAGS) reflect.c
shadowtex: shadowtex.o showbuffer.o
- $(CC) shadowtex.o showbuffer.o $(APP_LIB_DEPS) $(ARCH_FLAGS) -o $@
+ $(CC) $(CFLAGS) $(LDFLAGS) shadowtex.o showbuffer.o $(LIBS) -o $@
shadowtex.o: shadowtex.c showbuffer.h
$(CC) -c -I$(INCDIR) $(CFLAGS) shadowtex.c
gloss: gloss.o trackball.o readtex.o
- $(CC) gloss.o trackball.o readtex.o $(APP_LIB_DEPS) $(ARCH_FLAGS) -o $@
+ $(CC) $(CFLAGS) $(LDFLAGS) gloss.o trackball.o readtex.o $(LIBS) -o $@
gloss.o: gloss.c trackball.h
$(CC) -c -I$(INCDIR) $(CFLAGS) gloss.c
engine: engine.o trackball.o readtex.o
- $(CC) engine.o trackball.o readtex.o $(APP_LIB_DEPS) $(ARCH_FLAGS) -o $@
+ $(CC) $(CFLAGS) $(LDFLAGS) engine.o trackball.o readtex.o $(LIBS) -o $@
engine.o: engine.c trackball.h
$(CC) -c -I$(INCDIR) $(CFLAGS) engine.c
fslight: fslight.o
- $(CC) fslight.o $(APP_LIB_DEPS) $(ARCH_FLAGS) -o $@
+ $(CC) $(CFLAGS) $(LDFLAGS) fslight.o $(LIBS) -o $@
fslight.o: fslight.c extfuncs.h
$(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 0000000..15001e8
--- /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 ef5d235..b3bdd64 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 0000000..d7a9121
--- /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 143b02a..6040a2f 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 0000000..ed87dd1
--- /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 3a1662c..35bde04 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 4ee1292..4ee1292 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 d963985..451fd11 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 d19f049..5c53d42 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>
diff --git a/progs/demos/shadowtex.c b/progs/demos/shadowtex.c
index 0574175..4787f0f 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/directfb/Makefile b/progs/directfb/Makefile
index 53b100a..93c2a7d 100644
--- a/progs/directfb/Makefile
+++ b/progs/directfb/Makefile
@@ -11,6 +11,8 @@ LIB_DEP = $(TOP)/$(LIB_DIR)/$(GL_LIB_NAME) $(TOP)/$(LIB_DIR)/$(GLU_LIB_NAME)
CFLAGS += $(shell pkg-config --cflags directfb)
APP_LIB_DEPS += $(shell pkg-config --libs directfb)
+LIBS = -L$(TOP)/$(LIB_DIR) -l$(GLU_LIB) -l$(GL_LIB) $(APP_LIB_DEPS)
+
PROGS = df_gears \
df_reflect \
df_morph3d \
@@ -22,7 +24,7 @@ PROGS = df_gears \
.SUFFIXES: .c
.c: $(LIB_DEP)
- $(CC) -I$(INCDIR) $(CFLAGS) $< $(APP_LIB_DEPS) -o $@
+ $(CC) -I$(INCDIR) $(CFLAGS) $(LDFLAGS) $< $(LIBS) -o $@
##### TARGETS #####
diff --git a/progs/egl/Makefile b/progs/egl/Makefile
index 948d735..75cd411 100644
--- a/progs/egl/Makefile
+++ b/progs/egl/Makefile
@@ -29,42 +29,42 @@ default: $(PROGRAMS)
demo1: demo1.o $(TOP)/$(LIB_DIR)/libEGL.so
- $(CC) $(CFLAGS) demo1.o -L$(TOP)/$(LIB_DIR) -lEGL $(LIBDRM_LIB) -o $@
+ $(CC) $(CFLAGS) $(LDFLAGS) demo1.o -L$(TOP)/$(LIB_DIR) -lEGL $(LIBDRM_LIB) -o $@
demo1.o: demo1.c $(HEADERS)
$(CC) -c $(CFLAGS) -I$(TOP)/include demo1.c
demo2: demo2.o $(TOP)/$(LIB_DIR)/libEGL.so
- $(CC) $(CFLAGS) demo2.o -L$(TOP)/$(LIB_DIR) -lEGL $(LIBDRM_LIB) $(APP_LIB_DEPS) -o $@
+ $(CC) $(CFLAGS) $(LDFLAGS) demo2.o -L$(TOP)/$(LIB_DIR) -lEGL $(LIBDRM_LIB) $(APP_LIB_DEPS) -o $@
demo2.o: demo2.c $(HEADERS)
$(CC) -c $(CFLAGS) -I$(TOP)/include demo2.c
demo3: demo3.o $(TOP)/$(LIB_DIR)/libEGL.so
- $(CC) $(CFLAGS) demo3.o -L$(TOP)/$(LIB_DIR) -lEGL $(LIBDRM_LIB) $(APP_LIB_DEPS) -o $@
+ $(CC) $(CFLAGS) $(LDFLAGS) demo3.o -L$(TOP)/$(LIB_DIR) -lEGL $(LIBDRM_LIB) $(APP_LIB_DEPS) -o $@
demo3.o: demo3.c $(HEADERS)
$(CC) -c $(CFLAGS) -I$(TOP)/include demo3.c
egltri: egltri.o $(TOP)/$(LIB_DIR)/libEGL.so
- $(CC) $(CFLAGS) egltri.o -L$(TOP)/$(LIB_DIR) -lGL -lEGL $(LIBDRM_LIB) -o $@
+ $(CC) $(CFLAGS) egltri.o -L$(TOP)/$(LIB_DIR) -lEGL $(LIBDRM_LIB) -o $@
egltri.o: egltri.c $(HEADERS)
$(CC) -c $(CFLAGS) -I$(TOP)/include egltri.c
eglinfo: eglinfo.o $(TOP)/$(LIB_DIR)/libEGL.so
- $(CC) $(CFLAGS) eglinfo.o -L$(TOP)/$(LIB_DIR) -lGL -lEGL $(LIBDRM_LIB) -o $@
+ $(CC) $(CFLAGS) $(LDFLAGS) eglinfo.o -L$(TOP)/$(LIB_DIR) -lEGL $(LIBDRM_LIB) -o $@
eglinfo.o: eglinfo.c $(HEADERS)
$(CC) -c $(CFLAGS) -I$(TOP)/include eglinfo.c
eglgears: eglgears.o $(TOP)/$(LIB_DIR)/libEGL.so
- $(CC) $(CFLAGS) eglgears.o -L$(TOP)/$(LIB_DIR) -lEGL $(LIBDRM_LIB) $(APP_LIB_DEPS) -o $@
+ $(CC) $(CFLAGS) $(LDFLAGS) eglgears.o -L$(TOP)/$(LIB_DIR) -lEGL $(LIBDRM_LIB) $(APP_LIB_DEPS) -o $@
eglgears.o: eglgears.c $(HEADERS)
$(CC) -c $(CFLAGS) -I$(TOP)/include eglgears.c
@@ -92,12 +92,7 @@ xegl_tri.o: xegl_tri.c $(HEADERS)
clean:
- rm -f *.o *~
- rm -f *.so
- rm -f $(PROGRAMS)
+ -rm -f *.o *~
+ -rm -f *.so
+ -rm -f $(PROGRAMS)
-run:
- LD_LIBRARY_PATH=$(TOP)/lib ./egltri
-
-debug:
- LD_LIBRARY_PATH=$(TOP)/lib gdb ./eglgears
diff --git a/progs/fbdev/Makefile b/progs/fbdev/Makefile
index 178020e..e935a51 100644
--- a/progs/fbdev/Makefile
+++ b/progs/fbdev/Makefile
@@ -15,6 +15,7 @@ INCLUDES = \
-I. \
-I$(TOP)/include
+LIBS = -L$(TOP)/$(LIB_DIR) -l$(GLU_LIB) -l$(GL_LIB) $(APP_LIB_DEPS)
##### RULES #####
@@ -22,7 +23,7 @@ INCLUDES = \
.SUFFIXES: .c
.c:
- $(CC) $(INCLUDES) $(CFLAGS) $< $(APP_LIB_DEPS) -o $@
+ $(CC) $(INCLUDES) $(CFLAGS) $(LDFLAGS) $< $(LIBS) -o $@
.c.o:
$(CC) -c $(INCLUDES) $(CFLAGS) $< -o $@
@@ -36,8 +37,8 @@ INCLUDES = \
default: depend $(PROGS)
clean:
- rm -f $(PROGS)
- rm -f *.o
+ -rm -f $(PROGS)
+ -rm -f *.o
depend: $(SOURCES)
diff --git a/progs/fp/Makefile b/progs/fp/Makefile
index bcff699..2089fc5 100644
--- a/progs/fp/Makefile
+++ b/progs/fp/Makefile
@@ -8,7 +8,7 @@ TOP = ../..
include $(TOP)/configs/current
-LIBS = $(APP_LIB_DEPS)
+LIBS = -L$(TOP)/$(LIB_DIR) -l$(GLUT_LIB) -l$(GLU_LIB) -l$(GL_LIB) $(APP_LIB_DEPS)
SOURCES = \
tri-tex.c \
@@ -40,7 +40,7 @@ UTIL_FILES = readtex.h readtex.c
.SUFFIXES: .c
.c:
- $(CC) $(INCLUDES) $(CFLAGS) $< $(LIBS) -o $@
+ $(CC) $(INCLUDES) $(CFLAGS) $(LDFLAGS) $< $(LIBS) -o $@
.c.o:
$(CC) -c $(INCLUDES) $(CFLAGS) $(DEFINES) $< -o $@
@@ -54,9 +54,9 @@ UTIL_FILES = readtex.h readtex.c
default: $(UTIL_FILES) $(PROGS)
clean:
- rm -f $(PROGS)
- rm -f *.o
- rm -f getproclist.h
+ -rm -f $(PROGS)
+ -rm -f *.o
+ -rm -f getproclist.h
# auto code generation
@@ -67,13 +67,13 @@ getproclist.h: $(TOP)/src/mesa/glapi/gl_API.xml getprocaddress.c getprocaddress.
texrect: texrect.o readtex.o
- $(CC) texrect.o readtex.o $(LIBS) -o $@
+ $(CC) $(CFLAGS) $(LDFLAGS) texrect.o readtex.o $(LIBS) -o $@
texrect.o: texrect.c readtex.h
$(CC) -c $(INCLUDES) $(CFLAGS) $(DEFINES) $< -o $@
invert: invert.o readtex.o
- $(CC) invert.o readtex.o $(LIBS) -o $@
+ $(CC) $(CFLAGS) $(LDFLAGS) invert.o readtex.o $(LIBS) -o $@
invert.o: invert.c readtex.h
$(CC) -c $(INCLUDES) $(CFLAGS) $(DEFINES) $< -o $@
diff --git a/progs/glsl/.gitignore b/progs/glsl/.gitignore
index 81ecf5b..09340ff 100644
--- a/progs/glsl/.gitignore
+++ b/progs/glsl/.gitignore
@@ -1,11 +1,18 @@
+bitmap
brick
bump
convolutions
deriv
extfuncs.h
mandelbrot
+multitex
noise
+points
readtex.c
readtex.h
+shaderutil.c
+shaderutil.h
texdemo1
toyball
+trirast
+twoside
diff --git a/progs/glsl/CH06-brick.frag.txt b/progs/glsl/CH06-brick.frag
index 06ef04e..06ef04e 100644
--- a/progs/glsl/CH06-brick.frag.txt
+++ b/progs/glsl/CH06-brick.frag
diff --git a/progs/glsl/CH06-brick.vert.txt b/progs/glsl/CH06-brick.vert
index e95e6f4..e95e6f4 100644
--- a/progs/glsl/CH06-brick.vert.txt
+++ b/progs/glsl/CH06-brick.vert
diff --git a/progs/glsl/CH11-bumpmap.frag.txt b/progs/glsl/CH11-bumpmap.frag
index 063576f..063576f 100644
--- a/progs/glsl/CH11-bumpmap.frag.txt
+++ b/progs/glsl/CH11-bumpmap.frag
diff --git a/progs/glsl/CH11-bumpmap.vert.txt b/progs/glsl/CH11-bumpmap.vert
index d3d19f6..d3d19f6 100644
--- a/progs/glsl/CH11-bumpmap.vert.txt
+++ b/progs/glsl/CH11-bumpmap.vert
diff --git a/progs/glsl/CH11-toyball.frag.txt b/progs/glsl/CH11-toyball.frag
index 90ec1c2..90ec1c2 100644
--- a/progs/glsl/CH11-toyball.frag.txt
+++ b/progs/glsl/CH11-toyball.frag
diff --git a/progs/glsl/CH11-toyball.vert.txt b/progs/glsl/CH11-toyball.vert
index b7da3ac..b7da3ac 100644
--- a/progs/glsl/CH11-toyball.vert.txt
+++ b/progs/glsl/CH11-toyball.vert
diff --git a/progs/glsl/CH18-mandel.frag.txt b/progs/glsl/CH18-mandel.frag
index a472d81..a472d81 100644
--- a/progs/glsl/CH18-mandel.frag.txt
+++ b/progs/glsl/CH18-mandel.frag
diff --git a/progs/glsl/CH18-mandel.vert.txt b/progs/glsl/CH18-mandel.vert
index c4ca664..c4ca664 100644
--- a/progs/glsl/CH18-mandel.vert.txt
+++ b/progs/glsl/CH18-mandel.vert
diff --git a/progs/glsl/Makefile b/progs/glsl/Makefile
index b9cae66..ba7a4c6 100644
--- a/progs/glsl/Makefile
+++ b/progs/glsl/Makefile
@@ -7,13 +7,23 @@ INCDIR = $(TOP)/include
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 = \
+ bitmap \
brick \
bump \
+ convolutions \
deriv \
mandelbrot \
+ multitex \
noise \
+ points \
+ pointcoord \
+ texdemo1 \
toyball \
+ twoside \
+ trirast \
texdemo1 \
convolutions
@@ -26,7 +36,7 @@ PROGS = \
# make executable from .c file:
.c: $(LIB_DEP)
- $(CC) -I$(INCDIR) $(CFLAGS) $< $(APP_LIB_DEPS) -o $@
+ $(CC) -I$(INCDIR) $(CFLAGS) $(LDFLAGS) $< $(LIBS) -o $@
##### TARGETS #####
@@ -40,6 +50,7 @@ default: $(PROGS)
extfuncs.h: $(TOP)/progs/util/extfuncs.h
cp $< .
+
readtex.c: $(TOP)/progs/util/readtex.c
cp $< .
@@ -49,20 +60,116 @@ readtex.h: $(TOP)/progs/util/readtex.h
readtex.o: readtex.c readtex.h
$(CC) -c -I$(INCDIR) $(CFLAGS) readtex.c
-brick.c: extfuncs.h
-bump.c: extfuncs.h
+shaderutil.c: $(TOP)/progs/util/shaderutil.c
+ cp $< .
+
+shaderutil.h: $(TOP)/progs/util/shaderutil.h
+ cp $< .
+
+shaderutil.o: shaderutil.c shaderutil.h
+ $(CC) -c -I$(INCDIR) $(CFLAGS) shaderutil.c
+
+
+
+bitmap.o: bitmap.c extfuncs.h shaderutil.h
+ $(CC) -c -I$(INCDIR) $(CFLAGS) bitmap.c
+
+bitmap: bitmap.o shaderutil.o
+ $(CC) -I$(INCDIR) $(CFLAGS) $(LDFLAGS) bitmap.o shaderutil.o $(LIBS) -o $@
+
+
+brick.o: brick.c extfuncs.h shaderutil.h
+ $(CC) -c -I$(INCDIR) $(CFLAGS) brick.c
+
+brick: brick.o shaderutil.o
+ $(CC) -I$(INCDIR) $(CFLAGS) $(LDFLAGS) brick.o shaderutil.o $(LIBS) -o $@
+
+
+bump.o: bump.c extfuncs.h shaderutil.h
+ $(CC) -c -I$(INCDIR) $(CFLAGS) bump.c
+
+bump: bump.o shaderutil.o
+ $(CC) -I$(INCDIR) $(CFLAGS) $(LDFLAGS) bump.o shaderutil.o $(LIBS) -o $@
+
+
+convolutions.o: convolutions.c readtex.h
+ $(CC) -c -I$(INCDIR) $(CFLAGS) convolutions.c
+
+convolutions: convolutions.o readtex.o
+ $(CC) -I$(INCDIR) $(CFLAGS) $(LDFLAGS) convolutions.o readtex.o $(LIBS) -o $@
+
+
+deriv.o: deriv.c extfuncs.h shaderutil.h
+ $(CC) -c -I$(INCDIR) $(CFLAGS) deriv.c
-mandelbrot.c: extfuncs.h
+deriv: deriv.o shaderutil.o
+ $(CC) -I$(INCDIR) $(CFLAGS) $(LDFLAGS) deriv.o shaderutil.o $(LIBS) -o $@
-toyball.c: extfuncs.h
-texdemo1: texdemo1.o readtex.o
- $(CC) -I$(INCDIR) $(CFLAGS) texdemo1.o readtex.o $(APP_LIB_DEPS) -o $@
+mandelbrot.o: mandelbrot.c extfuncs.h shaderutil.h
+ $(CC) -c -I$(INCDIR) $(CFLAGS) mandelbrot.c
-texdemo1.o: texdemo1.c readtex.h extfuncs.h
+mandelbrot: mandelbrot.o shaderutil.o
+ $(CC) -I$(INCDIR) $(CFLAGS) $(LDFLAGS) mandelbrot.o shaderutil.o $(LIBS) -o $@
+
+
+multitex.o: multitex.c extfuncs.h readtex.h shaderutil.h
+ $(CC) -c -I$(INCDIR) $(CFLAGS) multitex.c
+
+multitex: multitex.o readtex.o shaderutil.o
+ $(CC) -I$(INCDIR) $(CFLAGS) $(LDFLAGS) multitex.o readtex.o shaderutil.o $(LIBS) -o $@
+
+
+noise.o: noise.c extfuncs.h shaderutil.h
+ $(CC) -c -I$(INCDIR) $(CFLAGS) noise.c
+
+noise: noise.o shaderutil.o
+ $(CC) -I$(INCDIR) $(CFLAGS) $(LDFLAGS) noise.o shaderutil.o $(LIBS) -o $@
+
+
+points.o: points.c extfuncs.h shaderutil.h
+ $(CC) -c -I$(INCDIR) $(CFLAGS) points.c
+
+points: points.o shaderutil.o
+ $(CC) -I$(INCDIR) $(CFLAGS) $(LDFLAGS) points.o shaderutil.o $(LIBS) -o $@
+
+
+pointcoord.o: pointcoord.c readtex.h extfuncs.h shaderutil.h
+ $(CC) -c -I$(INCDIR) $(CFLAGS) pointcoord.c
+
+pointcoord: pointcoord.o readtex.o shaderutil.o
+ $(CC) -I$(INCDIR) $(CFLAGS) $(LDFLAGS) pointcoord.o readtex.o shaderutil.o $(LIBS) -o $@
+
+
+texdemo1.o: texdemo1.c readtex.h extfuncs.h shaderutil.h
$(CC) -c -I$(INCDIR) $(CFLAGS) texdemo1.c
+texdemo1: texdemo1.o readtex.o shaderutil.o
+ $(CC) -I$(INCDIR) $(CFLAGS) $(LDFLAGS) texdemo1.o readtex.o shaderutil.o $(LIBS) -o $@
+
+
+toyball.o: toyball.c extfuncs.h shaderutil.h
+ $(CC) -c -I$(INCDIR) $(CFLAGS) toyball.c
+
+toyball: toyball.o shaderutil.o
+ $(CC) -I$(INCDIR) $(CFLAGS) $(LDFLAGS) toyball.o shaderutil.o $(LIBS) -o $@
+
+
+twoside.o: twoside.c extfuncs.h shaderutil.h
+ $(CC) -c -I$(INCDIR) $(CFLAGS) twoside.c
+
+twoside: twoside.o shaderutil.o
+ $(CC) -I$(INCDIR) $(CFLAGS) $(LDFLAGS) twoside.o shaderutil.o $(LIBS) -o $@
+
+
+trirast.o: trirast.c extfuncs.h shaderutil.h
+ $(CC) -c -I$(INCDIR) $(CFLAGS) trirast.c
+
+trirast: trirast.o shaderutil.o
+ $(CC) -I$(INCDIR) $(CFLAGS) $(LDFLAGS) trirast.o shaderutil.o $(LIBS) -o $@
+
+
convolutions: convolutions.o readtex.o
$(CC) -I$(INCDIR) $(CFLAGS) convolutions.o readtex.o $(APP_LIB_DEPS) -o $@
@@ -74,3 +181,4 @@ clean:
-rm -f $(PROGS)
-rm -f *.o *~
-rm -f extfuncs.h
+ -rm -f shaderutil.*
diff --git a/progs/glsl/bitmap.c b/progs/glsl/bitmap.c
new file mode 100644
index 0000000..d488ec6
--- /dev/null
+++ b/progs/glsl/bitmap.c
@@ -0,0 +1,323 @@
+/**
+ * Implement glRasterPos + glBitmap with textures + shaders.
+ * Brian Paul
+ * 14 May 2007
+ */
+
+#include <assert.h>
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+#include <GL/gl.h>
+#include <GL/glut.h>
+#include <GL/glext.h>
+#include "extfuncs.h"
+#include "shaderutil.h"
+
+
+static GLuint FragShader;
+static GLuint VertShader;
+static GLuint Program;
+
+static GLint Win = 0;
+static GLint WinWidth = 500, WinHeight = 500;
+static GLboolean Anim = GL_TRUE;
+static GLboolean Bitmap = GL_FALSE;
+static GLfloat Xrot = 20.0f, Yrot = 70.0f;
+static GLint uTex, uScale;
+static GLuint Textures[2];
+
+#define TEX_WIDTH 16
+#define TEX_HEIGHT 8
+
+
+static void
+BitmapText(const char *s)
+{
+ while (*s) {
+ glutBitmapCharacter(GLUT_BITMAP_8_BY_13, (int) *s);
+ s++;
+ }
+}
+
+
+static void
+Redisplay(void)
+{
+ static const GLfloat px[3] = { 1.2, 0, 0};
+ static const GLfloat nx[3] = {-1.2, 0, 0};
+
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+
+ glPushMatrix();
+ glRotatef(Xrot, 1.0f, 0.0f, 0.0f);
+ glRotatef(Yrot, 0.0f, 1.0f, 0.0f);
+
+ glEnable(GL_LIGHTING);
+
+ glPushMatrix();
+ glScalef(0.5, 0.5, 0.5);
+ glutSolidDodecahedron();
+ glPopMatrix();
+
+ glDisable(GL_LIGHTING);
+
+ glColor3f(0, 1, 0);
+ glBegin(GL_LINES);
+ glVertex3f(-1, 0, 0);
+ glVertex3f( 1, 0, 0);
+ glEnd();
+
+ glColor3f(1, 1, 0);
+
+ if (Bitmap) {
+ glRasterPos3fv(px);
+ BitmapText("+X");
+ glRasterPos3fv(nx);
+ BitmapText("-X");
+ }
+ else {
+ glUseProgram_func(Program);
+
+ /* vertex positions (deltas) depend on texture size and window size */
+ if (uScale != -1) {
+ glUniform2f_func(uScale,
+ 2.0 * TEX_WIDTH / WinWidth,
+ 2.0 * TEX_HEIGHT / WinHeight);
+ }
+
+ /* draw +X */
+ glBindTexture(GL_TEXTURE_2D, Textures[0]);
+ glBegin(GL_QUADS);
+ glTexCoord2f(0, 0); glVertex3fv(px);
+ glTexCoord2f(1, 0); glVertex3fv(px);
+ glTexCoord2f(1, 1); glVertex3fv(px);
+ glTexCoord2f(0, 1); glVertex3fv(px);
+ glEnd();
+
+ /* draw -X */
+ glBindTexture(GL_TEXTURE_2D, Textures[1]);
+ glBegin(GL_QUADS);
+ glTexCoord2f(0, 0); glVertex3fv(nx);
+ glTexCoord2f(1, 0); glVertex3fv(nx);
+ glTexCoord2f(1, 1); glVertex3fv(nx);
+ glTexCoord2f(0, 1); glVertex3fv(nx);
+ glEnd();
+
+ glUseProgram_func(0);
+ }
+
+ glPopMatrix();
+
+ glutSwapBuffers();
+}
+
+
+static void
+Idle(void)
+{
+ Yrot = glutGet(GLUT_ELAPSED_TIME) * 0.01;
+ glutPostRedisplay();
+}
+
+
+static void
+Reshape(int width, int height)
+{
+ WinWidth = width;
+ WinHeight = height;
+ glViewport(0, 0, width, height);
+ glMatrixMode(GL_PROJECTION);
+ glLoadIdentity();
+ glFrustum(-1.0, 1.0, -1.0, 1.0, 5.0, 25.0);
+ glMatrixMode(GL_MODELVIEW);
+ glLoadIdentity();
+ glTranslatef(0.0f, 0.0f, -10.0f);
+}
+
+
+static void
+Key(unsigned char key, int x, int y)
+{
+ (void) x;
+ (void) y;
+
+ switch(key) {
+ case ' ':
+ case 'a':
+ Anim = !Anim;
+ if (Anim)
+ glutIdleFunc(Idle);
+ else
+ glutIdleFunc(NULL);
+ break;
+ case 'b':
+ Bitmap = !Bitmap;
+ if (Bitmap)
+ printf("Using glBitmap\n");
+ else
+ printf("Using billboard texture\n");
+ break;
+ case 27:
+ glDeleteShader_func(FragShader);
+ glDeleteShader_func(VertShader);
+ glDeleteProgram_func(Program);
+ glutDestroyWindow(Win);
+ exit(0);
+ }
+ glutPostRedisplay();
+}
+
+
+static void
+SpecialKey(int key, int x, int y)
+{
+ const GLfloat step = 0.125f;
+ 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;
+ }
+ /*printf("Xrot: %f Yrot: %f\n", Xrot, Yrot);*/
+ glutPostRedisplay();
+}
+
+
+static void
+MakeTexImage(const char *p, GLuint texobj)
+{
+ GLubyte image[TEX_HEIGHT][TEX_WIDTH];
+ GLuint i, j, k;
+
+ for (i = 0; i < TEX_HEIGHT; i++) {
+ for (j = 0; j < TEX_WIDTH; j++) {
+ k = i * TEX_WIDTH + j;
+ if (p[k] == ' ') {
+ image[i][j] = 0;
+ }
+ else {
+ image[i][j] = 255;
+ }
+ }
+ }
+
+ glBindTexture(GL_TEXTURE_2D, texobj);
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_INTENSITY, TEX_WIDTH, TEX_HEIGHT, 0,
+ GL_RED, GL_UNSIGNED_BYTE, image);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 1);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+}
+
+
+static void
+MakeBitmapTextures(void)
+{
+ const char *px =
+ " X X "
+ " X X X "
+ " X X X "
+ " XXXXX X "
+ " X X X "
+ " X X X "
+ " X X "
+ " X X ";
+ const char *nx =
+ " X X "
+ " X X "
+ " X X "
+ " XXXXX X "
+ " X X "
+ " X X "
+ " X X "
+ " X X ";
+ glGenTextures(2, Textures);
+ MakeTexImage(px, Textures[0]);
+ MakeTexImage(nx, Textures[1]);
+}
+
+
+static void
+Init(void)
+{
+ /* Fragment shader: modulate raster color by texture, discard fragments
+ * with alpha < 1.0
+ */
+ static const char *fragShaderText =
+ "uniform sampler2D tex2d; \n"
+ "void main() {\n"
+ " vec4 c = texture2D(tex2d, gl_TexCoord[0].xy); \n"
+ " if (c.w < 1.0) \n"
+ " discard; \n"
+ " gl_FragColor = c * gl_Color; \n"
+ "}\n";
+ /* Vertex shader: compute new vertex position based on incoming vertex pos,
+ * texcoords and special scale factor.
+ */
+ static const char *vertShaderText =
+ "uniform vec2 scale; \n"
+ "void main() {\n"
+ " vec4 p = gl_ModelViewProjectionMatrix * gl_Vertex;\n"
+ " gl_Position.xy = p.xy + gl_MultiTexCoord0.xy * scale * p.w; \n"
+ " gl_Position.zw = p.zw; \n"
+ " gl_TexCoord[0] = gl_MultiTexCoord0; \n"
+ " gl_FrontColor = gl_Color; \n"
+ "}\n";
+
+ if (!ShadersSupported())
+ exit(1);
+
+ GetExtensionFuncs();
+
+ VertShader = CompileShaderText(GL_VERTEX_SHADER, vertShaderText);
+ FragShader = CompileShaderText(GL_FRAGMENT_SHADER, fragShaderText);
+ Program = LinkShaders(VertShader, FragShader);
+
+ glUseProgram_func(Program);
+
+ uScale = glGetUniformLocation_func(Program, "scale");
+ uTex = glGetUniformLocation_func(Program, "tex2d");
+ if (uTex != -1) {
+ glUniform1i_func(uTex, 0); /* tex unit 0 */
+ }
+
+ glUseProgram_func(0);
+
+ glClearColor(0.3f, 0.3f, 0.3f, 0.0f);
+ glEnable(GL_DEPTH_TEST);
+ glEnable(GL_NORMALIZE);
+ glEnable(GL_LIGHT0);
+
+ MakeBitmapTextures();
+}
+
+
+int
+main(int argc, char *argv[])
+{
+ glutInit(&argc, argv);
+ glutInitWindowSize(WinWidth, WinHeight);
+ glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
+ Win = glutCreateWindow(argv[0]);
+ glutReshapeFunc(Reshape);
+ glutKeyboardFunc(Key);
+ glutSpecialFunc(SpecialKey);
+ glutDisplayFunc(Redisplay);
+ if (Anim)
+ glutIdleFunc(Idle);
+ Init();
+ glutMainLoop();
+ return 0;
+}
+
+
diff --git a/progs/glsl/brick.c b/progs/glsl/brick.c
index 522698b..526ef0e 100644
--- a/progs/glsl/brick.c
+++ b/progs/glsl/brick.c
@@ -13,33 +13,26 @@
#include <GL/glut.h>
#include <GL/glext.h>
#include "extfuncs.h"
+#include "shaderutil.h"
-static char *FragProgFile = "CH06-brick.frag.txt";
-static char *VertProgFile = "CH06-brick.vert.txt";
+static char *FragProgFile = "CH06-brick.frag";
+static char *VertProgFile = "CH06-brick.vert";
/* program/shader objects */
static GLuint fragShader;
static GLuint vertShader;
static GLuint program;
-
-struct uniform_info {
- const char *name;
- GLuint size;
- GLint location;
- GLfloat value[4];
-};
-
static struct uniform_info Uniforms[] = {
/* vert */
- { "LightPosition", 3, -1, { 0.1, 0.1, 9.0, 0} },
+ { "LightPosition", 3, GL_FLOAT, { 0.1, 0.1, 9.0, 0}, -1 },
/* frag */
- { "BrickColor", 3, -1, { 0.8, 0.2, 0.2, 0 } },
- { "MortarColor", 3, -1, { 0.6, 0.6, 0.6, 0 } },
- { "BrickSize", 2, -1, { 1.0, 0.3, 0, 0 } },
- { "BrickPct", 2, -1, { 0.9, 0.8, 0, 0 } },
- { NULL, 0, 0, { 0, 0, 0, 0 } }
+ { "BrickColor", 3, GL_FLOAT, { 0.8, 0.2, 0.2, 0 }, -1 },
+ { "MortarColor", 3, GL_FLOAT, { 0.6, 0.6, 0.6, 0 }, -1 },
+ { "BrickSize", 2, GL_FLOAT, { 1.0, 0.3, 0, 0 }, -1 },
+ { "BrickPct", 2, GL_FLOAT, { 0.9, 0.8, 0, 0 }, -1 },
+ END_OF_UNIFORMS
};
static GLint win = 0;
@@ -146,121 +139,20 @@ SpecialKey(int key, int x, int y)
static void
-LoadAndCompileShader(GLuint shader, const char *text)
-{
- GLint stat;
-
- glShaderSource_func(shader, 1, (const GLchar **) &text, NULL);
-
- glCompileShader_func(shader);
-
- glGetShaderiv_func(shader, GL_COMPILE_STATUS, &stat);
- if (!stat) {
- GLchar log[1000];
- GLsizei len;
- glGetShaderInfoLog_func(shader, 1000, &len, log);
- fprintf(stderr, "brick: problem compiling shader: %s\n", log);
- exit(1);
- }
- else {
- printf("Shader compiled OK\n");
- }
-}
-
-
-/**
- * Read a shader from a file.
- */
-static void
-ReadShader(GLuint shader, const char *filename)
-{
- const int max = 100*1000;
- int n;
- char *buffer = (char*) malloc(max);
- FILE *f = fopen(filename, "r");
- if (!f) {
- fprintf(stderr, "brick: Unable to open shader file %s\n", filename);
- exit(1);
- }
-
- n = fread(buffer, 1, max, f);
- printf("brick: read %d bytes from shader file %s\n", n, filename);
- if (n > 0) {
- buffer[n] = 0;
- LoadAndCompileShader(shader, buffer);
- }
-
- fclose(f);
- free(buffer);
-}
-
-
-static void
-CheckLink(GLuint prog)
-{
- GLint stat;
- glGetProgramiv_func(prog, GL_LINK_STATUS, &stat);
- if (!stat) {
- GLchar log[1000];
- GLsizei len;
- glGetProgramInfoLog_func(prog, 1000, &len, log);
- fprintf(stderr, "Linker error:\n%s\n", log);
- }
- else {
- fprintf(stderr, "Link success!\n");
- }
-}
-
-
-static void
Init(void)
{
- const char *version;
- GLint i;
-
- version = (const char *) glGetString(GL_VERSION);
- if (version[0] != '2' || version[1] != '.') {
- printf("Warning: this program expects OpenGL 2.0\n");
- /*exit(1);*/
- }
+ if (!ShadersSupported())
+ exit(1);
GetExtensionFuncs();
- vertShader = glCreateShader_func(GL_VERTEX_SHADER);
- ReadShader(vertShader, VertProgFile);
-
- fragShader = glCreateShader_func(GL_FRAGMENT_SHADER);
- ReadShader(fragShader, FragProgFile);
+ vertShader = CompileShaderFile(GL_VERTEX_SHADER, VertProgFile);
+ fragShader = CompileShaderFile(GL_FRAGMENT_SHADER, FragProgFile);
+ program = LinkShaders(vertShader, fragShader);
- program = glCreateProgram_func();
- glAttachShader_func(program, fragShader);
- glAttachShader_func(program, vertShader);
- glLinkProgram_func(program);
- CheckLink(program);
glUseProgram_func(program);
- for (i = 0; Uniforms[i].name; i++) {
- Uniforms[i].location
- = glGetUniformLocation_func(program, Uniforms[i].name);
- printf("Uniform %s location: %d\n", Uniforms[i].name,
- Uniforms[i].location);
- switch (Uniforms[i].size) {
- case 1:
- glUniform1fv_func(Uniforms[i].location, 1, Uniforms[i].value);
- break;
- case 2:
- glUniform2fv_func(Uniforms[i].location, 1, Uniforms[i].value);
- break;
- case 3:
- glUniform3fv_func(Uniforms[i].location, 1, Uniforms[i].value);
- break;
- case 4:
- glUniform4fv_func(Uniforms[i].location, 1, Uniforms[i].value);
- break;
- default:
- abort();
- }
- }
+ InitUniforms(program, Uniforms);
assert(glGetError() == 0);
diff --git a/progs/glsl/bump.c b/progs/glsl/bump.c
index a6846ac..a2e0916 100644
--- a/progs/glsl/bump.c
+++ b/progs/glsl/bump.c
@@ -13,10 +13,11 @@
#include <GL/glu.h>
#include <GL/glext.h>
#include "extfuncs.h"
+#include "shaderutil.h"
-static char *FragProgFile = "CH11-bumpmap.frag.txt";
-static char *VertProgFile = "CH11-bumpmap.vert.txt";
+static char *FragProgFile = "CH11-bumpmap.frag";
+static char *VertProgFile = "CH11-bumpmap.vert";
/* program/shader objects */
static GLuint fragShader;
@@ -24,20 +25,13 @@ static GLuint vertShader;
static GLuint program;
-struct uniform_info {
- const char *name;
- GLuint size;
- GLint location;
- GLfloat value[4];
-};
-
static struct uniform_info Uniforms[] = {
- { "LightPosition", 3, -1, { 0.57737, 0.57735, 0.57735, 0.0 } },
- { "SurfaceColor", 3, -1, { 0.8, 0.8, 0.2, 0 } },
- { "BumpDensity", 1, -1, { 10.0, 0, 0, 0 } },
- { "BumpSize", 1, -1, { 0.125, 0, 0, 0 } },
- { "SpecularFactor", 1, -1, { 0.5, 0, 0, 0 } },
- { NULL, 0, 0, { 0, 0, 0, 0 } }
+ { "LightPosition", 3, GL_FLOAT, { 0.57737, 0.57735, 0.57735, 0.0 }, -1 },
+ { "SurfaceColor", 3, GL_FLOAT, { 0.8, 0.8, 0.2, 0 }, -1 },
+ { "BumpDensity", 1, GL_FLOAT, { 10.0, 0, 0, 0 }, -1 },
+ { "BumpSize", 1, GL_FLOAT, { 0.125, 0, 0, 0 }, -1 },
+ { "SpecularFactor", 1, GL_FLOAT, { 0.5, 0, 0, 0 }, -1 },
+ END_OF_UNIFORMS
};
static GLint win = 0;
@@ -232,100 +226,18 @@ SpecialKey(int key, int x, int y)
}
-
-static void
-LoadAndCompileShader(GLuint shader, const char *text)
-{
- GLint stat;
-
- glShaderSource_func(shader, 1, (const GLchar **) &text, NULL);
-
- glCompileShader_func(shader);
-
- glGetShaderiv_func(shader, GL_COMPILE_STATUS, &stat);
- if (!stat) {
- GLchar log[1000];
- GLsizei len;
- glGetShaderInfoLog_func(shader, 1000, &len, log);
- fprintf(stderr, "brick: problem compiling shader: %s\n", log);
- exit(1);
- }
- else {
- printf("Shader compiled OK\n");
- }
-}
-
-
-/**
- * Read a shader from a file.
- */
-static void
-ReadShader(GLuint shader, const char *filename)
-{
- const int max = 100*1000;
- int n;
- char *buffer = (char*) malloc(max);
- FILE *f = fopen(filename, "r");
- if (!f) {
- fprintf(stderr, "brick: Unable to open shader file %s\n", filename);
- exit(1);
- }
-
- n = fread(buffer, 1, max, f);
- printf("brick: read %d bytes from shader file %s\n", n, filename);
- if (n > 0) {
- buffer[n] = 0;
- LoadAndCompileShader(shader, buffer);
- }
-
- fclose(f);
- free(buffer);
-}
-
-
-static void
-CheckLink(GLuint prog)
-{
- GLint stat;
- glGetProgramiv_func(prog, GL_LINK_STATUS, &stat);
- if (!stat) {
- GLchar log[1000];
- GLsizei len;
- glGetProgramInfoLog_func(prog, 1000, &len, log);
- fprintf(stderr, "Linker error:\n%s\n", log);
- }
- else {
- fprintf(stderr, "Link success!\n");
- }
-}
-
-
static void
Init(void)
{
- const char *version;
- GLint i;
-
- version = (const char *) glGetString(GL_VERSION);
- if (version[0] != '2' || version[1] != '.') {
- printf("Warning: this program expects OpenGL 2.0\n");
- /*exit(1);*/
- }
- printf("GL_RENDERER = %s\n",(const char *) glGetString(GL_RENDERER));
+ if (!ShadersSupported())
+ exit(1);
GetExtensionFuncs();
- vertShader = glCreateShader_func(GL_VERTEX_SHADER);
- ReadShader(vertShader, VertProgFile);
-
- fragShader = glCreateShader_func(GL_FRAGMENT_SHADER);
- ReadShader(fragShader, FragProgFile);
+ vertShader = CompileShaderFile(GL_VERTEX_SHADER, VertProgFile);
+ fragShader = CompileShaderFile(GL_FRAGMENT_SHADER, FragProgFile);
+ program = LinkShaders(vertShader, fragShader);
- program = glCreateProgram_func();
- glAttachShader_func(program, fragShader);
- glAttachShader_func(program, vertShader);
- glLinkProgram_func(program);
- CheckLink(program);
glUseProgram_func(program);
assert(glIsProgram_func(program));
@@ -336,28 +248,7 @@ Init(void)
CheckError(__LINE__);
- for (i = 0; Uniforms[i].name; i++) {
- Uniforms[i].location
- = glGetUniformLocation_func(program, Uniforms[i].name);
- printf("Uniform %s location: %d\n", Uniforms[i].name,
- Uniforms[i].location);
- switch (Uniforms[i].size) {
- case 1:
- glUniform1fv_func(Uniforms[i].location, 1, Uniforms[i].value);
- break;
- case 2:
- glUniform2fv_func(Uniforms[i].location, 1, Uniforms[i].value);
- break;
- case 3:
- glUniform3fv_func(Uniforms[i].location, 1, Uniforms[i].value);
- break;
- case 4:
- glUniform4fv_func(Uniforms[i].location, 1, Uniforms[i].value);
- break;
- default:
- abort();
- }
- }
+ InitUniforms(program, Uniforms);
CheckError(__LINE__);
diff --git a/progs/glsl/convolutions.c b/progs/glsl/convolutions.c
index 9b9ee53..a25dad5 100644
--- a/progs/glsl/convolutions.c
+++ b/progs/glsl/convolutions.c
@@ -1,3 +1,10 @@
+/**
+ * Convolution with GLSL.
+ * Note: uses GL_ARB_shader_objects, GL_ARB_vertex_shader, GL_ARB_fragment_shader,
+ * not the OpenGL 2.0 shader API.
+ * Author: Zack Rusin
+ */
+
#define GL_GLEXT_PROTOTYPES
#include "readtex.h"
@@ -227,9 +234,11 @@ static void createProgram(const char *vertProgFile,
glUseProgram(program);
+ /*
assert(glIsProgram(program));
assert(glIsShader(fragShader));
assert(glIsShader(vertShader));
+ */
checkError(__LINE__);
{/*texture*/
@@ -316,6 +325,13 @@ static void menuInit()
static void init()
{
+ if (!glutExtensionSupported("GL_ARB_shader_objects") ||
+ !glutExtensionSupported("GL_ARB_vertex_shader") ||
+ !glutExtensionSupported("GL_ARB_fragment_shader")) {
+ fprintf(stderr, "Sorry, this program requires GL_ARB_shader_objects, GL_ARB_vertex_shader, and GL_ARB_fragment_shader\n");
+ exit(1);
+ }
+
fprintf(stderr, "GL_RENDERER = %s\n", (char *) glGetString(GL_RENDERER));
fprintf(stderr, "GL_VERSION = %s\n", (char *) glGetString(GL_VERSION));
fprintf(stderr, "GL_VENDOR = %s\n", (char *) glGetString(GL_VENDOR));
diff --git a/progs/glsl/cubemap.frag.txt b/progs/glsl/cubemap.frag
index 9c27648..9c27648 100644
--- a/progs/glsl/cubemap.frag.txt
+++ b/progs/glsl/cubemap.frag
diff --git a/progs/glsl/deriv.c b/progs/glsl/deriv.c
index 8b652bc..e69f0b8 100644
--- a/progs/glsl/deriv.c
+++ b/progs/glsl/deriv.c
@@ -17,6 +17,7 @@
#include <GL/glut.h>
#include <GL/glext.h>
#include "extfuncs.h"
+#include "shaderutil.h"
static char *FragProgFile = NULL;
@@ -159,68 +160,6 @@ MakeRect(void)
}
-
-static void
-LoadAndCompileShader(GLuint shader, const char *text)
-{
- GLint stat;
-
- glShaderSource_func(shader, 1, (const GLchar **) &text, NULL);
-
- glCompileShader_func(shader);
-
- glGetShaderiv_func(shader, GL_COMPILE_STATUS, &stat);
- if (!stat) {
- GLchar log[1000];
- GLsizei len;
- glGetShaderInfoLog_func(shader, 1000, &len, log);
- fprintf(stderr, "fslight: problem compiling shader:\n%s\n", log);
- exit(1);
- }
-}
-
-
-/**
- * Read a shader from a file.
- */
-static void
-ReadShader(GLuint shader, const char *filename)
-{
- const int max = 100*1000;
- int n;
- char *buffer = (char*) malloc(max);
- FILE *f = fopen(filename, "r");
- if (!f) {
- fprintf(stderr, "fslight: Unable to open shader file %s\n", filename);
- exit(1);
- }
-
- n = fread(buffer, 1, max, f);
- printf("fslight: read %d bytes from shader file %s\n", n, filename);
- if (n > 0) {
- buffer[n] = 0;
- LoadAndCompileShader(shader, buffer);
- }
-
- fclose(f);
- free(buffer);
-}
-
-
-static void
-CheckLink(GLuint prog)
-{
- GLint stat;
- glGetProgramiv_func(prog, GL_LINK_STATUS, &stat);
- if (!stat) {
- GLchar log[1000];
- GLsizei len;
- glGetProgramInfoLog_func(prog, 1000, &len, log);
- fprintf(stderr, "Linker error:\n%s\n", log);
- }
-}
-
-
static void
Init(void)
{
@@ -234,33 +173,16 @@ Init(void)
" gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;\n"
" gl_TexCoord[0] = gl_MultiTexCoord0;\n"
"}\n";
- const char *version;
- version = (const char *) glGetString(GL_VERSION);
- if (version[0] != '2' || version[1] != '.') {
- printf("This program requires OpenGL 2.x, found %s\n", version);
+ if (!ShadersSupported())
exit(1);
- }
GetExtensionFuncs();
- fragShader = glCreateShader_func(GL_FRAGMENT_SHADER);
- if (FragProgFile)
- ReadShader(fragShader, FragProgFile);
- else
- LoadAndCompileShader(fragShader, fragShaderText);
-
- vertShader = glCreateShader_func(GL_VERTEX_SHADER);
- if (VertProgFile)
- ReadShader(vertShader, VertProgFile);
- else
- LoadAndCompileShader(vertShader, vertShaderText);
-
- program = glCreateProgram_func();
- glAttachShader_func(program, fragShader);
- glAttachShader_func(program, vertShader);
- glLinkProgram_func(program);
- CheckLink(program);
+ vertShader = CompileShaderText(GL_VERTEX_SHADER, vertShaderText);
+ fragShader = CompileShaderText(GL_FRAGMENT_SHADER, fragShaderText);
+ program = LinkShaders(vertShader, fragShader);
+
glUseProgram_func(program);
/*assert(glGetError() == 0);*/
diff --git a/progs/glsl/mandelbrot.c b/progs/glsl/mandelbrot.c
index 7a2bad6..e6361b4 100644
--- a/progs/glsl/mandelbrot.c
+++ b/progs/glsl/mandelbrot.c
@@ -13,10 +13,11 @@
#include <GL/glut.h>
#include <GL/glext.h>
#include "extfuncs.h"
+#include "shaderutil.h"
-static char *FragProgFile = "CH18-mandel.frag.txt";
-static char *VertProgFile = "CH18-mandel.vert.txt";
+static char *FragProgFile = "CH18-mandel.frag";
+static char *VertProgFile = "CH18-mandel.vert";
/* program/shader objects */
static GLuint fragShader;
@@ -24,28 +25,21 @@ static GLuint vertShader;
static GLuint program;
-struct uniform_info {
- const char *name;
- GLuint size;
- GLint location;
- GLfloat value[4];
-};
-
static struct uniform_info Uniforms[] = {
/* vert */
- { "LightPosition", 3, -1, { 0.1, 0.1, 9.0, 0} },
- { "SpecularContribution", 1, -1, { 0.5, 0, 0, 0 } },
- { "DiffuseContribution", 1, -1, { 0.5, 0, 0, 0 } },
- { "Shininess", 1, -1, { 20.0, 0, 0, 0 } },
+ { "LightPosition", 3, GL_FLOAT, { 0.1, 0.1, 9.0, 0}, -1 },
+ { "SpecularContribution", 1, GL_FLOAT, { 0.5, 0, 0, 0 }, -1 },
+ { "DiffuseContribution", 1, GL_FLOAT, { 0.5, 0, 0, 0 }, -1 },
+ { "Shininess", 1, GL_FLOAT, { 20.0, 0, 0, 0 }, -1 },
/* frag */
- { "MaxIterations", 1, -1, { 12, 0, 0, 0 } },
- { "Zoom", 1, -1, { 0.125, 0, 0, 0 } },
- { "Xcenter", 1, -1, { -1.5, 0, 0, 0 } },
- { "Ycenter", 1, -1, { .005, 0, 0, 0 } },
- { "InnerColor", 3, -1, { 1, 0, 0, 0 } },
- { "OuterColor1", 3, -1, { 0, 1, 0, 0 } },
- { "OuterColor2", 3, -1, { 0, 0, 1, 0 } },
- { NULL, 0, 0, { 0, 0, 0, 0 } }
+ { "MaxIterations", 1, GL_FLOAT, { 12, 0, 0, 0 }, -1 },
+ { "Zoom", 1, GL_FLOAT, { 0.125, 0, 0, 0 }, -1 },
+ { "Xcenter", 1, GL_FLOAT, { -1.5, 0, 0, 0 }, -1 },
+ { "Ycenter", 1, GL_FLOAT, { .005, 0, 0, 0 }, -1 },
+ { "InnerColor", 3, GL_FLOAT, { 1, 0, 0, 0 }, -1 },
+ { "OuterColor1", 3, GL_FLOAT, { 0, 1, 0, 0 }, -1 },
+ { "OuterColor2", 3, GL_FLOAT, { 0, 0, 1, 0 }, -1 },
+ END_OF_UNIFORMS
};
static GLint win = 0;
@@ -157,123 +151,21 @@ SpecialKey(int key, int x, int y)
}
-
-static void
-LoadAndCompileShader(GLuint shader, const char *text)
-{
- GLint stat;
-
- glShaderSource_func(shader, 1, (const GLchar **) &text, NULL);
-
- glCompileShader_func(shader);
-
- glGetShaderiv_func(shader, GL_COMPILE_STATUS, &stat);
- if (!stat) {
- GLchar log[1000];
- GLsizei len;
- glGetShaderInfoLog_func(shader, 1000, &len, log);
- fprintf(stderr, "brick: problem compiling shader: %s\n", log);
- exit(1);
- }
- else {
- printf("Shader compiled OK\n");
- }
-}
-
-
-/**
- * Read a shader from a file.
- */
-static void
-ReadShader(GLuint shader, const char *filename)
-{
- const int max = 100*1000;
- int n;
- char *buffer = (char*) malloc(max);
- FILE *f = fopen(filename, "r");
- if (!f) {
- fprintf(stderr, "brick: Unable to open shader file %s\n", filename);
- exit(1);
- }
-
- n = fread(buffer, 1, max, f);
- printf("brick: read %d bytes from shader file %s\n", n, filename);
- if (n > 0) {
- buffer[n] = 0;
- LoadAndCompileShader(shader, buffer);
- }
-
- fclose(f);
- free(buffer);
-}
-
-
-static void
-CheckLink(GLuint prog)
-{
- GLint stat;
- glGetProgramiv_func(prog, GL_LINK_STATUS, &stat);
- if (!stat) {
- GLchar log[1000];
- GLsizei len;
- glGetProgramInfoLog_func(prog, 1000, &len, log);
- fprintf(stderr, "Linker error:\n%s\n", log);
- }
- else {
- fprintf(stderr, "Link success!\n");
- }
-}
-
-
static void
Init(void)
{
- const char *version;
- GLint i;
-
- version = (const char *) glGetString(GL_VERSION);
- if (version[0] != '2' || version[1] != '.') {
- printf("Warning: this program expects OpenGL 2.0\n");
- /*exit(1);*/
- }
+ if (!ShadersSupported())
+ exit(1);
GetExtensionFuncs();
- vertShader = glCreateShader_func(GL_VERTEX_SHADER);
- ReadShader(vertShader, VertProgFile);
-
- fragShader = glCreateShader_func(GL_FRAGMENT_SHADER);
- ReadShader(fragShader, FragProgFile);
+ vertShader = CompileShaderFile(GL_VERTEX_SHADER, VertProgFile);
+ fragShader = CompileShaderFile(GL_FRAGMENT_SHADER, FragProgFile);
+ program = LinkShaders(vertShader, fragShader);
- program = glCreateProgram_func();
- glAttachShader_func(program, fragShader);
- glAttachShader_func(program, vertShader);
- glLinkProgram_func(program);
- CheckLink(program);
glUseProgram_func(program);
- for (i = 0; Uniforms[i].name; i++) {
- Uniforms[i].location
- = glGetUniformLocation_func(program, Uniforms[i].name);
- printf("Uniform %s location: %d\n", Uniforms[i].name,
- Uniforms[i].location);
- switch (Uniforms[i].size) {
- case 1:
- glUniform1fv_func(Uniforms[i].location, 1, Uniforms[i].value);
- break;
- case 2:
- glUniform2fv_func(Uniforms[i].location, 1, Uniforms[i].value);
- break;
- case 3:
- glUniform3fv_func(Uniforms[i].location, 1, Uniforms[i].value);
- break;
- case 4:
- glUniform4fv_func(Uniforms[i].location, 1, Uniforms[i].value);
- break;
- default:
- abort();
- }
- }
+ InitUniforms(program, Uniforms);
uZoom = glGetUniformLocation_func(program, "Zoom");
uXcenter = glGetUniformLocation_func(program, "Xcenter");
diff --git a/progs/glsl/multitex.c b/progs/glsl/multitex.c
new file mode 100644
index 0000000..096d40f
--- /dev/null
+++ b/progs/glsl/multitex.c
@@ -0,0 +1,285 @@
+/**
+ * Test multi-texturing with GL shading language.
+ *
+ * Copyright (C) 2008 Brian Paul All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+
+#include <assert.h>
+#include <math.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "GL/glut.h"
+#include "readtex.h"
+#include "extfuncs.h"
+#include "shaderutil.h"
+
+static const char *Demo = "multitex";
+
+static const char *VertFile = "multitex.vert";
+static const char *FragFile = "multitex.frag";
+
+static const char *TexFiles[2] =
+ {
+ "../images/tile.rgb",
+ "../images/tree2.rgba"
+ };
+
+
+static GLuint Program;
+
+static GLfloat Xrot = -90.0, Yrot = .0, Zrot = 0.0;
+static GLfloat EyeDist = 10;
+static GLboolean Anim = GL_TRUE;
+
+
+/* value[0] = tex unit */
+static struct uniform_info Uniforms[] = {
+ { "tex1", 1, GL_INT, { 0, 0, 0, 0 }, -1 },
+ { "tex2", 1, GL_INT, { 1, 0, 0, 0 }, -1 },
+ END_OF_UNIFORMS
+};
+
+
+static void
+DrawPolygon(GLfloat size)
+{
+ glPushMatrix();
+ glRotatef(90, 1, 0, 0);
+ glNormal3f(0, 0, 1);
+ glBegin(GL_POLYGON);
+
+ glMultiTexCoord2f(GL_TEXTURE0, 0, 0);
+ glMultiTexCoord2f(GL_TEXTURE1, 0, 0);
+ glVertex2f(-size, -size);
+
+ glMultiTexCoord2f(GL_TEXTURE0, 2, 0);
+ glMultiTexCoord2f(GL_TEXTURE1, 1, 0);
+ glVertex2f( size, -size);
+
+ glMultiTexCoord2f(GL_TEXTURE0, 2, 2);
+ glMultiTexCoord2f(GL_TEXTURE1, 1, 1);
+ glVertex2f( size, size);
+
+ glMultiTexCoord2f(GL_TEXTURE0, 0, 2);
+ glMultiTexCoord2f(GL_TEXTURE1, 0, 1);
+ glVertex2f(-size, size);
+
+ glEnd();
+ glPopMatrix();
+}
+
+
+static void
+draw(void)
+{
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+
+ glPushMatrix(); /* modelview matrix */
+ glTranslatef(0.0, 0.0, -EyeDist);
+ glRotatef(Zrot, 0, 0, 1);
+ glRotatef(Yrot, 0, 1, 0);
+ glRotatef(Xrot, 1, 0, 0);
+
+ DrawPolygon(3.0);
+
+ glPopMatrix();
+
+ glutSwapBuffers();
+}
+
+
+static void
+idle(void)
+{
+ GLfloat t = 0.05 * glutGet(GLUT_ELAPSED_TIME);
+ Yrot = t;
+ glutPostRedisplay();
+}
+
+
+static void
+key(unsigned char k, int x, int y)
+{
+ (void) x;
+ (void) y;
+ switch (k) {
+ case ' ':
+ case 'a':
+ Anim = !Anim;
+ if (Anim)
+ glutIdleFunc(idle);
+ else
+ glutIdleFunc(NULL);
+ break;
+ case 'z':
+ EyeDist -= 0.5;
+ if (EyeDist < 3.0)
+ EyeDist = 3.0;
+ break;
+ case 'Z':
+ EyeDist += 0.5;
+ if (EyeDist > 90.0)
+ EyeDist = 90;
+ break;
+ case 27:
+ exit(0);
+ }
+ glutPostRedisplay();
+}
+
+
+static void
+specialkey(int key, int x, int y)
+{
+ GLfloat step = 2.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();
+}
+
+
+/* new window size or exposure */
+static void
+Reshape(int width, int height)
+{
+ GLfloat ar = (float) width / (float) height;
+ glViewport(0, 0, (GLint)width, (GLint)height);
+ glMatrixMode(GL_PROJECTION);
+ glLoadIdentity();
+ glFrustum(-2.0*ar, 2.0*ar, -2.0, 2.0, 4.0, 100.0);
+ glMatrixMode(GL_MODELVIEW);
+ glLoadIdentity();
+}
+
+
+static void
+InitTextures(void)
+{
+ GLenum filter = GL_LINEAR;
+ int i;
+
+ for (i = 0; i < 2; i++) {
+ GLint imgWidth, imgHeight;
+ GLenum imgFormat;
+ GLubyte *image = NULL;
+
+ image = LoadRGBImage(TexFiles[i], &imgWidth, &imgHeight, &imgFormat);
+ if (!image) {
+ printf("Couldn't read %s\n", TexFiles[i]);
+ exit(0);
+ }
+
+ glActiveTexture(GL_TEXTURE0 + i);
+ glBindTexture(GL_TEXTURE_2D, 42 + i);
+ gluBuild2DMipmaps(GL_TEXTURE_2D, 4, imgWidth, imgHeight,
+ imgFormat, GL_UNSIGNED_BYTE, image);
+ free(image);
+
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filter);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filter);
+ }
+}
+
+
+static GLuint
+CreateProgram(const char *vertProgFile, const char *fragProgFile,
+ struct uniform_info *uniforms)
+{
+ GLuint fragShader, vertShader, program;
+
+ vertShader = CompileShaderFile(GL_VERTEX_SHADER, vertProgFile);
+ fragShader = CompileShaderFile(GL_FRAGMENT_SHADER, fragProgFile);
+ assert(vertShader);
+ program = LinkShaders(vertShader, fragShader);
+
+ glUseProgram_func(program);
+
+ InitUniforms(program, uniforms);
+
+ return program;
+}
+
+
+static void
+InitPrograms(void)
+{
+ Program = CreateProgram(VertFile, FragFile, Uniforms);
+}
+
+
+static void
+InitGL(void)
+{
+ const char *version = (const char *) glGetString(GL_VERSION);
+
+ if (version[0] != '2' || version[1] != '.') {
+ printf("Warning: this program expects OpenGL 2.0\n");
+ /*exit(1);*/
+ }
+ printf("GL_RENDERER = %s\n",(const char *) glGetString(GL_RENDERER));
+
+ GetExtensionFuncs();
+
+ InitTextures();
+ InitPrograms();
+
+ glEnable(GL_DEPTH_TEST);
+
+ glClearColor(.6, .6, .9, 0);
+ glColor3f(1.0, 1.0, 1.0);
+}
+
+
+int
+main(int argc, char *argv[])
+{
+ glutInit(&argc, argv);
+ glutInitWindowSize(500, 400);
+ glutInitDisplayMode(GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE);
+ glutCreateWindow(Demo);
+ glutReshapeFunc(Reshape);
+ glutKeyboardFunc(key);
+ glutSpecialFunc(specialkey);
+ glutDisplayFunc(draw);
+ if (Anim)
+ glutIdleFunc(idle);
+ InitGL();
+ glutMainLoop();
+ return 0;
+}
diff --git a/progs/glsl/multitex.frag b/progs/glsl/multitex.frag
new file mode 100644
index 0000000..a2633ce
--- /dev/null
+++ b/progs/glsl/multitex.frag
@@ -0,0 +1,15 @@
+// Multi-texture fragment shader
+// Brian Paul
+
+// Composite second texture over first.
+// We're assuming the 2nd texture has a meaningful alpha channel.
+
+uniform sampler2D tex1;
+uniform sampler2D tex2;
+
+void main()
+{
+ vec4 t1 = texture2D(tex1, gl_TexCoord[0].xy);
+ vec4 t2 = texture2D(tex2, gl_TexCoord[1].xy);
+ gl_FragColor = mix(t1, t2, t2.w);
+}
diff --git a/progs/glsl/multitex.vert b/progs/glsl/multitex.vert
new file mode 100644
index 0000000..5518ca1
--- /dev/null
+++ b/progs/glsl/multitex.vert
@@ -0,0 +1,10 @@
+// Multi-texture vertex shader
+// Brian Paul
+
+
+void main()
+{
+ gl_TexCoord[0] = gl_MultiTexCoord0;
+ gl_TexCoord[1] = gl_MultiTexCoord1;
+ gl_Position = ftransform();
+}
diff --git a/progs/glsl/noise.c b/progs/glsl/noise.c
index a26a805..9da71ac 100644
--- a/progs/glsl/noise.c
+++ b/progs/glsl/noise.c
@@ -12,6 +12,7 @@
#include <GL/glut.h>
#include <GL/glext.h>
#include "extfuncs.h"
+#include "shaderutil.h"
static const char *VertShaderText =
@@ -34,18 +35,11 @@ static const char *FragShaderText =
"}\n";
-struct uniform_info {
- const char *name;
- GLuint size;
- GLint location;
- GLfloat value[4];
-};
-
static struct uniform_info Uniforms[] = {
- { "Scale", 4, -1, { 0.5, 0.4, 0.0, 0} },
- { "Bias", 4, -1, { 0.5, 0.3, 0.0, 0} },
- { "Slice", 1, -1, { 0.5, 0, 0, 0} },
- { NULL, 0, 0, { 0, 0, 0, 0 } }
+ { "Scale", 4, GL_FLOAT, { 0.5, 0.4, 0.0, 0}, -1 },
+ { "Bias", 4, GL_FLOAT, { 0.5, 0.3, 0.0, 0}, -1 },
+ { "Slice", 1, GL_FLOAT, { 0.5, 0, 0, 0}, -1 },
+ END_OF_UNIFORMS
};
/* program/shader objects */
@@ -175,94 +169,20 @@ SpecialKey(int key, int x, int y)
static void
-LoadAndCompileShader(GLuint shader, const char *text)
-{
- GLint stat;
-
- glShaderSource_func(shader, 1, (const GLchar **) &text, NULL);
-
- glCompileShader_func(shader);
-
- glGetShaderiv_func(shader, GL_COMPILE_STATUS, &stat);
- if (!stat) {
- GLchar log[1000];
- GLsizei len;
- glGetShaderInfoLog_func(shader, 1000, &len, log);
- fprintf(stderr, "brick: problem compiling shader: %s\n", log);
- exit(1);
- }
- else {
- printf("Shader compiled OK\n");
- }
-}
-
-
-static void
-CheckLink(GLuint prog)
-{
- GLint stat;
- glGetProgramiv_func(prog, GL_LINK_STATUS, &stat);
- if (!stat) {
- GLchar log[1000];
- GLsizei len;
- glGetProgramInfoLog_func(prog, 1000, &len, log);
- fprintf(stderr, "Linker error:\n%s\n", log);
- }
- else {
- fprintf(stderr, "Link success!\n");
- }
-}
-
-
-static void
Init(void)
{
- const char *version;
- GLint i;
-
- version = (const char *) glGetString(GL_VERSION);
- if (version[0] != '2' || version[1] != '.') {
- printf("Warning: this program expects OpenGL 2.0\n");
- /*exit(1);*/
- }
+ if (!ShadersSupported())
+ exit(1);
GetExtensionFuncs();
- vertShader = glCreateShader_func(GL_VERTEX_SHADER);
- LoadAndCompileShader(vertShader, VertShaderText);
-
- fragShader = glCreateShader_func(GL_FRAGMENT_SHADER);
- LoadAndCompileShader(fragShader, FragShaderText);
+ vertShader = CompileShaderText(GL_VERTEX_SHADER, VertShaderText);
+ fragShader = CompileShaderText(GL_FRAGMENT_SHADER, FragShaderText);
+ program = LinkShaders(vertShader, fragShader);
- program = glCreateProgram_func();
- glAttachShader_func(program, fragShader);
- glAttachShader_func(program, vertShader);
- glLinkProgram_func(program);
- CheckLink(program);
glUseProgram_func(program);
- for (i = 0; Uniforms[i].name; i++) {
- Uniforms[i].location
- = glGetUniformLocation_func(program, Uniforms[i].name);
- printf("Uniform %s location: %d\n", Uniforms[i].name,
- Uniforms[i].location);
- switch (Uniforms[i].size) {
- case 1:
- glUniform1fv_func(Uniforms[i].location, 1, Uniforms[i].value);
- break;
- case 2:
- glUniform2fv_func(Uniforms[i].location, 1, Uniforms[i].value);
- break;
- case 3:
- glUniform3fv_func(Uniforms[i].location, 1, Uniforms[i].value);
- break;
- case 4:
- glUniform4fv_func(Uniforms[i].location, 1, Uniforms[i].value);
- break;
- default:
- abort();
- }
- }
+ InitUniforms(program, Uniforms);
assert(glGetError() == 0);
diff --git a/progs/glsl/pointcoord.c b/progs/glsl/pointcoord.c
new file mode 100644
index 0000000..b240077
--- /dev/null
+++ b/progs/glsl/pointcoord.c
@@ -0,0 +1,205 @@
+/**
+ * Test GLSL 1.20 gl_PointCoord fragment program attribute.
+ * Brian Paul
+ * 11 Aug 2007
+ */
+
+
+#include <assert.h>
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+#include <GL/gl.h>
+#include <GL/glut.h>
+#include <GL/glext.h>
+#include "extfuncs.h"
+#include "shaderutil.h"
+
+
+static GLint WinWidth = 300, WinHeight = 300;
+static char *FragProgFile = NULL;
+static char *VertProgFile = NULL;
+static GLuint fragShader;
+static GLuint vertShader;
+static GLuint program;
+static GLint win = 0;
+static GLint tex0;
+static GLenum Filter = GL_NEAREST;
+
+
+static void
+Redisplay(void)
+{
+ glClear(GL_COLOR_BUFFER_BIT);
+
+ /* draw one point/sprite */
+ glPushMatrix();
+ glPointSize(60);
+ glBegin(GL_POINTS);
+ glVertex2f(WinWidth / 2.0f, WinHeight / 2.0f);
+ glEnd();
+ glPopMatrix();
+
+ glutSwapBuffers();
+}
+
+
+static void
+Reshape(int width, int height)
+{
+ glViewport(0, 0, width, height);
+ glMatrixMode(GL_PROJECTION);
+ glLoadIdentity();
+ glOrtho(0, width, 0, height, -1, 1);
+
+ glMatrixMode(GL_MODELVIEW);
+ glLoadIdentity();
+
+ WinWidth = width;
+ WinHeight = height;
+}
+
+
+static void
+CleanUp(void)
+{
+ glDeleteShader_func(fragShader);
+ glDeleteShader_func(vertShader);
+ glDeleteProgram_func(program);
+ glutDestroyWindow(win);
+}
+
+
+static void
+Key(unsigned char key, int x, int y)
+{
+ (void) x;
+ (void) y;
+
+ switch(key) {
+ case 27:
+ CleanUp();
+ exit(0);
+ break;
+ }
+ glutPostRedisplay();
+}
+
+
+
+static void
+MakeTexture(void)
+{
+#define SZ 16
+ GLubyte image[SZ][SZ][4];
+ GLuint i, j;
+
+ for (i = 0; i < SZ; i++) {
+ for (j = 0; j < SZ; j++) {
+ if ((i + j) & 1) {
+ image[i][j][0] = 0;
+ image[i][j][1] = 0;
+ image[i][j][2] = 0;
+ image[i][j][3] = 255;
+ }
+ else {
+ image[i][j][0] = j * 255 / (SZ-1);
+ image[i][j][1] = i * 255 / (SZ-1);
+ image[i][j][2] = 0;
+ image[i][j][3] = 255;
+ }
+ }
+ }
+
+ glActiveTexture(GL_TEXTURE0); /* unit 0 */
+ glBindTexture(GL_TEXTURE_2D, 42);
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, SZ, SZ, 0,
+ GL_RGBA, GL_UNSIGNED_BYTE, image);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, Filter);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, Filter);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+#undef SZ
+}
+
+
+static void
+Init(void)
+{
+ static const char *fragShaderText =
+ "#version 120 \n"
+ "uniform sampler2D tex0; \n"
+ "void main() { \n"
+ " gl_FragColor = texture2D(tex0, gl_PointCoord.xy, 0.0); \n"
+ "}\n";
+ static const char *vertShaderText =
+ "void main() {\n"
+ " gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;\n"
+ "}\n";
+
+ if (!ShadersSupported())
+ exit(1);
+
+ GetExtensionFuncs();
+
+ vertShader = CompileShaderText(GL_VERTEX_SHADER, vertShaderText);
+ fragShader = CompileShaderText(GL_FRAGMENT_SHADER, fragShaderText);
+ program = LinkShaders(vertShader, fragShader);
+
+ glUseProgram_func(program);
+
+ tex0 = glGetUniformLocation_func(program, "tex0");
+ printf("Uniforms: tex0: %d\n", tex0);
+
+ glUniform1i_func(tex0, 0); /* tex unit 0 */
+
+ /*assert(glGetError() == 0);*/
+
+ glClearColor(0.3f, 0.3f, 0.3f, 0.0f);
+
+ printf("GL_RENDERER = %s\n",(const char *) glGetString(GL_RENDERER));
+
+ assert(glIsProgram_func(program));
+ assert(glIsShader_func(fragShader));
+ assert(glIsShader_func(vertShader));
+
+ MakeTexture();
+
+ glEnable(GL_POINT_SPRITE);
+
+ glColor3f(1, 0, 0);
+}
+
+
+static void
+ParseOptions(int argc, char *argv[])
+{
+ int i;
+ for (i = 1; i < argc; i++) {
+ if (strcmp(argv[i], "-fs") == 0) {
+ FragProgFile = argv[i+1];
+ }
+ else if (strcmp(argv[i], "-vs") == 0) {
+ VertProgFile = argv[i+1];
+ }
+ }
+}
+
+
+int
+main(int argc, char *argv[])
+{
+ glutInit(&argc, argv);
+ glutInitWindowPosition( 0, 0);
+ glutInitWindowSize(WinWidth, WinHeight);
+ glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE);
+ win = glutCreateWindow(argv[0]);
+ glutReshapeFunc(Reshape);
+ glutKeyboardFunc(Key);
+ glutDisplayFunc(Redisplay);
+ ParseOptions(argc, argv);
+ Init();
+ glutMainLoop();
+ return 0;
+}
diff --git a/progs/glsl/points.c b/progs/glsl/points.c
new file mode 100644
index 0000000..392dc4d
--- /dev/null
+++ b/progs/glsl/points.c
@@ -0,0 +1,260 @@
+/**
+ * Implement smooth (AA) points with shaders.
+ * A simple variation could be used for sprite points.
+ * Brian Paul
+ * 29 July 2007
+ */
+
+#include <assert.h>
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+#include <GL/gl.h>
+#include <GL/glut.h>
+#include <GL/glext.h>
+#include "extfuncs.h"
+#include "shaderutil.h"
+
+
+static GLuint FragShader;
+static GLuint VertShader;
+static GLuint Program;
+
+static GLint Win = 0;
+static GLint WinWidth = 500, WinHeight = 200;
+static GLfloat Xpos = 0.0f, Ypos = 0.0f;
+static GLint uViewportInv;
+static GLboolean Smooth = GL_TRUE, Blend = GL_TRUE;
+
+
+/**
+ * Issue vertices for a "shader point".
+ * The position is duplicated, only texcoords (or other vertex attrib) change.
+ * The vertex program will compute the "real" quad corners.
+ */
+static void
+PointVertex3f(GLfloat x, GLfloat y, GLfloat z)
+{
+ glTexCoord2f(-1, -1);
+ glVertex3f(x, y, z);
+
+ glTexCoord2f( 1, -1);
+ glVertex3f(x, y, z);
+
+ glTexCoord2f( 1, 1);
+ glVertex3f(x, y, z);
+
+ glTexCoord2f(-1, 1);
+ glVertex3f(x, y, z);
+}
+
+
+static void
+DrawPoints(GLboolean shaderPoints)
+{
+ int i;
+ for (i = 0; i < 9; i++) {
+ GLfloat x = i - 4, y = 0, z = 0;
+ /* note: can't call glPointSize inside Begin/End :( */
+ glPointSize( 2 + i * 5 );
+ if (shaderPoints) {
+ glBegin(GL_QUADS);
+ PointVertex3f(x, y, z);
+ glEnd();
+ }
+ else {
+ glBegin(GL_POINTS);
+ glVertex3f(x, y, z);
+ glEnd();
+ }
+ }
+}
+
+
+/**
+ * Top row of points rendered convetionally,
+ * bottom row rendered with shaders.
+ */
+static void
+Redisplay(void)
+{
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+
+ if (Smooth)
+ glEnable(GL_POINT_SMOOTH);
+ else
+ glDisable(GL_POINT_SMOOTH);
+
+ if (Blend)
+ glEnable(GL_BLEND);
+ else
+ glDisable(GL_BLEND);
+
+ glPushMatrix();
+ glTranslatef(Xpos, Ypos, 0);
+
+ /*
+ * regular points
+ */
+ glPushMatrix();
+ glTranslatef(0, 1.2, 0);
+ glUseProgram_func(0);
+ DrawPoints(GL_FALSE);
+ glPopMatrix();
+
+ /*
+ * shader points
+ */
+ glPushMatrix();
+ glTranslatef(0, -1.2, 0);
+ glUseProgram_func(Program);
+ if (uViewportInv != -1) {
+ glUniform2f_func(uViewportInv, 1.0 / WinWidth, 1.0 / WinHeight);
+ }
+ DrawPoints(GL_TRUE);
+ glPopMatrix();
+
+ glPopMatrix();
+
+ glutSwapBuffers();
+}
+
+
+static void
+Reshape(int width, int height)
+{
+ WinWidth = width;
+ WinHeight = height;
+ glViewport(0, 0, width, height);
+ glMatrixMode(GL_PROJECTION);
+ glLoadIdentity();
+ glFrustum(-1.0, 1.0, -1.0, 1.0, 4.0, 30.0);
+ glMatrixMode(GL_MODELVIEW);
+ glLoadIdentity();
+ glTranslatef(0.0f, 0.0f, -20.0f);
+}
+
+
+static void
+Key(unsigned char key, int x, int y)
+{
+ (void) x;
+ (void) y;
+
+ switch(key) {
+ case 'b':
+ Blend = !Blend;
+ break;
+ case 's':
+ Smooth = !Smooth;
+ break;
+ case 27:
+ glDeleteShader_func(FragShader);
+ glDeleteShader_func(VertShader);
+ glDeleteProgram_func(Program);
+ glutDestroyWindow(Win);
+ exit(0);
+ }
+ glutPostRedisplay();
+}
+
+
+static void
+SpecialKey(int key, int x, int y)
+{
+ const GLfloat step = 1/100.0;
+ 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(void)
+{
+ /* Fragment shader: compute distance of fragment from center of point
+ * (we're using texcoords but another varying could be used).
+ * if dist > 1, discard (coverage==0)
+ * if dist < k, coverage = 1
+ * else, coverage = func(dist)
+ * Note: length() uses sqrt() and may be expensive. The distance could
+ * be squared instead (with adjustments to the threshold (k) test)
+ */
+ static const char *fragShaderText =
+ "void main() {\n"
+ " float cover; \n"
+ " float k = 2.0 / gl_Point.size; \n"
+ " float d = length(gl_TexCoord[0].xy); \n"
+ " if (d >= 1.0) \n"
+ " discard; \n"
+ " if (d < 1.0 - k) \n"
+ " cover = 1.0; \n"
+ " else \n"
+ " cover = (1.0 - d) * 0.5 * gl_Point.size; \n"
+ " gl_FragColor.rgb = gl_Color.rgb; \n"
+ " gl_FragColor.a = cover; \n"
+ "}\n";
+ /* Vertex shader: compute new vertex position based on incoming vertex pos,
+ * texcoords, point size, and inverse viewport scale factor.
+ * Note: should compute point size attenuation here too.
+ */
+ static const char *vertShaderText =
+ "uniform vec2 viewportInv; \n"
+ "void main() {\n"
+ " vec4 pos = gl_ModelViewProjectionMatrix * gl_Vertex;\n"
+ " gl_Position.xy = pos.xy + gl_MultiTexCoord0.xy * viewportInv \n"
+ " * gl_Point.size * pos.w; \n"
+ " gl_Position.zw = pos.zw; \n"
+ " gl_TexCoord[0] = gl_MultiTexCoord0; \n"
+ " gl_FrontColor = gl_Color; \n"
+ "}\n";
+
+ if (!ShadersSupported())
+ exit(1);
+
+ GetExtensionFuncs();
+
+ VertShader = CompileShaderText(GL_VERTEX_SHADER, vertShaderText);
+ FragShader = CompileShaderText(GL_FRAGMENT_SHADER, fragShaderText);
+ Program = LinkShaders(VertShader, FragShader);
+
+ glUseProgram_func(Program);
+
+ uViewportInv = glGetUniformLocation_func(Program, "viewportInv");
+
+ glUseProgram_func(0);
+
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+}
+
+
+int
+main(int argc, char *argv[])
+{
+ glutInit(&argc, argv);
+ glutInitWindowSize(WinWidth, WinHeight);
+ glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
+ Win = glutCreateWindow(argv[0]);
+ glutReshapeFunc(Reshape);
+ glutKeyboardFunc(Key);
+ glutSpecialFunc(SpecialKey);
+ glutDisplayFunc(Redisplay);
+ Init();
+ glutMainLoop();
+ return 0;
+}
+
+
diff --git a/progs/glsl/reflect.vert.txt b/progs/glsl/reflect.vert
index 402be38..402be38 100644
--- a/progs/glsl/reflect.vert.txt
+++ b/progs/glsl/reflect.vert
diff --git a/progs/glsl/shadowtex.frag.txt b/progs/glsl/shadowtex.frag
index a6a80da..a6a80da 100644
--- a/progs/glsl/shadowtex.frag.txt
+++ b/progs/glsl/shadowtex.frag
diff --git a/progs/glsl/simple.vert.txt b/progs/glsl/simple.vert
index a0abe0d..a0abe0d 100644
--- a/progs/glsl/simple.vert.txt
+++ b/progs/glsl/simple.vert
diff --git a/progs/glsl/texdemo1.c b/progs/glsl/texdemo1.c
index 3ceae14..96ddca1 100644
--- a/progs/glsl/texdemo1.c
+++ b/progs/glsl/texdemo1.c
@@ -31,14 +31,15 @@
#include "GL/glut.h"
#include "readtex.h"
#include "extfuncs.h"
+#include "shaderutil.h"
static const char *Demo = "texdemo1";
-static const char *ReflectVertFile = "reflect.vert.txt";
-static const char *CubeFragFile = "cubemap.frag.txt";
+static const char *ReflectVertFile = "reflect.vert";
+static const char *CubeFragFile = "cubemap.frag";
-static const char *SimpleVertFile = "simple.vert.txt";
-static const char *SimpleTexFragFile = "shadowtex.frag.txt";
+static const char *SimpleVertFile = "simple.vert";
+static const char *SimpleTexFragFile = "shadowtex.frag";
static const char *GroundImage = "../images/tile.rgb";
@@ -51,39 +52,20 @@ static GLboolean Anim = GL_TRUE;
static int win = 0;
-struct uniform_info {
- const char *name;
- GLuint size;
- GLint location;
- GLenum type; /**< GL_FLOAT or GL_INT */
- GLfloat value[4];
-};
-
static struct uniform_info ReflectUniforms[] = {
- { "cubeTex", 1, -1, GL_INT, { 0, 0, 0, 0 } },
- { "lightPos", 3, -1, GL_FLOAT, { 10, 10, 20, 0 } },
- { NULL, 0, 0, 0, { 0, 0, 0, 0 } }
+ { "cubeTex", 1, GL_INT, { 0, 0, 0, 0 }, -1 },
+ { "lightPos", 3, GL_FLOAT, { 10, 10, 20, 0 }, -1 },
+ END_OF_UNIFORMS
};
static struct uniform_info SimpleUniforms[] = {
- { "tex2d", 1, -1, GL_INT, { 1, 0, 0, 0 } },
- { "lightPos", 3, -1, GL_FLOAT, { 10, 10, 20, 0 } },
- { NULL, 0, 0, 0, { 0, 0, 0, 0 } }
+ { "tex2d", 1, GL_INT, { 1, 0, 0, 0 }, -1 },
+ { "lightPos", 3, GL_FLOAT, { 10, 10, 20, 0 }, -1 },
+ END_OF_UNIFORMS
};
static void
-CheckError(int line)
-{
- GLenum err = glGetError();
- if (err) {
- printf("GL Error %s (0x%x) at line %d\n",
- gluErrorString(err), (int) err, line);
- }
-}
-
-
-static void
DrawGround(GLfloat size)
{
glPushMatrix();
@@ -388,132 +370,19 @@ InitTextures(GLboolean useImageFiles)
}
-static void
-LoadAndCompileShader(GLuint shader, const char *text)
-{
- GLint stat;
-
- glShaderSource_func(shader, 1, (const GLchar **) &text, NULL);
-
- glCompileShader_func(shader);
-
- glGetShaderiv_func(shader, GL_COMPILE_STATUS, &stat);
- if (!stat) {
- GLchar log[1000];
- GLsizei len;
- glGetShaderInfoLog_func(shader, 1000, &len, log);
- fprintf(stderr, "%s: problem compiling shader: %s\n", Demo, log);
- exit(1);
- }
- else {
- printf("Shader compiled OK\n");
- }
-}
-
-
-/**
- * Read a shader from a file.
- */
-static void
-ReadShader(GLuint shader, const char *filename)
-{
- const int max = 100*1000;
- int n;
- char *buffer = (char*) malloc(max);
- FILE *f = fopen(filename, "r");
- if (!f) {
- fprintf(stderr, "%s: Unable to open shader file %s\n", Demo, filename);
- exit(1);
- }
-
- n = fread(buffer, 1, max, f);
- printf("%s: read %d bytes from shader file %s\n", Demo, n, filename);
- if (n > 0) {
- buffer[n] = 0;
- LoadAndCompileShader(shader, buffer);
- }
-
- fclose(f);
- free(buffer);
-}
-
-
-static void
-CheckLink(GLuint prog)
-{
- GLint stat;
- glGetProgramiv_func(prog, GL_LINK_STATUS, &stat);
- if (!stat) {
- GLchar log[1000];
- GLsizei len;
- glGetProgramInfoLog_func(prog, 1000, &len, log);
- fprintf(stderr, "Linker error:\n%s\n", log);
- }
- else {
- fprintf(stderr, "Link success!\n");
- }
-}
-
-
static GLuint
CreateProgram(const char *vertProgFile, const char *fragProgFile,
struct uniform_info *uniforms)
{
- GLuint fragShader = 0, vertShader = 0, program = 0;
- GLint i;
-
- program = glCreateProgram_func();
- if (vertProgFile) {
- vertShader = glCreateShader_func(GL_VERTEX_SHADER);
- ReadShader(vertShader, vertProgFile);
- glAttachShader_func(program, vertShader);
- }
+ GLuint fragShader, vertShader, program;
- if (fragProgFile) {
- fragShader = glCreateShader_func(GL_FRAGMENT_SHADER);
- ReadShader(fragShader, fragProgFile);
- glAttachShader_func(program, fragShader);
- }
-
- glLinkProgram_func(program);
- CheckLink(program);
+ vertShader = CompileShaderFile(GL_VERTEX_SHADER, vertProgFile);
+ fragShader = CompileShaderFile(GL_FRAGMENT_SHADER, fragProgFile);
+ program = LinkShaders(vertShader, fragShader);
glUseProgram_func(program);
- assert(glIsProgram_func(program));
- assert(glIsShader_func(fragShader));
- assert(glIsShader_func(vertShader));
-
- CheckError(__LINE__);
- for (i = 0; uniforms[i].name; i++) {
- uniforms[i].location
- = glGetUniformLocation_func(program, uniforms[i].name);
- printf("Uniform %s location: %d\n", uniforms[i].name,
- uniforms[i].location);
-
- switch (uniforms[i].size) {
- case 1:
- if (uniforms[i].type == GL_INT)
- glUniform1i_func(uniforms[i].location,
- (GLint) uniforms[i].value[0]);
- else
- glUniform1fv_func(uniforms[i].location, 1, uniforms[i].value);
- break;
- case 2:
- glUniform2fv_func(uniforms[i].location, 1, uniforms[i].value);
- break;
- case 3:
- glUniform3fv_func(uniforms[i].location, 1, uniforms[i].value);
- break;
- case 4:
- glUniform4fv_func(uniforms[i].location, 1, uniforms[i].value);
- break;
- default:
- abort();
- }
- }
-
- CheckError(__LINE__);
+ InitUniforms(program, uniforms);
return program;
}
diff --git a/progs/glsl/toyball.c b/progs/glsl/toyball.c
index cef52c0..2daaedd 100644
--- a/progs/glsl/toyball.c
+++ b/progs/glsl/toyball.c
@@ -13,10 +13,11 @@
#include <GL/glut.h>
#include <GL/glext.h>
#include "extfuncs.h"
+#include "shaderutil.h"
-static char *FragProgFile = "CH11-toyball.frag.txt";
-static char *VertProgFile = "CH11-toyball.vert.txt";
+static char *FragProgFile = "CH11-toyball.frag";
+static char *VertProgFile = "CH11-toyball.vert";
/* program/shader objects */
static GLuint fragShader;
@@ -24,30 +25,23 @@ static GLuint vertShader;
static GLuint program;
-struct uniform_info {
- const char *name;
- GLuint size;
- GLint location;
- GLfloat value[4];
-};
-
static struct uniform_info Uniforms[] = {
- { "LightDir", 4, -1, { 0.57737, 0.57735, 0.57735, 0.0 } },
- { "HVector", 4, -1, { 0.32506, 0.32506, 0.88808, 0.0 } },
- { "BallCenter", 4, -1, { 0.0, 0.0, 0.0, 1.0 } },
- { "SpecularColor", 4, -1, { 0.4, 0.4, 0.4, 60.0 } },
- { "Red", 4, -1, { 0.6, 0.0, 0.0, 1.0 } },
- { "Blue", 4, -1, { 0.0, 0.3, 0.6, 1.0 } },
- { "Yellow", 4, -1, { 0.6, 0.5, 0.0, 1.0 } },
- { "HalfSpace0", 4, -1, { 1.0, 0.0, 0.0, 0.2 } },
- { "HalfSpace1", 4, -1, { 0.309016994, 0.951056516, 0.0, 0.2 } },
- { "HalfSpace2", 4, -1, { -0.809016994, 0.587785252, 0.0, 0.2 } },
- { "HalfSpace3", 4, -1, { -0.809016994, -0.587785252, 0.0, 0.2 } },
- { "HalfSpace4", 4, -1, { 0.309116994, -0.951056516, 0.0, 0.2 } },
- { "InOrOutInit", 1, -1, { -3.0, 0, 0, 0 } },
- { "StripeWidth", 1, -1, { 0.3, 0, 0, 0 } },
- { "FWidth", 1, -1, { 0.005, 0, 0, 0 } },
- { NULL, 0, 0, { 0, 0, 0, 0 } }
+ { "LightDir", 4, GL_FLOAT, { 0.57737, 0.57735, 0.57735, 0.0 }, -1 },
+ { "HVector", 4, GL_FLOAT, { 0.32506, 0.32506, 0.88808, 0.0 }, -1 },
+ { "BallCenter", 4, GL_FLOAT, { 0.0, 0.0, 0.0, 1.0 }, -1 },
+ { "SpecularColor", 4, GL_FLOAT, { 0.4, 0.4, 0.4, 60.0 }, -1 },
+ { "Red", 4, GL_FLOAT, { 0.6, 0.0, 0.0, 1.0 }, -1 },
+ { "Blue", 4, GL_FLOAT, { 0.0, 0.3, 0.6, 1.0 }, -1 },
+ { "Yellow", 4, GL_FLOAT, { 0.6, 0.5, 0.0, 1.0 }, -1 },
+ { "HalfSpace0", 4, GL_FLOAT, { 1.0, 0.0, 0.0, 0.2 }, -1 },
+ { "HalfSpace1", 4, GL_FLOAT, { 0.309016994, 0.951056516, 0.0, 0.2 }, -1 },
+ { "HalfSpace2", 4, GL_FLOAT, { -0.809016994, 0.587785252, 0.0, 0.2 }, -1 },
+ { "HalfSpace3", 4, GL_FLOAT, { -0.809016994, -0.587785252, 0.0, 0.2 }, -1 },
+ { "HalfSpace4", 4, GL_FLOAT, { 0.309116994, -0.951056516, 0.0, 0.2 }, -1 },
+ { "InOrOutInit", 1, GL_FLOAT, { -3.0, 0, 0, 0 }, -1 },
+ { "StripeWidth", 1, GL_FLOAT, { 0.3, 0, 0, 0 }, -1 },
+ { "FWidth", 1, GL_FLOAT, { 0.005, 0, 0, 0 }, -1 },
+ END_OF_UNIFORMS
};
static GLint win = 0;
@@ -172,127 +166,20 @@ SpecialKey(int key, int x, int y)
static void
-LoadAndCompileShader(GLuint shader, const char *text)
-{
- GLint stat;
-
- glShaderSource_func(shader, 1, (const GLchar **) &text, NULL);
-
- glCompileShader_func(shader);
-
- glGetShaderiv_func(shader, GL_COMPILE_STATUS, &stat);
- if (!stat) {
- GLchar log[1000];
- GLsizei len;
- glGetShaderInfoLog_func(shader, 1000, &len, log);
- fprintf(stderr, "brick: problem compiling shader: %s\n", log);
- exit(1);
- }
- else {
- printf("Shader compiled OK\n");
- }
-}
-
-
-/**
- * Read a shader from a file.
- */
-static void
-ReadShader(GLuint shader, const char *filename)
-{
- const int max = 100*1000;
- int n;
- char *buffer = (char*) malloc(max);
- FILE *f = fopen(filename, "r");
- if (!f) {
- fprintf(stderr, "brick: Unable to open shader file %s\n", filename);
- exit(1);
- }
-
- n = fread(buffer, 1, max, f);
- printf("brick: read %d bytes from shader file %s\n", n, filename);
- if (n > 0) {
- buffer[n] = 0;
- LoadAndCompileShader(shader, buffer);
- }
-
- fclose(f);
- free(buffer);
-}
-
-
-static void
-CheckLink(GLuint prog)
-{
- GLint stat;
- glGetProgramiv_func(prog, GL_LINK_STATUS, &stat);
- if (!stat) {
- GLchar log[1000];
- GLsizei len;
- glGetProgramInfoLog_func(prog, 1000, &len, log);
- fprintf(stderr, "Linker error:\n%s\n", log);
- }
- else {
- fprintf(stderr, "Link success!\n");
- }
-}
-
-
-static void
Init(void)
{
- const char *version;
- GLint i;
-
- version = (const char *) glGetString(GL_VERSION);
- if (version[0] != '2' || version[1] != '.') {
- printf("Warning: this program expects OpenGL 2.0\n");
- /*exit(1);*/
- }
- printf("GL_RENDERER = %s\n",(const char *) glGetString(GL_RENDERER));
+ if (!ShadersSupported())
+ exit(1);
GetExtensionFuncs();
- vertShader = glCreateShader_func(GL_VERTEX_SHADER);
- ReadShader(vertShader, VertProgFile);
-
- fragShader = glCreateShader_func(GL_FRAGMENT_SHADER);
- ReadShader(fragShader, FragProgFile);
+ vertShader = CompileShaderFile(GL_VERTEX_SHADER, VertProgFile);
+ fragShader = CompileShaderFile(GL_FRAGMENT_SHADER, FragProgFile);
+ program = LinkShaders(vertShader, fragShader);
- program = glCreateProgram_func();
- glAttachShader_func(program, fragShader);
- glAttachShader_func(program, vertShader);
- glLinkProgram_func(program);
- CheckLink(program);
glUseProgram_func(program);
- assert(glIsProgram_func(program));
- assert(glIsShader_func(fragShader));
- assert(glIsShader_func(vertShader));
-
-
- for (i = 0; Uniforms[i].name; i++) {
- Uniforms[i].location
- = glGetUniformLocation_func(program, Uniforms[i].name);
- printf("Uniform %s location: %d\n", Uniforms[i].name,
- Uniforms[i].location);
- switch (Uniforms[i].size) {
- case 1:
- glUniform1fv_func(Uniforms[i].location, 1, Uniforms[i].value);
- break;
- case 2:
- glUniform2fv_func(Uniforms[i].location, 1, Uniforms[i].value);
- break;
- case 3:
- glUniform3fv_func(Uniforms[i].location, 1, Uniforms[i].value);
- break;
- case 4:
- glUniform4fv_func(Uniforms[i].location, 1, Uniforms[i].value);
- break;
- default:
- abort();
- }
- }
+ InitUniforms(program, Uniforms);
assert(glGetError() == 0);
diff --git a/progs/glsl/trirast.c b/progs/glsl/trirast.c
new file mode 100644
index 0000000..89df64f
--- /dev/null
+++ b/progs/glsl/trirast.c
@@ -0,0 +1,259 @@
+/**
+ * Demonstration of doing triangle rasterization with a fragment program.
+ * Basic idea:
+ * 1. Draw screen-aligned quad / bounding box around the triangle verts.
+ * 2. For each pixel in the quad, determine if pixel is inside/outside
+ * the triangle edges.
+ *
+ * Brian Paul
+ * 1 Aug 2007
+ */
+
+
+#include <assert.h>
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+#include <GL/gl.h>
+#include <GL/glut.h>
+#include <GL/glext.h>
+#include "extfuncs.h"
+#include "shaderutil.h"
+
+
+static GLint WinWidth = 300, WinHeight = 300;
+static char *FragProgFile = NULL;
+static char *VertProgFile = NULL;
+static GLuint fragShader;
+static GLuint vertShader;
+static GLuint program;
+static GLint win = 0;
+static GLboolean anim = GL_TRUE;
+static GLfloat Zrot = 0.0f;
+static GLint uv0, uv1, uv2;
+
+
+static const GLfloat TriVerts[3][2] = {
+ { 50, 50 },
+ { 250, 50 },
+ { 150, 250 }
+};
+
+
+static void
+RotateVerts(GLfloat a,
+ GLuint n, const GLfloat vertsIn[][2], GLfloat vertsOut[][2])
+{
+ GLuint i;
+ GLfloat cx = WinWidth / 2, cy = WinHeight / 2;
+ for (i = 0; i < n; i++) {
+ float x = vertsIn[i][0] - cx;
+ float y = vertsIn[i][1] - cy;
+
+ vertsOut[i][0] = x * cos(a) + y * sin(a) + cx;
+ vertsOut[i][1] = -x * sin(a) + y * cos(a) + cy;
+ }
+}
+
+static void
+ComputeBounds(GLuint n, GLfloat vertsIn[][2],
+ GLfloat *xmin, GLfloat *ymin,
+ GLfloat *xmax, GLfloat *ymax)
+{
+ GLuint i;
+ *xmin = *xmax = vertsIn[0][0];
+ *ymin = *ymax = vertsIn[0][1];
+ for (i = 1; i < n; i++) {
+ if (vertsIn[i][0] < *xmin)
+ *xmin = vertsIn[i][0];
+ else if (vertsIn[i][0] > *xmax)
+ *xmax = vertsIn[i][0];
+ if (vertsIn[i][1] < *ymin)
+ *ymin = vertsIn[i][1];
+ else if (vertsIn[i][1] > *ymax)
+ *ymax = vertsIn[i][1];
+ }
+}
+
+
+static void
+Redisplay(void)
+{
+ GLfloat v[3][2], xmin, ymin, xmax, ymax;
+
+ RotateVerts(Zrot, 3, TriVerts, v);
+ ComputeBounds(3, v, &xmin, &ymin, &xmax, &ymax);
+
+ glUniform2fv_func(uv0, 1, v[0]);
+ glUniform2fv_func(uv1, 1, v[1]);
+ glUniform2fv_func(uv2, 1, v[2]);
+
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+
+ glPushMatrix();
+ glBegin(GL_POLYGON);
+ glVertex2f(xmin, ymin);
+ glVertex2f(xmax, ymin);
+ glVertex2f(xmax, ymax);
+ glVertex2f(xmin, ymax);
+ glEnd();
+ glPopMatrix();
+
+ glutSwapBuffers();
+}
+
+
+static void
+Idle(void)
+{
+ if (anim) {
+ Zrot = glutGet(GLUT_ELAPSED_TIME) * 0.0005;
+ glutPostRedisplay();
+ }
+ else
+ abort();
+}
+
+
+static void
+Reshape(int width, int height)
+{
+ glViewport(0, 0, width, height);
+ glMatrixMode(GL_PROJECTION);
+ glLoadIdentity();
+ glOrtho(0, width, 0, height, -1, 1);
+
+ glMatrixMode(GL_MODELVIEW);
+ glLoadIdentity();
+}
+
+
+static void
+CleanUp(void)
+{
+ glDeleteShader_func(fragShader);
+ glDeleteShader_func(vertShader);
+ glDeleteProgram_func(program);
+ glutDestroyWindow(win);
+}
+
+
+static void
+Key(unsigned char key, int x, int y)
+{
+ (void) x;
+ (void) y;
+
+ switch(key) {
+ case ' ':
+ case 'a':
+ anim = !anim;
+ if (anim)
+ glutIdleFunc(Idle);
+ else
+ glutIdleFunc(NULL);
+ break;
+ case 'z':
+ Zrot = 0;
+ break;
+ case 's':
+ Zrot += 0.05;
+ break;
+ case 27:
+ CleanUp();
+ exit(0);
+ break;
+ }
+ glutPostRedisplay();
+}
+
+
+static void
+Init(void)
+{
+ static const char *fragShaderText =
+ "uniform vec2 v0, v1, v2; \n"
+ "float crs(const vec2 u, const vec2 v) \n"
+ "{ \n"
+ " return u.x * v.y - u.y * v.x; \n"
+ "} \n"
+ "\n"
+ "void main() {\n"
+ " vec2 p = gl_FragCoord.xy; \n"
+ " if (crs(v1 - v0, p - v0) >= 0 && \n"
+ " crs(v2 - v1, p - v1) >= 0 && \n"
+ " crs(v0 - v2, p - v2) >= 0) \n"
+ " gl_FragColor = vec4(1.0); \n"
+ " else \n"
+ " gl_FragColor = vec4(0.5); \n"
+ "}\n";
+ static const char *vertShaderText =
+ "void main() {\n"
+ " gl_Position = ftransform(); \n"
+ "}\n";
+
+ if (!ShadersSupported())
+ exit(1);
+
+ GetExtensionFuncs();
+
+ vertShader = CompileShaderText(GL_VERTEX_SHADER, vertShaderText);
+ fragShader = CompileShaderText(GL_FRAGMENT_SHADER, fragShaderText);
+ program = LinkShaders(vertShader, fragShader);
+
+ glUseProgram_func(program);
+
+ uv0 = glGetUniformLocation_func(program, "v0");
+ uv1 = glGetUniformLocation_func(program, "v1");
+ uv2 = glGetUniformLocation_func(program, "v2");
+ printf("Uniforms: %d %d %d\n", uv0, uv1, uv2);
+
+ /*assert(glGetError() == 0);*/
+
+ glClearColor(0.3f, 0.3f, 0.3f, 0.0f);
+ glEnable(GL_DEPTH_TEST);
+
+ printf("GL_RENDERER = %s\n",(const char *) glGetString(GL_RENDERER));
+
+ assert(glIsProgram_func(program));
+ assert(glIsShader_func(fragShader));
+ assert(glIsShader_func(vertShader));
+
+ glColor3f(1, 0, 0);
+}
+
+
+static void
+ParseOptions(int argc, char *argv[])
+{
+ int i;
+ for (i = 1; i < argc; i++) {
+ if (strcmp(argv[i], "-fs") == 0) {
+ FragProgFile = argv[i+1];
+ }
+ else if (strcmp(argv[i], "-vs") == 0) {
+ VertProgFile = argv[i+1];
+ }
+ }
+}
+
+
+int
+main(int argc, char *argv[])
+{
+ glutInit(&argc, argv);
+ glutInitWindowPosition( 0, 0);
+ glutInitWindowSize(WinWidth, WinHeight);
+ glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
+ win = glutCreateWindow(argv[0]);
+ glutReshapeFunc(Reshape);
+ glutKeyboardFunc(Key);
+ glutDisplayFunc(Redisplay);
+ if (anim)
+ glutIdleFunc(Idle);
+ ParseOptions(argc, argv);
+ Init();
+ glutMainLoop();
+ return 0;
+}
diff --git a/progs/glsl/twoside.c b/progs/glsl/twoside.c
new file mode 100644
index 0000000..672a004
--- /dev/null
+++ b/progs/glsl/twoside.c
@@ -0,0 +1,294 @@
+/**
+ * Test two-sided lighting with shaders.
+ * Both GL_VERTEX_PROGRAM_TWO_SIDE and gl_FrontFacing can be tested
+ * (see keys below).
+ *
+ * Brian Paul
+ * 18 Dec 2007
+ */
+
+#include <assert.h>
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+#include <GL/gl.h>
+#include <GL/glut.h>
+#include <GL/glext.h>
+#include "extfuncs.h"
+#include "shaderutil.h"
+
+
+static GLint WinWidth = 300, WinHeight = 300;
+static char *FragProgFile = NULL;
+static char *VertProgFile = NULL;
+static GLuint fragShader;
+static GLuint vertShader;
+static GLuint program;
+static GLint win = 0;
+static GLboolean anim = 0*GL_TRUE;
+static GLboolean DetermineInFragProg = GL_TRUE;
+static GLfloat Xrot = 30.0f;
+static GLint u_fragface;
+static GLenum FrontWinding = GL_CCW;
+static int prevTime = 0;
+
+
+static const GLfloat Red[4] = {1, 0, 0, 0};
+static const GLfloat Green[4] = {0, 1, 0, 0};
+
+
+static void
+Redisplay(void)
+{
+ int i;
+ float radius = 2;
+
+ glFrontFace(FrontWinding);
+
+ if (DetermineInFragProg) {
+ glUniform1i_func(u_fragface, 1);
+ glDisable(GL_VERTEX_PROGRAM_TWO_SIDE);
+ }
+ else {
+ glUniform1i_func(u_fragface, 0);
+ glEnable(GL_VERTEX_PROGRAM_TWO_SIDE);
+ }
+
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
+
+ glPushMatrix();
+ glRotatef(Xrot, 1, 0, 0);
+
+ /* Draw a tristrip ring */
+ glBegin(GL_TRIANGLE_STRIP);
+ glColor4fv(Red);
+ glSecondaryColor3fv_func(Green);
+ for (i = 0; i < 20; i++) {
+ float a = i / 19.0 * M_PI * 2.0;
+ float x = radius * cos(a);
+ float y = radius * sin(a);
+ glVertex3f(x, -1, y);
+ glVertex3f(x, +1, y);
+ }
+ glEnd();
+
+ glPopMatrix();
+
+ glutSwapBuffers();
+}
+
+
+static void
+Idle(void)
+{
+ int curTime = glutGet(GLUT_ELAPSED_TIME);
+ int dt = curTime - prevTime;
+
+ if (prevTime == 0) {
+ prevTime = curTime;
+ return;
+ }
+ prevTime = curTime;
+
+ Xrot += dt * 0.1;
+ glutPostRedisplay();
+}
+
+
+static void
+Reshape(int width, int height)
+{
+ float ar = (float) width / height;
+ glViewport(0, 0, width, height);
+ glMatrixMode(GL_PROJECTION);
+ glLoadIdentity();
+ glFrustum(-ar, ar, -1, 1, 3, 25);
+ glMatrixMode(GL_MODELVIEW);
+ glLoadIdentity();
+ glTranslatef(0, 0, -10);
+}
+
+
+static void
+CleanUp(void)
+{
+ glDeleteShader_func(fragShader);
+ glDeleteShader_func(vertShader);
+ glDeleteProgram_func(program);
+ glutDestroyWindow(win);
+}
+
+
+static void
+Key(unsigned char key, int x, int y)
+{
+ (void) x;
+ (void) y;
+
+ switch(key) {
+ case ' ':
+ case 'a':
+ anim = !anim;
+ if (anim) {
+ prevTime = glutGet(GLUT_ELAPSED_TIME);
+ glutIdleFunc(Idle);
+ }
+ else
+ glutIdleFunc(NULL);
+ break;
+ case 'f':
+ printf("Using frag shader gl_FrontFacing\n");
+ DetermineInFragProg = GL_TRUE;
+ break;
+ case 'v':
+ printf("Using vert shader Two-sided lighting\n");
+ DetermineInFragProg = GL_FALSE;
+ break;
+ case 'r':
+ /* reset */
+ Xrot = 30;
+ anim = 0;
+ glutIdleFunc(NULL);
+ break;
+ case 's':
+ Xrot += 5;
+ break;
+ case 'S':
+ Xrot -= 5;
+ break;
+ case 'w':
+ if (FrontWinding == GL_CCW) {
+ FrontWinding = GL_CW;
+ printf("FrontFace = GL_CW\n");
+ }
+ else {
+ FrontWinding = GL_CCW;
+ printf("FrontFace = GL_CCW\n");
+ }
+ break;
+ case 27:
+ CleanUp();
+ exit(0);
+ break;
+ }
+ glutPostRedisplay();
+}
+
+
+static void
+Init(void)
+{
+ static const char *fragShaderText =
+ "uniform bool fragface; \n"
+ "void main() { \n"
+#if 0
+ " if (!fragface || gl_FrontFacing) { \n"
+ " gl_FragColor = gl_Color; \n"
+ " } \n"
+ " else { \n"
+ " gl_FragColor = 0.8 * gl_SecondaryColor; \n"
+ " } \n"
+#else
+ " bool f = gl_FrontFacing; \n"
+ " if (f) { \n"
+ " gl_FragColor = vec4(1.0, 0.0, 0.0, 0.0); \n"
+ " } \n"
+ " else { \n"
+ " gl_FragColor = vec4(0.0, 1.0, 0.0, 0.0); \n"
+ " } \n"
+ " //float g = float(gl_FrontFacing) * 0.5 + 0.5; \n"
+ " //gl_FragColor = vec4(g); \n"
+#endif
+ "} \n";
+ static const char *vertShaderText =
+ "uniform bool fragface; \n"
+ "void main() { \n"
+ " gl_FrontColor = gl_Color; \n"
+ " if (fragface) { \n"
+ " // front/back chosen in frag prog \n"
+ " gl_FrontSecondaryColor = gl_SecondaryColor; \n"
+ " } \n"
+ " else { \n"
+ " // front/back chosen in prim setup \n"
+ " gl_BackColor = gl_SecondaryColor; \n"
+ " } \n"
+ " gl_Position = ftransform(); \n"
+ "} \n";
+
+ if (!ShadersSupported())
+ exit(1);
+
+ GetExtensionFuncs();
+
+ vertShader = CompileShaderText(GL_VERTEX_SHADER, vertShaderText);
+ fragShader = CompileShaderText(GL_FRAGMENT_SHADER, fragShaderText);
+ program = LinkShaders(vertShader, fragShader);
+
+ glUseProgram_func(program);
+
+ u_fragface = glGetUniformLocation_func(program, "fragface");
+ printf("Uniforms: %d\n", u_fragface);
+
+ /*assert(glGetError() == 0);*/
+
+ glClearColor(0.3f, 0.3f, 0.3f, 0.0f);
+
+ printf("GL_RENDERER = %s\n",(const char *) glGetString(GL_RENDERER));
+
+ assert(glIsProgram_func(program));
+ assert(glIsShader_func(fragShader));
+ assert(glIsShader_func(vertShader));
+
+ glEnable(GL_DEPTH_TEST);
+}
+
+
+static void
+ParseOptions(int argc, char *argv[])
+{
+ int i;
+ for (i = 1; i < argc; i++) {
+ if (strcmp(argv[i], "-fs") == 0) {
+ FragProgFile = argv[i+1];
+ }
+ else if (strcmp(argv[i], "-vs") == 0) {
+ VertProgFile = argv[i+1];
+ }
+ }
+}
+
+
+static void
+Usage(void)
+{
+ printf("Keys:\n");
+ printf(" f - do front/back determination in fragment shader\n");
+ printf(" v - do front/back determination in vertex shader\n");
+ printf(" r - reset, show front\n");
+ printf(" a - toggle animation\n");
+ printf(" s - step rotation\n");
+ printf(" w - toggle CW, CCW front-face winding\n");
+ printf("NOTE: red = front face, green = back face.\n");
+}
+
+
+int
+main(int argc, char *argv[])
+{
+ glutInit(&argc, argv);
+ glutInitWindowPosition( 0, 0);
+ glutInitWindowSize(WinWidth, WinHeight);
+ glutInitDisplayMode(GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE);
+ win = glutCreateWindow(argv[0]);
+ glutReshapeFunc(Reshape);
+ glutKeyboardFunc(Key);
+ glutDisplayFunc(Redisplay);
+ if (anim)
+ glutIdleFunc(Idle);
+ ParseOptions(argc, argv);
+ Init();
+ Usage();
+ glutMainLoop();
+ return 0;
+}
diff --git a/progs/miniglx/Makefile b/progs/miniglx/Makefile
index cc27024..e6f5fa5 100644
--- a/progs/miniglx/Makefile
+++ b/progs/miniglx/Makefile
@@ -20,6 +20,8 @@ INCLUDES = \
-I. \
-I$(TOP)/include
+LIBS = -L$(TOP)/$(LIB_DIR) -l$(GLUT_LIB) -l$(GLU_LIB) -l$(GL_LIB) $(APP_LIB_DEPS)
+
##### RULES #####
@@ -27,7 +29,7 @@ INCLUDES = \
.SUFFIXES: .c
.c:
- $(CC) $(INCLUDES) $(CFLAGS) $< $(APP_LIB_DEPS) -o $@
+ $(CC) $(INCLUDES) $(CFLAGS) $(LDFLAGS) $< $(LIBS) -o $@
.c.o:
$(CC) -c $(INCLUDES) $(CFLAGS) $< -o $@
@@ -41,8 +43,8 @@ INCLUDES = \
default: depend $(PROGS)
clean:
- rm -f $(PROGS)
- rm -f *.o
+ -rm -f $(PROGS)
+ -rm -f *.o
depend: $(SOURCES)
diff --git a/progs/osdemos/Makefile b/progs/osdemos/Makefile
index f8cba9e..023ea02 100644
--- a/progs/osdemos/Makefile
+++ b/progs/osdemos/Makefile
@@ -5,13 +5,19 @@ include $(TOP)/configs/current
INCDIR = $(TOP)/include
-OSMESA_LIBS = -L$(TOP)/$(LIB_DIR) -lOSMesa $(APP_LIB_DEPS)
+OSMESA_LIBS = -L$(TOP)/$(LIB_DIR) -l$(GLU_LIB) -l$(OSMESA_LIB) $(APP_LIB_DEPS)
-OSMESA16_LIBS = -L$(TOP)/$(LIB_DIR) -lglut -lOSMesa16 -lGLU -lGL $(APP_LIB_DEPS)
+OSMESA16_LIBS = -L$(TOP)/$(LIB_DIR) -l$(GLUT_LIB) -lOSMesa16 -l$(GLU_LIB) \
+ -l$(GL_LIB) $(APP_LIB_DEPS)
-OSMESA32_LIBS = -L$(TOP)/$(LIB_DIR) -lglut -lOSMesa32 -lGLU -lGL $(APP_LIB_DEPS)
+OSMESA32_LIBS = -L$(TOP)/$(LIB_DIR) -l$(GLUT_LIB) -lOSMesa32 -l$(GLU_LIB) \
+ -l$(GL_LIB) $(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 = \
osdemo \
@@ -26,7 +32,7 @@ PROGS = \
# make executable from .c file:
.c: $(LIB_DEP) readtex.o
- $(CC) -I$(INCDIR) $(CFLAGS) $< readtex.o $(APP_LIB_DEPS) -o $@
+ $(CC) -I$(INCDIR) $(CFLAGS) $(LDFLAGS) $< readtex.o $(LIBS) -o $@
##### TARGETS #####
@@ -56,19 +62,19 @@ showbuffer.o: showbuffer.c showbuffer.h
# special case: need the -lOSMesa library:
osdemo: osdemo.c
- $(CC) -I$(INCDIR) $(CFLAGS) osdemo.c $(OSMESA_LIBS) -o $@
+ $(CC) -I$(INCDIR) $(CFLAGS) $(LDFLAGS) osdemo.c $(OSMESA_LIBS) -o $@
# special case: need the -lOSMesa library:
ostest1: ostest1.c
- $(CC) -I$(INCDIR) $(CFLAGS) ostest1.c $(OSMESA_LIBS) -o $@
+ $(CC) -I$(INCDIR) $(CFLAGS) $(LDFLAGS) ostest1.c $(OSMESA_LIBS) -o $@
# another special case: need the -lOSMesa16 library:
osdemo16: osdemo16.c
- $(CC) -I$(INCDIR) $(CFLAGS) osdemo16.c $(OSMESA16_LIBS) -o $@
+ $(CC) -I$(INCDIR) $(CFLAGS) $(LDFLAGS) osdemo16.c $(OSMESA16_LIBS) -o $@
# another special case: need the -lOSMesa32 library:
osdemo32: osdemo32.c
- $(CC) -I$(INCDIR) $(CFLAGS) osdemo32.c $(OSMESA32_LIBS) -o $@
+ $(CC) -I$(INCDIR) $(CFLAGS) $(LDFLAGS) osdemo32.c $(OSMESA32_LIBS) -o $@
diff --git a/progs/osdemos/ostest1.c b/progs/osdemos/ostest1.c
index 2c7adfc..000b8c4 100644
--- a/progs/osdemos/ostest1.c
+++ b/progs/osdemos/ostest1.c
@@ -407,7 +407,10 @@ test(GLenum type, GLint bits, const char *filename)
glGetIntegerv(GL_ALPHA_BITS, &cBits);
assert(cBits == bits);
- printf("Rendering %d bit/channel image: %s\n", bits, filename);
+ if (WriteFiles)
+ printf("Rendering %d bit/channel image: %s\n", bits, filename);
+ else
+ printf("Rendering %d bit/channel image\n", bits);
OSMesaColorClamp(GL_TRUE);
@@ -458,6 +461,8 @@ main( int argc, char *argv[] )
{
int i;
+ printf("Use -f to write image files\n");
+
for (i = 1; i < argc; i++) {
if (strcmp(argv[i], "-f") == 0)
WriteFiles = GL_TRUE;
diff --git a/progs/redbook/Makefile b/progs/redbook/Makefile
index febc744..7ba676c 100644
--- a/progs/redbook/Makefile
+++ b/progs/redbook/Makefile
@@ -7,6 +7,8 @@ INCDIR = $(TOP)/include
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 = aaindex aapoly aargb accanti accpersp alpha alpha3D anti \
bezcurve bezmesh checker clip colormat cube depthcue dof \
double drawf feedback fog fogindex font hello image light \
@@ -24,7 +26,7 @@ PROGS = aaindex aapoly aargb accanti accpersp alpha alpha3D anti \
.SUFFIXES: .c
.c: $(LIB_DEP)
- $(CC) -I$(INCDIR) $(CFLAGS) $< $(APP_LIB_DEPS) -o $@
+ $(CC) -I$(INCDIR) $(CFLAGS) $(LDFLAGS) $< $(LIBS) -o $@
diff --git a/progs/samples/Makefile b/progs/samples/Makefile
index 063008d..6509a55 100644
--- a/progs/samples/Makefile
+++ b/progs/samples/Makefile
@@ -7,6 +7,8 @@ INCDIR = $(TOP)/include
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 = accum bitmap1 bitmap2 blendeq blendxor copy cursor depth eval fog \
font line logo nurb olympic overlay point prim quad select \
shape sphere star stencil stretch texture tri wave
@@ -18,7 +20,7 @@ PROGS = accum bitmap1 bitmap2 blendeq blendxor copy cursor depth eval fog \
.SUFFIXES: .c
.c: $(LIB_DEP)
- $(CC) -I$(INCDIR) $(CFLAGS) $< $(APP_LIB_DEPS) -o $@
+ $(CC) -I$(INCDIR) $(CFLAGS) $(LDFLAGS) $< $(LIBS) -o $@
##### TARGETS #####
@@ -27,7 +29,7 @@ default: $(PROGS)
sphere: sphere.o readtex.o
- $(CC) -I$(INCDIR) $(CFLAGS) sphere.o readtex.o $(APP_LIB_DEPS) -o $@
+ $(CC) -I$(INCDIR) $(CFLAGS) $(LDFLAGS) sphere.o readtex.o $(LIBS) -o $@
sphere.o: sphere.c readtex.h
$(CC) -c -I$(INCDIR) $(CFLAGS) sphere.c
diff --git a/progs/samples/Makefile.mgw b/progs/samples/Makefile.mgw
new file mode 100644
index 0000000..8bb975b
--- /dev/null
+++ b/progs/samples/Makefile.mgw
@@ -0,0 +1,78 @@
+# Mesa 3-D graphics library
+# Version: 4.0
+#
+# Copyright (C) 1999 Brian Paul All Rights Reserved.
+#
+# Permission is hereby granted, free of charge, to any person obtaining a
+# copy of this software and associated documentation files (the "Software"),
+# to deal in the Software without restriction, including without limitation
+# the rights to use, copy, modify, merge, publish, distribute, sublicense,
+# and/or sell copies of the Software, and to permit persons to whom the
+# Software is furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included
+# in all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+# BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+# MinGW samples makefile v1.2 for Mesa
+#
+# Copyright (C) 2002 - Daniel Borca
+# Email : dborca@users.sourceforge.net
+# Web : http://www.geocities.com/dborca
+
+# MinGW samples makefile updated for Mesa 7.0
+#
+# Updated : by Heromyth, on 2007-7-21
+# Email : zxpmyth@yahoo.com.cn
+# Bugs : 1) All the default settings work fine. But the setting X86=1 can't work.
+# The others havn't been tested yet.
+# 2) The generated DLLs are *not* compatible with the ones built
+# with the other compilers like VC8, especially for GLUT.
+# 3) Although more tests are needed, it can be used individually!
+
+#
+# Available options:
+#
+# Environment variables:
+#
+# Targets:
+# <file.exe> build a specific file
+#
+
+
+
+.PHONY: all
+.SUFFIXES: .c .o .exe
+.SECONDARY: ../util/readtex.o ../util/showbuffer.o
+
+TOP = ../..
+
+CC = mingw32-gcc
+CFLAGS = -Wall -pedantic
+CFLAGS += -O2 -ffast-math -D_DLL
+CFLAGS += -I$(TOP)/include -I../util
+ifeq ($(FX),1)
+ CFLAGS += -DFX
+endif
+
+CFLAGS += -DGLUT_DISABLE_ATEXIT_HACK
+
+LD = mingw32-g++
+LDFLAGS = -s -L$(TOP)/lib
+
+LDLIBS = -lglut32 -lglu32 -lopengl32
+
+.c.o:
+ $(CC) -o $@ $(CFLAGS) -c $<
+%.exe: ../util/readtex.o ../util/showbuffer.o %.o
+ $(LD) -o $@ $(LDFLAGS) $(LDLIBS) $^
+
+
+all:
+ $(error Must specify <filename.exe> to build)
diff --git a/progs/samples/blendeq.c b/progs/samples/blendeq.c
index f78afd3..d5143ec 100644
--- a/progs/samples/blendeq.c
+++ b/progs/samples/blendeq.c
@@ -25,6 +25,27 @@ static int doPrint = 1;
static int deltaY;
GLint windW, windH;
+static const struct {
+ GLenum mode;
+ const char *name;
+} LogicOpModes[] = {
+ { GL_SET, "GL_SET" },
+ { GL_COPY, "GL_COPY" },
+ { GL_NOOP, "GL_NOOP" },
+ { GL_AND, "GL_AND" },
+ { GL_INVERT, "GL_INVERT" },
+ { GL_OR, "GL_OR" },
+ { GL_XOR, "GL_XOR" },
+ { GL_NOR, "GL_NOR" },
+ { GL_NAND, "GL_NAND" },
+ { GL_OR_REVERSE, "GL_OR_REVERSE" },
+ { GL_OR_INVERTED, "GL_OR_INVERTED" },
+ { GL_AND_INVERTED, "GL_AND_INVERTED" },
+ { 0, NULL }
+};
+
+
+
static void DrawString(const char *string)
{
int i;
@@ -47,7 +68,7 @@ static void Reshape(int width, int height)
windH = (GLint)height;
glViewport(0, 0, (GLint)width, (GLint)height);
- deltaY = windH /16;
+ deltaY = windH /20;
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
@@ -105,7 +126,7 @@ static void Draw(void)
{
int stringOffset = 5, stringx = 8;
int x1, x2, xleft, xright;
- int i;
+ int i, k;
(dithering) ? glEnable(GL_DITHER) : glDisable(GL_DITHER);
glDisable(GL_BLEND);
@@ -122,6 +143,7 @@ static void Draw(void)
/* Draw labels */
glColor3f(0.8, 0.8, 0.0);
i = windH - deltaY + stringOffset;
+
glRasterPos2f(stringx, i); i -= deltaY;
DrawString("SOURCE");
glRasterPos2f(stringx, i); i -= deltaY;
@@ -136,21 +158,12 @@ static void Draw(void)
DrawString("reverse_subtract");
glRasterPos2f(stringx, i); i -= deltaY;
DrawString("clear");
- glRasterPos2f(stringx, i); i -= deltaY;
- DrawString("set");
- glRasterPos2f(stringx, i); i -= deltaY;
- DrawString("copy");
- glRasterPos2f(stringx, i); i -= deltaY;
- DrawString("noop");
- glRasterPos2f(stringx, i); i -= deltaY;
- DrawString("and");
- glRasterPos2f(stringx, i); i -= deltaY;
- DrawString("invert");
- glRasterPos2f(stringx, i); i -= deltaY;
- DrawString("or");
- glRasterPos2f(stringx, i); i -= deltaY;
- DrawString("xor");
+ for (k = 0; LogicOpModes[k].name; k++) {
+ glRasterPos2f(stringx, i);
+ i -= deltaY;
+ DrawString(LogicOpModes[k].name);
+ }
i = windH - deltaY;
x1 = windW/4;
@@ -193,43 +206,23 @@ static void Draw(void)
glLogicOp(GL_CLEAR);
glRectf(x1, i, x2, i+deltaY);
- i -= deltaY;
- glLogicOp(GL_SET);
- glRectf(x1, i, x2, i+deltaY);
-
- i -= deltaY;
- glLogicOp(GL_COPY);
- glRectf(x1, i, x2, i+deltaY);
-
- i -= deltaY;
- glLogicOp(GL_NOOP);
- glRectf(x1, i, x2, i+deltaY);
-
- i -= deltaY;
- glLogicOp(GL_AND);
- glRectf(x1, i, x2, i+deltaY);
-
- i -= deltaY;
- glLogicOp(GL_INVERT);
- glRectf(x1, i, x2, i+deltaY);
-
- i -= deltaY;
- glLogicOp(GL_OR);
- glRectf(x1, i, x2, i+deltaY);
-
- i -= deltaY;
- glLogicOp(GL_XOR);
- glRectf(x1, i, x2, i+deltaY);
- glRectf(x1, i+10, x2, i+5);
+ for (k = 0; LogicOpModes[k].name; k++) {
+ i -= deltaY;
+ glLogicOp(LogicOpModes[k].mode);
+ glRectf(x1, i, x2, i+deltaY);
+ if (LogicOpModes[k].mode == GL_XOR) {
+ glRectf(x1, i+10, x2, i+5);
+ }
+ }
- if (doPrint) {
- glDisable(GL_BLEND);
- if (supportlogops & 2)
+ if (doPrint) {
+ glDisable(GL_BLEND);
+ if (supportlogops & 2)
glDisable(GL_COLOR_LOGIC_OP);
- glColor3f(1.0, 1.0, 1.0);
- PrintColorStrings();
- }
- glFlush();
+ glColor3f(1.0, 1.0, 1.0);
+ PrintColorStrings();
+ }
+ glFlush();
if (doubleBuffer) {
glutSwapBuffers();
@@ -271,7 +264,7 @@ int main(int argc, char **argv)
exit(1);
}
- glutInitWindowPosition(0, 0); glutInitWindowSize( 800, 400);
+ glutInitWindowPosition(0, 0); glutInitWindowSize( 800, 520);
type = GLUT_RGB;
type |= (doubleBuffer) ? GLUT_DOUBLE : GLUT_SINGLE;
diff --git a/progs/slang/Makefile b/progs/slang/Makefile
index 1c602ce..f6f34fc 100644
--- a/progs/slang/Makefile
+++ b/progs/slang/Makefile
@@ -8,6 +8,8 @@ INCDIR = $(TOP)/include
LIB_DEP = $(TOP)/$(LIB_DIR)/$(GL_LIB_NAME)
+LIBS = -L$(TOP)/$(LIB_DIR) -l$(GLUT_LIB) -l$(GLU_LIB) -l$(GL_LIB) $(APP_LIB_DEPS)
+
#
# targets
#
@@ -22,34 +24,34 @@ tests: default
! ./cltest 2> /dev/null | (grep -e ^[*][*][*])
clean:
- rm -f cltest.o sotest.o vstest.o framework.o cltest sotest vstest
+ -rm -f cltest.o sotest.o vstest.o framework.o cltest sotest vstest
#
# executables
#
cltest: cltest.o framework.o $(LIB_DEP)
- $(CC) cltest.o framework.o $(APP_LIB_DEPS) -o cltest
+ $(CC) $(CFLAGS) $(LDFLAGS) cltest.o framework.o $(LIBS) -o cltest
sotest: sotest.o framework.o $(LIB_DEP)
- $(CC) sotest.o framework.o $(APP_LIB_DEPS) -o sotest
+ $(CC) $(CFLAGS) $(LDFLAGS) sotest.o framework.o $(LIBS) -o sotest
vstest: vstest.o framework.o $(LIB_DEP)
- $(CC) vstest.o framework.o $(APP_LIB_DEPS) -o vstest
+ $(CC) $(CFLAGS) $(LDFLAGS) vstest.o framework.o $(LIBS) -o vstest
#
# objects
#
framework.o: framework.c framework.h
- $(CC) -c -I$(INCDIR) framework.c -o framework.o
+ $(CC) -c -I$(INCDIR) $(CFLAGS) framework.c -o framework.o
cltest.o: cltest.c framework.h
- $(CC) -c -I$(INCDIR) cltest.c -o cltest.o
+ $(CC) -c -I$(INCDIR) $(CFLAGS) cltest.c -o cltest.o
sotest.o: sotest.c framework.h
- $(CC) -c -I$(INCDIR) sotest.c -o sotest.o
+ $(CC) -c -I$(INCDIR) $(CFLAGS) sotest.c -o sotest.o
vstest.o: vstest.c framework.h
- $(CC) -c -I$(INCDIR) vstest.c -o vstest.o
+ $(CC) -c -I$(INCDIR) $(CFLAGS) vstest.c -o vstest.o
diff --git a/progs/tests/.gitignore b/progs/tests/.gitignore
index 40cb685..c5b9e28 100644
--- a/progs/tests/.gitignore
+++ b/progs/tests/.gitignore
@@ -26,6 +26,7 @@ cva
dinoshade
drawbuffers
extfuncs.h
+exactrast
fbotest1
fbotest2
fbotexture
@@ -40,6 +41,7 @@ getproclist.h
interleave
invert
jkrahntest
+lineclip
manytex
minmag
mipmap_limits
@@ -56,6 +58,9 @@ readtex.c
readtex.h
seccolor
sharedtex
+shader_api
+stencil_twoside
+stencil_wrap
stencilwrap
stencil_wrap
subtex
@@ -69,6 +74,7 @@ texline
texobjshare
texrect
texwrap
+unfilledclip
vao-01
vao-02
vparray
diff --git a/progs/tests/Makefile b/progs/tests/Makefile
index 7e8c0c8..b111154 100644
--- a/progs/tests/Makefile
+++ b/progs/tests/Makefile
@@ -8,7 +8,7 @@ TOP = ../..
include $(TOP)/configs/current
-LIBS = $(APP_LIB_DEPS)
+LIBS = -L$(TOP)/$(LIB_DIR) -l$(GLUT_LIB) -l$(GLU_LIB) -l$(GL_LIB) $(APP_LIB_DEPS)
SOURCES = \
afsmultiarb.c \
@@ -37,6 +37,7 @@ SOURCES = \
cva.c \
dinoshade.c \
drawbuffers.c \
+ exactrast.c \
floattex.c \
fbotest1.c \
fbotest2.c \
@@ -50,6 +51,7 @@ SOURCES = \
interleave.c \
invert.c \
jkrahntest.c \
+ lineclip.c \
manytex.c \
minmag.c \
mipmap_limits.c \
@@ -63,7 +65,9 @@ SOURCES = \
random.c \
readrate.c \
seccolor.c \
+ shader_api.c \
sharedtex.c \
+ stencil_twoside.c \
stencilwrap.c \
stencil_wrap.c \
subtex \
@@ -75,6 +79,7 @@ SOURCES = \
texobjshare.c \
texrect.c \
texwrap.c \
+ unfilledclip.c \
vao-01.c \
vao-02.c \
vparray.c \
@@ -96,13 +101,22 @@ INCLUDES = -I. -I$(TOP)/include
UTIL_FILES = readtex.h readtex.c
+##### TARGETS #####
+
+default: $(UTIL_FILES) $(PROGS)
+
+clean:
+ -rm -f $(PROGS)
+ -rm -f *.o
+ -rm -f getproclist.h
+
##### RULES #####
.SUFFIXES:
.SUFFIXES: .c
.c:
- $(CC) $(INCLUDES) $(CFLAGS) $< $(LIBS) -o $@
+ $(CC) $(INCLUDES) $(CFLAGS) $(LDFLAGS) $< $(LIBS) -o $@
.c.o:
$(CC) -c $(INCLUDES) $(CFLAGS) $(DEFINES) $< -o $@
@@ -110,17 +124,6 @@ UTIL_FILES = readtex.h readtex.c
.S.o:
$(CC) -c $(INCLUDES) $(CFLAGS) $(DEFINES) $< -o $@
-
-##### TARGETS #####
-
-default: $(UTIL_FILES) $(PROGS)
-
-clean:
- rm -f $(PROGS)
- rm -f *.o
- rm -f getproclist.h
-
-
# auto code generation
getprocaddress: getprocaddress.c getproclist.h
@@ -131,37 +134,37 @@ arraytexture: arraytexture.o readtex.o
$(CC) $(CFLAGS) arraytexture.o readtex.o $(LIBS) -o $@
arraytexture.o: arraytexture.c readtex.h
- $(CC) -c $(INCLUDES) $(CFLAGS) $(DEFINES) $< -o $@
+ $(CC) -c $(INCLUDES) $(CFLAGS) $(DEFINES) arraytexture.c -o $@
afsmultiarb: afsmultiarb.o readtex.o
- $(CC) $(CFLAGS) afsmultiarb.o readtex.o $(LIBS) -o $@
+ $(CC) $(CFLAGS) $(LDFLAGS) afsmultiarb.o readtex.o $(LIBS) -o $@
afsmultiarb.o: afsmultiarb.c readtex.h
- $(CC) -c $(INCLUDES) $(CFLAGS) $(DEFINES) $< -o $@
+ $(CC) -c $(INCLUDES) $(CFLAGS) $(DEFINES) afsmultiarb.c -o $@
drawbuffers: drawbuffers.o
- $(CC) $(CFLAGS) drawbuffers.o $(LIBS) -o $@
+ $(CC) $(CFLAGS) $(LDFLAGS) drawbuffers.o $(LIBS) -o $@
drawbuffers.o: drawbuffers.c extfuncs.h
- $(CC) -c $(INCLUDES) $(CFLAGS) $(DEFINES) $< -o $@
+ $(CC) -c $(INCLUDES) $(CFLAGS) $(DEFINES) drawbuffers.c -o $@
texrect: texrect.o readtex.o
- $(CC) $(CFLAGS) texrect.o readtex.o $(LIBS) -o $@
+ $(CC) $(CFLAGS) $(LDFLAGS) texrect.o readtex.o $(LIBS) -o $@
texrect.o: texrect.c readtex.h
- $(CC) -c $(INCLUDES) $(CFLAGS) $(DEFINES) $< -o $@
+ $(CC) -c $(INCLUDES) $(CFLAGS) $(DEFINES) texrect.c -o $@
bug_3195: bug_3195.o readtex.o
- $(CC) $(CFLAGS) bug_3195.o readtex.o $(LIBS) -o $@
+ $(CC) $(CFLAGS) $(LDFLAGS) bug_3195.o readtex.o $(LIBS) -o $@
bug_3195.o: bug_3195.c readtex.h
- $(CC) -c $(INCLUDES) $(CFLAGS) $(DEFINES) $< -o $@
+ $(CC) -c $(INCLUDES) $(CFLAGS) $(DEFINES) bug_3195.c -o $@
invert: invert.o readtex.o
- $(CC) $(CFLAGS) invert.o readtex.o $(LIBS) -o $@
+ $(CC) $(CFLAGS) $(LDFLAGS) invert.o readtex.o $(LIBS) -o $@
invert.o: invert.c readtex.h
- $(CC) -c $(INCLUDES) $(CFLAGS) $(DEFINES) $< -o $@
+ $(CC) -c $(INCLUDES) $(CFLAGS) $(DEFINES) invert.c -o $@
mipmap_view: mipmap_view.o readtex.o
$(CC) $(CFLAGS) mipmap_view.o readtex.o $(LIBS) -o $@
@@ -179,7 +182,7 @@ fillrate.o: fillrate.c readtex.h
readtex.o: readtex.c
- $(CC) -c $(INCLUDES) $(CFLAGS) $(DEFINES) $< -o $@
+ $(CC) -c $(INCLUDES) $(CFLAGS) $(DEFINES) readtex.c -o $@
readtex.h: $(TOP)/progs/util/readtex.h
diff --git a/progs/tests/antialias.c b/progs/tests/antialias.c
index 3a83c34..f23b5af 100644
--- a/progs/tests/antialias.c
+++ b/progs/tests/antialias.c
@@ -15,6 +15,7 @@
static GLfloat Zrot = 0;
static GLboolean Anim = GL_TRUE;
static GLboolean HaveMultisample = GL_TRUE;
+static GLboolean DoMultisample = GL_TRUE;
static void
@@ -85,7 +86,10 @@ Display( void )
glColor3f(1, 1, 1);
if (HaveMultisample) {
glRasterPos2f(-3.1, -1.6);
- PrintString("MULTISAMPLE");
+ if (DoMultisample)
+ PrintString("MULTISAMPLE");
+ else
+ PrintString("MULTISAMPLE (off)");
}
glRasterPos2f(-0.8, -1.6);
PrintString("No antialiasing");
@@ -95,7 +99,8 @@ Display( void )
/* multisample */
if (HaveMultisample) {
glEnable(GL_DEPTH_TEST);
- glEnable(GL_MULTISAMPLE_ARB);
+ if (DoMultisample)
+ glEnable(GL_MULTISAMPLE_ARB);
glPushMatrix();
glTranslatef(-2.5, 0, 0);
glPushMatrix();
@@ -172,6 +177,9 @@ Key( unsigned char key, int x, int y )
else
glutIdleFunc(NULL);
break;
+ case 'm':
+ DoMultisample = !DoMultisample;
+ break;
case 'z':
Zrot = (int) (Zrot - step);
break;
diff --git a/progs/tests/cva.c b/progs/tests/cva.c
index a47b2a9..a9393ae 100644
--- a/progs/tests/cva.c
+++ b/progs/tests/cva.c
@@ -10,17 +10,13 @@
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
-#ifdef __VMS
-# include <stddef.h> /* for ptrdiff_t, referenced by GL.h when GL_GLEXT_LEGACY defined */
-#else
-# include <malloc.h> /* for ptrdiff_t, referenced by GL.h when GL_GLEXT_LEGACY defined */
-#endif
+#include <stddef.h> /* for ptrdiff_t, referenced by GL.h when GL_GLEXT_LEGACY defined */
#ifdef _WIN32
#include <windows.h>
#endif
#define GL_GLEXT_LEGACY
#include <GL/glut.h>
-
+#include <GL/glext.h>
GLfloat verts[][4] = {
{ -0.5, -0.5, -2.0, 0.0 },
diff --git a/progs/tests/dinoshade.c b/progs/tests/dinoshade.c
index ed7b879..504b4af 100644
--- a/progs/tests/dinoshade.c
+++ b/progs/tests/dinoshade.c
@@ -38,11 +38,7 @@
#include <stdlib.h>
#include <string.h>
#include <math.h> /* for cos(), sin(), and sqrt() */
-#ifdef __VMS
-# include <stddef.h> /* for ptrdiff_t, referenced by GL.h when GL_GLEXT_LEGACY defined */
-#else
-# include <malloc.h> /* for ptrdiff_t, referenced by GL.h when GL_GLEXT_LEGACY defined */
-#endif
+#include <stddef.h> /* for ptrdiff_t, referenced by GL.h when GL_GLEXT_LEGACY defined */
#ifdef _WIN32
#include <windows.h>
#endif
diff --git a/progs/tests/exactrast.c b/progs/tests/exactrast.c
new file mode 100644
index 0000000..56c0c79
--- /dev/null
+++ b/progs/tests/exactrast.c
@@ -0,0 +1,200 @@
+/**
+ * Test for exact point/line/polygon rasterization, or at least rasterization
+ * that fits the tolerance of the OpenGL spec.
+ *
+ * Brian Paul
+ * 9 Nov 2007
+ */
+
+/*
+ * Notes:
+ * - 'm' to cycle through point, hline, vline and quad drawing
+ * - Use cursor keys to translate coordinates (z to reset)
+ * - Resize window to check for proper rasterization
+ * - Make sure your LCD is running in its native resolution
+ *
+ * If translation is (0,0):
+ * a point will be drawn where x%2==0 and y%2==0,
+ * a horizontal line will be drawn where x%2==0,
+ * a vertical line will be drawn where y%2==0,
+ * for quads, pixels will be set where (x%4)!=3 and (y%4)!=3
+ *
+ * XXX todo: do glReadPixels and test that the results are what's expected.
+ * Upon failure, iterate over sub-pixel translations to find the ideal offset.
+ */
+
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <GL/glut.h>
+
+static int Width = 400, Height = 400;
+static int Win;
+static float Xtrans = 0, Ytrans = 0;
+static float Step = 0.125;
+
+enum {
+ POINTS,
+ HLINES,
+ VLINES,
+ QUADS,
+ NUM_MODES
+};
+
+static int Mode = POINTS;
+
+
+static void
+Draw(void)
+{
+ /* See the OpenGL Programming Guide, Appendix H, "OpenGL Correctness Tips"
+ * for information about the 0.375 translation factor.
+ */
+ float tx = 0.375, ty = 0.375;
+ int i, j;
+
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+
+ glPushMatrix();
+ glTranslatef(tx + Xtrans, ty + Ytrans, 0);
+
+ if (Mode == POINTS) {
+ glBegin(GL_POINTS);
+ for (j = 0; j < Height; j += 2) {
+ for (i = 0; i < Width; i += 2) {
+ glVertex2f(i, j);
+ }
+ }
+ glEnd();
+ }
+ else if (Mode == HLINES) {
+ glBegin(GL_LINES);
+ for (i = 0; i < Height; i += 2) {
+ glVertex2f(0, i);
+ glVertex2f(Width, i);
+ }
+ glEnd();
+ }
+ else if (Mode == VLINES) {
+ glBegin(GL_LINES);
+ for (i = 0; i < Width; i += 2) {
+ glVertex2f(i, 0 );
+ glVertex2f(i, Height);
+ }
+ glEnd();
+ }
+ else if (Mode == QUADS) {
+ glBegin(GL_QUADS);
+ for (j = 0; j < Height; j += 4) {
+ for (i = 0; i < Width; i += 4) {
+ glVertex2f(i, j );
+ glVertex2f(i + 3, j );
+ glVertex2f(i + 3, j + 3);
+ glVertex2f(i, j + 3);
+ }
+ }
+ glEnd();
+ }
+
+ glPopMatrix();
+
+ glutSwapBuffers();
+}
+
+
+static void
+Reshape(int width, int height)
+{
+ Width = width;
+ Height = height;
+ glViewport(0, 0, width, height);
+ glMatrixMode(GL_PROJECTION);
+ glLoadIdentity();
+ glOrtho(0, width, 0, height, -1, 1);
+ glMatrixMode(GL_MODELVIEW);
+ glLoadIdentity();
+}
+
+
+static void
+Key(unsigned char key, int x, int y)
+{
+ (void) x;
+ (void) y;
+ switch (key) {
+ case 'm':
+ case 'M':
+ Mode = (Mode + 1) % NUM_MODES;
+ break;
+ case 'z':
+ case 'Z':
+ Xtrans = Ytrans = 0;
+ printf("Translation: %f, %f\n", Xtrans, Ytrans);
+ break;
+ case 27:
+ glutDestroyWindow(Win);
+ exit(0);
+ break;
+ }
+ glutPostRedisplay();
+}
+
+
+static void
+SpecialKey(int key, int x, int y)
+{
+ (void) x;
+ (void) y;
+ switch (key) {
+ case GLUT_KEY_UP:
+ Ytrans += Step;
+ break;
+ case GLUT_KEY_DOWN:
+ Ytrans -= Step;
+ break;
+ case GLUT_KEY_LEFT:
+ Xtrans -= Step;
+ break;
+ case GLUT_KEY_RIGHT:
+ Xtrans += Step;
+ break;
+ }
+ glutPostRedisplay();
+ printf("Translation: %f, %f\n", Xtrans, Ytrans);
+}
+
+
+static void
+Init(void)
+{
+}
+
+
+static void
+Usage(void)
+{
+ printf("Keys:\n");
+ printf(" up/down/left/right - translate by %f\n", Step);
+ printf(" z - reset translation to zero\n");
+ printf(" m - change rendering mode (points, hlines, vlines, quads)\n");
+ printf(" Esc - exit\n");
+}
+
+
+int
+main(int argc, char *argv[])
+{
+ glutInit(&argc, argv);
+ glutInitWindowPosition(0, 0);
+ glutInitWindowSize(Width, Height);
+ glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE);
+ Win = glutCreateWindow(argv[0]);
+ glutReshapeFunc(Reshape);
+ glutKeyboardFunc(Key);
+ glutSpecialFunc(SpecialKey);
+ glutDisplayFunc(Draw);
+ Init();
+ Usage();
+ glutMainLoop();
+ return 0;
+}
diff --git a/progs/tests/fbotexture.c b/progs/tests/fbotexture.c
index aa9f617..88d0549 100644
--- a/progs/tests/fbotexture.c
+++ b/progs/tests/fbotexture.c
@@ -38,6 +38,8 @@ static GLfloat Rot = 0.0;
static GLboolean UsePackedDepthStencil = GL_FALSE;
static GLuint TextureLevel = 1; /* which texture level to render to */
static GLenum TexIntFormat = GL_RGB; /* either GL_RGB or GL_RGBA */
+static GLboolean Cull = GL_FALSE;
+static GLboolean Wireframe = GL_FALSE;
static void
@@ -115,6 +117,22 @@ RenderTexture(void)
CheckError(__LINE__);
+ if (Wireframe) {
+ glPolygonMode(GL_FRONT, GL_LINE);
+ }
+ else {
+ glPolygonMode(GL_FRONT, GL_FILL);
+ }
+
+ if (Cull) {
+ /* cull back */
+ glCullFace(GL_BACK);
+ glEnable(GL_CULL_FACE);
+ }
+ else {
+ glDisable(GL_CULL_FACE);
+ }
+
#if 0
glBegin(GL_POLYGON);
glColor3f(1, 0, 0);
@@ -129,7 +147,9 @@ RenderTexture(void)
glEnable(GL_LIGHT0);
glPushMatrix();
glRotatef(0.5 * Rot, 1.0, 0.0, 0.0);
+ glFrontFace(GL_CW); /* Teapot patches backward */
glutSolidTeapot(0.5);
+ glFrontFace(GL_CCW);
glPopMatrix();
glDisable(GL_LIGHTING);
/*
@@ -139,6 +159,8 @@ RenderTexture(void)
glDisable(GL_DEPTH_TEST);
glDisable(GL_STENCIL_TEST);
+ glDisable(GL_CULL_FACE);
+ glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
#if DRAW
/* Bind normal framebuffer */
@@ -245,25 +267,46 @@ Key(unsigned char key, int x, int y)
(void) x;
(void) y;
switch (key) {
- case 'a':
- Anim = !Anim;
- if (Anim)
- glutIdleFunc(Idle);
- else
- glutIdleFunc(NULL);
- break;
- case 's':
- Rot += 2.0;
- break;
- case 27:
- CleanUp();
- break;
+ case 'a':
+ Anim = !Anim;
+ if (Anim)
+ glutIdleFunc(Idle);
+ else
+ glutIdleFunc(NULL);
+ break;
+ case 'c':
+ Cull = !Cull;
+ break;
+ case 'w':
+ Wireframe = !Wireframe;
+ break;
+ case 's':
+ Rot += 2.0;
+ break;
+ case 'S':
+ Rot -= 2.0;
+ break;
+ case 27:
+ CleanUp();
+ break;
}
glutPostRedisplay();
}
static void
+Usage(void)
+{
+ printf("Usage:\n");
+ printf(" a Toggle animation\n");
+ printf(" s/s Step/rotate\n");
+ printf(" c Toggle back-face culling\n");
+ printf(" w Toggle wireframe mode (front-face only)\n");
+ printf(" Esc Exit\n");
+}
+
+
+static void
Init(int argc, char *argv[])
{
static const GLfloat mat[4] = { 1.0, 0.5, 0.5, 1.0 };
@@ -402,6 +445,7 @@ main(int argc, char *argv[])
if (Anim)
glutIdleFunc(Idle);
Init(argc, argv);
+ Usage();
glutMainLoop();
return 0;
}
diff --git a/progs/tests/lineclip.c b/progs/tests/lineclip.c
new file mode 100644
index 0000000..098f5e9
--- /dev/null
+++ b/progs/tests/lineclip.c
@@ -0,0 +1,175 @@
+/*
+ * Copyright © 2008 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ * Authors:
+ * Eric Anholt <eric@anholt.net>
+ *
+ */
+
+#include <stdlib.h>
+#include <GL/glut.h>
+
+static int win_width, win_height;
+
+static void
+line(GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2)
+{
+ glBegin(GL_LINES);
+ glVertex2f(x1, y1);
+ glVertex2f(x2, y2);
+ glEnd();
+}
+
+static void
+line3(GLfloat x1, GLfloat y1, GLfloat z1, GLfloat x2, GLfloat y2, GLfloat z2)
+{
+ glBegin(GL_LINES);
+ glVertex3f(x1, y1, z1);
+ glVertex3f(x2, y2, z2);
+ glEnd();
+}
+
+static void
+display(void)
+{
+ glClearColor(0.0, 0.0, 0.0, 0.0);
+ glClear(GL_COLOR_BUFFER_BIT);
+
+ glColor3f(1.0, 0.0, 0.0);
+ /* 2 lines clipped along xmin */
+ line(-20, win_height / 2 - 20,
+ 20, win_height / 2 - 20);
+ line( 20, win_height / 2 + 20,
+ -20, win_height / 2 + 20);
+
+ glColor3f(0.0, 1.0, 0.0);
+ /* 2 lines clipped along ymax */
+ line(win_width / 2 - 20, win_height + 20,
+ win_width / 2 - 20, win_height - 20);
+ line(win_width / 2 + 20, win_height - 20,
+ win_width / 2 + 20, win_height + 20);
+
+ glColor3f(0.0, 0.0, 1.0);
+ /* 2 lines clipped along xmax */
+ line(win_width - 20, win_height / 2 - 20,
+ win_width + 20, win_height / 2 - 20);
+ line(win_width + 20, win_height / 2 + 20,
+ win_width - 20, win_height / 2 + 20);
+
+ glColor3f(1.0, 1.0, 1.0);
+ /* 2 lines clipped along ymin */
+ line(win_width / 2 - 20, 20,
+ win_width / 2 - 20, -20);
+ line(win_width / 2 + 20, -20,
+ win_width / 2 + 20, 20);
+
+ /* 2 lines clipped along near */
+ glColor3f(1.0, 0.0, 1.0);
+ line3(win_width / 2 - 20 - 20, win_height / 2, 0.5,
+ win_width / 2 - 20 + 20, win_height / 2, -0.5);
+ line3(win_width / 2 - 20, win_height / 2 - 20, -0.5,
+ win_width / 2 - 20, win_height / 2 + 20, 0.5);
+
+ /* 2 lines clipped along far */
+ glColor3f(0.0, 1.0, 1.0);
+ line3(win_width / 2 + 20 - 20, win_height / 2, 1.5,
+ win_width / 2 + 20 + 20, win_height / 2, 0.5);
+ line3(win_width / 2 + 20, win_height / 2 - 20, 0.5,
+ win_width / 2 + 20, win_height / 2 + 20, 1.5);
+
+ /* entirely clipped along near/far */
+ glColor3f(.5, .5, .5);
+ line3(win_width / 2, win_height / 2 - 20, -0.5,
+ win_width / 2, win_height / 2 + 20, -0.5);
+ glColor3f(.5, .5, .5);
+ line3(win_width / 2, win_height / 2 - 20, 1.5,
+ win_width / 2, win_height / 2 + 20, 1.5);
+
+ glColor3f(1.0, 1.0, 0.0);
+ /* lines clipped along both x and y limits */
+ line(-5, 20,
+ 20, -5); /* xmin, ymin */
+ line(-5, win_height - 20,
+ 20, win_height + 5); /* xmin, ymax */
+ line(win_width - 20, -5,
+ win_width + 5, 20); /* xmax, ymin */
+ line(win_width - 20, win_height + 5,
+ win_width + 5, win_height - 20); /* xmax, ymax */
+
+ glutSwapBuffers();
+}
+
+static void
+reshape(int width, int height)
+{
+ win_width = width;
+ win_height = height;
+ glViewport(0, 0, width, height);
+
+ glMatrixMode(GL_PROJECTION);
+ glLoadIdentity();
+ glOrtho(0, win_width, 0, win_height, 0.0, -1.0);
+
+ glMatrixMode(GL_MODELVIEW);
+ glLoadIdentity();
+ glTranslatef(.25, .25, 0);
+}
+
+static void key( unsigned char key, int x, int y )
+{
+ (void) x;
+ (void) y;
+
+ switch (key) {
+ case 27: /* esc */
+ exit(0);
+ break;
+ }
+
+ glutPostRedisplay();
+}
+
+static void
+init(void)
+{
+}
+
+int
+main(int argc, char *argv[])
+{
+ win_width = 200;
+ win_height = 200;
+
+ glutInit(&argc, argv);
+ glutInitWindowPosition(0, 0);
+ glutInitWindowSize(win_width, win_height);
+ glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
+ glutCreateWindow(argv[0]);
+ glutReshapeFunc(reshape);
+ glutKeyboardFunc(key);
+ glutDisplayFunc(display);
+
+ init();
+
+ glutMainLoop();
+ return 0;
+}
diff --git a/progs/tests/multipal.c b/progs/tests/multipal.c
index 52818fc..7bd4473 100644
--- a/progs/tests/multipal.c
+++ b/progs/tests/multipal.c
@@ -8,11 +8,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
-#ifdef __VMS
-# include <stddef.h> /* for ptrdiff_t, referenced by GL.h when GL_GLEXT_LEGACY defined */
-#else
-# include <malloc.h> /* for ptrdiff_t, referenced by GL.h when GL_GLEXT_LEGACY defined */
-#endif
+#include <stddef.h> /* for ptrdiff_t, referenced by GL.h when GL_GLEXT_LEGACY defined */
#ifdef _WIN32
#include <windows.h>
#endif
diff --git a/progs/tests/shader_api.c b/progs/tests/shader_api.c
new file mode 100644
index 0000000..598f029
--- /dev/null
+++ b/progs/tests/shader_api.c
@@ -0,0 +1,337 @@
+/* Tests to validate fixes to various bugs in src/mesa/shader/shader_api.c
+ *
+ * Written by Bruce Merry
+ */
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+#define GL_GLEXT_PROTOTYPES
+#include <GL/glut.h>
+
+static void assert_test(const char *file, int line, int cond, const char *msg)
+{
+ if (!cond)
+ fprintf(stderr, "%s:%d assertion \"%s\" failed\n", file, line, msg);
+}
+
+#undef assert
+#define assert(x) assert_test(__FILE__, __LINE__, (x), #x)
+
+static void assert_no_error_test(const char *file, int line)
+{
+ GLenum err;
+
+ err = glGetError();
+ if (err != GL_NO_ERROR)
+ fprintf(stderr, "%s:%d received error %s\n",
+ file, line, gluErrorString(err));
+}
+
+#define assert_no_error() assert_no_error_test(__FILE__, __LINE__)
+
+static void assert_error_test(const char *file, int line, GLenum expect)
+{
+ GLenum err;
+
+ err = glGetError();
+ if (err != expect)
+ fprintf(stderr, "%s:%d expected %s but received %s\n",
+ file, line, gluErrorString(expect), gluErrorString(err));
+ while (glGetError()); /* consume any following errors */
+}
+
+#define assert_error(err) assert_error_test(__FILE__, __LINE__, (err))
+
+static void check_status(GLuint id, GLenum pname, void (*query)(GLuint, GLenum, GLint *))
+{
+ GLint status;
+
+ query(id, pname, &status);
+ if (!status)
+ {
+ char info[65536];
+
+ fprintf(stderr, "Compilation/link failure:\n");
+ glGetInfoLogARB(id, sizeof(info), NULL, info);
+ fprintf(stderr, "%s\n", info);
+ exit(1);
+ }
+}
+
+static void check_compile_status(GLuint id)
+{
+ check_status(id, GL_COMPILE_STATUS, glGetShaderiv);
+}
+
+static void check_link_status(GLuint id)
+{
+ check_status(id, GL_LINK_STATUS, glGetProgramiv);
+}
+
+static GLuint make_shader(GLenum type, const char *src)
+{
+ GLuint id;
+
+ assert_no_error();
+ id = glCreateShader(type);
+ glShaderSource(id, 1, &src, NULL);
+ glCompileShader(id);
+ check_compile_status(id);
+ assert_no_error();
+ return id;
+}
+
+static GLuint make_program(const char *vs_src, const char *fs_src)
+{
+ GLuint id, vs, fs;
+
+ assert_no_error();
+ id = glCreateProgram();
+ if (vs_src) {
+ vs = make_shader(GL_VERTEX_SHADER, vs_src);
+ glAttachShader(id, vs);
+ glDeleteShader(vs);
+ }
+ if (fs_src) {
+ fs = make_shader(GL_FRAGMENT_SHADER, fs_src);
+ glAttachShader(id, fs);
+ glDeleteShader(fs);
+ }
+ glLinkProgram(id);
+ check_link_status(id);
+ glUseProgram(id);
+ glDeleteProgram(id);
+ assert_no_error();
+ return id;
+}
+
+static void test_uniform_size_type1(const char *glslType, GLenum glType, const char *el)
+{
+ char buffer[1024];
+ GLuint program;
+ GLint active, i;
+ GLenum type;
+ GLint size;
+
+ printf(" Running subtest %s\n", glslType); fflush(stdout);
+ sprintf(buffer, "#version 120\nuniform %s m[60];\nvoid main() { gl_Position[0] = m[59]%s; }\n",
+ glslType, el);
+
+ program = make_program(buffer, NULL);
+ glGetProgramiv(program, GL_ACTIVE_UNIFORMS, &active);
+ assert_no_error();
+ for (i = 0; i < active; i++) {
+ size = -1;
+ type = 0;
+ glGetActiveUniform(program, i, sizeof(buffer), NULL, &size, &type, buffer);
+ assert_no_error();
+ if (strncmp(buffer, "m", 1) == 0)
+ break;
+ }
+ assert(i < active); /* Otherwise the compiler optimised it out */
+ assert(type == glType);
+ assert(size == 60);
+}
+
+static void test_uniform_size_type(void)
+{
+ test_uniform_size_type1("float", GL_FLOAT, "");
+ test_uniform_size_type1("vec2", GL_FLOAT_VEC2, "[0]");
+ test_uniform_size_type1("vec3", GL_FLOAT_VEC3, "[0]");
+ test_uniform_size_type1("vec4", GL_FLOAT_VEC4, "[0]");
+
+ test_uniform_size_type1("bool", GL_BOOL, " ? 1.0 : 0.0");
+ test_uniform_size_type1("bvec2", GL_BOOL_VEC2, "[0] ? 1.0 : 0.0");
+ test_uniform_size_type1("bvec3", GL_BOOL_VEC3, "[0] ? 1.0 : 0.0");
+ test_uniform_size_type1("bvec4", GL_BOOL_VEC4, "[0] ? 1.0 : 0.0");
+
+ test_uniform_size_type1("int", GL_INT, "");
+ test_uniform_size_type1("ivec2", GL_INT_VEC2, "[0]");
+ test_uniform_size_type1("ivec3", GL_INT_VEC3, "[0]");
+ test_uniform_size_type1("ivec4", GL_INT_VEC4, "[0]");
+
+ test_uniform_size_type1("mat2", GL_FLOAT_MAT2, "[0][0]");
+ test_uniform_size_type1("mat3", GL_FLOAT_MAT3, "[0][0]");
+ test_uniform_size_type1("mat4", GL_FLOAT_MAT4, "[0][0]");
+ test_uniform_size_type1("mat2x3", GL_FLOAT_MAT2x3, "[0][0]");
+ test_uniform_size_type1("mat2x4", GL_FLOAT_MAT2x4, "[0][0]");
+ test_uniform_size_type1("mat3x2", GL_FLOAT_MAT3x2, "[0][0]");
+ test_uniform_size_type1("mat3x4", GL_FLOAT_MAT3x4, "[0][0]");
+ test_uniform_size_type1("mat4x2", GL_FLOAT_MAT4x2, "[0][0]");
+ test_uniform_size_type1("mat4x3", GL_FLOAT_MAT4x3, "[0][0]");
+}
+
+static void test_attrib_size_type1(const char *glslType, GLenum glType, const char *el)
+{
+ char buffer[1024];
+ GLuint program;
+ GLint active, i;
+ GLenum type;
+ GLint size;
+
+ printf(" Running subtest %s\n", glslType); fflush(stdout);
+ sprintf(buffer, "#version 120\nattribute %s m;\nvoid main() { gl_Position[0] = m%s; }\n",
+ glslType, el);
+
+ program = make_program(buffer, NULL);
+ glGetProgramiv(program, GL_ACTIVE_ATTRIBUTES, &active);
+ assert_no_error();
+ for (i = 0; i < active; i++) {
+ size = -1;
+ type = -1;
+ glGetActiveAttrib(program, i, sizeof(buffer), NULL, &size, &type, buffer);
+ assert_no_error();
+ if (strncmp(buffer, "m", 1) == 0)
+ break;
+ }
+ assert(i < active); /* Otherwise the compiler optimised it out */
+ assert(type == glType);
+ assert(size == 1);
+}
+
+static void test_attrib_size_type(void)
+{
+ test_attrib_size_type1("float", GL_FLOAT, "");
+ test_attrib_size_type1("vec2", GL_FLOAT_VEC2, "[0]");
+ test_attrib_size_type1("vec3", GL_FLOAT_VEC3, "[0]");
+ test_attrib_size_type1("vec4", GL_FLOAT_VEC4, "[0]");
+
+ test_attrib_size_type1("mat2", GL_FLOAT_MAT2, "[0][0]");
+ test_attrib_size_type1("mat3", GL_FLOAT_MAT3, "[0][0]");
+ test_attrib_size_type1("mat4", GL_FLOAT_MAT4, "[0][0]");
+ test_attrib_size_type1("mat2x3", GL_FLOAT_MAT2x3, "[0][0]");
+ test_attrib_size_type1("mat2x4", GL_FLOAT_MAT2x4, "[0][0]");
+ test_attrib_size_type1("mat3x2", GL_FLOAT_MAT3x2, "[0][0]");
+ test_attrib_size_type1("mat3x4", GL_FLOAT_MAT3x4, "[0][0]");
+ test_attrib_size_type1("mat4x2", GL_FLOAT_MAT4x2, "[0][0]");
+ test_attrib_size_type1("mat4x3", GL_FLOAT_MAT4x3, "[0][0]");
+}
+
+static void test_uniform_array_overflow(void)
+{
+ GLuint program;
+ GLint location;
+ GLfloat data[128];
+
+ program = make_program("#version 120\nuniform vec2 x[10];\nvoid main() { gl_Position.xy = x[9]; }\n", NULL);
+ location = glGetUniformLocation(program, "x");
+ assert_no_error();
+ glUniform2fv(location, 64, data);
+ assert_no_error();
+}
+
+static void test_uniform_scalar_count(void)
+{
+ GLuint program;
+ GLint location;
+ GLfloat data[128];
+
+ program = make_program("#version 110\nuniform vec2 x;\nvoid main() { gl_Position.xy = x; }\n", NULL);
+ location = glGetUniformLocation(program, "x");
+ assert_no_error();
+ glUniform2fv(location, 64, data);
+ assert_error(GL_INVALID_OPERATION);
+}
+
+static void test_uniform_query_matrix(void)
+{
+ GLuint program;
+ GLfloat data[18];
+ GLint i, r, c;
+ GLint location;
+
+ program = make_program("#version 110\nuniform mat3 m[2];\nvoid main() { gl_Position.xyz = m[1][2]; }\n", NULL);
+ location = glGetUniformLocation(program, "m");
+ for (i = 0; i < 9; i++)
+ data[i] = i;
+ for (i = 9; i < 18; i++)
+ data[i] = 321.0;
+ glUniformMatrix3fv(location, 1, GL_TRUE, data);
+
+ for (i = 0; i < 18; i++)
+ data[i] = 123.0;
+ glGetUniformfv(program, location, data);
+ for (c = 0; c < 3; c++)
+ for (r = 0; r < 3; r++)
+ assert(data[c * 3 + r] == r * 3 + c);
+ for (i = 9; i < 18; i++)
+ assert(data[i] == 123.0);
+}
+
+static void test_uniform_neg_location(void)
+{
+ GLuint program;
+ GLfloat data[4];
+
+ program = make_program("#version 110\nvoid main() { gl_Position = vec4(1.0, 1.0, 1.0, 1.0); }\n", NULL);
+ assert_no_error();
+ glUniform1i(-1, 1);
+ assert_no_error();
+ glUniform1i(-200, 1);
+ assert_error(GL_INVALID_OPERATION);
+ glUniformMatrix2fv(-1, 1, GL_FALSE, data);
+ assert_no_error();
+ glUniformMatrix2fv(-200, 1, GL_FALSE, data);
+ assert_error(GL_INVALID_OPERATION);
+}
+
+static void test_uniform_bool_conversion(void)
+{
+ GLuint program;
+ GLint location;
+ GLint value[16]; /* in case glGetUniformiv goes nuts on the stack */
+
+ assert_no_error();
+ program = make_program("uniform bool b;\nvoid main() { gl_Position.x = b ? 1.5 : 0.5; }\n", NULL);
+ location = glGetUniformLocation(program, "b");
+ assert(location != -1);
+ assert_no_error();
+ glUniform1i(location, 5);
+ assert_no_error();
+ glGetUniformiv(program, location, &value[0]);
+ assert_no_error();
+ assert(value[0] == 1);
+}
+
+static void test_uniform_multiple_samplers(void)
+{
+ GLuint program;
+ GLint location;
+ GLint values[2] = {0, 1};
+
+ assert_no_error();
+ program = make_program(NULL, "uniform sampler2D s[2];\nvoid main() { gl_FragColor = texture2D(s[1], vec2(0.0, 0.0)); }\n");
+ location = glGetUniformLocation(program, "s[0]");
+ if (location == -1) /* Mesa doesn't currently support indexing */
+ location = glGetUniformLocation(program, "s");
+ assert(location != -1);
+ assert_no_error();
+ glUniform1iv(location, 2, values);
+ assert_no_error();
+}
+
+static void run_test(const char *name, void (*callback)(void))
+{
+ printf("Running %s\n", name);
+ fflush(stdout);
+ callback();
+}
+
+#define RUN_TEST(name) run_test(#name, (name))
+
+int main(int argc, char **argv)
+{
+ glutInit(&argc, argv);
+ glutCreateWindow("Mesa bug demo");
+
+ RUN_TEST(test_uniform_size_type);
+ RUN_TEST(test_attrib_size_type);
+ RUN_TEST(test_uniform_array_overflow);
+ RUN_TEST(test_uniform_scalar_count);
+ RUN_TEST(test_uniform_query_matrix);
+ RUN_TEST(test_uniform_neg_location);
+ RUN_TEST(test_uniform_bool_conversion);
+ /* Leave this one at the end, since it crashes Mesa's shader compiler */
+ RUN_TEST(test_uniform_multiple_samplers);
+ return 0;
+}
diff --git a/progs/tests/stencil_twoside.c b/progs/tests/stencil_twoside.c
new file mode 100644
index 0000000..be9d9a7
--- /dev/null
+++ b/progs/tests/stencil_twoside.c
@@ -0,0 +1,299 @@
+/*
+ * (C) Copyright IBM Corporation 2004
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * on the rights to use, copy, modify, merge, publish, distribute, sub
+ * license, and/or sell copies of the Software, and to permit persons to whom
+ * the Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * VA LINUX SYSTEM, IBM AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+ * USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/**
+ * \file stencil_twoside.c
+ *
+ * Simple test of GL_ATI_separate_stencil (or the OGL 2.0 equivalent) functionality.
+ * Four squares are drawn
+ * with different stencil modes, but all should be rendered with the same
+ * final color.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <GL/glut.h>
+
+static int use20syntax = 1;
+static int Width = 550;
+static int Height = 200;
+static const GLfloat Near = 5.0, Far = 25.0;
+
+
+static PFNGLSTENCILFUNCSEPARATEPROC stencil_func_separate = NULL;
+static PFNGLSTENCILFUNCSEPARATEATIPROC stencil_func_separate_ati = NULL;
+static PFNGLSTENCILOPSEPARATEPROC stencil_op_separate = NULL;
+
+static void Display( void )
+{
+ GLint max_stencil;
+ GLint stencil_bits;
+ unsigned i;
+
+
+ glGetIntegerv( GL_STENCIL_BITS, & stencil_bits );
+ max_stencil = (1U << stencil_bits) - 1;
+ printf( "Stencil bits = %u, maximum stencil value = 0x%08x\n",
+ stencil_bits, max_stencil );
+
+ glClearStencil( 1 );
+ glClearColor( 0.2, 0.2, 0.8, 0 );
+ glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT
+ | GL_STENCIL_BUFFER_BIT );
+
+
+ glPushMatrix();
+
+ /* This is the "reference" square.
+ */
+
+ glDisable(GL_STENCIL_TEST);
+ glTranslatef(-6.0, 0, 0);
+ glBegin(GL_QUADS);
+ glColor3f( 0.5, 0.5, 0.5 );
+ glVertex2f(-1, -1);
+ glVertex2f( 1, -1);
+ glVertex2f( 1, 1);
+ glVertex2f(-1, 1);
+ glEnd();
+
+
+ glEnable(GL_STENCIL_TEST);
+
+ /* Draw the first two squares using incr for the affected face
+ */
+
+ if (use20syntax) {
+ stencil_func_separate(GL_FRONT, GL_ALWAYS, 0, ~0);
+ stencil_func_separate(GL_BACK, GL_ALWAYS, 0, ~0);
+ }
+ else {
+ stencil_func_separate_ati(GL_ALWAYS, GL_ALWAYS, 0, ~0);
+ }
+ stencil_op_separate(GL_FRONT, GL_KEEP, GL_KEEP, GL_INCR);
+ stencil_op_separate(GL_BACK, GL_KEEP, GL_KEEP, GL_DECR);
+
+ glTranslatef(3.0, 0, 0);
+ glBegin(GL_QUADS);
+ glColor3f( 0.9, 0.9, 0.9 );
+ /* this should be front facing */
+ for ( i = 0 ; i < (max_stencil + 5) ; i++ ) {
+ glVertex2f(-1, -1);
+ glVertex2f( 1, -1);
+ glVertex2f( 1, 1);
+ glVertex2f(-1, 1);
+ }
+ glEnd();
+
+ glStencilFunc(GL_EQUAL, max_stencil, ~0);
+ glBegin(GL_QUADS);
+ glColor3f( 0.5, 0.5, 0.5 );
+ glVertex2f(-1, -1);
+ glVertex2f( 1, -1);
+ glVertex2f( 1, 1);
+ glVertex2f(-1, 1);
+ glEnd();
+
+
+ if (use20syntax) {
+ stencil_func_separate(GL_FRONT, GL_ALWAYS, 0, ~0);
+ stencil_func_separate(GL_BACK, GL_ALWAYS, 0, ~0);
+ }
+ else {
+ stencil_func_separate_ati(GL_ALWAYS, GL_ALWAYS, 0, ~0);
+ }
+ stencil_op_separate(GL_FRONT, GL_KEEP, GL_KEEP, GL_DECR);
+ stencil_op_separate(GL_BACK, GL_KEEP, GL_KEEP, GL_INCR);
+
+ glTranslatef(3.0, 0, 0);
+ glBegin(GL_QUADS);
+ glColor3f( 0.9, 0.9, 0.9 );
+
+ /* this should be back facing */
+ for ( i = 0 ; i < (max_stencil + 5) ; i++ ) {
+ glVertex2f(-1, -1);
+ glVertex2f(-1, 1);
+ glVertex2f( 1, 1);
+ glVertex2f( 1, -1);
+ }
+ glEnd();
+
+ glStencilFunc(GL_EQUAL, max_stencil, ~0);
+ glBegin(GL_QUADS);
+ glColor3f( 0.5, 0.5, 0.5 );
+ glVertex2f(-1, -1);
+ glVertex2f( 1, -1);
+ glVertex2f( 1, 1);
+ glVertex2f(-1, 1);
+ glEnd();
+
+ if (use20syntax) {
+ stencil_func_separate(GL_FRONT, GL_NEVER, 0, ~0);
+ stencil_func_separate(GL_BACK, GL_ALWAYS, 0, ~0);
+ }
+ else {
+ stencil_func_separate_ati(GL_NEVER, GL_ALWAYS, 0, ~0);
+ }
+ stencil_op_separate(GL_FRONT, GL_KEEP, GL_KEEP, GL_DECR);
+ stencil_op_separate(GL_BACK, GL_KEEP, GL_KEEP, GL_INCR);
+
+ glTranslatef(3.0, 0, 0);
+ glBegin(GL_QUADS);
+ glColor3f( 0.9, 0.9, 0.9 );
+
+ /* this should be back facing */
+ for ( i = 0 ; i < (max_stencil + 5) ; i++ ) {
+ /* this should be back facing */
+ glVertex2f(-1, -1);
+ glVertex2f(-1, 1);
+ glVertex2f( 1, 1);
+ glVertex2f( 1, -1);
+ /* this should be front facing */
+ glVertex2f(-1, -1);
+ glVertex2f( 1, -1);
+ glVertex2f( 1, 1);
+ glVertex2f(-1, 1);
+ }
+ glEnd();
+
+ glStencilFunc(GL_EQUAL, max_stencil, ~0);
+ glBegin(GL_QUADS);
+ glColor3f( 0.5, 0.5, 0.5 );
+ glVertex2f(-1, -1);
+ glVertex2f( 1, -1);
+ glVertex2f( 1, 1);
+ glVertex2f(-1, 1);
+ glEnd();
+
+ if (use20syntax) {
+ stencil_func_separate(GL_FRONT, GL_ALWAYS, 0, ~0);
+ stencil_func_separate(GL_BACK, GL_ALWAYS, 0, ~0);
+ }
+ else {
+ stencil_func_separate_ati(GL_ALWAYS, GL_ALWAYS, 0, ~0);
+ }
+ stencil_op_separate(GL_FRONT, GL_KEEP, GL_KEEP, GL_DECR);
+ stencil_op_separate(GL_BACK, GL_KEEP, GL_KEEP, GL_INCR);
+
+ glTranslatef(3.0, 0, 0);
+ glBegin(GL_QUADS);
+ glColor3f( 0.9, 0.9, 0.9 );
+
+ /* this should be back facing */
+ for ( i = 0 ; i < (max_stencil + 5) ; i++ ) {
+ /* this should be back facing */
+ glVertex2f(-1, -1);
+ glVertex2f(-1, 1);
+ glVertex2f( 1, 1);
+ glVertex2f( 1, -1);
+ /* this should be front facing */
+ glVertex2f(-1, -1);
+ glVertex2f( 1, -1);
+ glVertex2f( 1, 1);
+ glVertex2f(-1, 1);
+ }
+ glEnd();
+
+ glStencilFunc(GL_EQUAL, 1, ~0);
+ glBegin(GL_QUADS);
+ glColor3f( 0.5, 0.5, 0.5 );
+ glVertex2f(-1, -1);
+ glVertex2f( 1, -1);
+ glVertex2f( 1, 1);
+ glVertex2f(-1, 1);
+ glEnd();
+
+ glPopMatrix();
+
+ glutSwapBuffers();
+}
+
+
+static void Reshape( int width, int height )
+{
+ GLfloat ar = (float) width / (float) height;
+ Width = width;
+ Height = height;
+ glViewport( 0, 0, width, height );
+ glMatrixMode( GL_PROJECTION );
+ glLoadIdentity();
+ glFrustum( -ar, ar, -1.0, 1.0, Near, Far );
+ glMatrixMode( GL_MODELVIEW );
+ glLoadIdentity();
+ glTranslatef( 0.0, 0.0, -15.0 );
+}
+
+
+static void Key( unsigned char key, int x, int y )
+{
+ (void) x;
+ (void) y;
+ switch (key) {
+ case 27:
+ exit(0);
+ break;
+ }
+ glutPostRedisplay();
+}
+
+
+static void Init( void )
+{
+ const char * const ver_string = (const char * const)
+ glGetString( GL_VERSION );
+
+ printf("GL_RENDERER = %s\n", (char *) glGetString(GL_RENDERER));
+ printf("GL_VERSION = %s\n", ver_string);
+
+ if ( !glutExtensionSupported("GL_ATI_separate_stencil")
+ && (atof( ver_string ) < 2.0) ) {
+ printf("Sorry, this program requires either GL_ATI_separate_stencil or OpenGL 2.0.\n");
+ exit(1);
+ }
+ if (atof( ver_string ) < 2.0) {
+ use20syntax = 0;
+ }
+ stencil_func_separate = glutGetProcAddress( "glStencilFuncSeparate" );
+ stencil_func_separate_ati = glutGetProcAddress( "glStencilFuncSeparateATI" );
+ stencil_op_separate = glutGetProcAddress( "glStencilOpSeparate" );
+
+ printf("\nAll 5 squares should be the same color.\n");
+ glEnable( GL_BLEND );
+}
+
+
+int main( int argc, char *argv[] )
+{
+ glutInit( &argc, argv );
+ glutInitWindowPosition( 0, 0 );
+ glutInitWindowSize( Width, Height );
+ glutInitDisplayMode( GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH | GLUT_STENCIL );
+ glutCreateWindow( "GL_ATI_separate_stencil test" );
+ glutReshapeFunc( Reshape );
+ glutKeyboardFunc( Key );
+ glutDisplayFunc( Display );
+ Init();
+ glutMainLoop();
+ return 0;
+}
diff --git a/progs/tests/texline.c b/progs/tests/texline.c
index ee16ed4..76dfccd 100644
--- a/progs/tests/texline.c
+++ b/progs/tests/texline.c
@@ -6,7 +6,6 @@
* September 2000
*/
-
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
@@ -210,7 +209,9 @@ static void SpecialKey( int key, int x, int y )
static void Init( int argc, char *argv[] )
{
+ GLfloat r[2];
GLuint u;
+
for (u = 0; u < 2; u++) {
glActiveTextureARB(GL_TEXTURE0_ARB + u);
glBindTexture(GL_TEXTURE_2D, 10+u);
@@ -241,6 +242,15 @@ static void Init( int argc, char *argv[] )
printf("GL_VENDOR = %s\n", (char *) glGetString(GL_VENDOR));
printf("GL_EXTENSIONS = %s\n", (char *) glGetString(GL_EXTENSIONS));
}
+
+ glGetFloatv(GL_ALIASED_POINT_SIZE_RANGE, r);
+ printf("Non-smooth point size range: %g .. %g\n", r[0], r[1]);
+ glGetFloatv(GL_POINT_SIZE_RANGE, r);
+ printf("Smoothed point size range: %g .. %g\n", r[0], r[1]);
+ glGetFloatv(GL_ALIASED_LINE_WIDTH_RANGE, r);
+ printf("Non-smooth line width range: %g .. %g\n", r[0], r[1]);
+ glGetFloatv(GL_LINE_WIDTH_RANGE, r);
+ printf("Smoothed line width range: %g .. %g\n", r[0], r[1]);
}
diff --git a/progs/tests/unfilledclip.c b/progs/tests/unfilledclip.c
new file mode 100644
index 0000000..f25e526
--- /dev/null
+++ b/progs/tests/unfilledclip.c
@@ -0,0 +1,205 @@
+/*
+ * Copyright © 2008 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ * Authors:
+ * Eric Anholt <eric@anholt.net>
+ *
+ */
+
+#include <stdlib.h>
+#include <GL/glut.h>
+
+static int win_width, win_height;
+
+static void
+line(GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2)
+{
+ glBegin(GL_LINES);
+ glVertex2f(x1, y1);
+ glVertex2f(x2, y2);
+ glEnd();
+}
+
+static void
+line3(GLfloat x1, GLfloat y1, GLfloat z1, GLfloat x2, GLfloat y2, GLfloat z2)
+{
+ glBegin(GL_LINES);
+ glVertex3f(x1, y1, z1);
+ glVertex3f(x2, y2, z2);
+ glEnd();
+}
+
+static void
+display(void)
+{
+ glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
+
+ glClearColor(0.0, 0.0, 0.0, 0.0);
+ glClear(GL_COLOR_BUFFER_BIT);
+
+ glColor3f(1.0, 0.0, 0.0);
+ /* clipped along xmin */
+ glBegin(GL_TRIANGLES);
+ glVertex2f(-20, win_height / 2 - 20);
+ glVertex2f(20, win_height / 2);
+ glVertex2f(-20, win_height / 2 + 20);
+ glEnd();
+
+ glColor3f(0.0, 1.0, 0.0);
+ /* clipped along ymax */
+ glBegin(GL_TRIANGLES);
+ glVertex2f(win_height / 2 - 20, win_height + 20);
+ glVertex2f(win_height / 2, win_height - 20);
+ glVertex2f(win_height / 2 + 20, win_height + 20);
+ glEnd();
+
+ glColor3f(0.0, 0.0, 1.0);
+ /* clipped along xmax */
+ glBegin(GL_TRIANGLES);
+ glVertex2f(win_height + 20, win_height / 2 - 20);
+ glVertex2f(win_height - 20, win_height / 2);
+ glVertex2f(win_height + 20, win_height / 2 + 20);
+ glEnd();
+
+ glColor3f(1.0, 1.0, 1.0);
+ /* clipped along ymin */
+ glBegin(GL_TRIANGLES);
+ glVertex2f(win_height / 2 - 20, -20);
+ glVertex2f(win_height / 2, 20);
+ glVertex2f(win_height / 2 + 20, -20);
+ glEnd();
+
+ /* clipped along near */
+ glColor3f(1.0, 0.0, 1.0);
+ glBegin(GL_TRIANGLES);
+ glVertex3f(win_width / 2 - 20, win_height / 2 - 20, 0.5);
+ glVertex3f(win_width / 2 - 40, win_height / 2, -0.5);
+ glVertex3f(win_width / 2 - 20, win_height / 2 + 20, 0.5);
+ glEnd();
+
+ /* clipped along far */
+ glColor3f(0.0, 1.0, 1.0);
+ glBegin(GL_TRIANGLES);
+ glVertex3f(win_width / 2 + 20, win_height / 2 - 20, 0.5);
+ glVertex3f(win_width / 2 + 40, win_height / 2, 1.5);
+ glVertex3f(win_width / 2 + 20, win_height / 2 + 20, 0.5);
+ glEnd();
+
+ /* entirely clipped along near/far */
+ glColor3f(.5, .5, .5);
+ glBegin(GL_TRIANGLES);
+ glVertex3f(win_width / 2 - 20, win_height / 2 + 20, -0.5);
+ glVertex3f(win_width / 2, win_height / 2 + 40, -0.5);
+ glVertex3f(win_width / 2 + 20, win_height / 2 + 20, -0.5);
+ glEnd();
+
+ glBegin(GL_TRIANGLES);
+ glVertex3f(win_width / 2 - 20, win_height / 2 - 20, 1.5);
+ glVertex3f(win_width / 2, win_height / 2 - 40, 1.5);
+ glVertex3f(win_width / 2 + 20, win_height / 2 - 20, 1.5);
+ glEnd();
+
+ glColor3f(.5, .5, .5);
+ line3(win_width / 2, win_height / 2 - 20, 1.5,
+ win_width / 2, win_height / 2 + 20, 1.5);
+
+ glColor3f(1.0, 1.0, 0.0);
+ /* clipped along both x and y limits */
+ glBegin(GL_TRIANGLES); /* xmin, ymin */
+ glVertex2f(-5, 20);
+ glVertex2f(20, 20);
+ glVertex2f(20, -5);
+ glEnd();
+ glBegin(GL_TRIANGLES); /* xmin, ymax */
+ glVertex2f(-5, win_height - 20);
+ glVertex2f(20, win_height - 20);
+ glVertex2f(20, win_height + 5);
+ glEnd();
+ glBegin(GL_TRIANGLES); /* xmax, ymax */
+ glVertex2f(win_width - 20, win_height + 5);
+ glVertex2f(win_width - 20, win_height - 20);
+ glVertex2f(win_width + 5, win_height - 20);
+ glEnd();
+ glBegin(GL_TRIANGLES); /* xmax, ymin */
+ glVertex2f(win_width + 5, 20);
+ glVertex2f(win_width - 20, 20);
+ glVertex2f(win_width - 20, -5);
+ glEnd();
+
+ glutSwapBuffers();
+}
+
+static void
+reshape(int width, int height)
+{
+ win_width = width;
+ win_height = height;
+ glViewport(0, 0, width, height);
+
+ glMatrixMode(GL_PROJECTION);
+ glLoadIdentity();
+ glOrtho(0, win_width, 0, win_height, 0.0, -1.0);
+
+ glMatrixMode(GL_MODELVIEW);
+ glLoadIdentity();
+ glTranslatef(.25, .25, 0);
+}
+
+static void key( unsigned char key, int x, int y )
+{
+ (void) x;
+ (void) y;
+
+ switch (key) {
+ case 27: /* esc */
+ exit(0);
+ break;
+ }
+
+ glutPostRedisplay();
+}
+
+static void
+init(void)
+{
+}
+
+int
+main(int argc, char *argv[])
+{
+ win_width = 200;
+ win_height = 200;
+
+ glutInit(&argc, argv);
+ glutInitWindowPosition(0, 0);
+ glutInitWindowSize(win_width, win_height);
+ glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
+ glutCreateWindow(argv[0]);
+ glutReshapeFunc(reshape);
+ glutKeyboardFunc(key);
+ glutDisplayFunc(display);
+
+ init();
+
+ glutMainLoop();
+ return 0;
+}
diff --git a/progs/tools/trace/Makefile b/progs/tools/trace/Makefile
index 3f7bdcb..822e466 100644
--- a/progs/tools/trace/Makefile
+++ b/progs/tools/trace/Makefile
@@ -16,8 +16,8 @@ TRACER = gltrace.so
default: $(TRACER)
$(TRACER): $(OBJECTS)
- $(TOP)/bin/mklib -o $(TRACER) -noprefix -cplusplus \
- $(MKLIB_OPTIONS) $(OBJECTS)
+ $(MKLIB) -o $(TRACER) -noprefix -cplusplus -linker '$(CXX)' \
+ -ldflags '$(LDFLAGS)' $(MKLIB_OPTIONS) $(OBJECTS)
gltrace.cc: gltrace.py
PYTHONPATH=$(TOP)/src/mesa/glapi python gltrace.py -f $(TOP)/src/mesa/glapi/gl_API.xml > gltrace.cc
diff --git a/progs/tools/trace/gltrace_support.cc b/progs/tools/trace/gltrace_support.cc
index b188e73..0b76d32 100644
--- a/progs/tools/trace/gltrace_support.cc
+++ b/progs/tools/trace/gltrace_support.cc
@@ -20,6 +20,8 @@
*/
#include "gltrace_support.h"
+#include <cstdlib>
+#include <cstring>
#include <assert.h>
#include <sstream>
#include <fstream>
@@ -136,7 +138,7 @@ namespace gltrace {
struct timeval now;
struct tm t;
- static char *months[12] =
+ static char const *months[12] =
{
"Jan", "Feb", "Mar", "Apr", "May", "Jun",
"Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
diff --git a/progs/trivial/Makefile b/progs/trivial/Makefile
index 786576c..01475f9 100644
--- a/progs/trivial/Makefile
+++ b/progs/trivial/Makefile
@@ -8,7 +8,7 @@ TOP = ../..
include $(TOP)/configs/current
-LIBS = $(APP_LIB_DEPS)
+LIBS = -L$(TOP)/$(LIB_DIR) -l$(GLUT_LIB) -l$(GLU_LIB) -l$(GL_LIB) $(APP_LIB_DEPS)
SOURCES = \
clear-fbo-tex.c \
@@ -138,7 +138,7 @@ UTIL_FILES = readtex.h readtex.c
.SUFFIXES: .c
.c:
- $(CC) $(INCLUDES) $(CFLAGS) $< $(LIBS) -o $@
+ $(CC) $(INCLUDES) $(CFLAGS) $(LDFLAGS) $< $(LIBS) -o $@
.c.o:
$(CC) -c $(INCLUDES) $(CFLAGS) $(DEFINES) $< -o $@
@@ -152,9 +152,9 @@ UTIL_FILES = readtex.h readtex.c
default: $(UTIL_FILES) $(PROGS)
clean:
- rm -f $(PROGS)
- rm -f *.o
- rm -f getproclist.h
+ -rm -f $(PROGS)
+ -rm -f *.o
+ -rm -f getproclist.h
# auto code generation
@@ -165,13 +165,13 @@ getproclist.h: $(TOP)/src/mesa/glapi/gl_API.xml getprocaddress.c getprocaddress.
texrect: texrect.o readtex.o
- $(CC) texrect.o readtex.o $(LIBS) -o $@
+ $(CC) $(CFLAGS) $(LDFLAGS) texrect.o readtex.o $(LIBS) -o $@
texrect.o: texrect.c readtex.h
$(CC) -c $(INCLUDES) $(CFLAGS) $(DEFINES) $< -o $@
invert: invert.o readtex.o
- $(CC) invert.o readtex.o $(LIBS) -o $@
+ $(CC) $(CFLAGS) $(LDFLAGS) invert.o readtex.o $(LIBS) -o $@
invert.o: invert.c readtex.h
$(CC) -c $(INCLUDES) $(CFLAGS) $(DEFINES) $< -o $@
diff --git a/progs/trivial/point-param.c b/progs/trivial/point-param.c
index be4328d..96544a0 100644
--- a/progs/trivial/point-param.c
+++ b/progs/trivial/point-param.c
@@ -22,15 +22,14 @@
* OF THIS SOFTWARE.
*/
+#define GL_GLEXT_PROTOTYPES
+#include <math.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <GL/glut.h>
-#define CI_OFFSET_1 16
-#define CI_OFFSET_2 32
-
GLenum doubleBuffer;
@@ -40,53 +39,63 @@ static void Init(void)
fprintf(stderr, "GL_VERSION = %s\n", (char *) glGetString(GL_VERSION));
fprintf(stderr, "GL_VENDOR = %s\n", (char *) glGetString(GL_VENDOR));
- glClearColor(0.0, 0.0, 1.0, 0.0);
+ glClearColor(0.0, 0.0, 1.0, 0.0);
}
static void Reshape(int width, int height)
{
-
glViewport(0, 0, (GLint)width, (GLint)height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
- glOrtho(-1.0, 1.0, -1.0, 1.0, -0.5, 1000.0);
+ glOrtho(-1.0, 1.0, -1.0, 1.0, 0, 100.0);
glMatrixMode(GL_MODELVIEW);
}
static void Key(unsigned char key, int x, int y)
{
-
switch (key) {
- case 27:
+ case 27:
exit(1);
- default:
+ default:
return;
}
-
glutPostRedisplay();
}
+
+static float
+expected(float z, float size, const float atten[3])
+{
+ float dist = fabs(z);
+ const GLfloat q = atten[0] + dist * (atten[1] + dist * atten[2]);
+ const GLfloat a = sqrt(1.0 / q);
+ return size * a;
+}
+
+
static void Draw(void)
{
- static GLfloat theQuad[3] = { 0.25, 0.0, 1/60.0 };
+ static GLfloat atten[3] = { 0.0, 0.1, .01 };
+ float size = 40.0;
+ int i;
glClear(GL_COLOR_BUFFER_BIT);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- glPointSize(8.0);
- glPointParameterfvARB(GL_POINT_DISTANCE_ATTENUATION_ARB, theQuad);
+ glPointSize(size);
+ glPointParameterfvARB(GL_POINT_DISTANCE_ATTENUATION_ARB, atten);
+ glColor3f(1,0,0);
+ printf("Expected point sizes:\n");
glBegin(GL_POINTS);
- glColor3f(1,0,0);
- glVertex3f( 0.9, -0.9, -10.0);
- glColor3f(1,1,0);
- glVertex3f( 0.9, 0.9, -5.0);
- glColor3f(1,0,1);
- glVertex3f(-0.9, 0.9, -30.0);
- glColor3f(0,1,1);
- glVertex3f(-0.9, -0.9, -20.0);
+ for (i = 0; i < 5; i++) {
+ float x = -0.8 + i * 0.4;
+ float z = -i * 20 - 10;
+ glVertex3f( x, 0.0, z);
+ printf(" %f\n", expected(z, size, atten));
+ }
glEnd();
glFlush();
@@ -96,6 +105,7 @@ static void Draw(void)
}
}
+
static GLenum Args(int argc, char **argv)
{
GLint i;
@@ -115,6 +125,7 @@ static GLenum Args(int argc, char **argv)
return GL_TRUE;
}
+
int main(int argc, char **argv)
{
GLenum type;
@@ -131,7 +142,7 @@ int main(int argc, char **argv)
type |= (doubleBuffer) ? GLUT_DOUBLE : GLUT_SINGLE;
glutInitDisplayMode(type);
- if (glutCreateWindow("First Tri") == GL_FALSE) {
+ if (glutCreateWindow(argv[0]) == GL_FALSE) {
exit(1);
}
@@ -141,5 +152,5 @@ int main(int argc, char **argv)
glutKeyboardFunc(Key);
glutDisplayFunc(Draw);
glutMainLoop();
- return 0;
+ return 0;
}
diff --git a/progs/trivial/quad-clip-nearplane.c b/progs/trivial/quad-clip-nearplane.c
index e76eb29..1e8056c 100644
--- a/progs/trivial/quad-clip-nearplane.c
+++ b/progs/trivial/quad-clip-nearplane.c
@@ -33,6 +33,7 @@
GLenum doubleBuffer;
+float Z = -6;
static void Init(void)
{
@@ -40,30 +41,36 @@ static void Init(void)
fprintf(stderr, "GL_VERSION = %s\n", (char *) glGetString(GL_VERSION));
fprintf(stderr, "GL_VENDOR = %s\n", (char *) glGetString(GL_VENDOR));
- glClearColor(0.0, 0.0, 1.0, 0.0);
+ fprintf(stderr, "Press z/Z to translate quad\n");
+
+ glClearColor(0.0, 0.0, 1.0, 0.0);
}
static void Reshape(int width, int height)
{
-
glViewport(0, 0, (GLint)width, (GLint)height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
- glOrtho(-1.0, 1.0, -1.0, 1.0, -0.5, 1000.0);
+ glFrustum(-1.0, 1.0, -1.0, 1.0, 5, 100.0);
glMatrixMode(GL_MODELVIEW);
}
static void Key(unsigned char key, int x, int y)
{
-
switch (key) {
- case 27:
- exit(1);
- default:
- return;
+ case 'z':
+ Z += 0.5;
+ break;
+ case 'Z':
+ Z -= 0.5;
+ break;
+ case 27:
+ exit(1);
+ default:
+ return;
}
-
+ printf("Z = %f\n", Z);
glutPostRedisplay();
}
@@ -71,17 +78,22 @@ static void Draw(void)
{
glClear(GL_COLOR_BUFFER_BIT);
+ glPushMatrix();
+ glTranslatef(0, -0.5, Z);
+
glBegin(GL_QUADS);
glColor3f(1,0,0);
- glVertex3f( 0.9, -0.9, 30.0);
+ glVertex3f( -0.8, 0, -4.0);
glColor3f(1,1,0);
- glVertex3f( 0.9, 0.9, 30.0);
+ glVertex3f( 0.8, 0, -4.0);
glColor3f(1,0,1);
- glVertex3f(-1.9, 0.9, 30.0);
+ glVertex3f( 0.8, 0, 4.0);
glColor3f(0,1,1);
- glVertex3f(-1.9, -0.9, -30.0);
+ glVertex3f( -0.8, 0, 4.0);
glEnd();
+ glPopMatrix();
+
glFlush();
if (doubleBuffer) {
@@ -118,7 +130,8 @@ int main(int argc, char **argv)
exit(1);
}
- glutInitWindowPosition(0, 0); glutInitWindowSize( 250, 250);
+ glutInitWindowPosition(0, 0);
+ glutInitWindowSize( 250, 250);
type = GLUT_RGB | GLUT_ALPHA;
type |= (doubleBuffer) ? GLUT_DOUBLE : GLUT_SINGLE;
@@ -134,5 +147,5 @@ int main(int argc, char **argv)
glutKeyboardFunc(Key);
glutDisplayFunc(Draw);
glutMainLoop();
- return 0;
+ return 0;
}
diff --git a/progs/trivial/tri.c b/progs/trivial/tri.c
index 12fa8d1..c75acb3 100644
--- a/progs/trivial/tri.c
+++ b/progs/trivial/tri.c
@@ -33,6 +33,7 @@
GLenum doubleBuffer = 1;
+int win;
static void Init(void)
{
@@ -59,6 +60,10 @@ static void Key(unsigned char key, int x, int y)
switch (key) {
case 27:
+<<<<<<< HEAD:progs/trivial/tri.c
+ glutDestroyWindow(win);
+=======
+>>>>>>> gallium-0.1:progs/trivial/tri.c
exit(0);
default:
return;
@@ -120,7 +125,8 @@ int main(int argc, char **argv)
type |= (doubleBuffer) ? GLUT_DOUBLE : GLUT_SINGLE;
glutInitDisplayMode(type);
- if (glutCreateWindow("First Tri") == GL_FALSE) {
+ win = glutCreateWindow("First Tri");
+ if (!win) {
exit(1);
}
diff --git a/progs/util/shaderutil.c b/progs/util/shaderutil.c
new file mode 100644
index 0000000..4f17dd7
--- /dev/null
+++ b/progs/util/shaderutil.c
@@ -0,0 +1,162 @@
+/**
+ * Utilities for OpenGL shading language
+ *
+ * Brian Paul
+ * 9 April 2008
+ */
+
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <GL/glut.h>
+#include "extfuncs.h"
+#include "shaderutil.h"
+
+
+static void
+Init(void)
+{
+ static GLboolean firstCall = GL_TRUE;
+ if (firstCall) {
+ GetExtensionFuncs();
+ firstCall = GL_FALSE;
+ }
+}
+
+
+GLboolean
+ShadersSupported(void)
+{
+ const char *version = (const char *) glGetString(GL_VERSION);
+ if (version[0] == '2' && version[1] == '.') {
+ return GL_TRUE;
+ }
+ else if (glutExtensionSupported("GL_ARB_vertex_shader")
+ && glutExtensionSupported("GL_ARB_fragment_shader")
+ && glutExtensionSupported("GL_ARB_shader_objects")) {
+ fprintf(stderr, "Warning: Trying ARB GLSL instead of OpenGL 2.x. This may not work.\n");
+ return GL_TRUE;
+ }
+ return GL_TRUE;
+}
+
+
+GLuint
+CompileShaderText(GLenum shaderType, const char *text)
+{
+ GLuint shader;
+ GLint stat;
+
+ Init();
+
+ shader = glCreateShader_func(shaderType);
+ glShaderSource_func(shader, 1, (const GLchar **) &text, NULL);
+ glCompileShader_func(shader);
+ glGetShaderiv_func(shader, GL_COMPILE_STATUS, &stat);
+ if (!stat) {
+ GLchar log[1000];
+ GLsizei len;
+ glGetShaderInfoLog_func(shader, 1000, &len, log);
+ fprintf(stderr, "Error: problem compiling shader: %s\n", log);
+ exit(1);
+ }
+ else {
+ /*printf("Shader compiled OK\n");*/
+ }
+ return shader;
+}
+
+
+/**
+ * Read a shader from a file.
+ */
+GLuint
+CompileShaderFile(GLenum shaderType, const char *filename)
+{
+ const int max = 100*1000;
+ int n;
+ char *buffer = (char*) malloc(max);
+ GLuint shader;
+
+ FILE *f = fopen(filename, "r");
+ if (!f) {
+ return 0;
+ }
+
+ n = fread(buffer, 1, max, f);
+ /*printf("read %d bytes from shader file %s\n", n, filename);*/
+ if (n > 0) {
+ buffer[n] = 0;
+ shader = CompileShaderText(shaderType, buffer);
+ }
+ else {
+ return 0;
+ }
+
+ fclose(f);
+ free(buffer);
+
+ return shader;
+}
+
+
+GLuint
+LinkShaders(GLuint vertShader, GLuint fragShader)
+{
+ GLuint program = glCreateProgram_func();
+
+ glAttachShader_func(program, fragShader);
+ glAttachShader_func(program, vertShader);
+ glLinkProgram_func(program);
+
+ /* check link */
+ {
+ GLint stat;
+ glGetProgramiv_func(program, GL_LINK_STATUS, &stat);
+ if (!stat) {
+ GLchar log[1000];
+ GLsizei len;
+ glGetProgramInfoLog_func(program, 1000, &len, log);
+ fprintf(stderr, "Shader link error:\n%s\n", log);
+ return 0;
+ }
+ }
+
+ return program;
+}
+
+
+void
+InitUniforms(GLuint program, struct uniform_info uniforms[])
+{
+ GLuint i;
+
+ for (i = 0; uniforms[i].name; i++) {
+ uniforms[i].location
+ = glGetUniformLocation_func(program, uniforms[i].name);
+
+ printf("Uniform %s location: %d\n", uniforms[i].name,
+ uniforms[i].location);
+
+ switch (uniforms[i].size) {
+ case 1:
+ if (uniforms[i].type == GL_INT)
+ glUniform1i_func(uniforms[i].location,
+ (GLint) uniforms[i].value[0]);
+ else
+ glUniform1fv_func(uniforms[i].location, 1, uniforms[i].value);
+ break;
+ case 2:
+ glUniform2fv_func(uniforms[i].location, 1, uniforms[i].value);
+ break;
+ case 3:
+ glUniform3fv_func(uniforms[i].location, 1, uniforms[i].value);
+ break;
+ case 4:
+ glUniform4fv_func(uniforms[i].location, 1, uniforms[i].value);
+ break;
+ default:
+ abort();
+ }
+ }
+}
diff --git a/progs/util/shaderutil.h b/progs/util/shaderutil.h
new file mode 100644
index 0000000..cfb8c1f
--- /dev/null
+++ b/progs/util/shaderutil.h
@@ -0,0 +1,34 @@
+#ifndef SHADER_UTIL_H
+#define SHADER_UTIL_H
+
+
+
+struct uniform_info
+{
+ const char *name;
+ GLuint size;
+ GLenum type; /**< GL_FLOAT or GL_INT */
+ GLfloat value[4];
+ GLint location; /**< filled in by InitUniforms() */
+};
+
+#define END_OF_UNIFORMS { NULL, 0, GL_NONE, { 0, 0, 0, 0 }, -1 }
+
+
+extern GLboolean
+ShadersSupported(void);
+
+extern GLuint
+CompileShaderText(GLenum shaderType, const char *text);
+
+extern GLuint
+CompileShaderFile(GLenum shaderType, const char *filename);
+
+extern GLuint
+LinkShaders(GLuint vertShader, GLuint fragShader);
+
+extern void
+InitUniforms(GLuint program, struct uniform_info uniforms[]);
+
+
+#endif /* SHADER_UTIL_H */
diff --git a/progs/vp/Makefile b/progs/vp/Makefile
index c3faeb5..28d6323 100644
--- a/progs/vp/Makefile
+++ b/progs/vp/Makefile
@@ -8,7 +8,7 @@ TOP = ../..
include $(TOP)/configs/current
-LIBS = $(APP_LIB_DEPS)
+LIBS = -L$(TOP)/$(LIB_DIR) -l$(GLUT_LIB) -l$(GLU_LIB) -l$(GL_LIB) $(APP_LIB_DEPS)
SOURCES = \
vp-tris.c
@@ -26,7 +26,7 @@ INCLUDES = -I. -I$(TOP)/include -I../samples
.SUFFIXES: .c
.c:
- $(CC) $(INCLUDES) $(CFLAGS) $< $(LIBS) -o $@
+ $(CC) $(INCLUDES) $(CFLAGS) $(LDFLAGS) $< $(LIBS) -o $@
.c.o:
$(CC) -c $(INCLUDES) $(CFLAGS) $(DEFINES) $< -o $@
@@ -40,9 +40,9 @@ INCLUDES = -I. -I$(TOP)/include -I../samples
default: $(PROGS)
clean:
- rm -f $(PROGS)
- rm -f *.o
- rm -f getproclist.h
+ -rm -f $(PROGS)
+ -rm -f *.o
+ -rm -f getproclist.h
diff --git a/progs/xdemos/.gitignore b/progs/xdemos/.gitignore
index 3455110..868249d 100644
--- a/progs/xdemos/.gitignore
+++ b/progs/xdemos/.gitignore
@@ -1,12 +1,15 @@
+corender
glthreads
glxcontexts
glxdemo
glxgears
glxgears_fbconfig
+glxgears_pixmap
glxheads
glxinfo
glxpbdemo
glxpixmap
+glxsnoop
glxswapcontrol
manywin
offset
diff --git a/progs/xdemos/Makefile b/progs/xdemos/Makefile
index 896b160..b259671 100644
--- a/progs/xdemos/Makefile
+++ b/progs/xdemos/Makefile
@@ -6,17 +6,23 @@ include $(TOP)/configs/current
INCDIR = $(TOP)/include
-LIB_DEP = $(TOP)/$(LIB_DIR)/$(GL_LIB_NAME) $(TOP)/$(LIB_DIR)/$(GLU_LIB_NAME)
+LIB_DEP = $(TOP)/$(LIB_DIR)/$(GL_LIB_NAME)
-PROGS = glthreads \
+LIBS = -L$(TOP)/$(LIB_DIR) -l$(GL_LIB) $(APP_LIB_DEPS)
+
+PROGS = \
+ corender \
+ glthreads \
glxdemo \
glxgears \
glxgears_fbconfig \
+ glxgears_pixmap \
glxcontexts \
glxheads \
glxinfo \
glxpixmap \
glxpbdemo \
+ glxsnoop \
glxswapcontrol \
manywin \
offset \
@@ -27,10 +33,14 @@ PROGS = glthreads \
texture_from_pixmap \
wincopy \
xfont \
- xrotfontdemo \
- yuvrect_client
+ xrotfontdemo
+
+# Don't build these by default because of extra library dependencies
+EXTRA_PROGS = \
+ shape \
+ yuvrect_client \
+ xdemo
-# omit this XMesa API demo: xdemo
##### RULES #####
@@ -39,7 +49,7 @@ PROGS = glthreads \
.SUFFIXES: .c
.c: $(LIB_DEP)
- $(CC) -I$(INCDIR) $(CFLAGS) $< $(APP_LIB_DEPS) -o $@
+ $(CC) -I$(INCDIR) $(X11_INCLUDES) $(CFLAGS) $(LDFLAGS) $< $(LIBS) -o $@
##### TARGETS #####
@@ -47,39 +57,54 @@ PROGS = glthreads \
default: $(PROGS)
+extra: $(EXTRA_PROGS)
+
+
clean:
- -rm -f $(PROGS)
+ -rm -f $(PROGS) $(EXTRA_PROGS)
-rm -f *.o *~
# special cases
pbinfo: pbinfo.o pbutil.o
- $(CC) -I$(INCDIR) $(CFLAGS) pbinfo.o pbutil.o $(APP_LIB_DEPS) -o $@
+ $(CC) $(CFLAGS) $(LDFLAGS) pbinfo.o pbutil.o $(LIBS) -o $@
pbdemo: pbdemo.o pbutil.o
- $(CC) -I$(INCDIR) $(CFLAGS) pbdemo.o pbutil.o $(APP_LIB_DEPS) -o $@
+ $(CC) $(CFLAGS) $(LDFLAGS) pbdemo.o pbutil.o $(LIBS) -o $@
pbinfo.o: pbinfo.c pbutil.h
- $(CC) -c -I. -I$(INCDIR) $(CFLAGS) pbinfo.c
+ $(CC) -c -I. -I$(INCDIR) $(X11_INCLUDES) $(CFLAGS) pbinfo.c
pbdemo.o: pbdemo.c pbutil.h
- $(CC) -c -I. -I$(INCDIR) $(CFLAGS) pbdemo.c
+ $(CC) -c -I. -I$(INCDIR) $(X11_INCLUDES) $(CFLAGS) pbdemo.c
pbutil.o: pbutil.c pbutil.h
- $(CC) -c -I. -I$(INCDIR) $(CFLAGS) pbutil.c
+ $(CC) -c -I. -I$(INCDIR) $(X11_INCLUDES) $(CFLAGS) pbutil.c
glxgears_fbconfig: glxgears_fbconfig.o pbutil.o
- $(CC) -I$(INCDIR) $(CFLAGS) glxgears_fbconfig.o pbutil.o $(APP_LIB_DEPS) -o $@
+ $(CC) $(CFLAGS) $(LDFLAGS) glxgears_fbconfig.o pbutil.o $(LIBS) -o $@
glxgears_fbconfig.o: glxgears_fbconfig.c pbutil.h
- $(CC) -I$(INCDIR) $(CFLAGS) -c -I. $(CFLAGS) glxgears_fbconfig.c
+ $(CC) -I$(INCDIR) $(X11_INCLUDES) $(CFLAGS) -c -I. $(CFLAGS) glxgears_fbconfig.c
xrotfontdemo: xrotfontdemo.o xuserotfont.o
- $(CC) -I$(INCDIR) $(CFLAGS) xrotfontdemo.o xuserotfont.o $(APP_LIB_DEPS) -o $@
+ $(CC) $(CFLAGS) $(LDFLAGS) xrotfontdemo.o xuserotfont.o $(LIBS) -o $@
xuserotfont.o: xuserotfont.c xuserotfont.h
- $(CC) -c -I. -I$(INCDIR) $(CFLAGS) xuserotfont.c
+ $(CC) -c -I. -I$(INCDIR) $(X11_INCLUDES) $(CFLAGS) xuserotfont.c
xrotfontdemo.o: xrotfontdemo.c xuserotfont.h
- $(CC) -c -I. -I$(INCDIR) $(CFLAGS) xrotfontdemo.c
+ $(CC) -c -I. -I$(INCDIR) $(X11_INCLUDES) $(CFLAGS) xrotfontdemo.c
+
+corender: corender.o ipc.o
+ $(CC) $(CFLAGS) corender.o ipc.o $(LIBS) -o $@
+
+corender.o: corender.c ipc.h
+ $(CC) -c -I. -I$(INCDIR) $(X11_INCLUDES) $(CFLAGS) corender.c
+
+ipc.o: ipc.c ipc.h
+ $(CC) -c -I. -I$(INCDIR) $(X11_INCLUDES) $(CFLAGS) ipc.c
+
+yuvrect_client: yuvrect_client.c
+ $(CC) -I$(INCDIR) $(X11_INCLUDES) $(CFLAGS) $< $(LDFLAGS) $(LIBS) -l$(GLU_LIB) -o $@
diff --git a/progs/xdemos/corender.c b/progs/xdemos/corender.c
new file mode 100644
index 0000000..f2b8145
--- /dev/null
+++ b/progs/xdemos/corender.c
@@ -0,0 +1,400 @@
+/**
+ * Example of cooperative rendering into one window by two processes.
+ * The first instance of the program creates the GLX window.
+ * The second instance of the program gets the window ID from the first
+ * and draws into it.
+ * Socket IPC is used for synchronization.
+ *
+ * Usage:
+ * 1. run 'corender &'
+ * 2. run 'corender 2' (any arg will do)
+ *
+ * Brian Paul
+ * 11 Oct 2007
+ */
+
+
+#include <GL/gl.h>
+#include <GL/glx.h>
+#include <assert.h>
+#include <math.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <X11/keysym.h>
+#include <unistd.h>
+#include "ipc.h"
+
+
+#ifndef M_PI
+#define M_PI 3.14159265358979323846
+#endif
+
+static int MyID = 0; /* 0 or 1 */
+static int WindowID = 0;
+static GLXContext Context = 0;
+static int Width = 700, Height = 350;
+static int Rot = 0;
+static int Sock = 0;
+
+static GLfloat Red[4] = {1.0, 0.2, 0.2, 1.0};
+static GLfloat Blue[4] = {0.2, 0.2, 1.0, 1.0};
+
+static int Sync = 1; /** synchronized rendering? */
+
+
+static void
+setup_ipc(void)
+{
+ int k, port = 10001;
+
+ if (MyID == 0) {
+ /* I'm the first one, wait for connection from second */
+ k = CreatePort(&port);
+ assert(k != -1);
+
+ printf("Waiting for connection from another 'corender'\n");
+ Sock = AcceptConnection(k);
+
+ printf("Got connection, sending windowID\n");
+
+ /* send windowID */
+ SendData(Sock, &WindowID, sizeof(WindowID));
+ }
+ else {
+ /* I'm the second one, connect to first */
+ char hostname[1000];
+
+ MyHostName(hostname, 1000);
+ Sock = Connect(hostname, port);
+ assert(Sock != -1);
+
+ /* get windowID */
+ ReceiveData(Sock, &WindowID, sizeof(WindowID));
+ printf("Contacted first 'corender', getting WindowID\n");
+ }
+}
+
+
+
+/** from GLUT */
+static void
+doughnut(GLfloat r, GLfloat R, GLint nsides, GLint rings)
+{
+ int i, j;
+ GLfloat theta, phi, theta1;
+ GLfloat cosTheta, sinTheta;
+ GLfloat cosTheta1, sinTheta1;
+ GLfloat ringDelta, sideDelta;
+
+ ringDelta = 2.0 * M_PI / rings;
+ sideDelta = 2.0 * M_PI / nsides;
+
+ theta = 0.0;
+ cosTheta = 1.0;
+ sinTheta = 0.0;
+ for (i = rings - 1; i >= 0; i--) {
+ theta1 = theta + ringDelta;
+ cosTheta1 = cos(theta1);
+ sinTheta1 = sin(theta1);
+ glBegin(GL_QUAD_STRIP);
+ phi = 0.0;
+ for (j = nsides; j >= 0; j--) {
+ GLfloat cosPhi, sinPhi, dist;
+
+ phi += sideDelta;
+ cosPhi = cos(phi);
+ sinPhi = sin(phi);
+ dist = R + r * cosPhi;
+
+ glNormal3f(cosTheta1 * cosPhi, -sinTheta1 * cosPhi, sinPhi);
+ glVertex3f(cosTheta1 * dist, -sinTheta1 * dist, r * sinPhi);
+ glNormal3f(cosTheta * cosPhi, -sinTheta * cosPhi, sinPhi);
+ glVertex3f(cosTheta * dist, -sinTheta * dist, r * sinPhi);
+ }
+ glEnd();
+ theta = theta1;
+ cosTheta = cosTheta1;
+ sinTheta = sinTheta1;
+ }
+}
+
+
+static void
+redraw(Display *dpy)
+{
+ int dbg = 0;
+
+ glXMakeCurrent(dpy, WindowID, Context);
+ glEnable(GL_LIGHTING);
+ glEnable(GL_LIGHT0);
+ glEnable(GL_DEPTH_TEST);
+ glClearColor(0.5, 0.5, 0.5, 0.0);
+
+ if (MyID == 0) {
+ /* First process */
+
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+
+ glPushMatrix();
+ glTranslatef(-1, 0, 0);
+ glRotatef(Rot, 1, 0, 0);
+ glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, Red);
+ doughnut(0.5, 2.0, 20, 30);
+ glPopMatrix();
+
+ glFinish();
+ if (!Sync) {
+ usleep(1000*10);
+ }
+
+ /* signal second process to render */
+ if (Sync) {
+ int code = 1;
+ if (dbg) printf("0: send signal\n");
+ SendData(Sock, &code, sizeof(code));
+ SendData(Sock, &Rot, sizeof(Rot));
+ }
+
+ /* wait for second process to finish rendering */
+ if (Sync) {
+ int code = 0;
+ if (dbg) printf("0: wait signal\n");
+ ReceiveData(Sock, &code, sizeof(code));
+ if (dbg) printf("0: got signal\n");
+ assert(code == 2);
+ }
+
+ }
+ else {
+ /* Second process */
+
+ /* wait for first process's signal for me to render */
+ if (Sync) {
+ int code = 0;
+ if (dbg) printf("1: wait signal\n");
+ ReceiveData(Sock, &code, sizeof(code));
+ ReceiveData(Sock, &Rot, sizeof(Rot));
+
+ if (dbg) printf("1: got signal\n");
+ assert(code == 1);
+ }
+
+ /* XXX this clear should not be here, but for some reason, it
+ * makes things _mostly_ work correctly w/ NVIDIA's driver.
+ * There's only occasional glitches.
+ * Without this glClear(), depth buffer for the second process
+ * is pretty much broken.
+ */
+ //glClear(GL_DEPTH_BUFFER_BIT);
+
+ glPushMatrix();
+ glTranslatef(1, 0, 0);
+ glRotatef(Rot + 90 , 1, 0, 0);
+ glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, Blue);
+ doughnut(0.5, 2.0, 20, 30);
+ glPopMatrix();
+ glFinish();
+
+ glXSwapBuffers(dpy, WindowID);
+ usleep(1000*10);
+
+ /* signal first process that I'm done rendering */
+ if (Sync) {
+ int code = 2;
+ if (dbg) printf("1: send signal\n");
+ SendData(Sock, &code, sizeof(code));
+ }
+ }
+}
+
+
+static void
+resize(Display *dpy, int width, int height)
+{
+ float ar = (float) width / height;
+
+ glXMakeCurrent(dpy, WindowID, Context);
+
+ glViewport(0, 0, width, height);
+ glMatrixMode(GL_PROJECTION);
+ glLoadIdentity();
+ glFrustum(-ar, ar, 1.0, -1.0, 5.0, 200.0);
+ glMatrixMode(GL_MODELVIEW);
+ glLoadIdentity();
+ glTranslatef(0, 0, -15);
+
+ Width = width;
+ Height = height;
+}
+
+
+
+static void
+set_window_title(Display *dpy, Window win, const char *title)
+{
+ XSizeHints sizehints;
+ sizehints.flags = 0;
+ XSetStandardProperties(dpy, win, title, title,
+ None, (char **)NULL, 0, &sizehints);
+}
+
+
+static Window
+make_gl_window(Display *dpy, XVisualInfo *visinfo, int width, int height)
+{
+ int scrnum;
+ XSetWindowAttributes attr;
+ unsigned long mask;
+ Window root;
+ Window win;
+ int x = 0, y = 0;
+ char *name = NULL;
+
+ scrnum = DefaultScreen( dpy );
+ root = RootWindow( dpy, scrnum );
+
+ /* window attributes */
+ attr.background_pixel = 0;
+ attr.border_pixel = 0;
+ attr.colormap = XCreateColormap( dpy, root, visinfo->visual, AllocNone);
+ attr.event_mask = StructureNotifyMask | ExposureMask | KeyPressMask;
+ mask = CWBackPixel | CWBorderPixel | CWColormap | CWEventMask;
+
+ win = XCreateWindow( dpy, root, x, y, width, height,
+ 0, visinfo->depth, InputOutput,
+ visinfo->visual, mask, &attr );
+
+ /* set hints and properties */
+ {
+ XSizeHints sizehints;
+ sizehints.x = x;
+ sizehints.y = y;
+ sizehints.width = width;
+ sizehints.height = height;
+ sizehints.flags = USSize | USPosition;
+ XSetNormalHints(dpy, win, &sizehints);
+ XSetStandardProperties(dpy, win, name, name,
+ None, (char **)NULL, 0, &sizehints);
+ }
+
+ return win;
+}
+
+
+static void
+set_event_mask(Display *dpy, Window win)
+{
+ XSetWindowAttributes attr;
+ attr.event_mask = StructureNotifyMask | ExposureMask | KeyPressMask;
+ XChangeWindowAttributes(dpy, win, CWEventMask, &attr);
+}
+
+
+static void
+event_loop(Display *dpy)
+{
+ while (1) {
+ while (XPending(dpy) > 0) {
+ XEvent event;
+ XNextEvent(dpy, &event);
+
+ switch (event.type) {
+ case Expose:
+ redraw(dpy);
+ break;
+ case ConfigureNotify:
+ resize(dpy, event.xconfigure.width, event.xconfigure.height);
+ break;
+ case KeyPress:
+ {
+ char buffer[10];
+ int r, code;
+ code = XLookupKeysym(&event.xkey, 0);
+ if (code == XK_Left) {
+ }
+ else {
+ r = XLookupString(&event.xkey, buffer, sizeof(buffer),
+ NULL, NULL);
+ if (buffer[0] == 27) {
+ exit(0);
+ }
+ }
+ }
+ default:
+ /* nothing */
+ ;
+ }
+ }
+
+ if (MyID == 0 || !Sync)
+ Rot += 1;
+ redraw(dpy);
+ }
+}
+
+
+static XVisualInfo *
+choose_visual(Display *dpy)
+{
+ int attribs[] = { GLX_RGBA,
+ GLX_RED_SIZE, 1,
+ GLX_GREEN_SIZE, 1,
+ GLX_BLUE_SIZE, 1,
+ GLX_DOUBLEBUFFER,
+ GLX_DEPTH_SIZE, 1,
+ None };
+ int scrnum = DefaultScreen( dpy );
+ return glXChooseVisual(dpy, scrnum, attribs);
+}
+
+
+static void
+parse_opts(int argc, char *argv[])
+{
+ if (argc > 1) {
+ MyID = 1;
+ }
+}
+
+
+int
+main( int argc, char *argv[] )
+{
+ Display *dpy;
+ XVisualInfo *visinfo;
+
+ parse_opts(argc, argv);
+
+ dpy = XOpenDisplay(NULL);
+
+ visinfo = choose_visual(dpy);
+
+ Context = glXCreateContext( dpy, visinfo, NULL, True );
+ if (!Context) {
+ printf("Error: glXCreateContext failed\n");
+ exit(1);
+ }
+
+ if (MyID == 0) {
+ WindowID = make_gl_window(dpy, visinfo, Width, Height);
+ set_window_title(dpy, WindowID, "corender");
+ XMapWindow(dpy, WindowID);
+ /*printf("WindowID 0x%x\n", (int) WindowID);*/
+ }
+
+ /* do ipc hand-shake here */
+ setup_ipc();
+ assert(Sock);
+ assert(WindowID);
+
+ if (MyID == 1) {
+ set_event_mask(dpy, WindowID);
+ }
+
+ resize(dpy, Width, Height);
+
+ event_loop(dpy);
+
+ return 0;
+}
diff --git a/progs/xdemos/glxgears_pixmap.c b/progs/xdemos/glxgears_pixmap.c
new file mode 100644
index 0000000..661d130
--- /dev/null
+++ b/progs/xdemos/glxgears_pixmap.c
@@ -0,0 +1,547 @@
+/*
+ * Copyright (C) 1999-2001 Brian Paul All Rights Reserved.
+ * Copyright (C) 2008 Red Hat, Inc All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/**
+ * \file glxgears_pixmap.c
+ * Yet-another-version of gears. Originally ported to GLX by Brian Paul on
+ * 23 March 2001. Modified to use fbconfigs by Ian Romanick on 10 Feb 2004.
+ *
+ * Command line options:
+ * -info print GL implementation information
+ *
+ * \author Brian Paul
+ * \author Ian Romanick <idr@us.ibm.com>
+ * \author Kristian Hoegsberg <krh@redhat.com>
+ */
+
+
+#define GLX_GLXEXT_PROTOTYPES
+
+#include <math.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <X11/Xlib.h>
+#include <X11/keysym.h>
+#include <GL/gl.h>
+#include <GL/glx.h>
+#include <GL/glxext.h>
+#include <assert.h>
+#include "pbutil.h"
+
+#define BENCHMARK
+
+#ifdef BENCHMARK
+
+/* XXX this probably isn't very portable */
+
+#include <sys/time.h>
+#include <unistd.h>
+
+/* return current time (in seconds) */
+static int
+current_time(void)
+{
+ struct timeval tv;
+#ifdef __VMS
+ (void) gettimeofday(&tv, NULL );
+#else
+ struct timezone tz;
+ (void) gettimeofday(&tv, &tz);
+#endif
+ return (int) tv.tv_sec;
+}
+
+#else /*BENCHMARK*/
+
+/* dummy */
+static int
+current_time(void)
+{
+ return 0;
+}
+
+#endif /*BENCHMARK*/
+
+
+
+#ifndef M_PI
+#define M_PI 3.14159265
+#endif
+
+
+static GLfloat view_rotx = 20.0, view_roty = 30.0, view_rotz = 0.0;
+static GLint gear1, gear2, gear3;
+static GLfloat angle = 0.0;
+
+
+/*
+ *
+ * Draw a gear wheel. You'll probably want to call this function when
+ * building a display list since we do a lot of trig here.
+ *
+ * Input: inner_radius - radius of hole at center
+ * outer_radius - radius at center of teeth
+ * width - width of gear
+ * teeth - number of teeth
+ * tooth_depth - depth of tooth
+ */
+static void
+gear(GLfloat inner_radius, GLfloat outer_radius, GLfloat width,
+ GLint teeth, GLfloat tooth_depth)
+{
+ GLint i;
+ GLfloat r0, r1, r2;
+ GLfloat angle, da;
+ GLfloat u, v, len;
+
+ r0 = inner_radius;
+ r1 = outer_radius - tooth_depth / 2.0;
+ r2 = outer_radius + tooth_depth / 2.0;
+
+ da = 2.0 * M_PI / teeth / 4.0;
+
+ glShadeModel(GL_FLAT);
+
+ glNormal3f(0.0, 0.0, 1.0);
+
+ /* draw front face */
+ glBegin(GL_QUAD_STRIP);
+ for (i = 0; i <= teeth; i++) {
+ angle = i * 2.0 * M_PI / teeth;
+ glVertex3f(r0 * cos(angle), r0 * sin(angle), width * 0.5);
+ glVertex3f(r1 * cos(angle), r1 * sin(angle), width * 0.5);
+ if (i < teeth) {
+ glVertex3f(r0 * cos(angle), r0 * sin(angle), width * 0.5);
+ glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da),
+ width * 0.5);
+ }
+ }
+ glEnd();
+
+ /* draw front sides of teeth */
+ glBegin(GL_QUADS);
+ da = 2.0 * M_PI / teeth / 4.0;
+ for (i = 0; i < teeth; i++) {
+ angle = i * 2.0 * M_PI / teeth;
+
+ glVertex3f(r1 * cos(angle), r1 * sin(angle), width * 0.5);
+ glVertex3f(r2 * cos(angle + da), r2 * sin(angle + da), width * 0.5);
+ glVertex3f(r2 * cos(angle + 2 * da), r2 * sin(angle + 2 * da),
+ width * 0.5);
+ glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da),
+ width * 0.5);
+ }
+ glEnd();
+
+ glNormal3f(0.0, 0.0, -1.0);
+
+ /* draw back face */
+ glBegin(GL_QUAD_STRIP);
+ for (i = 0; i <= teeth; i++) {
+ angle = i * 2.0 * M_PI / teeth;
+ glVertex3f(r1 * cos(angle), r1 * sin(angle), -width * 0.5);
+ glVertex3f(r0 * cos(angle), r0 * sin(angle), -width * 0.5);
+ if (i < teeth) {
+ glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da),
+ -width * 0.5);
+ glVertex3f(r0 * cos(angle), r0 * sin(angle), -width * 0.5);
+ }
+ }
+ glEnd();
+
+ /* draw back sides of teeth */
+ glBegin(GL_QUADS);
+ da = 2.0 * M_PI / teeth / 4.0;
+ for (i = 0; i < teeth; i++) {
+ angle = i * 2.0 * M_PI / teeth;
+
+ glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da),
+ -width * 0.5);
+ glVertex3f(r2 * cos(angle + 2 * da), r2 * sin(angle + 2 * da),
+ -width * 0.5);
+ glVertex3f(r2 * cos(angle + da), r2 * sin(angle + da), -width * 0.5);
+ glVertex3f(r1 * cos(angle), r1 * sin(angle), -width * 0.5);
+ }
+ glEnd();
+
+ /* draw outward faces of teeth */
+ glBegin(GL_QUAD_STRIP);
+ for (i = 0; i < teeth; i++) {
+ angle = i * 2.0 * M_PI / teeth;
+
+ glVertex3f(r1 * cos(angle), r1 * sin(angle), width * 0.5);
+ glVertex3f(r1 * cos(angle), r1 * sin(angle), -width * 0.5);
+ u = r2 * cos(angle + da) - r1 * cos(angle);
+ v = r2 * sin(angle + da) - r1 * sin(angle);
+ len = sqrt(u * u + v * v);
+ u /= len;
+ v /= len;
+ glNormal3f(v, -u, 0.0);
+ glVertex3f(r2 * cos(angle + da), r2 * sin(angle + da), width * 0.5);
+ glVertex3f(r2 * cos(angle + da), r2 * sin(angle + da), -width * 0.5);
+ glNormal3f(cos(angle), sin(angle), 0.0);
+ glVertex3f(r2 * cos(angle + 2 * da), r2 * sin(angle + 2 * da),
+ width * 0.5);
+ glVertex3f(r2 * cos(angle + 2 * da), r2 * sin(angle + 2 * da),
+ -width * 0.5);
+ u = r1 * cos(angle + 3 * da) - r2 * cos(angle + 2 * da);
+ v = r1 * sin(angle + 3 * da) - r2 * sin(angle + 2 * da);
+ glNormal3f(v, -u, 0.0);
+ glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da),
+ width * 0.5);
+ glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da),
+ -width * 0.5);
+ glNormal3f(cos(angle), sin(angle), 0.0);
+ }
+
+ glVertex3f(r1 * cos(0), r1 * sin(0), width * 0.5);
+ glVertex3f(r1 * cos(0), r1 * sin(0), -width * 0.5);
+
+ glEnd();
+
+ glShadeModel(GL_SMOOTH);
+
+ /* draw inside radius cylinder */
+ glBegin(GL_QUAD_STRIP);
+ for (i = 0; i <= teeth; i++) {
+ angle = i * 2.0 * M_PI / teeth;
+ glNormal3f(-cos(angle), -sin(angle), 0.0);
+ glVertex3f(r0 * cos(angle), r0 * sin(angle), -width * 0.5);
+ glVertex3f(r0 * cos(angle), r0 * sin(angle), width * 0.5);
+ }
+ glEnd();
+}
+
+
+static void
+draw(void)
+{
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+
+ glPushMatrix();
+ glRotatef(view_rotx, 1.0, 0.0, 0.0);
+ glRotatef(view_roty, 0.0, 1.0, 0.0);
+ glRotatef(view_rotz, 0.0, 0.0, 1.0);
+
+ glPushMatrix();
+ glTranslatef(-3.0, -2.0, 0.0);
+ glRotatef(angle, 0.0, 0.0, 1.0);
+ glCallList(gear1);
+ glPopMatrix();
+
+ glPushMatrix();
+ glTranslatef(3.1, -2.0, 0.0);
+ glRotatef(-2.0 * angle - 9.0, 0.0, 0.0, 1.0);
+ glCallList(gear2);
+ glPopMatrix();
+
+ glPushMatrix();
+ glTranslatef(-3.1, 4.2, 0.0);
+ glRotatef(-2.0 * angle - 25.0, 0.0, 0.0, 1.0);
+ glCallList(gear3);
+ glPopMatrix();
+
+ glPopMatrix();
+}
+
+
+struct gears {
+ Window win;
+ GLXContext ctx;
+ Pixmap pixmap;
+ GLXPixmap glxpixmap;
+ GC gc;
+ int width, height;
+};
+
+
+/* new window size or exposure */
+static void
+reshape(struct gears *gears, int width, int height)
+{
+ gears->width = width;
+ gears->height = height;
+}
+
+
+static void
+init(int width, int height)
+{
+ static GLfloat pos[4] = { 5.0, 5.0, 10.0, 0.0 };
+ static GLfloat red[4] = { 0.8, 0.1, 0.0, 1.0 };
+ static GLfloat green[4] = { 0.0, 0.8, 0.2, 1.0 };
+ static GLfloat blue[4] = { 0.2, 0.2, 1.0, 1.0 };
+ GLfloat h = (GLfloat) height / (GLfloat) width;
+
+ glLightfv(GL_LIGHT0, GL_POSITION, pos);
+ glEnable(GL_CULL_FACE);
+ glEnable(GL_LIGHTING);
+ glEnable(GL_LIGHT0);
+ glEnable(GL_DEPTH_TEST);
+
+ /* make the gears */
+ gear1 = glGenLists(1);
+ glNewList(gear1, GL_COMPILE);
+ glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, red);
+ gear(1.0, 4.0, 1.0, 20, 0.7);
+ glEndList();
+
+ gear2 = glGenLists(1);
+ glNewList(gear2, GL_COMPILE);
+ glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, green);
+ gear(0.5, 2.0, 2.0, 10, 0.7);
+ glEndList();
+
+ gear3 = glGenLists(1);
+ glNewList(gear3, GL_COMPILE);
+ glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, blue);
+ gear(1.3, 2.0, 0.5, 10, 0.7);
+ glEndList();
+
+ glEnable(GL_NORMALIZE);
+
+ glViewport(0, 0, (GLint) width, (GLint) height);
+ glMatrixMode(GL_PROJECTION);
+ glLoadIdentity();
+ glFrustum(-1.0, 1.0, -h, h, 5.0, 60.0);
+ glMatrixMode(GL_MODELVIEW);
+ glLoadIdentity();
+ glTranslatef(0.0, 0.0, -40.0);
+}
+
+/*
+ * Create an RGB, double-buffered window.
+ * Return the window and context handles.
+ */
+static void
+make_window( Display *dpy, const char *name,
+ int x, int y, int width, int height, struct gears *gears)
+{
+ int attrib[] = { GLX_DRAWABLE_TYPE, GLX_WINDOW_BIT,
+ GLX_RENDER_TYPE, GLX_RGBA_BIT,
+ GLX_RED_SIZE, 1,
+ GLX_GREEN_SIZE, 1,
+ GLX_BLUE_SIZE, 1,
+ GLX_DOUBLEBUFFER, GL_FALSE,
+ GLX_DEPTH_SIZE, 1,
+ None };
+ GLXFBConfig * fbconfig;
+ int num_configs;
+ int scrnum;
+ XSetWindowAttributes attr;
+ unsigned long mask;
+ Window root;
+ XVisualInfo *visinfo;
+
+ gears->width = width;
+ gears->height = height;
+
+ scrnum = DefaultScreen( dpy );
+ root = RootWindow( dpy, scrnum );
+
+ fbconfig = glXChooseFBConfig(dpy, scrnum, attrib, & num_configs);
+ if (fbconfig == NULL) {
+ printf("Error: couldn't get an RGB, Double-buffered visual\n");
+ exit(1);
+ }
+
+ /* window attributes */
+ visinfo = glXGetVisualFromFBConfig(dpy, fbconfig[0]);
+ assert(visinfo != NULL);
+ attr.background_pixel = 0;
+ attr.border_pixel = 0;
+ attr.colormap = XCreateColormap( dpy, root, visinfo->visual, AllocNone);
+ attr.event_mask = StructureNotifyMask | ExposureMask | KeyPressMask;
+ mask = CWBackPixel | CWBorderPixel | CWColormap | CWEventMask;
+
+ gears->win = XCreateWindow( dpy, root, 0, 0, width, height,
+ 0, visinfo->depth, InputOutput,
+ visinfo->visual, mask, &attr );
+
+ /* set hints and properties */
+ {
+ XSizeHints sizehints;
+ sizehints.x = x;
+ sizehints.y = y;
+ sizehints.width = width;
+ sizehints.height = height;
+ sizehints.flags = USSize | USPosition;
+ XSetNormalHints(dpy, gears->win, &sizehints);
+ XSetStandardProperties(dpy, gears->win, name, name,
+ None, (char **)NULL, 0, &sizehints);
+ }
+
+ gears->gc = XCreateGC(dpy, gears->win, 0, NULL);
+
+ gears->pixmap = XCreatePixmap(dpy, gears->win,
+ width, height, visinfo->depth);
+ if (!gears->pixmap) {
+ printf("Error: XCreatePixmap failed\n");
+ exit(-1);
+ }
+
+ gears->glxpixmap = glXCreatePixmap(dpy, fbconfig[0], gears->pixmap, NULL);
+ if (!gears->glxpixmap) {
+ printf("Error: glXCreatePixmap failed\n");
+ exit(-1);
+ }
+
+ gears->ctx = glXCreateNewContext(dpy, fbconfig[0],
+ GLX_RGBA_TYPE, NULL, GL_TRUE);
+ if (!gears->ctx) {
+ printf("Error: glXCreateNewContext failed\n");
+ exit(1);
+ }
+
+ XFree(fbconfig);
+}
+
+
+static void
+event_loop(Display *dpy, struct gears *gears)
+{
+ int x, y;
+
+ while (1) {
+ while (XPending(dpy) > 0) {
+ XEvent event;
+ XNextEvent(dpy, &event);
+ switch (event.type) {
+ case Expose:
+ /* we'll redraw below */
+ break;
+ case ConfigureNotify:
+ reshape(gears, event.xconfigure.width, event.xconfigure.height);
+ break;
+ case KeyPress:
+ {
+ char buffer[10];
+ int r, code;
+ code = XLookupKeysym(&event.xkey, 0);
+ if (code == XK_Left) {
+ view_roty += 5.0;
+ }
+ else if (code == XK_Right) {
+ view_roty -= 5.0;
+ }
+ else if (code == XK_Up) {
+ view_rotx += 5.0;
+ }
+ else if (code == XK_Down) {
+ view_rotx -= 5.0;
+ }
+ else {
+ r = XLookupString(&event.xkey, buffer, sizeof(buffer),
+ NULL, NULL);
+ if (buffer[0] == 27) {
+ /* escape */
+ return;
+ }
+ }
+ }
+ }
+ }
+
+ /* next frame */
+ angle += 2.0;
+
+ draw();
+ glFinish();
+
+ for (x = 0; x < gears->width; x += 100)
+ for (y = 0; y < gears->width; y += 100)
+ XCopyArea(dpy, gears->pixmap, gears->win, gears->gc,
+ 50, 50, 100, 100, x, y);
+
+ /* calc framerate */
+ {
+ static int t0 = -1;
+ static int frames = 0;
+ int t = current_time();
+
+ if (t0 < 0)
+ t0 = t;
+
+ frames++;
+
+ if (t - t0 >= 5.0) {
+ GLfloat seconds = t - t0;
+ GLfloat fps = frames / seconds;
+ printf("%d frames in %3.1f seconds = %6.3f FPS\n", frames, seconds,
+ fps);
+ t0 = t;
+ frames = 0;
+ }
+ }
+ }
+}
+
+
+int
+main(int argc, char *argv[])
+{
+ Display *dpy;
+ const char *dpyName = NULL;
+ GLboolean printInfo = GL_FALSE;
+ struct gears gears;
+ int i, width = 200, height = 200;
+
+ for (i = 1; i < argc; i++) {
+ if (strcmp(argv[i], "-display") == 0) {
+ dpyName = argv[i+1];
+ i++;
+ }
+ else if (strcmp(argv[i], "-info") == 0) {
+ printInfo = GL_TRUE;
+ }
+ }
+
+ dpy = XOpenDisplay(dpyName);
+ if (!dpy) {
+ printf("Error: couldn't open display %s\n", XDisplayName(dpyName));
+ return -1;
+ }
+
+ make_window(dpy, "glxgears", 0, 0, width, height, &gears);
+ XMapWindow(dpy, gears.win);
+ glXMakeCurrent(dpy, gears.glxpixmap, gears.ctx);
+
+ if (printInfo) {
+ printf("GL_RENDERER = %s\n", (char *) glGetString(GL_RENDERER));
+ printf("GL_VERSION = %s\n", (char *) glGetString(GL_VERSION));
+ printf("GL_VENDOR = %s\n", (char *) glGetString(GL_VENDOR));
+ printf("GL_EXTENSIONS = %s\n", (char *) glGetString(GL_EXTENSIONS));
+ }
+
+ init(width, height);
+
+ event_loop(dpy, &gears);
+
+ glXDestroyContext(dpy, gears.ctx);
+ XDestroyWindow(dpy, gears.win);
+ glXDestroyPixmap(dpy, gears.pixmap);
+ XFreePixmap(dpy, gears.pixmap);
+ XCloseDisplay(dpy);
+
+ return 0;
+}
diff --git a/progs/xdemos/glxinfo.c b/progs/xdemos/glxinfo.c
index 3e8e0be..6cf127a 100644
--- a/progs/xdemos/glxinfo.c
+++ b/progs/xdemos/glxinfo.c
@@ -52,6 +52,13 @@
#define GLX_TRANSPARENT_RGB 0x8008
#endif
+#ifndef GLX_RGBA_BIT
+#define GLX_RGBA_BIT 0x00000001
+#endif
+
+#ifndef GLX_COLOR_INDEX_BIT
+#define GLX_COLOR_INDEX_BIT 0x00000002
+#endif
typedef enum
{
@@ -81,7 +88,7 @@ struct visual_attribs
int transparentIndexValue;
int bufferSize;
int level;
- int rgba;
+ int render_type;
int doubleBuffer;
int stereo;
int auxBuffers;
@@ -388,20 +395,61 @@ print_screen_info(Display *dpy, int scrnum, Bool allowDirect, GLboolean limits)
XSetWindowAttributes attr;
unsigned long mask;
Window root;
- GLXContext ctx;
+ GLXContext ctx = NULL;
XVisualInfo *visinfo;
int width = 100, height = 100;
root = RootWindow(dpy, scrnum);
visinfo = glXChooseVisual(dpy, scrnum, attribSingle);
- if (!visinfo) {
+ if (!visinfo)
visinfo = glXChooseVisual(dpy, scrnum, attribDouble);
- if (!visinfo) {
- fprintf(stderr, "Error: couldn't find RGB GLX visual\n");
- return;
+
+ if (visinfo)
+ ctx = glXCreateContext( dpy, visinfo, NULL, allowDirect );
+
+#ifdef GLX_VERSION_1_3
+ {
+ int fbAttribSingle[] = {
+ GLX_RENDER_TYPE, GLX_RGBA_BIT,
+ GLX_RED_SIZE, 1,
+ GLX_GREEN_SIZE, 1,
+ GLX_BLUE_SIZE, 1,
+ GLX_DOUBLEBUFFER, GL_TRUE,
+ None };
+ int fbAttribDouble[] = {
+ GLX_RENDER_TYPE, GLX_RGBA_BIT,
+ GLX_RED_SIZE, 1,
+ GLX_GREEN_SIZE, 1,
+ GLX_BLUE_SIZE, 1,
+ None };
+ GLXFBConfig *configs = NULL;
+ int nConfigs;
+
+ if (!visinfo)
+ configs = glXChooseFBConfig(dpy, scrnum, fbAttribSingle, &nConfigs);
+ if (!visinfo)
+ configs = glXChooseFBConfig(dpy, scrnum, fbAttribDouble, &nConfigs);
+
+ if (configs) {
+ visinfo = glXGetVisualFromFBConfig(dpy, configs[0]);
+ ctx = glXCreateNewContext(dpy, configs[0], GLX_RGBA_TYPE, NULL, allowDirect);
+ XFree(configs);
}
}
+#endif
+
+ if (!visinfo) {
+ fprintf(stderr, "Error: couldn't find RGB GLX visual or fbconfig\n");
+ return;
+ }
+
+ if (!ctx) {
+ fprintf(stderr, "Error: glXCreateContext failed\n");
+ XFree(visinfo);
+ XDestroyWindow(dpy, win);
+ return;
+ }
attr.background_pixel = 0;
attr.border_pixel = 0;
@@ -412,14 +460,6 @@ print_screen_info(Display *dpy, int scrnum, Bool allowDirect, GLboolean limits)
0, visinfo->depth, InputOutput,
visinfo->visual, mask, &attr);
- ctx = glXCreateContext( dpy, visinfo, NULL, allowDirect );
- if (!ctx) {
- fprintf(stderr, "Error: glXCreateContext failed\n");
- XFree(visinfo);
- XDestroyWindow(dpy, win);
- return;
- }
-
if (glXMakeCurrent(dpy, win, ctx)) {
const char *serverVendor = glXQueryServerString(dpy, scrnum, GLX_VENDOR);
const char *serverVersion = glXQueryServerString(dpy, scrnum, GLX_VERSION);
@@ -483,6 +523,13 @@ print_screen_info(Display *dpy, int scrnum, Bool allowDirect, GLboolean limits)
printf("OpenGL vendor string: %s\n", glVendor);
printf("OpenGL renderer string: %s\n", glRenderer);
printf("OpenGL version string: %s\n", glVersion);
+#ifdef GL_VERSION_2_0
+ if (glVersion[0] >= '2' && glVersion[1] == '.') {
+ char *v = (char *) glGetString(GL_SHADING_LANGUAGE_VERSION);
+ printf("OpenGL shading language version string: %s\n", v);
+ }
+#endif
+
printf("OpenGL extensions:\n");
print_extension_list(glExtensions);
if (limits)
@@ -541,12 +588,27 @@ visual_class_abbrev(int cls)
}
}
+static const char *
+visual_render_type_name(int type)
+{
+ switch (type) {
+ case GLX_RGBA_BIT:
+ return "rgba";
+ case GLX_COLOR_INDEX_BIT:
+ return "ci";
+ case GLX_RGBA_BIT | GLX_COLOR_INDEX_BIT:
+ return "rgba|ci";
+ default:
+ return "";
+ }
+}
-static void
+static GLboolean
get_visual_attribs(Display *dpy, XVisualInfo *vInfo,
struct visual_attribs *attribs)
{
const char *ext = glXQueryExtensionsString(dpy, vInfo->screen);
+ int rgba;
memset(attribs, 0, sizeof(struct visual_attribs));
@@ -563,11 +625,17 @@ get_visual_attribs(Display *dpy, XVisualInfo *vInfo,
attribs->colormapSize = vInfo->colormap_size;
attribs->bitsPerRGB = vInfo->bits_per_rgb;
- if (glXGetConfig(dpy, vInfo, GLX_USE_GL, &attribs->supportsGL) != 0)
- return;
+ if (glXGetConfig(dpy, vInfo, GLX_USE_GL, &attribs->supportsGL) != 0 ||
+ !attribs->supportsGL)
+ return GL_FALSE;
glXGetConfig(dpy, vInfo, GLX_BUFFER_SIZE, &attribs->bufferSize);
glXGetConfig(dpy, vInfo, GLX_LEVEL, &attribs->level);
- glXGetConfig(dpy, vInfo, GLX_RGBA, &attribs->rgba);
+ glXGetConfig(dpy, vInfo, GLX_RGBA, &rgba);
+ if (rgba)
+ attribs->render_type = GLX_RGBA_BIT;
+ else
+ attribs->render_type = GLX_COLOR_INDEX_BIT;
+
glXGetConfig(dpy, vInfo, GLX_DOUBLEBUFFER, &attribs->doubleBuffer);
glXGetConfig(dpy, vInfo, GLX_STEREO, &attribs->stereo);
glXGetConfig(dpy, vInfo, GLX_AUX_BUFFERS, &attribs->auxBuffers);
@@ -596,7 +664,7 @@ get_visual_attribs(Display *dpy, XVisualInfo *vInfo,
/* multisample attribs */
#ifdef GLX_ARB_multisample
- if (ext && strstr(ext, "GLX_ARB_multisample") == 0) {
+ if (ext && strstr(ext, "GLX_ARB_multisample")) {
glXGetConfig(dpy, vInfo, GLX_SAMPLE_BUFFERS_ARB, &attribs->numMultisample);
glXGetConfig(dpy, vInfo, GLX_SAMPLES_ARB, &attribs->numSamples);
}
@@ -616,8 +684,97 @@ get_visual_attribs(Display *dpy, XVisualInfo *vInfo,
#else
attribs->visualCaveat = 0;
#endif
+
+ return GL_TRUE;
+}
+
+#ifdef GLX_VERSION_1_3
+
+static int
+glx_token_to_visual_class(int visual_type)
+{
+ switch (visual_type) {
+ case GLX_TRUE_COLOR:
+ return TrueColor;
+ case GLX_DIRECT_COLOR:
+ return DirectColor;
+ case GLX_PSEUDO_COLOR:
+ return PseudoColor;
+ case GLX_STATIC_COLOR:
+ return StaticColor;
+ case GLX_GRAY_SCALE:
+ return GrayScale;
+ case GLX_STATIC_GRAY:
+ return StaticGray;
+ case GLX_NONE:
+ default:
+ return None;
+ }
+}
+
+static GLboolean
+get_fbconfig_attribs(Display *dpy, GLXFBConfig fbconfig,
+ struct visual_attribs *attribs)
+{
+ int visual_type;
+
+ memset(attribs, 0, sizeof(struct visual_attribs));
+
+ glXGetFBConfigAttrib(dpy, fbconfig, GLX_FBCONFIG_ID, &attribs->id);
+
+#if 0
+ attribs->depth = vInfo->depth;
+ attribs->redMask = vInfo->red_mask;
+ attribs->greenMask = vInfo->green_mask;
+ attribs->blueMask = vInfo->blue_mask;
+ attribs->colormapSize = vInfo->colormap_size;
+ attribs->bitsPerRGB = vInfo->bits_per_rgb;
+#endif
+
+ glXGetFBConfigAttrib(dpy, fbconfig, GLX_X_VISUAL_TYPE, &visual_type);
+ attribs->klass = glx_token_to_visual_class(visual_type);
+
+ glXGetFBConfigAttrib(dpy, fbconfig, GLX_BUFFER_SIZE, &attribs->bufferSize);
+ glXGetFBConfigAttrib(dpy, fbconfig, GLX_LEVEL, &attribs->level);
+ glXGetFBConfigAttrib(dpy, fbconfig, GLX_RENDER_TYPE, &attribs->render_type);
+ glXGetFBConfigAttrib(dpy, fbconfig, GLX_DOUBLEBUFFER, &attribs->doubleBuffer);
+ glXGetFBConfigAttrib(dpy, fbconfig, GLX_STEREO, &attribs->stereo);
+ glXGetFBConfigAttrib(dpy, fbconfig, GLX_AUX_BUFFERS, &attribs->auxBuffers);
+
+ glXGetFBConfigAttrib(dpy, fbconfig, GLX_RED_SIZE, &attribs->redSize);
+ glXGetFBConfigAttrib(dpy, fbconfig, GLX_GREEN_SIZE, &attribs->greenSize);
+ glXGetFBConfigAttrib(dpy, fbconfig, GLX_BLUE_SIZE, &attribs->blueSize);
+ glXGetFBConfigAttrib(dpy, fbconfig, GLX_ALPHA_SIZE, &attribs->alphaSize);
+ glXGetFBConfigAttrib(dpy, fbconfig, GLX_DEPTH_SIZE, &attribs->depthSize);
+ glXGetFBConfigAttrib(dpy, fbconfig, GLX_STENCIL_SIZE, &attribs->stencilSize);
+
+ glXGetFBConfigAttrib(dpy, fbconfig, GLX_ACCUM_RED_SIZE, &attribs->accumRedSize);
+ glXGetFBConfigAttrib(dpy, fbconfig, GLX_ACCUM_GREEN_SIZE, &attribs->accumGreenSize);
+ glXGetFBConfigAttrib(dpy, fbconfig, GLX_ACCUM_BLUE_SIZE, &attribs->accumBlueSize);
+ glXGetFBConfigAttrib(dpy, fbconfig, GLX_ACCUM_ALPHA_SIZE, &attribs->accumAlphaSize);
+
+ /* get transparent pixel stuff */
+ glXGetFBConfigAttrib(dpy, fbconfig,GLX_TRANSPARENT_TYPE, &attribs->transparentType);
+ if (attribs->transparentType == GLX_TRANSPARENT_RGB) {
+ glXGetFBConfigAttrib(dpy, fbconfig, GLX_TRANSPARENT_RED_VALUE, &attribs->transparentRedValue);
+ glXGetFBConfigAttrib(dpy, fbconfig, GLX_TRANSPARENT_GREEN_VALUE, &attribs->transparentGreenValue);
+ glXGetFBConfigAttrib(dpy, fbconfig, GLX_TRANSPARENT_BLUE_VALUE, &attribs->transparentBlueValue);
+ glXGetFBConfigAttrib(dpy, fbconfig, GLX_TRANSPARENT_ALPHA_VALUE, &attribs->transparentAlphaValue);
+ }
+ else if (attribs->transparentType == GLX_TRANSPARENT_INDEX) {
+ glXGetFBConfigAttrib(dpy, fbconfig, GLX_TRANSPARENT_INDEX_VALUE, &attribs->transparentIndexValue);
+ }
+
+ glXGetFBConfigAttrib(dpy, fbconfig, GLX_SAMPLE_BUFFERS, &attribs->numMultisample);
+ glXGetFBConfigAttrib(dpy, fbconfig, GLX_SAMPLES, &attribs->numSamples);
+ glXGetFBConfigAttrib(dpy, fbconfig, GLX_CONFIG_CAVEAT, &attribs->visualCaveat);
+
+ return GL_TRUE;
}
+#endif
+
+
static void
print_visual_attribs_verbose(const struct visual_attribs *attribs)
@@ -625,7 +782,8 @@ print_visual_attribs_verbose(const struct visual_attribs *attribs)
printf("Visual ID: %x depth=%d class=%s\n",
attribs->id, attribs->depth, visual_class_name(attribs->klass));
printf(" bufferSize=%d level=%d renderType=%s doubleBuffer=%d stereo=%d\n",
- attribs->bufferSize, attribs->level, attribs->rgba ? "rgba" : "ci",
+ attribs->bufferSize, attribs->level,
+ visual_render_type_name(attribs->render_type),
attribs->doubleBuffer, attribs->stereo);
printf(" rgba: redSize=%d greenSize=%d blueSize=%d alphaSize=%d\n",
attribs->redSize, attribs->greenSize,
@@ -683,16 +841,17 @@ print_visual_attribs_short(const struct visual_attribs *attribs)
caveat = "None";
#endif
- printf("0x%2x %2d %2s %2d %2d %2d %1s %2s %2s %2d %2d %2d %2d %2d %2d %2d",
+ printf("0x%02x %2d %2s %2d %2d %2d %c%c %c %c %2d %2d %2d %2d %2d %2d %2d",
attribs->id,
attribs->depth,
visual_class_abbrev(attribs->klass),
attribs->transparentType != GLX_NONE,
attribs->bufferSize,
attribs->level,
- attribs->rgba ? "r" : "c",
- attribs->doubleBuffer ? "y" : ".",
- attribs->stereo ? "y" : ".",
+ (attribs->render_type & GLX_RGBA_BIT) ? 'r' : ' ',
+ (attribs->render_type & GLX_COLOR_INDEX_BIT) ? 'c' : ' ',
+ attribs->doubleBuffer ? 'y' : '.',
+ attribs->stereo ? 'y' : '.',
attribs->redSize, attribs->greenSize,
attribs->blueSize, attribs->alphaSize,
attribs->auxBuffers,
@@ -728,7 +887,7 @@ print_visual_attribs_long(const struct visual_attribs *attribs)
attribs->transparentType != GLX_NONE,
attribs->bufferSize,
attribs->level,
- attribs->rgba ? "rgba" : "ci ",
+ visual_render_type_name(attribs->render_type),
attribs->doubleBuffer,
attribs->stereo,
attribs->redSize, attribs->greenSize,
@@ -751,42 +910,86 @@ print_visual_info(Display *dpy, int scrnum, InfoMode mode)
{
XVisualInfo theTemplate;
XVisualInfo *visuals;
- int numVisuals;
+ int numVisuals, numGlxVisuals;
long mask;
int i;
+ struct visual_attribs attribs;
/* get list of all visuals on this screen */
theTemplate.screen = scrnum;
mask = VisualScreenMask;
visuals = XGetVisualInfo(dpy, mask, &theTemplate, &numVisuals);
- if (mode == Verbose) {
- for (i = 0; i < numVisuals; i++) {
- struct visual_attribs attribs;
- get_visual_attribs(dpy, &visuals[i], &attribs);
- print_visual_attribs_verbose(&attribs);
- }
+ numGlxVisuals = 0;
+ for (i = 0; i < numVisuals; i++) {
+ if (get_visual_attribs(dpy, &visuals[i], &attribs))
+ numGlxVisuals++;
}
- else if (mode == Normal) {
+
+ if (numGlxVisuals == 0)
+ return;
+
+ printf("%d GLX Visuals\n", numGlxVisuals);
+
+ if (mode == Normal)
print_visual_attribs_short_header();
- for (i = 0; i < numVisuals; i++) {
- struct visual_attribs attribs;
- get_visual_attribs(dpy, &visuals[i], &attribs);
+ else if (mode == Wide)
+ print_visual_attribs_long_header();
+
+ for (i = 0; i < numVisuals; i++) {
+ if (!get_visual_attribs(dpy, &visuals[i], &attribs))
+ continue;
+
+ if (mode == Verbose)
+ print_visual_attribs_verbose(&attribs);
+ else if (mode == Normal)
print_visual_attribs_short(&attribs);
- }
+ else if (mode == Wide)
+ print_visual_attribs_long(&attribs);
}
- else if (mode == Wide) {
+ printf("\n");
+
+ XFree(visuals);
+}
+
+#ifdef GLX_VERSION_1_3
+
+static void
+print_fbconfig_info(Display *dpy, int scrnum, InfoMode mode)
+{
+ int numFBConfigs;
+ struct visual_attribs attribs;
+ GLXFBConfig *fbconfigs;
+ int i;
+
+ /* get list of all fbconfigs on this screen */
+ fbconfigs = glXGetFBConfigs(dpy, scrnum, &numFBConfigs);
+
+ if (numFBConfigs == 0)
+ return;
+
+ printf("%d GLXFBConfigs:\n", numFBConfigs);
+ if (mode == Normal)
+ print_visual_attribs_short_header();
+ else if (mode == Wide)
print_visual_attribs_long_header();
- for (i = 0; i < numVisuals; i++) {
- struct visual_attribs attribs;
- get_visual_attribs(dpy, &visuals[i], &attribs);
+
+ for (i = 0; i < numFBConfigs; i++) {
+ get_fbconfig_attribs(dpy, fbconfigs[i], &attribs);
+
+ if (mode == Verbose)
+ print_visual_attribs_verbose(&attribs);
+ else if (mode == Normal)
+ print_visual_attribs_short(&attribs);
+ else if (mode == Wide)
print_visual_attribs_long(&attribs);
- }
}
+ printf("\n");
- XFree(visuals);
+ XFree(fbconfigs);
}
+#endif
/*
* Stand-alone Mesa doesn't really implement the GLX protocol so it
@@ -860,7 +1063,7 @@ find_best_visual(Display *dpy, int scrnum)
/* see if this vis is better than bestVis */
if ((!bestVis.supportsGL && vis.supportsGL) ||
(bestVis.visualCaveat != GLX_NONE_EXT) ||
- (!bestVis.rgba && vis.rgba) ||
+ (!(bestVis.render_type & GLX_RGBA_BIT) && (vis.render_type & GLX_RGBA_BIT)) ||
(!bestVis.doubleBuffer && vis.doubleBuffer) ||
(bestVis.redSize < vis.redSize) ||
(bestVis.greenSize < vis.greenSize) ||
@@ -957,6 +1160,9 @@ main(int argc, char *argv[])
print_screen_info(dpy, scrnum, allowDirect, limits);
printf("\n");
print_visual_info(dpy, scrnum, mode);
+#ifdef GLX_VERSION_1_3
+ print_fbconfig_info(dpy, scrnum, mode);
+#endif
if (scrnum + 1 < numScreens)
printf("\n\n");
}
diff --git a/progs/xdemos/glxsnoop.c b/progs/xdemos/glxsnoop.c
new file mode 100644
index 0000000..2e95134
--- /dev/null
+++ b/progs/xdemos/glxsnoop.c
@@ -0,0 +1,377 @@
+/**
+ * Display/snoop the z/stencil/back/front buffers of another app's window.
+ * Also, an example of the need for shared ancillary renderbuffers.
+ *
+ * Hint: use 'xwininfo' to get a window's ID.
+ *
+ * Brian Paul
+ * 11 Oct 2007
+ */
+
+#define GL_GLEXT_PROTOTYPES
+
+#include <GL/gl.h>
+#include <GL/glx.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <X11/keysym.h>
+
+
+#define Z_BUFFER 1
+#define STENCIL_BUFFER 2
+#define BACK_BUFFER 3
+#define FRONT_BUFFER 4
+
+
+static int Buffer = BACK_BUFFER;
+static int WindowID = 0;
+static const char *DisplayName = NULL;
+static GLXContext Context = 0;
+static int Width, Height;
+
+
+/**
+ * Grab the z/stencil/back/front image from the srcWin and display it
+ * (possibly converted to grayscale) in the dstWin.
+ */
+static void
+redraw(Display *dpy, Window srcWin, Window dstWin )
+{
+ GLubyte *image = malloc(Width * Height * 4);
+
+ glXMakeCurrent(dpy, srcWin, Context);
+ glPixelStorei(GL_PACK_ALIGNMENT, 1);
+ if (Buffer == BACK_BUFFER) {
+ glReadBuffer(GL_BACK);
+ glReadPixels(0, 0, Width, Height, GL_RGBA, GL_UNSIGNED_BYTE, image);
+ }
+ else if (Buffer == FRONT_BUFFER) {
+ glReadBuffer(GL_FRONT);
+ glReadPixels(0, 0, Width, Height, GL_RGBA, GL_UNSIGNED_BYTE, image);
+ }
+ else if (Buffer == Z_BUFFER) {
+ GLfloat *z = malloc(Width * Height * sizeof(GLfloat));
+ int i;
+ glReadPixels(0, 0, Width, Height, GL_DEPTH_COMPONENT, GL_FLOAT, z);
+ for (i = 0; i < Width * Height; i++) {
+ image[i*4+0] =
+ image[i*4+1] =
+ image[i*4+2] = (GLint) (255.0 * z[i]);
+ image[i*4+3] = 255;
+ }
+ free(z);
+ }
+ else if (Buffer == STENCIL_BUFFER) {
+ GLubyte *sten = malloc(Width * Height * sizeof(GLubyte));
+ int i, min = 100, max = -1;
+ float step;
+ int sz;
+ glGetIntegerv(GL_STENCIL_BITS, &sz);
+ glReadPixels(0, 0, Width, Height,
+ GL_STENCIL_INDEX, GL_UNSIGNED_BYTE, sten);
+ /* find min/max for converting stencil to grayscale */
+ for (i = 0; i < Width * Height; i++) {
+ if (sten[i] < min)
+ min = sten[i];
+ if (sten[i] > max)
+ max = sten[i];
+ }
+ if (min == max)
+ step = 0;
+ else
+ step = 255.0 / (float) (max - min);
+ for (i = 0; i < Width * Height; i++) {
+ image[i*4+0] =
+ image[i*4+1] =
+ image[i*4+2] = (GLint) ((sten[i] - min) * step);
+ image[i*4+3] = 255;
+ }
+ free(sten);
+ }
+
+ glXMakeCurrent(dpy, dstWin, Context);
+ glWindowPos2iARB(0, 0);
+ glDrawBuffer(GL_FRONT);
+ glDrawPixels(Width, Height, GL_RGBA, GL_UNSIGNED_BYTE, image);
+ glFlush();
+
+ free(image);
+}
+
+
+static void
+set_window_title(Display *dpy, Window win, const char *title)
+{
+ XSizeHints sizehints;
+ sizehints.flags = 0;
+ XSetStandardProperties(dpy, win, title, title,
+ None, (char **)NULL, 0, &sizehints);
+}
+
+
+static Window
+make_gl_window(Display *dpy, XVisualInfo *visinfo, int width, int height)
+{
+ int scrnum;
+ XSetWindowAttributes attr;
+ unsigned long mask;
+ Window root;
+ Window win;
+ int x = 0, y = 0;
+ char *name = NULL;
+
+ scrnum = DefaultScreen( dpy );
+ root = RootWindow( dpy, scrnum );
+
+ /* window attributes */
+ attr.background_pixel = 0;
+ attr.border_pixel = 0;
+ attr.colormap = XCreateColormap( dpy, root, visinfo->visual, AllocNone);
+ attr.event_mask = StructureNotifyMask | ExposureMask | KeyPressMask;
+ mask = CWBackPixel | CWBorderPixel | CWColormap | CWEventMask;
+
+ win = XCreateWindow( dpy, root, x, y, width, height,
+ 0, visinfo->depth, InputOutput,
+ visinfo->visual, mask, &attr );
+
+ /* set hints and properties */
+ {
+ XSizeHints sizehints;
+ sizehints.x = x;
+ sizehints.y = y;
+ sizehints.width = width;
+ sizehints.height = height;
+ sizehints.flags = USSize | USPosition;
+ XSetNormalHints(dpy, win, &sizehints);
+ XSetStandardProperties(dpy, win, name, name,
+ None, (char **)NULL, 0, &sizehints);
+ }
+
+ return win;
+}
+
+
+static void
+update_window_title(Display *dpy, Window win)
+{
+ char title[1000], *buf;
+
+ switch (Buffer) {
+ case Z_BUFFER:
+ buf = "Z";
+ break;
+ case STENCIL_BUFFER:
+ buf = "Stencil";
+ break;
+ case BACK_BUFFER:
+ buf = "Back";
+ break;
+ case FRONT_BUFFER:
+ buf = "Front";
+ break;
+ default:
+ buf = "";
+ }
+
+ sprintf(title, "glxsnoop window 0x%x (%s buffer)", (int) WindowID, buf);
+
+ set_window_title(dpy, win, title);
+}
+
+
+static void
+keypress(Display *dpy, Window win, char key)
+{
+ switch (key) {
+ case 27:
+ /* escape */
+ exit(0);
+ break;
+ case 's':
+ Buffer = STENCIL_BUFFER;
+ break;
+ case 'z':
+ Buffer = Z_BUFFER;
+ break;
+ case 'f':
+ Buffer = FRONT_BUFFER;
+ break;
+ case 'b':
+ Buffer = BACK_BUFFER;
+ break;
+ default:
+ return;
+ }
+
+ update_window_title(dpy, win);
+ redraw(dpy, WindowID, win);
+}
+
+
+static void
+event_loop(Display *dpy, Window win)
+{
+ XEvent event;
+
+ while (1) {
+ XNextEvent( dpy, &event );
+
+ switch (event.type) {
+ case Expose:
+ redraw(dpy, WindowID, win);
+ break;
+ case ConfigureNotify:
+ /*resize( event.xconfigure.width, event.xconfigure.height );*/
+ break;
+ case KeyPress:
+ {
+ char buffer[10];
+ int r, code;
+ code = XLookupKeysym(&event.xkey, 0);
+ if (code == XK_Left) {
+ }
+ else {
+ r = XLookupString(&event.xkey, buffer, sizeof(buffer),
+ NULL, NULL);
+ keypress(dpy, win, buffer[0]);
+ }
+ }
+ default:
+ /* nothing */
+ ;
+ }
+ }
+}
+
+
+static VisualID
+get_window_visualid(Display *dpy, Window win)
+{
+ XWindowAttributes attr;
+
+ if (XGetWindowAttributes(dpy, win, &attr)) {
+ return attr.visual->visualid;
+ }
+ else {
+ return 0;
+ }
+}
+
+
+static void
+get_window_size(Display *dpy, Window win, int *w, int *h)
+{
+ XWindowAttributes attr;
+
+ if (XGetWindowAttributes(dpy, win, &attr)) {
+ *w = attr.width;
+ *h = attr.height;
+ }
+ else {
+ *w = *h = 0;
+ }
+}
+
+
+static XVisualInfo *
+visualid_to_visualinfo(Display *dpy, VisualID vid)
+{
+ XVisualInfo *vinfo, templ;
+ long mask;
+ int n;
+
+ templ.visualid = vid;
+ mask = VisualIDMask;
+
+ vinfo = XGetVisualInfo(dpy, mask, &templ, &n);
+ return vinfo;
+}
+
+
+static void
+key_usage(void)
+{
+ printf("Keyboard:\n");
+ printf(" z - display Z buffer\n");
+ printf(" s - display stencil buffer\n");
+ printf(" f - display front color buffer\n");
+ printf(" b - display back buffer\n");
+}
+
+
+static void
+usage(void)
+{
+ printf("Usage: glxsnoop [-display dpy] windowID\n");
+ key_usage();
+}
+
+
+static void
+parse_opts(int argc, char *argv[])
+{
+ int i;
+
+ for (i = 1; i < argc; i++) {
+ if (strcmp(argv[i], "-h") == 0) {
+ usage();
+ exit(0);
+ }
+ else if (strcmp(argv[i], "-display") == 0) {
+ DisplayName = argv[i + 1];
+ i++;
+ }
+ else {
+ if (argv[i][0] == '0' && argv[i][1] == 'x') {
+ /* hex */
+ WindowID = strtol(argv[i], NULL, 16);
+ }
+ else {
+ WindowID = atoi(argv[i]);
+ }
+ break;
+ }
+ }
+
+ if (!WindowID) {
+ usage();
+ exit(0);
+ }
+}
+
+
+int
+main( int argc, char *argv[] )
+{
+ Display *dpy;
+ VisualID vid;
+ XVisualInfo *visinfo;
+ Window win;
+
+ parse_opts(argc, argv);
+
+ key_usage();
+
+ dpy = XOpenDisplay(DisplayName);
+
+ /* find the VisualID for the named window */
+ vid = get_window_visualid(dpy, WindowID);
+ get_window_size(dpy, WindowID, &Width, &Height);
+
+ visinfo = visualid_to_visualinfo(dpy, vid);
+
+ Context = glXCreateContext( dpy, visinfo, NULL, True );
+ if (!Context) {
+ printf("Error: glXCreateContext failed\n");
+ exit(1);
+ }
+
+ win = make_gl_window(dpy, visinfo, Width, Height);
+ XMapWindow(dpy, win);
+ update_window_title(dpy, win);
+
+ event_loop( dpy, win );
+
+ return 0;
+}
diff --git a/progs/xdemos/glxswapcontrol.c b/progs/xdemos/glxswapcontrol.c
index d9be984..e429d58 100644
--- a/progs/xdemos/glxswapcontrol.c
+++ b/progs/xdemos/glxswapcontrol.c
@@ -814,6 +814,11 @@ main(int argc, char *argv[])
init();
+ /* Set initial projection/viewing transformation.
+ * same as glxgears.c
+ */
+ reshape(300, 300);
+
event_loop(dpy, win);
glXDestroyContext(dpy, ctx);
diff --git a/progs/xdemos/ipc.c b/progs/xdemos/ipc.c
new file mode 100644
index 0000000..c872d16
--- /dev/null
+++ b/progs/xdemos/ipc.c
@@ -0,0 +1,264 @@
+/* Copyright (c) 2003 Tungsten Graphics, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files ("the
+ * Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions: The above copyright notice, the Tungsten
+ * Graphics splash screen, and this permission notice shall be included
+ * in all copies or substantial portions of the Software. THE SOFTWARE
+ * IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
+ * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
+ * SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
+ * THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/*
+ * Simple IPC API
+ * Brian Paul
+ */
+
+
+#include <assert.h>
+#include <stdio.h>
+#include <string.h>
+#include <sys/types.h>
+#include <netinet/in.h>
+#include <netinet/tcp.h>
+#include <arpa/inet.h>
+#include <netdb.h>
+#include <unistd.h>
+#include <sys/socket.h>
+#include "ipc.h"
+
+#if defined(IRIX) || defined(irix)
+typedef int socklen_t;
+#endif
+
+#define NO_DELAY 1
+
+#define DEFAULT_MASTER_PORT 7011
+
+
+/*
+ * Return my hostname in <nameOut>.
+ * Return 1 for success, 0 for error.
+ */
+int
+MyHostName(char *nameOut, int maxNameLength)
+{
+ int k = gethostname(nameOut, maxNameLength);
+ return k==0;
+}
+
+
+/*
+ * Create a socket attached to a port. Later, we can call AcceptConnection
+ * on the socket returned from this function.
+ * Return the new socket number or -1 if error.
+ */
+int
+CreatePort(int *port)
+{
+ char hostname[1000];
+ struct sockaddr_in servaddr;
+ struct hostent *hp;
+ int so_reuseaddr = 1;
+ int tcp_nodelay = 1;
+ int sock, k;
+
+ /* create socket */
+ sock = socket(AF_INET, SOCK_STREAM, 0);
+ assert(sock > 2);
+
+ /* get my host name */
+ k = gethostname(hostname, 1000);
+ assert(k == 0);
+
+ /* get hostent info */
+ hp = gethostbyname(hostname);
+ assert(hp);
+
+ /* initialize the servaddr struct */
+ memset(&servaddr, 0, sizeof(servaddr) );
+ servaddr.sin_family = AF_INET;
+ servaddr.sin_port = htons((unsigned short) (*port));
+ memcpy((char *) &servaddr.sin_addr, hp->h_addr,
+ sizeof(servaddr.sin_addr));
+
+ /* deallocate when we exit */
+ k = setsockopt(sock, SOL_SOCKET, SO_REUSEADDR,
+ (char *) &so_reuseaddr, sizeof(so_reuseaddr));
+ assert(k==0);
+
+ /* send packets immediately */
+#if NO_DELAY
+ k = setsockopt(sock, IPPROTO_TCP, TCP_NODELAY,
+ (char *) &tcp_nodelay, sizeof(tcp_nodelay));
+ assert(k==0);
+#endif
+
+ if (*port == 0)
+ *port = DEFAULT_MASTER_PORT;
+
+ k = 1;
+ while (k && (*port < 65534)) {
+ /* bind our address to the socket */
+ servaddr.sin_port = htons((unsigned short) (*port));
+ k = bind(sock, (struct sockaddr *) &servaddr, sizeof(servaddr));
+ if (k)
+ *port = *port + 1;
+ }
+
+#if 0
+ printf("###### Real Port: %d\n", *port);
+#endif
+
+ /* listen for connections */
+ k = listen(sock, 100);
+ assert(k == 0);
+
+ return sock;
+}
+
+
+/*
+ * Accept a connection on the named socket.
+ * Return a new socket for the new connection, or -1 if error.
+ */
+int
+AcceptConnection(int socket)
+{
+ struct sockaddr addr;
+ socklen_t addrLen;
+ int newSock;
+
+ addrLen = sizeof(addr);
+ newSock = accept(socket, &addr, &addrLen);
+ if (newSock == 1)
+ return -1;
+ else
+ return newSock;
+}
+
+
+/*
+ * Contact the server running on the given host on the named port.
+ * Return socket number or -1 if error.
+ */
+int
+Connect(const char *hostname, int port)
+{
+ struct sockaddr_in servaddr;
+ struct hostent *hp;
+ int sock, k;
+ int tcp_nodelay = 1;
+
+ assert(port);
+
+ sock = socket(AF_INET, SOCK_STREAM, 0);
+ assert(sock >= 0);
+
+ hp = gethostbyname(hostname);
+ assert(hp);
+
+ memset(&servaddr, 0, sizeof(servaddr));
+ servaddr.sin_family = AF_INET;
+ servaddr.sin_port = htons((unsigned short) port);
+ memcpy((char *) &servaddr.sin_addr, hp->h_addr, sizeof(servaddr.sin_addr));
+
+ k = connect(sock, (struct sockaddr *) &servaddr, sizeof(servaddr));
+ if (k != 0) {
+ perror("Connect:");
+ return -1;
+ }
+
+#if NO_DELAY
+ /* send packets immediately */
+ k = setsockopt(sock, IPPROTO_TCP, TCP_NODELAY,
+ (char *) &tcp_nodelay, sizeof(tcp_nodelay));
+ assert(k==0);
+#endif
+
+ return sock;
+}
+
+
+void
+CloseSocket(int socket)
+{
+ close(socket);
+}
+
+
+int
+SendData(int socket, const void *data, int bytes)
+{
+ int sent = 0;
+ int b;
+
+ while (sent < bytes) {
+ b = write(socket, (char *) data + sent, bytes - sent);
+ if (b <= 0)
+ return -1; /* something broke */
+ sent += b;
+ }
+ return sent;
+}
+
+
+int
+ReceiveData(int socket, void *data, int bytes)
+{
+ int received = 0, b;
+
+ while (received < bytes) {
+ b = read(socket, (char *) data + received, bytes - received);
+ if (b <= 0)
+ return -1;
+ received += b;
+ }
+ return received;
+}
+
+
+int
+SendString(int socket, const char *str)
+{
+ const int len = strlen(str);
+ int sent, b;
+
+ /* first, send a 4-byte length indicator */
+ b = write(socket, &len, sizeof(len));
+ if (b <= 0)
+ return -1;
+
+ sent = SendData(socket, str, len);
+ assert(sent == len);
+ return sent;
+}
+
+
+int
+ReceiveString(int socket, char *str, int maxLen)
+{
+ int len, received, b;
+
+ /* first, read 4 bytes to see how long of string to receive */
+ b = read(socket, &len, sizeof(len));
+ if (b <= 0)
+ return -1;
+
+ assert(len <= maxLen); /* XXX fix someday */
+ assert(len >= 0);
+ received = ReceiveData(socket, str, len);
+ assert(received != -1);
+ assert(received == len);
+ str[len] = 0;
+ return received;
+}
diff --git a/progs/xdemos/ipc.h b/progs/xdemos/ipc.h
new file mode 100644
index 0000000..3f43445
--- /dev/null
+++ b/progs/xdemos/ipc.h
@@ -0,0 +1,16 @@
+#ifndef IPC_H
+#define IPC_H
+
+
+extern int MyHostName(char *nameOut, int maxNameLength);
+extern int CreatePort(int *port);
+extern int AcceptConnection(int socket);
+extern int Connect(const char *hostname, int port);
+extern void CloseSocket(int socket);
+extern int SendData(int socket, const void *data, int bytes);
+extern int ReceiveData(int socket, void *data, int bytes);
+extern int SendString(int socket, const char *str);
+extern int ReceiveString(int socket, char *str, int maxLen);
+
+
+#endif /* IPC_H */
diff --git a/progs/xdemos/offset.c b/progs/xdemos/offset.c
index 0ad9147..6c5abf3 100644
--- a/progs/xdemos/offset.c
+++ b/progs/xdemos/offset.c
@@ -47,7 +47,6 @@ PERFORMANCE OF THIS SOFTWARE.
#include <GL/glx.h>
-#include <GL/glu.h>
#include <X11/keysym.h>
#include <stdlib.h>
#include <stdio.h>
@@ -135,7 +134,7 @@ int main(int argc, char** argv) {
/* set up viewing parameters */
glMatrixMode(GL_PROJECTION);
- gluPerspective(20, 1, 10, 20);
+ glFrustum(-1, 1, -1, 1, 6, 20);
glMatrixMode(GL_MODELVIEW);
glTranslatef(0, 0, -15);
diff --git a/progs/xdemos/pbutil.c b/progs/xdemos/pbutil.c
index d0bbd1b..ce133d0 100644
--- a/progs/xdemos/pbutil.c
+++ b/progs/xdemos/pbutil.c
@@ -18,12 +18,12 @@
* Test if we pixel buffers are available for a particular X screen.
* Input: dpy - the X display
* screen - screen number
- * Return: 0 = pixel buffers not available.
- * 1 = pixel buffers are available via GLX 1.3.
- * 2 = pixel buffers are available via GLX_SGIX_fbconfig/pbuffer.
+ * Return: 0 = fbconfigs not available.
+ * 1 = fbconfigs are available via GLX 1.3.
+ * 2 = fbconfigs and pbuffers are available via GLX_SGIX_fbconfig
*/
int
-QueryPbuffers(Display *dpy, int screen)
+QueryFBConfig(Display *dpy, int screen)
{
#if defined(GLX_VERSION_1_3)
{
@@ -40,36 +40,55 @@ QueryPbuffers(Display *dpy, int screen)
}
#endif
-#if defined(GLX_SGIX_fbconfig) && defined(GLX_SGIX_pbuffer)
/* Try the SGIX extensions */
{
char *extensions;
extensions = (char *) glXQueryServerString(dpy, screen, GLX_EXTENSIONS);
- if (!extensions ||
- !strstr(extensions,"GLX_SGIX_fbconfig") ||
- !strstr(extensions,"GLX_SGIX_pbuffer")) {
- return 0;
+ if (extensions && strstr(extensions,"GLX_SGIX_fbconfig")) {
+ return 2;
}
- return 2;
}
-#endif
return 0;
}
+/**
+ * Test if we pixel buffers are available for a particular X screen.
+ * Input: dpy - the X display
+ * screen - screen number
+ * Return: 0 = pixel buffers not available.
+ * 1 = pixel buffers are available via GLX 1.3.
+ * 2 = pixel buffers are available via GLX_SGIX_fbconfig/pbuffer.
+ */
+int
+QueryPbuffers(Display *dpy, int screen)
+{
+ int ret;
+ ret = QueryFBConfig(dpy, screen);
+ if (ret == 2) {
+ char *extensions;
+ extensions = (char *) glXQueryServerString(dpy, screen, GLX_EXTENSIONS);
+ if (extensions && strstr(extensions, "GLX_SGIX_pbuffer"))
+ return 2;
+ else
+ return 0;
+ }
+ else
+ return ret;
+}
FBCONFIG *
ChooseFBConfig(Display *dpy, int screen, const int attribs[], int *nConfigs)
{
- int pbSupport = QueryPbuffers(dpy, screen);
+ int fbcSupport = QueryPbuffers(dpy, screen);
#if defined(GLX_VERSION_1_3)
- if (pbSupport == 1) {
+ if (fbcSupport == 1) {
return glXChooseFBConfig(dpy, screen, attribs, nConfigs);
}
#endif
#if defined(GLX_SGIX_fbconfig) && defined(GLX_SGIX_pbuffer)
- if (pbSupport == 2) {
+ if (fbcSupport == 2) {
return glXChooseFBConfigSGIX(dpy, screen, (int *) attribs, nConfigs);
}
#endif
@@ -80,14 +99,14 @@ ChooseFBConfig(Display *dpy, int screen, const int attribs[], int *nConfigs)
FBCONFIG *
GetAllFBConfigs(Display *dpy, int screen, int *nConfigs)
{
- int pbSupport = QueryPbuffers(dpy, screen);
+ int fbcSupport = QueryFBConfig(dpy, screen);
#if defined(GLX_VERSION_1_3)
- if (pbSupport == 1) {
+ if (fbcSupport == 1) {
return glXGetFBConfigs(dpy, screen, nConfigs);
}
#endif
#if defined(GLX_SGIX_fbconfig) && defined(GLX_SGIX_pbuffer)
- if (pbSupport == 2) {
+ if (fbcSupport == 2) {
/* The GLX_SGIX_fbconfig extensions says to pass NULL to get list
* of all available configurations.
*/
@@ -101,14 +120,14 @@ GetAllFBConfigs(Display *dpy, int screen, int *nConfigs)
XVisualInfo *
GetVisualFromFBConfig(Display *dpy, int screen, FBCONFIG config)
{
- int pbSupport = QueryPbuffers(dpy, screen);
+ int fbcSupport = QueryFBConfig(dpy, screen);
#if defined(GLX_VERSION_1_3)
- if (pbSupport == 1) {
+ if (fbcSupport == 1) {
return glXGetVisualFromFBConfig(dpy, config);
}
#endif
#if defined(GLX_SGIX_fbconfig) && defined(GLX_SGIX_pbuffer)
- if (pbSupport == 2) {
+ if (fbcSupport == 2) {
return glXGetVisualFromFBConfigSGIX(dpy, config);
}
#endif
@@ -130,11 +149,11 @@ GetFBConfigAttrib(Display *dpy, int screen,
int attrib
)
{
- int pbSupport = QueryPbuffers(dpy, screen);
+ int fbcSupport = QueryFBConfig(dpy, screen);
int value = 0;
#if defined(GLX_VERSION_1_3)
- if (pbSupport == 1) {
+ if (fbcSupport == 1) {
/* ok */
if (glXGetFBConfigAttrib(dpy, config, attrib, &value) != 0) {
value = 0;
@@ -145,7 +164,7 @@ GetFBConfigAttrib(Display *dpy, int screen,
#endif
#if defined(GLX_SGIX_fbconfig) && defined(GLX_SGIX_pbuffer)
- if (pbSupport == 2) {
+ if (fbcSupport == 2) {
if (glXGetFBConfigAttribSGIX(dpy, config, attrib, &value) != 0) {
value = 0;
}
@@ -295,9 +314,9 @@ PrintFBConfigInfo(Display *dpy, int screen, FBCONFIG config, Bool horizFormat)
GLXContext
CreateContext(Display *dpy, int screen, FBCONFIG config)
{
- int pbSupport = QueryPbuffers(dpy, screen);
+ int fbcSupport = QueryFBConfig(dpy, screen);
#if defined(GLX_VERSION_1_3)
- if (pbSupport == 1) {
+ if (fbcSupport == 1) {
/* GLX 1.3 */
GLXContext c;
c = glXCreateNewContext(dpy, config, GLX_RGBA_TYPE, NULL, True);
@@ -309,7 +328,7 @@ CreateContext(Display *dpy, int screen, FBCONFIG config)
}
#endif
#if defined(GLX_SGIX_fbconfig) && defined(GLX_SGIX_pbuffer)
- if (pbSupport == 2) {
+ if (fbcSupport == 2) {
GLXContext c;
c = glXCreateContextWithConfigSGIX(dpy, config, GLX_RGBA_TYPE_SGIX, NULL, True);
if (!c) {
@@ -393,6 +412,7 @@ CreatePbuffer(Display *dpy, int screen, FBCONFIG config,
pBuffer = None;
}
+ XSync(dpy, False);
/* Restore original X error handler */
(void) XSetErrorHandler(oldHandler);
diff --git a/progs/xdemos/pbutil.h b/progs/xdemos/pbutil.h
index e95b256..d420522 100644
--- a/progs/xdemos/pbutil.h
+++ b/progs/xdemos/pbutil.h
@@ -27,6 +27,9 @@
extern int
+QueryFBConfig(Display *dpy, int screen);
+
+extern int
QueryPbuffers(Display *dpy, int screen);
diff --git a/progs/xdemos/shape.c b/progs/xdemos/shape.c
index dbbc0b4..5ff0970 100644
--- a/progs/xdemos/shape.c
+++ b/progs/xdemos/shape.c
@@ -34,7 +34,6 @@
static int Width=500, Height=500;
static float Xangle = 0.0, Yangle = 0.0;
-static int Redraw = 0;
static int Sides = 5;
static int MinSides = 3;
static int MaxSides = 20;