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