summaryrefslogtreecommitdiffstats
path: root/progs
diff options
context:
space:
mode:
Diffstat (limited to 'progs')
-rw-r--r--progs/Makefile2
-rw-r--r--progs/beos/Makefile4
-rw-r--r--progs/demos/.gitignore63
-rw-r--r--progs/demos/Makefile22
-rw-r--r--progs/demos/copypix.c248
-rw-r--r--progs/demos/cubemap.c51
-rw-r--r--progs/demos/descrip.mms52
-rw-r--r--progs/demos/engine.c19
-rw-r--r--progs/demos/gears.c37
-rw-r--r--progs/demos/geartrain.dat238
-rw-r--r--[-rwxr-xr-x]progs/demos/glslnoise.c0
-rw-r--r--progs/demos/lodbias.c12
-rw-r--r--progs/demos/multiarb.c123
-rw-r--r--progs/demos/rain.cxx1
-rw-r--r--progs/demos/readtex.c454
-rw-r--r--progs/demos/readtex.h26
-rw-r--r--progs/demos/shadowtex.c373
-rw-r--r--progs/demos/showbuffer.c192
-rw-r--r--progs/demos/showbuffer.h36
-rw-r--r--progs/demos/spriteblast.c22
-rw-r--r--progs/demos/streaming_rect.c25
-rw-r--r--progs/demos/texenv.c4
-rw-r--r--progs/demos/trackball.c338
-rw-r--r--progs/demos/trackball.h84
-rw-r--r--progs/ggi/sphere.asc264
-rw-r--r--progs/ggi/torus.asc528
-rw-r--r--progs/glsl/.gitignore6
-rw-r--r--progs/glsl/Makefile107
-rw-r--r--progs/glsl/bitmap.c323
-rw-r--r--progs/glsl/brick.c134
-rw-r--r--progs/glsl/bump.c135
-rw-r--r--progs/glsl/deriv.c90
-rw-r--r--progs/glsl/mandelbrot.c146
-rw-r--r--progs/glsl/multitex.c285
-rw-r--r--progs/glsl/multitex.frag.txt15
-rw-r--r--progs/glsl/multitex.vert.txt10
-rw-r--r--progs/glsl/noise.c102
-rw-r--r--progs/glsl/points.c260
-rw-r--r--progs/glsl/texdemo1.c155
-rw-r--r--progs/glsl/toyball.c159
-rw-r--r--progs/glsl/trirast.c259
-rw-r--r--progs/glsl/twoside.c270
-rw-r--r--progs/osdemos/Makefile14
-rw-r--r--progs/osdemos/ostest1.c7
-rw-r--r--progs/osdemos/readtex.c454
-rw-r--r--progs/samples/.gitignore47
-rw-r--r--progs/samples/blendeq.c97
-rw-r--r--progs/samples/readtex.c454
-rw-r--r--progs/slang/.gitignore3
-rw-r--r--progs/tools/trace/.gitignore1
-rw-r--r--progs/util/extfuncs.h24
-rw-r--r--progs/util/shaderutil.c159
-rw-r--r--progs/util/shaderutil.h34
-rw-r--r--progs/util/showbuffer.c6
-rw-r--r--progs/util/xrotfont.c368
-rw-r--r--progs/vp/.gitignore1
-rw-r--r--progs/xdemos/.gitignore25
-rw-r--r--progs/xdemos/Makefile14
-rw-r--r--progs/xdemos/corender.c400
-rw-r--r--progs/xdemos/glthreads.c25
-rw-r--r--progs/xdemos/glxgears.c196
-rw-r--r--progs/xdemos/glxgears_pixmap.c (renamed from progs/xdemos/glxgears2.c)179
-rw-r--r--progs/xdemos/glxinfo.c285
-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.c32
-rw-r--r--progs/xdemos/pbutil.c72
-rw-r--r--progs/xdemos/pbutil.h3
-rw-r--r--progs/xdemos/sharedtex.c324
-rw-r--r--progs/xdemos/texture_from_pixmap.c396
72 files changed, 5710 insertions, 4246 deletions
diff --git a/progs/Makefile b/progs/Makefile
index 5e705efa7ee..c99f4eebcc1 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 491e8e442d1..0dc4cdce632 100644
--- a/progs/beos/Makefile
+++ b/progs/beos/Makefile
@@ -19,8 +19,8 @@ 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) $(LIBS) -o $@
diff --git a/progs/demos/.gitignore b/progs/demos/.gitignore
new file mode 100644
index 00000000000..ab836eb8340
--- /dev/null
+++ b/progs/demos/.gitignore
@@ -0,0 +1,63 @@
+.cvsignore
+arbfplight
+arbfslight
+arbocclude
+bounce
+clearspd
+copypix
+cubemap
+drawpix
+engine
+extfuncs.h
+fire
+fogcoord
+fplight
+fslight
+gamma
+gearbox
+gears
+geartrain
+glinfo
+gloss
+glslnoise
+gltestperf
+glutfx
+ipers
+isosurf
+lodbias
+morph3d
+multiarb
+occlude
+osdemo
+paltex
+pixeltex
+pointblast
+rain
+ray
+readpix
+readtex.c
+readtex.h
+reflect
+renormal
+shadowtex
+showbuffer.c
+showbuffer.h
+singlebuffer
+spectex
+spriteblast
+stex3d
+streaming_rect
+teapot
+terrain
+tessdemo
+texcyl
+texdown
+texenv
+texobj
+trackball.c
+trackball.h
+trispd
+tunnel
+tunnel2
+vao_demo
+winpos
diff --git a/progs/demos/Makefile b/progs/demos/Makefile
index 1014ccce893..7fde77f0b41 100644
--- a/progs/demos/Makefile
+++ b/progs/demos/Makefile
@@ -11,9 +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)
+LIBS = -L$(TOP)/$(LIB_DIR) -l$(GLUT_LIB) -l$(GLU_LIB) -l$(GL_LIB) \
+ $(APP_LIB_DEPS)
PROGS = \
arbfplight \
@@ -21,6 +23,7 @@ PROGS = \
arbocclude \
bounce \
clearspd \
+ copypix \
cubemap \
drawpix \
engine \
@@ -44,6 +47,7 @@ PROGS = \
multiarb \
paltex \
pointblast \
+ rain \
ray \
readpix \
reflect \
@@ -72,7 +76,7 @@ PROGS = \
.SUFFIXES:
.SUFFIXES: .c
-
+.SUFFIXES: .cxx
# make executable from .c file:
.c: $(LIB_DEP) readtex.o
@@ -153,6 +157,18 @@ fslight: fslight.o
fslight.o: fslight.c extfuncs.h
$(CC) -c -I$(INCDIR) $(CFLAGS) fslight.c
+rain: particles.o rain.o readtex.o
+ $(CXX) $(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 00000000000..15001e851be
--- /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 ef5d2355509..b3bdd64f68d 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
index a374fdf13d0..d7a912133ac 100644
--- a/progs/demos/descrip.mms
+++ b/progs/demos/descrip.mms
@@ -1,6 +1,6 @@
# Makefile for GLUT-based demo programs for VMS
-# contributed by Jouk Jansen [email protected]
-# Last update : 20 May 2005
+# contributed by Jouk Jansen [email protected]
+# Last update : 30 November 2007
.first
define gl [--.include.gl]
@@ -21,10 +21,10 @@ 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;
+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 #####
@@ -39,33 +39,33 @@ clean :
delete *.obj;*
realclean :
- delete $(PROGS)
+ 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
+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
+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\
+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)
+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)
+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)
diff --git a/progs/demos/engine.c b/progs/demos/engine.c
index 68c4d500dfa..6040a2f1030 100644
--- a/progs/demos/engine.c
+++ b/progs/demos/engine.c
@@ -445,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();
}
@@ -745,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);
@@ -764,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();
@@ -784,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);
@@ -1254,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);
@@ -1265,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/gears.c b/progs/demos/gears.c
index ab9bc007421..2a9fefefb53 100644
--- a/progs/demos/gears.c
+++ b/progs/demos/gears.c
@@ -27,6 +27,9 @@ static GLint T0 = 0;
static GLint Frames = 0;
static GLint autoexit = 0;
static GLint win = 0;
+static GLboolean Visible = GL_TRUE;
+static GLboolean Animate = GL_TRUE;
+static GLfloat viewDist = 40.0;
/**
@@ -179,6 +182,9 @@ draw(void)
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glPushMatrix();
+
+ glTranslatef(0.0, 0.0, -viewDist);
+
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);
@@ -240,6 +246,15 @@ idle(void)
glutPostRedisplay();
}
+static void
+update_idle_func(void)
+{
+ if (Visible && Animate)
+ glutIdleFunc(idle);
+ else
+ glutIdleFunc(NULL);
+}
+
/* change view angle, exit upon ESC */
/* ARGSUSED1 */
static void
@@ -252,6 +267,16 @@ key(unsigned char k, int x, int y)
case 'Z':
view_rotz -= 5.0;
break;
+ case 'd':
+ viewDist += 1.0;
+ break;
+ case 'D':
+ viewDist -= 1.0;
+ break;
+ case 'a':
+ Animate = !Animate;
+ update_idle_func();
+ break;
case 27: /* Escape */
cleanup();
exit(0);
@@ -295,10 +320,8 @@ reshape(int width, int height)
glViewport(0, 0, (GLint) width, (GLint) height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
- glFrustum(-1.0, 1.0, -h, h, 5.0, 60.0);
+ glFrustum(-1.0, 1.0, -h, h, 5.0, 200.0);
glMatrixMode(GL_MODELVIEW);
- glLoadIdentity();
- glTranslatef(0.0, 0.0, -40.0);
}
static void
@@ -351,13 +374,12 @@ init(int argc, char *argv[])
}
}
+
static void
visible(int vis)
{
- if (vis == GLUT_VISIBLE)
- glutIdleFunc(idle);
- else
- glutIdleFunc(NULL);
+ Visible = vis;
+ update_idle_func();
}
int main(int argc, char *argv[])
@@ -375,6 +397,7 @@ int main(int argc, char *argv[])
glutKeyboardFunc(key);
glutSpecialFunc(special);
glutVisibilityFunc(visible);
+ update_idle_func();
glutMainLoop();
return 0; /* ANSI C requires main to return int. */
diff --git a/progs/demos/geartrain.dat b/progs/demos/geartrain.dat
index 374de48bd5e..09fe4c64c28 100644
--- a/progs/demos/geartrain.dat
+++ b/progs/demos/geartrain.dat
@@ -1,119 +1,119 @@
-BACKGROUND = 0.000 0.500 0.700
-
-ANAME = AXLE1
-ARADIUS = 1.000
-AAXIS = 2
-APOSITION = -7.000 0.000 0.000
-ACOLOR = 0.800 0.500 0.200
-ALENGTH = 6.000
-AMOTORED = 1
-AANGULARVELOCITY = 90.000
-ADIRECTION = 1
-
-ANAME = AXLE2
-ARADIUS = 1.000
-AAXIS = 2
-APOSITION = -3.000 0.000 0.000
-ACOLOR = 0.800 0.500 0.200
-ALENGTH = 12.000
-AMOTORED = 0
-
-ANAME = AXLE3
-ARADIUS = 1.000
-AAXIS = 2
-APOSITION = 1.000 0.000 0.000
-ACOLOR = 0.800 0.500 0.200
-ALENGTH = 6.000
-AMOTORED = 0
-
-ANAME = AXLE4
-ARADIUS = 1.000
-AAXIS = 2
-APOSITION = 8.000 0.000 0.000
-ACOLOR = 0.800 0.500 0.200
-ALENGTH = 18.000
-AMOTORED = 0
-
-ANAME = AXLE5
-ARADIUS = 1.000
-AAXIS = 1
-APOSITION = 8.000 -8.200 -7.400
-ACOLOR = 0.800 0.500 0.200
-ALENGTH = 12.000
-AMOTORED = 0
-
-GNAME = GEAR1
-GTYPE = NORMAL
-GRADIUS = 2.200
-GWIDTH = 3.000
-GTEETH = 40
-GTOOTHDEPTH = 0.500
-GCOLOR = 0.500 0.500 0.500
-GAXLE = AXLE1
-GPOSITION = 0.000
-
-GNAME = GEAR2
-GTYPE = NORMAL
-GRADIUS = 2.200
-GWIDTH = 3.000
-GTEETH = 30
-GTOOTHDEPTH = 0.500
-GCOLOR = 0.500 0.500 0.500
-GAXLE = AXLE2
-GPOSITION = 0.000
-
-GNAME = GEAR3
-GTYPE = NORMAL
-GRADIUS = 2.200
-GWIDTH = 3.000
-GTEETH = 20
-GTOOTHDEPTH = 0.500
-GCOLOR = 0.500 0.500 0.500
-GAXLE = AXLE3
-GPOSITION = 0.000
-
-GNAME = GEAR4
-GTYPE = NORMAL
-GRADIUS = 1.700
-GWIDTH = 1.000
-GTEETH = 20
-GTOOTHDEPTH = 0.500
-GCOLOR = 0.500 0.500 0.500
-GAXLE = AXLE2
-GPOSITION = 5.000
-
-GNAME = GEAR5
-GTYPE = NORMAL
-GRADIUS = 3.000
-GWIDTH = 1.000
-GTEETH = 20
-GTOOTHDEPTH = 0.500
-GCOLOR = 0.500 0.500 0.500
-GAXLE = AXLE4
-GPOSITION = 5.000
-
-GNAME = GEAR6
-GTYPE = BEVEL
-GFACE = 0
-GRADIUS = 4.000
-GWIDTH = 1.000
-GTEETH = 20
-GTOOTHDEPTH = 1.700
-GCOLOR = 0.500 0.500 0.500
-GAXLE = AXLE4
-GPOSITION = -4.000
-
-GNAME = GEAR7
-GTYPE = BEVEL
-GFACE = 0
-GRADIUS = 4.000
-GWIDTH = 1.000
-GTEETH = 20
-GTOOTHDEPTH = 1.700
-GCOLOR = 0.500 0.500 0.500
-GAXLE = AXLE5
-GPOSITION = 5.000
-
-BELTNAME = BELT1
-GEAR1NAME = GEAR5
-GEAR2NAME = GEAR4
+BACKGROUND = 0.000 0.500 0.700
+
+ANAME = AXLE1
+ARADIUS = 1.000
+AAXIS = 2
+APOSITION = -7.000 0.000 0.000
+ACOLOR = 0.800 0.500 0.200
+ALENGTH = 6.000
+AMOTORED = 1
+AANGULARVELOCITY = 90.000
+ADIRECTION = 1
+
+ANAME = AXLE2
+ARADIUS = 1.000
+AAXIS = 2
+APOSITION = -3.000 0.000 0.000
+ACOLOR = 0.800 0.500 0.200
+ALENGTH = 12.000
+AMOTORED = 0
+
+ANAME = AXLE3
+ARADIUS = 1.000
+AAXIS = 2
+APOSITION = 1.000 0.000 0.000
+ACOLOR = 0.800 0.500 0.200
+ALENGTH = 6.000
+AMOTORED = 0
+
+ANAME = AXLE4
+ARADIUS = 1.000
+AAXIS = 2
+APOSITION = 8.000 0.000 0.000
+ACOLOR = 0.800 0.500 0.200
+ALENGTH = 18.000
+AMOTORED = 0
+
+ANAME = AXLE5
+ARADIUS = 1.000
+AAXIS = 1
+APOSITION = 8.000 -8.200 -7.400
+ACOLOR = 0.800 0.500 0.200
+ALENGTH = 12.000
+AMOTORED = 0
+
+GNAME = GEAR1
+GTYPE = NORMAL
+GRADIUS = 2.200
+GWIDTH = 3.000
+GTEETH = 40
+GTOOTHDEPTH = 0.500
+GCOLOR = 0.500 0.500 0.500
+GAXLE = AXLE1
+GPOSITION = 0.000
+
+GNAME = GEAR2
+GTYPE = NORMAL
+GRADIUS = 2.200
+GWIDTH = 3.000
+GTEETH = 30
+GTOOTHDEPTH = 0.500
+GCOLOR = 0.500 0.500 0.500
+GAXLE = AXLE2
+GPOSITION = 0.000
+
+GNAME = GEAR3
+GTYPE = NORMAL
+GRADIUS = 2.200
+GWIDTH = 3.000
+GTEETH = 20
+GTOOTHDEPTH = 0.500
+GCOLOR = 0.500 0.500 0.500
+GAXLE = AXLE3
+GPOSITION = 0.000
+
+GNAME = GEAR4
+GTYPE = NORMAL
+GRADIUS = 1.700
+GWIDTH = 1.000
+GTEETH = 20
+GTOOTHDEPTH = 0.500
+GCOLOR = 0.500 0.500 0.500
+GAXLE = AXLE2
+GPOSITION = 5.000
+
+GNAME = GEAR5
+GTYPE = NORMAL
+GRADIUS = 3.000
+GWIDTH = 1.000
+GTEETH = 20
+GTOOTHDEPTH = 0.500
+GCOLOR = 0.500 0.500 0.500
+GAXLE = AXLE4
+GPOSITION = 5.000
+
+GNAME = GEAR6
+GTYPE = BEVEL
+GFACE = 0
+GRADIUS = 4.000
+GWIDTH = 1.000
+GTEETH = 20
+GTOOTHDEPTH = 1.700
+GCOLOR = 0.500 0.500 0.500
+GAXLE = AXLE4
+GPOSITION = -4.000
+
+GNAME = GEAR7
+GTYPE = BEVEL
+GFACE = 0
+GRADIUS = 4.000
+GWIDTH = 1.000
+GTEETH = 20
+GTOOTHDEPTH = 1.700
+GCOLOR = 0.500 0.500 0.500
+GAXLE = AXLE5
+GPOSITION = 5.000
+
+BELTNAME = BELT1
+GEAR1NAME = GEAR5
+GEAR2NAME = GEAR4
diff --git a/progs/demos/glslnoise.c b/progs/demos/glslnoise.c
index 4ee12928164..4ee12928164 100755..100644
--- a/progs/demos/glslnoise.c
+++ b/progs/demos/glslnoise.c
diff --git a/progs/demos/lodbias.c b/progs/demos/lodbias.c
index a4db22e26e4..c5a2a1b4573 100644
--- a/progs/demos/lodbias.c
+++ b/progs/demos/lodbias.c
@@ -159,6 +159,18 @@ static void Key( unsigned char key, int x, int y )
case 'B':
Bias += 10;
break;
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9':
+ Bias = 100.0 * (key - '0');
+ break;
case 27:
exit(0);
break;
diff --git a/progs/demos/multiarb.c b/progs/demos/multiarb.c
index d963985c69d..451fd11efe1 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 d19f049c5f3..5c53d4248c5 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/readtex.c b/progs/demos/readtex.c
deleted file mode 100644
index 37d5fcd0d3a..00000000000
--- a/progs/demos/readtex.c
+++ /dev/null
@@ -1,454 +0,0 @@
-/* readtex.c */
-
-/*
- * Read an SGI .rgb image file and generate a mipmap texture set.
- * Much of this code was borrowed from SGI's tk OpenGL toolkit.
- */
-
-
-
-#include <GL/gl.h>
-#include <GL/glu.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include "readtex.h"
-
-
-#ifndef SEEK_SET
-# define SEEK_SET 0
-#endif
-
-
-/*
-** RGB Image Structure
-*/
-
-typedef struct _TK_RGBImageRec {
- GLint sizeX, sizeY;
- GLint components;
- unsigned char *data;
-} TK_RGBImageRec;
-
-
-
-/******************************************************************************/
-
-typedef struct _rawImageRec {
- unsigned short imagic;
- unsigned short type;
- unsigned short dim;
- unsigned short sizeX, sizeY, sizeZ;
- unsigned long min, max;
- unsigned long wasteBytes;
- char name[80];
- unsigned long colorMap;
- FILE *file;
- unsigned char *tmp, *tmpR, *tmpG, *tmpB, *tmpA;
- unsigned long rleEnd;
- GLuint *rowStart;
- GLint *rowSize;
-} rawImageRec;
-
-/******************************************************************************/
-
-static void ConvertShort(unsigned short *array, long length)
-{
- unsigned long b1, b2;
- unsigned char *ptr;
-
- ptr = (unsigned char *)array;
- while (length--) {
- b1 = *ptr++;
- b2 = *ptr++;
- *array++ = (unsigned short) ((b1 << 8) | (b2));
- }
-}
-
-static void ConvertLong(GLuint *array, long length)
-{
- unsigned long b1, b2, b3, b4;
- unsigned char *ptr;
-
- ptr = (unsigned char *)array;
- while (length--) {
- b1 = *ptr++;
- b2 = *ptr++;
- b3 = *ptr++;
- b4 = *ptr++;
- *array++ = (b1 << 24) | (b2 << 16) | (b3 << 8) | (b4);
- }
-}
-
-static rawImageRec *RawImageOpen(const char *fileName)
-{
- union {
- int testWord;
- char testByte[4];
- } endianTest;
- rawImageRec *raw;
- GLenum swapFlag;
- int x;
-
- endianTest.testWord = 1;
- if (endianTest.testByte[0] == 1) {
- swapFlag = GL_TRUE;
- } else {
- swapFlag = GL_FALSE;
- }
-
- raw = (rawImageRec *)calloc(1, sizeof(rawImageRec));
- if (raw == NULL) {
- fprintf(stderr, "Out of memory!\n");
- return NULL;
- }
- if ((raw->file = fopen(fileName, "rb")) == NULL) {
- perror(fileName);
- return NULL;
- }
-
- fread(raw, 1, 12, raw->file);
-
- if (swapFlag) {
- ConvertShort(&raw->imagic, 6);
- }
-
- raw->tmp = (unsigned char *)malloc(raw->sizeX*256);
- raw->tmpR = (unsigned char *)malloc(raw->sizeX*256);
- raw->tmpG = (unsigned char *)malloc(raw->sizeX*256);
- raw->tmpB = (unsigned char *)malloc(raw->sizeX*256);
- if (raw->sizeZ==4) {
- raw->tmpA = (unsigned char *)malloc(raw->sizeX*256);
- }
- if (raw->tmp == NULL || raw->tmpR == NULL || raw->tmpG == NULL ||
- raw->tmpB == NULL) {
- fprintf(stderr, "Out of memory!\n");
- return NULL;
- }
-
- if ((raw->type & 0xFF00) == 0x0100) {
- x = raw->sizeY * raw->sizeZ * sizeof(GLuint);
- raw->rowStart = (GLuint *)malloc(x);
- raw->rowSize = (GLint *)malloc(x);
- if (raw->rowStart == NULL || raw->rowSize == NULL) {
- fprintf(stderr, "Out of memory!\n");
- return NULL;
- }
- raw->rleEnd = 512 + (2 * x);
- fseek(raw->file, 512, SEEK_SET);
- fread(raw->rowStart, 1, x, raw->file);
- fread(raw->rowSize, 1, x, raw->file);
- if (swapFlag) {
- ConvertLong(raw->rowStart, (long) (x/sizeof(GLuint)));
- ConvertLong((GLuint *)raw->rowSize, (long) (x/sizeof(GLint)));
- }
- }
- return raw;
-}
-
-static void RawImageClose(rawImageRec *raw)
-{
- fclose(raw->file);
- free(raw->tmp);
- free(raw->tmpR);
- free(raw->tmpG);
- free(raw->tmpB);
- if (raw->rowStart)
- free(raw->rowStart);
- if (raw->rowSize)
- free(raw->rowSize);
- if (raw->sizeZ>3) {
- free(raw->tmpA);
- }
- free(raw);
-}
-
-static void RawImageGetRow(rawImageRec *raw, unsigned char *buf, int y, int z)
-{
- unsigned char *iPtr, *oPtr, pixel;
- int count, done = 0;
-
- if ((raw->type & 0xFF00) == 0x0100) {
- fseek(raw->file, (long) raw->rowStart[y+z*raw->sizeY], SEEK_SET);
- fread(raw->tmp, 1, (unsigned int)raw->rowSize[y+z*raw->sizeY],
- raw->file);
-
- iPtr = raw->tmp;
- oPtr = buf;
- while (!done) {
- pixel = *iPtr++;
- count = (int)(pixel & 0x7F);
- if (!count) {
- done = 1;
- return;
- }
- if (pixel & 0x80) {
- while (count--) {
- *oPtr++ = *iPtr++;
- }
- } else {
- pixel = *iPtr++;
- while (count--) {
- *oPtr++ = pixel;
- }
- }
- }
- } else {
- fseek(raw->file, 512+(y*raw->sizeX)+(z*raw->sizeX*raw->sizeY),
- SEEK_SET);
- fread(buf, 1, raw->sizeX, raw->file);
- }
-}
-
-
-static void RawImageGetData(rawImageRec *raw, TK_RGBImageRec *final)
-{
- unsigned char *ptr;
- int i, j;
-
- final->data = (unsigned char *)malloc((raw->sizeX+1)*(raw->sizeY+1)*4);
- if (final->data == NULL) {
- fprintf(stderr, "Out of memory!\n");
- }
-
- ptr = final->data;
- for (i = 0; i < (int)(raw->sizeY); i++) {
- RawImageGetRow(raw, raw->tmpR, i, 0);
- RawImageGetRow(raw, raw->tmpG, i, 1);
- RawImageGetRow(raw, raw->tmpB, i, 2);
- if (raw->sizeZ>3) {
- RawImageGetRow(raw, raw->tmpA, i, 3);
- }
- for (j = 0; j < (int)(raw->sizeX); j++) {
- *ptr++ = *(raw->tmpR + j);
- *ptr++ = *(raw->tmpG + j);
- *ptr++ = *(raw->tmpB + j);
- if (raw->sizeZ>3) {
- *ptr++ = *(raw->tmpA + j);
- }
- }
- }
-}
-
-
-static TK_RGBImageRec *tkRGBImageLoad(const char *fileName)
-{
- rawImageRec *raw;
- TK_RGBImageRec *final;
-
- raw = RawImageOpen(fileName);
- if (!raw) {
- fprintf(stderr, "File not found\n");
- return NULL;
- }
- final = (TK_RGBImageRec *)malloc(sizeof(TK_RGBImageRec));
- if (final == NULL) {
- fprintf(stderr, "Out of memory!\n");
- return NULL;
- }
- final->sizeX = raw->sizeX;
- final->sizeY = raw->sizeY;
- final->components = raw->sizeZ;
- RawImageGetData(raw, final);
- RawImageClose(raw);
- return final;
-}
-
-
-static void FreeImage( TK_RGBImageRec *image )
-{
- free(image->data);
- free(image);
-}
-
-
-/*
- * Load an SGI .rgb file and generate a set of 2-D mipmaps from it.
- * Input: imageFile - name of .rgb to read
- * intFormat - internal texture format to use, or number of components
- * Return: GL_TRUE if success, GL_FALSE if error.
- */
-GLboolean LoadRGBMipmaps( const char *imageFile, GLint intFormat )
-{
- GLint w, h;
- return LoadRGBMipmaps2( imageFile, GL_TEXTURE_2D, intFormat, &w, &h );
-}
-
-
-
-GLboolean LoadRGBMipmaps2( const char *imageFile, GLenum target,
- GLint intFormat, GLint *width, GLint *height )
-{
- GLint error;
- GLenum format;
- TK_RGBImageRec *image;
-
- image = tkRGBImageLoad( imageFile );
- if (!image) {
- return GL_FALSE;
- }
-
- if (image->components==3) {
- format = GL_RGB;
- }
- else if (image->components==4) {
- format = GL_RGBA;
- }
- else {
- /* not implemented */
- fprintf(stderr,
- "Error in LoadRGBMipmaps %d-component images not implemented\n",
- image->components );
- return GL_FALSE;
- }
-
- error = gluBuild2DMipmaps( target,
- intFormat,
- image->sizeX, image->sizeY,
- format,
- GL_UNSIGNED_BYTE,
- image->data );
-
- *width = image->sizeX;
- *height = image->sizeY;
-
- FreeImage(image);
-
- return error ? GL_FALSE : GL_TRUE;
-}
-
-
-
-/*
- * Load an SGI .rgb file and return a pointer to the image data.
- * Input: imageFile - name of .rgb to read
- * Output: width - width of image
- * height - height of image
- * format - format of image (GL_RGB or GL_RGBA)
- * Return: pointer to image data or NULL if error
- */
-GLubyte *LoadRGBImage( const char *imageFile, GLint *width, GLint *height,
- GLenum *format )
-{
- TK_RGBImageRec *image;
- GLint bytes;
- GLubyte *buffer;
-
- image = tkRGBImageLoad( imageFile );
- if (!image) {
- return NULL;
- }
-
- if (image->components==3) {
- *format = GL_RGB;
- }
- else if (image->components==4) {
- *format = GL_RGBA;
- }
- else {
- /* not implemented */
- fprintf(stderr,
- "Error in LoadRGBImage %d-component images not implemented\n",
- image->components );
- return NULL;
- }
-
- *width = image->sizeX;
- *height = image->sizeY;
-
- bytes = image->sizeX * image->sizeY * image->components;
- buffer = (GLubyte *) malloc(bytes);
- if (!buffer)
- return NULL;
-
- memcpy( (void *) buffer, (void *) image->data, bytes );
-
- FreeImage(image);
-
- return buffer;
-}
-
-#define CLAMP( X, MIN, MAX ) ( (X)<(MIN) ? (MIN) : ((X)>(MAX) ? (MAX) : (X)) )
-
-
-static void ConvertRGBtoYUV(GLint w, GLint h, GLint texel_bytes,
- const GLubyte *src,
- GLushort *dest)
-{
- GLint i, j;
-
- for (i = 0; i < h; i++) {
- for (j = 0; j < w; j++) {
- const GLfloat r = (src[0]) / 255.0;
- const GLfloat g = (src[1]) / 255.0;
- const GLfloat b = (src[2]) / 255.0;
- GLfloat y, cr, cb;
- GLint iy, icr, icb;
-
- y = r * 65.481 + g * 128.553 + b * 24.966 + 16;
- cb = r * -37.797 + g * -74.203 + b * 112.0 + 128;
- cr = r * 112.0 + g * -93.786 + b * -18.214 + 128;
- /*printf("%f %f %f -> %f %f %f\n", r, g, b, y, cb, cr);*/
- iy = (GLint) CLAMP(y, 0, 254);
- icb = (GLint) CLAMP(cb, 0, 254);
- icr = (GLint) CLAMP(cr, 0, 254);
-
- if (j & 1) {
- /* odd */
- *dest = (iy << 8) | icr;
- }
- else {
- /* even */
- *dest = (iy << 8) | icb;
- }
- dest++;
- src += texel_bytes;
- }
- }
-}
-
-
-/*
- * Load an SGI .rgb file and return a pointer to the image data, converted
- * to 422 yuv.
- *
- * Input: imageFile - name of .rgb to read
- * Output: width - width of image
- * height - height of image
- * Return: pointer to image data or NULL if error
- */
-GLushort *LoadYUVImage( const char *imageFile, GLint *width, GLint *height )
-{
- TK_RGBImageRec *image;
- GLushort *buffer;
-
- image = tkRGBImageLoad( imageFile );
- if (!image) {
- return NULL;
- }
-
- if (image->components != 3 && image->components !=4 ) {
- /* not implemented */
- fprintf(stderr,
- "Error in LoadYUVImage %d-component images not implemented\n",
- image->components );
- return NULL;
- }
-
- *width = image->sizeX;
- *height = image->sizeY;
-
- buffer = (GLushort *) malloc( image->sizeX * image->sizeY * 2 );
-
- if (buffer)
- ConvertRGBtoYUV( image->sizeX,
- image->sizeY,
- image->components,
- image->data,
- buffer );
-
-
- FreeImage(image);
- return buffer;
-}
-
diff --git a/progs/demos/readtex.h b/progs/demos/readtex.h
deleted file mode 100644
index 6c9a3828d38..00000000000
--- a/progs/demos/readtex.h
+++ /dev/null
@@ -1,26 +0,0 @@
-/* readtex.h */
-
-#ifndef READTEX_H
-#define READTEX_H
-
-
-#include <GL/gl.h>
-
-
-extern GLboolean
-LoadRGBMipmaps( const char *imageFile, GLint intFormat );
-
-
-extern GLboolean
-LoadRGBMipmaps2( const char *imageFile, GLenum target,
- GLint intFormat, GLint *width, GLint *height );
-
-
-extern GLubyte *
-LoadRGBImage( const char *imageFile,
- GLint *width, GLint *height, GLenum *format );
-
-extern GLushort *
-LoadYUVImage( const char *imageFile, GLint *width, GLint *height );
-
-#endif
diff --git a/progs/demos/shadowtex.c b/progs/demos/shadowtex.c
index b11c6f53630..4787f0f29d2 100644
--- a/progs/demos/shadowtex.c
+++ b/progs/demos/shadowtex.c
@@ -9,6 +9,7 @@
* Added GL_EXT_packed_depth_stencil support on 15 March 2006.
* Added GL_EXT_framebuffer_object support on 27 March 2006.
* Removed old SGIX extension support on 5 April 2006.
+ * Added vertex / fragment program support on 7 June 2007 (Ian Romanick).
*
* Copyright (C) 1999-2006 Brian Paul All Rights Reserved.
*
@@ -34,6 +35,7 @@
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
+#include <string.h>
#include <math.h>
#include <GL/glut.h>
#include "showbuffer.h"
@@ -67,8 +69,28 @@ static GLboolean NeedNewShadowMap = GL_FALSE;
static GLuint ShadowTexture, GrayTexture;
static GLuint ShadowFBO;
+static GLfloat lightModelview[16];
+static GLfloat lightProjection[16];
+
+static GLuint vert_prog;
+static GLuint frag_progs[3];
+static GLuint curr_frag = 0;
+static GLuint max_frag = 1;
+
+#define NUM_FRAG_MODES 3
+static const char *FragProgNames[] = {
+ "fixed-function",
+ "program without \"OPTION ARB_fragment_program_shadow\"",
+ "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;
+static GLboolean HaveFP = GL_FALSE;
+static GLboolean HaveFP_Shadow = GL_FALSE;
+static GLboolean UseVP = GL_FALSE;
static GLboolean HavePackedDepthStencil = GL_FALSE;
static GLboolean UsePackedDepthStencil = GL_FALSE;
static GLboolean HaveEXTshadowFuncs = GL_FALSE;
@@ -91,6 +113,103 @@ static GLuint DisplayMode;
+#define MAT4_MUL(dest_vec, src_mat, src_vec) \
+ "DP4 " dest_vec ".x, " src_mat "[0], " src_vec ";\n" \
+ "DP4 " dest_vec ".y, " src_mat "[1], " src_vec ";\n" \
+ "DP4 " dest_vec ".z, " src_mat "[2], " src_vec ";\n" \
+ "DP4 " dest_vec ".w, " src_mat "[3], " src_vec ";\n"
+
+#define MAT3_MUL(dest_vec, src_mat, src_vec) \
+ "DP3 " dest_vec ".x, " src_mat "[0], " src_vec ";\n" \
+ "DP3 " dest_vec ".y, " src_mat "[1], " src_vec ";\n" \
+ "DP3 " dest_vec ".z, " src_mat "[2], " src_vec ";\n"
+
+#define NORMALIZE(dest, src) \
+ "DP3 " dest ".w, " src ", " src ";\n" \
+ "RSQ " dest ".w, " dest ".w;\n" \
+ "MUL " dest ", " src ", " dest ".w;\n"
+
+/**
+ * Vertex program for shadow mapping.
+ */
+static const char vert_code[] =
+ "!!ARBvp1.0\n"
+ "ATTRIB iPos = vertex.position;\n"
+ "ATTRIB iNorm = vertex.normal;\n"
+
+ "PARAM mvinv[4] = { state.matrix.modelview.invtrans };\n"
+ "PARAM mvp[4] = { state.matrix.mvp };\n"
+ "PARAM mv[4] = { state.matrix.modelview };\n"
+ "PARAM texmat[4] = { state.matrix.texture[0] };\n"
+ "PARAM lightPos = state.light[0].position;\n"
+ "PARAM ambientCol = state.lightprod[0].ambient;\n"
+ "PARAM diffuseCol = state.lightprod[0].diffuse;\n"
+
+ "TEMP n, lightVec;\n"
+ "ALIAS V = lightVec;\n"
+ "ALIAS NdotL = n;\n"
+
+ "OUTPUT oPos = result.position;\n"
+ "OUTPUT oColor = result.color;\n"
+ "OUTPUT oTex = result.texcoord[0];\n"
+
+ /* Transform the vertex to clip coordinates. */
+ MAT4_MUL("oPos", "mvp", "iPos")
+
+ /* Transform the vertex to eye coordinates. */
+ MAT4_MUL("V", "mv", "iPos")
+
+ /* Transform the vertex to projected light coordinates. */
+ MAT4_MUL("oTex", "texmat", "iPos")
+
+ /* Transform the normal to eye coordinates. */
+ MAT3_MUL("n", "mvinv", "iNorm")
+
+ /* Calculate the vector from the vertex to the light in eye
+ * coordinates.
+ */
+ "SUB lightVec, lightPos, V;\n"
+ NORMALIZE("lightVec", "lightVec")
+
+ /* Compute diffuse lighting coefficient.
+ */
+ "DP3 NdotL.x, n, lightVec;\n"
+ "MAX NdotL.x, NdotL.x, {0.0};\n"
+ "MIN NdotL.x, NdotL.x, {1.0};\n"
+
+ /* Accumulate color contributions.
+ */
+ "MOV oColor, diffuseCol;\n"
+ "MAD oColor.xyz, NdotL.x, diffuseCol, ambientCol;\n"
+ "END\n"
+ ;
+
+static const char frag_code[] =
+ "!!ARBfp1.0\n"
+
+ "TEMP shadow, temp;\n"
+
+ "TXP shadow, fragment.texcoord[0], texture[0], 2D;\n"
+ "RCP temp.x, fragment.texcoord[0].w;\n"
+ "MUL temp.x, temp.x, fragment.texcoord[0].z;\n"
+ "SGE shadow, shadow.x, temp.x;\n"
+ "MUL result.color.rgb, fragment.color, shadow.x;\n"
+ "MOV result.color.a, fragment.color;\n"
+ "END\n"
+ ;
+
+static const char frag_shadow_code[] =
+ "!!ARBfp1.0\n"
+ "OPTION ARB_fragment_program_shadow;\n"
+
+ "TEMP shadow;\n"
+
+ "TXP shadow, fragment.texcoord[0], texture[0], SHADOW2D;\n"
+ "MUL result.color.rgb, fragment.color, shadow.x;\n"
+ "MOV result.color.a, fragment.color.a;\n"
+ "END\n"
+ ;
+
static void
DrawScene(void)
{
@@ -134,27 +253,56 @@ DrawScene(void)
}
-/*
- * Load the GL_TEXTURE matrix with the projection from the light
- * source's point of view.
+/**
+ * Calculate modelview and project matrices for the light
+ *
+ * Stores the results in \c lightProjection (projection matrix) and
+ * \c lightModelview (modelview matrix).
*/
static void
MakeShadowMatrix(const GLfloat lightPos[4], const GLfloat spotDir[3],
GLfloat spotAngle, GLfloat shadowNear, GLfloat shadowFar)
{
- GLfloat d;
-
- glMatrixMode(GL_TEXTURE);
+ /* compute frustum to enclose spot light cone */
+ const GLfloat d = shadowNear * tan(spotAngle);
+
+ glMatrixMode(GL_PROJECTION);
+ glPushMatrix();
glLoadIdentity();
- glTranslatef(0.5, 0.5, 0.5 + Bias);
- glScalef(0.5, 0.5, 0.5);
- d = shadowNear * tan(spotAngle);
glFrustum(-d, d, -d, d, shadowNear, shadowFar);
+ glGetFloatv(GL_PROJECTION_MATRIX, lightProjection);
+ glPopMatrix();
+
+ glMatrixMode(GL_MODELVIEW);
+ glPushMatrix();
+ glLoadIdentity();
gluLookAt(lightPos[0], lightPos[1], lightPos[2],
lightPos[0] + spotDir[0],
lightPos[1] + spotDir[1],
lightPos[2] + spotDir[2],
- 0, 1, 0);
+ 0.0, 1.0, 0.0);
+ glGetFloatv(GL_MODELVIEW_MATRIX, lightModelview);
+ glPopMatrix();
+}
+
+
+/**
+ * Load \c GL_TEXTURE matrix with light's MVP matrix.
+ */
+static void SetShadowTextureMatrix(void)
+{
+ static const GLfloat biasMatrix[16] = {
+ 0.5, 0.0, 0.0, 0.0,
+ 0.0, 0.5, 0.0, 0.0,
+ 0.0, 0.0, 0.5, 0.0,
+ 0.5, 0.5, 0.5, 1.0,
+ };
+
+ glMatrixMode(GL_TEXTURE);
+ glLoadMatrixf(biasMatrix);
+ glTranslatef(0.0, 0.0, Bias);
+ glMultMatrixf(lightProjection);
+ glMultMatrixf(lightModelview);
glMatrixMode(GL_MODELVIEW);
}
@@ -258,7 +406,6 @@ RenderShadowMap(void)
{
GLenum depthFormat; /* GL_DEPTH_COMPONENT or GL_DEPTH_STENCIL_EXT */
GLenum depthType; /* GL_UNSIGNED_INT_24_8_EXT or GL_UNSIGNED_INT */
- float d;
if (WindowWidth >= 1024 && WindowHeight >= 1024) {
ShadowTexWidth = ShadowTexHeight = 1024;
@@ -283,17 +430,11 @@ RenderShadowMap(void)
depthType = GL_UNSIGNED_INT;
}
- /* compute frustum to enclose spot light cone */
- d = ShadowNear * tan(SpotAngle);
-
glMatrixMode(GL_PROJECTION);
- glLoadIdentity();
- glFrustum(-d, d, -d, d, ShadowNear, ShadowFar);
+ glLoadMatrixf(lightProjection);
+
glMatrixMode(GL_MODELVIEW);
- glLoadIdentity();
- gluLookAt(LightPos[0], LightPos[1], LightPos[2], /* from */
- 0, 0, 0, /* target */
- 0, 1, 0); /* up */
+ glLoadMatrixf(lightModelview);
if (UseFBO) {
GLenum fbo_status;
@@ -389,10 +530,11 @@ ShowShadowMap(void)
DisableTexgen();
/* interpret texture's depth values as luminance values */
-#if defined(GL_ARB_shadow)
- 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);
-#endif
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
glBegin(GL_POLYGON);
@@ -420,6 +562,7 @@ Display(void)
LightPos, SpotDir);
if (NeedNewShadowMap) {
+ MakeShadowMatrix(LightPos, SpotDir, SpotAngle, ShadowNear, ShadowFar);
RenderShadowMap();
NeedNewShadowMap = GL_FALSE;
}
@@ -457,12 +600,13 @@ Display(void)
}
if (DisplayMode == SHOW_DEPTH_MAPPING) {
-#if defined(GL_ARB_shadow)
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE_ARB, GL_NONE);
-#endif
+ 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);
- MakeShadowMatrix(LightPos, SpotDir, SpotAngle, ShadowNear, ShadowFar);
+
+ SetShadowTextureMatrix();
EnableIdentityTexgen();
}
else if (DisplayMode == SHOW_DISTANCE) {
@@ -476,19 +620,44 @@ Display(void)
}
else {
assert(DisplayMode == SHOW_SHADOWS);
-#if defined(GL_ARB_shadow)
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE_ARB,
- GL_COMPARE_R_TO_TEXTURE_ARB);
-#endif
- glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
+ 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);
+ }
+ else {
+ glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
+ }
glEnable(GL_TEXTURE_2D);
- MakeShadowMatrix(LightPos, SpotDir, SpotAngle, ShadowNear, ShadowFar);
- EnableIdentityTexgen();
+
+ SetShadowTextureMatrix();
+
+ if (UseVP) {
+ glEnable(GL_VERTEX_PROGRAM_ARB);
+ }
+ else {
+ glEnable(GL_LIGHTING);
+ EnableIdentityTexgen();
+ }
}
DrawScene();
- DisableTexgen();
+ if (UseVP) {
+ glDisable(GL_VERTEX_PROGRAM_ARB);
+ }
+ else {
+ DisableTexgen();
+ glDisable(GL_LIGHTING);
+ }
+
+ if (curr_frag > 0) {
+ glDisable(GL_FRAGMENT_PROGRAM_ARB);
+ }
+
glDisable(GL_TEXTURE_1D);
glDisable(GL_TEXTURE_2D);
}
@@ -561,6 +730,18 @@ Key(unsigned char key, int x, int y)
case 'm':
DisplayMode = SHOW_DEPTH_MAPPING;
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) {
+ glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, frag_progs[curr_frag]);
+ }
+ break;
case 'n':
case 's':
case ' ':
@@ -572,10 +753,10 @@ Key(unsigned char key, int x, int y)
if (Operator >= 8)
Operator = 0;
printf("Operator: %s\n", OperatorName[Operator]);
-#if defined(GL_ARB_shadow)
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC_ARB,
- OperatorFunc[Operator]);
-#endif
+ if (HaveShadow) {
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC_ARB,
+ OperatorFunc[Operator]);
+ }
}
break;
case 'p':
@@ -592,6 +773,11 @@ Key(unsigned char key, int x, int y)
NeedNewShadowMap = GL_TRUE;
}
break;
+ case 'v':
+ UseVP = !UseVP && HaveVP;
+ printf("Using vertex %s mode.\n",
+ UseVP ? "program" : "fixed-function");
+ break;
case 'z':
Zrot -= step;
break;
@@ -646,28 +832,76 @@ SpecialKey(int key, int x, int y)
}
+/* A helper for finding errors in program strings */
+static int FindLine( const char *program, int position )
+{
+ int i, line = 1;
+ for (i = 0; i < position; i++) {
+ if (program[i] == '\n')
+ line++;
+ }
+ return line;
+}
+
+
+static GLuint
+compile_program(GLenum target, const char *code)
+{
+ GLuint p;
+ GLint errorPos;
+
+
+ glGenProgramsARB(1, & p);
+
+ glBindProgramARB(target, p);
+ glProgramStringARB(target, GL_PROGRAM_FORMAT_ASCII_ARB,
+ strlen(code), code);
+ glGetIntegerv(GL_PROGRAM_ERROR_POSITION_ARB, &errorPos);
+ if (glGetError() != GL_NO_ERROR || errorPos != -1) {
+ int l = FindLine(code, errorPos);
+ printf("Fragment Program Error (pos=%d line=%d): %s\n", errorPos, l,
+ (char *) glGetString(GL_PROGRAM_ERROR_STRING_ARB));
+ exit(0);
+ }
+
+ glBindProgramARB(target, 0);
+ return p;
+}
+
static void
Init(void)
{
static const GLfloat borderColor[4] = {1.0, 0.0, 0.0, 0.0};
-#if defined(GL_ARB_depth_texture) && defined(GL_ARB_shadow)
- if (!glutExtensionSupported("GL_ARB_depth_texture") ||
- !glutExtensionSupported("GL_ARB_shadow")) {
-#else
- if (1) {
-#endif
- 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);
+ }
+
+ 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 and GL_ARB_shadow\n");
-#if defined(GL_ARB_shadow_ambient)
+ 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");
}
-#endif
HaveEXTshadowFuncs = glutExtensionSupported("GL_EXT_shadow_funcs");
@@ -690,15 +924,15 @@ 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);
-#if defined(GL_ARB_shadow)
- 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);
-#endif
+
+ 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) {
-#if defined(GL_ARB_shadow_ambient)
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FAIL_VALUE_ARB, 0.3);
-#endif
}
#if defined(GL_EXT_framebuffer_object)
@@ -721,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);
{
@@ -733,6 +966,30 @@ Init(void)
256, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, image);
}
+ if (HaveVP) {
+ vert_prog = compile_program(GL_VERTEX_PROGRAM_ARB, vert_code);
+ glBindProgramARB(GL_VERTEX_PROGRAM_ARB, vert_prog);
+ }
+
+ max_frag = 1;
+ frag_progs[0] = 0;
+
+ if (HaveFP) {
+ frag_progs[1] = compile_program(GL_FRAGMENT_PROGRAM_ARB, frag_code);
+ max_frag = 2;
+ }
+
+ if (HaveFP && HaveFP_Shadow) {
+ frag_progs[2] = compile_program(GL_FRAGMENT_PROGRAM_ARB,
+ frag_shadow_code);
+ 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);
@@ -751,6 +1008,8 @@ PrintHelp(void)
printf(" f = toggle nearest/bilinear texture filtering\n");
printf(" b/B = decrease/increase shadow map Z bias\n");
printf(" p = toggle use of packed depth/stencil\n");
+ printf(" M = cycle through fragment program modes\n");
+ printf(" v = toggle vertex program modes\n");
printf(" cursor keys = rotate scene\n");
printf(" <shift> + cursor keys = rotate light source\n");
if (HaveEXTshadowFuncs)
diff --git a/progs/demos/showbuffer.c b/progs/demos/showbuffer.c
deleted file mode 100644
index 17f84dc62bd..00000000000
--- a/progs/demos/showbuffer.c
+++ /dev/null
@@ -1,192 +0,0 @@
-/* showbuffer.c */
-
-
-/*
- * Copy the depth buffer to the color buffer as a grayscale image.
- * Useful for inspecting the depth buffer values.
- *
- * This program is in the public domain.
- *
- * Brian Paul November 4, 1998
- */
-
-
-#include <assert.h>
-#include <stdlib.h>
-#include <GL/gl.h>
-#include "showbuffer.h"
-
-
-
-/*
- * Copy the depth buffer values into the current color buffer as a
- * grayscale image.
- * Input: winWidth, winHeight - size of the window
- * zBlack - the Z value which should map to black (usually 1)
- * zWhite - the Z value which should map to white (usually 0)
- */
-void
-ShowDepthBuffer( GLsizei winWidth, GLsizei winHeight,
- GLfloat zBlack, GLfloat zWhite )
-{
- GLfloat *depthValues;
-
- assert(zBlack >= 0.0);
- assert(zBlack <= 1.0);
- assert(zWhite >= 0.0);
- assert(zWhite <= 1.0);
- assert(zBlack != zWhite);
-
- glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
- glPixelStorei(GL_PACK_ALIGNMENT, 1);
-
- /* Read depth values */
- depthValues = (GLfloat *) malloc(winWidth * winHeight * sizeof(GLfloat));
- assert(depthValues);
- glReadPixels(0, 0, winWidth, winHeight, GL_DEPTH_COMPONENT,
- GL_FLOAT, depthValues);
-
- /* Map Z values from [zBlack, zWhite] to gray levels in [0, 1] */
- /* Not using glPixelTransfer() because it's broke on some systems! */
- if (zBlack != 0.0 || zWhite != 1.0) {
- GLfloat scale = 1.0 / (zWhite - zBlack);
- GLfloat bias = -zBlack * scale;
- int n = winWidth * winHeight;
- int i;
- for (i = 0; i < n; i++)
- depthValues[i] = depthValues[i] * scale + bias;
- }
-
- /* save GL state */
- glPushAttrib(GL_CURRENT_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT |
- GL_TRANSFORM_BIT | GL_VIEWPORT_BIT);
-
- /* setup raster pos for glDrawPixels */
- glMatrixMode(GL_PROJECTION);
- glPushMatrix();
- glLoadIdentity();
-
- glOrtho(0.0, (GLdouble) winWidth, 0.0, (GLdouble) winHeight, -1.0, 1.0);
- glMatrixMode(GL_MODELVIEW);
- glPushMatrix();
- glLoadIdentity();
-
- glDisable(GL_STENCIL_TEST);
- glDisable(GL_DEPTH_TEST);
- glRasterPos2f(0, 0);
-
- glDrawPixels(winWidth, winHeight, GL_LUMINANCE, GL_FLOAT, depthValues);
-
- glPopMatrix();
- glMatrixMode(GL_PROJECTION);
- glPopMatrix();
- free(depthValues);
-
- glPopAttrib();
-}
-
-
-
-
-/*
- * Copy the alpha channel values into the current color buffer as a
- * grayscale image.
- * Input: winWidth, winHeight - size of the window
- */
-void
-ShowAlphaBuffer( GLsizei winWidth, GLsizei winHeight )
-{
- GLubyte *alphaValues;
-
- glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
- glPixelStorei(GL_PACK_ALIGNMENT, 1);
-
- /* Read alpha values */
- alphaValues = (GLubyte *) malloc(winWidth * winHeight * sizeof(GLubyte));
- assert(alphaValues);
- glReadPixels(0, 0, winWidth, winHeight, GL_ALPHA, GL_UNSIGNED_BYTE, alphaValues);
-
- /* save GL state */
- glPushAttrib(GL_CURRENT_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL |
- GL_TRANSFORM_BIT | GL_VIEWPORT_BIT);
-
- /* setup raster pos for glDrawPixels */
- glMatrixMode(GL_PROJECTION);
- glPushMatrix();
- glLoadIdentity();
-
- glOrtho(0.0, (GLdouble) winWidth, 0.0, (GLdouble) winHeight, -1.0, 1.0);
- glMatrixMode(GL_MODELVIEW);
- glPushMatrix();
- glLoadIdentity();
-
- glDisable(GL_STENCIL_TEST);
- glDisable(GL_DEPTH_TEST);
- glRasterPos2f(0, 0);
-
- glDrawPixels(winWidth, winHeight, GL_LUMINANCE, GL_UNSIGNED_BYTE, alphaValues);
-
- glPopMatrix();
- glMatrixMode(GL_PROJECTION);
- glPopMatrix();
- free(alphaValues);
-
- glPopAttrib();
-}
-
-
-
-/*
- * Copy the stencil buffer values into the current color buffer as a
- * grayscale image.
- * Input: winWidth, winHeight - size of the window
- * scale, bias - scale and bias to apply to stencil values for display
- */
-void
-ShowStencilBuffer( GLsizei winWidth, GLsizei winHeight,
- GLfloat scale, GLfloat bias )
-{
- GLubyte *stencilValues;
-
- glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
- glPixelStorei(GL_PACK_ALIGNMENT, 1);
-
- /* Read stencil values */
- stencilValues = (GLubyte *) malloc(winWidth * winHeight * sizeof(GLubyte));
- assert(stencilValues);
- glReadPixels(0, 0, winWidth, winHeight, GL_STENCIL_INDEX, GL_UNSIGNED_BYTE, stencilValues);
-
- /* save GL state */
- glPushAttrib(GL_CURRENT_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT |
- GL_PIXEL_MODE_BIT | GL_TRANSFORM_BIT | GL_VIEWPORT_BIT);
-
- /* setup raster pos for glDrawPixels */
- glMatrixMode(GL_PROJECTION);
- glPushMatrix();
- glLoadIdentity();
-
- glOrtho(0.0, (GLdouble) winWidth, 0.0, (GLdouble) winHeight, -1.0, 1.0);
- glMatrixMode(GL_MODELVIEW);
- glPushMatrix();
- glLoadIdentity();
-
- glDisable(GL_STENCIL_TEST);
- glDisable(GL_DEPTH_TEST);
- glRasterPos2f(0, 0);
-
- glPixelTransferf(GL_RED_SCALE, scale);
- glPixelTransferf(GL_RED_BIAS, bias);
- glPixelTransferf(GL_GREEN_SCALE, scale);
- glPixelTransferf(GL_GREEN_BIAS, bias);
- glPixelTransferf(GL_BLUE_SCALE, scale);
- glPixelTransferf(GL_BLUE_BIAS, bias);
-
- glDrawPixels(winWidth, winHeight, GL_LUMINANCE, GL_UNSIGNED_BYTE, stencilValues);
-
- glPopMatrix();
- glMatrixMode(GL_PROJECTION);
- glPopMatrix();
- free(stencilValues);
-
- glPopAttrib();
-}
diff --git a/progs/demos/showbuffer.h b/progs/demos/showbuffer.h
deleted file mode 100644
index 63533d8e9b5..00000000000
--- a/progs/demos/showbuffer.h
+++ /dev/null
@@ -1,36 +0,0 @@
-/* showbuffer. h*/
-
-/*
- * Copy the depth buffer to the color buffer as a grayscale image.
- * Useful for inspecting the depth buffer values.
- *
- * This program is in the public domain.
- *
- * Brian Paul November 4, 1998
- */
-
-
-#ifndef SHOWBUFFER_H
-#define SHOWBUFFER_H
-
-
-#include <GL/gl.h>
-
-
-
-extern void
-ShowDepthBuffer( GLsizei winWidth, GLsizei winHeight,
- GLfloat zBlack, GLfloat zWhite );
-
-
-extern void
-ShowAlphaBuffer( GLsizei winWidth, GLsizei winHeight );
-
-
-extern void
-ShowStencilBuffer( GLsizei winWidth, GLsizei winHeight,
- GLfloat scale, GLfloat bias );
-
-
-
-#endif
diff --git a/progs/demos/spriteblast.c b/progs/demos/spriteblast.c
index f0d3d0dfd41..5ad8e4d9a94 100644
--- a/progs/demos/spriteblast.c
+++ b/progs/demos/spriteblast.c
@@ -333,13 +333,13 @@ menu(int option)
smooth = 0;
break;
case 10:
- glPointSize(4.0);
+ glPointSize(16.0);
break;
case 11:
- glPointSize(8.0);
+ glPointSize(32.0);
break;
case 12:
- glPointSize(16.0);
+ glPointSize(64.0);
break;
case 13:
spin = 1 - spin;
@@ -411,19 +411,19 @@ key(unsigned char c, int x, int y)
glutPostRedisplay();
break;
case '1':
- glPointSize(2.0);
+ glPointSize(16.0);
glutPostRedisplay();
break;
case '2':
- glPointSize(4.0);
+ glPointSize(32.0);
glutPostRedisplay();
break;
case '3':
- glPointSize(8.0);
+ glPointSize(64.0);
glutPostRedisplay();
break;
case '4':
- glPointSize(16.0);
+ glPointSize(128.0);
glutPostRedisplay();
break;
case 27:
@@ -526,9 +526,9 @@ main(int argc, char **argv)
glutAddMenuEntry("Threshold 10", 7);
glutAddMenuEntry("Point smooth on", 8);
glutAddMenuEntry("Point smooth off", 9);
- glutAddMenuEntry("Point size 4", 10);
- glutAddMenuEntry("Point size 8", 11);
- glutAddMenuEntry("Point size 16", 12);
+ glutAddMenuEntry("Point size 16", 10);
+ glutAddMenuEntry("Point size 32", 11);
+ glutAddMenuEntry("Point size 64", 12);
glutAddMenuEntry("Toggle spin", 13);
glutAddMenuEntry("200 points ", 14);
glutAddMenuEntry("500 points ", 15);
@@ -544,7 +544,7 @@ main(int argc, char **argv)
glEnable(GL_DEPTH_TEST);
glEnable(GL_POINT_SMOOTH);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- glPointSize(16.0);
+ glPointSize(32.0);
#ifdef GL_ARB_point_parameters
glPointParameterfvARB(GL_POINT_DISTANCE_ATTENUATION_ARB, theQuad);
#endif
diff --git a/progs/demos/streaming_rect.c b/progs/demos/streaming_rect.c
index 86e00803c01..4c1d8535fd7 100644
--- a/progs/demos/streaming_rect.c
+++ b/progs/demos/streaming_rect.c
@@ -1,13 +1,9 @@
-
/*
- * GL_ARB_multitexture demo
+ * GL_ARB_pixel_buffer_object test
*
* Command line options:
- * -info print GL implementation information
- *
+ * -w WIDTH -h HEIGHT sets window size
*
- * Brian Paul November 1998 This program is in the public domain.
- * Modified on 12 Feb 2002 for > 2 texture units.
*/
#define GL_GLEXT_PROTOTYPES
@@ -25,6 +21,8 @@
#define PBO 11
#define QUIT 100
+static GLuint DrawPBO;
+
static GLboolean Animate = GL_TRUE;
static GLboolean use_pbo = 1;
static GLboolean whole_rect = 1;
@@ -49,7 +47,7 @@ static void Idle( void )
}
}
-static int max( int a, int b ) { return a > b ? a : b; }
+/*static int max( int a, int b ) { return a > b ? a : b; }*/
static int min( int a, int b ) { return a < b ? a : b; }
static void DrawObject()
@@ -62,6 +60,7 @@ static void DrawObject()
* release the old copy of the texture and allocate a new one
* without waiting for outstanding rendering to complete.
*/
+ glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_EXT, DrawPBO);
glBufferDataARB(GL_PIXEL_UNPACK_BUFFER_EXT, size, NULL, GL_STREAM_DRAW_ARB);
{
@@ -69,7 +68,7 @@ static void DrawObject()
printf("char %d\n", (unsigned char)(Drift * 255));
- memset(image, size, (unsigned char)(Drift * 255));
+ memset(image, (unsigned char)(Drift * 255), size);
glUnmapBufferARB(GL_PIXEL_UNPACK_BUFFER_EXT);
}
@@ -86,7 +85,9 @@ static void DrawObject()
if (image == NULL)
image = malloc(size);
- memset(image, size, (unsigned char)(Drift * 255));
+ glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_EXT, 0);
+
+ memset(image, (unsigned char)(Drift * 255), size);
/* BGRA should be the fast path for regular uploads as well.
*/
@@ -227,12 +228,12 @@ static void SpecialKey( int key, int x, int y )
static void Init( int argc, char *argv[] )
{
const char *exten = (const char *) glGetString(GL_EXTENSIONS);
- GLuint texObj, DrawPBO;
+ GLuint texObj;
GLint size;
- if (!strstr(exten, "GL_ARB_multitexture")) {
- printf("Sorry, GL_ARB_multitexture not supported by this renderer.\n");
+ if (!strstr(exten, "GL_ARB_pixel_buffer_object")) {
+ printf("Sorry, GL_ARB_pixel_buffer_object not supported by this renderer.\n");
exit(1);
}
diff --git a/progs/demos/texenv.c b/progs/demos/texenv.c
index 590867b4945..c4174dc173d 100644
--- a/progs/demos/texenv.c
+++ b/progs/demos/texenv.c
@@ -76,6 +76,7 @@ int textureWidth = 64;
int textureHeight = 64;
int winWidth = 580, winHeight = 720;
+int win;
struct formatInfo {
GLenum baseFormat;
@@ -288,6 +289,7 @@ static void keyboard( unsigned char c, int x, int y )
displayLevelInfo = !displayLevelInfo;
break;
case 27: /* Escape key should force exit. */
+ glutDestroyWindow(win);
exit(0);
break;
default:
@@ -785,7 +787,7 @@ int main( int argc, char *argv[] )
glutInitWindowSize( winWidth, winHeight );
glutInitWindowPosition( 0, 0 );
- glutCreateWindow( "Texture Environment Test" );
+ win = glutCreateWindow( "Texture Environment Test" );
initialize();
instructions();
diff --git a/progs/demos/trackball.c b/progs/demos/trackball.c
deleted file mode 100644
index a6c4c60d06b..00000000000
--- a/progs/demos/trackball.c
+++ /dev/null
@@ -1,338 +0,0 @@
-#include <stdio.h>
-/*
- * (c) Copyright 1993, 1994, Silicon Graphics, Inc.
- * ALL RIGHTS RESERVED
- * Permission to use, copy, modify, and distribute this software for
- * any purpose and without fee is hereby granted, provided that the above
- * copyright notice appear in all copies and that both the copyright notice
- * and this permission notice appear in supporting documentation, and that
- * the name of Silicon Graphics, Inc. not be used in advertising
- * or publicity pertaining to distribution of the software without specific,
- * written prior permission.
- *
- * THE MATERIAL EMBODIED ON THIS SOFTWARE IS PROVIDED TO YOU "AS-IS"
- * AND WITHOUT WARRANTY OF ANY KIND, EXPRESS, IMPLIED OR OTHERWISE,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY OR
- * FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
- * GRAPHICS, INC. BE LIABLE TO YOU OR ANYONE ELSE FOR ANY DIRECT,
- * SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY
- * KIND, OR ANY DAMAGES WHATSOEVER, INCLUDING WITHOUT LIMITATION,
- * LOSS OF PROFIT, LOSS OF USE, SAVINGS OR REVENUE, OR THE CLAIMS OF
- * THIRD PARTIES, WHETHER OR NOT SILICON GRAPHICS, INC. HAS BEEN
- * ADVISED OF THE POSSIBILITY OF SUCH LOSS, HOWEVER CAUSED AND ON
- * ANY THEORY OF LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE
- * POSSESSION, USE OR PERFORMANCE OF THIS SOFTWARE.
- *
- * US Government Users Restricted Rights
- * Use, duplication, or disclosure by the Government is subject to
- * restrictions set forth in FAR 52.227.19(c)(2) or subparagraph
- * (c)(1)(ii) of the Rights in Technical Data and Computer Software
- * clause at DFARS 252.227-7013 and/or in similar or successor
- * clauses in the FAR or the DOD or NASA FAR Supplement.
- * Unpublished-- rights reserved under the copyright laws of the
- * United States. Contractor/manufacturer is Silicon Graphics,
- * Inc., 2011 N. Shoreline Blvd., Mountain View, CA 94039-7311.
- *
- * OpenGL(TM) is a trademark of Silicon Graphics, Inc.
- */
-/*
- * Trackball code:
- *
- * Implementation of a virtual trackball.
- * Implemented by Gavin Bell, lots of ideas from Thant Tessman and
- * the August '88 issue of Siggraph's "Computer Graphics," pp. 121-129.
- *
- * Vector manip code:
- *
- * Original code from:
- * David M. Ciemiewicz, Mark Grossman, Henry Moreton, and Paul Haeberli
- *
- * Much mucking with by:
- * Gavin Bell
- */
-#if defined(_WIN32)
-#pragma warning (disable:4244) /* disable bogus conversion warnings */
-#endif
-#include <math.h>
-#include "trackball.h"
-
-/*
- * This size should really be based on the distance from the center of
- * rotation to the point on the object underneath the mouse. That
- * point would then track the mouse as closely as possible. This is a
- * simple example, though, so that is left as an Exercise for the
- * Programmer.
- */
-#define TRACKBALLSIZE (0.8f)
-
-/*
- * Local function prototypes (not defined in trackball.h)
- */
-static float tb_project_to_sphere(float, float, float);
-static void normalize_quat(float [4]);
-
-static void
-vzero(float v[3])
-{
- v[0] = 0.0;
- v[1] = 0.0;
- v[2] = 0.0;
-}
-
-static void
-vset(float v[3], float x, float y, float z)
-{
- v[0] = x;
- v[1] = y;
- v[2] = z;
-}
-
-static void
-vsub(const float src1[3], const float src2[3], float dst[3])
-{
- dst[0] = src1[0] - src2[0];
- dst[1] = src1[1] - src2[1];
- dst[2] = src1[2] - src2[2];
-}
-
-static void
-vcopy(const float v1[3], float v2[3])
-{
- register int i;
- for (i = 0 ; i < 3 ; i++)
- v2[i] = v1[i];
-}
-
-static void
-vcross(const float v1[3], const float v2[3], float cross[3])
-{
- float temp[3];
-
- temp[0] = (v1[1] * v2[2]) - (v1[2] * v2[1]);
- temp[1] = (v1[2] * v2[0]) - (v1[0] * v2[2]);
- temp[2] = (v1[0] * v2[1]) - (v1[1] * v2[0]);
- vcopy(temp, cross);
-}
-
-static float
-vlength(const float v[3])
-{
- return sqrt(v[0] * v[0] + v[1] * v[1] + v[2] * v[2]);
-}
-
-static void
-vscale(float v[3], float div)
-{
- v[0] *= div;
- v[1] *= div;
- v[2] *= div;
-}
-
-static void
-vnormal(float v[3])
-{
- vscale(v,1.0/vlength(v));
-}
-
-static float
-vdot(const float v1[3], const float v2[3])
-{
- return v1[0]*v2[0] + v1[1]*v2[1] + v1[2]*v2[2];
-}
-
-static void
-vadd(const float src1[3], const float src2[3], float dst[3])
-{
- dst[0] = src1[0] + src2[0];
- dst[1] = src1[1] + src2[1];
- dst[2] = src1[2] + src2[2];
-}
-
-/*
- * Ok, simulate a track-ball. Project the points onto the virtual
- * trackball, then figure out the axis of rotation, which is the cross
- * product of P1 P2 and O P1 (O is the center of the ball, 0,0,0)
- * Note: This is a deformed trackball-- is a trackball in the center,
- * but is deformed into a hyperbolic sheet of rotation away from the
- * center. This particular function was chosen after trying out
- * several variations.
- *
- * It is assumed that the arguments to this routine are in the range
- * (-1.0 ... 1.0)
- */
-void
-trackball(float q[4], float p1x, float p1y, float p2x, float p2y)
-{
- float a[3]; /* Axis of rotation */
- float phi; /* how much to rotate about axis */
- float p1[3], p2[3], d[3];
- float t;
-
- if (p1x == p2x && p1y == p2y) {
- /* Zero rotation */
- vzero(q);
- q[3] = 1.0;
- return;
- }
-
- /*
- * First, figure out z-coordinates for projection of P1 and P2 to
- * deformed sphere
- */
- vset(p1,p1x,p1y,tb_project_to_sphere(TRACKBALLSIZE,p1x,p1y));
- vset(p2,p2x,p2y,tb_project_to_sphere(TRACKBALLSIZE,p2x,p2y));
-
- /*
- * Now, we want the cross product of P1 and P2
- */
- vcross(p2,p1,a);
-
- /*
- * Figure out how much to rotate around that axis.
- */
- vsub(p1,p2,d);
- t = vlength(d) / (2.0*TRACKBALLSIZE);
-
- /*
- * Avoid problems with out-of-control values...
- */
- if (t > 1.0) t = 1.0;
- if (t < -1.0) t = -1.0;
- phi = 2.0 * asin(t);
-
- axis_to_quat(a,phi,q);
-}
-
-/*
- * Given an axis and angle, compute quaternion.
- */
-void
-axis_to_quat(const float a[3], float phi, float q[4])
-{
- vcopy(a,q);
- vnormal(q);
- vscale(q, sin(phi/2.0));
- q[3] = cos(phi/2.0);
-}
-
-/*
- * Project an x,y pair onto a sphere of radius r OR a hyperbolic sheet
- * if we are away from the center of the sphere.
- */
-static float
-tb_project_to_sphere(float r, float x, float y)
-{
- float d, t, z;
-
- d = sqrt(x*x + y*y);
- if (d < r * 0.70710678118654752440) { /* Inside sphere */
- z = sqrt(r*r - d*d);
- } else { /* On hyperbola */
- t = r / 1.41421356237309504880;
- z = t*t / d;
- }
- return z;
-}
-
-/*
- * Given two rotations, e1 and e2, expressed as quaternion rotations,
- * figure out the equivalent single rotation and stuff it into dest.
- *
- * This routine also normalizes the result every RENORMCOUNT times it is
- * called, to keep error from creeping in.
- *
- * NOTE: This routine is written so that q1 or q2 may be the same
- * as dest (or each other).
- */
-
-#define RENORMCOUNT 97
-
-void
-add_quats(const float q1[4], const float q2[4], float dest[4])
-{
- static int count=0;
- float t1[4], t2[4], t3[4];
- float tf[4];
-
-#if 0
-printf("q1 = %f %f %f %f\n", q1[0], q1[1], q1[2], q1[3]);
-printf("q2 = %f %f %f %f\n", q2[0], q2[1], q2[2], q2[3]);
-#endif
-
- vcopy(q1,t1);
- vscale(t1,q2[3]);
-
- vcopy(q2,t2);
- vscale(t2,q1[3]);
-
- vcross(q2,q1,t3);
- vadd(t1,t2,tf);
- vadd(t3,tf,tf);
- tf[3] = q1[3] * q2[3] - vdot(q1,q2);
-
-#if 0
-printf("tf = %f %f %f %f\n", tf[0], tf[1], tf[2], tf[3]);
-#endif
-
- dest[0] = tf[0];
- dest[1] = tf[1];
- dest[2] = tf[2];
- dest[3] = tf[3];
-
- if (++count > RENORMCOUNT) {
- count = 0;
- normalize_quat(dest);
- }
-}
-
-/*
- * Quaternions always obey: a^2 + b^2 + c^2 + d^2 = 1.0
- * If they don't add up to 1.0, dividing by their magnitued will
- * renormalize them.
- *
- * Note: See the following for more information on quaternions:
- *
- * - Shoemake, K., Animating rotation with quaternion curves, Computer
- * Graphics 19, No 3 (Proc. SIGGRAPH'85), 245-254, 1985.
- * - Pletinckx, D., Quaternion calculus as a basic tool in computer
- * graphics, The Visual Computer 5, 2-13, 1989.
- */
-static void
-normalize_quat(float q[4])
-{
- int i;
- float mag;
-
- mag = sqrt(q[0]*q[0] + q[1]*q[1] + q[2]*q[2] + q[3]*q[3]);
- for (i = 0; i < 4; i++)
- q[i] /= mag;
-}
-
-/*
- * Build a rotation matrix, given a quaternion rotation.
- *
- */
-void
-build_rotmatrix(float m[4][4], const float q[4])
-{
- m[0][0] = 1.0 - 2.0 * (q[1] * q[1] + q[2] * q[2]);
- m[0][1] = 2.0 * (q[0] * q[1] - q[2] * q[3]);
- m[0][2] = 2.0 * (q[2] * q[0] + q[1] * q[3]);
- m[0][3] = 0.0;
-
- m[1][0] = 2.0 * (q[0] * q[1] + q[2] * q[3]);
- m[1][1]= 1.0 - 2.0 * (q[2] * q[2] + q[0] * q[0]);
- m[1][2] = 2.0 * (q[1] * q[2] - q[0] * q[3]);
- m[1][3] = 0.0;
-
- m[2][0] = 2.0 * (q[2] * q[0] - q[1] * q[3]);
- m[2][1] = 2.0 * (q[1] * q[2] + q[0] * q[3]);
- m[2][2] = 1.0 - 2.0 * (q[1] * q[1] + q[0] * q[0]);
- m[2][3] = 0.0;
-
- m[3][0] = 0.0;
- m[3][1] = 0.0;
- m[3][2] = 0.0;
- m[3][3] = 1.0;
-}
-
diff --git a/progs/demos/trackball.h b/progs/demos/trackball.h
deleted file mode 100644
index 9b278640e10..00000000000
--- a/progs/demos/trackball.h
+++ /dev/null
@@ -1,84 +0,0 @@
-/*
- * (c) Copyright 1993, 1994, Silicon Graphics, Inc.
- * ALL RIGHTS RESERVED
- * Permission to use, copy, modify, and distribute this software for
- * any purpose and without fee is hereby granted, provided that the above
- * copyright notice appear in all copies and that both the copyright notice
- * and this permission notice appear in supporting documentation, and that
- * the name of Silicon Graphics, Inc. not be used in advertising
- * or publicity pertaining to distribution of the software without specific,
- * written prior permission.
- *
- * THE MATERIAL EMBODIED ON THIS SOFTWARE IS PROVIDED TO YOU "AS-IS"
- * AND WITHOUT WARRANTY OF ANY KIND, EXPRESS, IMPLIED OR OTHERWISE,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY OR
- * FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
- * GRAPHICS, INC. BE LIABLE TO YOU OR ANYONE ELSE FOR ANY DIRECT,
- * SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY
- * KIND, OR ANY DAMAGES WHATSOEVER, INCLUDING WITHOUT LIMITATION,
- * LOSS OF PROFIT, LOSS OF USE, SAVINGS OR REVENUE, OR THE CLAIMS OF
- * THIRD PARTIES, WHETHER OR NOT SILICON GRAPHICS, INC. HAS BEEN
- * ADVISED OF THE POSSIBILITY OF SUCH LOSS, HOWEVER CAUSED AND ON
- * ANY THEORY OF LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE
- * POSSESSION, USE OR PERFORMANCE OF THIS SOFTWARE.
- *
- * US Government Users Restricted Rights
- * Use, duplication, or disclosure by the Government is subject to
- * restrictions set forth in FAR 52.227.19(c)(2) or subparagraph
- * (c)(1)(ii) of the Rights in Technical Data and Computer Software
- * clause at DFARS 252.227-7013 and/or in similar or successor
- * clauses in the FAR or the DOD or NASA FAR Supplement.
- * Unpublished-- rights reserved under the copyright laws of the
- * United States. Contractor/manufacturer is Silicon Graphics,
- * Inc., 2011 N. Shoreline Blvd., Mountain View, CA 94039-7311.
- *
- * OpenGL(TM) is a trademark of Silicon Graphics, Inc.
- */
-/*
- * trackball.h
- * A virtual trackball implementation
- * Written by Gavin Bell for Silicon Graphics, November 1988.
- */
-
-#ifndef TRACKBALL_H
-#define TRACKBALL_H
-
-
-/*
- * Pass the x and y coordinates of the last and current positions of
- * the mouse, scaled so they are from (-1.0 ... 1.0).
- *
- * The resulting rotation is returned as a quaternion rotation in the
- * first paramater.
- */
-void
-trackball(float q[4], float p1x, float p1y, float p2x, float p2y);
-
-/*
- * Given two quaternions, add them together to get a third quaternion.
- * Adding quaternions to get a compound rotation is analagous to adding
- * translations to get a compound translation. When incrementally
- * adding rotations, the first argument here should be the new
- * rotation, the second and third the total rotation (which will be
- * over-written with the resulting new total rotation).
- */
-void
-add_quats(const float q1[4], const float q2[4], float dest[4]);
-
-/*
- * A useful function, builds a rotation matrix in Matrix based on
- * given quaternion.
- */
-void
-build_rotmatrix(float m[4][4], const float q[4]);
-
-/*
- * This function computes a quaternion based on an axis (defined by
- * the given vector) and an angle about which to rotate. The angle is
- * expressed in radians. The result is put into the third argument.
- */
-void
-axis_to_quat(const float a[3], float phi, float q[4]);
-
-
-#endif /* TRACKBALL_H */
diff --git a/progs/ggi/sphere.asc b/progs/ggi/sphere.asc
index 1424a740d7b..cf7cebf2249 100644
--- a/progs/ggi/sphere.asc
+++ b/progs/ggi/sphere.asc
@@ -1,132 +1,132 @@
-Ambient light color: Red=0.039216 Green=0.039216 Blue=0.039216
-
-Named object: "Object01"
-Tri-mesh, Vertices: 20 Faces: 36
-Vertex list:
-Vertex 0: X: -210 Y: -432.781738 Z: 180.000031
-Vertex 1: X: -610.810303 Y: 144.260559 Z: 103.580154
-Vertex 2: X: 56.586655 Y: 144.260544 Z: -128.902023
-Vertex 3: X: -75.776352 Y: 144.260605 Z: 565.321838
-Vertex 4: X: -462.815979 Y: -347.937683 Z: 131.797302
-Vertex 5: X: -616.506042 Y: -126.67173 Z: 102.494209
-Vertex 6: X: -41.847229 Y: -347.937683 Z: -14.843644
-Vertex 7: X: 60.375015 Y: -126.671753 Z: -133.291641
-Vertex 8: X: -125.336807 Y: -347.937653 Z: 423.046448
-Vertex 9: X: -73.868958 Y: -126.671692 Z: 570.797424
-Vertex 10: X: -448.353271 Y: 237.304672 Z: -92.34951
-Vertex 11: X: -192.440964 Y: 237.304672 Z: -181.494431
-Vertex 12: X: 145.038193 Y: 237.304672 Z: 109.754745
-Vertex 13: X: 94.283768 Y: 237.304688 Z: 375.953766
-Vertex 14: X: -326.684937 Y: 237.304733 Z: 522.594727
-Vertex 15: X: -531.842834 Y: 237.304718 Z: 345.540588
-Vertex 16: X: -331.419525 Y: -225.964966 Z: -168.564438
-Vertex 17: X: 152.575485 Y: -225.964935 Z: 249.129868
-Vertex 18: X: -451.155914 Y: -225.964905 Z: 459.434662
-Vertex 19: X: -298.413483 Y: 423.31897 Z: 163.142761
-Face list:
-Face 0: A:0 B:4 C:6 AB:1 BC:1 CA:1
-Face 1: A:4 B:5 C:16 AB:1 BC:1 CA:1
-Face 2: A:4 B:16 C:6 AB:1 BC:1 CA:1
-Face 3: A:6 B:16 C:7 AB:1 BC:1 CA:1
-Face 4: A:5 B:1 C:10 AB:1 BC:1 CA:1
-Face 5: A:5 B:10 C:16 AB:1 BC:1 CA:1
-Face 6: A:16 B:10 C:11 AB:1 BC:1 CA:1
-Face 7: A:16 B:11 C:7 AB:1 BC:1 CA:1
-Face 8: A:7 B:11 C:2 AB:1 BC:1 CA:1
-Face 9: A:0 B:6 C:8 AB:1 BC:1 CA:1
-Face 10: A:6 B:7 C:17 AB:1 BC:1 CA:1
-Face 11: A:6 B:17 C:8 AB:1 BC:1 CA:1
-Face 12: A:8 B:17 C:9 AB:1 BC:1 CA:1
-Face 13: A:7 B:2 C:12 AB:1 BC:1 CA:1
-Face 14: A:7 B:12 C:17 AB:1 BC:1 CA:1
-Face 15: A:17 B:12 C:13 AB:1 BC:1 CA:1
-Face 16: A:17 B:13 C:9 AB:1 BC:1 CA:1
-Face 17: A:9 B:13 C:3 AB:1 BC:1 CA:1
-Face 18: A:0 B:8 C:4 AB:1 BC:1 CA:1
-Face 19: A:8 B:9 C:18 AB:1 BC:1 CA:1
-Face 20: A:8 B:18 C:4 AB:1 BC:1 CA:1
-Face 21: A:4 B:18 C:5 AB:1 BC:1 CA:1
-Face 22: A:9 B:3 C:14 AB:1 BC:1 CA:1
-Face 23: A:9 B:14 C:18 AB:1 BC:1 CA:1
-Face 24: A:18 B:14 C:15 AB:1 BC:1 CA:1
-Face 25: A:18 B:15 C:5 AB:1 BC:1 CA:1
-Face 26: A:5 B:15 C:1 AB:1 BC:1 CA:1
-Face 27: A:1 B:15 C:10 AB:1 BC:1 CA:1
-Face 28: A:15 B:14 C:19 AB:1 BC:1 CA:1
-Face 29: A:15 B:19 C:10 AB:1 BC:1 CA:1
-Face 30: A:10 B:19 C:11 AB:1 BC:1 CA:1
-Face 31: A:14 B:3 C:13 AB:1 BC:1 CA:1
-Face 32: A:14 B:13 C:19 AB:1 BC:1 CA:1
-Face 33: A:19 B:13 C:12 AB:1 BC:1 CA:1
-Face 34: A:19 B:12 C:11 AB:1 BC:1 CA:1
-
- Page 1
-
-
-
-Face 35: A:11 B:12 C:2 AB:1 BC:1 CA:1
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Page 2
-
-
-
+Ambient light color: Red=0.039216 Green=0.039216 Blue=0.039216
+
+Named object: "Object01"
+Tri-mesh, Vertices: 20 Faces: 36
+Vertex list:
+Vertex 0: X: -210 Y: -432.781738 Z: 180.000031
+Vertex 1: X: -610.810303 Y: 144.260559 Z: 103.580154
+Vertex 2: X: 56.586655 Y: 144.260544 Z: -128.902023
+Vertex 3: X: -75.776352 Y: 144.260605 Z: 565.321838
+Vertex 4: X: -462.815979 Y: -347.937683 Z: 131.797302
+Vertex 5: X: -616.506042 Y: -126.67173 Z: 102.494209
+Vertex 6: X: -41.847229 Y: -347.937683 Z: -14.843644
+Vertex 7: X: 60.375015 Y: -126.671753 Z: -133.291641
+Vertex 8: X: -125.336807 Y: -347.937653 Z: 423.046448
+Vertex 9: X: -73.868958 Y: -126.671692 Z: 570.797424
+Vertex 10: X: -448.353271 Y: 237.304672 Z: -92.34951
+Vertex 11: X: -192.440964 Y: 237.304672 Z: -181.494431
+Vertex 12: X: 145.038193 Y: 237.304672 Z: 109.754745
+Vertex 13: X: 94.283768 Y: 237.304688 Z: 375.953766
+Vertex 14: X: -326.684937 Y: 237.304733 Z: 522.594727
+Vertex 15: X: -531.842834 Y: 237.304718 Z: 345.540588
+Vertex 16: X: -331.419525 Y: -225.964966 Z: -168.564438
+Vertex 17: X: 152.575485 Y: -225.964935 Z: 249.129868
+Vertex 18: X: -451.155914 Y: -225.964905 Z: 459.434662
+Vertex 19: X: -298.413483 Y: 423.31897 Z: 163.142761
+Face list:
+Face 0: A:0 B:4 C:6 AB:1 BC:1 CA:1
+Face 1: A:4 B:5 C:16 AB:1 BC:1 CA:1
+Face 2: A:4 B:16 C:6 AB:1 BC:1 CA:1
+Face 3: A:6 B:16 C:7 AB:1 BC:1 CA:1
+Face 4: A:5 B:1 C:10 AB:1 BC:1 CA:1
+Face 5: A:5 B:10 C:16 AB:1 BC:1 CA:1
+Face 6: A:16 B:10 C:11 AB:1 BC:1 CA:1
+Face 7: A:16 B:11 C:7 AB:1 BC:1 CA:1
+Face 8: A:7 B:11 C:2 AB:1 BC:1 CA:1
+Face 9: A:0 B:6 C:8 AB:1 BC:1 CA:1
+Face 10: A:6 B:7 C:17 AB:1 BC:1 CA:1
+Face 11: A:6 B:17 C:8 AB:1 BC:1 CA:1
+Face 12: A:8 B:17 C:9 AB:1 BC:1 CA:1
+Face 13: A:7 B:2 C:12 AB:1 BC:1 CA:1
+Face 14: A:7 B:12 C:17 AB:1 BC:1 CA:1
+Face 15: A:17 B:12 C:13 AB:1 BC:1 CA:1
+Face 16: A:17 B:13 C:9 AB:1 BC:1 CA:1
+Face 17: A:9 B:13 C:3 AB:1 BC:1 CA:1
+Face 18: A:0 B:8 C:4 AB:1 BC:1 CA:1
+Face 19: A:8 B:9 C:18 AB:1 BC:1 CA:1
+Face 20: A:8 B:18 C:4 AB:1 BC:1 CA:1
+Face 21: A:4 B:18 C:5 AB:1 BC:1 CA:1
+Face 22: A:9 B:3 C:14 AB:1 BC:1 CA:1
+Face 23: A:9 B:14 C:18 AB:1 BC:1 CA:1
+Face 24: A:18 B:14 C:15 AB:1 BC:1 CA:1
+Face 25: A:18 B:15 C:5 AB:1 BC:1 CA:1
+Face 26: A:5 B:15 C:1 AB:1 BC:1 CA:1
+Face 27: A:1 B:15 C:10 AB:1 BC:1 CA:1
+Face 28: A:15 B:14 C:19 AB:1 BC:1 CA:1
+Face 29: A:15 B:19 C:10 AB:1 BC:1 CA:1
+Face 30: A:10 B:19 C:11 AB:1 BC:1 CA:1
+Face 31: A:14 B:3 C:13 AB:1 BC:1 CA:1
+Face 32: A:14 B:13 C:19 AB:1 BC:1 CA:1
+Face 33: A:19 B:13 C:12 AB:1 BC:1 CA:1
+Face 34: A:19 B:12 C:11 AB:1 BC:1 CA:1
+
+ Page 1
+
+
+
+Face 35: A:11 B:12 C:2 AB:1 BC:1 CA:1
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Page 2
+
+
+
diff --git a/progs/ggi/torus.asc b/progs/ggi/torus.asc
index 6bd41f40337..605a62baa45 100644
--- a/progs/ggi/torus.asc
+++ b/progs/ggi/torus.asc
@@ -1,264 +1,264 @@
-Ambient light color: Red=0.039216 Green=0.039216 Blue=0.039216
-
-Named object: "Object01"
-Tri-mesh, Vertices: 40 Faces: 80
-Vertex list:
-Vertex 0: X: -50.170624 Y: -0.000026 Z: -240.147842
-Vertex 1: X: -80.584503 Y: -63.958851 Z: -205.014572
-Vertex 2: X: -129.795166 Y: -39.528744 Z: -148.16774
-Vertex 3: X: -129.795166 Y: 39.528721 Z: -148.16774
-Vertex 4: X: -80.584503 Y: 63.958797 Z: -205.014572
-Vertex 5: X: 85.963654 Y: -0.000002 Z: 31.490465
-Vertex 6: X: 39.614838 Y: -63.958828 Z: 34.827602
-Vertex 7: X: -35.37915 Y: -39.528728 Z: 40.227196
-Vertex 8: X: -35.37912 Y: 39.528736 Z: 40.227188
-Vertex 9: X: 39.614838 Y: 63.95882 Z: 34.827595
-Vertex 10: X: -9.852051 Y: 0.000023 Z: 319.829254
-Vertex 11: X: -44.985352 Y: -63.958805 Z: 289.415405
-Vertex 12: X: -101.832199 Y: -39.528709 Z: 240.204758
-Vertex 13: X: -101.832184 Y: 39.528755 Z: 240.204773
-Vertex 14: X: -44.985352 Y: 63.958843 Z: 289.415405
-Vertex 15: X: -281.490326 Y: 0.000035 Z: 455.963654
-Vertex 16: X: -284.827484 Y: -63.958794 Z: 409.614868
-Vertex 17: X: -290.227112 Y: -39.528702 Z: 334.62085
-Vertex 18: X: -290.227112 Y: 39.528763 Z: 334.62088
-Vertex 19: X: -284.827484 Y: 63.958855 Z: 409.614838
-Vertex 20: X: -569.829163 Y: 0.000026 Z: 360.14798
-Vertex 21: X: -539.415344 Y: -63.958801 Z: 325.014709
-Vertex 22: X: -490.204712 Y: -39.528709 Z: 268.167847
-Vertex 23: X: -490.204712 Y: 39.528755 Z: 268.167847
-Vertex 24: X: -539.415344 Y: 63.958847 Z: 325.014679
-Vertex 25: X: -705.963684 Y: 0.000002 Z: 88.509598
-Vertex 26: X: -659.614807 Y: -63.958824 Z: 85.172462
-Vertex 27: X: -584.62085 Y: -39.528725 Z: 79.77285
-Vertex 28: X: -584.62085 Y: 39.52874 Z: 79.77285
-Vertex 29: X: -659.614868 Y: 63.958824 Z: 85.172447
-Vertex 30: X: -610.147827 Y: -0.000023 Z: -199.829361
-Vertex 31: X: -575.014587 Y: -63.958847 Z: -169.415497
-Vertex 32: X: -518.167725 Y: -39.528744 Z: -120.204819
-Vertex 33: X: -518.167725 Y: 39.528721 Z: -120.204834
-Vertex 34: X: -575.014587 Y: 63.958801 Z: -169.415497
-Vertex 35: X: -338.509338 Y: -0.000035 Z: -335.963745
-Vertex 36: X: -335.172241 Y: -63.958858 Z: -289.614868
-Vertex 37: X: -329.772675 Y: -39.528751 Z: -214.620865
-Vertex 38: X: -329.772675 Y: 39.528713 Z: -214.620865
-Vertex 39: X: -335.172241 Y: 63.95879 Z: -289.614899
-Face list:
-Face 0: A:0 B:6 C:1 AB:0 BC:1 CA:1
-Smoothing: 1
-Face 1: A:0 B:5 C:6 AB:1 BC:1 CA:0
-Smoothing: 1
-Face 2: A:1 B:7 C:2 AB:0 BC:1 CA:1
-Smoothing: 2
-Face 3: A:1 B:6 C:7 AB:1 BC:1 CA:0
-Smoothing: 2
-Face 4: A:2 B:8 C:3 AB:0 BC:1 CA:1
-Smoothing: 3
-Face 5: A:2 B:7 C:8 AB:1 BC:1 CA:0
-Smoothing: 3
-Face 6: A:3 B:9 C:4 AB:0 BC:1 CA:1
-Smoothing: 4
-Face 7: A:3 B:8 C:9 AB:1 BC:1 CA:0
-
- Page 1
-
-
-
-Smoothing: 4
-Face 8: A:4 B:5 C:0 AB:0 BC:1 CA:1
-Smoothing: 5
-Face 9: A:4 B:9 C:5 AB:1 BC:1 CA:0
-Smoothing: 5
-Face 10: A:5 B:11 C:6 AB:0 BC:1 CA:1
-Smoothing: 6
-Face 11: A:5 B:10 C:11 AB:1 BC:1 CA:0
-Smoothing: 6
-Face 12: A:6 B:12 C:7 AB:0 BC:1 CA:1
-Smoothing: 7
-Face 13: A:6 B:11 C:12 AB:1 BC:1 CA:0
-Smoothing: 7
-Face 14: A:7 B:13 C:8 AB:0 BC:1 CA:1
-Smoothing: 8
-Face 15: A:7 B:12 C:13 AB:1 BC:1 CA:0
-Smoothing: 8
-Face 16: A:8 B:14 C:9 AB:0 BC:1 CA:1
-Smoothing: 9
-Face 17: A:8 B:13 C:14 AB:1 BC:1 CA:0
-Smoothing: 9
-Face 18: A:9 B:10 C:5 AB:0 BC:1 CA:1
-Smoothing: 10
-Face 19: A:9 B:14 C:10 AB:1 BC:1 CA:0
-Smoothing: 10
-Face 20: A:10 B:16 C:11 AB:0 BC:1 CA:1
-Smoothing: 11
-Face 21: A:10 B:15 C:16 AB:1 BC:1 CA:0
-Smoothing: 11
-Face 22: A:11 B:17 C:12 AB:0 BC:1 CA:1
-Smoothing: 12
-Face 23: A:11 B:16 C:17 AB:1 BC:1 CA:0
-Smoothing: 12
-Face 24: A:12 B:18 C:13 AB:0 BC:1 CA:1
-Smoothing: 13
-Face 25: A:12 B:17 C:18 AB:1 BC:1 CA:0
-Smoothing: 13
-Face 26: A:13 B:19 C:14 AB:0 BC:1 CA:1
-Smoothing: 14
-Face 27: A:13 B:18 C:19 AB:1 BC:1 CA:0
-Smoothing: 14
-Face 28: A:14 B:15 C:10 AB:0 BC:1 CA:1
-Smoothing: 15
-Face 29: A:14 B:19 C:15 AB:1 BC:1 CA:0
-Smoothing: 15
-Face 30: A:15 B:21 C:16 AB:0 BC:1 CA:1
-Smoothing: 16
-Face 31: A:15 B:20 C:21 AB:1 BC:1 CA:0
-Smoothing: 16
-Face 32: A:16 B:22 C:17 AB:0 BC:1 CA:1
-Smoothing: 17
-Face 33: A:16 B:21 C:22 AB:1 BC:1 CA:0
-Smoothing: 17
-Face 34: A:17 B:23 C:18 AB:0 BC:1 CA:1
-Smoothing: 18
-Face 35: A:17 B:22 C:23 AB:1 BC:1 CA:0
-Smoothing: 18
-Face 36: A:18 B:24 C:19 AB:0 BC:1 CA:1
-Smoothing: 19
-Face 37: A:18 B:23 C:24 AB:1 BC:1 CA:0
-Smoothing: 19
-
- Page 2
-
-
-
-Face 38: A:19 B:20 C:15 AB:0 BC:1 CA:1
-Smoothing: 20
-Face 39: A:19 B:24 C:20 AB:1 BC:1 CA:0
-Smoothing: 20
-Face 40: A:20 B:26 C:21 AB:0 BC:1 CA:1
-Smoothing: 21
-Face 41: A:20 B:25 C:26 AB:1 BC:1 CA:0
-Smoothing: 21
-Face 42: A:21 B:27 C:22 AB:0 BC:1 CA:1
-Smoothing: 22
-Face 43: A:21 B:26 C:27 AB:1 BC:1 CA:0
-Smoothing: 22
-Face 44: A:22 B:28 C:23 AB:0 BC:1 CA:1
-Smoothing: 23
-Face 45: A:22 B:27 C:28 AB:1 BC:1 CA:0
-Smoothing: 23
-Face 46: A:23 B:29 C:24 AB:0 BC:1 CA:1
-Smoothing: 24
-Face 47: A:23 B:28 C:29 AB:1 BC:1 CA:0
-Smoothing: 24
-Face 48: A:24 B:25 C:20 AB:0 BC:1 CA:1
-Smoothing: 25
-Face 49: A:24 B:29 C:25 AB:1 BC:1 CA:0
-Smoothing: 25
-Face 50: A:25 B:31 C:26 AB:0 BC:1 CA:1
-Smoothing: 26
-Face 51: A:25 B:30 C:31 AB:1 BC:1 CA:0
-Smoothing: 26
-Face 52: A:26 B:32 C:27 AB:0 BC:1 CA:1
-Smoothing: 27
-Face 53: A:26 B:31 C:32 AB:1 BC:1 CA:0
-Smoothing: 27
-Face 54: A:27 B:33 C:28 AB:0 BC:1 CA:1
-Smoothing: 28
-Face 55: A:27 B:32 C:33 AB:1 BC:1 CA:0
-Smoothing: 28
-Face 56: A:28 B:34 C:29 AB:0 BC:1 CA:1
-Smoothing: 29
-Face 57: A:28 B:33 C:34 AB:1 BC:1 CA:0
-Smoothing: 29
-Face 58: A:29 B:30 C:25 AB:0 BC:1 CA:1
-Smoothing: 30
-Face 59: A:29 B:34 C:30 AB:1 BC:1 CA:0
-Smoothing: 30
-Face 60: A:30 B:36 C:31 AB:0 BC:1 CA:1
-Smoothing: 31
-Face 61: A:30 B:35 C:36 AB:1 BC:1 CA:0
-Smoothing: 31
-Face 62: A:31 B:37 C:32 AB:0 BC:1 CA:1
-Smoothing: 32
-Face 63: A:31 B:36 C:37 AB:1 BC:1 CA:0
-Smoothing: 32
-Face 64: A:32 B:38 C:33 AB:0 BC:1 CA:1
-Smoothing: 1
-Face 65: A:32 B:37 C:38 AB:1 BC:1 CA:0
-Smoothing: 1
-Face 66: A:33 B:39 C:34 AB:0 BC:1 CA:1
-Smoothing: 2
-Face 67: A:33 B:38 C:39 AB:1 BC:1 CA:0
-Smoothing: 2
-Face 68: A:34 B:35 C:30 AB:0 BC:1 CA:1
-
- Page 3
-
-
-
-Smoothing: 3
-Face 69: A:34 B:39 C:35 AB:1 BC:1 CA:0
-Smoothing: 3
-Face 70: A:35 B:1 C:36 AB:0 BC:1 CA:1
-Smoothing: 4
-Face 71: A:35 B:0 C:1 AB:1 BC:1 CA:0
-Smoothing: 4
-Face 72: A:36 B:2 C:37 AB:0 BC:1 CA:1
-Smoothing: 5
-Face 73: A:36 B:1 C:2 AB:1 BC:1 CA:0
-Smoothing: 5
-Face 74: A:37 B:3 C:38 AB:0 BC:1 CA:1
-Smoothing: 6
-Face 75: A:37 B:2 C:3 AB:1 BC:1 CA:0
-Smoothing: 6
-Face 76: A:38 B:4 C:39 AB:0 BC:1 CA:1
-Smoothing: 7
-Face 77: A:38 B:3 C:4 AB:1 BC:1 CA:0
-Smoothing: 7
-Face 78: A:39 B:0 C:35 AB:0 BC:1 CA:1
-Smoothing: 8
-Face 79: A:39 B:4 C:0 AB:1 BC:1 CA:0
-Smoothing: 8
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Page 4
-
-
-
+Ambient light color: Red=0.039216 Green=0.039216 Blue=0.039216
+
+Named object: "Object01"
+Tri-mesh, Vertices: 40 Faces: 80
+Vertex list:
+Vertex 0: X: -50.170624 Y: -0.000026 Z: -240.147842
+Vertex 1: X: -80.584503 Y: -63.958851 Z: -205.014572
+Vertex 2: X: -129.795166 Y: -39.528744 Z: -148.16774
+Vertex 3: X: -129.795166 Y: 39.528721 Z: -148.16774
+Vertex 4: X: -80.584503 Y: 63.958797 Z: -205.014572
+Vertex 5: X: 85.963654 Y: -0.000002 Z: 31.490465
+Vertex 6: X: 39.614838 Y: -63.958828 Z: 34.827602
+Vertex 7: X: -35.37915 Y: -39.528728 Z: 40.227196
+Vertex 8: X: -35.37912 Y: 39.528736 Z: 40.227188
+Vertex 9: X: 39.614838 Y: 63.95882 Z: 34.827595
+Vertex 10: X: -9.852051 Y: 0.000023 Z: 319.829254
+Vertex 11: X: -44.985352 Y: -63.958805 Z: 289.415405
+Vertex 12: X: -101.832199 Y: -39.528709 Z: 240.204758
+Vertex 13: X: -101.832184 Y: 39.528755 Z: 240.204773
+Vertex 14: X: -44.985352 Y: 63.958843 Z: 289.415405
+Vertex 15: X: -281.490326 Y: 0.000035 Z: 455.963654
+Vertex 16: X: -284.827484 Y: -63.958794 Z: 409.614868
+Vertex 17: X: -290.227112 Y: -39.528702 Z: 334.62085
+Vertex 18: X: -290.227112 Y: 39.528763 Z: 334.62088
+Vertex 19: X: -284.827484 Y: 63.958855 Z: 409.614838
+Vertex 20: X: -569.829163 Y: 0.000026 Z: 360.14798
+Vertex 21: X: -539.415344 Y: -63.958801 Z: 325.014709
+Vertex 22: X: -490.204712 Y: -39.528709 Z: 268.167847
+Vertex 23: X: -490.204712 Y: 39.528755 Z: 268.167847
+Vertex 24: X: -539.415344 Y: 63.958847 Z: 325.014679
+Vertex 25: X: -705.963684 Y: 0.000002 Z: 88.509598
+Vertex 26: X: -659.614807 Y: -63.958824 Z: 85.172462
+Vertex 27: X: -584.62085 Y: -39.528725 Z: 79.77285
+Vertex 28: X: -584.62085 Y: 39.52874 Z: 79.77285
+Vertex 29: X: -659.614868 Y: 63.958824 Z: 85.172447
+Vertex 30: X: -610.147827 Y: -0.000023 Z: -199.829361
+Vertex 31: X: -575.014587 Y: -63.958847 Z: -169.415497
+Vertex 32: X: -518.167725 Y: -39.528744 Z: -120.204819
+Vertex 33: X: -518.167725 Y: 39.528721 Z: -120.204834
+Vertex 34: X: -575.014587 Y: 63.958801 Z: -169.415497
+Vertex 35: X: -338.509338 Y: -0.000035 Z: -335.963745
+Vertex 36: X: -335.172241 Y: -63.958858 Z: -289.614868
+Vertex 37: X: -329.772675 Y: -39.528751 Z: -214.620865
+Vertex 38: X: -329.772675 Y: 39.528713 Z: -214.620865
+Vertex 39: X: -335.172241 Y: 63.95879 Z: -289.614899
+Face list:
+Face 0: A:0 B:6 C:1 AB:0 BC:1 CA:1
+Smoothing: 1
+Face 1: A:0 B:5 C:6 AB:1 BC:1 CA:0
+Smoothing: 1
+Face 2: A:1 B:7 C:2 AB:0 BC:1 CA:1
+Smoothing: 2
+Face 3: A:1 B:6 C:7 AB:1 BC:1 CA:0
+Smoothing: 2
+Face 4: A:2 B:8 C:3 AB:0 BC:1 CA:1
+Smoothing: 3
+Face 5: A:2 B:7 C:8 AB:1 BC:1 CA:0
+Smoothing: 3
+Face 6: A:3 B:9 C:4 AB:0 BC:1 CA:1
+Smoothing: 4
+Face 7: A:3 B:8 C:9 AB:1 BC:1 CA:0
+
+ Page 1
+
+
+
+Smoothing: 4
+Face 8: A:4 B:5 C:0 AB:0 BC:1 CA:1
+Smoothing: 5
+Face 9: A:4 B:9 C:5 AB:1 BC:1 CA:0
+Smoothing: 5
+Face 10: A:5 B:11 C:6 AB:0 BC:1 CA:1
+Smoothing: 6
+Face 11: A:5 B:10 C:11 AB:1 BC:1 CA:0
+Smoothing: 6
+Face 12: A:6 B:12 C:7 AB:0 BC:1 CA:1
+Smoothing: 7
+Face 13: A:6 B:11 C:12 AB:1 BC:1 CA:0
+Smoothing: 7
+Face 14: A:7 B:13 C:8 AB:0 BC:1 CA:1
+Smoothing: 8
+Face 15: A:7 B:12 C:13 AB:1 BC:1 CA:0
+Smoothing: 8
+Face 16: A:8 B:14 C:9 AB:0 BC:1 CA:1
+Smoothing: 9
+Face 17: A:8 B:13 C:14 AB:1 BC:1 CA:0
+Smoothing: 9
+Face 18: A:9 B:10 C:5 AB:0 BC:1 CA:1
+Smoothing: 10
+Face 19: A:9 B:14 C:10 AB:1 BC:1 CA:0
+Smoothing: 10
+Face 20: A:10 B:16 C:11 AB:0 BC:1 CA:1
+Smoothing: 11
+Face 21: A:10 B:15 C:16 AB:1 BC:1 CA:0
+Smoothing: 11
+Face 22: A:11 B:17 C:12 AB:0 BC:1 CA:1
+Smoothing: 12
+Face 23: A:11 B:16 C:17 AB:1 BC:1 CA:0
+Smoothing: 12
+Face 24: A:12 B:18 C:13 AB:0 BC:1 CA:1
+Smoothing: 13
+Face 25: A:12 B:17 C:18 AB:1 BC:1 CA:0
+Smoothing: 13
+Face 26: A:13 B:19 C:14 AB:0 BC:1 CA:1
+Smoothing: 14
+Face 27: A:13 B:18 C:19 AB:1 BC:1 CA:0
+Smoothing: 14
+Face 28: A:14 B:15 C:10 AB:0 BC:1 CA:1
+Smoothing: 15
+Face 29: A:14 B:19 C:15 AB:1 BC:1 CA:0
+Smoothing: 15
+Face 30: A:15 B:21 C:16 AB:0 BC:1 CA:1
+Smoothing: 16
+Face 31: A:15 B:20 C:21 AB:1 BC:1 CA:0
+Smoothing: 16
+Face 32: A:16 B:22 C:17 AB:0 BC:1 CA:1
+Smoothing: 17
+Face 33: A:16 B:21 C:22 AB:1 BC:1 CA:0
+Smoothing: 17
+Face 34: A:17 B:23 C:18 AB:0 BC:1 CA:1
+Smoothing: 18
+Face 35: A:17 B:22 C:23 AB:1 BC:1 CA:0
+Smoothing: 18
+Face 36: A:18 B:24 C:19 AB:0 BC:1 CA:1
+Smoothing: 19
+Face 37: A:18 B:23 C:24 AB:1 BC:1 CA:0
+Smoothing: 19
+
+ Page 2
+
+
+
+Face 38: A:19 B:20 C:15 AB:0 BC:1 CA:1
+Smoothing: 20
+Face 39: A:19 B:24 C:20 AB:1 BC:1 CA:0
+Smoothing: 20
+Face 40: A:20 B:26 C:21 AB:0 BC:1 CA:1
+Smoothing: 21
+Face 41: A:20 B:25 C:26 AB:1 BC:1 CA:0
+Smoothing: 21
+Face 42: A:21 B:27 C:22 AB:0 BC:1 CA:1
+Smoothing: 22
+Face 43: A:21 B:26 C:27 AB:1 BC:1 CA:0
+Smoothing: 22
+Face 44: A:22 B:28 C:23 AB:0 BC:1 CA:1
+Smoothing: 23
+Face 45: A:22 B:27 C:28 AB:1 BC:1 CA:0
+Smoothing: 23
+Face 46: A:23 B:29 C:24 AB:0 BC:1 CA:1
+Smoothing: 24
+Face 47: A:23 B:28 C:29 AB:1 BC:1 CA:0
+Smoothing: 24
+Face 48: A:24 B:25 C:20 AB:0 BC:1 CA:1
+Smoothing: 25
+Face 49: A:24 B:29 C:25 AB:1 BC:1 CA:0
+Smoothing: 25
+Face 50: A:25 B:31 C:26 AB:0 BC:1 CA:1
+Smoothing: 26
+Face 51: A:25 B:30 C:31 AB:1 BC:1 CA:0
+Smoothing: 26
+Face 52: A:26 B:32 C:27 AB:0 BC:1 CA:1
+Smoothing: 27
+Face 53: A:26 B:31 C:32 AB:1 BC:1 CA:0
+Smoothing: 27
+Face 54: A:27 B:33 C:28 AB:0 BC:1 CA:1
+Smoothing: 28
+Face 55: A:27 B:32 C:33 AB:1 BC:1 CA:0
+Smoothing: 28
+Face 56: A:28 B:34 C:29 AB:0 BC:1 CA:1
+Smoothing: 29
+Face 57: A:28 B:33 C:34 AB:1 BC:1 CA:0
+Smoothing: 29
+Face 58: A:29 B:30 C:25 AB:0 BC:1 CA:1
+Smoothing: 30
+Face 59: A:29 B:34 C:30 AB:1 BC:1 CA:0
+Smoothing: 30
+Face 60: A:30 B:36 C:31 AB:0 BC:1 CA:1
+Smoothing: 31
+Face 61: A:30 B:35 C:36 AB:1 BC:1 CA:0
+Smoothing: 31
+Face 62: A:31 B:37 C:32 AB:0 BC:1 CA:1
+Smoothing: 32
+Face 63: A:31 B:36 C:37 AB:1 BC:1 CA:0
+Smoothing: 32
+Face 64: A:32 B:38 C:33 AB:0 BC:1 CA:1
+Smoothing: 1
+Face 65: A:32 B:37 C:38 AB:1 BC:1 CA:0
+Smoothing: 1
+Face 66: A:33 B:39 C:34 AB:0 BC:1 CA:1
+Smoothing: 2
+Face 67: A:33 B:38 C:39 AB:1 BC:1 CA:0
+Smoothing: 2
+Face 68: A:34 B:35 C:30 AB:0 BC:1 CA:1
+
+ Page 3
+
+
+
+Smoothing: 3
+Face 69: A:34 B:39 C:35 AB:1 BC:1 CA:0
+Smoothing: 3
+Face 70: A:35 B:1 C:36 AB:0 BC:1 CA:1
+Smoothing: 4
+Face 71: A:35 B:0 C:1 AB:1 BC:1 CA:0
+Smoothing: 4
+Face 72: A:36 B:2 C:37 AB:0 BC:1 CA:1
+Smoothing: 5
+Face 73: A:36 B:1 C:2 AB:1 BC:1 CA:0
+Smoothing: 5
+Face 74: A:37 B:3 C:38 AB:0 BC:1 CA:1
+Smoothing: 6
+Face 75: A:37 B:2 C:3 AB:1 BC:1 CA:0
+Smoothing: 6
+Face 76: A:38 B:4 C:39 AB:0 BC:1 CA:1
+Smoothing: 7
+Face 77: A:38 B:3 C:4 AB:1 BC:1 CA:0
+Smoothing: 7
+Face 78: A:39 B:0 C:35 AB:0 BC:1 CA:1
+Smoothing: 8
+Face 79: A:39 B:4 C:0 AB:1 BC:1 CA:0
+Smoothing: 8
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Page 4
+
+
+
diff --git a/progs/glsl/.gitignore b/progs/glsl/.gitignore
index b63693bbb5a..1e0aecebef4 100644
--- a/progs/glsl/.gitignore
+++ b/progs/glsl/.gitignore
@@ -4,10 +4,14 @@ bump
deriv
extfuncs.h
mandelbrot
+multitex
noise
points
readtex.c
readtex.h
+shaderutil.c
+shaderutil.h
texdemo1
-trirast
toyball
+trirast
+twoside
diff --git a/progs/glsl/Makefile b/progs/glsl/Makefile
index 546cd233eb2..e3f205cdb92 100644
--- a/progs/glsl/Makefile
+++ b/progs/glsl/Makefile
@@ -10,13 +10,18 @@ LIB_DEP = $(TOP)/$(LIB_DIR)/$(GL_LIB_NAME) $(TOP)/$(LIB_DIR)/$(GLU_LIB_NAME) $(T
LIBS = -L$(TOP)/$(LIB_DIR) -l$(GLUT_LIB) -l$(GLU_LIB) -l$(GL_LIB) $(APP_LIB_DEPS)
PROGS = \
+ bitmap \
brick \
bump \
deriv \
mandelbrot \
+ multitex \
noise \
+ points \
+ texdemo1 \
toyball \
- texdemo1
+ twoside \
+ trirast
##### RULES #####
@@ -41,6 +46,7 @@ default: $(PROGS)
extfuncs.h: $(TOP)/progs/util/extfuncs.h
cp $< .
+
readtex.c: $(TOP)/progs/util/readtex.c
cp $< .
@@ -50,22 +56,107 @@ 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 $@
+
+
+deriv.o: deriv.c extfuncs.h shaderutil.h
+ $(CC) -c -I$(INCDIR) $(CFLAGS) deriv.c
+
+deriv: deriv.o shaderutil.o
+ $(CC) -I$(INCDIR) $(CFLAGS) $(LDFLAGS) deriv.o shaderutil.o $(LIBS) -o $@
+
+
+mandelbrot.o: mandelbrot.c extfuncs.h shaderutil.h
+ $(CC) -c -I$(INCDIR) $(CFLAGS) mandelbrot.c
+
+mandelbrot: mandelbrot.o shaderutil.o
+ $(CC) -I$(INCDIR) $(CFLAGS) $(LDFLAGS) mandelbrot.o shaderutil.o $(LIBS) -o $@
-mandelbrot.c: extfuncs.h
-toyball.c: extfuncs.h
+multitex.o: multitex.c extfuncs.h readtex.h shaderutil.h
+ $(CC) -c -I$(INCDIR) $(CFLAGS) multitex.c
-texdemo1: texdemo1.o readtex.o
- $(CC) -I$(INCDIR) $(CFLAGS) $(LDFLAGS) texdemo1.o readtex.o $(LIBS) -o $@
+multitex: multitex.o readtex.o shaderutil.o
+ $(CC) -I$(INCDIR) $(CFLAGS) $(LDFLAGS) multitex.o readtex.o shaderutil.o $(LIBS) -o $@
-texdemo1.o: texdemo1.c readtex.h extfuncs.h
+
+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 $@
+
+
+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 $@
+
+
+
+
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 00000000000..d488ec6cb9f
--- /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 522698b5d43..4be266622b5 100644
--- a/progs/glsl/brick.c
+++ b/progs/glsl/brick.c
@@ -13,6 +13,7 @@
#include <GL/glut.h>
#include <GL/glext.h>
#include "extfuncs.h"
+#include "shaderutil.h"
static char *FragProgFile = "CH06-brick.frag.txt";
@@ -23,23 +24,15 @@ 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 11f87ab1274..e42421d489a 100644
--- a/progs/glsl/bump.c
+++ b/progs/glsl/bump.c
@@ -13,6 +13,7 @@
#include <GL/glu.h>
#include <GL/glext.h>
#include "extfuncs.h"
+#include "shaderutil.h"
static char *FragProgFile = "CH11-bumpmap.frag.txt";
@@ -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, "bump: 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, "bump: Unable to open shader file %s\n", filename);
- exit(1);
- }
-
- n = fread(buffer, 1, max, f);
- printf("bump: 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/deriv.c b/progs/glsl/deriv.c
index 8b652bc1e46..e69f0b82c45 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 e7b2b04b0df..fa67a3c2cae 100644
--- a/progs/glsl/mandelbrot.c
+++ b/progs/glsl/mandelbrot.c
@@ -13,6 +13,7 @@
#include <GL/glut.h>
#include <GL/glext.h>
#include "extfuncs.h"
+#include "shaderutil.h"
static char *FragProgFile = "CH18-mandel.frag.txt";
@@ -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, "mandelbrot: 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, "mandelbrot: Unable to open shader file %s\n", filename);
- exit(1);
- }
-
- n = fread(buffer, 1, max, f);
- printf("mandelbrot: 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 00000000000..5574ed4139f
--- /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.txt";
+static const char *FragFile = "multitex.frag.txt";
+
+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.txt b/progs/glsl/multitex.frag.txt
new file mode 100644
index 00000000000..86045306af2
--- /dev/null
+++ b/progs/glsl/multitex.frag.txt
@@ -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, 0.0);
+ vec4 t2 = texture2D(tex2, gl_TexCoord[1].xy, 0.0);
+ gl_FragColor = mix(t1, t2, t2.w);
+}
diff --git a/progs/glsl/multitex.vert.txt b/progs/glsl/multitex.vert.txt
new file mode 100644
index 00000000000..5518ca1ddd8
--- /dev/null
+++ b/progs/glsl/multitex.vert.txt
@@ -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 adccd1a7c8f..9da71ac775e 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, "noise: 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/points.c b/progs/glsl/points.c
new file mode 100644
index 00000000000..392dc4db853
--- /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/texdemo1.c b/progs/glsl/texdemo1.c
index d29ecf452b1..3dd19eaf4bf 100644
--- a/progs/glsl/texdemo1.c
+++ b/progs/glsl/texdemo1.c
@@ -31,6 +31,7 @@
#include "GL/glut.h"
#include "readtex.h"
#include "extfuncs.h"
+#include "shaderutil.h"
static const char *Demo = "texdemo1";
@@ -50,39 +51,20 @@ static GLfloat EyeDist = 10;
static GLboolean Anim = GL_TRUE;
-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();
@@ -386,132 +368,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 3aa096161ae..b870435f662 100644
--- a/progs/glsl/toyball.c
+++ b/progs/glsl/toyball.c
@@ -13,6 +13,7 @@
#include <GL/glut.h>
#include <GL/glext.h>
#include "extfuncs.h"
+#include "shaderutil.h"
static char *FragProgFile = "CH11-toyball.frag.txt";
@@ -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, "toyball: 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, "toyball: Unable to open shader file %s\n", filename);
- exit(1);
- }
-
- n = fread(buffer, 1, max, f);
- printf("toyball: 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 00000000000..67cbac0546c
--- /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 = 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);
+
+ 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 00000000000..77977be536f
--- /dev/null
+++ b/progs/glsl/twoside.c
@@ -0,0 +1,270 @@
+/**
+ * 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 Yrot = 0.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)
+{
+ float xmin = -1, xmax = 1, ymin = -1, ymax = 1;
+
+ 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);
+
+ glPushMatrix();
+ glRotatef(Yrot, 0, 1, 0);
+
+ glBegin(GL_POLYGON);
+ glColor4fv(Red);
+ glSecondaryColor3fv_func(Green);
+ glVertex2f(xmin, ymin);
+ glVertex2f(xmax, ymin);
+ glVertex2f(xmax, ymax);
+ glVertex2f(xmin, ymax);
+ 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;
+
+ Yrot += 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, 5, 15);
+ 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':
+ Yrot = 0;
+ anim = 0;
+ glutIdleFunc(NULL);
+ break;
+ case 's':
+ Yrot += 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 (!fragface || gl_FrontFacing) { \n"
+ " gl_FragColor = gl_Color; \n"
+ " } \n"
+ " else { \n"
+ " gl_FragColor = 0.8 * gl_SecondaryColor; \n"
+ " } \n"
+ "} \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));
+}
+
+
+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");
+}
+
+
+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);
+ if (anim)
+ glutIdleFunc(Idle);
+ ParseOptions(argc, argv);
+ Init();
+ Usage();
+ glutMainLoop();
+ return 0;
+}
diff --git a/progs/osdemos/Makefile b/progs/osdemos/Makefile
index 148d603b353..023ea02ae27 100644
--- a/progs/osdemos/Makefile
+++ b/progs/osdemos/Makefile
@@ -5,15 +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)
+LIBS = -L$(TOP)/$(LIB_DIR) -l$(GLUT_LIB) -l$(GLU_LIB) -l$(GL_LIB) \
+ $(APP_LIB_DEPS)
PROGS = \
osdemo \
diff --git a/progs/osdemos/ostest1.c b/progs/osdemos/ostest1.c
index 2c7adfc3537..000b8c4a781 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/osdemos/readtex.c b/progs/osdemos/readtex.c
deleted file mode 100644
index 37d5fcd0d3a..00000000000
--- a/progs/osdemos/readtex.c
+++ /dev/null
@@ -1,454 +0,0 @@
-/* readtex.c */
-
-/*
- * Read an SGI .rgb image file and generate a mipmap texture set.
- * Much of this code was borrowed from SGI's tk OpenGL toolkit.
- */
-
-
-
-#include <GL/gl.h>
-#include <GL/glu.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include "readtex.h"
-
-
-#ifndef SEEK_SET
-# define SEEK_SET 0
-#endif
-
-
-/*
-** RGB Image Structure
-*/
-
-typedef struct _TK_RGBImageRec {
- GLint sizeX, sizeY;
- GLint components;
- unsigned char *data;
-} TK_RGBImageRec;
-
-
-
-/******************************************************************************/
-
-typedef struct _rawImageRec {
- unsigned short imagic;
- unsigned short type;
- unsigned short dim;
- unsigned short sizeX, sizeY, sizeZ;
- unsigned long min, max;
- unsigned long wasteBytes;
- char name[80];
- unsigned long colorMap;
- FILE *file;
- unsigned char *tmp, *tmpR, *tmpG, *tmpB, *tmpA;
- unsigned long rleEnd;
- GLuint *rowStart;
- GLint *rowSize;
-} rawImageRec;
-
-/******************************************************************************/
-
-static void ConvertShort(unsigned short *array, long length)
-{
- unsigned long b1, b2;
- unsigned char *ptr;
-
- ptr = (unsigned char *)array;
- while (length--) {
- b1 = *ptr++;
- b2 = *ptr++;
- *array++ = (unsigned short) ((b1 << 8) | (b2));
- }
-}
-
-static void ConvertLong(GLuint *array, long length)
-{
- unsigned long b1, b2, b3, b4;
- unsigned char *ptr;
-
- ptr = (unsigned char *)array;
- while (length--) {
- b1 = *ptr++;
- b2 = *ptr++;
- b3 = *ptr++;
- b4 = *ptr++;
- *array++ = (b1 << 24) | (b2 << 16) | (b3 << 8) | (b4);
- }
-}
-
-static rawImageRec *RawImageOpen(const char *fileName)
-{
- union {
- int testWord;
- char testByte[4];
- } endianTest;
- rawImageRec *raw;
- GLenum swapFlag;
- int x;
-
- endianTest.testWord = 1;
- if (endianTest.testByte[0] == 1) {
- swapFlag = GL_TRUE;
- } else {
- swapFlag = GL_FALSE;
- }
-
- raw = (rawImageRec *)calloc(1, sizeof(rawImageRec));
- if (raw == NULL) {
- fprintf(stderr, "Out of memory!\n");
- return NULL;
- }
- if ((raw->file = fopen(fileName, "rb")) == NULL) {
- perror(fileName);
- return NULL;
- }
-
- fread(raw, 1, 12, raw->file);
-
- if (swapFlag) {
- ConvertShort(&raw->imagic, 6);
- }
-
- raw->tmp = (unsigned char *)malloc(raw->sizeX*256);
- raw->tmpR = (unsigned char *)malloc(raw->sizeX*256);
- raw->tmpG = (unsigned char *)malloc(raw->sizeX*256);
- raw->tmpB = (unsigned char *)malloc(raw->sizeX*256);
- if (raw->sizeZ==4) {
- raw->tmpA = (unsigned char *)malloc(raw->sizeX*256);
- }
- if (raw->tmp == NULL || raw->tmpR == NULL || raw->tmpG == NULL ||
- raw->tmpB == NULL) {
- fprintf(stderr, "Out of memory!\n");
- return NULL;
- }
-
- if ((raw->type & 0xFF00) == 0x0100) {
- x = raw->sizeY * raw->sizeZ * sizeof(GLuint);
- raw->rowStart = (GLuint *)malloc(x);
- raw->rowSize = (GLint *)malloc(x);
- if (raw->rowStart == NULL || raw->rowSize == NULL) {
- fprintf(stderr, "Out of memory!\n");
- return NULL;
- }
- raw->rleEnd = 512 + (2 * x);
- fseek(raw->file, 512, SEEK_SET);
- fread(raw->rowStart, 1, x, raw->file);
- fread(raw->rowSize, 1, x, raw->file);
- if (swapFlag) {
- ConvertLong(raw->rowStart, (long) (x/sizeof(GLuint)));
- ConvertLong((GLuint *)raw->rowSize, (long) (x/sizeof(GLint)));
- }
- }
- return raw;
-}
-
-static void RawImageClose(rawImageRec *raw)
-{
- fclose(raw->file);
- free(raw->tmp);
- free(raw->tmpR);
- free(raw->tmpG);
- free(raw->tmpB);
- if (raw->rowStart)
- free(raw->rowStart);
- if (raw->rowSize)
- free(raw->rowSize);
- if (raw->sizeZ>3) {
- free(raw->tmpA);
- }
- free(raw);
-}
-
-static void RawImageGetRow(rawImageRec *raw, unsigned char *buf, int y, int z)
-{
- unsigned char *iPtr, *oPtr, pixel;
- int count, done = 0;
-
- if ((raw->type & 0xFF00) == 0x0100) {
- fseek(raw->file, (long) raw->rowStart[y+z*raw->sizeY], SEEK_SET);
- fread(raw->tmp, 1, (unsigned int)raw->rowSize[y+z*raw->sizeY],
- raw->file);
-
- iPtr = raw->tmp;
- oPtr = buf;
- while (!done) {
- pixel = *iPtr++;
- count = (int)(pixel & 0x7F);
- if (!count) {
- done = 1;
- return;
- }
- if (pixel & 0x80) {
- while (count--) {
- *oPtr++ = *iPtr++;
- }
- } else {
- pixel = *iPtr++;
- while (count--) {
- *oPtr++ = pixel;
- }
- }
- }
- } else {
- fseek(raw->file, 512+(y*raw->sizeX)+(z*raw->sizeX*raw->sizeY),
- SEEK_SET);
- fread(buf, 1, raw->sizeX, raw->file);
- }
-}
-
-
-static void RawImageGetData(rawImageRec *raw, TK_RGBImageRec *final)
-{
- unsigned char *ptr;
- int i, j;
-
- final->data = (unsigned char *)malloc((raw->sizeX+1)*(raw->sizeY+1)*4);
- if (final->data == NULL) {
- fprintf(stderr, "Out of memory!\n");
- }
-
- ptr = final->data;
- for (i = 0; i < (int)(raw->sizeY); i++) {
- RawImageGetRow(raw, raw->tmpR, i, 0);
- RawImageGetRow(raw, raw->tmpG, i, 1);
- RawImageGetRow(raw, raw->tmpB, i, 2);
- if (raw->sizeZ>3) {
- RawImageGetRow(raw, raw->tmpA, i, 3);
- }
- for (j = 0; j < (int)(raw->sizeX); j++) {
- *ptr++ = *(raw->tmpR + j);
- *ptr++ = *(raw->tmpG + j);
- *ptr++ = *(raw->tmpB + j);
- if (raw->sizeZ>3) {
- *ptr++ = *(raw->tmpA + j);
- }
- }
- }
-}
-
-
-static TK_RGBImageRec *tkRGBImageLoad(const char *fileName)
-{
- rawImageRec *raw;
- TK_RGBImageRec *final;
-
- raw = RawImageOpen(fileName);
- if (!raw) {
- fprintf(stderr, "File not found\n");
- return NULL;
- }
- final = (TK_RGBImageRec *)malloc(sizeof(TK_RGBImageRec));
- if (final == NULL) {
- fprintf(stderr, "Out of memory!\n");
- return NULL;
- }
- final->sizeX = raw->sizeX;
- final->sizeY = raw->sizeY;
- final->components = raw->sizeZ;
- RawImageGetData(raw, final);
- RawImageClose(raw);
- return final;
-}
-
-
-static void FreeImage( TK_RGBImageRec *image )
-{
- free(image->data);
- free(image);
-}
-
-
-/*
- * Load an SGI .rgb file and generate a set of 2-D mipmaps from it.
- * Input: imageFile - name of .rgb to read
- * intFormat - internal texture format to use, or number of components
- * Return: GL_TRUE if success, GL_FALSE if error.
- */
-GLboolean LoadRGBMipmaps( const char *imageFile, GLint intFormat )
-{
- GLint w, h;
- return LoadRGBMipmaps2( imageFile, GL_TEXTURE_2D, intFormat, &w, &h );
-}
-
-
-
-GLboolean LoadRGBMipmaps2( const char *imageFile, GLenum target,
- GLint intFormat, GLint *width, GLint *height )
-{
- GLint error;
- GLenum format;
- TK_RGBImageRec *image;
-
- image = tkRGBImageLoad( imageFile );
- if (!image) {
- return GL_FALSE;
- }
-
- if (image->components==3) {
- format = GL_RGB;
- }
- else if (image->components==4) {
- format = GL_RGBA;
- }
- else {
- /* not implemented */
- fprintf(stderr,
- "Error in LoadRGBMipmaps %d-component images not implemented\n",
- image->components );
- return GL_FALSE;
- }
-
- error = gluBuild2DMipmaps( target,
- intFormat,
- image->sizeX, image->sizeY,
- format,
- GL_UNSIGNED_BYTE,
- image->data );
-
- *width = image->sizeX;
- *height = image->sizeY;
-
- FreeImage(image);
-
- return error ? GL_FALSE : GL_TRUE;
-}
-
-
-
-/*
- * Load an SGI .rgb file and return a pointer to the image data.
- * Input: imageFile - name of .rgb to read
- * Output: width - width of image
- * height - height of image
- * format - format of image (GL_RGB or GL_RGBA)
- * Return: pointer to image data or NULL if error
- */
-GLubyte *LoadRGBImage( const char *imageFile, GLint *width, GLint *height,
- GLenum *format )
-{
- TK_RGBImageRec *image;
- GLint bytes;
- GLubyte *buffer;
-
- image = tkRGBImageLoad( imageFile );
- if (!image) {
- return NULL;
- }
-
- if (image->components==3) {
- *format = GL_RGB;
- }
- else if (image->components==4) {
- *format = GL_RGBA;
- }
- else {
- /* not implemented */
- fprintf(stderr,
- "Error in LoadRGBImage %d-component images not implemented\n",
- image->components );
- return NULL;
- }
-
- *width = image->sizeX;
- *height = image->sizeY;
-
- bytes = image->sizeX * image->sizeY * image->components;
- buffer = (GLubyte *) malloc(bytes);
- if (!buffer)
- return NULL;
-
- memcpy( (void *) buffer, (void *) image->data, bytes );
-
- FreeImage(image);
-
- return buffer;
-}
-
-#define CLAMP( X, MIN, MAX ) ( (X)<(MIN) ? (MIN) : ((X)>(MAX) ? (MAX) : (X)) )
-
-
-static void ConvertRGBtoYUV(GLint w, GLint h, GLint texel_bytes,
- const GLubyte *src,
- GLushort *dest)
-{
- GLint i, j;
-
- for (i = 0; i < h; i++) {
- for (j = 0; j < w; j++) {
- const GLfloat r = (src[0]) / 255.0;
- const GLfloat g = (src[1]) / 255.0;
- const GLfloat b = (src[2]) / 255.0;
- GLfloat y, cr, cb;
- GLint iy, icr, icb;
-
- y = r * 65.481 + g * 128.553 + b * 24.966 + 16;
- cb = r * -37.797 + g * -74.203 + b * 112.0 + 128;
- cr = r * 112.0 + g * -93.786 + b * -18.214 + 128;
- /*printf("%f %f %f -> %f %f %f\n", r, g, b, y, cb, cr);*/
- iy = (GLint) CLAMP(y, 0, 254);
- icb = (GLint) CLAMP(cb, 0, 254);
- icr = (GLint) CLAMP(cr, 0, 254);
-
- if (j & 1) {
- /* odd */
- *dest = (iy << 8) | icr;
- }
- else {
- /* even */
- *dest = (iy << 8) | icb;
- }
- dest++;
- src += texel_bytes;
- }
- }
-}
-
-
-/*
- * Load an SGI .rgb file and return a pointer to the image data, converted
- * to 422 yuv.
- *
- * Input: imageFile - name of .rgb to read
- * Output: width - width of image
- * height - height of image
- * Return: pointer to image data or NULL if error
- */
-GLushort *LoadYUVImage( const char *imageFile, GLint *width, GLint *height )
-{
- TK_RGBImageRec *image;
- GLushort *buffer;
-
- image = tkRGBImageLoad( imageFile );
- if (!image) {
- return NULL;
- }
-
- if (image->components != 3 && image->components !=4 ) {
- /* not implemented */
- fprintf(stderr,
- "Error in LoadYUVImage %d-component images not implemented\n",
- image->components );
- return NULL;
- }
-
- *width = image->sizeX;
- *height = image->sizeY;
-
- buffer = (GLushort *) malloc( image->sizeX * image->sizeY * 2 );
-
- if (buffer)
- ConvertRGBtoYUV( image->sizeX,
- image->sizeY,
- image->components,
- image->data,
- buffer );
-
-
- FreeImage(image);
- return buffer;
-}
-
diff --git a/progs/samples/.gitignore b/progs/samples/.gitignore
new file mode 100644
index 00000000000..f60d6e94eac
--- /dev/null
+++ b/progs/samples/.gitignore
@@ -0,0 +1,47 @@
+.cvsignore
+accum
+anywin
+bdemo
+binfo
+bitmap1
+bitmap2
+blendeq
+blendxor
+bugger
+copy
+cursor
+demo
+depth
+eval
+ffset
+fog
+font
+font
+incopy
+line
+logo
+lthreads
+lxdemo
+lxgears
+lxheads
+lxinfo
+lxpixmap
+nurb
+oglinfo
+olympic
+overlay
+pend
+point
+prim
+quad
+readtex.c
+readtex.h
+select
+shape
+sphere
+star
+stencil
+stretch
+texture
+tri
+wave
diff --git a/progs/samples/blendeq.c b/progs/samples/blendeq.c
index f78afd30381..d5143ecdf5c 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/samples/readtex.c b/progs/samples/readtex.c
deleted file mode 100644
index 37d5fcd0d3a..00000000000
--- a/progs/samples/readtex.c
+++ /dev/null
@@ -1,454 +0,0 @@
-/* readtex.c */
-
-/*
- * Read an SGI .rgb image file and generate a mipmap texture set.
- * Much of this code was borrowed from SGI's tk OpenGL toolkit.
- */
-
-
-
-#include <GL/gl.h>
-#include <GL/glu.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include "readtex.h"
-
-
-#ifndef SEEK_SET
-# define SEEK_SET 0
-#endif
-
-
-/*
-** RGB Image Structure
-*/
-
-typedef struct _TK_RGBImageRec {
- GLint sizeX, sizeY;
- GLint components;
- unsigned char *data;
-} TK_RGBImageRec;
-
-
-
-/******************************************************************************/
-
-typedef struct _rawImageRec {
- unsigned short imagic;
- unsigned short type;
- unsigned short dim;
- unsigned short sizeX, sizeY, sizeZ;
- unsigned long min, max;
- unsigned long wasteBytes;
- char name[80];
- unsigned long colorMap;
- FILE *file;
- unsigned char *tmp, *tmpR, *tmpG, *tmpB, *tmpA;
- unsigned long rleEnd;
- GLuint *rowStart;
- GLint *rowSize;
-} rawImageRec;
-
-/******************************************************************************/
-
-static void ConvertShort(unsigned short *array, long length)
-{
- unsigned long b1, b2;
- unsigned char *ptr;
-
- ptr = (unsigned char *)array;
- while (length--) {
- b1 = *ptr++;
- b2 = *ptr++;
- *array++ = (unsigned short) ((b1 << 8) | (b2));
- }
-}
-
-static void ConvertLong(GLuint *array, long length)
-{
- unsigned long b1, b2, b3, b4;
- unsigned char *ptr;
-
- ptr = (unsigned char *)array;
- while (length--) {
- b1 = *ptr++;
- b2 = *ptr++;
- b3 = *ptr++;
- b4 = *ptr++;
- *array++ = (b1 << 24) | (b2 << 16) | (b3 << 8) | (b4);
- }
-}
-
-static rawImageRec *RawImageOpen(const char *fileName)
-{
- union {
- int testWord;
- char testByte[4];
- } endianTest;
- rawImageRec *raw;
- GLenum swapFlag;
- int x;
-
- endianTest.testWord = 1;
- if (endianTest.testByte[0] == 1) {
- swapFlag = GL_TRUE;
- } else {
- swapFlag = GL_FALSE;
- }
-
- raw = (rawImageRec *)calloc(1, sizeof(rawImageRec));
- if (raw == NULL) {
- fprintf(stderr, "Out of memory!\n");
- return NULL;
- }
- if ((raw->file = fopen(fileName, "rb")) == NULL) {
- perror(fileName);
- return NULL;
- }
-
- fread(raw, 1, 12, raw->file);
-
- if (swapFlag) {
- ConvertShort(&raw->imagic, 6);
- }
-
- raw->tmp = (unsigned char *)malloc(raw->sizeX*256);
- raw->tmpR = (unsigned char *)malloc(raw->sizeX*256);
- raw->tmpG = (unsigned char *)malloc(raw->sizeX*256);
- raw->tmpB = (unsigned char *)malloc(raw->sizeX*256);
- if (raw->sizeZ==4) {
- raw->tmpA = (unsigned char *)malloc(raw->sizeX*256);
- }
- if (raw->tmp == NULL || raw->tmpR == NULL || raw->tmpG == NULL ||
- raw->tmpB == NULL) {
- fprintf(stderr, "Out of memory!\n");
- return NULL;
- }
-
- if ((raw->type & 0xFF00) == 0x0100) {
- x = raw->sizeY * raw->sizeZ * sizeof(GLuint);
- raw->rowStart = (GLuint *)malloc(x);
- raw->rowSize = (GLint *)malloc(x);
- if (raw->rowStart == NULL || raw->rowSize == NULL) {
- fprintf(stderr, "Out of memory!\n");
- return NULL;
- }
- raw->rleEnd = 512 + (2 * x);
- fseek(raw->file, 512, SEEK_SET);
- fread(raw->rowStart, 1, x, raw->file);
- fread(raw->rowSize, 1, x, raw->file);
- if (swapFlag) {
- ConvertLong(raw->rowStart, (long) (x/sizeof(GLuint)));
- ConvertLong((GLuint *)raw->rowSize, (long) (x/sizeof(GLint)));
- }
- }
- return raw;
-}
-
-static void RawImageClose(rawImageRec *raw)
-{
- fclose(raw->file);
- free(raw->tmp);
- free(raw->tmpR);
- free(raw->tmpG);
- free(raw->tmpB);
- if (raw->rowStart)
- free(raw->rowStart);
- if (raw->rowSize)
- free(raw->rowSize);
- if (raw->sizeZ>3) {
- free(raw->tmpA);
- }
- free(raw);
-}
-
-static void RawImageGetRow(rawImageRec *raw, unsigned char *buf, int y, int z)
-{
- unsigned char *iPtr, *oPtr, pixel;
- int count, done = 0;
-
- if ((raw->type & 0xFF00) == 0x0100) {
- fseek(raw->file, (long) raw->rowStart[y+z*raw->sizeY], SEEK_SET);
- fread(raw->tmp, 1, (unsigned int)raw->rowSize[y+z*raw->sizeY],
- raw->file);
-
- iPtr = raw->tmp;
- oPtr = buf;
- while (!done) {
- pixel = *iPtr++;
- count = (int)(pixel & 0x7F);
- if (!count) {
- done = 1;
- return;
- }
- if (pixel & 0x80) {
- while (count--) {
- *oPtr++ = *iPtr++;
- }
- } else {
- pixel = *iPtr++;
- while (count--) {
- *oPtr++ = pixel;
- }
- }
- }
- } else {
- fseek(raw->file, 512+(y*raw->sizeX)+(z*raw->sizeX*raw->sizeY),
- SEEK_SET);
- fread(buf, 1, raw->sizeX, raw->file);
- }
-}
-
-
-static void RawImageGetData(rawImageRec *raw, TK_RGBImageRec *final)
-{
- unsigned char *ptr;
- int i, j;
-
- final->data = (unsigned char *)malloc((raw->sizeX+1)*(raw->sizeY+1)*4);
- if (final->data == NULL) {
- fprintf(stderr, "Out of memory!\n");
- }
-
- ptr = final->data;
- for (i = 0; i < (int)(raw->sizeY); i++) {
- RawImageGetRow(raw, raw->tmpR, i, 0);
- RawImageGetRow(raw, raw->tmpG, i, 1);
- RawImageGetRow(raw, raw->tmpB, i, 2);
- if (raw->sizeZ>3) {
- RawImageGetRow(raw, raw->tmpA, i, 3);
- }
- for (j = 0; j < (int)(raw->sizeX); j++) {
- *ptr++ = *(raw->tmpR + j);
- *ptr++ = *(raw->tmpG + j);
- *ptr++ = *(raw->tmpB + j);
- if (raw->sizeZ>3) {
- *ptr++ = *(raw->tmpA + j);
- }
- }
- }
-}
-
-
-static TK_RGBImageRec *tkRGBImageLoad(const char *fileName)
-{
- rawImageRec *raw;
- TK_RGBImageRec *final;
-
- raw = RawImageOpen(fileName);
- if (!raw) {
- fprintf(stderr, "File not found\n");
- return NULL;
- }
- final = (TK_RGBImageRec *)malloc(sizeof(TK_RGBImageRec));
- if (final == NULL) {
- fprintf(stderr, "Out of memory!\n");
- return NULL;
- }
- final->sizeX = raw->sizeX;
- final->sizeY = raw->sizeY;
- final->components = raw->sizeZ;
- RawImageGetData(raw, final);
- RawImageClose(raw);
- return final;
-}
-
-
-static void FreeImage( TK_RGBImageRec *image )
-{
- free(image->data);
- free(image);
-}
-
-
-/*
- * Load an SGI .rgb file and generate a set of 2-D mipmaps from it.
- * Input: imageFile - name of .rgb to read
- * intFormat - internal texture format to use, or number of components
- * Return: GL_TRUE if success, GL_FALSE if error.
- */
-GLboolean LoadRGBMipmaps( const char *imageFile, GLint intFormat )
-{
- GLint w, h;
- return LoadRGBMipmaps2( imageFile, GL_TEXTURE_2D, intFormat, &w, &h );
-}
-
-
-
-GLboolean LoadRGBMipmaps2( const char *imageFile, GLenum target,
- GLint intFormat, GLint *width, GLint *height )
-{
- GLint error;
- GLenum format;
- TK_RGBImageRec *image;
-
- image = tkRGBImageLoad( imageFile );
- if (!image) {
- return GL_FALSE;
- }
-
- if (image->components==3) {
- format = GL_RGB;
- }
- else if (image->components==4) {
- format = GL_RGBA;
- }
- else {
- /* not implemented */
- fprintf(stderr,
- "Error in LoadRGBMipmaps %d-component images not implemented\n",
- image->components );
- return GL_FALSE;
- }
-
- error = gluBuild2DMipmaps( target,
- intFormat,
- image->sizeX, image->sizeY,
- format,
- GL_UNSIGNED_BYTE,
- image->data );
-
- *width = image->sizeX;
- *height = image->sizeY;
-
- FreeImage(image);
-
- return error ? GL_FALSE : GL_TRUE;
-}
-
-
-
-/*
- * Load an SGI .rgb file and return a pointer to the image data.
- * Input: imageFile - name of .rgb to read
- * Output: width - width of image
- * height - height of image
- * format - format of image (GL_RGB or GL_RGBA)
- * Return: pointer to image data or NULL if error
- */
-GLubyte *LoadRGBImage( const char *imageFile, GLint *width, GLint *height,
- GLenum *format )
-{
- TK_RGBImageRec *image;
- GLint bytes;
- GLubyte *buffer;
-
- image = tkRGBImageLoad( imageFile );
- if (!image) {
- return NULL;
- }
-
- if (image->components==3) {
- *format = GL_RGB;
- }
- else if (image->components==4) {
- *format = GL_RGBA;
- }
- else {
- /* not implemented */
- fprintf(stderr,
- "Error in LoadRGBImage %d-component images not implemented\n",
- image->components );
- return NULL;
- }
-
- *width = image->sizeX;
- *height = image->sizeY;
-
- bytes = image->sizeX * image->sizeY * image->components;
- buffer = (GLubyte *) malloc(bytes);
- if (!buffer)
- return NULL;
-
- memcpy( (void *) buffer, (void *) image->data, bytes );
-
- FreeImage(image);
-
- return buffer;
-}
-
-#define CLAMP( X, MIN, MAX ) ( (X)<(MIN) ? (MIN) : ((X)>(MAX) ? (MAX) : (X)) )
-
-
-static void ConvertRGBtoYUV(GLint w, GLint h, GLint texel_bytes,
- const GLubyte *src,
- GLushort *dest)
-{
- GLint i, j;
-
- for (i = 0; i < h; i++) {
- for (j = 0; j < w; j++) {
- const GLfloat r = (src[0]) / 255.0;
- const GLfloat g = (src[1]) / 255.0;
- const GLfloat b = (src[2]) / 255.0;
- GLfloat y, cr, cb;
- GLint iy, icr, icb;
-
- y = r * 65.481 + g * 128.553 + b * 24.966 + 16;
- cb = r * -37.797 + g * -74.203 + b * 112.0 + 128;
- cr = r * 112.0 + g * -93.786 + b * -18.214 + 128;
- /*printf("%f %f %f -> %f %f %f\n", r, g, b, y, cb, cr);*/
- iy = (GLint) CLAMP(y, 0, 254);
- icb = (GLint) CLAMP(cb, 0, 254);
- icr = (GLint) CLAMP(cr, 0, 254);
-
- if (j & 1) {
- /* odd */
- *dest = (iy << 8) | icr;
- }
- else {
- /* even */
- *dest = (iy << 8) | icb;
- }
- dest++;
- src += texel_bytes;
- }
- }
-}
-
-
-/*
- * Load an SGI .rgb file and return a pointer to the image data, converted
- * to 422 yuv.
- *
- * Input: imageFile - name of .rgb to read
- * Output: width - width of image
- * height - height of image
- * Return: pointer to image data or NULL if error
- */
-GLushort *LoadYUVImage( const char *imageFile, GLint *width, GLint *height )
-{
- TK_RGBImageRec *image;
- GLushort *buffer;
-
- image = tkRGBImageLoad( imageFile );
- if (!image) {
- return NULL;
- }
-
- if (image->components != 3 && image->components !=4 ) {
- /* not implemented */
- fprintf(stderr,
- "Error in LoadYUVImage %d-component images not implemented\n",
- image->components );
- return NULL;
- }
-
- *width = image->sizeX;
- *height = image->sizeY;
-
- buffer = (GLushort *) malloc( image->sizeX * image->sizeY * 2 );
-
- if (buffer)
- ConvertRGBtoYUV( image->sizeX,
- image->sizeY,
- image->components,
- image->data,
- buffer );
-
-
- FreeImage(image);
- return buffer;
-}
-
diff --git a/progs/slang/.gitignore b/progs/slang/.gitignore
deleted file mode 100644
index 8a42b018e65..00000000000
--- a/progs/slang/.gitignore
+++ /dev/null
@@ -1,3 +0,0 @@
-cltest
-sotest
-vstest
diff --git a/progs/tools/trace/.gitignore b/progs/tools/trace/.gitignore
deleted file mode 100644
index afe0c5829e4..00000000000
--- a/progs/tools/trace/.gitignore
+++ /dev/null
@@ -1 +0,0 @@
-gltrace.cc
diff --git a/progs/util/extfuncs.h b/progs/util/extfuncs.h
index 5d647cdae7f..cf6b29d0e32 100644
--- a/progs/util/extfuncs.h
+++ b/progs/util/extfuncs.h
@@ -12,6 +12,7 @@ static PFNGLCREATESHADERPROC glCreateShader_func = NULL;
static PFNGLDELETEPROGRAMPROC glDeleteProgram_func = NULL;
static PFNGLDELETESHADERPROC glDeleteShader_func = NULL;
static PFNGLGETACTIVEATTRIBPROC glGetActiveAttrib_func = NULL;
+static PFNGLGETACTIVEUNIFORMPROC glGetActiveUniform_func = NULL;
static PFNGLGETATTACHEDSHADERSPROC glGetAttachedShaders_func = NULL;
static PFNGLGETATTRIBLOCATIONPROC glGetAttribLocation_func = NULL;
static PFNGLGETPROGRAMINFOLOGPROC glGetProgramInfoLog_func = NULL;
@@ -26,6 +27,13 @@ static PFNGLISSHADERPROC glIsShader_func = NULL;
static PFNGLLINKPROGRAMPROC glLinkProgram_func = NULL;
static PFNGLSHADERSOURCEPROC glShaderSource_func = NULL;
static PFNGLUNIFORM1IPROC glUniform1i_func = NULL;
+static PFNGLUNIFORM2IPROC glUniform2i_func = NULL;
+static PFNGLUNIFORM3IPROC glUniform3i_func = NULL;
+static PFNGLUNIFORM4IPROC glUniform4i_func = NULL;
+static PFNGLUNIFORM1FPROC glUniform1f_func = NULL;
+static PFNGLUNIFORM2FPROC glUniform2f_func = NULL;
+static PFNGLUNIFORM3FPROC glUniform3f_func = NULL;
+static PFNGLUNIFORM4FPROC glUniform4f_func = NULL;
static PFNGLUNIFORM1FVPROC glUniform1fv_func = NULL;
static PFNGLUNIFORM2FVPROC glUniform2fv_func = NULL;
static PFNGLUNIFORM3FVPROC glUniform3fv_func = NULL;
@@ -47,6 +55,10 @@ static PFNGLUNIFORMMATRIX4X2FVPROC glUniformMatrix4x2fv_func = NULL;
static PFNGLUNIFORMMATRIX3X4FVPROC glUniformMatrix3x4fv_func = NULL;
static PFNGLUNIFORMMATRIX4X3FVPROC glUniformMatrix4x3fv_func = NULL;
+/* OpenGL 1.4 */
+static PFNGLPOINTPARAMETERFVPROC glPointParameterfv_func = NULL;
+static PFNGLSECONDARYCOLOR3FVPROC glSecondaryColor3fv_func = NULL;
+
/* GL_ARB_vertex/fragment_program */
static PFNGLBINDPROGRAMARBPROC glBindProgramARB_func = NULL;
static PFNGLDELETEPROGRAMSARBPROC glDeleteProgramsARB_func = NULL;
@@ -80,6 +92,7 @@ GetExtensionFuncs(void)
glDeleteProgram_func = (PFNGLDELETEPROGRAMPROC) glutGetProcAddress("glDeleteProgram");
glDeleteShader_func = (PFNGLDELETESHADERPROC) glutGetProcAddress("glDeleteShader");
glGetActiveAttrib_func = (PFNGLGETACTIVEATTRIBPROC) glutGetProcAddress("glGetActiveAttrib");
+ glGetActiveUniform_func = (PFNGLGETACTIVEUNIFORMPROC) glutGetProcAddress("glGetActiveUniform");
glGetAttachedShaders_func = (PFNGLGETATTACHEDSHADERSPROC) glutGetProcAddress("glGetAttachedShaders");
glGetAttribLocation_func = (PFNGLGETATTRIBLOCATIONPROC) glutGetProcAddress("glGetAttribLocation");
glGetProgramInfoLog_func = (PFNGLGETPROGRAMINFOLOGPROC) glutGetProcAddress("glGetProgramInfoLog");
@@ -94,6 +107,13 @@ GetExtensionFuncs(void)
glLinkProgram_func = (PFNGLLINKPROGRAMPROC) glutGetProcAddress("glLinkProgram");
glShaderSource_func = (PFNGLSHADERSOURCEPROC) glutGetProcAddress("glShaderSource");
glUniform1i_func = (PFNGLUNIFORM1IPROC) glutGetProcAddress("glUniform1i");
+ glUniform2i_func = (PFNGLUNIFORM2IPROC) glutGetProcAddress("glUniform2i");
+ glUniform3i_func = (PFNGLUNIFORM3IPROC) glutGetProcAddress("glUniform3i");
+ glUniform4i_func = (PFNGLUNIFORM4IPROC) glutGetProcAddress("glUniform3i");
+ glUniform1f_func = (PFNGLUNIFORM1FPROC) glutGetProcAddress("glUniform1f");
+ glUniform2f_func = (PFNGLUNIFORM2FPROC) glutGetProcAddress("glUniform2f");
+ glUniform3f_func = (PFNGLUNIFORM3FPROC) glutGetProcAddress("glUniform3f");
+ glUniform4f_func = (PFNGLUNIFORM4FPROC) glutGetProcAddress("glUniform4f");
glUniform1fv_func = (PFNGLUNIFORM1FVPROC) glutGetProcAddress("glUniform1fv");
glUniform2fv_func = (PFNGLUNIFORM2FVPROC) glutGetProcAddress("glUniform2fv");
glUniform3fv_func = (PFNGLUNIFORM3FVPROC) glutGetProcAddress("glUniform3fv");
@@ -115,6 +135,10 @@ GetExtensionFuncs(void)
glUniformMatrix3x4fv_func = (PFNGLUNIFORMMATRIX3X4FVPROC) glutGetProcAddress("glUniformMatrix3x4fv");
glUniformMatrix4x3fv_func = (PFNGLUNIFORMMATRIX4X3FVPROC) glutGetProcAddress("glUniformMatrix4x3fv");
+ /* OpenGL 1.4 */
+ glPointParameterfv_func = (PFNGLPOINTPARAMETERFVPROC) glutGetProcAddress("glPointParameterfv");
+ glSecondaryColor3fv_func = (PFNGLSECONDARYCOLOR3FVPROC) glutGetProcAddress("glSecondaryColor3fv");
+
/* GL_ARB_vertex/fragment_program */
glBindProgramARB_func = (PFNGLBINDPROGRAMARBPROC) glutGetProcAddress("glBindProgramARB");
glDeleteProgramsARB_func = (PFNGLDELETEPROGRAMSARBPROC) glutGetProcAddress("glDeleteProgramsARB");
diff --git a/progs/util/shaderutil.c b/progs/util/shaderutil.c
new file mode 100644
index 00000000000..477209ab45f
--- /dev/null
+++ b/progs/util/shaderutil.c
@@ -0,0 +1,159 @@
+/**
+ * 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;
+
+ version = (const char *) glGetString(GL_VERSION);
+ if (version[0] != '2' || version[1] != '.') {
+ printf("GL_RENDERER = %s\n",(const char *) glGetString(GL_RENDERER));
+ return GL_FALSE;
+ }
+ 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 00000000000..cfb8c1f3b06
--- /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/util/showbuffer.c b/progs/util/showbuffer.c
index 17f84dc62bd..b0cedea217c 100644
--- a/progs/util/showbuffer.c
+++ b/progs/util/showbuffer.c
@@ -71,6 +71,8 @@ ShowDepthBuffer( GLsizei winWidth, GLsizei winHeight,
glPushMatrix();
glLoadIdentity();
+ glViewport(0, 0, winWidth, winHeight);
+
glDisable(GL_STENCIL_TEST);
glDisable(GL_DEPTH_TEST);
glRasterPos2f(0, 0);
@@ -120,6 +122,8 @@ ShowAlphaBuffer( GLsizei winWidth, GLsizei winHeight )
glPushMatrix();
glLoadIdentity();
+ glViewport(0, 0, winWidth, winHeight);
+
glDisable(GL_STENCIL_TEST);
glDisable(GL_DEPTH_TEST);
glRasterPos2f(0, 0);
@@ -170,6 +174,8 @@ ShowStencilBuffer( GLsizei winWidth, GLsizei winHeight,
glPushMatrix();
glLoadIdentity();
+ glViewport(0, 0, winWidth, winHeight);
+
glDisable(GL_STENCIL_TEST);
glDisable(GL_DEPTH_TEST);
glRasterPos2f(0, 0);
diff --git a/progs/util/xrotfont.c b/progs/util/xrotfont.c
deleted file mode 100644
index f1779678a7a..00000000000
--- a/progs/util/xrotfont.c
+++ /dev/null
@@ -1,368 +0,0 @@
-/*
- * Mesa 3-D graphics library
- *
- * Copyright (C) 1999-2004 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.
- */
-
-
-/*
- * glXUseRotatedXFontMESA() function - like glXUseXFont() but allows
- * specification of a 0, 90, 180 or 270 degree rotation.
- * Handy for drawing labels along vertical axes of graphs, etc.
- *
- * Based on Mesa's glXUseXFont code written and copyrighted by Thorsten Ohl.
- */
-
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <X11/Xlib.h>
-#include <X11/Xutil.h>
-#include <GL/gl.h>
-#include <GL/glx.h>
-
-
-
-/**
- * Generate OpenGL-compatible bitmap by drawing an X character glyph
- * to an off-screen pixmap, then getting the image and testing pixels.
- * \param width bitmap width in pixels
- * \param height bitmap height in pixels
- */
-static void
-fill_bitmap(Display *dpy, Pixmap pixmap, GC gc,
- unsigned int bitmapWidth, unsigned int bitmapHeight,
- unsigned int charWidth, unsigned int charHeight,
- int xPos, int yPos, unsigned int c, GLubyte * bitmap,
- int rotation)
-{
- const int bytesPerRow = (bitmapWidth + 7) / 8;
- XImage *image;
- XChar2b char2b;
-
- /* clear pixmap to 0 */
- XSetForeground(dpy, gc, 0);
- XFillRectangle(dpy, pixmap, gc, 0, 0, charWidth, charHeight);
-
- /* The glyph is drawn snug up against the left/top edges of the pixmap */
- XSetForeground(dpy, gc, 1);
- char2b.byte1 = (c >> 8) & 0xff;
- char2b.byte2 = (c & 0xff);
- XDrawString16(dpy, pixmap, gc, xPos, yPos, &char2b, 1);
-
- /* initialize GL bitmap */
- memset(bitmap, 0, bytesPerRow * bitmapHeight);
-
- image = XGetImage(dpy, pixmap, 0, 0, charWidth, charHeight, 1, XYPixmap);
- if (image) {
- /* Set appropriate bits in the GL bitmap.
- * Note: X11 and OpenGL are upside down wrt each other).
- */
- unsigned int x, y;
- if (rotation == 0) {
- for (y = 0; y < charHeight; y++) {
- for (x = 0; x < charWidth; x++) {
- if (XGetPixel(image, x, y)) {
- int y2 = bitmapHeight - y - 1;
- bitmap[bytesPerRow * y2 + x / 8] |= (1 << (7 - (x % 8)));
- }
- }
- }
- }
- else if (rotation == 90) {
- for (y = 0; y < charHeight; y++) {
- for (x = 0; x < charWidth; x++) {
- if (XGetPixel(image, x, y)) {
- int x2 = y;
- int y2 = x;
- bitmap[bytesPerRow * y2 + x2 / 8] |= (1 << (7 - (x2 % 8)));
- }
- }
- }
- }
- else if (rotation == 180) {
- for (y = 0; y < charHeight; y++) {
- for (x = 0; x < charWidth; x++) {
- if (XGetPixel(image, x, y)) {
- int x2 = charWidth - x - 1;
- bitmap[bytesPerRow * y + x2 / 8] |= (1 << (7 - (x2 % 8)));
- }
- }
- }
- }
- else {
- for (y = 0; y < charHeight; y++) {
- for (x = 0; x < charWidth; x++) {
- if (XGetPixel(image, x, y)) {
- int x2 = charHeight - y - 1;
- int y2 = charWidth - x - 1;
- bitmap[bytesPerRow * y2 + x2 / 8] |= (1 << (7 - (x2 % 8)));
- }
- }
- }
- }
- XDestroyImage(image);
- }
-}
-
-
-/**
- * Determine if a given glyph is valid and return the
- * corresponding XCharStruct.
- */
-static const XCharStruct *
-isvalid(const XFontStruct * fs, unsigned int which)
-{
- unsigned int rows, pages;
- unsigned int byte1 = 0, byte2 = 0;
- int i, valid = 1;
-
- rows = fs->max_byte1 - fs->min_byte1 + 1;
- pages = fs->max_char_or_byte2 - fs->min_char_or_byte2 + 1;
-
- if (rows == 1) {
- /* "linear" fonts */
- if ((fs->min_char_or_byte2 > which) || (fs->max_char_or_byte2 < which))
- valid = 0;
- }
- else {
- /* "matrix" fonts */
- byte2 = which & 0xff;
- byte1 = which >> 8;
- if ((fs->min_char_or_byte2 > byte2) ||
- (fs->max_char_or_byte2 < byte2) ||
- (fs->min_byte1 > byte1) || (fs->max_byte1 < byte1))
- valid = 0;
- }
-
- if (valid) {
- if (fs->per_char) {
- if (rows == 1) {
- /* "linear" fonts */
- return fs->per_char + (which - fs->min_char_or_byte2);
- }
- else {
- /* "matrix" fonts */
- i = ((byte1 - fs->min_byte1) * pages) +
- (byte2 - fs->min_char_or_byte2);
- return fs->per_char + i;
- }
- }
- else {
- return &fs->min_bounds;
- }
- }
- return NULL;
-}
-
-
-/**
- * Just like glXUseXFont() but with a rotation parameter.
- * \param rotation may be 0, 90, 180 or 270 only.
- */
-void
-glXUseRotatedXFontMESA(Font font, int first, int count, int listbase,
- int rotation)
-{
- Display *dpy;
- Window win;
- Pixmap pixmap;
- GC gc;
- XFontStruct *fs;
- GLint swapbytes, lsbfirst, rowlength;
- GLint skiprows, skippixels, alignment;
- unsigned int maxCharWidth, maxCharHeight;
- GLubyte *bm;
- int i;
-
- if (rotation != 0 &&
- rotation != 90 &&
- rotation != 180 &&
- rotation != 270)
- return;
-
- dpy = glXGetCurrentDisplay();
- if (!dpy)
- return; /* I guess glXMakeCurrent wasn't called */
- win = RootWindow(dpy, DefaultScreen(dpy));
-
- fs = XQueryFont(dpy, font);
- if (!fs) {
- fprintf(stderr, "XQueryFont failed");
- return;
- }
-
- /* Allocate a GL bitmap that can fit any character */
- maxCharWidth = fs->max_bounds.rbearing - fs->min_bounds.lbearing;
- maxCharHeight = fs->max_bounds.ascent + fs->max_bounds.descent;
- /* use max, in case we're rotating */
- if (rotation == 90 || rotation == 270) {
- /* swap width/height */
- bm = (GLubyte *) malloc((maxCharHeight + 7) / 8 * maxCharWidth);
- }
- else {
- /* normal or upside down */
- bm = (GLubyte *) malloc((maxCharWidth + 7) / 8 * maxCharHeight);
- }
- if (!bm) {
- XFreeFontInfo(NULL, fs, 1);
- fprintf(stderr, "Out of memory in glXUseRotatedXFontMESA");
- return;
- }
-
- /* Save the current packing mode for bitmaps. */
- glGetIntegerv(GL_UNPACK_SWAP_BYTES, &swapbytes);
- glGetIntegerv(GL_UNPACK_LSB_FIRST, &lsbfirst);
- glGetIntegerv(GL_UNPACK_ROW_LENGTH, &rowlength);
- glGetIntegerv(GL_UNPACK_SKIP_ROWS, &skiprows);
- glGetIntegerv(GL_UNPACK_SKIP_PIXELS, &skippixels);
- glGetIntegerv(GL_UNPACK_ALIGNMENT, &alignment);
-
- /* Enforce a standard packing mode which is compatible with
- fill_bitmap() from above. This is actually the default mode,
- except for the (non)alignment. */
- glPixelStorei(GL_UNPACK_SWAP_BYTES, GL_FALSE);
- glPixelStorei(GL_UNPACK_LSB_FIRST, GL_FALSE);
- glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
- glPixelStorei(GL_UNPACK_SKIP_ROWS, 0);
- glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
- glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
-
- /* Create pixmap and GC */
- pixmap = XCreatePixmap(dpy, win, maxCharWidth, maxCharHeight, 1);
- {
- XGCValues values;
- unsigned long valuemask;
- values.foreground = BlackPixel(dpy, DefaultScreen(dpy));
- values.background = WhitePixel(dpy, DefaultScreen(dpy));
- values.font = fs->fid;
- valuemask = GCForeground | GCBackground | GCFont;
- gc = XCreateGC(dpy, pixmap, valuemask, &values);
- }
-
- for (i = 0; i < count; i++) {
- const unsigned int c = first + i;
- const int list = listbase + i;
- unsigned int charWidth, charHeight;
- unsigned int bitmapWidth, bitmapHeight;
- GLfloat xOrig, yOrig, xStep, yStep, dtemp;
- const XCharStruct *ch;
- int xPos, yPos;
- int valid;
-
- /* check on index validity and get the bounds */
- ch = isvalid(fs, c);
- if (!ch) {
- ch = &fs->max_bounds;
- valid = 0;
- }
- else {
- valid = 1;
- }
-
- /* glBitmap()' parameters:
- straight from the glXUseXFont(3) manpage. */
- charWidth = ch->rbearing - ch->lbearing;
- charHeight = ch->ascent + ch->descent;
- xOrig = -ch->lbearing;
- yOrig = ch->descent;
- xStep = ch->width;
- yStep = 0;
-
- /* X11's starting point. */
- xPos = -ch->lbearing;
- yPos = ch->ascent;
-
- /* Apply rotation */
- switch (rotation) {
- case 0:
- /* nothing */
- bitmapWidth = charWidth;
- bitmapHeight = charHeight;
- break;
- case 90:
- /* xStep, yStep */
- dtemp = xStep;
- xStep = -yStep;
- yStep = dtemp;
- /* xOrig, yOrig */
- yOrig = xOrig;
- xOrig = charHeight - (charHeight - yPos);
- /* width, height */
- bitmapWidth = charHeight;
- bitmapHeight = charWidth;
- break;
- case 180:
- /* xStep, yStep */
- xStep = -xStep;
- yStep = -yStep;
- /* xOrig, yOrig */
- xOrig = charWidth - xOrig - 1;
- yOrig = charHeight - yOrig - 1;
- bitmapWidth = charWidth;
- bitmapHeight = charHeight;
- break;
- case 270:
- /* xStep, yStep */
- dtemp = xStep;
- xStep = yStep;
- yStep = -dtemp;
- /* xOrig, yOrig */
- dtemp = yOrig;
- yOrig = charWidth - xOrig;
- xOrig = dtemp;
- /* width, height */
- bitmapWidth = charHeight;
- bitmapHeight = charWidth;
- break;
- default:
- /* should never get here */
- ;
- }
-
- glNewList(list, GL_COMPILE);
- if (valid && bitmapWidth > 0 && bitmapHeight > 0) {
-
- fill_bitmap(dpy, pixmap, gc, bitmapWidth, bitmapHeight,
- charWidth, charHeight,
- xPos, yPos, c, bm, rotation);
-
- glBitmap(bitmapWidth, bitmapHeight, xOrig, yOrig, xStep, yStep, bm);
- }
- else {
- glBitmap(0, 0, 0.0, 0.0, xStep, yStep, NULL);
- }
- glEndList();
- }
-
- free(bm);
- XFreeFontInfo(NULL, fs, 1);
- XFreePixmap(dpy, pixmap);
- XFreeGC(dpy, gc);
-
- /* Restore saved packing modes. */
- glPixelStorei(GL_UNPACK_SWAP_BYTES, swapbytes);
- glPixelStorei(GL_UNPACK_LSB_FIRST, lsbfirst);
- glPixelStorei(GL_UNPACK_ROW_LENGTH, rowlength);
- glPixelStorei(GL_UNPACK_SKIP_ROWS, skiprows);
- glPixelStorei(GL_UNPACK_SKIP_PIXELS, skippixels);
- glPixelStorei(GL_UNPACK_ALIGNMENT, alignment);
-}
diff --git a/progs/vp/.gitignore b/progs/vp/.gitignore
deleted file mode 100644
index a5ff9935254..00000000000
--- a/progs/vp/.gitignore
+++ /dev/null
@@ -1 +0,0 @@
-vp-tris
diff --git a/progs/xdemos/.gitignore b/progs/xdemos/.gitignore
new file mode 100644
index 00000000000..868249db884
--- /dev/null
+++ b/progs/xdemos/.gitignore
@@ -0,0 +1,25 @@
+corender
+glthreads
+glxcontexts
+glxdemo
+glxgears
+glxgears_fbconfig
+glxgears_pixmap
+glxheads
+glxinfo
+glxpbdemo
+glxpixmap
+glxsnoop
+glxswapcontrol
+manywin
+offset
+overlay
+pbdemo
+pbinfo
+sharedtex
+texture_from_pixmap
+wincopy
+xdemo
+xfont
+xrotfontdemo
+yuvrect_client
diff --git a/progs/xdemos/Makefile b/progs/xdemos/Makefile
index 1803633ef11..c90159bd38c 100644
--- a/progs/xdemos/Makefile
+++ b/progs/xdemos/Makefile
@@ -11,21 +11,26 @@ LIB_DEP = $(TOP)/$(LIB_DIR)/$(GL_LIB_NAME)
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 \
overlay \
pbinfo \
pbdemo \
+ sharedtex \
+ texture_from_pixmap \
wincopy \
xfont \
xrotfontdemo
@@ -91,6 +96,15 @@ xuserotfont.o: xuserotfont.c xuserotfont.h
xrotfontdemo.o: xrotfontdemo.c xuserotfont.h
$(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 00000000000..f2b8145e52b
--- /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/glthreads.c b/progs/xdemos/glthreads.c
index 6c7029b6ecf..4f87ee75d40 100644
--- a/progs/xdemos/glthreads.c
+++ b/progs/xdemos/glthreads.c
@@ -24,6 +24,7 @@
* This program tests GLX thread safety.
* Command line options:
* -p Open a display connection for each thread
+ * -l Enable application-side locking
* -n <num threads> Number of threads to create (default is 2)
* -display <display name> Specify X display (default is :0.0)
*
@@ -405,6 +406,19 @@ clean_up(void)
}
+static void
+usage(void)
+{
+ printf("glthreads: test of GL thread safety (any key = exit)\n");
+ printf("Usage:\n");
+ printf(" glthreads [options]\n");
+ printf("Options:\n");
+ printf(" -display DISPLAYNAME Specify display string\n");
+ printf(" -n NUMTHREADS Number of threads to create\n");
+ printf(" -p Use a separate display connection for each thread\n");
+ printf(" -l Use application-side locking\n");
+}
+
int
main(int argc, char *argv[])
@@ -416,9 +430,7 @@ main(int argc, char *argv[])
Status threadStat;
if (argc == 1) {
- printf("glthreads: test of GL thread safety (any key = exit)\n");
- printf("Usage:\n");
- printf(" glthreads [-display dpyName] [-n numthreads]\n");
+ usage();
}
else {
int i;
@@ -442,13 +454,14 @@ main(int argc, char *argv[])
i++;
}
else {
- fprintf(stderr, "glthreads: unexpected flag: %s\n", argv[i]);
+ usage();
+ exit(1);
}
}
}
if (Locking)
- printf("glthreads: Using explict locks around Xlib calls.\n");
+ printf("glthreads: Using explicit locks around Xlib calls.\n");
else
printf("glthreads: No explict locking.\n");
@@ -505,7 +518,7 @@ main(int argc, char *argv[])
for (i = 0; i < numThreads; i++) {
pthread_create(&WinThreads[i].Thread, NULL, thread_function,
(void*) &WinThreads[i]);
- printf("glthreads: Created thread %p\n", WinThreads[i].Thread);
+ printf("glthreads: Created thread %p\n", (void *) WinThreads[i].Thread);
}
if (MultiDisplays)
diff --git a/progs/xdemos/glxgears.c b/progs/xdemos/glxgears.c
index 75d63e51a2e..c98c3157b5d 100644
--- a/progs/xdemos/glxgears.c
+++ b/progs/xdemos/glxgears.c
@@ -88,12 +88,18 @@ current_time(void)
#endif
+/** Event handler results: */
+#define NOP 0
+#define EXIT 1
+#define DRAW 2
+
static GLfloat view_rotx = 20.0, view_roty = 30.0, view_rotz = 0.0;
static GLint gear1, gear2, gear3;
static GLfloat angle = 0.0;
static GLboolean fullscreen = GL_FALSE; /* Create a single fullscreen window */
static GLboolean stereo = GL_FALSE; /* Enable stereo. */
+static GLboolean animate = GL_TRUE; /* Animation */
static GLfloat eyesep = 5.0; /* Eye separation. */
static GLfloat fix_point = 40.0; /* Fixation point distance. */
static GLfloat left, right, asp; /* Stereo frustum params. */
@@ -239,7 +245,7 @@ gear(GLfloat inner_radius, GLfloat outer_radius, GLfloat width,
static void
-do_draw(void)
+draw(void)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
@@ -269,8 +275,9 @@ do_draw(void)
glPopMatrix();
}
+
static void
-draw(void)
+draw_gears(void)
{
if (stereo) {
/* First left eye. */
@@ -284,7 +291,7 @@ draw(void)
glPushMatrix();
glTranslated(+0.5 * eyesep, 0.0, 0.0);
- do_draw();
+ draw();
glPopMatrix();
/* Then right eye. */
@@ -298,10 +305,50 @@ draw(void)
glPushMatrix();
glTranslated(-0.5 * eyesep, 0.0, 0.0);
- do_draw();
+ draw();
glPopMatrix();
- } else
- do_draw();
+ }
+ else {
+ draw();
+ }
+}
+
+
+/** Draw single frame, do SwapBuffers, compute FPS */
+static void
+draw_frame(Display *dpy, Window win)
+{
+ static int frames = 0;
+ static double tRot0 = -1.0, tRate0 = -1.0;
+ double dt, t = current_time();
+
+ if (tRot0 < 0.0)
+ tRot0 = t;
+ dt = t - tRot0;
+ tRot0 = t;
+
+ if (animate) {
+ /* advance rotation for next frame */
+ angle += 70.0 * dt; /* 70 degrees per second */
+ if (angle > 3600.0)
+ angle -= 3600.0;
+ }
+
+ draw_gears();
+ glXSwapBuffers(dpy, win);
+
+ frames++;
+
+ if (tRate0 < 0.0)
+ tRate0 = t;
+ if (t - tRate0 >= 5.0) {
+ GLfloat seconds = t - tRate0;
+ GLfloat fps = frames / seconds;
+ printf("%d frames in %3.1f seconds = %6.3f FPS\n", frames, seconds,
+ fps);
+ tRate0 = t;
+ frames = 0;
+ }
}
@@ -319,7 +366,8 @@ reshape(int width, int height)
left = -5.0 * ((w - 0.5 * eyesep) / fix_point);
right = 5.0 * ((w + 0.5 * eyesep) / fix_point);
- } else {
+ }
+ else {
GLfloat h = (GLfloat) height / (GLfloat) width;
glMatrixMode(GL_PROJECTION);
@@ -430,10 +478,11 @@ make_window( Display *dpy, const char *name,
attr.border_pixel = 0;
attr.colormap = XCreateColormap( dpy, root, visinfo->visual, AllocNone);
attr.event_mask = StructureNotifyMask | ExposureMask | KeyPressMask;
+ /* XXX this is a bad way to get a borderless window! */
attr.override_redirect = fullscreen;
mask = CWBackPixel | CWBorderPixel | CWColormap | CWEventMask | CWOverrideRedirect;
- win = XCreateWindow( dpy, root, 0, 0, width, height,
+ win = XCreateWindow( dpy, root, x, y, width, height,
0, visinfo->depth, InputOutput,
visinfo->visual, mask, &attr );
@@ -463,79 +512,70 @@ make_window( Display *dpy, const char *name,
}
+/**
+ * Handle one X event.
+ * \return NOP, EXIT or DRAW
+ */
+static int
+handle_event(Display *dpy, Window win, XEvent *event)
+{
+ switch (event->type) {
+ case Expose:
+ return DRAW;
+ case ConfigureNotify:
+ reshape(event->xconfigure.width, event->xconfigure.height);
+ break;
+ case KeyPress:
+ {
+ char buffer[10];
+ int r, code;
+ code = XLookupKeysym(&event->xkey, 0);
+ if (code == XK_Left) {
+ view_roty += 5.0;
+ }
+ else if (code == XK_Right) {
+ view_roty -= 5.0;
+ }
+ else if (code == XK_Up) {
+ view_rotx += 5.0;
+ }
+ else if (code == XK_Down) {
+ view_rotx -= 5.0;
+ }
+ else {
+ r = XLookupString(&event->xkey, buffer, sizeof(buffer),
+ NULL, NULL);
+ if (buffer[0] == 27) {
+ /* escape */
+ return EXIT;
+ }
+ else if (buffer[0] == 'a' || buffer[0] == 'A') {
+ animate = !animate;
+ }
+ }
+ return DRAW;
+ }
+ }
+ return NOP;
+}
+
+
static void
event_loop(Display *dpy, Window win)
{
while (1) {
- while (XPending(dpy) > 0) {
+ int op;
+ while (!animate || XPending(dpy) > 0) {
XEvent event;
XNextEvent(dpy, &event);
- switch (event.type) {
- case Expose:
- /* we'll redraw below */
- break;
- case ConfigureNotify:
- reshape(event.xconfigure.width, event.xconfigure.height);
- break;
- case KeyPress:
- {
- char buffer[10];
- int r, code;
- code = XLookupKeysym(&event.xkey, 0);
- if (code == XK_Left) {
- view_roty += 5.0;
- }
- else if (code == XK_Right) {
- view_roty -= 5.0;
- }
- else if (code == XK_Up) {
- view_rotx += 5.0;
- }
- else if (code == XK_Down) {
- view_rotx -= 5.0;
- }
- else {
- r = XLookupString(&event.xkey, buffer, sizeof(buffer),
- NULL, NULL);
- if (buffer[0] == 27) {
- /* escape */
- return;
- }
- }
- }
- }
+ op = handle_event(dpy, win, &event);
+ if (op == EXIT)
+ return;
+ else if (op == DRAW)
+ break;
}
- {
- static int frames = 0;
- static double tRot0 = -1.0, tRate0 = -1.0;
- double dt, t = current_time();
- if (tRot0 < 0.0)
- tRot0 = t;
- dt = t - tRot0;
- tRot0 = t;
-
- /* advance rotation for next frame */
- angle += 70.0 * dt; /* 70 degrees per second */
- if (angle > 3600.0)
- angle -= 3600.0;
-
- draw();
- glXSwapBuffers(dpy, win);
-
- frames++;
-
- if (tRate0 < 0.0)
- tRate0 = t;
- if (t - tRate0 >= 5.0) {
- GLfloat seconds = t - tRate0;
- GLfloat fps = frames / seconds;
- printf("%d frames in %3.1f seconds = %6.3f FPS\n", frames, seconds,
- fps);
- tRate0 = t;
- frames = 0;
- }
- }
+ draw_frame(dpy, win);
}
}
@@ -548,13 +588,15 @@ usage(void)
printf(" -stereo run in stereo mode\n");
printf(" -fullscreen run in fullscreen mode\n");
printf(" -info display OpenGL renderer info\n");
+ printf(" -geometry WxH+X+Y window geometry\n");
}
int
main(int argc, char *argv[])
{
- const int winWidth = 300, winHeight = 300;
+ unsigned int winWidth = 300, winHeight = 300;
+ int x = 0, y = 0;
Display *dpy;
Window win;
GLXContext ctx;
@@ -576,6 +618,10 @@ main(int argc, char *argv[])
else if (strcmp(argv[i], "-fullscreen") == 0) {
fullscreen = GL_TRUE;
}
+ else if (i < argc-1 && strcmp(argv[i], "-geometry") == 0) {
+ XParseGeometry(argv[i+1], &x, &y, &winWidth, &winHeight);
+ i++;
+ }
else {
usage();
return -1;
@@ -589,7 +635,7 @@ main(int argc, char *argv[])
return -1;
}
- make_window(dpy, "glxgears", 0, 0, winWidth, winHeight, &win, &ctx);
+ make_window(dpy, "glxgears", x, y, winWidth, winHeight, &win, &ctx);
XMapWindow(dpy, win);
glXMakeCurrent(dpy, win, ctx);
diff --git a/progs/xdemos/glxgears2.c b/progs/xdemos/glxgears_pixmap.c
index 5de5601240e..661d130e41c 100644
--- a/progs/xdemos/glxgears2.c
+++ b/progs/xdemos/glxgears_pixmap.c
@@ -1,6 +1,7 @@
/*
* 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
@@ -19,16 +20,22 @@
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
-/*
- * This is a port of the infamous "gears" demo to straight GLX (i.e. no GLUT)
- * Port by Brian Paul 23 March 2001
+/**
+ * \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 <[email protected]>
+ * \author Kristian Hoegsberg <[email protected]>
*/
+#define GLX_GLXEXT_PROTOTYPES
+
#include <math.h>
#include <stdlib.h>
#include <stdio.h>
@@ -37,7 +44,9 @@
#include <X11/keysym.h>
#include <GL/gl.h>
#include <GL/glx.h>
-
+#include <GL/glxext.h>
+#include <assert.h>
+#include "pbutil.h"
#define BENCHMARK
@@ -83,7 +92,7 @@ current_time(void)
static GLfloat view_rotx = 20.0, view_roty = 30.0, view_rotz = 0.0;
static GLint gear1, gear2, gear3;
static GLfloat angle = 0.0;
-static GLint WinWidth = 300, WinHeight = 300;
+
/*
*
@@ -256,33 +265,33 @@ draw(void)
}
+struct gears {
+ Window win;
+ GLXContext ctx;
+ Pixmap pixmap;
+ GLXPixmap glxpixmap;
+ GC gc;
+ int width, height;
+};
+
+
/* new window size or exposure */
static void
-reshape(int width, int height)
+reshape(struct gears *gears, int width, int height)
{
- GLfloat h = (GLfloat) height / (GLfloat) width;
-
- 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);
- WinWidth = width;
- WinHeight = height;
+ gears->width = width;
+ gears->height = height;
}
static void
-init(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 };
-
- glClearColor(1, 0, 0, 0);
+ GLfloat h = (GLfloat) height / (GLfloat) width;
glLightfv(GL_LIGHT0, GL_POSITION, pos);
glEnable(GL_CULL_FACE);
@@ -310,8 +319,15 @@ init(void)
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.
@@ -319,43 +335,48 @@ init(void)
*/
static void
make_window( Display *dpy, const char *name,
- int x, int y, int width, int height,
- Window *winRet, GLXContext *ctxRet)
+ int x, int y, int width, int height, struct gears *gears)
{
- int attrib[] = { GLX_RGBA,
- GLX_RED_SIZE, 1,
- GLX_GREEN_SIZE, 1,
- GLX_BLUE_SIZE, 1,
- GLX_DOUBLEBUFFER,
- GLX_DEPTH_SIZE, 1,
+ 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;
- Window win;
- GLXContext ctx;
XVisualInfo *visinfo;
+ gears->width = width;
+ gears->height = height;
+
scrnum = DefaultScreen( dpy );
root = RootWindow( dpy, scrnum );
- visinfo = glXChooseVisual( dpy, scrnum, attrib );
- if (!visinfo) {
+ 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;
- win = XCreateWindow( dpy, root, 0, 0, width, height,
- 0, visinfo->depth, InputOutput,
- visinfo->visual, mask, &attr );
+ gears->win = XCreateWindow( dpy, root, 0, 0, width, height,
+ 0, visinfo->depth, InputOutput,
+ visinfo->visual, mask, &attr );
/* set hints and properties */
{
@@ -365,27 +386,42 @@ make_window( Display *dpy, const char *name,
sizehints.width = width;
sizehints.height = height;
sizehints.flags = USSize | USPosition;
- XSetNormalHints(dpy, win, &sizehints);
- XSetStandardProperties(dpy, win, name, name,
+ XSetNormalHints(dpy, gears->win, &sizehints);
+ XSetStandardProperties(dpy, gears->win, name, name,
None, (char **)NULL, 0, &sizehints);
}
- ctx = glXCreateContext( dpy, visinfo, NULL, True );
- if (!ctx) {
- printf("Error: glXCreateContext failed\n");
- exit(1);
+ 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);
}
- XFree(visinfo);
+ gears->ctx = glXCreateNewContext(dpy, fbconfig[0],
+ GLX_RGBA_TYPE, NULL, GL_TRUE);
+ if (!gears->ctx) {
+ printf("Error: glXCreateNewContext failed\n");
+ exit(1);
+ }
- *winRet = win;
- *ctxRet = ctx;
+ XFree(fbconfig);
}
static void
-event_loop(Display *dpy, Window win)
+event_loop(Display *dpy, struct gears *gears)
{
+ int x, y;
+
while (1) {
while (XPending(dpy) > 0) {
XEvent event;
@@ -395,7 +431,7 @@ event_loop(Display *dpy, Window win)
/* we'll redraw below */
break;
case ConfigureNotify:
- reshape(event.xconfigure.width, event.xconfigure.height);
+ reshape(gears, event.xconfigure.width, event.xconfigure.height);
break;
case KeyPress:
{
@@ -430,24 +466,12 @@ event_loop(Display *dpy, Window win)
angle += 2.0;
draw();
+ glFinish();
-#if 0
- glXSwapBuffers(dpy, win);
-#else
- {
- GLfloat c[4];
-
- glReadBuffer(GL_BACK);
-
- glReadPixels(WinWidth-1, 0, 1, 1, GL_RGB, GL_FLOAT, c);
- printf("Bottom right pixel color: %g, %g, %g\n", c[0], c[1], c[2]);
-
- glDrawBuffer(GL_FRONT);
- glWindowPos2iARB(0,0);
- glCopyPixels(WinWidth/2, 0, WinWidth/2, WinHeight, GL_COLOR);
- glDrawBuffer(GL_BACK);
- }
-#endif
+ 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 */
{
@@ -477,11 +501,10 @@ int
main(int argc, char *argv[])
{
Display *dpy;
- Window win;
- GLXContext ctx;
- char *dpyName = ":0";
+ const char *dpyName = NULL;
GLboolean printInfo = GL_FALSE;
- int i;
+ struct gears gears;
+ int i, width = 200, height = 200;
for (i = 1; i < argc; i++) {
if (strcmp(argv[i], "-display") == 0) {
@@ -495,13 +518,13 @@ main(int argc, char *argv[])
dpy = XOpenDisplay(dpyName);
if (!dpy) {
- printf("Error: couldn't open display %s\n", dpyName);
+ printf("Error: couldn't open display %s\n", XDisplayName(dpyName));
return -1;
}
- make_window(dpy, "glxgears", 0, 0, WinWidth, WinHeight, &win, &ctx);
- XMapWindow(dpy, win);
- glXMakeCurrent(dpy, win, ctx);
+ 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));
@@ -510,12 +533,14 @@ main(int argc, char *argv[])
printf("GL_EXTENSIONS = %s\n", (char *) glGetString(GL_EXTENSIONS));
}
- init();
+ init(width, height);
- event_loop(dpy, win);
+ event_loop(dpy, &gears);
- glXDestroyContext(dpy, ctx);
- XDestroyWindow(dpy, win);
+ 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 e33cddff047..35b6ed16b09 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);
@@ -541,12 +581,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 +618,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);
@@ -616,8 +677,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 +775,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 +834,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 +880,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 +903,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 +1056,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 +1153,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 00000000000..2e951345b58
--- /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 d9be984be57..e429d58ecc4 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 00000000000..c872d1641ab
--- /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 00000000000..3f434457c6f
--- /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 97170f5c8de..6c5abf383be 100644
--- a/progs/xdemos/offset.c
+++ b/progs/xdemos/offset.c
@@ -70,12 +70,12 @@ typedef Vertex Quad[4];
/* data to define the six faces of a unit cube */
Quad quads[MAXQUAD] = {
- { {0,0,0}, {1,0,0}, {1,1,0}, {0,1,0} },
- { {0,0,1}, {1,0,1}, {1,1,1}, {0,1,1} },
- { {0,0,0}, {1,0,0}, {1,0,1}, {0,0,1} },
- { {0,1,0}, {1,1,0}, {1,1,1}, {0,1,1} },
- { {0,0,0}, {0,0,1}, {0,1,1}, {0,1,0} },
- { {1,0,0}, {1,0,1}, {1,1,1}, {1,1,0} }
+ { {0,0,0}, {0,0,1}, {0,1,1}, {0,1,0} }, /* x = 0 */
+ { {0,0,0}, {1,0,0}, {1,0,1}, {0,0,1} }, /* y = 0 */
+ { {0,0,0}, {1,0,0}, {1,1,0}, {0,1,0} }, /* z = 0 */
+ { {1,0,0}, {1,0,1}, {1,1,1}, {1,1,0} }, /* x = 1 */
+ { {0,1,0}, {1,1,0}, {1,1,1}, {0,1,1} }, /* y = 1 */
+ { {0,0,1}, {1,0,1}, {1,1,1}, {0,1,1} } /* z = 1 */
};
#define WIREFRAME 0
@@ -85,7 +85,7 @@ static void error(const char* prog, const char* msg);
static void cubes(int mx, int my, int mode);
static void fill(Quad quad);
static void outline(Quad quad);
-static void draw_hidden(Quad quad, int mode);
+static void draw_hidden(Quad quad, int mode, int face);
static void process_input(Display *dpy, Window win);
static int query_extension(char* extName);
@@ -100,6 +100,7 @@ int main(int argc, char** argv) {
XSetWindowAttributes swa;
Window win;
GLXContext cx;
+ GLint z;
dpy = XOpenDisplay(0);
if (!dpy) error(argv[0], "can't open display");
@@ -140,6 +141,9 @@ int main(int argc, char** argv) {
/* set other relevant state information */
glEnable(GL_DEPTH_TEST);
+ glGetIntegerv(GL_DEPTH_BITS, &z);
+ printf("GL_DEPTH_BITS = %d\n", z);
+
#ifdef GL_EXT_polygon_offset
printf("using 1.0 offset extension\n");
glPolygonOffsetEXT( 1.0, 0.00001 );
@@ -159,6 +163,7 @@ int main(int argc, char** argv) {
static void
draw_scene(int mx, int my) {
+ glClearColor(0.25, 0.25, 0.25, 0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glPushMatrix();
@@ -205,7 +210,7 @@ cubes(int mx, int my, int mode) {
glTranslatef(x, y, z);
glScalef(0.8, 0.8, 0.8);
for (i = 0; i < MAXQUAD; i++)
- draw_hidden(quads[i], mode);
+ draw_hidden(quads[i], mode, i);
glPopMatrix();
}
}
@@ -235,13 +240,18 @@ outline(Quad quad) {
}
static void
-draw_hidden(Quad quad, int mode) {
+draw_hidden(Quad quad, int mode, int face) {
+ static const GLfloat colors[3][3] = {
+ {0.5, 0.5, 0.0},
+ {0.8, 0.5, 0.0},
+ {0.0, 0.5, 0.8}
+ };
if (mode == HIDDEN_LINE) {
- glColor3f(0, 0, 0);
+ glColor3fv(colors[face % 3]);
fill(quad);
}
- /* draw the outline using white, optionally fill the interior with black */
+ /* draw the outline using white */
glColor3f(1, 1, 1);
outline(quad);
}
diff --git a/progs/xdemos/pbutil.c b/progs/xdemos/pbutil.c
index d0bbd1b0fce..ce133d012dc 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 e95b2565a23..d420522ff01 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/sharedtex.c b/progs/xdemos/sharedtex.c
new file mode 100644
index 00000000000..81703fe0e7d
--- /dev/null
+++ b/progs/xdemos/sharedtex.c
@@ -0,0 +1,324 @@
+/*
+ * Test sharing of texture objects by two rendering contexts.
+ * In particular, test that changing a texture object in one context
+ * effects the texture in the second context.
+ *
+ * Brian Paul
+ * 30 Apr 2008
+ *
+ * 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 <GL/gl.h>
+#include <GL/glx.h>
+#include <assert.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <X11/keysym.h>
+
+
+#define MAX_CONTEXTS 2
+
+#define TEX_SIZE 32
+
+static const char *DisplayName = NULL;
+static Display *Dpy;
+static XVisualInfo *VisInfo;
+static Window Win;
+static GLXContext Contexts[MAX_CONTEXTS];
+static int WinWidth = 300, WinHeight = 300;
+
+static int DrawContext = 0, TexContext = 1;
+
+static GLuint TexObj = 0;
+static GLboolean NewTexture = GL_FALSE;
+
+
+static void
+Error(const char *msg)
+{
+ fprintf(stderr, "sharedtex error: %s\n", msg);
+ exit(1);
+}
+
+
+static void
+CreateWindow(const char *name)
+{
+ int attrib[] = { GLX_RGBA,
+ GLX_RED_SIZE, 1,
+ GLX_GREEN_SIZE, 1,
+ GLX_BLUE_SIZE, 1,
+ GLX_DOUBLEBUFFER,
+ None };
+ int scrnum;
+ XSetWindowAttributes attr;
+ unsigned long mask;
+ Window root;
+ int xpos = 0, ypos = 0;
+ static int n = 0;
+
+ scrnum = DefaultScreen(Dpy);
+ root = RootWindow(Dpy, scrnum);
+
+ VisInfo = glXChooseVisual(Dpy, scrnum, attrib);
+ if (!VisInfo) {
+ Error("Unable to find RGB, double-buffered visual");
+ }
+
+ /* window attributes */
+ xpos = (n % 10) * 100;
+ ypos = (n / 10) * 100;
+ n++;
+
+ 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, xpos, ypos, WinWidth, WinHeight,
+ 0, VisInfo->depth, InputOutput,
+ VisInfo->visual, mask, &attr);
+ if (!Win) {
+ Error("Couldn't create window");
+ }
+
+ {
+ XSizeHints sizehints;
+ sizehints.x = xpos;
+ sizehints.y = ypos;
+ sizehints.width = WinWidth;
+ sizehints.height = WinHeight;
+ sizehints.flags = USSize | USPosition;
+ XSetNormalHints(Dpy, Win, &sizehints);
+ XSetStandardProperties(Dpy, Win, name, name,
+ None, (char **)NULL, 0, &sizehints);
+ }
+
+ XMapWindow(Dpy, Win);
+}
+
+
+/**
+ * Change texture image, using TexContext
+ */
+static void
+ModifyTexture(void)
+{
+ GLuint tex[TEX_SIZE][TEX_SIZE];
+ GLuint c0, c1;
+ int i, j;
+
+ if (Win && !glXMakeCurrent(Dpy, Win, Contexts[TexContext])) {
+ Error("glXMakeCurrent failed");
+ }
+
+ /* choose two random colors */
+ c0 = rand() & 0xffffffff;
+ c1 = rand() & 0xffffffff;
+
+ for (i = 0; i < TEX_SIZE; i++) {
+ for (j = 0; j < TEX_SIZE; j++) {
+ if (((i / 4) ^ (j / 4)) & 1) {
+ tex[i][j] = c0;
+ }
+ else {
+ tex[i][j] = c1;
+ }
+ }
+ }
+
+ glBindTexture(GL_TEXTURE_2D, TexObj);
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, TEX_SIZE, TEX_SIZE, 0,
+ GL_RGBA, GL_UNSIGNED_BYTE, tex);
+
+ NewTexture = GL_TRUE;
+}
+
+
+static void
+InitContext(void)
+{
+ glGenTextures(1, &TexObj);
+ assert(TexObj);
+ glBindTexture(GL_TEXTURE_2D, TexObj);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ glEnable(GL_TEXTURE_2D);
+
+ printf("GL_RENDERER = %s\n", (char*) glGetString(GL_RENDERER));
+}
+
+
+static void
+Setup(void)
+{
+ int i;
+
+ Dpy = XOpenDisplay(DisplayName);
+ if (!Dpy) {
+ Error("Unable to open display");
+ }
+
+ CreateWindow("sharedtex");
+
+ for (i = 0; i < MAX_CONTEXTS; i++) {
+ GLXContext share = i > 0 ? Contexts[0] : 0;
+
+ Contexts[i] = glXCreateContext(Dpy, VisInfo, share, True);
+ if (!Contexts[i]) {
+ Error("Unable to create GLX context");
+ }
+
+ if (!glXMakeCurrent(Dpy, Win, Contexts[i])) {
+ Error("glXMakeCurrent failed");
+ }
+
+ InitContext();
+ }
+
+ ModifyTexture();
+}
+
+
+/**
+ * Redraw window, using DrawContext
+ */
+static void
+Redraw(void)
+{
+ static float rot = 0.0;
+ float ar;
+
+ rot += 1.0;
+
+ if (Win && !glXMakeCurrent(Dpy, Win, Contexts[DrawContext])) {
+ Error("glXMakeCurrent failed");
+ }
+
+ glViewport(0, 0, WinWidth, WinHeight);
+ ar = (float) WinWidth / (float) WinHeight;
+ glMatrixMode(GL_PROJECTION);
+ glLoadIdentity();
+ glOrtho(-ar, ar, -1.0, 1.0, -1.0, 1.0);
+ glMatrixMode(GL_MODELVIEW);
+
+ glShadeModel(GL_FLAT);
+ glClearColor(0.5, 0.5, 0.5, 1.0);
+ glClear(GL_COLOR_BUFFER_BIT);
+
+ glPushMatrix();
+ glRotatef(rot, 0, 0, 1);
+ glScalef(0.7, 0.7, 0.7);
+
+ if (NewTexture) {
+ /* rebind to get new contents */
+ glBindTexture(GL_TEXTURE_2D, TexObj);
+ NewTexture = GL_FALSE;
+ }
+
+ /* draw textured quad */
+ glBegin(GL_POLYGON);
+ glTexCoord2f( 0.0, 0.0 ); glVertex2f( -1.0, -1.0 );
+ glTexCoord2f( 1.0, 0.0 ); glVertex2f( 1.0, -1.0 );
+ glTexCoord2f( 1.0, 1.0 ); glVertex2f( 1.0, 1.0 );
+ glTexCoord2f( 0.0, 1.0 ); glVertex2f( -1.0, 1.0 );
+ glEnd();
+
+ glPopMatrix();
+
+ if (Win)
+ glXSwapBuffers(Dpy, Win);
+}
+
+
+static void
+EventLoop(void)
+{
+ while (1) {
+ while (XPending(Dpy) > 0) {
+ XEvent event;
+ XNextEvent(Dpy, &event);
+
+ switch (event.type) {
+ case Expose:
+ Redraw();
+ break;
+ case ConfigureNotify:
+ WinWidth = event.xconfigure.width;
+ WinHeight = event.xconfigure.height;
+ break;
+ case KeyPress:
+ {
+ char buf[100];
+ KeySym keySym;
+ XComposeStatus stat;
+ XLookupString(&event.xkey, buf, sizeof(buf), &keySym, &stat);
+ switch (keySym) {
+ case XK_Escape:
+ exit(0);
+ break;
+ case XK_t:
+ case XK_T:
+ ModifyTexture();
+ break;
+ default:
+ ;
+ }
+ }
+ Redraw();
+ break;
+ default:
+ /*no-op*/ ;
+ }
+ }
+
+ Redraw();
+ usleep(10000);
+ }
+}
+
+
+
+
+int
+main(int argc, char *argv[])
+{
+ int i;
+
+ for (i = 1; i < argc; i++) {
+ if (strcmp(argv[i], "-display") == 0 && i < argc) {
+ DisplayName = argv[i+1];
+ i++;
+ }
+ }
+
+ Setup();
+
+ printf("Press 't' to change texture image/colors\n");
+
+ EventLoop();
+
+ return 0;
+}
diff --git a/progs/xdemos/texture_from_pixmap.c b/progs/xdemos/texture_from_pixmap.c
new file mode 100644
index 00000000000..ab215b0ac30
--- /dev/null
+++ b/progs/xdemos/texture_from_pixmap.c
@@ -0,0 +1,396 @@
+/*
+ * Mesa 3-D graphics library
+ * Version: 7.1
+ *
+ * Copyright (C) 1999-2007 Brian Paul All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+/*
+ * Test the GLX_EXT_texture_from_pixmap extension
+ * Brian Paul
+ * 19 May 2007
+ */
+
+
+#define GL_GLEXT_PROTOTYPES
+#define GLX_GLXEXT_PROTOTYPES
+#include <GL/gl.h>
+#include <GL/glx.h>
+#include <X11/keysym.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+
+static float top, bottom;
+
+static PFNGLXBINDTEXIMAGEEXTPROC glXBindTexImageEXT_func = NULL;
+static PFNGLXRELEASETEXIMAGEEXTPROC glXReleaseTexImageEXT_func = NULL;
+
+
+static Display *
+OpenDisplay(void)
+{
+ int screen;
+ Display *dpy;
+ const char *ext;
+
+ dpy = XOpenDisplay(NULL);
+ if (!dpy) {
+ printf("Couldn't open default display!\n");
+ exit(1);
+ }
+
+ screen = DefaultScreen(dpy);
+ ext = glXQueryExtensionsString(dpy, screen);
+ if (!strstr(ext, "GLX_EXT_texture_from_pixmap")) {
+ fprintf(stderr, "GLX_EXT_texture_from_pixmap not supported.\n");
+ exit(1);
+ }
+
+ glXBindTexImageEXT_func = (PFNGLXBINDTEXIMAGEEXTPROC)
+ glXGetProcAddress((GLubyte *) "glXBindTexImageEXT");
+ glXReleaseTexImageEXT_func = (PFNGLXRELEASETEXIMAGEEXTPROC)
+ glXGetProcAddress((GLubyte*) "glXReleaseTexImageEXT");
+
+ if (!glXBindTexImageEXT_func || !glXReleaseTexImageEXT_func) {
+ fprintf(stderr, "glXGetProcAddress failed!\n");
+ exit(1);
+ }
+
+ return dpy;
+}
+
+
+static GLXFBConfig
+ChoosePixmapFBConfig(Display *display)
+{
+ int screen = DefaultScreen(display);
+ GLXFBConfig *fbconfigs;
+ int i, nfbconfigs, value;
+
+ fbconfigs = glXGetFBConfigs(display, screen, &nfbconfigs);
+ for (i = 0; i < nfbconfigs; i++) {
+
+ glXGetFBConfigAttrib(display, fbconfigs[i], GLX_DRAWABLE_TYPE, &value);
+ if (!(value & GLX_PIXMAP_BIT))
+ continue;
+
+ glXGetFBConfigAttrib(display, fbconfigs[i],
+ GLX_BIND_TO_TEXTURE_TARGETS_EXT, &value);
+ if (!(value & GLX_TEXTURE_2D_BIT_EXT))
+ continue;
+
+ glXGetFBConfigAttrib(display, fbconfigs[i],
+ GLX_BIND_TO_TEXTURE_RGBA_EXT, &value);
+ if (value == False) {
+ glXGetFBConfigAttrib(display, fbconfigs[i],
+ GLX_BIND_TO_TEXTURE_RGB_EXT, &value);
+ if (value == False)
+ continue;
+ }
+
+ glXGetFBConfigAttrib(display, fbconfigs[i],
+ GLX_Y_INVERTED_EXT, &value);
+ if (value == True) {
+ top = 0.0f;
+ bottom = 1.0f;
+ }
+ else {
+ top = 1.0f;
+ bottom = 0.0f;
+ }
+
+ break;
+ }
+
+ if (i == nfbconfigs) {
+ printf("Unable to find FBconfig for texturing\n");
+ exit(1);
+ }
+
+ return fbconfigs[i];
+}
+
+
+static GLXPixmap
+CreatePixmap(Display *dpy, GLXFBConfig config, int w, int h, Pixmap *p)
+{
+ GLXPixmap gp;
+ const int pixmapAttribs[] = {
+ GLX_TEXTURE_TARGET_EXT, GLX_TEXTURE_2D_EXT,
+ GLX_TEXTURE_FORMAT_EXT, GLX_TEXTURE_FORMAT_RGB_EXT,
+ None
+ };
+ Window root = RootWindow(dpy, 0);
+
+ *p = XCreatePixmap(dpy, root, w, h, 24);
+ XSync(dpy, 0);
+ gp = glXCreatePixmap(dpy, config, *p, pixmapAttribs);
+ XSync(dpy, 0);
+
+ return gp;
+}
+
+
+static void
+DrawPixmapImage(Display *dpy, Pixmap pm, int w, int h)
+{
+ XGCValues gcvals;
+ GC gc;
+
+ gcvals.background = 0;
+ gc = XCreateGC(dpy, pm, GCBackground, &gcvals);
+
+ XSetForeground(dpy, gc, 0x0);
+ XFillRectangle(dpy, pm, gc, 0, 0, w, h);
+
+ XSetForeground(dpy, gc, 0xff0000);
+ XFillRectangle(dpy, pm, gc, 0, 0, 50, 50);
+
+ XSetForeground(dpy, gc, 0x00ff00);
+ XFillRectangle(dpy, pm, gc, w - 50, 0, 50, 50);
+
+ XSetForeground(dpy, gc, 0x0000ff);
+ XFillRectangle(dpy, pm, gc, 0, h - 50, 50, 50);
+
+ XSetForeground(dpy, gc, 0xffffff);
+ XFillRectangle(dpy, pm, gc, h - 50, h - 50, 50, 50);
+
+ XSetForeground(dpy, gc, 0xffff00);
+ XSetLineAttributes(dpy, gc, 3, LineSolid, CapButt, JoinBevel);
+ XDrawLine(dpy, pm, gc, 0, 0, w, h);
+ XDrawLine(dpy, pm, gc, 0, h, w, 0);
+
+ XFreeGC(dpy, gc);
+}
+
+
+static XVisualInfo *
+ChooseWindowVisual(Display *dpy)
+{
+ int screen = DefaultScreen(dpy);
+ XVisualInfo *visinfo;
+ int attribs[] = {
+ GLX_RGBA,
+ GLX_RED_SIZE, 1,
+ GLX_GREEN_SIZE, 1,
+ GLX_BLUE_SIZE, 1,
+ GLX_DOUBLEBUFFER,
+ None
+ };
+
+ visinfo = glXChooseVisual(dpy, screen, attribs);
+ if (!visinfo) {
+ printf("Unable to find RGB, double-buffered visual\n");
+ exit(1);
+ }
+
+ return visinfo;
+}
+
+
+static Window
+CreateWindow(Display *dpy, XVisualInfo *visinfo,
+ int width, int height, const char *name)
+{
+ int screen = DefaultScreen(dpy);
+ Window win;
+ XSetWindowAttributes attr;
+ unsigned long mask;
+ Window root;
+
+ root = RootWindow(dpy, screen);
+
+ /* 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, 0, 0, width, height,
+ 0, visinfo->depth, InputOutput,
+ visinfo->visual, mask, &attr);
+ if (win) {
+ XSizeHints sizehints;
+ sizehints.width = width;
+ sizehints.height = height;
+ sizehints.flags = USSize;
+ XSetNormalHints(dpy, win, &sizehints);
+ XSetStandardProperties(dpy, win, name, name,
+ None, (char **)NULL, 0, &sizehints);
+
+ XMapWindow(dpy, win);
+ }
+ return win;
+}
+
+
+static void
+BindPixmapTexture(Display *dpy, GLXPixmap gp)
+{
+ GLuint texture;
+
+ glGenTextures(1, &texture);
+ glBindTexture(GL_TEXTURE_2D, texture);
+
+ glXBindTexImageEXT_func(dpy, gp, GLX_FRONT_LEFT_EXT, NULL);
+
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+
+ glEnable(GL_TEXTURE_2D);
+ /*
+ glXReleaseTexImageEXT_func(display, glxpixmap, GLX_FRONT_LEFT_EXT);
+ */
+}
+
+
+static void
+Resize(Window win, unsigned int width, unsigned int height)
+{
+ float sz = 1.5;
+ glViewport(0, 0, width, height);
+ glMatrixMode(GL_PROJECTION);
+ glLoadIdentity();
+ glOrtho(-sz, sz, -sz, sz, -1.0, 1.0);
+ glMatrixMode(GL_MODELVIEW);
+}
+
+
+static void
+Redraw(Display *dpy, Window win, float rot)
+{
+ glClearColor(0.25, 0.25, 0.25, 0.0);
+ glClear(GL_COLOR_BUFFER_BIT);
+ glPushMatrix();
+ glRotatef(rot, 0, 0, 1);
+ glRotatef(2.0 * rot, 1, 0, 0);
+
+ glBegin(GL_QUADS);
+ glTexCoord2d(0.0, bottom);
+ glVertex2f(-1, -1);
+ glTexCoord2d(1.0, bottom);
+ glVertex2f( 1, -1);
+ glTexCoord2d(1.0, top);
+ glVertex2d(1.0, 1.0);
+ glTexCoord2d(0.0, top);
+ glVertex2f(-1.0, 1.0);
+ glEnd();
+
+ glPopMatrix();
+
+ glXSwapBuffers(dpy, win);
+}
+
+
+static void
+EventLoop(Display *dpy, Window win)
+{
+ GLfloat rot = 0.0;
+ int anim = 0;
+
+ while (1) {
+ if (!anim || XPending(dpy) > 0) {
+ XEvent event;
+ XNextEvent(dpy, &event);
+
+ switch (event.type) {
+ case Expose:
+ Redraw(dpy, win, rot);
+ break;
+ case ConfigureNotify:
+ Resize(event.xany.window,
+ event.xconfigure.width,
+ event.xconfigure.height);
+ break;
+ case KeyPress:
+ {
+ char buf[100];
+ KeySym keySym;
+ XComposeStatus stat;
+ XLookupString(&event.xkey, buf, sizeof(buf), &keySym, &stat);
+ if (keySym == XK_Escape) {
+ return; /* exit */
+ }
+ else if (keySym == XK_r) {
+ rot += 1.0;
+ Redraw(dpy, win, rot);
+ }
+ else if (keySym == XK_a) {
+ anim = !anim;
+ }
+ else if (keySym == XK_R) {
+ rot -= 1.0;
+ Redraw(dpy, win, rot);
+ }
+ }
+ break;
+ default:
+ ; /*no-op*/
+ }
+ }
+ else {
+ /* animate */
+ rot += 1.0;
+ Redraw(dpy, win, rot);
+ }
+ }
+}
+
+
+
+int
+main(int argc, char *argv[])
+{
+ Display *dpy;
+ GLXFBConfig pixmapConfig;
+ XVisualInfo *windowVis;
+ GLXPixmap gp;
+ Window win;
+ GLXContext ctx;
+ Pixmap p;
+
+ dpy = OpenDisplay();
+
+ pixmapConfig = ChoosePixmapFBConfig(dpy);
+ windowVis = ChooseWindowVisual(dpy);
+ win = CreateWindow(dpy, windowVis, 500, 500, "Texture From Pixmap");
+
+ gp = CreatePixmap(dpy, pixmapConfig, 512, 512, &p);
+ DrawPixmapImage(dpy, p, 512, 512);
+
+ ctx = glXCreateContext(dpy, windowVis, NULL, True);
+ if (!ctx) {
+ printf("Couldn't create GLX context\n");
+ exit(1);
+ }
+
+ glXMakeCurrent(dpy, win, ctx);
+
+ BindPixmapTexture(dpy, gp);
+
+ EventLoop(dpy, win);
+
+ return 0;
+}