1
2/*
3 * glDrawPixels demo/test/benchmark
4 *
5 * Brian Paul   September 25, 1997  This file is in the public domain.
6 */
7
8#include <stdio.h>
9#include <stdlib.h>
10#include <math.h>
11#include <string.h>
12#include "glut_wrap.h"
13
14#include "readtex.h"
15
16#define IMAGE_FILE DEMOS_DATA_DIR "girl.rgb"
17
18static int ImgWidth, ImgHeight;
19static GLenum ImgFormat;
20static GLubyte *Image = NULL;
21
22static int Xpos, Ypos;
23static int SkipPixels, SkipRows;
24static int DrawWidth, DrawHeight;
25static int Scissor = 0;
26static int Fog = 0;
27static GLfloat Zpos = -1.0;
28static float Xzoom, Yzoom;
29static GLboolean DrawFront = GL_FALSE;
30static GLboolean Dither = GL_TRUE;
31static int win = 0;
32
33
34static void Reset( void )
35{
36   Xpos = Ypos = 20;
37   DrawWidth = ImgWidth;
38   DrawHeight = ImgHeight;
39   SkipPixels = SkipRows = 0;
40   Scissor = 0;
41   Fog = 0;
42   Zpos = -1.0;
43   Xzoom = Yzoom = 1.0;
44}
45
46
47static void Display( void )
48{
49   glClear( GL_COLOR_BUFFER_BIT );
50
51#if 0
52   glRasterPos2i(Xpos, Ypos);
53#else
54   /* This allows negative raster positions: */
55   glRasterPos3f(0, 0, Zpos);
56   glBitmap(0, 0, 0, 0, Xpos, Ypos, NULL);
57#endif
58
59   glPixelStorei(GL_UNPACK_SKIP_PIXELS, SkipPixels);
60   glPixelStorei(GL_UNPACK_SKIP_ROWS, SkipRows);
61
62   glPixelZoom( Xzoom, Yzoom );
63
64   if (Scissor)
65      glEnable(GL_SCISSOR_TEST);
66
67   if (Fog)
68      glEnable(GL_FOG);
69
70   glDrawPixels(DrawWidth, DrawHeight, ImgFormat, GL_UNSIGNED_BYTE, Image);
71
72   glDisable(GL_SCISSOR_TEST);
73   glDisable(GL_FOG);
74
75   if (DrawFront)
76      glFinish();
77   else
78      glutSwapBuffers();
79}
80
81
82static void Benchmark( void )
83{
84   int startTime, endTime;
85   int draws = 500;
86   double seconds, pixelsPerSecond;
87
88   printf("Benchmarking...\n");
89   /* GL set-up */
90   glPixelStorei(GL_UNPACK_SKIP_PIXELS, SkipPixels);
91   glPixelStorei(GL_UNPACK_SKIP_ROWS, SkipRows);
92   glPixelZoom( Xzoom, Yzoom );
93   if (Scissor)
94      glEnable(GL_SCISSOR_TEST);
95   if (Fog)
96      glEnable(GL_FOG);
97
98   if (DrawFront)
99      glDrawBuffer(GL_FRONT);
100   else
101      glDrawBuffer(GL_BACK);
102
103   /* Run timing test */
104   draws = 0;
105   startTime = glutGet(GLUT_ELAPSED_TIME);
106   do {
107      glDrawPixels(DrawWidth, DrawHeight, ImgFormat, GL_UNSIGNED_BYTE, Image);
108      draws++;
109      endTime = glutGet(GLUT_ELAPSED_TIME);
110   } while (endTime - startTime < 4000);   /* 4 seconds */
111
112   /* GL clean-up */
113   glDisable(GL_SCISSOR_TEST);
114   glDisable(GL_FOG);
115
116   /* Results */
117   seconds = (double) (endTime - startTime) / 1000.0;
118   pixelsPerSecond = draws * DrawWidth * DrawHeight / seconds;
119   printf("Result:  %d draws in %f seconds = %f pixels/sec\n",
120          draws, seconds, pixelsPerSecond);
121}
122
123
124static void Reshape( int width, int height )
125{
126   glViewport( 0, 0, width, height );
127   glMatrixMode( GL_PROJECTION );
128   glLoadIdentity();
129   glOrtho( 0.0, width, 0.0, height, 0.0, 2.0 );
130   glMatrixMode( GL_MODELVIEW );
131   glLoadIdentity();
132
133   glScissor(width/4, height/4, width/2, height/2);
134}
135
136
137static void Key( unsigned char key, int x, int y )
138{
139   (void) x;
140   (void) y;
141   switch (key) {
142      case ' ':
143         Reset();
144         break;
145      case 'd':
146         Dither = !Dither;
147         if (Dither)
148            glEnable(GL_DITHER);
149         else
150            glDisable(GL_DITHER);
151         break;
152      case 'w':
153         if (DrawWidth > 0)
154            DrawWidth--;
155         break;
156      case 'W':
157         DrawWidth++;
158         break;
159      case 'h':
160         if (DrawHeight > 0)
161            DrawHeight--;
162         break;
163      case 'H':
164         DrawHeight++;
165         break;
166      case 'p':
167         if (SkipPixels > 0)
168             SkipPixels--;
169         break;
170      case 'P':
171         SkipPixels++;
172         break;
173      case 'r':
174         if (SkipRows > 0)
175             SkipRows--;
176         break;
177      case 'R':
178         SkipRows++;
179         break;
180      case 's':
181         Scissor = !Scissor;
182         break;
183      case 'x':
184         Xzoom -= 0.1;
185         break;
186      case 'X':
187         Xzoom += 0.1;
188         break;
189      case 'y':
190         Yzoom -= 0.1;
191         break;
192      case 'Y':
193         Yzoom += 0.1;
194         break;
195      case 'z':
196         Zpos -= 0.1;
197         printf("RasterPos Z = %g\n", Zpos);
198         break;
199      case 'Z':
200         Zpos += 0.1;
201         printf("RasterPos Z = %g\n", Zpos);
202         break;
203      case 'b':
204         Benchmark();
205         break;
206      case 'F':
207         Fog = !Fog;
208         printf("Fog %d\n", Fog);
209         break;
210      case 'f':
211         DrawFront = !DrawFront;
212         if (DrawFront)
213            glDrawBuffer(GL_FRONT);
214         else
215            glDrawBuffer(GL_BACK);
216         printf("glDrawBuffer(%s)\n", DrawFront ? "GL_FRONT" : "GL_BACK");
217         break;
218      case 27:
219         glutDestroyWindow(win);
220         exit(0);
221         break;
222   }
223   glutPostRedisplay();
224}
225
226
227static void SpecialKey( int key, int x, int y )
228{
229   (void) x;
230   (void) y;
231   switch (key) {
232      case GLUT_KEY_UP:
233         Ypos += 1;
234         break;
235      case GLUT_KEY_DOWN:
236         Ypos -= 1;
237         break;
238      case GLUT_KEY_LEFT:
239         Xpos -= 1;
240         break;
241      case GLUT_KEY_RIGHT:
242         Xpos += 1;
243         break;
244   }
245   glutPostRedisplay();
246}
247
248
249static void Init( GLboolean ciMode, const char *filename )
250{
251   static const GLfloat fogColor[4] = {0, 1, 0, 0};
252
253   printf("GL_VERSION = %s\n", (char *) glGetString(GL_VERSION));
254   printf("GL_RENDERER = %s\n", (char *) glGetString(GL_RENDERER));
255
256   Image = LoadRGBImage( filename, &ImgWidth, &ImgHeight, &ImgFormat );
257   if (!Image) {
258      printf("Couldn't read %s\n", filename);
259      exit(0);
260   }
261
262   if (ciMode) {
263      /* Convert RGB image to grayscale */
264      GLubyte *indexImage = (GLubyte *) malloc( ImgWidth * ImgHeight );
265      GLint i;
266      for (i=0; i<ImgWidth*ImgHeight; i++) {
267         int gray = Image[i*3] + Image[i*3+1] + Image[i*3+2];
268         indexImage[i] = gray / 3;
269      }
270      free(Image);
271      Image = indexImage;
272      ImgFormat = GL_COLOR_INDEX;
273
274      for (i=0;i<255;i++) {
275         float g = i / 255.0;
276         glutSetColor(i, g, g, g);
277      }
278   }
279
280   printf("Loaded %d by %d image\n", ImgWidth, ImgHeight );
281
282   glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
283   glPixelStorei(GL_UNPACK_ROW_LENGTH, ImgWidth);
284
285   glFogi(GL_FOG_MODE, GL_LINEAR);
286   glFogf(GL_FOG_START, 0);
287   glFogf(GL_FOG_END, 2);
288   glFogfv(GL_FOG_COLOR, fogColor);
289
290   Reset();
291}
292
293
294static void Usage(void)
295{
296   printf("Keys:\n");
297   printf("       SPACE  Reset Parameters\n");
298   printf("     Up/Down  Move image up/down\n");
299   printf("  Left/Right  Move image left/right\n");
300   printf("           x  Decrease X-axis PixelZoom\n");
301   printf("           X  Increase X-axis PixelZoom\n");
302   printf("           y  Decrease Y-axis PixelZoom\n");
303   printf("           Y  Increase Y-axis PixelZoom\n");
304   printf("           w  Decrease glDrawPixels width*\n");
305   printf("           W  Increase glDrawPixels width*\n");
306   printf("           h  Decrease glDrawPixels height*\n");
307   printf("           H  Increase glDrawPixels height*\n");
308   printf("           p  Decrease GL_UNPACK_SKIP_PIXELS*\n");
309   printf("           P  Increase GL_UNPACK_SKIP_PIXELS*\n");
310   printf("           r  Decrease GL_UNPACK_SKIP_ROWS*\n");
311   printf("           R  Increase GL_UNPACK_SKIP_ROWS*\n");
312   printf("           s  Toggle GL_SCISSOR_TEST\n");
313   printf("           F  Toggle GL_FOG\n");
314   printf("           z  Decrease RasterPos Z\n");
315   printf("           Z  Increase RasterPos Z\n");
316
317   printf("           f  Toggle front/back buffer drawing\n");
318   printf("           b  Benchmark test\n");
319   printf("         ESC  Exit\n");
320   printf("* Warning: no limits are imposed on these parameters so it's\n");
321   printf("  possible to cause a segfault if you go too far.\n");
322}
323
324
325int main( int argc, char *argv[] )
326{
327   GLboolean ciMode = GL_FALSE;
328   const char *filename = IMAGE_FILE;
329   int i = 1;
330
331   glutInitWindowSize( 500, 400 );
332   glutInit( &argc, argv );
333
334   if (argc > i && strcmp(argv[i], "-ci")==0) {
335      ciMode = GL_TRUE;
336      i++;
337   }
338   if (argc > i) {
339      filename = argv[i];
340   }
341
342   if (ciMode)
343      glutInitDisplayMode( GLUT_INDEX | GLUT_DOUBLE );
344   else
345      glutInitDisplayMode( GLUT_RGB | GLUT_DOUBLE);
346
347   win = glutCreateWindow(argv[0]);
348
349   Init(ciMode, filename);
350   Usage();
351
352   glutReshapeFunc( Reshape );
353   glutKeyboardFunc( Key );
354   glutSpecialFunc( SpecialKey );
355   glutDisplayFunc( Display );
356
357   glutMainLoop();
358   return 0;
359}
360