blob: dd3a0af6fc3200b1b4699ca99b110744be7a9d10 [file] [log] [blame]
Brian Paul4f6d60e2000-03-23 19:47:25 +00001/* $Id: readpix.c,v 1.2 2000/03/23 19:47:25 brianp Exp $ */
Brian Pauleca1bc92000-03-01 16:23:14 +00002
3/*
4 * glReadPixels and glCopyPixels test
5 *
6 * Brian Paul March 1, 2000 This file is in the public domain.
7 */
8
9/*
10 * $Log: readpix.c,v $
Brian Paul4f6d60e2000-03-23 19:47:25 +000011 * Revision 1.2 2000/03/23 19:47:25 brianp
12 * added benchmarking
13 *
Brian Pauleca1bc92000-03-01 16:23:14 +000014 * Revision 1.1 2000/03/01 16:23:14 brianp
15 * test glDraw/Read/CopyPixels()
16 *
17 */
18
19
20#include <assert.h>
21#include <stdio.h>
22#include <stdlib.h>
23#include <math.h>
24#include <GL/glut.h>
25
26#include "../util/readtex.c" /* a hack, I know */
27
28#define IMAGE_FILE "../images/girl.rgb"
29
30static int ImgWidth, ImgHeight;
31static GLenum ImgFormat;
32static GLubyte *Image = NULL;
33
34static int APosX, APosY; /* simple drawpixels */
35static int BPosX, BPosY; /* read/draw pixels */
36static int CPosX, CPosY; /* copypixels */
37
38static GLboolean DrawFront = GL_FALSE;
39static GLboolean ScaleAndBias = GL_FALSE;
Brian Paul4f6d60e2000-03-23 19:47:25 +000040static GLboolean Benchmark = GL_FALSE;
Brian Pauleca1bc92000-03-01 16:23:14 +000041static GLubyte *TempImage = NULL;
42
43
44static void
45Reset( void )
46{
47 APosX = 5; APosY = 20;
48 BPosX = APosX + ImgWidth + 5; BPosY = 20;
49 CPosX = BPosX + ImgWidth + 5; CPosY = 20;
50}
51
52
53static void
54PrintString(const char *s)
55{
56 while (*s) {
57 glutBitmapCharacter(GLUT_BITMAP_8_BY_13, (int) *s);
58 s++;
59 }
60}
61
62
63static void
64SetupPixelTransfer(GLboolean invert)
65{
66 if (invert) {
67 glPixelTransferf(GL_RED_SCALE, -1.0);
68 glPixelTransferf(GL_RED_BIAS, 1.0);
69 glPixelTransferf(GL_GREEN_SCALE, -1.0);
70 glPixelTransferf(GL_GREEN_BIAS, 1.0);
71 glPixelTransferf(GL_BLUE_SCALE, -1.0);
72 glPixelTransferf(GL_BLUE_BIAS, 1.0);
73 }
74 else {
75 glPixelTransferf(GL_RED_SCALE, 1.0);
76 glPixelTransferf(GL_RED_BIAS, 0.0);
77 glPixelTransferf(GL_GREEN_SCALE, 1.0);
78 glPixelTransferf(GL_GREEN_BIAS, 0.0);
79 glPixelTransferf(GL_BLUE_SCALE, 1.0);
80 glPixelTransferf(GL_BLUE_BIAS, 0.0);
81 }
82}
83
84
85static void
86Display( void )
87{
88 glClear( GL_COLOR_BUFFER_BIT );
89
90 glRasterPos2i(5, ImgHeight+25);
Brian Paul4f6d60e2000-03-23 19:47:25 +000091 PrintString("f = toggle front/back s = toggle scale/bias b = benchmark");
Brian Pauleca1bc92000-03-01 16:23:14 +000092
93 /* draw original image */
94 glRasterPos2i(APosX, 5);
95 PrintString("Original");
96 glRasterPos2i(APosX, APosY);
97 glEnable(GL_DITHER);
98 SetupPixelTransfer(GL_FALSE);
99 glDrawPixels(ImgWidth, ImgHeight, ImgFormat, GL_UNSIGNED_BYTE, Image);
100
101 /* do readpixels, drawpixels */
102 glRasterPos2i(BPosX, 5);
103 PrintString("Read/DrawPixels");
104 SetupPixelTransfer(ScaleAndBias);
Brian Paul4f6d60e2000-03-23 19:47:25 +0000105 if (Benchmark) {
106 GLint reads = 0;
107 GLint endTime;
108 GLint startTime = glutGet(GLUT_ELAPSED_TIME);
109 GLdouble seconds, pixelsPerSecond;
110 printf("Benchmarking...\n");
111 do {
112 glReadPixels(APosX, APosY, ImgWidth, ImgHeight,
113 ImgFormat, GL_UNSIGNED_BYTE, TempImage);
114 reads++;
115 endTime = glutGet(GLUT_ELAPSED_TIME);
116 } while (endTime - startTime < 4000); /* 4 seconds */
117 seconds = (double) (endTime - startTime) / 1000.0;
118 pixelsPerSecond = reads * ImgWidth * ImgHeight / seconds;
119 printf("Result: %d reads in %f seconds = %f pixels/sec\n",
120 reads, seconds, pixelsPerSecond);
121 Benchmark = GL_FALSE;
122 }
123 else {
124 glReadPixels(APosX, APosY, ImgWidth, ImgHeight,
125 ImgFormat, GL_UNSIGNED_BYTE, TempImage);
126 }
Brian Pauleca1bc92000-03-01 16:23:14 +0000127 glRasterPos2i(BPosX, BPosY);
128 glDisable(GL_DITHER);
129 SetupPixelTransfer(GL_FALSE);
130 glDrawPixels(ImgWidth, ImgHeight, ImgFormat, GL_UNSIGNED_BYTE, TempImage);
131
132 /* do copypixels */
133 glRasterPos2i(CPosX, 5);
134 PrintString("CopyPixels");
135 glRasterPos2i(CPosX, CPosY);
136 glDisable(GL_DITHER);
137 SetupPixelTransfer(ScaleAndBias);
138 glCopyPixels(APosX, APosY, ImgWidth, ImgHeight, GL_COLOR);
139
140 if (!DrawFront)
141 glutSwapBuffers();
142}
143
144
Brian Paul4f6d60e2000-03-23 19:47:25 +0000145static void
146Reshape( int width, int height )
Brian Pauleca1bc92000-03-01 16:23:14 +0000147{
148 glViewport( 0, 0, width, height );
149 glMatrixMode( GL_PROJECTION );
150 glLoadIdentity();
151 glOrtho( 0.0, width, 0.0, height, -1.0, 1.0 );
152 glMatrixMode( GL_MODELVIEW );
153 glLoadIdentity();
154}
155
156
Brian Paul4f6d60e2000-03-23 19:47:25 +0000157static void
158Key( unsigned char key, int x, int y )
Brian Pauleca1bc92000-03-01 16:23:14 +0000159{
160 (void) x;
161 (void) y;
162 switch (key) {
163 case 'b':
Brian Paul4f6d60e2000-03-23 19:47:25 +0000164 Benchmark = GL_TRUE;
165 break;
166 case 's':
Brian Pauleca1bc92000-03-01 16:23:14 +0000167 ScaleAndBias = !ScaleAndBias;
168 break;
169 case 'f':
170 DrawFront = !DrawFront;
Brian Paul4f6d60e2000-03-23 19:47:25 +0000171 if (DrawFront) {
Brian Pauleca1bc92000-03-01 16:23:14 +0000172 glDrawBuffer(GL_FRONT);
Brian Paul4f6d60e2000-03-23 19:47:25 +0000173 glReadBuffer(GL_FRONT);
174 }
175 else {
Brian Pauleca1bc92000-03-01 16:23:14 +0000176 glDrawBuffer(GL_BACK);
Brian Paul4f6d60e2000-03-23 19:47:25 +0000177 glReadBuffer(GL_BACK);
178 }
Brian Pauleca1bc92000-03-01 16:23:14 +0000179 printf("glDrawBuffer(%s)\n", DrawFront ? "GL_FRONT" : "GL_BACK");
180 break;
181 case 27:
182 exit(0);
183 break;
184 }
185 glutPostRedisplay();
186}
187
188
Brian Pauleca1bc92000-03-01 16:23:14 +0000189static void
190Init( GLboolean ciMode )
191{
192 printf("GL_VERSION = %s\n", (char *) glGetString(GL_VERSION));
193 printf("GL_RENDERER = %s\n", (char *) glGetString(GL_RENDERER));
194
195 Image = LoadRGBImage( IMAGE_FILE, &ImgWidth, &ImgHeight, &ImgFormat );
196 if (!Image) {
197 printf("Couldn't read %s\n", IMAGE_FILE);
198 exit(0);
199 }
200
201 if (ciMode) {
202 /* Convert RGB image to grayscale */
203 GLubyte *indexImage = malloc( ImgWidth * ImgHeight );
204 GLint i;
205 for (i=0; i<ImgWidth*ImgHeight; i++) {
206 int gray = Image[i*3] + Image[i*3+1] + Image[i*3+2];
207 indexImage[i] = gray / 3;
208 }
209 free(Image);
210 Image = indexImage;
211 ImgFormat = GL_COLOR_INDEX;
212
213 for (i=0;i<255;i++) {
214 float g = i / 255.0;
215 glutSetColor(i, g, g, g);
216 }
217 }
218
219 printf("Loaded %d by %d image\n", ImgWidth, ImgHeight );
220
221 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
222 glPixelStorei(GL_UNPACK_ROW_LENGTH, ImgWidth);
223 glPixelStorei(GL_PACK_ALIGNMENT, 1);
224 glPixelStorei(GL_PACK_ROW_LENGTH, ImgWidth);
225
226 Reset();
227
228 TempImage = (GLubyte *) malloc(ImgWidth * ImgHeight * 4 * sizeof(GLubyte));
229 assert(TempImage);
230}
231
232
Brian Paul4f6d60e2000-03-23 19:47:25 +0000233int
234main( int argc, char *argv[] )
Brian Pauleca1bc92000-03-01 16:23:14 +0000235{
236 GLboolean ciMode = GL_FALSE;
Brian Pauleca1bc92000-03-01 16:23:14 +0000237 if (argc > 1 && strcmp(argv[1], "-ci")==0) {
238 ciMode = GL_TRUE;
239 }
Brian Pauleca1bc92000-03-01 16:23:14 +0000240 glutInit( &argc, argv );
241 glutInitWindowPosition( 0, 0 );
242 glutInitWindowSize( 750, 250 );
Brian Pauleca1bc92000-03-01 16:23:14 +0000243 if (ciMode)
244 glutInitDisplayMode( GLUT_INDEX | GLUT_DOUBLE );
245 else
246 glutInitDisplayMode( GLUT_RGB | GLUT_DOUBLE );
Brian Pauleca1bc92000-03-01 16:23:14 +0000247 glutCreateWindow(argv[0]);
Brian Pauleca1bc92000-03-01 16:23:14 +0000248 Init(ciMode);
Brian Pauleca1bc92000-03-01 16:23:14 +0000249 glutReshapeFunc( Reshape );
250 glutKeyboardFunc( Key );
Brian Pauleca1bc92000-03-01 16:23:14 +0000251 glutDisplayFunc( Display );
Brian Pauleca1bc92000-03-01 16:23:14 +0000252 glutMainLoop();
253 return 0;
254}