diff options
Diffstat (limited to 'progs/tests')
-rw-r--r-- | progs/tests/Makefile | 3 | ||||
-rw-r--r-- | progs/tests/SConscript | 22 | ||||
-rw-r--r-- | progs/tests/bufferobj.c | 8 | ||||
-rw-r--r-- | progs/tests/condrender.c | 242 | ||||
-rw-r--r-- | progs/tests/drawbuffers2.c | 364 | ||||
-rw-r--r-- | progs/tests/texleak.c | 140 |
6 files changed, 759 insertions, 20 deletions
diff --git a/progs/tests/Makefile b/progs/tests/Makefile index 197e14d5b00..836396b2499 100644 --- a/progs/tests/Makefile +++ b/progs/tests/Makefile @@ -37,10 +37,12 @@ SOURCES = \ bug_3195.c \ bug_texstore_i8.c \ calibrate_rast.c \ + condrender.c \ copypixrate.c \ crossbar.c \ cva.c \ drawbuffers.c \ + drawbuffers2.c \ exactrast.c \ ext422square.c \ floattex.c \ @@ -98,6 +100,7 @@ SOURCES = \ texdown \ texfilt.c \ texgenmix.c \ + texleak.c \ texline.c \ texobj.c \ texobjshare.c \ diff --git a/progs/tests/SConscript b/progs/tests/SConscript index 3a0da62717c..e2c65382887 100644 --- a/progs/tests/SConscript +++ b/progs/tests/SConscript @@ -1,23 +1,5 @@ Import('*') -if not env['GLUT']: - Return() - -env = env.Clone() - -env.Prepend(CPPPATH = [ - '../util', -]) - -env.Prepend(LIBS = [ - util, - '$GLUT_LIB' -]) - -if env['platform'] == 'windows': - env.Append(CPPDEFINES = ['NOMINMAX']) - env.Prepend(LIBS = ['winmm']) - linux_progs = [ 'api_speed', ] @@ -59,10 +41,12 @@ progs = [ 'bug_3195', 'bug_texstore_i8', 'calibrate_rast', + 'condrender', 'copypixrate', 'crossbar', 'cva', 'drawbuffers', + 'drawbuffers2', 'exactrast', 'ext422square', 'fbotest1', @@ -138,7 +122,7 @@ progs = [ ] for prog in progs: - env.Program( + progs_env.Program( target = prog, source = prog + '.c', ) diff --git a/progs/tests/bufferobj.c b/progs/tests/bufferobj.c index d4ca2700160..dc479af0452 100644 --- a/progs/tests/bufferobj.c +++ b/progs/tests/bufferobj.c @@ -29,6 +29,7 @@ struct object GLuint VertexStride; GLuint ColorStride; GLuint NumElements; + GLuint MaxElement; }; static struct object Objects[NUM_OBJECTS]; @@ -58,7 +59,8 @@ static void DrawObject( const struct object *obj ) if (obj->NumElements > 0) { /* indexed arrays */ glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, obj->ElementsBufferID); - glDrawElements(GL_LINE_LOOP, obj->NumElements, GL_UNSIGNED_INT, NULL); + glDrawRangeElements(GL_LINE_LOOP, 0, obj->MaxElement, + obj->NumElements, GL_UNSIGNED_INT, NULL); } else { /* non-indexed arrays */ @@ -300,6 +302,7 @@ static void MakeObject1(struct object *obj) obj->VertexStride = 0; obj->ColorStride = 0; obj->NumElements = 0; + obj->MaxElement = 0; glUnmapBufferARB(GL_ARRAY_BUFFER_ARB); @@ -345,6 +348,7 @@ static void MakeObject2(struct object *obj) obj->ColorStride = 6 * sizeof(GLfloat); obj->NumElements = 0; + obj->MaxElement = 0; glUnmapBufferARB(GL_ARRAY_BUFFER_ARB); @@ -401,6 +405,7 @@ static void MakeObject3(struct object *obj) i[3] = 3; glUnmapBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB); obj->NumElements = 4; + obj->MaxElement = 3; if (Have_ARB_vertex_array_object) { CreateVertexArrayObject(obj); @@ -445,6 +450,7 @@ static void MakeObject4(struct object *obj) /* Setup a buffer of indices to test the ELEMENTS path */ obj->ElementsBufferID = 0; obj->NumElements = 0; + obj->MaxElement = 0; if (Have_ARB_vertex_array_object) { CreateVertexArrayObject(obj); diff --git a/progs/tests/condrender.c b/progs/tests/condrender.c new file mode 100644 index 00000000000..1db8a7c15af --- /dev/null +++ b/progs/tests/condrender.c @@ -0,0 +1,242 @@ +/* + * Test GL_NV_conditional_render + * + * Brian Paul + * 30 Dec 2009 + * + * Copyright (C) 2009 VMware, Inc. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#include <assert.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <math.h> +#include <GL/glew.h> +#include <GL/glut.h> + +#define TEST_DISPLAY_LISTS 0 + +static GLboolean Anim = GL_TRUE; +static GLfloat Xpos = 0; +static GLuint OccQuery; +static GLint Win = 0; + + +static void Idle(void) +{ + static int lastTime = 0; + static int sign = +1; + int time = glutGet(GLUT_ELAPSED_TIME); + float step; + + if (lastTime == 0) + lastTime = time; + else if (time - lastTime < 20) /* 50Hz update */ + return; + + step = (time - lastTime) / 1000.0 * sign; + lastTime = time; + + Xpos += step; + + if (Xpos > 2.5) { + Xpos = 2.5; + sign = -1; + } + else if (Xpos < -2.5) { + Xpos = -2.5; + sign = +1; + } + glutPostRedisplay(); +} + + +static void Display( void ) +{ + glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ); + + glEnable(GL_DEPTH_TEST); + + glMatrixMode( GL_PROJECTION ); + glLoadIdentity(); + glFrustum( -1.0, 1.0, -1.0, 1.0, 5.0, 25.0 ); + glMatrixMode( GL_MODELVIEW ); + glLoadIdentity(); + glTranslatef( 0.0, 0.0, -15.0 ); + + /* draw the occluding polygons */ + glColor3f(0, 0.6, 0.8); + glBegin(GL_QUADS); + glVertex2f(-1.6, -1.5); + glVertex2f(-0.4, -1.5); + glVertex2f(-0.4, 1.5); + glVertex2f(-1.6, 1.5); + + glVertex2f( 0.4, -1.5); + glVertex2f( 1.6, -1.5); + glVertex2f( 1.6, 1.5); + glVertex2f( 0.4, 1.5); + glEnd(); + + /* draw the test polygon with occlusion testing */ + glPushMatrix(); + glTranslatef(Xpos, 0, -0.5); + glScalef(0.3, 0.3, 1.0); + glRotatef(-90.0 * Xpos, 0, 0, 1); + +#if TEST_DISPLAY_LISTS + glNewList(10, GL_COMPILE); + glBeginQueryARB(GL_SAMPLES_PASSED_ARB, OccQuery); + glEndList(); + glCallList(10); +#else + glBeginQueryARB(GL_SAMPLES_PASSED_ARB, OccQuery); +#endif + + glColorMask(0, 0, 0, 0); + glDepthMask(GL_FALSE); + + glBegin(GL_POLYGON); + glVertex3f(-1, -1, 0); + glVertex3f( 1, -1, 0); + glVertex3f( 1, 1, 0); + glVertex3f(-1, 1, 0); + glEnd(); + +#if TEST_DISPLAY_LISTS + glNewList(11, GL_COMPILE); + glEndQueryARB(GL_SAMPLES_PASSED_ARB); + glEndList(); + glCallList(11); +#else + glEndQueryARB(GL_SAMPLES_PASSED_ARB); +#endif + + glColorMask(1, 1, 1, 1); + glDepthMask(GL_TRUE); + + /* Note: disable depth test here so that we'll always see the orange + * box, except when it's totally culled. + */ + glDisable(GL_DEPTH_TEST); + + glBeginConditionalRenderNV(OccQuery, GL_QUERY_WAIT_NV); + /* draw the orange rect, so we can see what's going on */ + glColor3f(0.8, 0.5, 0); + glBegin(GL_POLYGON); + glVertex3f(-1, -1, 0); + glVertex3f( 1, -1, 0); + glVertex3f( 1, 1, 0); + glVertex3f(-1, 1, 0); + glEnd(); + glEndConditionalRenderNV(); + + /* always draw white outline around orange box */ + glColor3f(1.0, 1.0, 1.0); + glBegin(GL_LINE_LOOP); + glVertex3f(-1, -1, 0); + glVertex3f( 1, -1, 0); + glVertex3f( 1, 1, 0); + glVertex3f(-1, 1, 0); + glEnd(); + + glPopMatrix(); + + glutSwapBuffers(); +} + + +static void Reshape( int width, int height ) +{ + glViewport( 0, 0, width, height ); +} + + +static void Key( unsigned char key, int x, int y ) +{ + (void) x; + (void) y; + switch (key) { + case 27: + glDeleteQueriesARB(1, &OccQuery); + glutDestroyWindow(Win); + exit(0); + break; + case ' ': + Anim = !Anim; + if (Anim) + glutIdleFunc(Idle); + else + glutIdleFunc(NULL); + break; + } + glutPostRedisplay(); +} + + +static void SpecialKey( int key, int x, int y ) +{ + const GLfloat step = 0.1; + (void) x; + (void) y; + switch (key) { + case GLUT_KEY_LEFT: + Xpos -= step; + break; + case GLUT_KEY_RIGHT: + Xpos += step; + break; + } + glutPostRedisplay(); +} + + +static void Init( void ) +{ + if (!glutExtensionSupported("GL_ARB_occlusion_query") || + !glutExtensionSupported("GL_NV_conditional_render")) { + printf("Sorry, this demo requires the extensions:\n"); + printf(" GL_ARB_occlusion_query\n"); + printf(" GL_NV_conditional_render\n"); + exit(-1); + } + + glGenQueriesARB(1, &OccQuery); + assert(OccQuery > 0); +} + + +int main( int argc, char *argv[] ) +{ + glutInitWindowSize( 400, 400 ); + glutInit( &argc, argv ); + glutInitDisplayMode( GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH ); + Win = glutCreateWindow(argv[0]); + glewInit(); + glutReshapeFunc( Reshape ); + glutKeyboardFunc( Key ); + glutSpecialFunc( SpecialKey ); + glutIdleFunc( Idle ); + glutDisplayFunc( Display ); + Init(); + glutMainLoop(); + return 0; +} diff --git a/progs/tests/drawbuffers2.c b/progs/tests/drawbuffers2.c new file mode 100644 index 00000000000..7b8cc5ca6a3 --- /dev/null +++ b/progs/tests/drawbuffers2.c @@ -0,0 +1,364 @@ +/* + * Test GL_ARB_draw_buffers2, GL_ARB_draw_buffers, GL_EXT_framebuffer_object + * and GLSL's gl_FragData[]. + * + * We draw to two color buffers and show the left half of the first + * color buffer on the left side of the window, and show the right + * half of the second color buffer on the right side of the window. + * + * Different color masks are used for the two color buffers. + * Blending is enabled for the second buffer only. + * + * Brian Paul + * 31 Dec 2009 + */ + + +#include <assert.h> +#include <stdio.h> +#include <stdlib.h> +#include <math.h> +#include <GL/glew.h> +#include <GL/glut.h> +#include "extfuncs.h" + +static int Win; +static int Width = 400, Height = 400; +static GLuint FBobject, RBobjects[3]; +static GLfloat Xrot = 0.0, Yrot = 0.0; +static GLuint Program; +static GLboolean Anim = GL_TRUE; + + +static void +CheckError(int line) +{ + GLenum err = glGetError(); + if (err) { + printf("GL Error 0x%x at line %d\n", (int) err, line); + } +} + + +static void +Display(void) +{ + GLubyte *buffer = malloc(Width * Height * 4); + static const GLenum buffers[2] = { + GL_COLOR_ATTACHMENT0_EXT, + GL_COLOR_ATTACHMENT1_EXT + }; + + glUseProgram_func(Program); + + glEnable(GL_DEPTH_TEST); + + /* draw to user framebuffer */ + glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, FBobject); + + /* Clear color buffer 0 (blue) */ + glDrawBuffer(GL_COLOR_ATTACHMENT0_EXT); + glClear(GL_COLOR_BUFFER_BIT); + + /* Clear color buffer 1 (1 - blue) */ + glDrawBuffer(GL_COLOR_ATTACHMENT1_EXT); + glClear(GL_COLOR_BUFFER_BIT); + + glClear(GL_DEPTH_BUFFER_BIT); + + /* draw to two buffers w/ fragment shader */ + glDrawBuffersARB(2, buffers); + + /* different color masks for each buffer */ + if (1) { + glColorMaskIndexedEXT(0, GL_TRUE, GL_FALSE, GL_FALSE, GL_FALSE); + glColorMaskIndexedEXT(1, GL_FALSE, GL_TRUE, GL_FALSE, GL_FALSE); + } + + glPushMatrix(); + glRotatef(Xrot, 1, 0, 0); + glRotatef(Yrot, 0, 1, 0); + glPushMatrix(); + glTranslatef(1, 0, 0); + glutSolidTorus(1.0, 2.0, 10, 20); + glPopMatrix(); + glPushMatrix(); + glTranslatef(-1, 0, 0); + glRotatef(90, 1, 0, 0); + glutSolidTorus(1.0, 2.0, 10, 20); + glPopMatrix(); + glPopMatrix(); + + /* restore default color masks */ + glColorMaskIndexedEXT(0, GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); + glColorMaskIndexedEXT(1, GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); + + /* read from user framebuffer */ + /* left half = colorbuffer 0 */ + glReadBuffer(GL_COLOR_ATTACHMENT0_EXT); + glPixelStorei(GL_PACK_ROW_LENGTH, Width); + glPixelStorei(GL_PACK_SKIP_PIXELS, 0); + glReadPixels(0, 0, Width / 2, Height, GL_RGBA, GL_UNSIGNED_BYTE, + buffer); + + /* right half = colorbuffer 1 */ + glReadBuffer(GL_COLOR_ATTACHMENT1_EXT); + glPixelStorei(GL_PACK_SKIP_PIXELS, Width / 2); + glReadPixels(Width / 2, 0, Width - Width / 2, Height, + GL_RGBA, GL_UNSIGNED_BYTE, + buffer); + + /* draw to window */ + glUseProgram_func(0); + glDisable(GL_DEPTH_TEST); + glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); + glWindowPos2iARB(0, 0); + glDrawPixels(Width, Height, GL_RGBA, GL_UNSIGNED_BYTE, buffer); + + free(buffer); + glutSwapBuffers(); + CheckError(__LINE__); +} + + +static void +Idle(void) +{ + Xrot = glutGet(GLUT_ELAPSED_TIME) * 0.05; + glutPostRedisplay(); +} + + +static void +Reshape(int width, int height) +{ + float ar = (float) width / (float) height; + + glViewport(0, 0, width, height); + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + glFrustum(-ar, ar, -1.0, 1.0, 5.0, 35.0); + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + glTranslatef(0.0, 0.0, -20.0); + + Width = width; + Height = height; + + glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, RBobjects[0]); + glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_RGB, Width, Height); + glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, RBobjects[1]); + glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_RGB, Width, Height); + glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, RBobjects[2]); + glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT, + Width, Height); +} + + +static void +CleanUp(void) +{ + glDeleteFramebuffersEXT(1, &FBobject); + glDeleteRenderbuffersEXT(3, RBobjects); + glutDestroyWindow(Win); + exit(0); +} + + +static void +Key(unsigned char key, int x, int y) +{ + (void) x; + (void) y; + switch (key) { + case ' ': + Anim = !Anim; + glutIdleFunc(Anim ? Idle : NULL); + break; + case 'x': + Xrot += 5.0; + break; + case 'X': + Xrot -= 5.0; + break; + case 'y': + Yrot += 5.0; + break; + case 'Y': + Yrot -= 5.0; + break; + case 27: + CleanUp(); + break; + } + glutPostRedisplay(); +} + + +static void +CheckExtensions(void) +{ + const char *req[] = { + "GL_EXT_framebuffer_object", + "GL_ARB_draw_buffers", + "GL_EXT_draw_buffers2" + }; + + const char *version = (const char *) glGetString(GL_VERSION); + GLint numBuf; + GLint i; + + for (i = 0; i < 3; i++) { + if (!glutExtensionSupported(req[i])) { + printf("Sorry, %s extension is required!\n", req[i]); + exit(1); + } + } + if (version[0] != '2') { + printf("Sorry, OpenGL 2.0 is required!\n"); + exit(1); + } + + glGetIntegerv(GL_MAX_DRAW_BUFFERS_ARB, &numBuf); + printf("GL_MAX_DRAW_BUFFERS_ARB = %d\n", numBuf); + if (numBuf < 2) { + printf("Sorry, GL_MAX_DRAW_BUFFERS_ARB needs to be >= 2\n"); + exit(1); + } + + printf("GL_RENDERER = %s\n", (char *) glGetString(GL_RENDERER)); +} + + +static void +SetupRenderbuffers(void) +{ + glGenFramebuffersEXT(1, &FBobject); + glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, FBobject); + + glGenRenderbuffersEXT(3, RBobjects); + + glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, RBobjects[0]); + glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_RGB, Width, Height); + + glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, RBobjects[1]); + glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_RGB, Width, Height); + + glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, RBobjects[2]); + glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT, + Width, Height); + + glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, + GL_RENDERBUFFER_EXT, RBobjects[0]); + glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT1_EXT, + GL_RENDERBUFFER_EXT, RBobjects[1]); + glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, + GL_RENDERBUFFER_EXT, RBobjects[2]); + + CheckError(__LINE__); +} + + +static GLuint +LoadAndCompileShader(GLenum target, const char *text) +{ + GLint stat; + GLuint shader = glCreateShader_func(target); + glShaderSource_func(shader, 1, (const GLchar **) &text, NULL); + glCompileShader_func(shader); + glGetShaderiv_func(shader, GL_COMPILE_STATUS, &stat); + if (!stat) { + GLchar log[1000]; + GLsizei len; + glGetShaderInfoLog_func(shader, 1000, &len, log); + fprintf(stderr, "drawbuffers: problem compiling shader:\n%s\n", log); + exit(1); + } + return shader; +} + + +static void +CheckLink(GLuint prog) +{ + GLint stat; + glGetProgramiv_func(prog, GL_LINK_STATUS, &stat); + if (!stat) { + GLchar log[1000]; + GLsizei len; + glGetProgramInfoLog_func(prog, 1000, &len, log); + fprintf(stderr, "drawbuffers: shader link error:\n%s\n", log); + } +} + + +static void +SetupShaders(void) +{ + /* emit same color to both draw buffers */ + static const char *fragShaderText = + "void main() {\n" + " gl_FragData[0] = gl_Color; \n" + " gl_FragData[1] = gl_Color; \n" + "}\n"; + + GLuint fragShader; + + fragShader = LoadAndCompileShader(GL_FRAGMENT_SHADER, fragShaderText); + Program = glCreateProgram_func(); + + glAttachShader_func(Program, fragShader); + glLinkProgram_func(Program); + CheckLink(Program); + glUseProgram_func(Program); +} + + +static void +SetupLighting(void) +{ + static const GLfloat ambient[4] = { 0.0, 0.0, 0.0, 0.0 }; + static const GLfloat diffuse[4] = { 1.0, 1.0, 1.0, 0.75 }; + + glLightModelfv(GL_LIGHT_MODEL_AMBIENT, ambient); + glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, ambient); + glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, diffuse); + + glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, 0); + glEnable(GL_LIGHT0); + glEnable(GL_LIGHTING); +} + + +static void +Init(void) +{ + CheckExtensions(); + GetExtensionFuncs(); + SetupRenderbuffers(); + SetupShaders(); + SetupLighting(); + glEnable(GL_DEPTH_TEST); + + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glEnableIndexedEXT(GL_BLEND, 1); +} + + +int +main(int argc, char *argv[]) +{ + glutInit(&argc, argv); + glutInitWindowPosition(0, 0); + glutInitWindowSize(Width, Height); + glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE); + Win = glutCreateWindow(argv[0]); + glewInit(); + glutIdleFunc(Anim ? Idle : NULL); + glutReshapeFunc(Reshape); + glutKeyboardFunc(Key); + glutDisplayFunc(Display); + Init(); + glutMainLoop(); + return 0; +} diff --git a/progs/tests/texleak.c b/progs/tests/texleak.c new file mode 100644 index 00000000000..5cf4ff32393 --- /dev/null +++ b/progs/tests/texleak.c @@ -0,0 +1,140 @@ +/* + * 'Texture leak' test + * + * Allocates and uses an additional texture of the maximum supported size for + * each frame. This tests the system's ability to cope with using increasing + * amounts of texture memory. + * + * Michel Dänzer July 2009 This program is in the public domain. + */ + + +#include <math.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <sys/time.h> +#include <unistd.h> +#include <GL/glew.h> +#include <GL/glut.h> + + +GLint size; +GLvoid *image; +static GLuint numTexObj; +static GLuint *texObj; + + +static void Idle( void ) +{ + glutPostRedisplay(); +} + + +static void DrawObject(void) +{ + static const GLfloat tex_coords[] = { 0.0, 0.0, 1.0, 1.0, 0.0 }; + static const GLfloat vtx_coords[] = { -1.0, -1.0, 1.0, 1.0, -1.0 }; + GLint i, j; + + glEnable(GL_TEXTURE_2D); + + for (i = 0; i < numTexObj; i++) { + glBindTexture(GL_TEXTURE_2D, texObj[i]); + glBegin(GL_QUADS); + for (j = 0; j < 4; j++ ) { + glTexCoord2f(tex_coords[j], tex_coords[j+1]); + glVertex2f( vtx_coords[j], vtx_coords[j+1] ); + } + glEnd(); + } +} + + +static void Display( void ) +{ + struct timeval start, end; + + texObj = realloc(texObj, ++numTexObj * sizeof(*texObj)); + + /* allocate a texture object */ + glGenTextures(1, texObj + (numTexObj - 1)); + + glBindTexture(GL_TEXTURE_2D, texObj[numTexObj - 1]); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + memset(image, (16 * numTexObj) & 0xff, 4 * size * size); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, size, size, 0, + GL_RGBA, GL_UNSIGNED_BYTE, image); + + gettimeofday(&start, NULL); + + glClear( GL_COLOR_BUFFER_BIT ); + + glPushMatrix(); + glScalef(5.0, 5.0, 5.0); + DrawObject(); + glPopMatrix(); + + glutSwapBuffers(); + + glFinish(); + gettimeofday(&end, NULL); + printf("Rendering frame took %lu ms using %u MB of textures\n", + end.tv_sec * 1000 + end.tv_usec / 1000 - start.tv_sec * 1000 - + start.tv_usec / 1000, numTexObj * 4 * size / 1024 * size / 1024); + + sleep(1); +} + + +static void Reshape( int width, int height ) +{ + glViewport( 0, 0, width, height ); + glMatrixMode( GL_PROJECTION ); + glLoadIdentity(); + glOrtho( -6.0, 6.0, -6.0, 6.0, 10.0, 100.0 ); + glMatrixMode( GL_MODELVIEW ); + glLoadIdentity(); + glTranslatef( 0.0, 0.0, -70.0 ); +} + + +static void Init( int argc, char *argv[] ) +{ + glGetIntegerv(GL_MAX_TEXTURE_SIZE, &size); + printf("%d x %d max texture size\n", size, size); + + image = malloc(4 * size * size); + if (!image) { + fprintf(stderr, "Failed to allocate %u bytes of memory\n", 4 * size * size); + exit(1); + } + + glPixelStorei(GL_UNPACK_ALIGNMENT, 1); + + glShadeModel(GL_FLAT); + glClearColor(0.3, 0.3, 0.4, 1.0); + + Idle(); +} + + +int main( int argc, char *argv[] ) +{ + glutInit( &argc, argv ); + glutInitWindowSize( 300, 300 ); + glutInitWindowPosition( 0, 0 ); + glutInitDisplayMode( GLUT_RGB | GLUT_DOUBLE ); + glutCreateWindow(argv[0] ); + glewInit(); + + Init( argc, argv ); + + glutReshapeFunc( Reshape ); + glutDisplayFunc( Display ); + glutIdleFunc(Idle); + + glutMainLoop(); + return 0; +} |