132001f49Smrg/**
232001f49Smrg * Try to see other parts of the user's video memory by creating textures
332001f49Smrg * with uninitialized contents.  Display those textures in the window.
432001f49Smrg * Insprired by stories of WebGL security issues.
532001f49Smrg *
632001f49Smrg * The OpenGL driver should probably initialize all memory allocations
732001f49Smrg * to zero (textures, renderbuffers, buffer objects, etc).
832001f49Smrg *
932001f49Smrg * Brian Paul
1032001f49Smrg * June 2011
1132001f49Smrg */
1232001f49Smrg
1332001f49Smrg#define GL_GLEXT_PROTOTYPES
1432001f49Smrg
1532001f49Smrg#include <stdio.h>
1632001f49Smrg#include <stdlib.h>
1732001f49Smrg#include <math.h>
1832001f49Smrg#include <GL/glew.h>
1932001f49Smrg#include "glut_wrap.h"
2032001f49Smrg
2132001f49Smrgstatic int Win;
2232001f49Smrgstatic int WinWidth = 1024, WinHeight = 512;
2332001f49Smrgstatic GLboolean Anim = GL_FALSE;
2432001f49Smrg
2532001f49Smrgstatic GLuint *Textures;
2632001f49Smrgstatic GLuint TexWidth = 1024, TexHeight = 512;
2732001f49Smrgstatic GLuint NumTextures = 50, CurTexture;
2832001f49Smrg
2932001f49Smrg
3032001f49Smrgstatic void
3132001f49SmrgIdle(void)
3232001f49Smrg{
3332001f49Smrg   static int prevTime = 0;
3432001f49Smrg   int curTime = glutGet(GLUT_ELAPSED_TIME);
3532001f49Smrg
3632001f49Smrg   if (!prevTime) {
3732001f49Smrg      prevTime = curTime;
3832001f49Smrg   }
3932001f49Smrg   else {
4032001f49Smrg      if (curTime - prevTime > 250) {
4132001f49Smrg         prevTime = curTime;
4232001f49Smrg         CurTexture = (CurTexture + 1) % NumTextures;
4332001f49Smrg         glutPostRedisplay();
4432001f49Smrg      }
4532001f49Smrg   }
4632001f49Smrg}
4732001f49Smrg
4832001f49Smrg
4932001f49Smrgstatic void
5032001f49SmrgMakeTextures(void)
5132001f49Smrg{
5232001f49Smrg   GLuint i;
5332001f49Smrg
5432001f49Smrg   Textures = (GLuint *) malloc(NumTextures * sizeof(GLuint));
5532001f49Smrg
5632001f49Smrg   glGenTextures(NumTextures, Textures);
5732001f49Smrg   for (i = 0; i < NumTextures; i++) {
5832001f49Smrg      glBindTexture(GL_TEXTURE_2D, Textures[i]);
5932001f49Smrg      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
6032001f49Smrg      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
6132001f49Smrg      glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, TexWidth, TexHeight, 0,
6232001f49Smrg                   GL_RGBA, GL_UNSIGNED_BYTE, NULL);
6332001f49Smrg   }
6432001f49Smrg}
6532001f49Smrg
6632001f49Smrg
6732001f49Smrgstatic void
6832001f49SmrgPrintString(const char *s)
6932001f49Smrg{
7032001f49Smrg   while (*s) {
7132001f49Smrg      glutBitmapCharacter(GLUT_BITMAP_8_BY_13, (int) *s);
7232001f49Smrg      s++;
7332001f49Smrg   }
7432001f49Smrg}
7532001f49Smrg
7632001f49Smrg
7732001f49Smrgstatic void
7832001f49SmrgDraw(void)
7932001f49Smrg{
8032001f49Smrg   char s[100];
8132001f49Smrg
8232001f49Smrg   sprintf(s, "Texture %u", CurTexture);
8332001f49Smrg
8432001f49Smrg   glClear(GL_COLOR_BUFFER_BIT);
8532001f49Smrg
8632001f49Smrg   glEnable(GL_TEXTURE_2D);
8732001f49Smrg   glBindTexture(GL_TEXTURE_2D, CurTexture);
8832001f49Smrg
8932001f49Smrg   glBegin(GL_POLYGON);
9032001f49Smrg   glTexCoord2f(0, 0);  glVertex2f(0, 0);
9132001f49Smrg   glTexCoord2f(1, 0);  glVertex2f(WinWidth, 0);
9232001f49Smrg   glTexCoord2f(1, 1);  glVertex2f(WinWidth, WinHeight);
9332001f49Smrg   glTexCoord2f(0, 1);  glVertex2f(0, WinHeight);
9432001f49Smrg   glEnd();
9532001f49Smrg
9632001f49Smrg   glDisable(GL_TEXTURE_2D);
9732001f49Smrg   glColor3f(0, 1, 0);
9832001f49Smrg   glWindowPos2iARB(10, 10);
9932001f49Smrg   PrintString(s);
10032001f49Smrg
10132001f49Smrg   glutSwapBuffers();
10232001f49Smrg}
10332001f49Smrg
10432001f49Smrg
10532001f49Smrgstatic void
10632001f49SmrgReshape(int width, int height)
10732001f49Smrg{
10832001f49Smrg   WinWidth = width;
10932001f49Smrg   WinHeight = height;
11032001f49Smrg   glViewport(0, 0, width, height);
11132001f49Smrg   glMatrixMode(GL_PROJECTION);
11232001f49Smrg   glLoadIdentity();
11332001f49Smrg   glOrtho(0, WinWidth, 0, WinHeight, -1, 1);
11432001f49Smrg   glMatrixMode(GL_MODELVIEW);
11532001f49Smrg   glLoadIdentity();
11632001f49Smrg}
11732001f49Smrg
11832001f49Smrg
11932001f49Smrgstatic void
12032001f49SmrgKey(unsigned char key, int x, int y)
12132001f49Smrg{
12232001f49Smrg   switch (key) {
12332001f49Smrg   case 'a':
12432001f49Smrg   case 'A':
12532001f49Smrg      Anim = !Anim;
12632001f49Smrg      if (Anim)
12732001f49Smrg         glutIdleFunc(Idle);
12832001f49Smrg      else
12932001f49Smrg         glutIdleFunc(NULL);
13032001f49Smrg      break;
13132001f49Smrg   case 27:
13232001f49Smrg      glutDestroyWindow(Win);
13332001f49Smrg      exit(0);
13432001f49Smrg      break;
13532001f49Smrg   }
13632001f49Smrg   glutPostRedisplay();
13732001f49Smrg}
13832001f49Smrg
13932001f49Smrg
14032001f49Smrgstatic void
14132001f49SmrgSpecialKey(int key, int x, int y)
14232001f49Smrg{
14332001f49Smrg   (void) x;
14432001f49Smrg   (void) y;
14532001f49Smrg   switch (key) {
14632001f49Smrg   case GLUT_KEY_LEFT:
14732001f49Smrg      if (CurTexture > 0)
14832001f49Smrg         CurTexture--;
14932001f49Smrg      break;
15032001f49Smrg   case GLUT_KEY_RIGHT:
15132001f49Smrg      if (CurTexture + 1 < NumTextures)
15232001f49Smrg         CurTexture++;
15332001f49Smrg      break;
15432001f49Smrg   }
15532001f49Smrg   glutPostRedisplay();
15632001f49Smrg}
15732001f49Smrg
15832001f49Smrg
15932001f49Smrgstatic void
16032001f49SmrgInit(void)
16132001f49Smrg{
16232001f49Smrg   printf("GL_RENDERER: %s\n", (char *) glGetString(GL_RENDERER));
16332001f49Smrg   if (glutExtensionSupported("GL_ARB_robustness"))
16432001f49Smrg      printf("GL_ARB_robustness supported\n");
16532001f49Smrg   else
16632001f49Smrg      printf("GL_ARB_robustness not supported\n");
16732001f49Smrg
16832001f49Smrg   MakeTextures();
16932001f49Smrg   glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
17032001f49Smrg
17132001f49Smrg   printf("Keys:\n");
17232001f49Smrg   printf("  a: toggle animation\n");
17332001f49Smrg   printf("  Left/Right: back / next frame\n");
17432001f49Smrg   printf("  Esc: exit\n");
17532001f49Smrg}
17632001f49Smrg
17732001f49Smrg
17832001f49Smrgint
17932001f49Smrgmain(int argc, char *argv[])
18032001f49Smrg{
18132001f49Smrg   glutInit(&argc, argv);
18232001f49Smrg
18332001f49Smrg   if (argc > 1) {
18432001f49Smrg      NumTextures = atoi(argv[1]);
18532001f49Smrg      if (NumTextures < 1) {
18632001f49Smrg         printf("Invalid argument (number of textures)\n");
18732001f49Smrg         return 1;
18832001f49Smrg      }
18932001f49Smrg   }
19032001f49Smrg   printf("Creating %u textures\n", NumTextures);
19132001f49Smrg
19232001f49Smrg   glutInitWindowSize(WinWidth, WinHeight);
19332001f49Smrg   glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE);
19432001f49Smrg   Win = glutCreateWindow(argv[0]);
19532001f49Smrg   glewInit();
19632001f49Smrg   glutReshapeFunc(Reshape);
19732001f49Smrg   glutKeyboardFunc(Key);
19832001f49Smrg   glutSpecialFunc(SpecialKey);
19932001f49Smrg   glutDisplayFunc(Draw);
20032001f49Smrg
20132001f49Smrg   if (Anim)
20232001f49Smrg      glutIdleFunc(Idle);
20332001f49Smrg
20432001f49Smrg   Init();
20532001f49Smrg
20632001f49Smrg   glutMainLoop();
20732001f49Smrg   return 0;
20832001f49Smrg}
209