summaryrefslogtreecommitdiff
path: root/progs/tests
diff options
context:
space:
mode:
Diffstat (limited to 'progs/tests')
-rw-r--r--progs/tests/.gitignore9
-rw-r--r--progs/tests/Makefile55
-rw-r--r--progs/tests/bug_texstore_i8.c194
-rw-r--r--progs/tests/calibrate_rast.c395
-rw-r--r--progs/tests/copypixrate.c63
-rw-r--r--progs/tests/descrip.mms84
-rw-r--r--progs/tests/fillrate.c203
-rw-r--r--progs/tests/manytex.c14
-rw-r--r--progs/tests/mipmap_view.c251
-rw-r--r--progs/tests/quads.c258
-rw-r--r--progs/tests/subtex.c223
-rw-r--r--progs/tests/zcomp.c223
-rw-r--r--progs/tests/zdrawpix.c192
13 files changed, 2039 insertions, 125 deletions
diff --git a/progs/tests/.gitignore b/progs/tests/.gitignore
index 6505c315a6..c5b9e28dab 100644
--- a/progs/tests/.gitignore
+++ b/progs/tests/.gitignore
@@ -18,6 +18,8 @@ bufferobj
bug_3050
bug_3101
bug_3195
+bug_texstore_i8
+calibrate_rast
copypixrate
crossbar
cva
@@ -28,6 +30,7 @@ exactrast
fbotest1
fbotest2
fbotexture
+fillrate
floattex
fog
fogcoord
@@ -40,7 +43,9 @@ invert
jkrahntest
lineclip
manytex
+minmag
mipmap_limits
+mipmap_view
multipal
no_s3tc
packedpixels
@@ -57,6 +62,8 @@ shader_api
stencil_twoside
stencil_wrap
stencilwrap
+stencil_wrap
+subtex
subtexrate
tex1d
texcmp
@@ -78,4 +85,6 @@ vptorus
vpwarpmesh
yuvrect
yuvsquare
+zcomp
+zdrawpix
zreaddraw
diff --git a/progs/tests/Makefile b/progs/tests/Makefile
index cf8e0bfc1e..94473fc59d 100644
--- a/progs/tests/Makefile
+++ b/progs/tests/Makefile
@@ -30,6 +30,8 @@ SOURCES = \
bug_3050.c \
bug_3101.c \
bug_3195.c \
+ bug_texstore_i8.c \
+ calibrate_rast.c \
copypixrate.c \
crossbar.c \
cva.c \
@@ -40,6 +42,7 @@ SOURCES = \
fbotest1.c \
fbotest2.c \
fbotexture.c \
+ fillrate.c \
fog.c \
fogcoord.c \
fptest1.c \
@@ -52,12 +55,14 @@ SOURCES = \
manytex.c \
minmag.c \
mipmap_limits.c \
+ mipmap_view.c \
multipal.c \
no_s3tc.c \
packedpixels.c \
pbo.c \
prog_parameter.c \
projtex.c \
+ quads.c \
random.c \
readrate.c \
seccolor.c \
@@ -66,6 +71,7 @@ SOURCES = \
stencil_twoside.c \
stencilwrap.c \
stencil_wrap.c \
+ subtex \
subtexrate.c \
tex1d.c \
texcompress2.c \
@@ -85,6 +91,8 @@ SOURCES = \
vpwarpmesh.c \
yuvrect.c \
yuvsquare.c \
+ zcomp.c \
+ zdrawpix.c \
zreaddraw.c
PROGS = $(SOURCES:%.c=%)
@@ -109,13 +117,13 @@ clean:
.SUFFIXES: .c
.c:
- $(CC) $(INCLUDES) $(CFLAGS) $(LDFLAGS) $< $(LIBS) -o $@
+ $(APP_CC) $(INCLUDES) $(CFLAGS) $(LDFLAGS) $< $(LIBS) -o $@
.c.o:
- $(CC) -c $(INCLUDES) $(CFLAGS) $(DEFINES) $< -o $@
+ $(APP_CC) -c $(INCLUDES) $(CFLAGS) $(DEFINES) $< -o $@
.S.o:
- $(CC) -c $(INCLUDES) $(CFLAGS) $(DEFINES) $< -o $@
+ $(APP_CC) -c $(INCLUDES) $(CFLAGS) $(DEFINES) $< -o $@
# auto code generation
getprocaddress: getprocaddress.c getproclist.h
@@ -124,43 +132,58 @@ getproclist.h: $(TOP)/src/mesa/glapi/gl_API.xml getprocaddress.c getprocaddress.
python getprocaddress.py > getproclist.h
arraytexture: arraytexture.o readtex.o
- $(CC) $(CFLAGS) arraytexture.o readtex.o $(LIBS) -o $@
+ $(APP_CC) $(CFLAGS) arraytexture.o readtex.o $(LIBS) -o $@
arraytexture.o: arraytexture.c readtex.h
- $(CC) -c $(INCLUDES) $(CFLAGS) $(DEFINES) arraytexture.c -o $@
+ $(APP_CC) -c $(INCLUDES) $(CFLAGS) $(DEFINES) arraytexture.c -o $@
afsmultiarb: afsmultiarb.o readtex.o
- $(CC) $(CFLAGS) $(LDFLAGS) afsmultiarb.o readtex.o $(LIBS) -o $@
+ $(APP_CC) $(CFLAGS) $(LDFLAGS) afsmultiarb.o readtex.o $(LIBS) -o $@
afsmultiarb.o: afsmultiarb.c readtex.h
- $(CC) -c $(INCLUDES) $(CFLAGS) $(DEFINES) afsmultiarb.c -o $@
+ $(APP_CC) -c $(INCLUDES) $(CFLAGS) $(DEFINES) afsmultiarb.c -o $@
drawbuffers: drawbuffers.o
- $(CC) $(CFLAGS) $(LDFLAGS) drawbuffers.o $(LIBS) -o $@
+ $(APP_CC) $(CFLAGS) $(LDFLAGS) drawbuffers.o $(LIBS) -o $@
drawbuffers.o: drawbuffers.c extfuncs.h
- $(CC) -c $(INCLUDES) $(CFLAGS) $(DEFINES) drawbuffers.c -o $@
+ $(APP_CC) -c $(INCLUDES) $(CFLAGS) $(DEFINES) drawbuffers.c -o $@
texrect: texrect.o readtex.o
- $(CC) $(CFLAGS) $(LDFLAGS) texrect.o readtex.o $(LIBS) -o $@
+ $(APP_CC) $(CFLAGS) $(LDFLAGS) texrect.o readtex.o $(LIBS) -o $@
texrect.o: texrect.c readtex.h
- $(CC) -c $(INCLUDES) $(CFLAGS) $(DEFINES) texrect.c -o $@
+ $(APP_CC) -c $(INCLUDES) $(CFLAGS) $(DEFINES) texrect.c -o $@
bug_3195: bug_3195.o readtex.o
- $(CC) $(CFLAGS) $(LDFLAGS) bug_3195.o readtex.o $(LIBS) -o $@
+ $(APP_CC) $(CFLAGS) $(LDFLAGS) bug_3195.o readtex.o $(LIBS) -o $@
bug_3195.o: bug_3195.c readtex.h
- $(CC) -c $(INCLUDES) $(CFLAGS) $(DEFINES) bug_3195.c -o $@
+ $(APP_CC) -c $(INCLUDES) $(CFLAGS) $(DEFINES) bug_3195.c -o $@
invert: invert.o readtex.o
- $(CC) $(CFLAGS) $(LDFLAGS) invert.o readtex.o $(LIBS) -o $@
+ $(APP_CC) $(CFLAGS) $(LDFLAGS) invert.o readtex.o $(LIBS) -o $@
invert.o: invert.c readtex.h
- $(CC) -c $(INCLUDES) $(CFLAGS) $(DEFINES) invert.c -o $@
+ $(APP_CC) -c $(INCLUDES) $(CFLAGS) $(DEFINES) invert.c -o $@
+
+mipmap_view: mipmap_view.o readtex.o
+ $(APP_CC) $(CFLAGS) mipmap_view.o readtex.o $(LIBS) -o $@
+
+mipmap_view.o: mipmap_view.c readtex.h
+ $(APP_CC) -c $(INCLUDES) $(CFLAGS) $(DEFINES) $< -o $@
+
+
+fillrate: fillrate.o readtex.o
+ $(APP_CC) $(CFLAGS) fillrate.o readtex.o $(LIBS) -o $@
+
+fillrate.o: fillrate.c readtex.h
+ $(APP_CC) -c $(INCLUDES) $(CFLAGS) $(DEFINES) $< -o $@
+
+
readtex.o: readtex.c
- $(CC) -c $(INCLUDES) $(CFLAGS) $(DEFINES) readtex.c -o $@
+ $(APP_CC) -c $(INCLUDES) $(CFLAGS) $(DEFINES) readtex.c -o $@
readtex.h: $(TOP)/progs/util/readtex.h
diff --git a/progs/tests/bug_texstore_i8.c b/progs/tests/bug_texstore_i8.c
new file mode 100644
index 0000000000..f8dac210f7
--- /dev/null
+++ b/progs/tests/bug_texstore_i8.c
@@ -0,0 +1,194 @@
+/*
+ * Copyright (c) 1991, 1992, 1993 Silicon Graphics, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and
+ * its documentation for any purpose is hereby granted without fee, provided
+ * that (i) the above copyright notices and this permission notice appear in
+ * all copies of the software and related documentation, and (ii) the name of
+ * Silicon Graphics may not be used in any advertising or
+ * publicity relating to the software without the specific, prior written
+ * permission of Silicon Graphics.
+ *
+ * THE SOFTWARE IS PROVIDED "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 BE LIABLE FOR
+ * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
+ * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+ * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
+ * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
+ * OF THIS SOFTWARE.
+ */
+/*
+ * Based on the trivial/quad-tex-2d program.
+ * Modified by Jakob Bornecrantz <jakob@tungstengraphics.com>
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <GL/glut.h>
+
+static GLenum Target = GL_TEXTURE_2D;
+static GLenum Filter = GL_NEAREST;
+GLenum doubleBuffer;
+static float Rot = 0;
+static int win = 0;
+
+static void Init(void)
+{
+ int internalFormat;
+ int sourceFormat;
+
+ fprintf(stderr, "GL_RENDERER = %s\n", (char *) glGetString(GL_RENDERER));
+ fprintf(stderr, "GL_VERSION = %s\n", (char *) glGetString(GL_VERSION));
+ fprintf(stderr, "GL_VENDOR = %s\n", (char *) glGetString(GL_VENDOR));
+
+ glClearColor(0.0, 0.0, 1.0, 0.0);
+
+#define SIZE 16
+ {
+ GLubyte tex2d[SIZE][SIZE][4];
+ GLint s, t;
+
+ for (s = 0; s < SIZE; s++) {
+ for (t = 0; t < SIZE; t++) {
+ tex2d[t][s][0] = 0xff;
+ tex2d[t][s][1] = 0xff;
+ tex2d[t][s][2] = 0xff;
+ tex2d[t][s][3] = 0xff;
+ }
+ }
+
+ internalFormat = GL_LUMINANCE8;
+ sourceFormat = GL_RGBA;
+
+ glTexImage2D(Target,
+ 0,
+ internalFormat,
+ SIZE, SIZE,
+ 0,
+ sourceFormat,
+ GL_UNSIGNED_BYTE,
+ //GL_UNSIGNED_INT,
+ tex2d);
+
+ glEnable(Target);
+ glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
+ glTexParameterf(Target, GL_TEXTURE_WRAP_R, GL_REPEAT);
+ glTexParameterf(Target, GL_TEXTURE_MIN_FILTER, Filter);
+ glTexParameterf(Target, GL_TEXTURE_MAG_FILTER, Filter);
+ }
+}
+
+static void Reshape(int width, int height)
+{
+ glViewport(0, 0, (GLint)width, (GLint)height);
+ glMatrixMode(GL_PROJECTION);
+ glLoadIdentity();
+#if 0
+ glOrtho(-1.0, 1.0, -1.0, 1.0, -0.5, 1000.0);
+#else
+ glFrustum(-1, 1, -1, 1, 10, 20);
+#endif
+ glMatrixMode(GL_MODELVIEW);
+ glLoadIdentity();
+ glTranslatef(0, 0, -15);
+}
+
+static void Key(unsigned char key, int x, int y)
+{
+ switch (key) {
+ case 'r':
+ Rot += 10.0;
+ break;
+ case 'R':
+ Rot -= 10.0;
+ break;
+ case 27:
+ glutDestroyWindow(win);
+ exit(0);
+ default:
+ return;
+ }
+ glutPostRedisplay();
+}
+
+static void Draw(void)
+{
+ glClear(GL_COLOR_BUFFER_BIT);
+
+ glPushMatrix();
+ glRotatef(Rot, 0, 1, 0);
+
+ glBegin(GL_QUADS);
+ glTexCoord2f(1,0);
+ glVertex3f( 0.9, -0.9, 0.0);
+ glTexCoord2f(1,1);
+ glVertex3f( 0.9, 0.9, 0.0);
+ glTexCoord2f(0,1);
+ glVertex3f(-0.9, 0.9, 0.0);
+ glTexCoord2f(0,0);
+ glVertex3f(-0.9, -0.9, 0.0);
+ glEnd();
+
+ glPopMatrix();
+
+ glFlush();
+
+ if (doubleBuffer) {
+ glutSwapBuffers();
+ }
+}
+
+static GLenum Args(int argc, char **argv)
+{
+ GLint i;
+
+ doubleBuffer = GL_FALSE;
+
+ for (i = 1; i < argc; i++) {
+ if (strcmp(argv[i], "-sb") == 0) {
+ doubleBuffer = GL_FALSE;
+ } else if (strcmp(argv[i], "-db") == 0) {
+ doubleBuffer = GL_TRUE;
+ } else {
+ fprintf(stderr, "%s (Bad option).\n", argv[i]);
+ return GL_FALSE;
+ }
+ }
+ return GL_TRUE;
+}
+
+int main(int argc, char **argv)
+{
+ GLenum type;
+
+ glutInit(&argc, argv);
+
+ if (Args(argc, argv) == GL_FALSE) {
+ exit(1);
+ }
+
+ glutInitWindowPosition(0, 0);
+ glutInitWindowSize(250, 250);
+
+ type = GLUT_RGB;
+ type |= (doubleBuffer) ? GLUT_DOUBLE : GLUT_SINGLE;
+ glutInitDisplayMode(type);
+
+ win = glutCreateWindow("Tex test");
+ if (!win) {
+ exit(1);
+ }
+
+ Init();
+
+ glutReshapeFunc(Reshape);
+ glutKeyboardFunc(Key);
+ glutDisplayFunc(Draw);
+ glutMainLoop();
+ return 0;
+}
diff --git a/progs/tests/calibrate_rast.c b/progs/tests/calibrate_rast.c
new file mode 100644
index 0000000000..37d8ac85e5
--- /dev/null
+++ b/progs/tests/calibrate_rast.c
@@ -0,0 +1,395 @@
+/*
+ * Automatic primitive rasterization precision test.
+ *
+ * Draw prims at various sub-pixel offsets and examine where the quad is
+ * actually drawn.
+ * Check if the range of offsets which paint the right pixels falls within
+ * OpenGL's specification.
+ * In case of failures, report the coordinate bias needed to fix the problem.
+ *
+ * Note that even Mesa/swrast fails some line tests. This is because some
+ * window coordinates wind up as 53.9999 instead of 54, for example. Enabling
+ * the small translation factor below fixes that. Revisit someday...
+ *
+ * Brian Paul
+ * 28 Feb 2008
+ */
+
+
+#include <assert.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <GL/glut.h>
+
+
+static int Width = 100, Height = 100;
+static int Win;
+static float Step = 0.125;
+#if 0
+/* This tiny offset fixes errors in Mesa/Xlib */
+static float Xtrans = 0.5 * 0.125;
+static float Ytrans = 0.5 * 0.125;
+#else
+static float Xtrans = 0.0;
+static float Ytrans = 0.0;
+#endif
+
+
+static void
+PointCalibrate(int xpos, int ypos)
+{
+ GLfloat rgba[4];
+ float x, y;
+ float xmin, ymin, xmax, ymax;
+
+ xmin = ymin = 1000.0;
+ xmax = ymax = -1000.0;
+
+ for (y = -1.0; y <= 1.0; y += Step) {
+ for (x = -1.0; x <= 1.0; x += Step) {
+ glClear(GL_COLOR_BUFFER_BIT);
+ glBegin(GL_POINTS);
+ glVertex2f(xpos + x, ypos + y);
+ glEnd();
+ glReadPixels(xpos, ypos, 1, 1, GL_RGBA, GL_FLOAT, rgba);
+ if (rgba[0] == 1.0 && rgba[1] == 1.0 && rgba[2] == 1.0) {
+ /* hit */
+ if (x < xmin)
+ xmin = x;
+ if (y < ymin)
+ ymin = y;
+ if (x > xmax)
+ xmax = x;
+ if (y > ymax)
+ ymax = y;
+ }
+ }
+ }
+
+ printf("Point at (%2d, %2d) drawn for x in [%6.3f, %6.3f] and y in [%6.3f, %6.3f]\n",
+ xpos, ypos,
+ xpos + xmin, xpos + xmax,
+ ypos + ymin, ypos + ymax);
+
+ if (xmax - xmin != 1.0 - Step) {
+ printf(" => Inconsistant X-axis rasterization!\n");
+ }
+ if (ymax - ymin != 1.0 - Step) {
+ printf(" => Inconsistant Y-axis rasterization!\n");
+ }
+ if (xmin < 0.0) {
+ printf(" => Points should be X biased by about %f\n", xmin);
+ }
+ if (ymin < 0.0) {
+ printf(" => Points should be Y biased by about %f\n", ymin);
+ }
+ if (xmax > 1.0) {
+ printf(" => Points should be X biased by about %f\n", 1.0 - xmax);
+ }
+ if (ymax > 1.0) {
+ printf(" => Points should be Y biased by about %f\n", 1.0 - ymax);
+ }
+
+}
+
+
+/**
+ * XXX Implement VLineCalibrate() someday
+ */
+static void
+HLineCalibrate(int xpos, int ypos, int len)
+{
+ GLfloat rgba[2][4];
+ float x, y;
+ float ymin, ymax;
+ float xmin_left, xmax_left, xmin_right, xmax_right;
+
+ xmin_left = xmin_right = 1000.0;
+ xmax_left = xmax_right = -1000.0;
+ ymin = 1000;
+ ymax = -1000.0;
+
+ /*
+ * First, check vertical positioning of the horizontal line
+ */
+ for (y = -1.0; y <= 1.0; y += Step) {
+ glClear(GL_COLOR_BUFFER_BIT);
+ glBegin(GL_LINES);
+ glVertex2f(xpos, ypos + y);
+ glVertex2f(xpos + len, ypos + y);
+ glEnd();
+
+ glReadPixels(xpos + len / 2, ypos, 1, 1, GL_RGBA, GL_FLOAT, rgba);
+ if (rgba[0][0] == 1.0) {
+ /* hit */
+ if (y < ymin)
+ ymin = y;
+ if (y > ymax)
+ ymax = y;
+ }
+ }
+
+ printf("H-line at Y=%2d drawn for y in [%6.3f, %6.3f]\n",
+ ypos,
+ ypos + ymin, ypos + ymax);
+
+ if (ymax - ymin != 1.0 - Step) {
+ printf(" => Inconsistant Y-axis rasterization!\n");
+ }
+
+ if (ymin > 0.5 ) {
+ printf(" => Lines should be Y biased by about %f\n", ymin - 0.5);
+ }
+
+ if (ymax < 0.5 ) {
+ printf(" => Lines should be Y biased by about %f\n", 0.5 - ymax);
+ }
+
+ /*
+ * Second, check endpoints (for Y at 1/2 pixel)
+ */
+ for (x = -1.0; x <= 1.0; x += Step) {
+ glClear(GL_COLOR_BUFFER_BIT);
+ glBegin(GL_LINES);
+ glVertex2f(xpos + x, ypos + 0.5f);
+ glVertex2f(xpos + x + len, ypos + 0.5f);
+ glEnd();
+
+ /* left end */
+ glReadPixels(xpos - 1, ypos, 2, 1, GL_RGBA, GL_FLOAT, rgba);
+ if (rgba[0][0] == 0.0 && rgba[1][0] == 1.0) {
+ /* hit */
+ if (x < xmin_left)
+ xmin_left = x;
+ if (x > xmax_left)
+ xmax_left = x;
+ }
+
+ /* right end */
+ glReadPixels(xpos + len - 1, ypos, 2, 1, GL_RGBA, GL_FLOAT, rgba);
+ if (rgba[0][0] == 1.0 && rgba[1][0] == 0.0) {
+ /* hit */
+ if (x < xmin_right)
+ xmin_right = x;
+ if (x > xmax_right)
+ xmax_right = x;
+ }
+ }
+
+ printf("H-line [%d..%d) hit left end for x in [%6.3f, %6.3f] "
+ "hit right end for x in [%6.3f, %6.3f]\n",
+ xpos, xpos + len,
+ xpos + xmin_left, xpos + xmax_left,
+ xpos + len + xmin_right, xpos + len + xmax_right);
+
+ if (xmax_left - xmin_left > 1.0 - Step) {
+ printf(" => Inconsistant left-end rasterization!\n");
+ }
+ if (xmax_right - xmin_right > 1.0 - Step) {
+ printf(" => Inconsistant right-end rasterization!\n");
+ }
+
+ if (xmin_left != xmin_right ||
+ xmax_left != xmax_right) {
+ printf(" => Inconsistant length!\n");
+ }
+
+ if (xmin_left < 0.0) {
+ printf(" => Coords should be X biased by about %f\n", xmin_left );
+ }
+ if (xmin_right < 0.0) {
+ printf(" => Coords should be X biased by about %f\n", xmin_right );
+ }
+ if (xmax_left >= 1.0) {
+ printf(" => Coords should be X biased by about %f\n", -xmax_right + 1.0);
+ }
+ if (xmax_right >= 1.0) {
+ printf(" => Coords should be X biased by about %f\n", -xmax_right + 1.0);
+ }
+
+}
+
+
+static void
+QuadCalibrate(int xpos, int ypos, int width, int height)
+{
+ GLfloat rgba1[2][4];
+ GLfloat rgba2[2][4];
+ float x, y;
+ float xmin, ymin, xmax, ymax;
+
+ xmin = ymin = 1000.0;
+ xmax = ymax = -1000.0;
+
+ for (y = -1.0; y <= 1.0; y += Step) {
+ for (x = -1.0; x <= 1.0; x += Step) {
+ glClear(GL_COLOR_BUFFER_BIT);
+ glBegin(GL_QUADS);
+ glVertex2f(xpos + x, ypos + y);
+ glVertex2f(xpos + x + width, ypos + y);
+ glVertex2f(xpos + x + width, ypos + y + height);
+ glVertex2f(xpos + x, ypos + y + height);
+ glEnd();
+
+ /* horizontal measurement */
+ glReadPixels(xpos - 1, ypos + 2, 2, 1, GL_RGBA, GL_FLOAT, rgba1);
+ glReadPixels(xpos + width - 1, ypos + 2, 2, 1, GL_RGBA, GL_FLOAT, rgba2);
+ if (rgba1[0][0] == 0.0 && rgba1[1][0] == 1.0 &&
+ rgba2[0][0] == 1.0 && rgba2[1][0] == 0.0) {
+ if (x < xmin)
+ xmin = x;
+ if (x > xmax)
+ xmax = x;
+ }
+
+ /* vertical measurement */
+ glReadPixels(xpos + 2, ypos - 1, 1, 2, GL_RGBA, GL_FLOAT, rgba1);
+ glReadPixels(xpos + 2, ypos + height - 1, 1, 2, GL_RGBA, GL_FLOAT, rgba2);
+ if (rgba1[0][0] == 0.0 && rgba1[1][0] == 1.0 &&
+ rgba2[0][0] == 1.0 && rgba2[1][0] == 0.0) {
+ if (y < ymin)
+ ymin = y;
+ if (y > ymax)
+ ymax = y;
+ }
+ }
+ }
+
+ printf("Quad at (%2d, %2d)..(%2d, %2d) drawn"
+ " for x in [%6.3f, %6.3f] and y in [%6.3f, %6.3f]\n",
+ xpos, ypos,
+ xpos + width, ypos + height,
+ xpos + xmin, xpos + xmax,
+ ypos + ymin, ypos + ymax);
+
+ if (xmax - xmin != 1.0 - Step) {
+ printf(" => Inconsistant X-axis rasterization/size!\n");
+ }
+ if (ymax - ymin != 1.0 - Step) {
+ printf(" => Inconsistant Y-axis rasterization/size!\n");
+ }
+
+ if (xmin < -0.5) {
+ printf(" => Coords should be X biased by about %f\n", 0.5 + xmin );
+ }
+ if (ymin < -0.5) {
+ printf(" => Coords should be Y biased by about %f\n", 0.5 + ymin);
+ }
+ if (xmax > 0.5) {
+ printf(" => Coords should be X biased by about %f\n", -xmax + 0.5);
+ }
+ if (ymax > 0.5) {
+ printf(" => Coords should be Y biased by about %f\n", -ymax + 0.5);
+ }
+}
+
+
+/**
+ * Misc/disabled code for debugging.
+ */
+static void
+DebugTest(void)
+{
+ glClear(GL_COLOR_BUFFER_BIT);
+ glEnable(GL_BLEND);
+ glBlendFunc(GL_ONE, GL_ONE);
+
+ glColor3f(.5, .5, .5);
+
+ glBegin(GL_LINES);
+ glVertex2f(30, 35.5);
+ glVertex2f(54, 35.5);
+ glVertex2f(54, 35.5);
+ glVertex2f(66, 35.5);
+ glEnd();
+
+ glDisable(GL_BLEND);
+ glColor3f(1,1,1);
+}
+
+
+static void
+Draw(void)
+{
+ glClear(GL_COLOR_BUFFER_BIT);
+
+ glPushMatrix();
+ glTranslatef(Xtrans, Ytrans, 0);
+
+ PointCalibrate(1, 1);
+ PointCalibrate(50, 50);
+ PointCalibrate(28, 17);
+ PointCalibrate(17, 18);
+ printf("\n");
+
+ HLineCalibrate(5, 10, 10);
+ HLineCalibrate(25, 22, 12);
+ HLineCalibrate(54, 33, 12);
+ HLineCalibrate(54+12, 33, 12);
+ printf("\n");
+
+ QuadCalibrate(2, 2, 10, 10);
+ QuadCalibrate(50, 50, 10, 10);
+ QuadCalibrate(28, 17, 12, 12);
+ QuadCalibrate(17, 28, 12, 12);
+
+ (void) DebugTest;
+
+ glPopMatrix();
+
+ glutSwapBuffers();
+}
+
+
+static void
+Reshape(int width, int height)
+{
+ Width = width;
+ Height = height;
+ glViewport(0, 0, width, height);
+ glMatrixMode(GL_PROJECTION);
+ glLoadIdentity();
+ glOrtho(0, width, 0, height, -1, 1);
+ glMatrixMode(GL_MODELVIEW);
+ glLoadIdentity();
+}
+
+
+static void
+Key(unsigned char key, int x, int y)
+{
+ (void) x;
+ (void) y;
+ switch (key) {
+ case 27:
+ glutDestroyWindow(Win);
+ exit(0);
+ break;
+ }
+ glutPostRedisplay();
+}
+
+
+static void
+Init(void)
+{
+ printf("Measurement/callibration for basic prim rasterization...\n");
+ printf("GL_RENDERER: %s\n", (char*) glGetString(GL_RENDERER));
+}
+
+
+int
+main(int argc, char *argv[])
+{
+ glutInit(&argc, argv);
+ glutInitWindowPosition(0, 0);
+ glutInitWindowSize(Width, Height);
+ glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE);
+ Win = glutCreateWindow(argv[0]);
+ glutReshapeFunc(Reshape);
+ glutKeyboardFunc(Key);
+ glutDisplayFunc(Draw);
+ Init();
+ glutMainLoop();
+ return 0;
+}
diff --git a/progs/tests/copypixrate.c b/progs/tests/copypixrate.c
index e9a42a1c8c..142315364c 100644
--- a/progs/tests/copypixrate.c
+++ b/progs/tests/copypixrate.c
@@ -73,6 +73,32 @@ Rand(int max)
}
+static void
+BlitOne(void)
+{
+ int x, y;
+
+ do {
+ x = Rand(WinWidth);
+ y = Rand(WinHeight);
+ } while (x <= ImgWidth && y <= ImgHeight);
+
+#ifdef GL_EXT_framebuffer_blit
+ if (UseBlit)
+ {
+ glBlitFramebufferEXT_func(0, 0, ImgWidth, ImgHeight,
+ x, y, x + ImgWidth, y + ImgHeight,
+ GL_COLOR_BUFFER_BIT, GL_LINEAR);
+ }
+ else
+#endif
+ {
+ glWindowPos2iARB(x, y);
+ glCopyPixels(0, 0, ImgWidth, ImgHeight, GL_COLOR);
+ }
+}
+
+
/**
* Measure glCopyPixels rate
*/
@@ -96,30 +122,14 @@ RunTest(void)
bpp = (r + g + b + a) / 8;
do {
- int x, y;
- x = Rand(WinWidth);
- y = Rand(WinHeight);
+ BlitOne();
- if (x > ImgWidth || y > ImgHeight) {
-#ifdef GL_EXT_framebuffer_blit
- if (UseBlit)
- {
- glBlitFramebufferEXT_func(0, 0, ImgWidth, ImgHeight,
- x, y, x + ImgWidth, y + ImgHeight,
- GL_COLOR_BUFFER_BIT, GL_LINEAR);
- }
- else
-#endif
- {
- glWindowPos2iARB(x, y);
- glCopyPixels(0, 0, ImgWidth, ImgHeight, GL_COLOR);
- }
- glFinish(); /* XXX OK? */
+ if (Buffer == GL_FRONT)
+ glFinish(); /* XXX to view progress */
- iters++;
+ iters++;
- t1 = glutGet(GLUT_ELAPSED_TIME) / 1000.0;
- }
+ t1 = glutGet(GLUT_ELAPSED_TIME) / 1000.0;
} while (t1 - t0 < 5.0);
glDisable(GL_ALPHA_TEST);
@@ -151,8 +161,10 @@ Draw(void)
else
glutSwapBuffers();
+#if 1
printf("exiting\n");
exit(0);
+#endif
}
@@ -175,9 +187,12 @@ Key(unsigned char key, int x, int y)
(void) x;
(void) y;
switch (key) {
- case 27:
- exit(0);
- break;
+ case 'b':
+ BlitOne();
+ break;
+ case 27:
+ exit(0);
+ break;
}
glutPostRedisplay();
}
diff --git a/progs/tests/descrip.mms b/progs/tests/descrip.mms
deleted file mode 100644
index b6ba3e1aeb..0000000000
--- a/progs/tests/descrip.mms
+++ /dev/null
@@ -1,84 +0,0 @@
-# Makefile for GLUT-based demo programs for VMS
-# contributed by Jouk Jansen joukj@hrem.stm.tudelft.nl
-
-
-.first
- define gl [--.include.gl]
-
-.include [--]mms-config.
-
-##### MACROS #####
-
-INCDIR = ([--.include],[-.util])
-CFLAGS = /include=$(INCDIR)/prefix=all/name=(as_is,short)/float=ieee/ieee=denorm
-
-.ifdef SHARE
-GL_LIBS = $(XLIBS)
-.else
-GL_LIBS = [--.lib]libGLUT/l,libMesaGLU/l,libMesaGL/l,$(XLIBS)
-.endif
-
-LIB_DEP = [--.lib]$(GL_LIB) [--.lib]$(GLU_LIB) [--.lib]$(GLUT_LIB)
-
-PROGS = cva.exe,\
- dinoshade.exe,\
- fogcoord.exe,\
- manytex.exe,\
- multipal.exe,\
- projtex.exe,\
- seccolor.exe,\
- sharedtex.exe,\
- texline.exe,\
- texwrap.exe,\
- vptest1.exe,\
- vptest2.exe,\
- vptest3.exe,\
- vptorus.exe,\
- vpwarpmesh.exe
-
-##### RULES #####
-.obj.exe :
- cxxlink $(MMS$TARGET_NAME),$(GL_LIBS)
-
-##### TARGETS #####
-default :
- $(MMS)$(MMSQUALIFIERS) $(PROGS)
-
-clean :
- delete *.obj;*
-
-realclean :
- delete $(PROGS)
- delete *.obj;*
-
-cva.exe : cva.obj $(LIB_DEP)
-dinoshade.exe : dinoshade.obj $(LIB_DEP)
-fogcoord.exe : fogcoord.obj $(LIB_DEP)
-manytex.exe : manytex.obj $(LIB_DEP)
-multipal.exe : multipal.obj $(LIB_DEP)
-projtex.exe : projtex.obj $(LIB_DEP)
-seccolor.exe : seccolor.obj $(LIB_DEP)
-sharedtex.exe : sharedtex.obj $(LIB_DEP)
-texline.exe : texline.obj $(LIB_DEP)
-texwrap.exe : texwrap.obj $(LIB_DEP)
-vptest1.exe : vptest1.obj $(LIB_DEP)
-vptest2.exe : vptest2.obj $(LIB_DEP)
-vptest3.exe : vptest3.obj $(LIB_DEP)
-vptorus.exe : vptorus.obj $(LIB_DEP)
-vpwarpmesh.exe : vpwarpmesh.obj $(LIB_DEP)
-
-cva.obj : cva.c
-dinoshade.obj : dinoshade.c
-fogcoord.obj : fogcoord.c
-manytex.obj : manytex.c
-multipal.obj : multipal.c
-projtex.obj : projtex.c
-seccolor.obj : seccolor.c
-sharedtex.obj : sharedtex.c
-texline.obj : texline.c
-texwrap.obj : texwrap.c
-vptest1.obj : vptest1.c
-vptest2.obj : vptest2.c
-vptest3.obj : vptest3.c
-vptorus.obj : vptorus.c
-vpwarpmesh.obj : vpwarpmesh.c
diff --git a/progs/tests/fillrate.c b/progs/tests/fillrate.c
new file mode 100644
index 0000000000..8fe636c364
--- /dev/null
+++ b/progs/tests/fillrate.c
@@ -0,0 +1,203 @@
+/**
+ * Measure fill rates for basic shading/texturing modes.
+ *
+ * Brian Paul
+ * 1 April 2008
+ */
+
+
+#define GL_GLEXT_PROTOTYPES
+#include <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+#include <GL/glut.h>
+#include "readtex.h"
+
+#define TEXTURE_1_FILE "../images/tile.rgb"
+#define TEXTURE_2_FILE "../images/reflect.rgb"
+
+static int Win;
+static int Width = 1010, Height = 1010;
+static GLuint Textures[2];
+
+
+/**
+ * Draw quad 10 pixels shorter, narrower than window size.
+ */
+static void
+DrawQuad(void)
+{
+ glBegin(GL_POLYGON);
+
+ glColor3f(1.0, 0.5, 0.5);
+ glMultiTexCoord2f(GL_TEXTURE0, 0, 0);
+ glMultiTexCoord2f(GL_TEXTURE1, 0, 0);
+ glVertex2f(5, 5);
+
+ glColor3f(0.5, 1.0, 0.5);
+ glMultiTexCoord2f(GL_TEXTURE0, 1, 0);
+ glMultiTexCoord2f(GL_TEXTURE1, 1, 0);
+ glVertex2f(Width - 5, 5);
+
+ glColor3f(0.5, 0.5, 1.0);
+ glMultiTexCoord2f(GL_TEXTURE0, 1, 1);
+ glMultiTexCoord2f(GL_TEXTURE1, 1, 1);
+ glVertex2f(Width - 5, Height - 5);
+
+ glColor3f(1.0, 0.5, 1.0);
+ glMultiTexCoord2f(GL_TEXTURE0, 0, 1);
+ glMultiTexCoord2f(GL_TEXTURE1, 0, 1);
+ glVertex2f(5, Height - 5);
+
+ glEnd();
+}
+
+
+/**
+ * Compute rate for drawing large quad with given shading/texture state.
+ */
+static void
+RunTest(GLenum shading, GLuint numTextures, GLenum texFilter)
+{
+ const GLdouble minPeriod = 2.0;
+ GLdouble t0, t1;
+ GLdouble pixels, rate;
+ GLint i, iters;
+
+ glActiveTexture(GL_TEXTURE0);
+ if (numTextures > 0) {
+ glBindTexture(GL_TEXTURE_2D, Textures[0]);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, texFilter);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, texFilter);
+ glEnable(GL_TEXTURE_2D);
+ }
+ else {
+ glDisable(GL_TEXTURE_2D);
+ }
+
+ glActiveTexture(GL_TEXTURE1);
+ if (numTextures > 1) {
+ glBindTexture(GL_TEXTURE_2D, Textures[1]);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, texFilter);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, texFilter);
+ glEnable(GL_TEXTURE_2D);
+ }
+ else {
+ glDisable(GL_TEXTURE_2D);
+ }
+
+ glShadeModel(shading);
+
+
+ glFinish();
+
+ iters = 1;
+ do {
+ iters *= 4;
+ t0 = glutGet(GLUT_ELAPSED_TIME) * 0.001;
+ for (i = 0; i < iters; i++) {
+ DrawQuad();
+ }
+ glFinish();
+ t1 = glutGet(GLUT_ELAPSED_TIME) * 0.001;
+ } while (t1 - t0 < minPeriod);
+
+ glutSwapBuffers();
+
+ pixels = (double) iters * (Width - 10) * (Height - 10);
+ rate = pixels / (t1 - t0);
+ rate /= 1000000.0; /* megapixels/second */
+
+ printf("%s ", shading == GL_FLAT ? "GL_FLAT" : "GL_SMOOTH");
+ printf("Textures=%u ", numTextures);
+ printf("Filter=%s: ", texFilter == GL_LINEAR ? "GL_LINEAR" : "GL_NEAREST");
+ printf("%g MPixels/sec\n", rate);
+}
+
+
+static void
+Draw(void)
+{
+ glClear(GL_COLOR_BUFFER_BIT);
+
+ RunTest(GL_FLAT, 0, GL_NEAREST);
+ RunTest(GL_SMOOTH, 0, GL_NEAREST);
+ RunTest(GL_SMOOTH, 1, GL_NEAREST);
+ RunTest(GL_SMOOTH, 1, GL_LINEAR);
+ RunTest(GL_SMOOTH, 2, GL_NEAREST);
+ RunTest(GL_SMOOTH, 2, GL_LINEAR);
+
+ glutSwapBuffers();
+}
+
+
+static void
+Reshape(int width, int height)
+{
+ glViewport(0, 0, width, height);
+ glMatrixMode(GL_PROJECTION);
+ glLoadIdentity();
+ glOrtho(0, width, 0, height, -1, 1);
+ glMatrixMode(GL_MODELVIEW);
+ glLoadIdentity();
+ Width = width;
+ Height = height;
+}
+
+
+static void
+Key(unsigned char key, int x, int y)
+{
+ (void) x;
+ (void) y;
+ switch (key) {
+ case 27:
+ glutDestroyWindow(Win);
+ exit(0);
+ break;
+ }
+ glutPostRedisplay();
+}
+
+
+static void
+Init(void)
+{
+ printf("GL_RENDERER = %s\n", (char *) glGetString(GL_RENDERER));
+
+ glGenTextures(2, Textures);
+
+ glBindTexture(GL_TEXTURE_2D, Textures[0]);
+ glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
+
+ if (!LoadRGBMipmaps(TEXTURE_1_FILE, GL_RGB)) {
+ printf("Error: couldn't load texture image\n");
+ exit(1);
+ }
+
+ glBindTexture(GL_TEXTURE_2D, Textures[1]);
+ glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
+
+ if (!LoadRGBMipmaps(TEXTURE_2_FILE, GL_RGB)) {
+ printf("Error: couldn't load texture image\n");
+ exit(1);
+ }
+
+}
+
+
+int
+main(int argc, char *argv[])
+{
+ glutInit(&argc, argv);
+ glutInitWindowPosition(0, 0);
+ glutInitWindowSize(Width, Height);
+ glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE);
+ Win = glutCreateWindow(argv[0]);
+ glutReshapeFunc(Reshape);
+ glutKeyboardFunc(Key);
+ glutDisplayFunc(Draw);
+ Init();
+ glutMainLoop();
+ return 0;
+}
diff --git a/progs/tests/manytex.c b/progs/tests/manytex.c
index 74b06649f6..83c8676657 100644
--- a/progs/tests/manytex.c
+++ b/progs/tests/manytex.c
@@ -29,6 +29,7 @@ static GLboolean LinearFilter = GL_FALSE;
static GLboolean RandomSize = GL_FALSE;
static GLint Rows, Columns;
static GLint LowPriorityCount = 0;
+static GLint Win;
static void Idle( void )
@@ -127,6 +128,14 @@ static int RandomInt(int min, int max)
}
+static void DeleteTextures(void)
+{
+ glDeleteTextures(NumTextures, TextureID);
+ free(TextureID);
+ TextureID = NULL;
+}
+
+
static void Init( void )
{
@@ -305,9 +314,12 @@ static void Key( unsigned char key, int x, int y )
Zrot += step;
break;
case ' ':
+ DeleteTextures();
Init();
break;
case 27:
+ DeleteTextures();
+ glutDestroyWindow(Win);
exit(0);
break;
}
@@ -323,7 +335,7 @@ int main( int argc, char *argv[] )
glutInitWindowPosition( 0, 0 );
glutInitWindowSize( WinWidth, WinHeight );
glutInitDisplayMode( GLUT_RGB | GLUT_DOUBLE );
- glutCreateWindow(argv[0]);
+ Win = glutCreateWindow(argv[0]);
glutReshapeFunc( Reshape );
glutKeyboardFunc( Key );
glutDisplayFunc( Display );
diff --git a/progs/tests/mipmap_view.c b/progs/tests/mipmap_view.c
new file mode 100644
index 0000000000..54607b8939
--- /dev/null
+++ b/progs/tests/mipmap_view.c
@@ -0,0 +1,251 @@
+/*
+ * Test mipmap generation and lod bias.
+ *
+ * Brian Paul
+ * 17 March 2008
+ */
+
+
+#include <assert.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <math.h>
+#include <GL/glut.h>
+#include <GL/glext.h>
+
+#include "readtex.h"
+
+#define TEXTURE_FILE "../images/arch.rgb"
+
+static int TexWidth = 256, TexHeight = 256;
+static int WinWidth = 1044, WinHeight = 900;
+static GLfloat Bias = 0.0;
+static GLboolean ScaleQuads = GL_FALSE;
+static GLint Win = 0;
+
+
+
+static void
+PrintString(const char *s)
+{
+ while (*s) {
+ glutBitmapCharacter(GLUT_BITMAP_8_BY_13, (int) *s);
+ s++;
+ }
+}
+
+
+static void
+Display(void)
+{
+ int x, y, bias;
+ char str[100];
+ int texWidth = TexWidth, texHeight = TexHeight;
+
+ glClear(GL_COLOR_BUFFER_BIT);
+
+ glMatrixMode(GL_PROJECTION);
+ glLoadIdentity();
+ glOrtho(0, WinWidth, 0, WinHeight, -1, 1);
+ glMatrixMode(GL_MODELVIEW);
+ glLoadIdentity();
+
+ glColor3f(1,1,1);
+
+ y = WinHeight - 300;
+ x = 4;
+
+ for (bias = -1; bias < 11; bias++) {
+
+ if (ScaleQuads) {
+ if (bias > 0) {
+ if (texWidth == 1 && texHeight == 1)
+ break;
+ texWidth = TexWidth >> bias;
+ texHeight = TexHeight >> bias;
+ if (texWidth < 1)
+ texWidth = 1;
+ if (texHeight < 1)
+ texHeight = 1;
+ }
+ glTexEnvf(GL_TEXTURE_FILTER_CONTROL_EXT, GL_TEXTURE_LOD_BIAS_EXT, 0.0);
+ }
+ else {
+ glTexEnvf(GL_TEXTURE_FILTER_CONTROL_EXT, GL_TEXTURE_LOD_BIAS_EXT, bias);
+ }
+
+ glRasterPos2f(x, y + TexHeight + 5);
+ if (ScaleQuads)
+ sprintf(str, "Texture Level %d: %d x %d",
+ (bias < 0 ? 0 : bias),
+ texWidth, texHeight);
+ else
+ sprintf(str, "Texture LOD Bias = %d", bias);
+ PrintString(str);
+
+ glPushMatrix();
+ glTranslatef(x, y, 0);
+
+ glEnable(GL_TEXTURE_2D);
+
+ glBegin(GL_POLYGON);
+ glTexCoord2f(0, 0); glVertex2f(0, 0);
+ glTexCoord2f(1, 0); glVertex2f(texWidth, 0);
+ glTexCoord2f(1, 1); glVertex2f(texWidth, texHeight);
+ glTexCoord2f(0, 1); glVertex2f(0, texHeight);
+ glEnd();
+
+ glPopMatrix();
+
+ glDisable(GL_TEXTURE_2D);
+
+ x += TexWidth + 4;
+ if (x >= WinWidth) {
+ x = 4;
+ y -= 300;
+ }
+ }
+
+ glutSwapBuffers();
+}
+
+
+static void
+Reshape(int width, int height)
+{
+ WinWidth = width;
+ WinHeight = height;
+ glViewport(0, 0, width, height);
+}
+
+
+static void
+Key(unsigned char key, int x, int y)
+{
+ (void) x;
+ (void) y;
+ switch (key) {
+ case 'b':
+ Bias -= 10;
+ break;
+ 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 's':
+ ScaleQuads = !ScaleQuads;
+ break;
+ case 27:
+ glutDestroyWindow(Win);
+ exit(0);
+ break;
+ }
+ glutPostRedisplay();
+}
+
+
+static void
+Init(void)
+{
+ GLfloat maxBias;
+
+ if (!glutExtensionSupported("GL_EXT_texture_lod_bias")) {
+ printf("Sorry, GL_EXT_texture_lod_bias not supported by this renderer.\n");
+ exit(1);
+ }
+
+ if (!glutExtensionSupported("GL_SGIS_generate_mipmap")) {
+ printf("Sorry, GL_SGIS_generate_mipmap not supported by this renderer.\n");
+ exit(1);
+ }
+
+ glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
+
+ if (1) {
+ /* test auto mipmap generation */
+ GLint width, height, i;
+ GLenum format;
+ GLubyte *image = LoadRGBImage(TEXTURE_FILE, &width, &height, &format);
+ if (!image) {
+ printf("Error: could not load texture image %s\n", TEXTURE_FILE);
+ exit(1);
+ }
+ /* resize to TexWidth x TexHeight */
+ if (width != TexWidth || height != TexHeight) {
+ GLubyte *newImage = malloc(TexWidth * TexHeight * 4);
+ gluScaleImage(format, width, height, GL_UNSIGNED_BYTE, image,
+ TexWidth, TexHeight, GL_UNSIGNED_BYTE, newImage);
+ free(image);
+ image = newImage;
+ }
+ printf("Using GL_SGIS_generate_mipmap\n");
+ glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP_SGIS, GL_TRUE);
+ glTexImage2D(GL_TEXTURE_2D, 0, format, TexWidth, TexHeight, 0,
+ format, GL_UNSIGNED_BYTE, image);
+ free(image);
+
+ /* make sure mipmap was really generated correctly */
+ width = TexWidth;
+ height = TexHeight;
+ for (i = 0; i < 9; i++) {
+ GLint w, h;
+ glGetTexLevelParameteriv(GL_TEXTURE_2D, i, GL_TEXTURE_WIDTH, &w);
+ glGetTexLevelParameteriv(GL_TEXTURE_2D, i, GL_TEXTURE_HEIGHT, &h);
+ printf("Level %d size: %d x %d\n", i, w, h);
+ assert(w == width);
+ assert(h == height);
+ width /= 2;
+ height /= 2;
+ }
+ }
+ else {
+ if (LoadRGBMipmaps(TEXTURE_FILE, GL_RGB)) {
+ printf("Using gluBuildMipmaps()\n");
+ }
+ else {
+ printf("Error: could not load texture image %s\n", TEXTURE_FILE);
+ exit(1);
+ }
+ }
+
+
+ /* mipmapping required for this extension */
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
+
+ glGetFloatv(GL_MAX_TEXTURE_LOD_BIAS_EXT, &maxBias);
+
+ printf("GL_RENDERER: %s\n", (char*) glGetString(GL_RENDERER));
+ printf("LOD bias range: [%g, %g]\n", -maxBias, maxBias);
+
+ printf("Press 's' to toggle quad scaling\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(Display);
+ Init();
+ glutMainLoop();
+ return 0;
+}
diff --git a/progs/tests/quads.c b/progs/tests/quads.c
new file mode 100644
index 0000000000..1bf57e6337
--- /dev/null
+++ b/progs/tests/quads.c
@@ -0,0 +1,258 @@
+/**
+ * Draw colored quads.
+ */
+
+
+#define GL_GLEXT_PROTOTYPES
+#include <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+#include <GL/glut.h>
+
+#define NUM_QUADS 20
+
+
+static int Win;
+static GLfloat Xrot = 40, Yrot = 0, Zrot = 0;
+static GLboolean Anim = GL_TRUE;
+static GLuint Vbuffer = 0;
+
+static GLfloat buf[NUM_QUADS * 6 * 4];
+
+static GLboolean SwapBuffers = GL_TRUE;
+
+static GLint Frames = 0, T0 = 0;
+
+
+static void
+Idle(void)
+{
+ Xrot += 3.0;
+ Yrot += 4.0;
+ Zrot += 2.0;
+ glutPostRedisplay();
+}
+
+
+static void
+Draw(void)
+{
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+
+ glPushMatrix();
+ glRotatef(Xrot, 1, 0, 0);
+ glRotatef(Yrot, 0, 1, 0);
+ glRotatef(Zrot, 0, 0, 1);
+
+ glDrawArrays(GL_QUADS, 0, NUM_QUADS*4);
+
+ glPopMatrix();
+
+ if (SwapBuffers)
+ glutSwapBuffers();
+ /*
+ else
+ glFinish();
+ */
+
+ {
+ GLint t = glutGet(GLUT_ELAPSED_TIME);
+ Frames++;
+ if (t - T0 >= 5000) {
+ GLfloat seconds = (t - T0) / 1000.0;
+ GLfloat fps = Frames / seconds;
+ printf("%d frames in %6.3f seconds = %6.3f FPS\n",
+ Frames, seconds, fps);
+ T0 = t;
+ Frames = 0;
+ }
+ }
+}
+
+
+static void
+Reshape(int width, int height)
+{
+ glViewport(0, 0, width, height);
+ glMatrixMode(GL_PROJECTION);
+ glLoadIdentity();
+ glFrustum(-1.0, 1.0, -1.0, 1.0, 5.0, 25.0);
+ glMatrixMode(GL_MODELVIEW);
+ glLoadIdentity();
+ glTranslatef(0.0, 0.0, -8.0);
+}
+
+
+static void
+Key(unsigned char key, int x, int y)
+{
+ const GLfloat step = 3.0;
+ (void) x;
+ (void) y;
+ switch (key) {
+ case 's':
+ SwapBuffers = !SwapBuffers;
+ break;
+ case 'a':
+ Anim = !Anim;
+ if (Anim)
+ glutIdleFunc(Idle);
+ else
+ glutIdleFunc(NULL);
+ break;
+ case 'z':
+ Zrot -= step;
+ break;
+ case 'Z':
+ Zrot += step;
+ break;
+ case 27:
+ glutDestroyWindow(Win);
+ exit(0);
+ break;
+ }
+ glutPostRedisplay();
+}
+
+
+static void
+SpecialKey(int key, int x, int y)
+{
+ const GLfloat step = 3.0;
+ (void) x;
+ (void) y;
+ switch (key) {
+ case GLUT_KEY_UP:
+ Xrot -= step;
+ break;
+ case GLUT_KEY_DOWN:
+ Xrot += step;
+ break;
+ case GLUT_KEY_LEFT:
+ Yrot -= step;
+ break;
+ case GLUT_KEY_RIGHT:
+ Yrot += step;
+ break;
+ }
+ glutPostRedisplay();
+}
+
+
+static void
+quad(float x, float y, float z, float *v)
+{
+ int k = 0;
+
+ /* color */
+ v[k++] = x * 0.5 + 0.5;
+ v[k++] = y * 0.5 + 0.5;
+ v[k++] = z * 0.5 + 0.5;
+ /* vert */
+ v[k++] = x;
+ v[k++] = y;
+ v[k++] = z;
+
+ /* color */
+ v[k++] = -x * 0.5 + 0.5;
+ v[k++] = -y * 0.5 + 0.5;
+ v[k++] = z * 0.5 + 0.5;
+ /* vert */
+ v[k++] = -x;
+ v[k++] = -y;
+ v[k++] = z;
+
+ /* color */
+ v[k++] = -x * 0.5 + 0.5;
+ v[k++] = -y * 0.5 + 0.5;
+ v[k++] = -z * 0.5 + 0.5;
+ /* vert */
+ v[k++] = -x;
+ v[k++] = -y;
+ v[k++] = -z;
+
+ /* color */
+ v[k++] = x * 0.5 + 0.5;
+ v[k++] = y * 0.5 + 0.5;
+ v[k++] = -z * 0.5 + 0.5;
+ /* vert */
+ v[k++] = x;
+ v[k++] = y;
+ v[k++] = -z;
+}
+
+static void
+gen_quads(GLfloat *buf)
+{
+ float *v = buf;
+ float r = 1.0;
+ int i;
+
+ for (i = 0; i < NUM_QUADS; i++) {
+ float angle = i / (float) NUM_QUADS * M_PI;
+ float x = r * cos(angle);
+ float y = r * sin(angle);
+ float z = 1.10;
+ quad(x, y, z, v);
+ v += 24;
+ }
+
+ if (0) {
+ float *p = buf;
+ for (i = 0; i < NUM_QUADS * 4 * 2; i++) {
+ printf("%d: %f %f %f\n", i, p[0], p[1], p[2]);
+ p += 3;
+ }
+ }
+}
+
+
+static void
+Init(void)
+{
+ int bytes = NUM_QUADS * 4 * 2 * 3 * sizeof(float);
+ GLfloat *f;
+
+#if 1
+ glGenBuffers(1, &Vbuffer);
+ glBindBuffer(GL_ARRAY_BUFFER, Vbuffer);
+ glBufferData(GL_ARRAY_BUFFER_ARB, bytes, NULL, GL_STATIC_DRAW_ARB);
+ f = (float *) glMapBuffer(GL_ARRAY_BUFFER_ARB, GL_WRITE_ONLY_ARB);
+ gen_quads(f);
+ glUnmapBuffer(GL_ARRAY_BUFFER_ARB);
+ glColorPointer(3, GL_FLOAT, 6*sizeof(float), (void *) 0);
+ glVertexPointer(3, GL_FLOAT, 6*sizeof(float), (void *) 12);
+#else
+ f = buf;
+ gen_quads(f);
+ glColorPointer(3, GL_FLOAT, 6*sizeof(float), buf);
+ glVertexPointer(3, GL_FLOAT, 6*sizeof(float), buf + 3);
+#endif
+
+ glEnableClientState(GL_COLOR_ARRAY);
+ glEnableClientState(GL_VERTEX_ARRAY);
+
+ glEnable(GL_DEPTH_TEST);
+
+ glClearColor(0.5, 0.5, 0.5, 0.0);
+}
+
+
+int
+main(int argc, char *argv[])
+{
+ glutInit(&argc, argv);
+ glutInitWindowPosition(0, 0);
+ glutInitWindowSize(600, 600);
+ glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
+ Win = glutCreateWindow(argv[0]);
+ glutReshapeFunc(Reshape);
+ glutKeyboardFunc(Key);
+ glutSpecialFunc(SpecialKey);
+ glutDisplayFunc(Draw);
+ if (Anim)
+ glutIdleFunc(Idle);
+ Init();
+ glutMainLoop();
+ return 0;
+}
diff --git a/progs/tests/subtex.c b/progs/tests/subtex.c
new file mode 100644
index 0000000000..81ceb085aa
--- /dev/null
+++ b/progs/tests/subtex.c
@@ -0,0 +1,223 @@
+/*
+ * Test glTexSubImage mid-way through a frame.
+ *
+ * The same texture is used for both quads but it gets redefined
+ * with glTexSubImage (or glTexImage) after the first quad.
+ */
+
+
+#include <assert.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include "GL/glut.h"
+
+static GLuint Window = 0;
+static GLboolean Anim = GL_FALSE;
+static GLfloat Angle = 0.0f;
+
+
+
+static void
+first_texture(void)
+{
+ static int width=8, height=8;
+ static GLubyte tex1[] = {
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 1, 0, 0, 0,
+ 0, 0, 0, 1, 1, 0, 0, 0,
+ 0, 0, 0, 0, 1, 0, 0, 0,
+ 0, 0, 0, 0, 1, 0, 0, 0,
+ 0, 0, 0, 0, 1, 0, 0, 0,
+ 0, 0, 0, 1, 1, 1, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0 };
+
+ GLubyte tex[64][3];
+ GLint i, j;
+
+ /* red on white */
+ for (i=0;i<height;i++) {
+ for (j=0;j<width;j++) {
+ int p = i*width+j;
+ if (tex1[(height-i-1)*width+j]) {
+ tex[p][0] = 255; tex[p][1] = 0; tex[p][2] = 0;
+ }
+ else {
+ tex[p][0] = 255; tex[p][1] = 255; tex[p][2] = 255;
+ }
+ }
+ }
+
+ glTexImage2D( GL_TEXTURE_2D, 0, 3, width, height, 0,
+ GL_RGB, GL_UNSIGNED_BYTE, tex );
+}
+
+
+static void
+second_texture(void)
+{
+ static int width=8, height=8;
+
+ static GLubyte tex2[] = {
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 2, 2, 0, 0, 0,
+ 0, 0, 2, 0, 0, 2, 0, 0,
+ 0, 0, 0, 0, 0, 2, 0, 0,
+ 0, 0, 0, 0, 2, 0, 0, 0,
+ 0, 0, 0, 2, 0, 0, 0, 0,
+ 0, 0, 2, 2, 2, 2, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0 };
+
+ GLubyte tex[64][3];
+ GLint i, j;
+
+ /* green on blue */
+ for (i=0;i<height;i++) {
+ for (j=0;j<width;j++) {
+ int p = i*width+j;
+ if (tex2[(height-i-1)*width+j]) {
+ tex[p][0] = 0; tex[p][1] = 255; tex[p][2] = 0;
+ }
+ else {
+ tex[p][0] = 0; tex[p][1] = 0; tex[p][2] = 255;
+ }
+ }
+ }
+#if 0
+ glTexImage2D( GL_TEXTURE_2D, 0, 3, width, height, 0,
+ GL_RGB, GL_UNSIGNED_BYTE, tex );
+#else
+ glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width, height,
+ GL_RGB, GL_UNSIGNED_BYTE, tex );
+#endif
+}
+
+
+
+static void draw( void )
+{
+ glClear( GL_COLOR_BUFFER_BIT );
+
+ glColor3f( 1.0, 1.0, 1.0 );
+
+ /* draw first polygon */
+ glPushMatrix();
+ glTranslatef( -1.0, 0.0, 0.0 );
+ glRotatef( Angle, 0.0, 0.0, 1.0 );
+
+ first_texture();
+
+ glBegin( GL_POLYGON );
+ glTexCoord2f( 0.0, 0.0 ); glVertex2f( -1.0, -1.0 );
+ glTexCoord2f( 1.0, 0.0 ); glVertex2f( 1.0, -1.0 );
+ glTexCoord2f( 1.0, 1.0 ); glVertex2f( 1.0, 1.0 );
+ glTexCoord2f( 0.0, 1.0 ); glVertex2f( -1.0, 1.0 );
+ glEnd();
+ glPopMatrix();
+
+ /* draw second polygon */
+ glPushMatrix();
+ glTranslatef( 1.0, 0.0, 0.0 );
+ glRotatef( Angle-90.0, 0.0, 1.0, 0.0 );
+
+ second_texture();
+
+ glBegin( GL_POLYGON );
+ glTexCoord2f( 0.0, 0.0 ); glVertex2f( -1.0, -1.0 );
+ glTexCoord2f( 1.0, 0.0 ); glVertex2f( 1.0, -1.0 );
+ glTexCoord2f( 1.0, 1.0 ); glVertex2f( 1.0, 1.0 );
+ glTexCoord2f( 0.0, 1.0 ); glVertex2f( -1.0, 1.0 );
+ glEnd();
+ glPopMatrix();
+
+ glutSwapBuffers();
+}
+
+
+
+static void idle( void )
+{
+ static double t0 = -1.;
+ double dt, t = glutGet(GLUT_ELAPSED_TIME) / 1000.0;
+ if (t0 < 0.0)
+ t0 = t;
+ dt = t - t0;
+ t0 = t;
+ Angle += 120.0*dt;
+ glutPostRedisplay();
+}
+
+
+
+/* change view Angle, exit upon ESC */
+static void key(unsigned char k, int x, int y)
+{
+ (void) x;
+ (void) y;
+ switch (k) {
+ case 'a':
+ Anim = !Anim;
+ if (Anim)
+ glutIdleFunc( idle );
+ else
+ glutIdleFunc( NULL );
+ break;
+ case 27:
+ glutDestroyWindow(Window);
+ exit(0);
+ }
+}
+
+
+
+/* new window size or exposure */
+static void reshape( int width, int height )
+{
+ glViewport(0, 0, (GLint)width, (GLint)height);
+ glMatrixMode(GL_PROJECTION);
+ glLoadIdentity();
+ /* glOrtho( -3.0, 3.0, -3.0, 3.0, -10.0, 10.0 );*/
+ glFrustum( -2.0, 2.0, -2.0, 2.0, 6.0, 20.0 );
+ glMatrixMode(GL_MODELVIEW);
+ glLoadIdentity();
+ glTranslatef( 0.0, 0.0, -8.0 );
+}
+
+
+static void init( void )
+{
+ /* Setup texturing */
+ glEnable( GL_TEXTURE_2D );
+ glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL );
+
+
+ glBindTexture( GL_TEXTURE_2D, 0 );
+ glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
+ glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
+ glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT );
+ glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT );
+}
+
+
+
+int main( int argc, char *argv[] )
+{
+ glutInit(&argc, argv);
+ glutInitWindowPosition(0, 0);
+ glutInitWindowSize(300, 300);
+ glutInitDisplayMode( GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE );
+
+ Window = glutCreateWindow("Texture Objects");
+ if (!Window) {
+ exit(1);
+ }
+
+ init();
+
+ glutReshapeFunc( reshape );
+ glutKeyboardFunc( key );
+ if (Anim)
+ glutIdleFunc( idle );
+ glutDisplayFunc( draw );
+ glutMainLoop();
+ return 0;
+}
diff --git a/progs/tests/zcomp.c b/progs/tests/zcomp.c
new file mode 100644
index 0000000000..b53079d07f
--- /dev/null
+++ b/progs/tests/zcomp.c
@@ -0,0 +1,223 @@
+/**
+ * Test Z compositing with glDrawPixels(GL_DEPTH_COMPONENT) and stencil test.
+ */
+
+#define GL_GLEXT_PROTOTYPES
+#include <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+#include <GL/glut.h>
+#include "../util/showbuffer.c"
+
+
+static int Win;
+static GLfloat Xrot = 0, Yrot = 0, Zpos = 6;
+static GLboolean Anim = GL_FALSE;
+
+static int Width = 400, Height = 200;
+static GLfloat *Zimg;
+static GLubyte *Cimg;
+static GLboolean showZ = 0;
+
+
+static void
+Idle(void)
+{
+ Xrot += 3.0;
+ Yrot += 4.0;
+ glutPostRedisplay();
+}
+
+
+/**
+ * Draw first object, save color+Z images
+ */
+static void
+DrawFirst(void)
+{
+ static const GLfloat red[4] = { 1.0, 0.0, 0.0, 0.0 };
+
+ glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, red);
+
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+
+ glPushMatrix();
+ glTranslatef(-1, 0, 0);
+ glRotatef(45 + Xrot, 1, 0, 0);
+
+ glutSolidTorus(0.75, 2.0, 10, 20);
+
+ glPopMatrix();
+
+ glReadPixels(0, 0, Width, Height, GL_DEPTH_COMPONENT, GL_FLOAT, Zimg);
+ glReadPixels(0, 0, Width, Height, GL_RGBA, GL_UNSIGNED_BYTE, Cimg);
+}
+
+
+/**
+ * Draw second object.
+ */
+static void
+DrawSecond(void)
+{
+ static const GLfloat blue[4] = { 0.0, 0.0, 1.0, 0.0 };
+
+ glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, blue);
+
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
+
+ glPushMatrix();
+ glTranslatef(+1, 0, 0);
+ glRotatef(-45 + Xrot, 1, 0, 0);
+
+ glutSolidTorus(0.75, 2.0, 10, 20);
+
+ glPopMatrix();
+}
+
+
+/**
+ * Composite first/saved image over second rendering.
+ */
+static void
+Composite(void)
+{
+ glWindowPos2i(0, 0);
+
+ /* Draw Z values, set stencil where Z test passes */
+ glEnable(GL_STENCIL_TEST);
+ glStencilFunc(GL_ALWAYS, 1, ~0);
+ glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
+ glColorMask(0,0,0,0);
+ glDrawPixels(Width, Height, GL_DEPTH_COMPONENT, GL_FLOAT, Zimg);
+ glColorMask(1,1,1,1);
+
+ /* Draw color where stencil==1 */
+ glStencilFunc(GL_EQUAL, 1, ~0);
+ glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
+ glDisable(GL_DEPTH_TEST);
+ glDrawPixels(Width, Height, GL_RGBA, GL_UNSIGNED_BYTE, Cimg);
+ glEnable(GL_DEPTH_TEST);
+
+ glDisable(GL_STENCIL_TEST);
+}
+
+
+static void
+Draw(void)
+{
+ DrawFirst();
+ DrawSecond();
+ Composite();
+ glutSwapBuffers();
+}
+
+
+static void
+Reshape(int width, int height)
+{
+ GLfloat ar = (float) width / height;
+ glViewport(0, 0, width, height);
+ glMatrixMode(GL_PROJECTION);
+ glLoadIdentity();
+ glFrustum(-ar, ar, -1.0, 1.0, 5.0, 30.0);
+ glMatrixMode(GL_MODELVIEW);
+ glLoadIdentity();
+ glTranslatef(0.0, 0.0, -15.0);
+
+ Width = width;
+ Height = height;
+
+ if (Zimg)
+ free(Zimg);
+ if (Cimg)
+ free(Cimg);
+ Zimg = (float *) malloc(width * height * 4);
+ Cimg = (GLubyte *) malloc(width * height * 4);
+}
+
+
+static void
+Key(unsigned char key, int x, int y)
+{
+ const GLfloat step = 1.0;
+ (void) x;
+ (void) y;
+ switch (key) {
+ case 'a':
+ Anim = !Anim;
+ if (Anim)
+ glutIdleFunc(Idle);
+ else
+ glutIdleFunc(NULL);
+ break;
+ case 'd':
+ showZ = !showZ;
+ break;
+ case 'z':
+ Zpos -= step;
+ break;
+ case 'Z':
+ Zpos += step;
+ break;
+ case 27:
+ glutDestroyWindow(Win);
+ exit(0);
+ break;
+ }
+ glutPostRedisplay();
+}
+
+
+static void
+SpecialKey(int key, int x, int y)
+{
+ const GLfloat step = 3.0;
+ (void) x;
+ (void) y;
+ switch (key) {
+ case GLUT_KEY_UP:
+ Xrot -= step;
+ break;
+ case GLUT_KEY_DOWN:
+ Xrot += step;
+ break;
+ case GLUT_KEY_LEFT:
+ Yrot -= step;
+ break;
+ case GLUT_KEY_RIGHT:
+ Yrot += step;
+ break;
+ }
+ glutPostRedisplay();
+}
+
+
+static void
+Init(void)
+{
+ /* setup lighting, etc */
+ glEnable(GL_DEPTH_TEST);
+ glEnable(GL_LIGHTING);
+ glEnable(GL_LIGHT0);
+}
+
+
+int
+main(int argc, char *argv[])
+{
+ glutInit(&argc, argv);
+ glutInitWindowPosition(0, 0);
+ glutInitWindowSize(Width, Height);
+ glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH | GLUT_STENCIL);
+ Win = glutCreateWindow(argv[0]);
+ glutReshapeFunc(Reshape);
+ glutKeyboardFunc(Key);
+ glutSpecialFunc(SpecialKey);
+ glutDisplayFunc(Draw);
+ if (Anim)
+ glutIdleFunc(Idle);
+ Init();
+ glutMainLoop();
+ return 0;
+}
diff --git a/progs/tests/zdrawpix.c b/progs/tests/zdrawpix.c
new file mode 100644
index 0000000000..dd222e7dd0
--- /dev/null
+++ b/progs/tests/zdrawpix.c
@@ -0,0 +1,192 @@
+/**
+ * Test glDrawPixels(GL_DEPTH_COMPONENT)
+ *
+ * We load a window-sized buffer of Z values so that Z=1 at the top and
+ * Z=0 at the bottom (and interpolate between).
+ * We draw that image into the Z buffer, then draw an ordinary cube.
+ * The bottom part of the cube should be "clipped" where the cube fails
+ * the Z test.
+ *
+ * Press 'd' to view the Z buffer as a grayscale image.
+ */
+
+#define GL_GLEXT_PROTOTYPES
+#include <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+#include <GL/glut.h>
+#include "../util/showbuffer.c"
+
+
+static int Win;
+static GLfloat Xrot = 50, Yrot = 40, Zpos = 6;
+static GLboolean Anim = GL_FALSE;
+
+static int Width = 200, Height = 200;
+static GLfloat *z;
+static GLboolean showZ = 0;
+
+
+static void
+Idle(void)
+{
+ Xrot += 3.0;
+ Yrot += 4.0;
+ glutPostRedisplay();
+}
+
+
+static void
+Draw(void)
+{
+ glClearColor(0, 0, 0.5, 0);
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+
+#if 1
+ glColor3f(1, 0, 0);
+ glWindowPos2i(0,0);
+ glColorMask(0,0,0,0);
+ glDrawPixels(Width, Height, GL_DEPTH_COMPONENT, GL_FLOAT, z);
+#elif 0
+ glPushMatrix();
+ glTranslatef(-0.75, 0, Zpos);
+ glutSolidSphere(1.0, 20, 10);
+ glPopMatrix();
+#endif
+ glColorMask(1,1,1,1);
+
+ /* draw cube */
+ glPushMatrix();
+ glTranslatef(0, 0, Zpos);
+ glRotatef(Xrot, 1, 0, 0);
+ glRotatef(Yrot, 0, 1, 0);
+ glutSolidCube(2.0);
+ glPopMatrix();
+
+#if 0
+ /* drawpixels after cube */
+ glColor3f(1, 0, 0);
+ glWindowPos2i(0,0);
+ //glColorMask(0,0,0,0);
+ glDrawPixels(Width, Height, GL_DEPTH_COMPONENT, GL_FLOAT, z);
+#endif
+
+ if (showZ) {
+ ShowDepthBuffer(Width, Height, 0.0, 1.0);
+ }
+
+ glutSwapBuffers();
+}
+
+
+static void
+Reshape(int width, int height)
+{
+ glViewport(0, 0, width, height);
+ glMatrixMode(GL_PROJECTION);
+ glLoadIdentity();
+ glFrustum(-1.0, 1.0, -1.0, 1.0, 5.0, 30.0);
+ glMatrixMode(GL_MODELVIEW);
+ glLoadIdentity();
+ glTranslatef(0.0, 0.0, -15.0);
+
+ Width = width;
+ Height = height;
+
+ z = (float *) malloc(width * height * 4);
+ {
+ int i, j, k = 0;
+ for (i = 0; i < height; i++) {
+ float zval = (float) i / (height - 1);
+ for (j = 0; j < width; j++) {
+ z[k++] = zval;
+ }
+ }
+ }
+}
+
+
+static void
+Key(unsigned char key, int x, int y)
+{
+ const GLfloat step = 1.0;
+ (void) x;
+ (void) y;
+ switch (key) {
+ case 'a':
+ Anim = !Anim;
+ if (Anim)
+ glutIdleFunc(Idle);
+ else
+ glutIdleFunc(NULL);
+ break;
+ case 'd':
+ showZ = !showZ;
+ break;
+ case 'z':
+ Zpos -= step;
+ break;
+ case 'Z':
+ Zpos += step;
+ break;
+ case 27:
+ glutDestroyWindow(Win);
+ exit(0);
+ break;
+ }
+ glutPostRedisplay();
+}
+
+
+static void
+SpecialKey(int key, int x, int y)
+{
+ const GLfloat step = 3.0;
+ (void) x;
+ (void) y;
+ switch (key) {
+ case GLUT_KEY_UP:
+ Xrot -= step;
+ break;
+ case GLUT_KEY_DOWN:
+ Xrot += step;
+ break;
+ case GLUT_KEY_LEFT:
+ Yrot -= step;
+ break;
+ case GLUT_KEY_RIGHT:
+ Yrot += step;
+ break;
+ }
+ glutPostRedisplay();
+}
+
+
+static void
+Init(void)
+{
+ /* setup lighting, etc */
+ glEnable(GL_DEPTH_TEST);
+ glEnable(GL_LIGHTING);
+ glEnable(GL_LIGHT0);
+}
+
+
+int
+main(int argc, char *argv[])
+{
+ glutInit(&argc, argv);
+ glutInitWindowPosition(0, 0);
+ glutInitWindowSize(400, 400);
+ glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
+ Win = glutCreateWindow(argv[0]);
+ glutReshapeFunc(Reshape);
+ glutKeyboardFunc(Key);
+ glutSpecialFunc(SpecialKey);
+ glutDisplayFunc(Draw);
+ if (Anim)
+ glutIdleFunc(Idle);
+ Init();
+ glutMainLoop();
+ return 0;
+}