132001f49Smrg 232001f49Smrg/* 332001f49Smrg * glDrawPixels demo/test/benchmark 432001f49Smrg * 532001f49Smrg * Brian Paul September 25, 1997 This file is in the public domain. 632001f49Smrg */ 732001f49Smrg 832001f49Smrg#include <stdio.h> 932001f49Smrg#include <stdlib.h> 1032001f49Smrg#include <math.h> 1132001f49Smrg#include <string.h> 1232001f49Smrg#include "glut_wrap.h" 1332001f49Smrg 1432001f49Smrg#include "readtex.h" 1532001f49Smrg 1632001f49Smrg#define IMAGE_FILE DEMOS_DATA_DIR "girl.rgb" 1732001f49Smrg 1832001f49Smrgstatic int ImgWidth, ImgHeight; 1932001f49Smrgstatic GLenum ImgFormat; 2032001f49Smrgstatic GLubyte *Image = NULL; 2132001f49Smrg 2232001f49Smrgstatic int Xpos, Ypos; 2332001f49Smrgstatic int SkipPixels, SkipRows; 2432001f49Smrgstatic int DrawWidth, DrawHeight; 2532001f49Smrgstatic int Scissor = 0; 2632001f49Smrgstatic int Fog = 0; 2732001f49Smrgstatic GLfloat Zpos = -1.0; 2832001f49Smrgstatic float Xzoom, Yzoom; 2932001f49Smrgstatic GLboolean DrawFront = GL_FALSE; 3032001f49Smrgstatic GLboolean Dither = GL_TRUE; 3132001f49Smrgstatic int win = 0; 3232001f49Smrg 3332001f49Smrg 3432001f49Smrgstatic void Reset( void ) 3532001f49Smrg{ 3632001f49Smrg Xpos = Ypos = 20; 3732001f49Smrg DrawWidth = ImgWidth; 3832001f49Smrg DrawHeight = ImgHeight; 3932001f49Smrg SkipPixels = SkipRows = 0; 4032001f49Smrg Scissor = 0; 4132001f49Smrg Fog = 0; 4232001f49Smrg Zpos = -1.0; 4332001f49Smrg Xzoom = Yzoom = 1.0; 4432001f49Smrg} 4532001f49Smrg 4632001f49Smrg 4732001f49Smrgstatic void Display( void ) 4832001f49Smrg{ 4932001f49Smrg glClear( GL_COLOR_BUFFER_BIT ); 5032001f49Smrg 5132001f49Smrg#if 0 5232001f49Smrg glRasterPos2i(Xpos, Ypos); 5332001f49Smrg#else 5432001f49Smrg /* This allows negative raster positions: */ 5532001f49Smrg glRasterPos3f(0, 0, Zpos); 5632001f49Smrg glBitmap(0, 0, 0, 0, Xpos, Ypos, NULL); 5732001f49Smrg#endif 5832001f49Smrg 5932001f49Smrg glPixelStorei(GL_UNPACK_SKIP_PIXELS, SkipPixels); 6032001f49Smrg glPixelStorei(GL_UNPACK_SKIP_ROWS, SkipRows); 6132001f49Smrg 6232001f49Smrg glPixelZoom( Xzoom, Yzoom ); 6332001f49Smrg 6432001f49Smrg if (Scissor) 6532001f49Smrg glEnable(GL_SCISSOR_TEST); 6632001f49Smrg 6732001f49Smrg if (Fog) 6832001f49Smrg glEnable(GL_FOG); 6932001f49Smrg 7032001f49Smrg glDrawPixels(DrawWidth, DrawHeight, ImgFormat, GL_UNSIGNED_BYTE, Image); 7132001f49Smrg 7232001f49Smrg glDisable(GL_SCISSOR_TEST); 7332001f49Smrg glDisable(GL_FOG); 7432001f49Smrg 7532001f49Smrg if (DrawFront) 7632001f49Smrg glFinish(); 7732001f49Smrg else 7832001f49Smrg glutSwapBuffers(); 7932001f49Smrg} 8032001f49Smrg 8132001f49Smrg 8232001f49Smrgstatic void Benchmark( void ) 8332001f49Smrg{ 8432001f49Smrg int startTime, endTime; 8532001f49Smrg int draws = 500; 8632001f49Smrg double seconds, pixelsPerSecond; 8732001f49Smrg 8832001f49Smrg printf("Benchmarking...\n"); 8932001f49Smrg /* GL set-up */ 9032001f49Smrg glPixelStorei(GL_UNPACK_SKIP_PIXELS, SkipPixels); 9132001f49Smrg glPixelStorei(GL_UNPACK_SKIP_ROWS, SkipRows); 9232001f49Smrg glPixelZoom( Xzoom, Yzoom ); 9332001f49Smrg if (Scissor) 9432001f49Smrg glEnable(GL_SCISSOR_TEST); 9532001f49Smrg if (Fog) 9632001f49Smrg glEnable(GL_FOG); 9732001f49Smrg 9832001f49Smrg if (DrawFront) 9932001f49Smrg glDrawBuffer(GL_FRONT); 10032001f49Smrg else 10132001f49Smrg glDrawBuffer(GL_BACK); 10232001f49Smrg 10332001f49Smrg /* Run timing test */ 10432001f49Smrg draws = 0; 10532001f49Smrg startTime = glutGet(GLUT_ELAPSED_TIME); 10632001f49Smrg do { 10732001f49Smrg glDrawPixels(DrawWidth, DrawHeight, ImgFormat, GL_UNSIGNED_BYTE, Image); 10832001f49Smrg draws++; 10932001f49Smrg endTime = glutGet(GLUT_ELAPSED_TIME); 11032001f49Smrg } while (endTime - startTime < 4000); /* 4 seconds */ 11132001f49Smrg 11232001f49Smrg /* GL clean-up */ 11332001f49Smrg glDisable(GL_SCISSOR_TEST); 11432001f49Smrg glDisable(GL_FOG); 11532001f49Smrg 11632001f49Smrg /* Results */ 11732001f49Smrg seconds = (double) (endTime - startTime) / 1000.0; 11832001f49Smrg pixelsPerSecond = draws * DrawWidth * DrawHeight / seconds; 11932001f49Smrg printf("Result: %d draws in %f seconds = %f pixels/sec\n", 12032001f49Smrg draws, seconds, pixelsPerSecond); 12132001f49Smrg} 12232001f49Smrg 12332001f49Smrg 12432001f49Smrgstatic void Reshape( int width, int height ) 12532001f49Smrg{ 12632001f49Smrg glViewport( 0, 0, width, height ); 12732001f49Smrg glMatrixMode( GL_PROJECTION ); 12832001f49Smrg glLoadIdentity(); 12932001f49Smrg glOrtho( 0.0, width, 0.0, height, 0.0, 2.0 ); 13032001f49Smrg glMatrixMode( GL_MODELVIEW ); 13132001f49Smrg glLoadIdentity(); 13232001f49Smrg 13332001f49Smrg glScissor(width/4, height/4, width/2, height/2); 13432001f49Smrg} 13532001f49Smrg 13632001f49Smrg 13732001f49Smrgstatic void Key( unsigned char key, int x, int y ) 13832001f49Smrg{ 13932001f49Smrg (void) x; 14032001f49Smrg (void) y; 14132001f49Smrg switch (key) { 14232001f49Smrg case ' ': 14332001f49Smrg Reset(); 14432001f49Smrg break; 14532001f49Smrg case 'd': 14632001f49Smrg Dither = !Dither; 14732001f49Smrg if (Dither) 14832001f49Smrg glEnable(GL_DITHER); 14932001f49Smrg else 15032001f49Smrg glDisable(GL_DITHER); 15132001f49Smrg break; 15232001f49Smrg case 'w': 15332001f49Smrg if (DrawWidth > 0) 15432001f49Smrg DrawWidth--; 15532001f49Smrg break; 15632001f49Smrg case 'W': 15732001f49Smrg DrawWidth++; 15832001f49Smrg break; 15932001f49Smrg case 'h': 16032001f49Smrg if (DrawHeight > 0) 16132001f49Smrg DrawHeight--; 16232001f49Smrg break; 16332001f49Smrg case 'H': 16432001f49Smrg DrawHeight++; 16532001f49Smrg break; 16632001f49Smrg case 'p': 16732001f49Smrg if (SkipPixels > 0) 16832001f49Smrg SkipPixels--; 16932001f49Smrg break; 17032001f49Smrg case 'P': 17132001f49Smrg SkipPixels++; 17232001f49Smrg break; 17332001f49Smrg case 'r': 17432001f49Smrg if (SkipRows > 0) 17532001f49Smrg SkipRows--; 17632001f49Smrg break; 17732001f49Smrg case 'R': 17832001f49Smrg SkipRows++; 17932001f49Smrg break; 18032001f49Smrg case 's': 18132001f49Smrg Scissor = !Scissor; 18232001f49Smrg break; 18332001f49Smrg case 'x': 18432001f49Smrg Xzoom -= 0.1; 18532001f49Smrg break; 18632001f49Smrg case 'X': 18732001f49Smrg Xzoom += 0.1; 18832001f49Smrg break; 18932001f49Smrg case 'y': 19032001f49Smrg Yzoom -= 0.1; 19132001f49Smrg break; 19232001f49Smrg case 'Y': 19332001f49Smrg Yzoom += 0.1; 19432001f49Smrg break; 19532001f49Smrg case 'z': 19632001f49Smrg Zpos -= 0.1; 19732001f49Smrg printf("RasterPos Z = %g\n", Zpos); 19832001f49Smrg break; 19932001f49Smrg case 'Z': 20032001f49Smrg Zpos += 0.1; 20132001f49Smrg printf("RasterPos Z = %g\n", Zpos); 20232001f49Smrg break; 20332001f49Smrg case 'b': 20432001f49Smrg Benchmark(); 20532001f49Smrg break; 20632001f49Smrg case 'F': 20732001f49Smrg Fog = !Fog; 20832001f49Smrg printf("Fog %d\n", Fog); 20932001f49Smrg break; 21032001f49Smrg case 'f': 21132001f49Smrg DrawFront = !DrawFront; 21232001f49Smrg if (DrawFront) 21332001f49Smrg glDrawBuffer(GL_FRONT); 21432001f49Smrg else 21532001f49Smrg glDrawBuffer(GL_BACK); 21632001f49Smrg printf("glDrawBuffer(%s)\n", DrawFront ? "GL_FRONT" : "GL_BACK"); 21732001f49Smrg break; 21832001f49Smrg case 27: 21932001f49Smrg glutDestroyWindow(win); 22032001f49Smrg exit(0); 22132001f49Smrg break; 22232001f49Smrg } 22332001f49Smrg glutPostRedisplay(); 22432001f49Smrg} 22532001f49Smrg 22632001f49Smrg 22732001f49Smrgstatic void SpecialKey( int key, int x, int y ) 22832001f49Smrg{ 22932001f49Smrg (void) x; 23032001f49Smrg (void) y; 23132001f49Smrg switch (key) { 23232001f49Smrg case GLUT_KEY_UP: 23332001f49Smrg Ypos += 1; 23432001f49Smrg break; 23532001f49Smrg case GLUT_KEY_DOWN: 23632001f49Smrg Ypos -= 1; 23732001f49Smrg break; 23832001f49Smrg case GLUT_KEY_LEFT: 23932001f49Smrg Xpos -= 1; 24032001f49Smrg break; 24132001f49Smrg case GLUT_KEY_RIGHT: 24232001f49Smrg Xpos += 1; 24332001f49Smrg break; 24432001f49Smrg } 24532001f49Smrg glutPostRedisplay(); 24632001f49Smrg} 24732001f49Smrg 24832001f49Smrg 24932001f49Smrgstatic void Init( GLboolean ciMode, const char *filename ) 25032001f49Smrg{ 25132001f49Smrg static const GLfloat fogColor[4] = {0, 1, 0, 0}; 25232001f49Smrg 25332001f49Smrg printf("GL_VERSION = %s\n", (char *) glGetString(GL_VERSION)); 25432001f49Smrg printf("GL_RENDERER = %s\n", (char *) glGetString(GL_RENDERER)); 25532001f49Smrg 25632001f49Smrg Image = LoadRGBImage( filename, &ImgWidth, &ImgHeight, &ImgFormat ); 25732001f49Smrg if (!Image) { 25832001f49Smrg printf("Couldn't read %s\n", filename); 25932001f49Smrg exit(0); 26032001f49Smrg } 26132001f49Smrg 26232001f49Smrg if (ciMode) { 26332001f49Smrg /* Convert RGB image to grayscale */ 26432001f49Smrg GLubyte *indexImage = (GLubyte *) malloc( ImgWidth * ImgHeight ); 26532001f49Smrg GLint i; 26632001f49Smrg for (i=0; i<ImgWidth*ImgHeight; i++) { 26732001f49Smrg int gray = Image[i*3] + Image[i*3+1] + Image[i*3+2]; 26832001f49Smrg indexImage[i] = gray / 3; 26932001f49Smrg } 27032001f49Smrg free(Image); 27132001f49Smrg Image = indexImage; 27232001f49Smrg ImgFormat = GL_COLOR_INDEX; 27332001f49Smrg 27432001f49Smrg for (i=0;i<255;i++) { 27532001f49Smrg float g = i / 255.0; 27632001f49Smrg glutSetColor(i, g, g, g); 27732001f49Smrg } 27832001f49Smrg } 27932001f49Smrg 28032001f49Smrg printf("Loaded %d by %d image\n", ImgWidth, ImgHeight ); 28132001f49Smrg 28232001f49Smrg glPixelStorei(GL_UNPACK_ALIGNMENT, 1); 28332001f49Smrg glPixelStorei(GL_UNPACK_ROW_LENGTH, ImgWidth); 28432001f49Smrg 28532001f49Smrg glFogi(GL_FOG_MODE, GL_LINEAR); 28632001f49Smrg glFogf(GL_FOG_START, 0); 28732001f49Smrg glFogf(GL_FOG_END, 2); 28832001f49Smrg glFogfv(GL_FOG_COLOR, fogColor); 28932001f49Smrg 29032001f49Smrg Reset(); 29132001f49Smrg} 29232001f49Smrg 29332001f49Smrg 29432001f49Smrgstatic void Usage(void) 29532001f49Smrg{ 29632001f49Smrg printf("Keys:\n"); 29732001f49Smrg printf(" SPACE Reset Parameters\n"); 29832001f49Smrg printf(" Up/Down Move image up/down\n"); 29932001f49Smrg printf(" Left/Right Move image left/right\n"); 30032001f49Smrg printf(" x Decrease X-axis PixelZoom\n"); 30132001f49Smrg printf(" X Increase X-axis PixelZoom\n"); 30232001f49Smrg printf(" y Decrease Y-axis PixelZoom\n"); 30332001f49Smrg printf(" Y Increase Y-axis PixelZoom\n"); 30432001f49Smrg printf(" w Decrease glDrawPixels width*\n"); 30532001f49Smrg printf(" W Increase glDrawPixels width*\n"); 30632001f49Smrg printf(" h Decrease glDrawPixels height*\n"); 30732001f49Smrg printf(" H Increase glDrawPixels height*\n"); 30832001f49Smrg printf(" p Decrease GL_UNPACK_SKIP_PIXELS*\n"); 30932001f49Smrg printf(" P Increase GL_UNPACK_SKIP_PIXELS*\n"); 31032001f49Smrg printf(" r Decrease GL_UNPACK_SKIP_ROWS*\n"); 31132001f49Smrg printf(" R Increase GL_UNPACK_SKIP_ROWS*\n"); 31232001f49Smrg printf(" s Toggle GL_SCISSOR_TEST\n"); 31332001f49Smrg printf(" F Toggle GL_FOG\n"); 31432001f49Smrg printf(" z Decrease RasterPos Z\n"); 31532001f49Smrg printf(" Z Increase RasterPos Z\n"); 31632001f49Smrg 31732001f49Smrg printf(" f Toggle front/back buffer drawing\n"); 31832001f49Smrg printf(" b Benchmark test\n"); 31932001f49Smrg printf(" ESC Exit\n"); 32032001f49Smrg printf("* Warning: no limits are imposed on these parameters so it's\n"); 32132001f49Smrg printf(" possible to cause a segfault if you go too far.\n"); 32232001f49Smrg} 32332001f49Smrg 32432001f49Smrg 32532001f49Smrgint main( int argc, char *argv[] ) 32632001f49Smrg{ 32732001f49Smrg GLboolean ciMode = GL_FALSE; 32832001f49Smrg const char *filename = IMAGE_FILE; 32932001f49Smrg int i = 1; 33032001f49Smrg 33132001f49Smrg glutInitWindowSize( 500, 400 ); 33232001f49Smrg glutInit( &argc, argv ); 33332001f49Smrg 33432001f49Smrg if (argc > i && strcmp(argv[i], "-ci")==0) { 33532001f49Smrg ciMode = GL_TRUE; 33632001f49Smrg i++; 33732001f49Smrg } 33832001f49Smrg if (argc > i) { 33932001f49Smrg filename = argv[i]; 34032001f49Smrg } 34132001f49Smrg 34232001f49Smrg if (ciMode) 34332001f49Smrg glutInitDisplayMode( GLUT_INDEX | GLUT_DOUBLE ); 34432001f49Smrg else 34532001f49Smrg glutInitDisplayMode( GLUT_RGB | GLUT_DOUBLE); 34632001f49Smrg 34732001f49Smrg win = glutCreateWindow(argv[0]); 34832001f49Smrg 34932001f49Smrg Init(ciMode, filename); 35032001f49Smrg Usage(); 35132001f49Smrg 35232001f49Smrg glutReshapeFunc( Reshape ); 35332001f49Smrg glutKeyboardFunc( Key ); 35432001f49Smrg glutSpecialFunc( SpecialKey ); 35532001f49Smrg glutDisplayFunc( Display ); 35632001f49Smrg 35732001f49Smrg glutMainLoop(); 35832001f49Smrg return 0; 35932001f49Smrg} 360