1/**
2 * Try to see other parts of the user's video memory by creating textures
3 * with uninitialized contents.  Display those textures in the window.
4 * Insprired by stories of WebGL security issues.
5 *
6 * The OpenGL driver should probably initialize all memory allocations
7 * to zero (textures, renderbuffers, buffer objects, etc).
8 *
9 * Brian Paul
10 * June 2011
11 */
12
13#define GL_GLEXT_PROTOTYPES
14
15#include <stdio.h>
16#include <stdlib.h>
17#include <math.h>
18#include <GL/glew.h>
19#include "glut_wrap.h"
20
21static int Win;
22static int WinWidth = 1024, WinHeight = 512;
23static GLboolean Anim = GL_FALSE;
24
25static GLuint *Textures;
26static GLuint TexWidth = 1024, TexHeight = 512;
27static GLuint NumTextures = 50, CurTexture;
28
29
30static void
31Idle(void)
32{
33   static int prevTime = 0;
34   int curTime = glutGet(GLUT_ELAPSED_TIME);
35
36   if (!prevTime) {
37      prevTime = curTime;
38   }
39   else {
40      if (curTime - prevTime > 250) {
41         prevTime = curTime;
42         CurTexture = (CurTexture + 1) % NumTextures;
43         glutPostRedisplay();
44      }
45   }
46}
47
48
49static void
50MakeTextures(void)
51{
52   GLuint i;
53
54   Textures = (GLuint *) malloc(NumTextures * sizeof(GLuint));
55
56   glGenTextures(NumTextures, Textures);
57   for (i = 0; i < NumTextures; i++) {
58      glBindTexture(GL_TEXTURE_2D, Textures[i]);
59      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
60      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
61      glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, TexWidth, TexHeight, 0,
62                   GL_RGBA, GL_UNSIGNED_BYTE, NULL);
63   }
64}
65
66
67static void
68PrintString(const char *s)
69{
70   while (*s) {
71      glutBitmapCharacter(GLUT_BITMAP_8_BY_13, (int) *s);
72      s++;
73   }
74}
75
76
77static void
78Draw(void)
79{
80   char s[100];
81
82   sprintf(s, "Texture %u", CurTexture);
83
84   glClear(GL_COLOR_BUFFER_BIT);
85
86   glEnable(GL_TEXTURE_2D);
87   glBindTexture(GL_TEXTURE_2D, CurTexture);
88
89   glBegin(GL_POLYGON);
90   glTexCoord2f(0, 0);  glVertex2f(0, 0);
91   glTexCoord2f(1, 0);  glVertex2f(WinWidth, 0);
92   glTexCoord2f(1, 1);  glVertex2f(WinWidth, WinHeight);
93   glTexCoord2f(0, 1);  glVertex2f(0, WinHeight);
94   glEnd();
95
96   glDisable(GL_TEXTURE_2D);
97   glColor3f(0, 1, 0);
98   glWindowPos2iARB(10, 10);
99   PrintString(s);
100
101   glutSwapBuffers();
102}
103
104
105static void
106Reshape(int width, int height)
107{
108   WinWidth = width;
109   WinHeight = height;
110   glViewport(0, 0, width, height);
111   glMatrixMode(GL_PROJECTION);
112   glLoadIdentity();
113   glOrtho(0, WinWidth, 0, WinHeight, -1, 1);
114   glMatrixMode(GL_MODELVIEW);
115   glLoadIdentity();
116}
117
118
119static void
120Key(unsigned char key, int x, int y)
121{
122   switch (key) {
123   case 'a':
124   case 'A':
125      Anim = !Anim;
126      if (Anim)
127         glutIdleFunc(Idle);
128      else
129         glutIdleFunc(NULL);
130      break;
131   case 27:
132      glutDestroyWindow(Win);
133      exit(0);
134      break;
135   }
136   glutPostRedisplay();
137}
138
139
140static void
141SpecialKey(int key, int x, int y)
142{
143   (void) x;
144   (void) y;
145   switch (key) {
146   case GLUT_KEY_LEFT:
147      if (CurTexture > 0)
148         CurTexture--;
149      break;
150   case GLUT_KEY_RIGHT:
151      if (CurTexture + 1 < NumTextures)
152         CurTexture++;
153      break;
154   }
155   glutPostRedisplay();
156}
157
158
159static void
160Init(void)
161{
162   printf("GL_RENDERER: %s\n", (char *) glGetString(GL_RENDERER));
163   if (glutExtensionSupported("GL_ARB_robustness"))
164      printf("GL_ARB_robustness supported\n");
165   else
166      printf("GL_ARB_robustness not supported\n");
167
168   MakeTextures();
169   glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
170
171   printf("Keys:\n");
172   printf("  a: toggle animation\n");
173   printf("  Left/Right: back / next frame\n");
174   printf("  Esc: exit\n");
175}
176
177
178int
179main(int argc, char *argv[])
180{
181   glutInit(&argc, argv);
182
183   if (argc > 1) {
184      NumTextures = atoi(argv[1]);
185      if (NumTextures < 1) {
186         printf("Invalid argument (number of textures)\n");
187         return 1;
188      }
189   }
190   printf("Creating %u textures\n", NumTextures);
191
192   glutInitWindowSize(WinWidth, WinHeight);
193   glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE);
194   Win = glutCreateWindow(argv[0]);
195   glewInit();
196   glutReshapeFunc(Reshape);
197   glutKeyboardFunc(Key);
198   glutSpecialFunc(SpecialKey);
199   glutDisplayFunc(Draw);
200
201   if (Anim)
202      glutIdleFunc(Idle);
203
204   Init();
205
206   glutMainLoop();
207   return 0;
208}
209