demos: added glsl/texaaline.c program and overhaul the Makefile
authorBrian Paul <brianp@vmware.com>
Sat, 18 Apr 2009 20:18:59 +0000 (14:18 -0600)
committerBrian Paul <brianp@vmware.com>
Sat, 18 Apr 2009 20:18:59 +0000 (14:18 -0600)
progs/glsl/Makefile
progs/glsl/texaaline.c [new file with mode: 0644]

index 8e61ab690b4a25793dfe2ee10c9f4c4fc458c773..71db895d1d94aed2085871376a29dacde1d759f7 100644 (file)
@@ -5,48 +5,69 @@ include $(TOP)/configs/current
 
 INCDIR = $(TOP)/include
 
-LIB_DEP = $(TOP)/$(LIB_DIR)/$(GL_LIB_NAME) $(TOP)/$(LIB_DIR)/$(GLU_LIB_NAME) $(TOP)/$(LIB_DIR)/$(GLUT_LIB_NAME)
+LIB_DEP = \
+       $(TOP)/$(LIB_DIR)/$(GL_LIB_NAME) \
+       $(TOP)/$(LIB_DIR)/$(GLU_LIB_NAME) \
+       $(TOP)/$(LIB_DIR)/$(GLUT_LIB_NAME)
 
 LIBS = -L$(TOP)/$(LIB_DIR) -l$(GLUT_LIB) -l$(GLU_LIB) -l$(GL_LIB) $(APP_LIB_DEPS)
 
-PROGS = \
-       array \
-       bitmap \
-       brick \
-       bump \
-       convolutions \
-       deriv \
-       identity \
-       fragcoord \
-       linktest \
-       mandelbrot \
-       multinoise \
-       multitex \
-       noise \
-       noise2 \
-       points \
-       pointcoord \
-       samplers \
-       samplers_array \
-       shadow_sampler \
-       skinning \
-       texdemo1 \
-       toyball \
-       twoside \
-       trirast \
-       vert-or-frag-only \
-       vert-tex
+INCLUDE_DIRS = -I$(TOP)/progs/util
+
+DEMO_SOURCES = \
+       array.c \
+       bitmap.c \
+       brick.c \
+       bump.c \
+       convolutions.c \
+       deriv.c \
+       fragcoord.c \
+       identity.c \
+       linktest.c \
+       mandelbrot.c \
+       multinoise.c \
+       multitex.c \
+       noise.c \
+       noise2.c \
+       pointcoord.c \
+       points.c \
+       samplers.c \
+       shadow_sampler.c \
+       skinning.c \
+       texaaline.c \
+       texdemo1.c \
+       toyball.c \
+       trirast.c \
+       twoside.c \
+       vert-or-frag-only.c \
+       vert-tex.c
+
+UTIL_HEADERS = \
+       extfuncs.h \
+       shaderutil.h \
+       readtex.h
+
+UTIL_SOURCES = \
+       shaderutil.c \
+       readtex.c
+
+UTIL_OBJS = $(UTIL_SOURCES:.c=.o)
+
+
+PROGS = $(DEMO_SOURCES:%.c=%)
+
 
 
 ##### RULES #####
 
-.SUFFIXES:
-.SUFFIXES: .c
+# make .o file from .c file:
+.c.o:
+       $(APP_CC) -c -I$(INCDIR) $(CFLAGS) $< -o $@
 
 
-# make executable from .c file:
-.c: $(LIB_DEP)
-       $(APP_CC) -I$(INCDIR) $(CFLAGS) $(LDFLAGS) $< $(LIBS) -o $@
+# make executable from .o files
+.o:
+       $(APP_CC) $(INCLUDES) $(CFLAGS) $(LDFLAGS) $< $(UTIL_OBJS) $(LIBS) -o $@
 
 
 ##### TARGETS #####
@@ -54,202 +75,163 @@ PROGS = \
 default: $(PROGS)
 
 
+clean:
+       -rm -f $(PROGS)
+       -rm -f *.o *~
+       -rm -f extfuncs.h
+       -rm -f shaderutil.*
+
+
 
 ##### Extra dependencies
 
-extfuncs.h:  $(TOP)/progs/util/extfuncs.h
-       cp $< .
+extfuncs.h:
+       cp $(TOP)/progs/util/extfuncs.h .
 
+readtex.c:
+       cp $(TOP)/progs/util/readtex.c .
 
-readtex.c: $(TOP)/progs/util/readtex.c
-       cp $< .
+readtex.h:
+       cp $(TOP)/progs/util/readtex.h .
 
-readtex.h: $(TOP)/progs/util/readtex.h
-       cp $< .
+shaderutil.c:
+       cp $(TOP)/progs/util/shaderutil.c .
 
-readtex.o: readtex.c readtex.h
-       $(APP_CC) -c -I$(INCDIR) $(CFLAGS) readtex.c
+shaderutil.h:
+       cp $(TOP)/progs/util/shaderutil.h .
 
 
-shaderutil.c: $(TOP)/progs/util/shaderutil.c
-       cp $< .
 
-shaderutil.h: $(TOP)/progs/util/shaderutil.h
-       cp $< .
+array.o: $(UTIL_HEADERS)
 
-shaderutil.o: shaderutil.c shaderutil.h
-       $(APP_CC) -c -I$(INCDIR) $(CFLAGS) shaderutil.c
+array: array.o  $(UTIL_OBJS)
 
 
+bitmap.o: $(UTIL_HEADERS)
 
-array.o: array.c extfuncs.h shaderutil.h
-       $(APP_CC) -c -I$(INCDIR) $(CFLAGS) array.c
+bitmap: bitmap.o $(UTIL_OBJS)
 
-array: array.o shaderutil.o
-       $(APP_CC) -I$(INCDIR) $(CFLAGS) $(LDFLAGS) array.o shaderutil.o $(LIBS) -o $@
 
+brick.o: $(UTIL_HEADERS)
 
-bitmap.o: bitmap.c extfuncs.h shaderutil.h
-       $(APP_CC) -c -I$(INCDIR) $(CFLAGS) bitmap.c
+brick: brick.o $(UTIL_OBJS)
 
-bitmap: bitmap.o shaderutil.o
-       $(APP_CC) -I$(INCDIR) $(CFLAGS) $(LDFLAGS) bitmap.o shaderutil.o $(LIBS) -o $@
 
+bump.o: $(UTIL_HEADERS)
 
-brick.o: brick.c extfuncs.h shaderutil.h
-       $(APP_CC) -c -I$(INCDIR) $(CFLAGS) brick.c
+bump: bump.o $(UTIL_OBJS)
 
-brick: brick.o shaderutil.o
-       $(APP_CC) -I$(INCDIR) $(CFLAGS) $(LDFLAGS) brick.o shaderutil.o $(LIBS) -o $@
 
+convolutions.o: $(UTIL_HEADERS)
 
-bump.o: bump.c extfuncs.h shaderutil.h
-       $(APP_CC) -c -I$(INCDIR) $(CFLAGS) bump.c
+convolutions: convolutions.o $(UTIL_OBJS)
 
-bump: bump.o shaderutil.o
-       $(APP_CC) -I$(INCDIR) $(CFLAGS) $(LDFLAGS) bump.o shaderutil.o $(LIBS) -o $@
 
+deriv.o: deriv.c $(UTIL_HEADERS)
 
-convolutions.o: convolutions.c readtex.h
-       $(APP_CC) -c -I$(INCDIR) $(CFLAGS) convolutions.c
+deriv: deriv.o $(UTIL_OBJS)
 
-convolutions: convolutions.o readtex.o
-       $(APP_CC) -I$(INCDIR) $(CFLAGS) $(LDFLAGS) convolutions.o readtex.o $(LIBS) -o $@
 
+identity.o: $(UTIL_HEADERS)
 
-deriv.o: deriv.c extfuncs.h shaderutil.h
-       $(APP_CC) -c -I$(INCDIR) $(CFLAGS) deriv.c
+identity: identity.o $(UTIL_OBJS)
 
-deriv: deriv.o shaderutil.o
-       $(APP_CC) -I$(INCDIR) $(CFLAGS) $(LDFLAGS) deriv.o shaderutil.o $(LIBS) -o $@
 
+fragcoord.o: $(UTIL_HEADERS)
 
-identity.o: identity.c extfuncs.h shaderutil.h
-       $(APP_CC) -c -I$(INCDIR) $(CFLAGS) identity.c
+fragcoord: fragcoord.o $(UTIL_OBJS)
 
-identity: identity.o shaderutil.o
-       $(APP_CC) -I$(INCDIR) $(CFLAGS) $(LDFLAGS) identity.o shaderutil.o $(LIBS) -o $@
 
+linktest.o: $(UTIL_HEADERS)
 
-fragcoord.o: fragcoord.c extfuncs.h shaderutil.h
-       $(APP_CC) -c -I$(INCDIR) $(CFLAGS) fragcoord.c
+linktest: linktest.o $(UTIL_OBJS)
 
-fragcoord: fragcoord.o shaderutil.o
-       $(APP_CC) -I$(INCDIR) $(CFLAGS) $(LDFLAGS) fragcoord.o shaderutil.o $(LIBS) -o $@
 
+mandelbrot.o: $(UTIL_HEADERS)
 
-linktest.o: linktest.c extfuncs.h shaderutil.h
-       $(APP_CC) -c -I$(INCDIR) $(CFLAGS) linktest.c
+mandelbrot: mandelbrot.o $(UTIL_OBJS)
 
-linktest: linktest.o shaderutil.o
-       $(APP_CC) -I$(INCDIR) $(CFLAGS) $(LDFLAGS) linktest.o shaderutil.o $(LIBS) -o $@
 
-mandelbrot.o: mandelbrot.c extfuncs.h shaderutil.h
-       $(APP_CC) -c -I$(INCDIR) $(CFLAGS) mandelbrot.c
+multinoise.o: $(UTIL_HEADERS)
 
-mandelbrot: mandelbrot.o shaderutil.o
-       $(APP_CC) -I$(INCDIR) $(CFLAGS) $(LDFLAGS) mandelbrot.o shaderutil.o $(LIBS) -o $@
+multinoise: multinoise.o $(UTIL_OBJS)
 
-multitex.o: multitex.c extfuncs.h readtex.h shaderutil.h
-       $(APP_CC) -c -I$(INCDIR) $(CFLAGS) multitex.c
 
-multitex: multitex.o readtex.o shaderutil.o
-       $(APP_CC) -I$(INCDIR) $(CFLAGS) $(LDFLAGS) multitex.o readtex.o shaderutil.o $(LIBS) -o $@
+multitex.o: $(UTIL_HEADERS)
 
+multitex: multitex.o $(UTIL_OBJS)
 
-noise.o: noise.c extfuncs.h shaderutil.h
-       $(APP_CC) -c -I$(INCDIR) $(CFLAGS) noise.c
 
-noise: noise.o shaderutil.o
-       $(APP_CC) -I$(INCDIR) $(CFLAGS) $(LDFLAGS) noise.o shaderutil.o $(LIBS) -o $@
+noise.o: $(UTIL_HEADERS)
 
+noise: noise.o $(UTIL_OBJS)
 
-noise2.o: noise2.c extfuncs.h shaderutil.h
-       $(APP_CC) -c -I$(INCDIR) $(CFLAGS) noise2.c
 
-noise2: noise2.o shaderutil.o
-       $(APP_CC) -I$(INCDIR) $(CFLAGS) $(LDFLAGS) noise2.o shaderutil.o $(LIBS) -o $@
+noise2.o: $(UTIL_HEADERS)
 
+noise2: noise2.o $(UTIL_OBJS)
 
-points.o: points.c extfuncs.h shaderutil.h
-       $(APP_CC) -c -I$(INCDIR) $(CFLAGS) points.c
 
-points: points.o shaderutil.o
-       $(APP_CC) -I$(INCDIR) $(CFLAGS) $(LDFLAGS) points.o shaderutil.o $(LIBS) -o $@
+points.o: $(UTIL_HEADERS)
 
+points: points.o $(UTIL_OBJS)
 
-pointcoord.o: pointcoord.c readtex.h extfuncs.h shaderutil.h
-       $(APP_CC) -c -I$(INCDIR) $(CFLAGS) pointcoord.c
 
-pointcoord: pointcoord.o readtex.o shaderutil.o
-       $(APP_CC) -I$(INCDIR) $(CFLAGS) $(LDFLAGS) pointcoord.o readtex.o shaderutil.o $(LIBS) -o $@
+pointcoord.o: $(UTIL_HEADERS)
 
+pointcoord: pointcoord.o $(UTIL_OBJS)
 
-samplers.o: samplers.c readtex.h extfuncs.h shaderutil.h
-       $(APP_CC) -c -I$(INCDIR) $(CFLAGS) samplers.c
 
-samplers: samplers.o readtex.o shaderutil.o
-       $(APP_CC) -I$(INCDIR) $(CFLAGS) $(LDFLAGS) samplers.o readtex.o shaderutil.o $(LIBS) -o $@
+samplers.o: $(UTIL_HEADERS)
 
-samplers_array.o: samplers.c readtex.h extfuncs.h shaderutil.h
-       $(APP_CC) -c -DSAMPLERS_ARRAY -I$(INCDIR) $(CFLAGS) samplers.c -o samplers_array.o
+samplers: samplers.o $(UTIL_OBJS)
 
-samplers_array: samplers_array.o readtex.o shaderutil.o
-       $(APP_CC) -I$(INCDIR) $(CFLAGS) $(LDFLAGS) samplers_array.o readtex.o shaderutil.o $(LIBS) -o $@
 
-skinning.o: skinning.c readtex.h extfuncs.h shaderutil.h
-       $(APP_CC) -c -I$(INCDIR) $(CFLAGS) skinning.c
+samplers_array.o: $(UTIL_HEADERS)
 
-skinning: skinning.o readtex.o shaderutil.o
-       $(APP_CC) -I$(INCDIR) $(CFLAGS) $(LDFLAGS) skinning.o readtex.o shaderutil.o $(LIBS) -o $@
+samplers_array: samplers_array.o $(UTIL_OBJS)
 
 
-texdemo1.o: texdemo1.c readtex.h extfuncs.h shaderutil.h
-       $(APP_CC) -c -I$(INCDIR) $(CFLAGS) texdemo1.c
+shadow_sampler.o: $(UTIL_HEADERS)
 
-texdemo1: texdemo1.o readtex.o shaderutil.o
-       $(APP_CC) -I$(INCDIR) $(CFLAGS) $(LDFLAGS) texdemo1.o readtex.o shaderutil.o $(LIBS) -o $@
+shadow_sampler: shadow_sampler.o $(UTIL_OBJS)
 
 
-toyball.o: toyball.c extfuncs.h shaderutil.h
-       $(APP_CC) -c -I$(INCDIR) $(CFLAGS) toyball.c
+skinning.o: $(UTIL_HEADERS)
 
-toyball: toyball.o shaderutil.o
-       $(APP_CC) -I$(INCDIR) $(CFLAGS) $(LDFLAGS) toyball.o shaderutil.o $(LIBS) -o $@
+skinning: skinning.o $(UTIL_OBJS)
 
 
-twoside.o: twoside.c extfuncs.h shaderutil.h
-       $(APP_CC) -c -I$(INCDIR) $(CFLAGS) twoside.c
+texaaline.o: $(UTIL_HEADERS)
 
-twoside: twoside.o shaderutil.o
-       $(APP_CC) -I$(INCDIR) $(CFLAGS) $(LDFLAGS) twoside.o shaderutil.o $(LIBS) -o $@
+texaaline: texaaline.o $(UTIL_OBJS)
 
 
-trirast.o: trirast.c extfuncs.h shaderutil.h
-       $(APP_CC) -c -I$(INCDIR) $(CFLAGS) trirast.c
+texdemo1.o: $(UTIL_HEADERS)
 
-trirast: trirast.o shaderutil.o
-       $(APP_CC) -I$(INCDIR) $(CFLAGS) $(LDFLAGS) trirast.o shaderutil.o $(LIBS) -o $@
+texdemo1: texdemo1.o $(UTIL_OBJS)
 
 
-vert-or-frag-only.o: vert-or-frag-only.c extfuncs.h shaderutil.h
-       $(APP_CC) -c -I$(INCDIR) $(CFLAGS) vert-or-frag-only.c
+toyball.o: $(UTIL_HEADERS)
 
-vert-or-frag-only: vert-or-frag-only.o shaderutil.o
-       $(APP_CC) -I$(INCDIR) $(CFLAGS) $(LDFLAGS) vert-or-frag-only.o shaderutil.o $(LIBS) -o $@
+toyball: toyball.o $(UTIL_OBJS)
 
 
-vert-tex.o: vert-tex.c extfuncs.h shaderutil.h
-       $(APP_CC) -c -I$(INCDIR) $(CFLAGS) vert-tex.c
+twoside.o: $(UTIL_HEADERS)
 
-vert-tex: vert-tex.o shaderutil.o
-       $(APP_CC) -I$(INCDIR) $(CFLAGS) $(LDFLAGS) vert-tex.o shaderutil.o $(LIBS) -o $@
+twoside: twoside.o $(UTIL_OBJS)
 
 
+trirast.o: $(UTIL_HEADERS)
 
+trirast: trirast.o $(UTIL_OBJS)
 
-clean:
-       -rm -f $(PROGS)
-       -rm -f *.o *~
-       -rm -f extfuncs.h
-       -rm -f shaderutil.*
+
+vert-or-frag-only.o: $(UTIL_HEADERS)
+
+vert-or-frag-only: vert-or-frag-only.o $(UTIL_OBJS)
+
+
+vert-tex.o: $(UTIL_HEADERS)
+
+vert-tex: vert-tex.o $(UTIL_OBJS)
diff --git a/progs/glsl/texaaline.c b/progs/glsl/texaaline.c
new file mode 100644 (file)
index 0000000..0b3cc84
--- /dev/null
@@ -0,0 +1,369 @@
+/**
+ * AA lines with texture mapped quads
+ *
+ * Brian Paul
+ * 9 Feb 2008
+ */
+
+
+#include <assert.h>
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+#include <GL/gl.h>
+#include <GL/glut.h>
+#include <GL/glext.h>
+#include "extfuncs.h"
+
+
+static GLint WinWidth = 300, WinHeight = 300;
+static GLint win = 0;
+static GLfloat Width = 8.;
+
+/*
+ * Quad strip for line from v0 to v1:
+ *
+ 1   3                     5   7
+ +---+---------------------+---+
+ |                             |
+ |   *v0                 v1*   |
+ |                             |
+ +---+---------------------+---+
+ 0   2                     4   6
+ */
+static void
+QuadLine(const GLfloat *v0, const GLfloat *v1, GLfloat width)
+{
+   GLfloat dx = v1[0] - v0[0];
+   GLfloat dy = v1[1] - v0[1];
+   GLfloat len = sqrt(dx*dx + dy*dy);
+   float dx0, dx1, dx2, dx3, dx4, dx5, dx6, dx7;
+   float dy0, dy1, dy2, dy3, dy4, dy5, dy6, dy7;
+
+   dx /= len;
+   dy /= len;
+
+   width *= 0.5;  /* half width */
+   dx = dx * (width + 0.0);
+   dy = dy * (width + 0.0);
+
+   dx0 = -dx+dy;  dy0 = -dy-dx;
+   dx1 = -dx-dy;  dy1 = -dy+dx;
+
+   dx2 =   0+dy;  dy2 = -dx+0;
+   dx3 =   0-dy;  dy3 = +dx+0;
+
+   dx4 =   0+dy;  dy4 = -dx+0;
+   dx5 =   0-dy;  dy5 = +dx+0;
+
+   dx6 =  dx+dy;  dy6 =  dy-dx;
+   dx7 =  dx-dy;  dy7 =  dy+dx;
+
+   /*
+   printf("dx, dy = %g, %g\n", dx, dy);
+   printf("  dx0, dy0: %g, %g\n", dx0, dy0);
+   printf("  dx1, dy1: %g, %g\n", dx1, dy1);
+   printf("  dx2, dy2: %g, %g\n", dx2, dy2);
+   printf("  dx3, dy3: %g, %g\n", dx3, dy3);
+   */
+
+   glBegin(GL_QUAD_STRIP);
+   glTexCoord2f(0, 0);
+   glVertex2f(v0[0] + dx0, v0[1] + dy0);
+   glTexCoord2f(0, 1);
+   glVertex2f(v0[0] + dx1, v0[1] + dy1);
+
+   glTexCoord2f(0.5, 0);
+   glVertex2f(v0[0] + dx2, v0[1] + dy2);
+   glTexCoord2f(0.5, 1);
+   glVertex2f(v0[0] + dx3, v0[1] + dy3);
+
+   glTexCoord2f(0.5, 0);
+   glVertex2f(v1[0] + dx2, v1[1] + dy2);
+   glTexCoord2f(0.5, 1);
+   glVertex2f(v1[0] + dx3, v1[1] + dy3);
+
+   glTexCoord2f(1, 0);
+   glVertex2f(v1[0] + dx6, v1[1] + dy6);
+   glTexCoord2f(1, 1);
+   glVertex2f(v1[0] + dx7, v1[1] + dy7);
+   glEnd();
+}
+
+
+static float Cos(float a)
+{
+   return cos(a * M_PI / 180.);
+}
+
+static float Sin(float a)
+{
+   return sin(a * M_PI / 180.);
+}
+
+static void
+Redisplay(void)
+{
+   int i;
+
+   glClear(GL_COLOR_BUFFER_BIT);
+
+   glColor3f(1, 1, 1);
+
+   glEnable(GL_BLEND);
+   glEnable(GL_TEXTURE_2D);
+
+   for (i = 0; i < 360; i+=5) {
+      float v0[2], v1[2];
+      v0[0] = 150 + 40 * Cos(i);
+      v0[1] = 150 + 40 * Sin(i);
+      v1[0] = 150 + 130 * Cos(i);
+      v1[1] = 150 + 130 * Sin(i);
+      QuadLine(v0, v1, Width);
+   }
+
+   {
+      float v0[2], v1[2], x;
+      for (x = 0; x < 1.0; x += 0.2) {
+         v0[0] = 150 + x;
+         v0[1] = 150 + x * 40 - 20;
+         v1[0] = 150 + x + 5.0;
+         v1[1] = 150 + x * 40 - 20;
+         QuadLine(v0, v1, Width);
+      }
+   }
+
+   glDisable(GL_BLEND);
+   glDisable(GL_TEXTURE_2D);
+
+   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();
+}
+
+
+static void
+CleanUp(void)
+{
+   glutDestroyWindow(win);
+}
+
+
+static void
+Key(unsigned char key, int x, int y)
+{
+  (void) x;
+  (void) y;
+
+   switch(key) {
+   case 'w':
+      Width -= 0.5;
+      break;
+   case 'W':
+      Width += 0.5;
+      break;
+   case 27:
+      CleanUp();
+      exit(0);
+      break;
+   }
+#if 0
+   if (Width < 3)
+      Width = 3;
+#endif
+   printf("Width = %g\n", Width);
+   glutPostRedisplay();
+}
+
+
+static float
+ramp4(GLint i, GLint size)
+{
+   float d;
+   if (i < 4 ) {
+      d = i / 4.0;
+   }
+   else if (i >= size - 5) {
+      d = 1.0 - (i - (size - 5)) / 4.0;
+   }
+   else {
+      d = 1.0;
+   }
+   return d;
+}
+
+static float
+ramp2(GLint i, GLint size)
+{
+   float d;
+   if (i < 2 ) {
+      d = i / 2.0;
+   }
+   else if (i >= size - 3) {
+      d = 1.0 - (i - (size - 3)) / 2.0;
+   }
+   else {
+      d = 1.0;
+   }
+   return d;
+}
+
+static float
+ramp1(GLint i, GLint size)
+{
+   float d;
+   if (i == 0 || i == size-1) {
+      d = 0.0;
+   }
+   else {
+      d = 1.0;
+   }
+   return d;
+}
+
+
+/**
+ * Make an alpha texture for antialiasing lines.
+ * Just a linear fall-off ramp for now.
+ * Should have a number of different textures for different line widths.
+ * Could try a bell-like-curve....
+ */
+static void
+MakeTexture(void)
+{
+#define SZ 8
+   GLfloat tex[SZ][SZ];  /* alpha tex */
+   int i, j;
+   for (i = 0; i < SZ; i++) {
+      for (j = 0; j < SZ; j++) {
+#if 0
+         float k = (SZ-1) / 2.0;
+         float dx = fabs(i - k) / k;
+         float dy = fabs(j - k) / k;
+         float d;
+
+         dx = 1.0 - dx;
+         dy = 1.0 - dy;
+         d = dx * dy;
+
+#else
+         float d = ramp1(i, SZ) * ramp1(j, SZ);
+         printf("%d, %d: %g\n", i, j, d);
+#endif
+         tex[i][j] = d;
+      }
+   }
+
+   glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, SZ, SZ, 0, GL_ALPHA, GL_FLOAT, tex);
+   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+   glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
+#undef SZ
+}
+
+
+static void
+MakeMipmap(void)
+{
+#define SZ 64
+   GLfloat tex[SZ][SZ];  /* alpha tex */
+   int level;
+
+   glPixelStorei(GL_UNPACK_ROW_LENGTH, SZ);
+   for (level = 0; level < 7; level++) {
+      int sz = 1 << (6 - level);
+      int i, j;
+      for (i = 0; i < sz; i++) {
+         for (j = 0; j < sz; j++) {
+            if (level == 6)
+               tex[i][j] = 1.0;
+            else if (level == 5)
+               tex[i][j] = 0.5;
+            else
+               tex[i][j] = ramp1(i, sz) * ramp1(j, sz);
+         }
+      }
+
+      glTexImage2D(GL_TEXTURE_2D, level, GL_ALPHA,
+                   sz, sz, 0, GL_ALPHA, GL_FLOAT, tex);
+   }
+
+   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
+   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+   //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LOD, 4);
+   ////glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 5);
+
+   glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
+#undef SZ
+}
+
+
+static void
+Init(void)
+{
+   const char *version;
+
+   (void) MakeTexture;
+   (void) ramp4;
+   (void) ramp2;
+
+   version = (const char *) glGetString(GL_VERSION);
+   if (version[0] != '2' || version[1] != '.') {
+      printf("This program requires OpenGL 2.x, found %s\n", version);
+      exit(1);
+   }
+
+   GetExtensionFuncs();
+
+   glClearColor(0.3f, 0.3f, 0.3f, 0.0f);
+
+   printf("GL_RENDERER = %s\n",(const char *) glGetString(GL_RENDERER));
+
+   glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+#if 0
+   glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
+#elif 0
+   MakeTexture();
+#else
+   MakeMipmap();
+#endif
+}
+
+
+static void
+ParseOptions(int argc, char *argv[])
+{
+}
+
+
+int
+main(int argc, char *argv[])
+{
+   glutInit(&argc, argv);
+   glutInitWindowPosition( 0, 0);
+   glutInitWindowSize(WinWidth, WinHeight);
+   glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE);
+   win = glutCreateWindow(argv[0]);
+   glutReshapeFunc(Reshape);
+   glutKeyboardFunc(Key);
+   glutDisplayFunc(Redisplay);
+   ParseOptions(argc, argv);
+   Init();
+   glutMainLoop();
+   return 0;
+}