diff options
Diffstat (limited to 'progs/tests')
| -rw-r--r-- | progs/tests/.gitignore | 9 | ||||
| -rw-r--r-- | progs/tests/Makefile | 55 | ||||
| -rw-r--r-- | progs/tests/bug_texstore_i8.c | 194 | ||||
| -rw-r--r-- | progs/tests/calibrate_rast.c | 395 | ||||
| -rw-r--r-- | progs/tests/copypixrate.c | 63 | ||||
| -rw-r--r-- | progs/tests/descrip.mms | 84 | ||||
| -rw-r--r-- | progs/tests/fillrate.c | 203 | ||||
| -rw-r--r-- | progs/tests/manytex.c | 14 | ||||
| -rw-r--r-- | progs/tests/mipmap_view.c | 251 | ||||
| -rw-r--r-- | progs/tests/quads.c | 258 | ||||
| -rw-r--r-- | progs/tests/stencil_twoside.c | 2 | ||||
| -rw-r--r-- | progs/tests/subtex.c | 223 | ||||
| -rw-r--r-- | progs/tests/zcomp.c | 223 | ||||
| -rw-r--r-- | progs/tests/zdrawpix.c | 192 | 
14 files changed, 2039 insertions, 127 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 86b0cb537b..b96ad9f4b4 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,40 +132,55 @@ 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 $@ + +  floattex: floattex.o readtex.o shaderutil.o @@ -168,7 +191,7 @@ floattex.o: floattex.c readtex.h shaderutil.h  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  	ln -s $(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/stencil_twoside.c b/progs/tests/stencil_twoside.c index be9d9a776a..8826c46fc2 100644 --- a/progs/tests/stencil_twoside.c +++ b/progs/tests/stencil_twoside.c @@ -115,7 +115,6 @@ static void Display( void )     glVertex2f(-1,  1);     glEnd(); -     if (use20syntax) {        stencil_func_separate(GL_FRONT, GL_ALWAYS, 0, ~0);        stencil_func_separate(GL_BACK, GL_ALWAYS, 0, ~0); @@ -279,7 +278,6 @@ static void Init( void )     stencil_op_separate = glutGetProcAddress( "glStencilOpSeparate" );     printf("\nAll 5 squares should be the same color.\n"); -   glEnable( GL_BLEND );  } 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; +} | 
