diff options
Diffstat (limited to 'progs/tests')
-rw-r--r-- | progs/tests/.gitignore | 6 | ||||
-rw-r--r-- | progs/tests/Makefile | 77 | ||||
-rw-r--r-- | progs/tests/antialias.c | 12 | ||||
-rw-r--r-- | progs/tests/blendxor.c | 196 | ||||
-rw-r--r-- | progs/tests/bufferobj.c | 36 | ||||
-rw-r--r-- | progs/tests/cva.c | 8 | ||||
-rw-r--r-- | progs/tests/dinoshade.c | 8 | ||||
-rw-r--r-- | progs/tests/exactrast.c | 200 | ||||
-rw-r--r-- | progs/tests/fbotest1.c | 15 | ||||
-rw-r--r-- | progs/tests/fbotexture.c | 430 | ||||
-rw-r--r-- | progs/tests/floattex.c | 160 | ||||
-rw-r--r-- | progs/tests/lineclip.c | 175 | ||||
-rw-r--r-- | progs/tests/multipal.c | 6 | ||||
-rw-r--r-- | progs/tests/rubberband.c | 245 | ||||
-rw-r--r-- | progs/tests/shader_api.c | 337 | ||||
-rw-r--r-- | progs/tests/stencil_twoside.c | 297 | ||||
-rw-r--r-- | progs/tests/texline.c | 12 | ||||
-rw-r--r-- | progs/tests/unfilledclip.c | 205 |
18 files changed, 2202 insertions, 223 deletions
diff --git a/progs/tests/.gitignore b/progs/tests/.gitignore index 40cb6850fb..c5b9e28dab 100644 --- a/progs/tests/.gitignore +++ b/progs/tests/.gitignore @@ -26,6 +26,7 @@ cva dinoshade drawbuffers extfuncs.h +exactrast fbotest1 fbotest2 fbotexture @@ -40,6 +41,7 @@ getproclist.h interleave invert jkrahntest +lineclip manytex minmag mipmap_limits @@ -56,6 +58,9 @@ readtex.c readtex.h seccolor sharedtex +shader_api +stencil_twoside +stencil_wrap stencilwrap stencil_wrap subtex @@ -69,6 +74,7 @@ texline texobjshare texrect texwrap +unfilledclip vao-01 vao-02 vparray diff --git a/progs/tests/Makefile b/progs/tests/Makefile index 9c81f870d8..34c9ab1dce 100644 --- a/progs/tests/Makefile +++ b/progs/tests/Makefile @@ -8,7 +8,7 @@ TOP = ../.. include $(TOP)/configs/current -LIBS = $(APP_LIB_DEPS) +LIBS = -L$(TOP)/$(LIB_DIR) -l$(GLUT_LIB) -l$(GLU_LIB) -l$(GL_LIB) $(APP_LIB_DEPS) SOURCES = \ afsmultiarb.c \ @@ -26,6 +26,7 @@ SOURCES = \ arraytexture.c \ blendminmax.c \ blendsquare.c \ + blendxor.c \ bufferobj.c \ bug_3050.c \ bug_3101.c \ @@ -37,6 +38,7 @@ SOURCES = \ cva.c \ dinoshade.c \ drawbuffers.c \ + exactrast.c \ floattex.c \ fbotest1.c \ fbotest2.c \ @@ -50,6 +52,7 @@ SOURCES = \ interleave.c \ invert.c \ jkrahntest.c \ + lineclip.c \ manytex.c \ minmag.c \ mipmap_limits.c \ @@ -63,8 +66,11 @@ SOURCES = \ quads.c \ random.c \ readrate.c \ + rubberband.c \ seccolor.c \ + shader_api.c \ sharedtex.c \ + stencil_twoside.c \ stencilwrap.c \ stencil_wrap.c \ subtex \ @@ -76,6 +82,7 @@ SOURCES = \ texobjshare.c \ texrect.c \ texwrap.c \ + unfilledclip.c \ vao-01.c \ vao-02.c \ vparray.c \ @@ -97,13 +104,22 @@ INCLUDES = -I. -I$(TOP)/include UTIL_FILES = readtex.h readtex.c +##### TARGETS ##### + +default: $(UTIL_FILES) $(PROGS) + +clean: + -rm -f $(PROGS) + -rm -f *.o + -rm -f getproclist.h + ##### RULES ##### .SUFFIXES: .SUFFIXES: .c .c: - $(APP_CC) $(INCLUDES) $(CFLAGS) $< $(LIBS) -o $@ + $(APP_CC) $(INCLUDES) $(CFLAGS) $(LDFLAGS) $< $(LIBS) -o $@ .c.o: $(APP_CC) -c $(INCLUDES) $(CFLAGS) $(DEFINES) $< -o $@ @@ -111,17 +127,6 @@ UTIL_FILES = readtex.h readtex.c .S.o: $(APP_CC) -c $(INCLUDES) $(CFLAGS) $(DEFINES) $< -o $@ - -##### TARGETS ##### - -default: $(UTIL_FILES) $(PROGS) - -clean: - rm -f $(PROGS) - rm -f *.o - rm -f getproclist.h - - # auto code generation getprocaddress: getprocaddress.c getproclist.h @@ -132,37 +137,37 @@ arraytexture: arraytexture.o readtex.o $(APP_CC) $(CFLAGS) arraytexture.o readtex.o $(LIBS) -o $@ arraytexture.o: arraytexture.c readtex.h - $(APP_CC) -c $(INCLUDES) $(CFLAGS) $(DEFINES) $< -o $@ + $(APP_CC) -c $(INCLUDES) $(CFLAGS) $(DEFINES) arraytexture.c -o $@ afsmultiarb: afsmultiarb.o readtex.o - $(APP_CC) $(CFLAGS) afsmultiarb.o readtex.o $(LIBS) -o $@ + $(APP_CC) $(CFLAGS) $(LDFLAGS) afsmultiarb.o readtex.o $(LIBS) -o $@ afsmultiarb.o: afsmultiarb.c readtex.h - $(APP_CC) -c $(INCLUDES) $(CFLAGS) $(DEFINES) $< -o $@ + $(APP_CC) -c $(INCLUDES) $(CFLAGS) $(DEFINES) afsmultiarb.c -o $@ drawbuffers: drawbuffers.o - $(APP_CC) $(CFLAGS) drawbuffers.o $(LIBS) -o $@ + $(APP_CC) $(CFLAGS) $(LDFLAGS) drawbuffers.o $(LIBS) -o $@ drawbuffers.o: drawbuffers.c extfuncs.h - $(APP_CC) -c $(INCLUDES) $(CFLAGS) $(DEFINES) $< -o $@ + $(APP_CC) -c $(INCLUDES) $(CFLAGS) $(DEFINES) drawbuffers.c -o $@ texrect: texrect.o readtex.o - $(APP_CC) $(CFLAGS) texrect.o readtex.o $(LIBS) -o $@ + $(APP_CC) $(CFLAGS) $(LDFLAGS) texrect.o readtex.o $(LIBS) -o $@ texrect.o: texrect.c readtex.h - $(APP_CC) -c $(INCLUDES) $(CFLAGS) $(DEFINES) $< -o $@ + $(APP_CC) -c $(INCLUDES) $(CFLAGS) $(DEFINES) texrect.c -o $@ bug_3195: bug_3195.o readtex.o - $(APP_CC) $(CFLAGS) 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 - $(APP_CC) -c $(INCLUDES) $(CFLAGS) $(DEFINES) $< -o $@ + $(APP_CC) -c $(INCLUDES) $(CFLAGS) $(DEFINES) bug_3195.c -o $@ invert: invert.o readtex.o - $(APP_CC) $(CFLAGS) invert.o readtex.o $(LIBS) -o $@ + $(APP_CC) $(CFLAGS) $(LDFLAGS) invert.o readtex.o $(LIBS) -o $@ invert.o: invert.c readtex.h - $(APP_CC) -c $(INCLUDES) $(CFLAGS) $(DEFINES) $< -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 $@ @@ -179,9 +184,16 @@ fillrate.o: fillrate.c readtex.h -readtex.o: readtex.c - $(APP_CC) -c $(INCLUDES) $(CFLAGS) $(DEFINES) $< -o $@ +floattex: floattex.o readtex.o shaderutil.o + $(CC) $(CFLAGS) $(LDFLAGS) floattex.o readtex.o shaderutil.o $(LIBS) -o $@ + +floattex.o: floattex.c readtex.h shaderutil.h + $(CC) -c $(INCLUDES) $(CFLAGS) $(DEFINES) floattex.c -o $@ + + +readtex.o: readtex.c + $(APP_CC) -c $(INCLUDES) $(CFLAGS) $(DEFINES) readtex.c -o $@ readtex.h: $(TOP)/progs/util/readtex.h ln -s $(TOP)/progs/util/readtex.h . @@ -189,11 +201,24 @@ readtex.h: $(TOP)/progs/util/readtex.h readtex.c: $(TOP)/progs/util/readtex.c ln -s $(TOP)/progs/util/readtex.c . + + extfuncs.h: $(TOP)/progs/util/extfuncs.h ln -s $(TOP)/progs/util/extfuncs.h . +shaderutil.c: $(TOP)/progs/util/shaderutil.c + cp $< . + +shaderutil.h: $(TOP)/progs/util/shaderutil.h + cp $< . + +shaderutil.o: shaderutil.c shaderutil.h + $(CC) -c -I$(INCDIR) $(CFLAGS) shaderutil.c + + + # Emacs tags tags: etags `find . -name \*.[ch]` `find ../include` diff --git a/progs/tests/antialias.c b/progs/tests/antialias.c index 3a83c34b8d..f23b5aff32 100644 --- a/progs/tests/antialias.c +++ b/progs/tests/antialias.c @@ -15,6 +15,7 @@ static GLfloat Zrot = 0; static GLboolean Anim = GL_TRUE; static GLboolean HaveMultisample = GL_TRUE; +static GLboolean DoMultisample = GL_TRUE; static void @@ -85,7 +86,10 @@ Display( void ) glColor3f(1, 1, 1); if (HaveMultisample) { glRasterPos2f(-3.1, -1.6); - PrintString("MULTISAMPLE"); + if (DoMultisample) + PrintString("MULTISAMPLE"); + else + PrintString("MULTISAMPLE (off)"); } glRasterPos2f(-0.8, -1.6); PrintString("No antialiasing"); @@ -95,7 +99,8 @@ Display( void ) /* multisample */ if (HaveMultisample) { glEnable(GL_DEPTH_TEST); - glEnable(GL_MULTISAMPLE_ARB); + if (DoMultisample) + glEnable(GL_MULTISAMPLE_ARB); glPushMatrix(); glTranslatef(-2.5, 0, 0); glPushMatrix(); @@ -172,6 +177,9 @@ Key( unsigned char key, int x, int y ) else glutIdleFunc(NULL); break; + case 'm': + DoMultisample = !DoMultisample; + break; case 'z': Zrot = (int) (Zrot - step); break; diff --git a/progs/tests/blendxor.c b/progs/tests/blendxor.c new file mode 100644 index 0000000000..8961a827ea --- /dev/null +++ b/progs/tests/blendxor.c @@ -0,0 +1,196 @@ +/** + * Test XOR emulation with blending. + * + */ + +#define GL_GLEXT_PROTOTYPES +#include <stdio.h> +#include <stdlib.h> +#include <math.h> +#include <GL/glut.h> +#include "readtex.c" + +#define IMAGE_FILE "../images/arch.rgb" + +static int ImgWidth, ImgHeight; +static GLenum ImgFormat; +static GLubyte *Image = NULL; + +static int Win; +static int Width = 600, Height = 600; + +struct rect +{ + int x0, y0, x1, y1; +}; + +static struct rect OldRect, NewRect; + +static GLboolean ButtonDown = GL_FALSE; +static GLboolean LogicOp = 0*GL_TRUE; + + +static const GLfloat red[4] = {1.0, 0.2, 0.2, 1.0}; +static const GLfloat green[4] = {0.2, 1.0, 0.2, 1.0}; +static const GLfloat blue[4] = {0.2, 0.2, 1.0, 1.0}; + + +static void +PrintString(const char *s) +{ + while (*s) { + glutBitmapCharacter(GLUT_BITMAP_8_BY_13, (int) *s); + s++; + } +} + + +static void +Draw(void) +{ + glClear(GL_COLOR_BUFFER_BIT); + + glWindowPos2i((Width - ImgWidth) / 2, (Height - ImgHeight) / 2); + glDrawPixels(ImgWidth, ImgHeight, ImgFormat, GL_UNSIGNED_BYTE, Image); + + /* + * Draw 2D XOR rects + */ + glColor3f(1, 1, 1); + + glWindowPos2i(100, Height - 20); + PrintString("XOR LogicOp:"); + glLogicOp(GL_XOR); + glEnable(GL_COLOR_LOGIC_OP); + glRecti(100, 30, 250, Height - 30); + glDisable(GL_COLOR_LOGIC_OP); + + glWindowPos2i(Width/2 + 10, Height - 20); + PrintString("Invert Blending:"); + glBlendFunc(GL_ONE, GL_ONE); + glBlendEquation(GL_FUNC_SUBTRACT); + glEnable(GL_BLEND); + glRecti(Width / 2, 30, Width / 2 + 150, Height - 30); + glDisable(GL_BLEND); + + 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 'b': + case 'B': + LogicOp = GL_FALSE; + break; + case 'l': + case 'L': + LogicOp = GL_TRUE; + break; + case 27: + glutDestroyWindow(Win); + exit(0); + break; + } + glutPostRedisplay(); +} + + +static void +SpecialKey(int key, int x, int y) +{ + (void) x; + (void) y; + switch (key) { + case GLUT_KEY_UP: + break; + case GLUT_KEY_DOWN: + break; + case GLUT_KEY_LEFT: + break; + case GLUT_KEY_RIGHT: + break; + } + glutPostRedisplay(); +} + + +static void +MouseMotion(int x, int y) +{ + if (ButtonDown) { + NewRect.x1 = x; + NewRect.y1 = y; + glutPostRedisplay(); + } +} + + +static void +MouseButton(int button, int state, int x, int y) +{ + if (button == GLUT_LEFT_BUTTON && state == GLUT_DOWN) { + ButtonDown = GL_TRUE; + NewRect.x0 = NewRect.x1 = x; + NewRect.y0 = NewRect.y1 = y; + OldRect = NewRect; + } + else if (button == GLUT_LEFT_BUTTON && state == GLUT_UP) { + ButtonDown = GL_FALSE; + } +} + + +static void +Init(void) +{ + /* + * Load image and scale if needed. + */ + Image = LoadRGBImage(IMAGE_FILE, &ImgWidth, &ImgHeight, &ImgFormat); + if (!Image) { + printf("Couldn't read %s\n", IMAGE_FILE); + exit(0); + } + + glPixelStorei(GL_UNPACK_ALIGNMENT, 1); + glPixelStorei(GL_PACK_ALIGNMENT, 1); +} + + +int +main(int argc, char *argv[]) +{ + glutInit(&argc, argv); + glutInitWindowSize(Width, Height); + glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE); + Win = glutCreateWindow(argv[0]); + glutReshapeFunc(Reshape); + glutKeyboardFunc(Key); + glutSpecialFunc(SpecialKey); + glutMotionFunc(MouseMotion); + glutMouseFunc(MouseButton); + glutDisplayFunc(Draw); + Init(); + glutPostRedisplay(); + glutMainLoop(); + return 0; +} diff --git a/progs/tests/bufferobj.c b/progs/tests/bufferobj.c index 50ab5cdfa8..d1a85392e1 100644 --- a/progs/tests/bufferobj.c +++ b/progs/tests/bufferobj.c @@ -22,6 +22,8 @@ struct object GLuint NumVerts; GLuint VertexOffset; GLuint ColorOffset; + GLuint VertexStride; + GLuint ColorStride; GLuint NumElements; }; @@ -46,7 +48,7 @@ static void CheckError(int line) static void DrawObject( const struct object *obj ) { glBindBufferARB(GL_ARRAY_BUFFER_ARB, obj->BufferID); - glVertexPointer(3, GL_FLOAT, 0, (void *) obj->VertexOffset); + glVertexPointer(3, GL_FLOAT, obj->VertexStride, (void *) obj->VertexOffset); glEnable(GL_VERTEX_ARRAY); /* test push/pop attrib */ @@ -60,7 +62,7 @@ static void DrawObject( const struct object *obj ) glPopClientAttrib(); } #endif - glColorPointer(3, GL_FLOAT, 0, (void *) obj->ColorOffset); + glColorPointer(3, GL_FLOAT, obj->ColorStride, (void *) obj->ColorOffset); glEnable(GL_COLOR_ARRAY); if (obj->NumElements > 0) { @@ -241,6 +243,8 @@ static void MakeObject1(struct object *obj) obj->NumVerts = 4; obj->VertexOffset = 0; obj->ColorOffset = 3 * sizeof(GLfloat) * obj->NumVerts; + obj->VertexStride = 0; + obj->ColorStride = 0; obj->NumElements = 0; glUnmapBufferARB(GL_ARRAY_BUFFER_ARB); @@ -255,24 +259,28 @@ static void MakeObject1(struct object *obj) static void MakeObject2(struct object *obj) { - GLfloat *v, *c; + GLfloat *v; + int start = 40; /* bytes, to test non-zero array offsets */ glGenBuffersARB(1, &obj->BufferID); glBindBufferARB(GL_ARRAY_BUFFER_ARB, obj->BufferID); glBufferDataARB(GL_ARRAY_BUFFER_ARB, 1000, NULL, GL_STATIC_DRAW_ARB); v = (GLfloat *) glMapBufferARB(GL_ARRAY_BUFFER_ARB, GL_WRITE_ONLY_ARB); - /* Make triangle */ - v[0] = -1; v[1] = -1; v[2] = 0; - v[3] = 1; v[4] = -1; v[5] = 0; - v[6] = 0; v[7] = 1; v[8] = 0; - c = v + 9; - c[0] = 0; c[1] = 1; c[2] = 0; - c[3] = 0; c[4] = 1; c[5] = 0; - c[6] = 1; c[7] = 1; c[8] = 0; + v += start / sizeof(GLfloat); + + /* Make triangle: interleaved colors, then positions */ + /* R G B X Y Z */ + v[0] = 0; v[1] = 1; v[2] = 0; v[3] = -1; v[4] = -1; v[5] = 0; + v[6] = 0; v[7] = 1; v[8] = 0; v[9] = 1; v[10] = -1; v[11] = 0; + v[12] = 1; v[13] = 1; v[14] = 0; v[15] = 0; v[16] = 1; v[17] = 0; + obj->NumVerts = 3; - obj->VertexOffset = 0; - obj->ColorOffset = 3 * sizeof(GLfloat) * obj->NumVerts; + obj->VertexOffset = start + 3 * sizeof(GLfloat); + obj->ColorOffset = start; + obj->VertexStride = 6 * sizeof(GLfloat); + obj->ColorStride = 6 * sizeof(GLfloat); + obj->NumElements = 0; glUnmapBufferARB(GL_ARRAY_BUFFER_ARB); @@ -300,6 +308,8 @@ static void MakeObject3(struct object *obj) obj->NumVerts = 4; obj->VertexOffset = 0; obj->ColorOffset = 3 * sizeof(GLfloat) * obj->NumVerts; + obj->VertexStride = 0; + obj->ColorStride = 0; bytes = obj->NumVerts * (3 + 3) * sizeof(GLfloat); diff --git a/progs/tests/cva.c b/progs/tests/cva.c index a47b2a9319..a9393aef0c 100644 --- a/progs/tests/cva.c +++ b/progs/tests/cva.c @@ -10,17 +10,13 @@ #include <stdlib.h> #include <stdio.h> #include <string.h> -#ifdef __VMS -# include <stddef.h> /* for ptrdiff_t, referenced by GL.h when GL_GLEXT_LEGACY defined */ -#else -# include <malloc.h> /* for ptrdiff_t, referenced by GL.h when GL_GLEXT_LEGACY defined */ -#endif +#include <stddef.h> /* for ptrdiff_t, referenced by GL.h when GL_GLEXT_LEGACY defined */ #ifdef _WIN32 #include <windows.h> #endif #define GL_GLEXT_LEGACY #include <GL/glut.h> - +#include <GL/glext.h> GLfloat verts[][4] = { { -0.5, -0.5, -2.0, 0.0 }, diff --git a/progs/tests/dinoshade.c b/progs/tests/dinoshade.c index ed7b879bc7..44115b9209 100644 --- a/progs/tests/dinoshade.c +++ b/progs/tests/dinoshade.c @@ -38,11 +38,7 @@ #include <stdlib.h> #include <string.h> #include <math.h> /* for cos(), sin(), and sqrt() */ -#ifdef __VMS -# include <stddef.h> /* for ptrdiff_t, referenced by GL.h when GL_GLEXT_LEGACY defined */ -#else -# include <malloc.h> /* for ptrdiff_t, referenced by GL.h when GL_GLEXT_LEGACY defined */ -#endif +#include <stddef.h> /* for ptrdiff_t, referenced by GL.h when GL_GLEXT_LEGACY defined */ #ifdef _WIN32 #include <windows.h> #endif @@ -797,7 +793,7 @@ supportsOneDotOne(void) version = (char *) glGetString(GL_VERSION); if (sscanf(version, "%d.%d", &major, &minor) == 2) - return major >= 1 && minor >= 1; + return major * 10 + minor >= 11; return 0; /* OpenGL version string malformed! */ } diff --git a/progs/tests/exactrast.c b/progs/tests/exactrast.c new file mode 100644 index 0000000000..56c0c79c3f --- /dev/null +++ b/progs/tests/exactrast.c @@ -0,0 +1,200 @@ +/** + * Test for exact point/line/polygon rasterization, or at least rasterization + * that fits the tolerance of the OpenGL spec. + * + * Brian Paul + * 9 Nov 2007 + */ + +/* + * Notes: + * - 'm' to cycle through point, hline, vline and quad drawing + * - Use cursor keys to translate coordinates (z to reset) + * - Resize window to check for proper rasterization + * - Make sure your LCD is running in its native resolution + * + * If translation is (0,0): + * a point will be drawn where x%2==0 and y%2==0, + * a horizontal line will be drawn where x%2==0, + * a vertical line will be drawn where y%2==0, + * for quads, pixels will be set where (x%4)!=3 and (y%4)!=3 + * + * XXX todo: do glReadPixels and test that the results are what's expected. + * Upon failure, iterate over sub-pixel translations to find the ideal offset. + */ + + +#include <stdio.h> +#include <stdlib.h> +#include <GL/glut.h> + +static int Width = 400, Height = 400; +static int Win; +static float Xtrans = 0, Ytrans = 0; +static float Step = 0.125; + +enum { + POINTS, + HLINES, + VLINES, + QUADS, + NUM_MODES +}; + +static int Mode = POINTS; + + +static void +Draw(void) +{ + /* See the OpenGL Programming Guide, Appendix H, "OpenGL Correctness Tips" + * for information about the 0.375 translation factor. + */ + float tx = 0.375, ty = 0.375; + int i, j; + + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + glPushMatrix(); + glTranslatef(tx + Xtrans, ty + Ytrans, 0); + + if (Mode == POINTS) { + glBegin(GL_POINTS); + for (j = 0; j < Height; j += 2) { + for (i = 0; i < Width; i += 2) { + glVertex2f(i, j); + } + } + glEnd(); + } + else if (Mode == HLINES) { + glBegin(GL_LINES); + for (i = 0; i < Height; i += 2) { + glVertex2f(0, i); + glVertex2f(Width, i); + } + glEnd(); + } + else if (Mode == VLINES) { + glBegin(GL_LINES); + for (i = 0; i < Width; i += 2) { + glVertex2f(i, 0 ); + glVertex2f(i, Height); + } + glEnd(); + } + else if (Mode == QUADS) { + glBegin(GL_QUADS); + for (j = 0; j < Height; j += 4) { + for (i = 0; i < Width; i += 4) { + glVertex2f(i, j ); + glVertex2f(i + 3, j ); + glVertex2f(i + 3, j + 3); + glVertex2f(i, j + 3); + } + } + glEnd(); + } + + glPopMatrix(); + + glutSwapBuffers(); +} + + +static void +Reshape(int width, int height) +{ + Width = width; + Height = height; + glViewport(0, 0, width, height); + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + glOrtho(0, width, 0, height, -1, 1); + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); +} + + +static void +Key(unsigned char key, int x, int y) +{ + (void) x; + (void) y; + switch (key) { + case 'm': + case 'M': + Mode = (Mode + 1) % NUM_MODES; + break; + case 'z': + case 'Z': + Xtrans = Ytrans = 0; + printf("Translation: %f, %f\n", Xtrans, Ytrans); + break; + case 27: + glutDestroyWindow(Win); + exit(0); + break; + } + glutPostRedisplay(); +} + + +static void +SpecialKey(int key, int x, int y) +{ + (void) x; + (void) y; + switch (key) { + case GLUT_KEY_UP: + Ytrans += Step; + break; + case GLUT_KEY_DOWN: + Ytrans -= Step; + break; + case GLUT_KEY_LEFT: + Xtrans -= Step; + break; + case GLUT_KEY_RIGHT: + Xtrans += Step; + break; + } + glutPostRedisplay(); + printf("Translation: %f, %f\n", Xtrans, Ytrans); +} + + +static void +Init(void) +{ +} + + +static void +Usage(void) +{ + printf("Keys:\n"); + printf(" up/down/left/right - translate by %f\n", Step); + printf(" z - reset translation to zero\n"); + printf(" m - change rendering mode (points, hlines, vlines, quads)\n"); + printf(" Esc - exit\n"); +} + + +int +main(int argc, char *argv[]) +{ + glutInit(&argc, argv); + glutInitWindowPosition(0, 0); + glutInitWindowSize(Width, Height); + glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE); + Win = glutCreateWindow(argv[0]); + glutReshapeFunc(Reshape); + glutKeyboardFunc(Key); + glutSpecialFunc(SpecialKey); + glutDisplayFunc(Draw); + Init(); + Usage(); + glutMainLoop(); + return 0; +} diff --git a/progs/tests/fbotest1.c b/progs/tests/fbotest1.c index 8f4569ff3b..ab2757c3c3 100644 --- a/progs/tests/fbotest1.c +++ b/progs/tests/fbotest1.c @@ -122,6 +122,7 @@ Key( unsigned char key, int x, int y ) static void Init( void ) { + GLboolean ARB_fbo = glutExtensionSupported("GL_ARB_framebuffer_object"); GLint i; if (!glutExtensionSupported("GL_EXT_framebuffer_object")) { @@ -133,16 +134,20 @@ Init( void ) glGenFramebuffersEXT(1, &MyFB); assert(MyFB); assert(!glIsFramebufferEXT(MyFB)); - glDeleteFramebuffersEXT(1, &MyFB); - assert(!glIsFramebufferEXT(MyFB)); + if (!ARB_fbo) { + glDeleteFramebuffersEXT(1, &MyFB); + assert(!glIsFramebufferEXT(MyFB)); + } /* Note, continue to use MyFB below */ glGenRenderbuffersEXT(1, &MyRB); assert(MyRB); assert(!glIsRenderbufferEXT(MyRB)); - glDeleteRenderbuffersEXT(1, &MyRB); - assert(!glIsRenderbufferEXT(MyRB)); - MyRB = 42; /* an arbitrary ID */ + if (!ARB_fbo) { + glDeleteRenderbuffersEXT(1, &MyRB); + assert(!glIsRenderbufferEXT(MyRB)); + MyRB = 42; /* an arbitrary ID */ + } glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, MyFB); assert(glIsFramebufferEXT(MyFB)); diff --git a/progs/tests/fbotexture.c b/progs/tests/fbotexture.c index aa9f617122..1f7c45fc79 100644 --- a/progs/tests/fbotexture.c +++ b/progs/tests/fbotexture.c @@ -32,12 +32,16 @@ static int TexWidth = 512, TexHeight = 512; static GLuint MyFB; static GLuint TexObj; -static GLuint DepthRB, StencilRB; +static GLuint DepthRB = 0, StencilRB = 0; static GLboolean Anim = GL_FALSE; static GLfloat Rot = 0.0; static GLboolean UsePackedDepthStencil = GL_FALSE; -static GLuint TextureLevel = 1; /* which texture level to render to */ +static GLboolean UsePackedDepthStencilBoth = GL_FALSE; +static GLboolean Use_ARB_fbo = GL_FALSE; +static GLuint TextureLevel = 0; /* which texture level to render to */ static GLenum TexIntFormat = GL_RGB; /* either GL_RGB or GL_RGBA */ +static GLboolean Cull = GL_FALSE; +static GLboolean Wireframe = GL_FALSE; static void @@ -115,6 +119,22 @@ RenderTexture(void) CheckError(__LINE__); + if (Wireframe) { + glPolygonMode(GL_FRONT, GL_LINE); + } + else { + glPolygonMode(GL_FRONT, GL_FILL); + } + + if (Cull) { + /* cull back */ + glCullFace(GL_BACK); + glEnable(GL_CULL_FACE); + } + else { + glDisable(GL_CULL_FACE); + } + #if 0 glBegin(GL_POLYGON); glColor3f(1, 0, 0); @@ -129,7 +149,9 @@ RenderTexture(void) glEnable(GL_LIGHT0); glPushMatrix(); glRotatef(0.5 * Rot, 1.0, 0.0, 0.0); + glFrontFace(GL_CW); /* Teapot patches backward */ glutSolidTeapot(0.5); + glFrontFace(GL_CCW); glPopMatrix(); glDisable(GL_LIGHTING); /* @@ -139,6 +161,8 @@ RenderTexture(void) glDisable(GL_DEPTH_TEST); glDisable(GL_STENCIL_TEST); + glDisable(GL_CULL_FACE); + glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); #if DRAW /* Bind normal framebuffer */ @@ -226,8 +250,7 @@ CleanUp(void) glDeleteRenderbuffersEXT(1, &DepthRB); #endif #if STENCIL - if (!UsePackedDepthStencil) - glDeleteRenderbuffersEXT(1, &StencilRB); + glDeleteRenderbuffersEXT(1, &StencilRB); #endif glDeleteFramebuffersEXT(1, &MyFB); @@ -245,146 +268,321 @@ Key(unsigned char key, int x, int y) (void) x; (void) y; switch (key) { - case 'a': - Anim = !Anim; - if (Anim) - glutIdleFunc(Idle); - else - glutIdleFunc(NULL); - break; - case 's': - Rot += 2.0; - break; - case 27: - CleanUp(); - break; + case 'a': + Anim = !Anim; + if (Anim) + glutIdleFunc(Idle); + else + glutIdleFunc(NULL); + break; + case 'c': + Cull = !Cull; + break; + case 'w': + Wireframe = !Wireframe; + break; + case 's': + Rot += 2.0; + break; + case 'S': + Rot -= 2.0; + break; + case 27: + CleanUp(); + break; } glutPostRedisplay(); } -static void -Init(int argc, char *argv[]) +/** + * Attach depth and stencil renderbuffer(s) to the given framebuffer object. + * \param tryDepthStencil if true, try to use a combined depth+stencil buffer + * \param bindDepthStencil if true, and tryDepthStencil is true, bind with + * the GL_DEPTH_STENCIL_ATTACHMENT target. + * \return GL_TRUE for success, GL_FALSE for failure + */ +static GLboolean +AttachDepthAndStencilBuffers(GLuint fbo, + GLsizei width, GLsizei height, + GLboolean tryDepthStencil, + GLboolean bindDepthStencil, + GLuint *depthRbOut, GLuint *stencilRbOut) { - static const GLfloat mat[4] = { 1.0, 0.5, 0.5, 1.0 }; - GLint i; + GLenum status; - if (!glutExtensionSupported("GL_EXT_framebuffer_object")) { - printf("GL_EXT_framebuffer_object not found!\n"); - exit(0); - } + *depthRbOut = *stencilRbOut = 0; + + glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo); + + if (tryDepthStencil) { + GLuint rb; + + glGenRenderbuffersEXT(1, &rb); + glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, rb); + glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, + GL_DEPTH24_STENCIL8_EXT, + width, height); + if (glGetError()) + return GL_FALSE; - if (argc > 1 && strcmp(argv[1], "-ds") == 0) { - if (!glutExtensionSupported("GL_EXT_packed_depth_stencil")) { - printf("GL_EXT_packed_depth_stencil not found!\n"); - exit(0); + if (bindDepthStencil) { + /* attach to both depth and stencil at once */ + glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, + GL_DEPTH_STENCIL_ATTACHMENT, + GL_RENDERBUFFER_EXT, rb); + if (glGetError()) + return GL_FALSE; } - UsePackedDepthStencil = GL_TRUE; - printf("Using GL_EXT_packed_depth_stencil\n"); + else { + /* attach to depth attachment point */ + glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, + GL_DEPTH_ATTACHMENT_EXT, + GL_RENDERBUFFER_EXT, rb); + if (glGetError()) + return GL_FALSE; + + /* and attach to stencil attachment point */ + glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, + GL_STENCIL_ATTACHMENT_EXT, + GL_RENDERBUFFER_EXT, rb); + if (glGetError()) + return GL_FALSE; + } + + status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT); + if (status != GL_FRAMEBUFFER_COMPLETE_EXT) + return GL_FALSE; + + *depthRbOut = *stencilRbOut = rb; + return GL_TRUE; } - printf("GL_RENDERER = %s\n", (char *) glGetString(GL_RENDERER)); + /* just depth renderbuffer */ + { + GLuint rb; - /* gen framebuffer id, delete it, do some assertions, just for testing */ - glGenFramebuffersEXT(1, &MyFB); - assert(MyFB); - assert(!glIsFramebufferEXT(MyFB)); - glDeleteFramebuffersEXT(1, &MyFB); - assert(!glIsFramebufferEXT(MyFB)); - /* Note, continue to use MyFB below */ + glGenRenderbuffersEXT(1, &rb); + glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, rb); + glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, + GL_DEPTH_COMPONENT, + width, height); + if (glGetError()) + return GL_FALSE; - glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, MyFB); - assert(glIsFramebufferEXT(MyFB)); - glGetIntegerv(GL_FRAMEBUFFER_BINDING_EXT, &i); - assert(i == MyFB); + /* attach to depth attachment point */ + glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, + GL_DEPTH_ATTACHMENT_EXT, + GL_RENDERBUFFER_EXT, rb); + if (glGetError()) + return GL_FALSE; - /* Make texture object/image */ - glGenTextures(1, &TexObj); - glBindTexture(TexTarget, TexObj); - /* make two image levels */ - glTexImage2D(TexTarget, 0, TexIntFormat, TexWidth, TexHeight, 0, - GL_RGBA, GL_UNSIGNED_BYTE, NULL); - glTexImage2D(TexTarget, 1, TexIntFormat, TexWidth/2, TexHeight/2, 0, - GL_RGBA, GL_UNSIGNED_BYTE, NULL); - TexWidth = TexWidth >> TextureLevel; - TexHeight = TexHeight >> TextureLevel; - - glTexParameteri(TexTarget, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(TexTarget, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); - glTexParameteri(TexTarget, GL_TEXTURE_BASE_LEVEL, TextureLevel); - glTexParameteri(TexTarget, GL_TEXTURE_MAX_LEVEL, TextureLevel); + status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT); + if (status != GL_FRAMEBUFFER_COMPLETE_EXT) + return GL_FALSE; - CheckError(__LINE__); + *depthRbOut = rb; + } + + /* just stencil renderbuffer */ + { + GLuint rb; + + glGenRenderbuffersEXT(1, &rb); + glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, rb); + glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, + GL_STENCIL_INDEX, + width, height); + if (glGetError()) + return GL_FALSE; + + /* attach to depth attachment point */ + glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, + GL_STENCIL_ATTACHMENT_EXT, + GL_RENDERBUFFER_EXT, rb); + if (glGetError()) + return GL_FALSE; + + status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT); + if (status != GL_FRAMEBUFFER_COMPLETE_EXT) + return GL_FALSE; + + *stencilRbOut = rb; + } + + return GL_TRUE; +} + + +static void +ParseArgs(int argc, char *argv[]) +{ + GLint i; + for (i = 1; i < argc; i++) { + if (strcmp(argv[i], "-ds") == 0) { + if (!glutExtensionSupported("GL_EXT_packed_depth_stencil")) { + printf("GL_EXT_packed_depth_stencil not found!\n"); + exit(0); + } + UsePackedDepthStencil = GL_TRUE; + printf("Using GL_EXT_packed_depth_stencil\n"); + } + else if (strcmp(argv[i], "-ds2") == 0) { + if (!glutExtensionSupported("GL_EXT_packed_depth_stencil")) { + printf("GL_EXT_packed_depth_stencil not found!\n"); + exit(0); + } + if (!glutExtensionSupported("GL_ARB_framebuffer_object")) { + printf("GL_ARB_framebuffer_object not found!\n"); + exit(0); + } + UsePackedDepthStencilBoth = GL_TRUE; + printf("Using GL_EXT_packed_depth_stencil and GL_DEPTH_STENCIL attachment point\n"); + } + else if (strcmp(argv[i], "-arb") == 0) { + if (!glutExtensionSupported("GL_ARB_framebuffer_object")) { + printf("Sorry, GL_ARB_framebuffer object not supported!\n"); + } + else { + Use_ARB_fbo = GL_TRUE; + } + } + else { + printf("Unknown option: %s\n", argv[i]); + } + } +} + +/* + * Make FBO to render into given texture. + */ +static GLuint +MakeFBO_RenderTexture(GLuint TexObj) +{ + GLuint fb; + GLint sizeFudge = 0; + + glGenFramebuffersEXT(1, &fb); + glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fb); /* Render color to texture */ glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, TexTarget, TexObj, TextureLevel); + if (Use_ARB_fbo) { + /* use a smaller depth buffer to see what happens */ + sizeFudge = 90; + } -#if DEPTH - /* make depth renderbuffer */ - glGenRenderbuffersEXT(1, &DepthRB); - assert(DepthRB); - assert(!glIsRenderbufferEXT(DepthRB)); - glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, DepthRB); - assert(glIsRenderbufferEXT(DepthRB)); - if (UsePackedDepthStencil) - glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_STENCIL_EXT, - TexWidth, TexHeight); - else - glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT, - TexWidth, TexHeight); - CheckError(__LINE__); - glGetRenderbufferParameterivEXT(GL_RENDERBUFFER_EXT, - GL_RENDERBUFFER_DEPTH_SIZE_EXT, &i); - CheckError(__LINE__); - printf("Depth renderbuffer size = %d bits\n", i); - assert(i > 0); + /* Setup depth and stencil buffers */ + { + GLboolean b; + b = AttachDepthAndStencilBuffers(fb, + TexWidth - sizeFudge, + TexHeight - sizeFudge, + UsePackedDepthStencil, + UsePackedDepthStencilBoth, + &DepthRB, &StencilRB); + if (!b) { + /* try !UsePackedDepthStencil */ + b = AttachDepthAndStencilBuffers(fb, + TexWidth - sizeFudge, + TexHeight - sizeFudge, + !UsePackedDepthStencil, + UsePackedDepthStencilBoth, + &DepthRB, &StencilRB); + } + if (!b) { + printf("Unable to create/attach depth and stencil renderbuffers " + " to FBO!\n"); + exit(1); + } + } - /* attach DepthRB to MyFB */ - glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, - GL_RENDERBUFFER_EXT, DepthRB); -#endif + /* queries */ + { + GLint bits, w, h; - CheckError(__LINE__); + glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, DepthRB); + glGetRenderbufferParameterivEXT(GL_RENDERBUFFER_EXT, + GL_RENDERBUFFER_WIDTH_EXT, &w); + glGetRenderbufferParameterivEXT(GL_RENDERBUFFER_EXT, + GL_RENDERBUFFER_HEIGHT_EXT, &h); + printf("Color/Texture size: %d x %d\n", TexWidth, TexHeight); + printf("Depth buffer size: %d x %d\n", w, h); + + glGetRenderbufferParameterivEXT(GL_RENDERBUFFER_EXT, + GL_RENDERBUFFER_DEPTH_SIZE_EXT, &bits); + printf("Depth renderbuffer size = %d bits\n", bits); -#if STENCIL - if (UsePackedDepthStencil) { - /* DepthRb is a combined depth/stencil renderbuffer */ - glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, - GL_STENCIL_ATTACHMENT_EXT, - GL_RENDERBUFFER_EXT, DepthRB); - } - else { - /* make stencil renderbuffer */ - glGenRenderbuffersEXT(1, &StencilRB); - assert(StencilRB); - assert(!glIsRenderbufferEXT(StencilRB)); glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, StencilRB); - assert(glIsRenderbufferEXT(StencilRB)); - glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_STENCIL_INDEX, - TexWidth, TexHeight); - /* attach StencilRB to MyFB */ - glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, - GL_STENCIL_ATTACHMENT_EXT, - GL_RENDERBUFFER_EXT, StencilRB); + glGetRenderbufferParameterivEXT(GL_RENDERBUFFER_EXT, + GL_RENDERBUFFER_STENCIL_SIZE_EXT, &bits); + printf("Stencil renderbuffer size = %d bits\n", bits); } - glGetRenderbufferParameterivEXT(GL_RENDERBUFFER_EXT, - GL_RENDERBUFFER_STENCIL_SIZE_EXT, &i); - CheckError(__LINE__); - printf("Stencil renderbuffer size = %d bits\n", i); - assert(i > 0); -#endif - CheckError(__LINE__); - - /* bind regular framebuffer */ + /* bind the regular framebuffer */ glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); + return fb; +} + + +static void +Init(void) +{ + if (!glutExtensionSupported("GL_EXT_framebuffer_object")) { + printf("GL_EXT_framebuffer_object not found!\n"); + exit(0); + } + + printf("GL_RENDERER = %s\n", (char *) glGetString(GL_RENDERER)); /* lighting */ - glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, mat); + { + static const GLfloat mat[4] = { 1.0, 0.5, 0.5, 1.0 }; + glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, mat); + } + + /* + * Make texture object/image (we'll render into this texture) + */ + { + glGenTextures(1, &TexObj); + glBindTexture(TexTarget, TexObj); + + /* make two image levels */ + glTexImage2D(TexTarget, 0, TexIntFormat, TexWidth, TexHeight, 0, + GL_RGBA, GL_UNSIGNED_BYTE, NULL); + glTexImage2D(TexTarget, 1, TexIntFormat, TexWidth/2, TexHeight/2, 0, + GL_RGBA, GL_UNSIGNED_BYTE, NULL); + TexWidth = TexWidth >> TextureLevel; + TexHeight = TexHeight >> TextureLevel; + + glTexParameteri(TexTarget, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(TexTarget, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameteri(TexTarget, GL_TEXTURE_BASE_LEVEL, TextureLevel); + glTexParameteri(TexTarget, GL_TEXTURE_MAX_LEVEL, TextureLevel); + glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); + } + + MyFB = MakeFBO_RenderTexture(TexObj); +} + + +static void +Usage(void) +{ + printf("Usage:\n"); + printf(" -ds Use combined depth/stencil renderbuffer\n"); + printf(" -arb Try GL_ARB_framebuffer_object's mismatched buffer sizes\n"); + printf(" -ds2 Tye GL_ARB_framebuffer_object's GL_DEPTH_STENCIL_ATTACHMENT\n"); + printf("Keys:\n"); + printf(" a Toggle animation\n"); + printf(" s/s Step/rotate\n"); + printf(" c Toggle back-face culling\n"); + printf(" w Toggle wireframe mode (front-face only)\n"); + printf(" Esc Exit\n"); } @@ -401,7 +599,11 @@ main(int argc, char *argv[]) glutDisplayFunc(Display); if (Anim) glutIdleFunc(Idle); - Init(argc, argv); + + ParseArgs(argc, argv); + Init(); + Usage(); + glutMainLoop(); return 0; } diff --git a/progs/tests/floattex.c b/progs/tests/floattex.c index 2345a49b27..dd6d882089 100644 --- a/progs/tests/floattex.c +++ b/progs/tests/floattex.c @@ -9,32 +9,37 @@ #include <stdlib.h> #include <math.h> #include <GL/glut.h> +#include "extfuncs.h" +#include "readtex.h" +#include "shaderutil.h" -/* XXX - temporary */ -#ifndef GL_ARB_texture_float -#define GL_ARB_texture_float 1 -#define GL_TEXTURE_RED_TYPE_ARB 0x9000 -#define GL_TEXTURE_GREEN_TYPE_ARB 0x9001 -#define GL_TEXTURE_BLUE_TYPE_ARB 0x9002 -#define GL_TEXTURE_ALPHA_TYPE_ARB 0x9003 -#define GL_TEXTURE_LUMINANCE_TYPE_ARB 0x9004 -#define GL_TEXTURE_INTENSITY_TYPE_ARB 0x9005 -#define GL_TEXTURE_DEPTH_TYPE_ARB 0x9006 -#define GL_UNSIGNED_NORMALIZED_ARB 0x9007 -#define GL_RGBA32F_ARB 0x8814 -#define GL_RGB32F_ARB 0x8815 -#define GL_ALPHA32F_ARB 0x8816 -#define GL_INTENSITY32F_ARB 0x8817 -#define GL_LUMINANCE32F_ARB 0x8818 -#define GL_LUMINANCE_ALPHA32F_ARB 0x8819 -#define GL_RGBA16F_ARB 0x881A -#define GL_RGB16F_ARB 0x881B -#define GL_ALPHA16F_ARB 0x881C -#define GL_INTENSITY16F_ARB 0x881D -#define GL_LUMINANCE16F_ARB 0x881E -#define GL_LUMINANCE_ALPHA16F_ARB 0x881F -#endif +static const char *TexFile = "../images/arch.rgb"; + +static const char *FragShaderText = + "uniform sampler2D tex1; \n" + "void main() \n" + "{ \n" + " vec4 t = texture2D(tex1, gl_TexCoord[0].xy); \n" + " // convert from [-255,0] to [0,1] \n" + " gl_FragColor = t * (-1.0 / 255.0); \n" + "} \n"; + +static const char *VertShaderText = + "void main() \n" + "{ \n" + " gl_TexCoord[0] = gl_MultiTexCoord0; \n" + " gl_Position = ftransform(); \n" + "} \n"; + +static struct uniform_info Uniforms[] = { + { "tex1", 1, GL_INT, { 0, 0, 0, 0 }, -1 }, + END_OF_UNIFORMS +}; + + +static GLuint Program; + static GLboolean @@ -57,7 +62,12 @@ Draw(void) glPushMatrix(); - glutSolidCube(2.0); + 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(); @@ -74,7 +84,7 @@ Reshape(int width, int height) glFrustum(-1.0, 1.0, -1.0, 1.0, 5.0, 25.0); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); - glTranslatef(0.0, 0.0, -15.0); + glTranslatef(0.0, 0.0, -8.0); } @@ -94,31 +104,43 @@ Key(unsigned char key, int x, int y) static void -Init(void) +InitTexture(void) { - GLfloat tex[16][16][4]; - GLfloat tex2[16][16][4]; - GLint i, j, t; + GLenum filter = GL_LINEAR; + GLint imgWidth, imgHeight; + GLenum imgFormat; + GLubyte *image = NULL; + GLfloat *ftex; + GLint i, t; + + image = LoadRGBImage(TexFile, &imgWidth, &imgHeight, &imgFormat); + if (!image) { + printf("Couldn't read %s\n", TexFile); + exit(0); + } - if (!glutExtensionSupported("GL_MESAX_texture_float")) { - printf("Sorry, this test requires GL_MESAX_texture_float\n"); - exit(1); + assert(imgFormat == GL_RGB); + + ftex = (float *) malloc(imgWidth * imgHeight * 4 * sizeof(float)); + if (!ftex) { + printf("out of memory\n"); + exit(0); } - for (i = 0; i < 16; i++) { - for (j = 0; j < 16; j++) { - GLfloat s = i / 15.0; - tex[i][j][0] = s; - tex[i][j][1] = 2.0 * s; - tex[i][j][2] = -3.0 * s; - tex[i][j][3] = 4.0 * s; - } + /* convert ubytes to floats, negated */ + for (i = 0; i < imgWidth * imgHeight * 3; i++) { + ftex[i] = -1.0f * image[i]; } - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F_ARB, 16, 16, 0, GL_RGBA, - GL_FLOAT, tex); - CheckError(__LINE__); + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, 42); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F_ARB, + imgWidth, imgHeight, 0, + GL_RGB, GL_FLOAT, ftex); + + + /* sanity checks */ glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_RED_TYPE_ARB, &t); assert(t == GL_FLOAT); glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_GREEN_TYPE_ARB, &t); @@ -128,8 +150,15 @@ Init(void) glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_ALPHA_TYPE_ARB, &t); assert(t == GL_FLOAT); - CheckError(__LINE__); + free(image); + free(ftex); + + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filter); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filter); +#if 0 /* read back the texture and make sure values are correct */ glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_FLOAT, tex2); CheckError(__LINE__); @@ -147,8 +176,49 @@ Init(void) } } } +#endif +} + + +static GLuint +CreateProgram(void) +{ + GLuint fragShader, vertShader, program; + + vertShader = CompileShaderText(GL_VERTEX_SHADER, VertShaderText); + fragShader = CompileShaderText(GL_FRAGMENT_SHADER, FragShaderText); + assert(vertShader); + program = LinkShaders(vertShader, fragShader); + + assert(program); + + // InitUniforms(program, Uniforms); + + return program; +} + + +static void +Init(void) +{ + glClearColor(0.25, 0.25, 0.25, 0.0); + + GetExtensionFuncs(); + + if (!ShadersSupported()) { + printf("Sorry, this test requires GLSL\n"); + exit(1); + } + + if (!glutExtensionSupported("GL_MESAX_texture_float")) { + printf("Sorry, this test requires GL_MESAX_texture_float\n"); + exit(1); + } + InitTexture(); + Program = CreateProgram(); + glUseProgram_func(Program); } diff --git a/progs/tests/lineclip.c b/progs/tests/lineclip.c new file mode 100644 index 0000000000..098f5e92eb --- /dev/null +++ b/progs/tests/lineclip.c @@ -0,0 +1,175 @@ +/* + * Copyright © 2008 Intel Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + * + * Authors: + * Eric Anholt <eric@anholt.net> + * + */ + +#include <stdlib.h> +#include <GL/glut.h> + +static int win_width, win_height; + +static void +line(GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2) +{ + glBegin(GL_LINES); + glVertex2f(x1, y1); + glVertex2f(x2, y2); + glEnd(); +} + +static void +line3(GLfloat x1, GLfloat y1, GLfloat z1, GLfloat x2, GLfloat y2, GLfloat z2) +{ + glBegin(GL_LINES); + glVertex3f(x1, y1, z1); + glVertex3f(x2, y2, z2); + glEnd(); +} + +static void +display(void) +{ + glClearColor(0.0, 0.0, 0.0, 0.0); + glClear(GL_COLOR_BUFFER_BIT); + + glColor3f(1.0, 0.0, 0.0); + /* 2 lines clipped along xmin */ + line(-20, win_height / 2 - 20, + 20, win_height / 2 - 20); + line( 20, win_height / 2 + 20, + -20, win_height / 2 + 20); + + glColor3f(0.0, 1.0, 0.0); + /* 2 lines clipped along ymax */ + line(win_width / 2 - 20, win_height + 20, + win_width / 2 - 20, win_height - 20); + line(win_width / 2 + 20, win_height - 20, + win_width / 2 + 20, win_height + 20); + + glColor3f(0.0, 0.0, 1.0); + /* 2 lines clipped along xmax */ + line(win_width - 20, win_height / 2 - 20, + win_width + 20, win_height / 2 - 20); + line(win_width + 20, win_height / 2 + 20, + win_width - 20, win_height / 2 + 20); + + glColor3f(1.0, 1.0, 1.0); + /* 2 lines clipped along ymin */ + line(win_width / 2 - 20, 20, + win_width / 2 - 20, -20); + line(win_width / 2 + 20, -20, + win_width / 2 + 20, 20); + + /* 2 lines clipped along near */ + glColor3f(1.0, 0.0, 1.0); + line3(win_width / 2 - 20 - 20, win_height / 2, 0.5, + win_width / 2 - 20 + 20, win_height / 2, -0.5); + line3(win_width / 2 - 20, win_height / 2 - 20, -0.5, + win_width / 2 - 20, win_height / 2 + 20, 0.5); + + /* 2 lines clipped along far */ + glColor3f(0.0, 1.0, 1.0); + line3(win_width / 2 + 20 - 20, win_height / 2, 1.5, + win_width / 2 + 20 + 20, win_height / 2, 0.5); + line3(win_width / 2 + 20, win_height / 2 - 20, 0.5, + win_width / 2 + 20, win_height / 2 + 20, 1.5); + + /* entirely clipped along near/far */ + glColor3f(.5, .5, .5); + line3(win_width / 2, win_height / 2 - 20, -0.5, + win_width / 2, win_height / 2 + 20, -0.5); + glColor3f(.5, .5, .5); + line3(win_width / 2, win_height / 2 - 20, 1.5, + win_width / 2, win_height / 2 + 20, 1.5); + + glColor3f(1.0, 1.0, 0.0); + /* lines clipped along both x and y limits */ + line(-5, 20, + 20, -5); /* xmin, ymin */ + line(-5, win_height - 20, + 20, win_height + 5); /* xmin, ymax */ + line(win_width - 20, -5, + win_width + 5, 20); /* xmax, ymin */ + line(win_width - 20, win_height + 5, + win_width + 5, win_height - 20); /* xmax, ymax */ + + glutSwapBuffers(); +} + +static void +reshape(int width, int height) +{ + win_width = width; + win_height = height; + glViewport(0, 0, width, height); + + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + glOrtho(0, win_width, 0, win_height, 0.0, -1.0); + + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + glTranslatef(.25, .25, 0); +} + +static void key( unsigned char key, int x, int y ) +{ + (void) x; + (void) y; + + switch (key) { + case 27: /* esc */ + exit(0); + break; + } + + glutPostRedisplay(); +} + +static void +init(void) +{ +} + +int +main(int argc, char *argv[]) +{ + win_width = 200; + win_height = 200; + + glutInit(&argc, argv); + glutInitWindowPosition(0, 0); + glutInitWindowSize(win_width, win_height); + glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH); + glutCreateWindow(argv[0]); + glutReshapeFunc(reshape); + glutKeyboardFunc(key); + glutDisplayFunc(display); + + init(); + + glutMainLoop(); + return 0; +} diff --git a/progs/tests/multipal.c b/progs/tests/multipal.c index 52818fca7e..7bd4473565 100644 --- a/progs/tests/multipal.c +++ b/progs/tests/multipal.c @@ -8,11 +8,7 @@ #include <stdio.h> #include <stdlib.h> #include <string.h> -#ifdef __VMS -# include <stddef.h> /* for ptrdiff_t, referenced by GL.h when GL_GLEXT_LEGACY defined */ -#else -# include <malloc.h> /* for ptrdiff_t, referenced by GL.h when GL_GLEXT_LEGACY defined */ -#endif +#include <stddef.h> /* for ptrdiff_t, referenced by GL.h when GL_GLEXT_LEGACY defined */ #ifdef _WIN32 #include <windows.h> #endif diff --git a/progs/tests/rubberband.c b/progs/tests/rubberband.c new file mode 100644 index 0000000000..a8e64bc091 --- /dev/null +++ b/progs/tests/rubberband.c @@ -0,0 +1,245 @@ +/** + * Test rubber-band selection box w/ logicops and blend. + */ + +#define GL_GLEXT_PROTOTYPES +#include <stdio.h> +#include <stdlib.h> +#include <math.h> +#include <GL/glut.h> +#include "readtex.c" + +#define IMAGE_FILE "../images/arch.rgb" + +static int ImgWidth, ImgHeight; +static GLenum ImgFormat; +static GLubyte *Image = NULL; + +static int Win; +static int Width = 512, Height = 512; + +struct rect +{ + int x0, y0, x1, y1; +}; + +static struct rect OldRect, NewRect; + +static GLboolean ButtonDown = GL_FALSE; +static GLboolean LogicOp = 0*GL_TRUE; + +static GLboolean RedrawBackground = GL_TRUE; + +static const GLfloat red[4] = {1.0, 0.2, 0.2, 1.0}; +static const GLfloat green[4] = {0.2, 1.0, 0.2, 1.0}; +static const GLfloat blue[4] = {0.2, 0.2, 1.0, 1.0}; + + +/* + * Draw rubberband box in front buffer + */ +static void +DrawRect(const struct rect *r) +{ + glDrawBuffer(GL_FRONT); + + if (LogicOp) { + glLogicOp(GL_XOR); + glEnable(GL_COLOR_LOGIC_OP); + } + else { + glEnable(GL_BLEND); + glBlendFunc(GL_ONE, GL_ONE); + glBlendEquation(GL_FUNC_SUBTRACT); + } + + glColor3f(1, 1, 1); + + glLineWidth(3.0); + + glBegin(GL_LINE_LOOP); + glVertex2i(r->x0, r->y0); + glVertex2i(r->x1, r->y0); + glVertex2i(r->x1, r->y1); + glVertex2i(r->x0, r->y1); + glEnd(); + + glDisable(GL_COLOR_LOGIC_OP); + glDisable(GL_BLEND); + + glDrawBuffer(GL_BACK); +} + + +static void +PrintString(const char *s) +{ + while (*s) { + glutBitmapCharacter(GLUT_BITMAP_8_BY_13, (int) *s); + s++; + } +} + + +static void +DrawBackground(void) +{ + char s[100]; + + sprintf(s, "[L/B] %s mode. Use mouse to make selection box.", + LogicOp ? "LogicOp" : "Blend"); + + glClear(GL_COLOR_BUFFER_BIT); + + glWindowPos2i((Width - ImgWidth) / 2, (Height - ImgHeight) / 2); + glDrawPixels(ImgWidth, ImgHeight, ImgFormat, GL_UNSIGNED_BYTE, Image); + + glWindowPos2i(10, 10); + PrintString(s); + + glutSwapBuffers(); +} + + +static void +Draw(void) +{ + if (RedrawBackground) { + DrawBackground(); + } + + if (ButtonDown) { + if (!RedrawBackground) + DrawRect(&OldRect); /* erase old */ + + DrawRect(&NewRect); /* draw new */ + + OldRect = NewRect; + } + + RedrawBackground = GL_FALSE; +} + + +static void +Reshape(int width, int height) +{ + Width = width; + Height = height; + + glViewport(0, 0, width, height); + + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + glOrtho(0, Width, Height, 0, -1, 1); /* Inverted Y! */ + + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + + RedrawBackground = GL_TRUE; +} + + +static void +Key(unsigned char key, int x, int y) +{ + (void) x; + (void) y; + switch (key) { + case 'b': + case 'B': + LogicOp = GL_FALSE; + break; + case 'l': + case 'L': + LogicOp = GL_TRUE; + break; + case 27: + glutDestroyWindow(Win); + exit(0); + break; + } + RedrawBackground = GL_TRUE; + glutPostRedisplay(); +} + + +static void +SpecialKey(int key, int x, int y) +{ + (void) x; + (void) y; + switch (key) { + case GLUT_KEY_UP: + break; + case GLUT_KEY_DOWN: + break; + case GLUT_KEY_LEFT: + break; + case GLUT_KEY_RIGHT: + break; + } + glutPostRedisplay(); +} + + +static void +MouseMotion(int x, int y) +{ + if (ButtonDown) { + NewRect.x1 = x; + NewRect.y1 = y; + glutPostRedisplay(); + } +} + + +static void +MouseButton(int button, int state, int x, int y) +{ + if (button == GLUT_LEFT_BUTTON && state == GLUT_DOWN) { + ButtonDown = GL_TRUE; + RedrawBackground = GL_TRUE; + NewRect.x0 = NewRect.x1 = x; + NewRect.y0 = NewRect.y1 = y; + OldRect = NewRect; + } + else if (button == GLUT_LEFT_BUTTON && state == GLUT_UP) { + ButtonDown = GL_FALSE; + } + glutPostRedisplay(); +} + + +static void +Init(void) +{ + Image = LoadRGBImage(IMAGE_FILE, &ImgWidth, &ImgHeight, &ImgFormat); + if (!Image) { + printf("Couldn't read %s\n", IMAGE_FILE); + exit(0); + } + + glPixelStorei(GL_UNPACK_ALIGNMENT, 1); + glPixelStorei(GL_PACK_ALIGNMENT, 1); +} + + +int +main(int argc, char *argv[]) +{ + glutInit(&argc, argv); + glutInitWindowSize(Width, Height); + glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE); + Win = glutCreateWindow(argv[0]); + glutReshapeFunc(Reshape); + glutKeyboardFunc(Key); + glutSpecialFunc(SpecialKey); + glutMotionFunc(MouseMotion); + glutMouseFunc(MouseButton); + glutDisplayFunc(Draw); + Init(); + glutPostRedisplay(); + glutMainLoop(); + return 0; +} diff --git a/progs/tests/shader_api.c b/progs/tests/shader_api.c new file mode 100644 index 0000000000..679f9137c8 --- /dev/null +++ b/progs/tests/shader_api.c @@ -0,0 +1,337 @@ +/* Tests to validate fixes to various bugs in src/mesa/shader/shader_api.c + * + * Written by Bruce Merry + */ +#include <string.h> +#include <stdio.h> +#include <stdlib.h> +#define GL_GLEXT_PROTOTYPES +#include <GL/glut.h> + +static void assert_test(const char *file, int line, int cond, const char *msg) +{ + if (!cond) + fprintf(stderr, "%s:%d assertion \"%s\" failed\n", file, line, msg); +} + +#undef assert +#define assert(x) assert_test(__FILE__, __LINE__, (x), #x) + +static void assert_no_error_test(const char *file, int line) +{ + GLenum err; + + err = glGetError(); + if (err != GL_NO_ERROR) + fprintf(stderr, "%s:%d received error %s\n", + file, line, gluErrorString(err)); +} + +#define assert_no_error() assert_no_error_test(__FILE__, __LINE__) + +static void assert_error_test(const char *file, int line, GLenum expect) +{ + GLenum err; + + err = glGetError(); + if (err != expect) + fprintf(stderr, "%s:%d expected %s but received %s\n", + file, line, gluErrorString(expect), gluErrorString(err)); + while (glGetError()); /* consume any following errors */ +} + +#define assert_error(err) assert_error_test(__FILE__, __LINE__, (err)) + +static void check_status(GLuint id, GLenum pname, void (*query)(GLuint, GLenum, GLint *)) +{ + GLint status; + + query(id, pname, &status); + if (!status) + { + char info[65536]; + + fprintf(stderr, "Compilation/link failure:\n"); + glGetInfoLogARB(id, sizeof(info), NULL, info); + fprintf(stderr, "%s\n", info); + exit(1); + } +} + +static void check_compile_status(GLuint id) +{ + check_status(id, GL_COMPILE_STATUS, glGetShaderiv); +} + +static void check_link_status(GLuint id) +{ + check_status(id, GL_LINK_STATUS, glGetProgramiv); +} + +static GLuint make_shader(GLenum type, const char *src) +{ + GLuint id; + + assert_no_error(); + id = glCreateShader(type); + glShaderSource(id, 1, &src, NULL); + glCompileShader(id); + check_compile_status(id); + assert_no_error(); + return id; +} + +static GLuint make_program(const char *vs_src, const char *fs_src) +{ + GLuint id, vs, fs; + + assert_no_error(); + id = glCreateProgram(); + if (vs_src) { + vs = make_shader(GL_VERTEX_SHADER, vs_src); + glAttachShader(id, vs); + glDeleteShader(vs); + } + if (fs_src) { + fs = make_shader(GL_FRAGMENT_SHADER, fs_src); + glAttachShader(id, fs); + glDeleteShader(fs); + } + glLinkProgram(id); + check_link_status(id); + glUseProgram(id); + glDeleteProgram(id); + assert_no_error(); + return id; +} + +static void test_uniform_size_type1(const char *glslType, GLenum glType, const char *el) +{ + char buffer[1024]; + GLuint program; + GLint active, i; + GLenum type; + GLint size; + + printf(" Running subtest %s\n", glslType); + fflush(stdout); + sprintf(buffer, "#version 120\nuniform %s m[60];\nvoid main() { gl_Position[0] = m[59]%s; }\n", + glslType, el); + + program = make_program(buffer, NULL); + glGetProgramiv(program, GL_ACTIVE_UNIFORMS, &active); + assert_no_error(); + for (i = 0; i < active; i++) { + size = -1; + type = 0; + glGetActiveUniform(program, i, sizeof(buffer), NULL, &size, &type, buffer); + assert_no_error(); + if (strncmp(buffer, "m", 1) == 0) + break; + } + assert(i < active); /* Otherwise the compiler optimised it out */ + assert(type == glType); + assert(size == 60); +} + +static void test_uniform_size_type(void) +{ + test_uniform_size_type1("float", GL_FLOAT, ""); + test_uniform_size_type1("vec2", GL_FLOAT_VEC2, "[0]"); + test_uniform_size_type1("vec3", GL_FLOAT_VEC3, "[0]"); + test_uniform_size_type1("vec4", GL_FLOAT_VEC4, "[0]"); + + test_uniform_size_type1("bool", GL_BOOL, " ? 1.0 : 0.0"); + test_uniform_size_type1("bvec2", GL_BOOL_VEC2, "[0] ? 1.0 : 0.0"); + test_uniform_size_type1("bvec3", GL_BOOL_VEC3, "[0] ? 1.0 : 0.0"); + test_uniform_size_type1("bvec4", GL_BOOL_VEC4, "[0] ? 1.0 : 0.0"); + + test_uniform_size_type1("int", GL_INT, ""); + test_uniform_size_type1("ivec2", GL_INT_VEC2, "[0]"); + test_uniform_size_type1("ivec3", GL_INT_VEC3, "[0]"); + test_uniform_size_type1("ivec4", GL_INT_VEC4, "[0]"); + + test_uniform_size_type1("mat2", GL_FLOAT_MAT2, "[0][0]"); + test_uniform_size_type1("mat3", GL_FLOAT_MAT3, "[0][0]"); + test_uniform_size_type1("mat4", GL_FLOAT_MAT4, "[0][0]"); + test_uniform_size_type1("mat2x3", GL_FLOAT_MAT2x3, "[0][0]"); + test_uniform_size_type1("mat2x4", GL_FLOAT_MAT2x4, "[0][0]"); + test_uniform_size_type1("mat3x2", GL_FLOAT_MAT3x2, "[0][0]"); + test_uniform_size_type1("mat3x4", GL_FLOAT_MAT3x4, "[0][0]"); + test_uniform_size_type1("mat4x2", GL_FLOAT_MAT4x2, "[0][0]"); + test_uniform_size_type1("mat4x3", GL_FLOAT_MAT4x3, "[0][0]"); +} + +static void test_attrib_size_type1(const char *glslType, GLenum glType, const char *el) +{ + char buffer[1024]; + GLuint program; + GLint active, i; + GLenum type; + GLint size; + + printf(" Running subtest %s\n", glslType); + fflush(stdout); + sprintf(buffer, "#version 120\nattribute %s m;\nvoid main() { gl_Position[0] = m%s; }\n", + glslType, el); + + program = make_program(buffer, NULL); + glGetProgramiv(program, GL_ACTIVE_ATTRIBUTES, &active); + assert_no_error(); + for (i = 0; i < active; i++) { + size = -1; + type = -1; + glGetActiveAttrib(program, i, sizeof(buffer), NULL, &size, &type, buffer); + assert_no_error(); + if (strncmp(buffer, "m", 1) == 0) + break; + } + assert(i < active); /* Otherwise the compiler optimised it out */ + assert(type == glType); + assert(size == 1); +} + +static void test_attrib_size_type(void) +{ + test_attrib_size_type1("float", GL_FLOAT, ""); + test_attrib_size_type1("vec2", GL_FLOAT_VEC2, "[0]"); + test_attrib_size_type1("vec3", GL_FLOAT_VEC3, "[0]"); + test_attrib_size_type1("vec4", GL_FLOAT_VEC4, "[0]"); + + test_attrib_size_type1("mat2", GL_FLOAT_MAT2, "[0][0]"); + test_attrib_size_type1("mat3", GL_FLOAT_MAT3, "[0][0]"); + test_attrib_size_type1("mat4", GL_FLOAT_MAT4, "[0][0]"); + test_attrib_size_type1("mat2x3", GL_FLOAT_MAT2x3, "[0][0]"); + test_attrib_size_type1("mat2x4", GL_FLOAT_MAT2x4, "[0][0]"); + test_attrib_size_type1("mat3x2", GL_FLOAT_MAT3x2, "[0][0]"); + test_attrib_size_type1("mat3x4", GL_FLOAT_MAT3x4, "[0][0]"); + test_attrib_size_type1("mat4x2", GL_FLOAT_MAT4x2, "[0][0]"); + test_attrib_size_type1("mat4x3", GL_FLOAT_MAT4x3, "[0][0]"); +} + +static void test_uniform_array_overflow(void) +{ + GLuint program; + GLint location; + GLfloat data[128]; + + program = make_program("#version 120\nuniform vec2 x[10];\nvoid main() { gl_Position.xy = x[9]; }\n", NULL); + location = glGetUniformLocation(program, "x"); + assert_no_error(); + glUniform2fv(location, 64, data); + assert_no_error(); +} + +static void test_uniform_scalar_count(void) +{ + GLuint program; + GLint location; + GLfloat data[128]; + + program = make_program("#version 110\nuniform vec2 x;\nvoid main() { gl_Position.xy = x; }\n", NULL); + location = glGetUniformLocation(program, "x"); + assert_no_error(); + glUniform2fv(location, 64, data); + assert_error(GL_INVALID_OPERATION); +} + +static void test_uniform_query_matrix(void) +{ + GLuint program; + GLfloat data[18]; + GLint i, r, c; + GLint location; + + program = make_program("#version 110\nuniform mat3 m[2];\nvoid main() { gl_Position.xyz = m[1][2]; }\n", NULL); + location = glGetUniformLocation(program, "m"); + for (i = 0; i < 9; i++) + data[i] = i; + for (i = 9; i < 18; i++) + data[i] = 321.0; + glUniformMatrix3fv(location, 1, GL_TRUE, data); + + for (i = 0; i < 18; i++) + data[i] = 123.0; + glGetUniformfv(program, location, data); + for (c = 0; c < 3; c++) + for (r = 0; r < 3; r++) + assert(data[c * 3 + r] == r * 3 + c); + for (i = 9; i < 18; i++) + assert(data[i] == 123.0); +} + +static void test_uniform_neg_location(void) +{ + GLuint program; + GLfloat data[4]; + + program = make_program("#version 110\nvoid main() { gl_Position = vec4(1.0, 1.0, 1.0, 1.0); }\n", NULL); + assert_no_error(); + glUniform1i(-1, 1); + assert_no_error(); + glUniform1i(-200, 1); + assert_error(GL_INVALID_OPERATION); + glUniformMatrix2fv(-1, 1, GL_FALSE, data); + assert_no_error(); + glUniformMatrix2fv(-200, 1, GL_FALSE, data); + assert_error(GL_INVALID_OPERATION); +} + +static void test_uniform_bool_conversion(void) +{ + GLuint program; + GLint location; + GLint value[16]; /* in case glGetUniformiv goes nuts on the stack */ + + assert_no_error(); + program = make_program("uniform bool b;\nvoid main() { gl_Position.x = b ? 1.5 : 0.5; }\n", NULL); + location = glGetUniformLocation(program, "b"); + assert(location != -1); + assert_no_error(); + glUniform1i(location, 5); + assert_no_error(); + glGetUniformiv(program, location, &value[0]); + assert_no_error(); + assert(value[0] == 1); +} + +static void test_uniform_multiple_samplers(void) +{ + GLuint program; + GLint location; + GLint values[2] = {0, 1}; + + assert_no_error(); + program = make_program(NULL, "uniform sampler2D s[2];\nvoid main() { gl_FragColor = texture2D(s[1], vec2(0.0, 0.0)); }\n"); + location = glGetUniformLocation(program, "s[0]"); + assert(location != -1); + assert_no_error(); + glUniform1iv(location, 2, values); + assert_no_error(); +} + +static void run_test(const char *name, void (*callback)(void)) +{ + printf("Running %s\n", name); + fflush(stdout); + callback(); +} + +#define RUN_TEST(name) run_test(#name, (name)) + +int main(int argc, char **argv) +{ + glutInit(&argc, argv); + glutCreateWindow("Mesa bug demo"); + + RUN_TEST(test_uniform_size_type); + RUN_TEST(test_attrib_size_type); + RUN_TEST(test_uniform_array_overflow); + RUN_TEST(test_uniform_scalar_count); + RUN_TEST(test_uniform_query_matrix); + RUN_TEST(test_uniform_neg_location); + RUN_TEST(test_uniform_bool_conversion); + /* Leave this one at the end, since it crashes Mesa's shader compiler */ + RUN_TEST(test_uniform_multiple_samplers); + return 0; +} diff --git a/progs/tests/stencil_twoside.c b/progs/tests/stencil_twoside.c new file mode 100644 index 0000000000..8826c46fc2 --- /dev/null +++ b/progs/tests/stencil_twoside.c @@ -0,0 +1,297 @@ +/* + * (C) Copyright IBM Corporation 2004 + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * on the rights to use, copy, modify, merge, publish, distribute, sub + * license, and/or sell copies of the Software, and to permit persons to whom + * the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL + * VA LINUX SYSTEM, IBM AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE + * USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +/** + * \file stencil_twoside.c + * + * Simple test of GL_ATI_separate_stencil (or the OGL 2.0 equivalent) functionality. + * Four squares are drawn + * with different stencil modes, but all should be rendered with the same + * final color. + */ + +#include <stdio.h> +#include <stdlib.h> +#include <GL/glut.h> + +static int use20syntax = 1; +static int Width = 550; +static int Height = 200; +static const GLfloat Near = 5.0, Far = 25.0; + + +static PFNGLSTENCILFUNCSEPARATEPROC stencil_func_separate = NULL; +static PFNGLSTENCILFUNCSEPARATEATIPROC stencil_func_separate_ati = NULL; +static PFNGLSTENCILOPSEPARATEPROC stencil_op_separate = NULL; + +static void Display( void ) +{ + GLint max_stencil; + GLint stencil_bits; + unsigned i; + + + glGetIntegerv( GL_STENCIL_BITS, & stencil_bits ); + max_stencil = (1U << stencil_bits) - 1; + printf( "Stencil bits = %u, maximum stencil value = 0x%08x\n", + stencil_bits, max_stencil ); + + glClearStencil( 1 ); + glClearColor( 0.2, 0.2, 0.8, 0 ); + glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT + | GL_STENCIL_BUFFER_BIT ); + + + glPushMatrix(); + + /* This is the "reference" square. + */ + + glDisable(GL_STENCIL_TEST); + glTranslatef(-6.0, 0, 0); + glBegin(GL_QUADS); + glColor3f( 0.5, 0.5, 0.5 ); + glVertex2f(-1, -1); + glVertex2f( 1, -1); + glVertex2f( 1, 1); + glVertex2f(-1, 1); + glEnd(); + + + glEnable(GL_STENCIL_TEST); + + /* Draw the first two squares using incr for the affected face + */ + + if (use20syntax) { + stencil_func_separate(GL_FRONT, GL_ALWAYS, 0, ~0); + stencil_func_separate(GL_BACK, GL_ALWAYS, 0, ~0); + } + else { + stencil_func_separate_ati(GL_ALWAYS, GL_ALWAYS, 0, ~0); + } + stencil_op_separate(GL_FRONT, GL_KEEP, GL_KEEP, GL_INCR); + stencil_op_separate(GL_BACK, GL_KEEP, GL_KEEP, GL_DECR); + + glTranslatef(3.0, 0, 0); + glBegin(GL_QUADS); + glColor3f( 0.9, 0.9, 0.9 ); + /* this should be front facing */ + for ( i = 0 ; i < (max_stencil + 5) ; i++ ) { + glVertex2f(-1, -1); + glVertex2f( 1, -1); + glVertex2f( 1, 1); + glVertex2f(-1, 1); + } + glEnd(); + + glStencilFunc(GL_EQUAL, max_stencil, ~0); + glBegin(GL_QUADS); + glColor3f( 0.5, 0.5, 0.5 ); + glVertex2f(-1, -1); + glVertex2f( 1, -1); + glVertex2f( 1, 1); + glVertex2f(-1, 1); + glEnd(); + + if (use20syntax) { + stencil_func_separate(GL_FRONT, GL_ALWAYS, 0, ~0); + stencil_func_separate(GL_BACK, GL_ALWAYS, 0, ~0); + } + else { + stencil_func_separate_ati(GL_ALWAYS, GL_ALWAYS, 0, ~0); + } + stencil_op_separate(GL_FRONT, GL_KEEP, GL_KEEP, GL_DECR); + stencil_op_separate(GL_BACK, GL_KEEP, GL_KEEP, GL_INCR); + + glTranslatef(3.0, 0, 0); + glBegin(GL_QUADS); + glColor3f( 0.9, 0.9, 0.9 ); + + /* this should be back facing */ + for ( i = 0 ; i < (max_stencil + 5) ; i++ ) { + glVertex2f(-1, -1); + glVertex2f(-1, 1); + glVertex2f( 1, 1); + glVertex2f( 1, -1); + } + glEnd(); + + glStencilFunc(GL_EQUAL, max_stencil, ~0); + glBegin(GL_QUADS); + glColor3f( 0.5, 0.5, 0.5 ); + glVertex2f(-1, -1); + glVertex2f( 1, -1); + glVertex2f( 1, 1); + glVertex2f(-1, 1); + glEnd(); + + if (use20syntax) { + stencil_func_separate(GL_FRONT, GL_NEVER, 0, ~0); + stencil_func_separate(GL_BACK, GL_ALWAYS, 0, ~0); + } + else { + stencil_func_separate_ati(GL_NEVER, GL_ALWAYS, 0, ~0); + } + stencil_op_separate(GL_FRONT, GL_KEEP, GL_KEEP, GL_DECR); + stencil_op_separate(GL_BACK, GL_KEEP, GL_KEEP, GL_INCR); + + glTranslatef(3.0, 0, 0); + glBegin(GL_QUADS); + glColor3f( 0.9, 0.9, 0.9 ); + + /* this should be back facing */ + for ( i = 0 ; i < (max_stencil + 5) ; i++ ) { + /* this should be back facing */ + glVertex2f(-1, -1); + glVertex2f(-1, 1); + glVertex2f( 1, 1); + glVertex2f( 1, -1); + /* this should be front facing */ + glVertex2f(-1, -1); + glVertex2f( 1, -1); + glVertex2f( 1, 1); + glVertex2f(-1, 1); + } + glEnd(); + + glStencilFunc(GL_EQUAL, max_stencil, ~0); + glBegin(GL_QUADS); + glColor3f( 0.5, 0.5, 0.5 ); + glVertex2f(-1, -1); + glVertex2f( 1, -1); + glVertex2f( 1, 1); + glVertex2f(-1, 1); + glEnd(); + + if (use20syntax) { + stencil_func_separate(GL_FRONT, GL_ALWAYS, 0, ~0); + stencil_func_separate(GL_BACK, GL_ALWAYS, 0, ~0); + } + else { + stencil_func_separate_ati(GL_ALWAYS, GL_ALWAYS, 0, ~0); + } + stencil_op_separate(GL_FRONT, GL_KEEP, GL_KEEP, GL_DECR); + stencil_op_separate(GL_BACK, GL_KEEP, GL_KEEP, GL_INCR); + + glTranslatef(3.0, 0, 0); + glBegin(GL_QUADS); + glColor3f( 0.9, 0.9, 0.9 ); + + /* this should be back facing */ + for ( i = 0 ; i < (max_stencil + 5) ; i++ ) { + /* this should be back facing */ + glVertex2f(-1, -1); + glVertex2f(-1, 1); + glVertex2f( 1, 1); + glVertex2f( 1, -1); + /* this should be front facing */ + glVertex2f(-1, -1); + glVertex2f( 1, -1); + glVertex2f( 1, 1); + glVertex2f(-1, 1); + } + glEnd(); + + glStencilFunc(GL_EQUAL, 1, ~0); + glBegin(GL_QUADS); + glColor3f( 0.5, 0.5, 0.5 ); + glVertex2f(-1, -1); + glVertex2f( 1, -1); + glVertex2f( 1, 1); + glVertex2f(-1, 1); + glEnd(); + + glPopMatrix(); + + glutSwapBuffers(); +} + + +static void Reshape( int width, int height ) +{ + GLfloat ar = (float) width / (float) height; + Width = width; + Height = height; + glViewport( 0, 0, width, height ); + glMatrixMode( GL_PROJECTION ); + glLoadIdentity(); + glFrustum( -ar, ar, -1.0, 1.0, Near, Far ); + glMatrixMode( GL_MODELVIEW ); + glLoadIdentity(); + glTranslatef( 0.0, 0.0, -15.0 ); +} + + +static void Key( unsigned char key, int x, int y ) +{ + (void) x; + (void) y; + switch (key) { + case 27: + exit(0); + break; + } + glutPostRedisplay(); +} + + +static void Init( void ) +{ + const char * const ver_string = (const char * const) + glGetString( GL_VERSION ); + + printf("GL_RENDERER = %s\n", (char *) glGetString(GL_RENDERER)); + printf("GL_VERSION = %s\n", ver_string); + + if ( !glutExtensionSupported("GL_ATI_separate_stencil") + && (atof( ver_string ) < 2.0) ) { + printf("Sorry, this program requires either GL_ATI_separate_stencil or OpenGL 2.0.\n"); + exit(1); + } + if (atof( ver_string ) < 2.0) { + use20syntax = 0; + } + stencil_func_separate = glutGetProcAddress( "glStencilFuncSeparate" ); + stencil_func_separate_ati = glutGetProcAddress( "glStencilFuncSeparateATI" ); + stencil_op_separate = glutGetProcAddress( "glStencilOpSeparate" ); + + printf("\nAll 5 squares should be the same color.\n"); +} + + +int main( int argc, char *argv[] ) +{ + glutInit( &argc, argv ); + glutInitWindowPosition( 0, 0 ); + glutInitWindowSize( Width, Height ); + glutInitDisplayMode( GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH | GLUT_STENCIL ); + glutCreateWindow( "GL_ATI_separate_stencil test" ); + glutReshapeFunc( Reshape ); + glutKeyboardFunc( Key ); + glutDisplayFunc( Display ); + Init(); + glutMainLoop(); + return 0; +} diff --git a/progs/tests/texline.c b/progs/tests/texline.c index ee16ed40df..76dfccd9b1 100644 --- a/progs/tests/texline.c +++ b/progs/tests/texline.c @@ -6,7 +6,6 @@ * September 2000 */ - #include <stdio.h> #include <stdlib.h> #include <math.h> @@ -210,7 +209,9 @@ static void SpecialKey( int key, int x, int y ) static void Init( int argc, char *argv[] ) { + GLfloat r[2]; GLuint u; + for (u = 0; u < 2; u++) { glActiveTextureARB(GL_TEXTURE0_ARB + u); glBindTexture(GL_TEXTURE_2D, 10+u); @@ -241,6 +242,15 @@ static void Init( int argc, char *argv[] ) printf("GL_VENDOR = %s\n", (char *) glGetString(GL_VENDOR)); printf("GL_EXTENSIONS = %s\n", (char *) glGetString(GL_EXTENSIONS)); } + + glGetFloatv(GL_ALIASED_POINT_SIZE_RANGE, r); + printf("Non-smooth point size range: %g .. %g\n", r[0], r[1]); + glGetFloatv(GL_POINT_SIZE_RANGE, r); + printf("Smoothed point size range: %g .. %g\n", r[0], r[1]); + glGetFloatv(GL_ALIASED_LINE_WIDTH_RANGE, r); + printf("Non-smooth line width range: %g .. %g\n", r[0], r[1]); + glGetFloatv(GL_LINE_WIDTH_RANGE, r); + printf("Smoothed line width range: %g .. %g\n", r[0], r[1]); } diff --git a/progs/tests/unfilledclip.c b/progs/tests/unfilledclip.c new file mode 100644 index 0000000000..f25e52616a --- /dev/null +++ b/progs/tests/unfilledclip.c @@ -0,0 +1,205 @@ +/* + * Copyright © 2008 Intel Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + * + * Authors: + * Eric Anholt <eric@anholt.net> + * + */ + +#include <stdlib.h> +#include <GL/glut.h> + +static int win_width, win_height; + +static void +line(GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2) +{ + glBegin(GL_LINES); + glVertex2f(x1, y1); + glVertex2f(x2, y2); + glEnd(); +} + +static void +line3(GLfloat x1, GLfloat y1, GLfloat z1, GLfloat x2, GLfloat y2, GLfloat z2) +{ + glBegin(GL_LINES); + glVertex3f(x1, y1, z1); + glVertex3f(x2, y2, z2); + glEnd(); +} + +static void +display(void) +{ + glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); + + glClearColor(0.0, 0.0, 0.0, 0.0); + glClear(GL_COLOR_BUFFER_BIT); + + glColor3f(1.0, 0.0, 0.0); + /* clipped along xmin */ + glBegin(GL_TRIANGLES); + glVertex2f(-20, win_height / 2 - 20); + glVertex2f(20, win_height / 2); + glVertex2f(-20, win_height / 2 + 20); + glEnd(); + + glColor3f(0.0, 1.0, 0.0); + /* clipped along ymax */ + glBegin(GL_TRIANGLES); + glVertex2f(win_height / 2 - 20, win_height + 20); + glVertex2f(win_height / 2, win_height - 20); + glVertex2f(win_height / 2 + 20, win_height + 20); + glEnd(); + + glColor3f(0.0, 0.0, 1.0); + /* clipped along xmax */ + glBegin(GL_TRIANGLES); + glVertex2f(win_height + 20, win_height / 2 - 20); + glVertex2f(win_height - 20, win_height / 2); + glVertex2f(win_height + 20, win_height / 2 + 20); + glEnd(); + + glColor3f(1.0, 1.0, 1.0); + /* clipped along ymin */ + glBegin(GL_TRIANGLES); + glVertex2f(win_height / 2 - 20, -20); + glVertex2f(win_height / 2, 20); + glVertex2f(win_height / 2 + 20, -20); + glEnd(); + + /* clipped along near */ + glColor3f(1.0, 0.0, 1.0); + glBegin(GL_TRIANGLES); + glVertex3f(win_width / 2 - 20, win_height / 2 - 20, 0.5); + glVertex3f(win_width / 2 - 40, win_height / 2, -0.5); + glVertex3f(win_width / 2 - 20, win_height / 2 + 20, 0.5); + glEnd(); + + /* clipped along far */ + glColor3f(0.0, 1.0, 1.0); + glBegin(GL_TRIANGLES); + glVertex3f(win_width / 2 + 20, win_height / 2 - 20, 0.5); + glVertex3f(win_width / 2 + 40, win_height / 2, 1.5); + glVertex3f(win_width / 2 + 20, win_height / 2 + 20, 0.5); + glEnd(); + + /* entirely clipped along near/far */ + glColor3f(.5, .5, .5); + glBegin(GL_TRIANGLES); + glVertex3f(win_width / 2 - 20, win_height / 2 + 20, -0.5); + glVertex3f(win_width / 2, win_height / 2 + 40, -0.5); + glVertex3f(win_width / 2 + 20, win_height / 2 + 20, -0.5); + glEnd(); + + glBegin(GL_TRIANGLES); + glVertex3f(win_width / 2 - 20, win_height / 2 - 20, 1.5); + glVertex3f(win_width / 2, win_height / 2 - 40, 1.5); + glVertex3f(win_width / 2 + 20, win_height / 2 - 20, 1.5); + glEnd(); + + glColor3f(.5, .5, .5); + line3(win_width / 2, win_height / 2 - 20, 1.5, + win_width / 2, win_height / 2 + 20, 1.5); + + glColor3f(1.0, 1.0, 0.0); + /* clipped along both x and y limits */ + glBegin(GL_TRIANGLES); /* xmin, ymin */ + glVertex2f(-5, 20); + glVertex2f(20, 20); + glVertex2f(20, -5); + glEnd(); + glBegin(GL_TRIANGLES); /* xmin, ymax */ + glVertex2f(-5, win_height - 20); + glVertex2f(20, win_height - 20); + glVertex2f(20, win_height + 5); + glEnd(); + glBegin(GL_TRIANGLES); /* xmax, ymax */ + glVertex2f(win_width - 20, win_height + 5); + glVertex2f(win_width - 20, win_height - 20); + glVertex2f(win_width + 5, win_height - 20); + glEnd(); + glBegin(GL_TRIANGLES); /* xmax, ymin */ + glVertex2f(win_width + 5, 20); + glVertex2f(win_width - 20, 20); + glVertex2f(win_width - 20, -5); + glEnd(); + + glutSwapBuffers(); +} + +static void +reshape(int width, int height) +{ + win_width = width; + win_height = height; + glViewport(0, 0, width, height); + + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + glOrtho(0, win_width, 0, win_height, 0.0, -1.0); + + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + glTranslatef(.25, .25, 0); +} + +static void key( unsigned char key, int x, int y ) +{ + (void) x; + (void) y; + + switch (key) { + case 27: /* esc */ + exit(0); + break; + } + + glutPostRedisplay(); +} + +static void +init(void) +{ +} + +int +main(int argc, char *argv[]) +{ + win_width = 200; + win_height = 200; + + glutInit(&argc, argv); + glutInitWindowPosition(0, 0); + glutInitWindowSize(win_width, win_height); + glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH); + glutCreateWindow(argv[0]); + glutReshapeFunc(reshape); + glutKeyboardFunc(key); + glutDisplayFunc(display); + + init(); + + glutMainLoop(); + return 0; +} |