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 
18 static int ImgWidth, ImgHeight;
19 static GLenum ImgFormat;
20 static GLubyte *Image = NULL;
21 
22 static int Xpos, Ypos;
23 static int SkipPixels, SkipRows;
24 static int DrawWidth, DrawHeight;
25 static int Scissor = 0;
26 static int Fog = 0;
27 static GLfloat Zpos = -1.0;
28 static float Xzoom, Yzoom;
29 static GLboolean DrawFront = GL_FALSE;
30 static GLboolean Dither = GL_TRUE;
31 static int win = 0;
32 
33 
Reset(void)34 static 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 
Display(void)47 static 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 
Benchmark(void)82 static 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 
Reshape(int width,int height)124 static 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 
Key(unsigned char key,int x,int y)137 static 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 
SpecialKey(int key,int x,int y)227 static 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 
Init(GLboolean ciMode,const char * filename)249 static 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 
Usage(void)294 static 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 
main(int argc,char * argv[])325 int 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