1/*
2 * 'Texture leak' test
3 *
4 * Allocates and uses an additional texture of the maximum supported size for
5 * each frame. This tests the system's ability to cope with using increasing
6 * amounts of texture memory.
7 *
8 * Michel Dänzer  July 2009  This program is in the public domain.
9 */
10
11
12#include <math.h>
13#include <stdio.h>
14#include <stdlib.h>
15#include <string.h>
16#include <sys/time.h>
17#include <unistd.h>
18#include <GL/glew.h>
19#include "glut_wrap.h"
20
21
22GLint size;
23GLvoid *image;
24static GLuint numTexObj;
25static GLuint *texObj;
26
27
28static void Idle( void )
29{
30   glutPostRedisplay();
31}
32
33
34static void DrawObject(void)
35{
36   static const GLfloat tex_coords[] = {  0.0,  0.0,  1.0,  1.0,  0.0 };
37   static const GLfloat vtx_coords[] = { -1.0, -1.0,  1.0,  1.0, -1.0 };
38   GLint i, j;
39
40   glEnable(GL_TEXTURE_2D);
41
42   for (i = 0; i < numTexObj; i++) {
43      glBindTexture(GL_TEXTURE_2D, texObj[i]);
44      glBegin(GL_QUADS);
45      for (j = 0; j < 4; j++ ) {
46         glTexCoord2f(tex_coords[j], tex_coords[j+1]);
47         glVertex2f( vtx_coords[j], vtx_coords[j+1] );
48      }
49      glEnd();
50   }
51}
52
53
54static void Display( void )
55{
56   struct timeval start, end;
57
58   texObj = realloc(texObj, ++numTexObj * sizeof(*texObj));
59
60   /* allocate a texture object */
61   glGenTextures(1, texObj + (numTexObj - 1));
62
63   glBindTexture(GL_TEXTURE_2D, texObj[numTexObj - 1]);
64   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
65   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
66   memset(image, (16 * numTexObj) & 0xff, 4 * size * size);
67   glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, size, size, 0,
68                GL_RGBA, GL_UNSIGNED_BYTE, image);
69
70   gettimeofday(&start, NULL);
71
72   glClear( GL_COLOR_BUFFER_BIT );
73
74   glPushMatrix();
75      glScalef(5.0, 5.0, 5.0);
76      DrawObject();
77   glPopMatrix();
78
79   glutSwapBuffers();
80
81   glFinish();
82   gettimeofday(&end, NULL);
83   printf("Rendering frame took %lu ms using %u MB of textures\n",
84	  end.tv_sec * 1000 + end.tv_usec / 1000 - start.tv_sec * 1000 -
85	  start.tv_usec / 1000, numTexObj * 4 * size / 1024 * size / 1024);
86
87   sleep(1);
88}
89
90
91static void Reshape( int width, int height )
92{
93   glViewport( 0, 0, width, height );
94   glMatrixMode( GL_PROJECTION );
95   glLoadIdentity();
96   glOrtho( -6.0, 6.0, -6.0, 6.0, 10.0, 100.0 );
97   glMatrixMode( GL_MODELVIEW );
98   glLoadIdentity();
99   glTranslatef( 0.0, 0.0, -70.0 );
100}
101
102
103static void Init( int argc, char *argv[] )
104{
105   glGetIntegerv(GL_MAX_TEXTURE_SIZE, &size);
106   printf("%d x %d max texture size\n", size, size);
107
108   image = malloc(4 * size * size);
109   if (!image) {
110      fprintf(stderr, "Failed to allocate %u bytes of memory\n", 4 * size * size);
111      exit(1);
112   }
113
114   glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
115
116   glShadeModel(GL_FLAT);
117   glClearColor(0.3, 0.3, 0.4, 1.0);
118
119   Idle();
120}
121
122
123int main( int argc, char *argv[] )
124{
125   glutInit( &argc, argv );
126   glutInitWindowSize( 300, 300 );
127   glutInitWindowPosition( 0, 0 );
128   glutInitDisplayMode( GLUT_RGB | GLUT_DOUBLE );
129   glutCreateWindow(argv[0] );
130   glewInit();
131
132   Init( argc, argv );
133
134   glutReshapeFunc( Reshape );
135   glutDisplayFunc( Display );
136   glutIdleFunc(Idle);
137
138   glutMainLoop();
139   return 0;
140}
141