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