Merge branch 'mesa_7_7_branch'
[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 <string.h>
12 #include <GL/glut.h>
13
14 #include "readtex.h"
15
16 #define IMAGE_FILE "../images/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
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
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
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
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
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
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
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
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
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 }