blob: 238ef2ee1facbe985bf8c005cad8d20a61b37e65 [file] [log] [blame]
Brian Paul1100b4d2000-10-16 21:24:39 +00001/* $Id: readpix.c,v 1.4 2000/10/16 21:24:39 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 Paul1100b4d2000-10-16 21:24:39 +000011 * Revision 1.4 2000/10/16 21:24:39 brianp
12 * use gray background, memset TempImage to white to help with debugging
13 *
Brian Pauld3d72802000-03-31 01:01:31 +000014 * Revision 1.3 2000/03/31 01:01:31 brianp
15 * tweaks to allow different read formats/types
16 *
Brian Paul4f6d60e2000-03-23 19:47:25 +000017 * Revision 1.2 2000/03/23 19:47:25 brianp
18 * added benchmarking
19 *
Brian Pauleca1bc92000-03-01 16:23:14 +000020 * Revision 1.1 2000/03/01 16:23:14 brianp
21 * test glDraw/Read/CopyPixels()
22 *
23 */
24
25
26#include <assert.h>
27#include <stdio.h>
28#include <stdlib.h>
29#include <math.h>
30#include <GL/glut.h>
31
32#include "../util/readtex.c" /* a hack, I know */
33
34#define IMAGE_FILE "../images/girl.rgb"
35
36static int ImgWidth, ImgHeight;
37static GLenum ImgFormat;
38static GLubyte *Image = NULL;
39
40static int APosX, APosY; /* simple drawpixels */
41static int BPosX, BPosY; /* read/draw pixels */
42static int CPosX, CPosY; /* copypixels */
43
44static GLboolean DrawFront = GL_FALSE;
45static GLboolean ScaleAndBias = GL_FALSE;
Brian Paul4f6d60e2000-03-23 19:47:25 +000046static GLboolean Benchmark = GL_FALSE;
Brian Pauleca1bc92000-03-01 16:23:14 +000047static GLubyte *TempImage = NULL;
48
Brian Paul1100b4d2000-10-16 21:24:39 +000049#if 0
Brian Pauld3d72802000-03-31 01:01:31 +000050#define ReadFormat ImgFormat
51#define ReadType GL_UNSIGNED_BYTE
52#endif
Brian Paul1100b4d2000-10-16 21:24:39 +000053#if 1
Brian Pauld3d72802000-03-31 01:01:31 +000054static GLenum ReadFormat = GL_RGBA;
55static GLenum ReadType = GL_UNSIGNED_BYTE;
56#endif
57#if 0
58static GLenum ReadFormat = GL_RGB;
59static GLenum ReadType = GL_UNSIGNED_SHORT_5_6_5;
60#endif
Brian Paul1100b4d2000-10-16 21:24:39 +000061#if 0
62static GLenum ReadFormat = GL_RGBA;
63static GLenum ReadType = GL_UNSIGNED_SHORT_1_5_5_5_REV;
64#endif
65#if 0
66static GLenum ReadFormat = GL_BGRA;
67static GLenum ReadType = GL_UNSIGNED_SHORT_5_5_5_1;
68#endif
69#if 0
70static GLenum ReadFormat = GL_BGRA;
71static GLenum ReadType = GL_UNSIGNED_SHORT_4_4_4_4_REV;
72#endif
Brian Pauld3d72802000-03-31 01:01:31 +000073
Brian Pauleca1bc92000-03-01 16:23:14 +000074
75static void
76Reset( void )
77{
78 APosX = 5; APosY = 20;
79 BPosX = APosX + ImgWidth + 5; BPosY = 20;
80 CPosX = BPosX + ImgWidth + 5; CPosY = 20;
81}
82
83
84static void
85PrintString(const char *s)
86{
87 while (*s) {
88 glutBitmapCharacter(GLUT_BITMAP_8_BY_13, (int) *s);
89 s++;
90 }
91}
92
93
94static void
95SetupPixelTransfer(GLboolean invert)
96{
97 if (invert) {
98 glPixelTransferf(GL_RED_SCALE, -1.0);
99 glPixelTransferf(GL_RED_BIAS, 1.0);
100 glPixelTransferf(GL_GREEN_SCALE, -1.0);
101 glPixelTransferf(GL_GREEN_BIAS, 1.0);
102 glPixelTransferf(GL_BLUE_SCALE, -1.0);
103 glPixelTransferf(GL_BLUE_BIAS, 1.0);
104 }
105 else {
106 glPixelTransferf(GL_RED_SCALE, 1.0);
107 glPixelTransferf(GL_RED_BIAS, 0.0);
108 glPixelTransferf(GL_GREEN_SCALE, 1.0);
109 glPixelTransferf(GL_GREEN_BIAS, 0.0);
110 glPixelTransferf(GL_BLUE_SCALE, 1.0);
111 glPixelTransferf(GL_BLUE_BIAS, 0.0);
112 }
113}
114
115
116static void
117Display( void )
118{
Brian Paul1100b4d2000-10-16 21:24:39 +0000119 glClearColor(.3, .3, .3, 1);
Brian Pauleca1bc92000-03-01 16:23:14 +0000120 glClear( GL_COLOR_BUFFER_BIT );
121
122 glRasterPos2i(5, ImgHeight+25);
Brian Paul4f6d60e2000-03-23 19:47:25 +0000123 PrintString("f = toggle front/back s = toggle scale/bias b = benchmark");
Brian Pauleca1bc92000-03-01 16:23:14 +0000124
125 /* draw original image */
126 glRasterPos2i(APosX, 5);
127 PrintString("Original");
128 glRasterPos2i(APosX, APosY);
129 glEnable(GL_DITHER);
130 SetupPixelTransfer(GL_FALSE);
131 glDrawPixels(ImgWidth, ImgHeight, ImgFormat, GL_UNSIGNED_BYTE, Image);
132
133 /* do readpixels, drawpixels */
134 glRasterPos2i(BPosX, 5);
135 PrintString("Read/DrawPixels");
136 SetupPixelTransfer(ScaleAndBias);
Brian Paul4f6d60e2000-03-23 19:47:25 +0000137 if (Benchmark) {
138 GLint reads = 0;
139 GLint endTime;
140 GLint startTime = glutGet(GLUT_ELAPSED_TIME);
141 GLdouble seconds, pixelsPerSecond;
142 printf("Benchmarking...\n");
143 do {
144 glReadPixels(APosX, APosY, ImgWidth, ImgHeight,
Brian Pauld3d72802000-03-31 01:01:31 +0000145 ReadFormat, ReadType, TempImage);
Brian Paul4f6d60e2000-03-23 19:47:25 +0000146 reads++;
147 endTime = glutGet(GLUT_ELAPSED_TIME);
148 } while (endTime - startTime < 4000); /* 4 seconds */
149 seconds = (double) (endTime - startTime) / 1000.0;
150 pixelsPerSecond = reads * ImgWidth * ImgHeight / seconds;
151 printf("Result: %d reads in %f seconds = %f pixels/sec\n",
152 reads, seconds, pixelsPerSecond);
153 Benchmark = GL_FALSE;
154 }
155 else {
Brian Paul1100b4d2000-10-16 21:24:39 +0000156 /* clear the temporary image to white (helpful for debugging */
157 memset(TempImage, 255, ImgWidth * ImgHeight * 4);
Brian Paul4f6d60e2000-03-23 19:47:25 +0000158 glReadPixels(APosX, APosY, ImgWidth, ImgHeight,
Brian Pauld3d72802000-03-31 01:01:31 +0000159 ReadFormat, ReadType, TempImage);
Brian Paul4f6d60e2000-03-23 19:47:25 +0000160 }
Brian Pauleca1bc92000-03-01 16:23:14 +0000161 glRasterPos2i(BPosX, BPosY);
162 glDisable(GL_DITHER);
163 SetupPixelTransfer(GL_FALSE);
Brian Pauld3d72802000-03-31 01:01:31 +0000164 glDrawPixels(ImgWidth, ImgHeight, ReadFormat, ReadType, TempImage);
Brian Pauleca1bc92000-03-01 16:23:14 +0000165
166 /* do copypixels */
167 glRasterPos2i(CPosX, 5);
168 PrintString("CopyPixels");
169 glRasterPos2i(CPosX, CPosY);
170 glDisable(GL_DITHER);
171 SetupPixelTransfer(ScaleAndBias);
172 glCopyPixels(APosX, APosY, ImgWidth, ImgHeight, GL_COLOR);
173
174 if (!DrawFront)
175 glutSwapBuffers();
176}
177
178
Brian Paul4f6d60e2000-03-23 19:47:25 +0000179static void
180Reshape( int width, int height )
Brian Pauleca1bc92000-03-01 16:23:14 +0000181{
182 glViewport( 0, 0, width, height );
183 glMatrixMode( GL_PROJECTION );
184 glLoadIdentity();
185 glOrtho( 0.0, width, 0.0, height, -1.0, 1.0 );
186 glMatrixMode( GL_MODELVIEW );
187 glLoadIdentity();
188}
189
190
Brian Paul4f6d60e2000-03-23 19:47:25 +0000191static void
192Key( unsigned char key, int x, int y )
Brian Pauleca1bc92000-03-01 16:23:14 +0000193{
194 (void) x;
195 (void) y;
196 switch (key) {
197 case 'b':
Brian Paul4f6d60e2000-03-23 19:47:25 +0000198 Benchmark = GL_TRUE;
199 break;
200 case 's':
Brian Pauleca1bc92000-03-01 16:23:14 +0000201 ScaleAndBias = !ScaleAndBias;
202 break;
203 case 'f':
204 DrawFront = !DrawFront;
Brian Paul4f6d60e2000-03-23 19:47:25 +0000205 if (DrawFront) {
Brian Pauleca1bc92000-03-01 16:23:14 +0000206 glDrawBuffer(GL_FRONT);
Brian Paul4f6d60e2000-03-23 19:47:25 +0000207 glReadBuffer(GL_FRONT);
208 }
209 else {
Brian Pauleca1bc92000-03-01 16:23:14 +0000210 glDrawBuffer(GL_BACK);
Brian Paul4f6d60e2000-03-23 19:47:25 +0000211 glReadBuffer(GL_BACK);
212 }
Brian Pauleca1bc92000-03-01 16:23:14 +0000213 printf("glDrawBuffer(%s)\n", DrawFront ? "GL_FRONT" : "GL_BACK");
214 break;
215 case 27:
216 exit(0);
217 break;
218 }
219 glutPostRedisplay();
220}
221
222
Brian Pauleca1bc92000-03-01 16:23:14 +0000223static void
224Init( GLboolean ciMode )
225{
226 printf("GL_VERSION = %s\n", (char *) glGetString(GL_VERSION));
227 printf("GL_RENDERER = %s\n", (char *) glGetString(GL_RENDERER));
228
229 Image = LoadRGBImage( IMAGE_FILE, &ImgWidth, &ImgHeight, &ImgFormat );
230 if (!Image) {
231 printf("Couldn't read %s\n", IMAGE_FILE);
232 exit(0);
233 }
234
235 if (ciMode) {
236 /* Convert RGB image to grayscale */
237 GLubyte *indexImage = malloc( ImgWidth * ImgHeight );
238 GLint i;
239 for (i=0; i<ImgWidth*ImgHeight; i++) {
240 int gray = Image[i*3] + Image[i*3+1] + Image[i*3+2];
241 indexImage[i] = gray / 3;
242 }
243 free(Image);
244 Image = indexImage;
245 ImgFormat = GL_COLOR_INDEX;
246
247 for (i=0;i<255;i++) {
248 float g = i / 255.0;
249 glutSetColor(i, g, g, g);
250 }
251 }
252
253 printf("Loaded %d by %d image\n", ImgWidth, ImgHeight );
254
255 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
256 glPixelStorei(GL_UNPACK_ROW_LENGTH, ImgWidth);
257 glPixelStorei(GL_PACK_ALIGNMENT, 1);
258 glPixelStorei(GL_PACK_ROW_LENGTH, ImgWidth);
259
260 Reset();
261
262 TempImage = (GLubyte *) malloc(ImgWidth * ImgHeight * 4 * sizeof(GLubyte));
263 assert(TempImage);
264}
265
266
Brian Paul4f6d60e2000-03-23 19:47:25 +0000267int
268main( int argc, char *argv[] )
Brian Pauleca1bc92000-03-01 16:23:14 +0000269{
270 GLboolean ciMode = GL_FALSE;
Brian Pauleca1bc92000-03-01 16:23:14 +0000271 if (argc > 1 && strcmp(argv[1], "-ci")==0) {
272 ciMode = GL_TRUE;
273 }
Brian Pauleca1bc92000-03-01 16:23:14 +0000274 glutInit( &argc, argv );
275 glutInitWindowPosition( 0, 0 );
276 glutInitWindowSize( 750, 250 );
Brian Pauleca1bc92000-03-01 16:23:14 +0000277 if (ciMode)
278 glutInitDisplayMode( GLUT_INDEX | GLUT_DOUBLE );
279 else
280 glutInitDisplayMode( GLUT_RGB | GLUT_DOUBLE );
Brian Pauleca1bc92000-03-01 16:23:14 +0000281 glutCreateWindow(argv[0]);
Brian Pauleca1bc92000-03-01 16:23:14 +0000282 Init(ciMode);
Brian Pauleca1bc92000-03-01 16:23:14 +0000283 glutReshapeFunc( Reshape );
284 glutKeyboardFunc( Key );
Brian Pauleca1bc92000-03-01 16:23:14 +0000285 glutDisplayFunc( Display );
Brian Pauleca1bc92000-03-01 16:23:14 +0000286 glutMainLoop();
287 return 0;
288}