| /* |
| * '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; |
| } |