333cab36086058ff543cdba6f194f525e07eef15
[mesa.git] / progs / demos / drawpix.c
1 /* $Id: drawpix.c,v 1.6 2002/01/26 17:49:30 brianp Exp $ */
2
3 /*
4 * glDrawPixels demo/test/benchmark
5 *
6 * Brian Paul September 25, 1997 This file is in the public domain.
7 */
8
9 /*
10 * $Log: drawpix.c,v $
11 * Revision 1.6 2002/01/26 17:49:30 brianp
12 * added fog and raster Z position controls
13 *
14 * Revision 1.5 2000/12/24 22:53:54 pesco
15 * * demos/Makefile.am (INCLUDES): Added -I$(top_srcdir)/util.
16 * * demos/Makefile.X11, demos/Makefile.BeOS-R4, demos/Makefile.cygnus:
17 * Essentially the same.
18 * Program files updated to include "readtex.c", not "../util/readtex.c".
19 * * demos/reflect.c: Likewise for "showbuffer.c".
20 *
21 *
22 * * Makefile.am (EXTRA_DIST): Added top-level regular files.
23 *
24 * * include/GL/Makefile.am (INC_X11): Added glxext.h.
25 *
26 *
27 * * src/GGI/include/ggi/mesa/Makefile.am (EXTRA_HEADERS): Include
28 * Mesa GGI headers in dist even if HAVE_GGI is not given.
29 *
30 * * configure.in: Look for GLUT and demo source dirs in $srcdir.
31 *
32 * * src/swrast/Makefile.am (libMesaSwrast_la_SOURCES): Set to *.[ch].
33 * More source list updates in various Makefile.am's.
34 *
35 * * Makefile.am (dist-hook): Remove CVS directory from distribution.
36 * (DIST_SUBDIRS): List all possible subdirs here.
37 * (SUBDIRS): Only list subdirs selected for build again.
38 * The above two applied to all subdir Makefile.am's also.
39 *
40 * Revision 1.4 2000/09/08 21:45:21 brianp
41 * added dither key option
42 *
43 * Revision 1.3 1999/10/28 18:23:29 brianp
44 * minor changes to Usage() function
45 *
46 * Revision 1.2 1999/10/21 22:13:58 brianp
47 * added f key to toggle front/back drawing
48 *
49 * Revision 1.1.1.1 1999/08/19 00:55:40 jtg
50 * Imported sources
51 *
52 * Revision 3.3 1999/03/28 18:18:33 brianp
53 * minor clean-up
54 *
55 * Revision 3.2 1998/11/05 04:34:04 brianp
56 * moved image files to ../images/ directory
57 *
58 * Revision 3.1 1998/02/22 16:43:17 brianp
59 * added a few casts to silence compiler warnings
60 *
61 * Revision 3.0 1998/02/14 18:42:29 brianp
62 * initial rev
63 *
64 */
65
66
67 #include <stdio.h>
68 #include <stdlib.h>
69 #include <math.h>
70 #include <GL/glut.h>
71
72 #include "readtex.c"
73
74 #define IMAGE_FILE "../images/girl.rgb"
75
76 static int ImgWidth, ImgHeight;
77 static GLenum ImgFormat;
78 static GLubyte *Image = NULL;
79
80 static int Xpos, Ypos;
81 static int SkipPixels, SkipRows;
82 static int DrawWidth, DrawHeight;
83 static int Scissor = 0;
84 static int Fog = 0;
85 static GLfloat Zpos = -1.0;
86 static float Xzoom, Yzoom;
87 static GLboolean DrawFront = GL_FALSE;
88 static GLboolean Dither = GL_TRUE;
89
90
91 static void Reset( void )
92 {
93 Xpos = Ypos = 20;
94 DrawWidth = ImgWidth;
95 DrawHeight = ImgHeight;
96 SkipPixels = SkipRows = 0;
97 Scissor = 0;
98 Fog = 0;
99 Zpos = -1.0;
100 Xzoom = Yzoom = 1.0;
101 }
102
103
104 static void Display( void )
105 {
106 glClear( GL_COLOR_BUFFER_BIT );
107
108 #if 0
109 glRasterPos2i(Xpos, Ypos);
110 #else
111 /* This allows negative raster positions: */
112 glRasterPos3f(0, 0, Zpos);
113 glBitmap(0, 0, 0, 0, Xpos, Ypos, NULL);
114 #endif
115
116 glPixelStorei(GL_UNPACK_SKIP_PIXELS, SkipPixels);
117 glPixelStorei(GL_UNPACK_SKIP_ROWS, SkipRows);
118
119 glPixelZoom( Xzoom, Yzoom );
120
121 if (Scissor)
122 glEnable(GL_SCISSOR_TEST);
123
124 if (Fog)
125 glEnable(GL_FOG);
126
127 glDrawPixels(DrawWidth, DrawHeight, ImgFormat, GL_UNSIGNED_BYTE, Image);
128
129 glDisable(GL_SCISSOR_TEST);
130 glDisable(GL_FOG);
131
132 if (!DrawFront)
133 glutSwapBuffers();
134 }
135
136
137 static void Benchmark( void )
138 {
139 int startTime, endTime;
140 int draws = 500;
141 double seconds, pixelsPerSecond;
142
143 printf("Benchmarking...\n");
144 /* GL set-up */
145 glPixelStorei(GL_UNPACK_SKIP_PIXELS, SkipPixels);
146 glPixelStorei(GL_UNPACK_SKIP_ROWS, SkipRows);
147 glPixelZoom( Xzoom, Yzoom );
148 if (Scissor)
149 glEnable(GL_SCISSOR_TEST);
150 if (Fog)
151 glEnable(GL_FOG);
152
153 if (DrawFront)
154 glDrawBuffer(GL_FRONT);
155 else
156 glDrawBuffer(GL_BACK);
157
158 /* Run timing test */
159 draws = 0;
160 startTime = glutGet(GLUT_ELAPSED_TIME);
161 do {
162 glDrawPixels(DrawWidth, DrawHeight, ImgFormat, GL_UNSIGNED_BYTE, Image);
163 draws++;
164 endTime = glutGet(GLUT_ELAPSED_TIME);
165 } while (endTime - startTime < 4000); /* 4 seconds */
166
167 /* GL clean-up */
168 glDisable(GL_SCISSOR_TEST);
169 glDisable(GL_FOG);
170
171 /* Results */
172 seconds = (double) (endTime - startTime) / 1000.0;
173 pixelsPerSecond = draws * DrawWidth * DrawHeight / seconds;
174 printf("Result: %d draws in %f seconds = %f pixels/sec\n",
175 draws, seconds, pixelsPerSecond);
176 }
177
178
179 static void Reshape( int width, int height )
180 {
181 glViewport( 0, 0, width, height );
182 glMatrixMode( GL_PROJECTION );
183 glLoadIdentity();
184 glOrtho( 0.0, width, 0.0, height, 0.0, 2.0 );
185 glMatrixMode( GL_MODELVIEW );
186 glLoadIdentity();
187
188 glScissor(width/4, height/4, width/2, height/2);
189 }
190
191
192 static void Key( unsigned char key, int x, int y )
193 {
194 (void) x;
195 (void) y;
196 switch (key) {
197 case ' ':
198 Reset();
199 break;
200 case 'd':
201 Dither = !Dither;
202 if (Dither)
203 glEnable(GL_DITHER);
204 else
205 glDisable(GL_DITHER);
206 break;
207 case 'w':
208 if (DrawWidth > 0)
209 DrawWidth--;
210 break;
211 case 'W':
212 DrawWidth++;
213 break;
214 case 'h':
215 if (DrawHeight > 0)
216 DrawHeight--;
217 break;
218 case 'H':
219 DrawHeight++;
220 break;
221 case 'p':
222 if (SkipPixels > 0)
223 SkipPixels--;
224 break;
225 case 'P':
226 SkipPixels++;
227 break;
228 case 'r':
229 if (SkipRows > 0)
230 SkipRows--;
231 break;
232 case 'R':
233 SkipRows++;
234 break;
235 case 's':
236 Scissor = !Scissor;
237 break;
238 case 'x':
239 Xzoom -= 0.1;
240 break;
241 case 'X':
242 Xzoom += 0.1;
243 break;
244 case 'y':
245 Yzoom -= 0.1;
246 break;
247 case 'Y':
248 Yzoom += 0.1;
249 break;
250 case 'z':
251 Zpos -= 0.1;
252 printf("RasterPos Z = %g\n", Zpos);
253 break;
254 case 'Z':
255 Zpos += 0.1;
256 printf("RasterPos Z = %g\n", Zpos);
257 break;
258 case 'b':
259 Benchmark();
260 break;
261 case 'F':
262 Fog = !Fog;
263 printf("Fog %d\n", Fog);
264 break;
265 case 'f':
266 DrawFront = !DrawFront;
267 if (DrawFront)
268 glDrawBuffer(GL_FRONT);
269 else
270 glDrawBuffer(GL_BACK);
271 printf("glDrawBuffer(%s)\n", DrawFront ? "GL_FRONT" : "GL_BACK");
272 break;
273 case 27:
274 exit(0);
275 break;
276 }
277 glutPostRedisplay();
278 }
279
280
281 static void SpecialKey( int key, int x, int y )
282 {
283 (void) x;
284 (void) y;
285 switch (key) {
286 case GLUT_KEY_UP:
287 Ypos += 1;
288 break;
289 case GLUT_KEY_DOWN:
290 Ypos -= 1;
291 break;
292 case GLUT_KEY_LEFT:
293 Xpos -= 1;
294 break;
295 case GLUT_KEY_RIGHT:
296 Xpos += 1;
297 break;
298 }
299 glutPostRedisplay();
300 }
301
302
303 static void Init( GLboolean ciMode )
304 {
305 static const GLfloat fogColor[4] = {0, 1, 0, 0};
306
307 printf("GL_VERSION = %s\n", (char *) glGetString(GL_VERSION));
308 printf("GL_RENDERER = %s\n", (char *) glGetString(GL_RENDERER));
309
310 Image = LoadRGBImage( IMAGE_FILE, &ImgWidth, &ImgHeight, &ImgFormat );
311 if (!Image) {
312 printf("Couldn't read %s\n", IMAGE_FILE);
313 exit(0);
314 }
315
316 if (ciMode) {
317 /* Convert RGB image to grayscale */
318 GLubyte *indexImage = malloc( ImgWidth * ImgHeight );
319 GLint i;
320 for (i=0; i<ImgWidth*ImgHeight; i++) {
321 int gray = Image[i*3] + Image[i*3+1] + Image[i*3+2];
322 indexImage[i] = gray / 3;
323 }
324 free(Image);
325 Image = indexImage;
326 ImgFormat = GL_COLOR_INDEX;
327
328 for (i=0;i<255;i++) {
329 float g = i / 255.0;
330 glutSetColor(i, g, g, g);
331 }
332 }
333
334 printf("Loaded %d by %d image\n", ImgWidth, ImgHeight );
335
336 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
337 glPixelStorei(GL_UNPACK_ROW_LENGTH, ImgWidth);
338
339 glFogi(GL_FOG_MODE, GL_LINEAR);
340 glFogf(GL_FOG_START, 0);
341 glFogf(GL_FOG_END, 2);
342 glFogfv(GL_FOG_COLOR, fogColor);
343
344 Reset();
345 }
346
347
348 static void Usage(void)
349 {
350 printf("Keys:\n");
351 printf(" SPACE Reset Parameters\n");
352 printf(" Up/Down Move image up/down\n");
353 printf(" Left/Right Move image left/right\n");
354 printf(" x Decrease X-axis PixelZoom\n");
355 printf(" X Increase X-axis PixelZoom\n");
356 printf(" y Decrease Y-axis PixelZoom\n");
357 printf(" Y Increase Y-axis PixelZoom\n");
358 printf(" w Decrease glDrawPixels width*\n");
359 printf(" W Increase glDrawPixels width*\n");
360 printf(" h Decrease glDrawPixels height*\n");
361 printf(" H Increase glDrawPixels height*\n");
362 printf(" p Decrease GL_UNPACK_SKIP_PIXELS*\n");
363 printf(" P Increase GL_UNPACK_SKIP_PIXELS*\n");
364 printf(" r Decrease GL_UNPACK_SKIP_ROWS*\n");
365 printf(" R Increase GL_UNPACK_SKIP_ROWS*\n");
366 printf(" s Toggle GL_SCISSOR_TEST\n");
367 printf(" F Toggle GL_FOG\n");
368 printf(" z Decrease RasterPos Z\n");
369 printf(" Z Increase RasterPos Z\n");
370
371 printf(" f Toggle front/back buffer drawing\n");
372 printf(" b Benchmark test\n");
373 printf(" ESC Exit\n");
374 printf("* Warning: no limits are imposed on these parameters so it's\n");
375 printf(" possible to cause a segfault if you go too far.\n");
376 }
377
378
379 int main( int argc, char *argv[] )
380 {
381 GLboolean ciMode = GL_FALSE;
382
383 if (argc > 1 && strcmp(argv[1], "-ci")==0) {
384 ciMode = GL_TRUE;
385 }
386
387 glutInit( &argc, argv );
388 glutInitWindowPosition( 0, 0 );
389 glutInitWindowSize( 500, 400 );
390
391 if (ciMode)
392 glutInitDisplayMode( GLUT_INDEX | GLUT_DOUBLE );
393 else
394 glutInitDisplayMode( GLUT_RGB | GLUT_DOUBLE);
395
396 glutCreateWindow(argv[0]);
397
398 Init(ciMode);
399 Usage();
400
401 glutReshapeFunc( Reshape );
402 glutKeyboardFunc( Key );
403 glutSpecialFunc( SpecialKey );
404 glutDisplayFunc( Display );
405
406 glutMainLoop();
407 return 0;
408 }