blob: fc322f2e81124a09bef870fd09f489aa2c26c6f7 [file] [log] [blame]
Brian Pauleca1bc92000-03-01 16:23:14 +00001
2/*
3 * glReadPixels and glCopyPixels test
4 *
5 * Brian Paul March 1, 2000 This file is in the public domain.
6 */
7
Brian Pauleca1bc92000-03-01 16:23:14 +00008#include <assert.h>
9#include <stdio.h>
10#include <stdlib.h>
11#include <math.h>
12#include <GL/glut.h>
13
14#include "../util/readtex.c" /* a hack, I know */
15
16#define IMAGE_FILE "../images/girl.rgb"
17
18static int ImgWidth, ImgHeight;
19static GLenum ImgFormat;
20static GLubyte *Image = NULL;
21
22static int APosX, APosY; /* simple drawpixels */
23static int BPosX, BPosY; /* read/draw pixels */
24static int CPosX, CPosY; /* copypixels */
25
26static GLboolean DrawFront = GL_FALSE;
27static GLboolean ScaleAndBias = GL_FALSE;
Brian Paul4f6d60e2000-03-23 19:47:25 +000028static GLboolean Benchmark = GL_FALSE;
Brian Pauleca1bc92000-03-01 16:23:14 +000029static GLubyte *TempImage = NULL;
30
Brian Paul1100b4d2000-10-16 21:24:39 +000031#if 0
Brian Pauld3d72802000-03-31 01:01:31 +000032#define ReadFormat ImgFormat
33#define ReadType GL_UNSIGNED_BYTE
34#endif
Brian Paul1100b4d2000-10-16 21:24:39 +000035#if 1
Alan Hourihanea5cdf992002-05-02 09:17:59 +000036static GLenum ReadFormat = GL_RGBA;
Brian Pauld3d72802000-03-31 01:01:31 +000037static GLenum ReadType = GL_UNSIGNED_BYTE;
38#endif
39#if 0
40static GLenum ReadFormat = GL_RGB;
41static GLenum ReadType = GL_UNSIGNED_SHORT_5_6_5;
42#endif
Brian Paul1100b4d2000-10-16 21:24:39 +000043#if 0
44static GLenum ReadFormat = GL_RGBA;
45static GLenum ReadType = GL_UNSIGNED_SHORT_1_5_5_5_REV;
46#endif
47#if 0
48static GLenum ReadFormat = GL_BGRA;
49static GLenum ReadType = GL_UNSIGNED_SHORT_5_5_5_1;
50#endif
51#if 0
52static GLenum ReadFormat = GL_BGRA;
53static GLenum ReadType = GL_UNSIGNED_SHORT_4_4_4_4_REV;
54#endif
Brian Pauld3d72802000-03-31 01:01:31 +000055
Brian Pauleca1bc92000-03-01 16:23:14 +000056
57static void
58Reset( void )
59{
60 APosX = 5; APosY = 20;
61 BPosX = APosX + ImgWidth + 5; BPosY = 20;
62 CPosX = BPosX + ImgWidth + 5; CPosY = 20;
63}
64
65
66static void
67PrintString(const char *s)
68{
69 while (*s) {
70 glutBitmapCharacter(GLUT_BITMAP_8_BY_13, (int) *s);
71 s++;
72 }
73}
74
75
76static void
77SetupPixelTransfer(GLboolean invert)
78{
79 if (invert) {
80 glPixelTransferf(GL_RED_SCALE, -1.0);
81 glPixelTransferf(GL_RED_BIAS, 1.0);
82 glPixelTransferf(GL_GREEN_SCALE, -1.0);
83 glPixelTransferf(GL_GREEN_BIAS, 1.0);
84 glPixelTransferf(GL_BLUE_SCALE, -1.0);
85 glPixelTransferf(GL_BLUE_BIAS, 1.0);
86 }
87 else {
88 glPixelTransferf(GL_RED_SCALE, 1.0);
89 glPixelTransferf(GL_RED_BIAS, 0.0);
90 glPixelTransferf(GL_GREEN_SCALE, 1.0);
91 glPixelTransferf(GL_GREEN_BIAS, 0.0);
92 glPixelTransferf(GL_BLUE_SCALE, 1.0);
93 glPixelTransferf(GL_BLUE_BIAS, 0.0);
94 }
95}
96
97
98static void
99Display( void )
100{
Brian Paul1100b4d2000-10-16 21:24:39 +0000101 glClearColor(.3, .3, .3, 1);
Brian Pauleca1bc92000-03-01 16:23:14 +0000102 glClear( GL_COLOR_BUFFER_BIT );
103
104 glRasterPos2i(5, ImgHeight+25);
Brian Paul4f6d60e2000-03-23 19:47:25 +0000105 PrintString("f = toggle front/back s = toggle scale/bias b = benchmark");
Brian Pauleca1bc92000-03-01 16:23:14 +0000106
107 /* draw original image */
108 glRasterPos2i(APosX, 5);
109 PrintString("Original");
110 glRasterPos2i(APosX, APosY);
111 glEnable(GL_DITHER);
112 SetupPixelTransfer(GL_FALSE);
113 glDrawPixels(ImgWidth, ImgHeight, ImgFormat, GL_UNSIGNED_BYTE, Image);
114
115 /* do readpixels, drawpixels */
116 glRasterPos2i(BPosX, 5);
117 PrintString("Read/DrawPixels");
118 SetupPixelTransfer(ScaleAndBias);
Brian Paul4f6d60e2000-03-23 19:47:25 +0000119 if (Benchmark) {
120 GLint reads = 0;
121 GLint endTime;
122 GLint startTime = glutGet(GLUT_ELAPSED_TIME);
123 GLdouble seconds, pixelsPerSecond;
124 printf("Benchmarking...\n");
125 do {
126 glReadPixels(APosX, APosY, ImgWidth, ImgHeight,
Brian Pauld3d72802000-03-31 01:01:31 +0000127 ReadFormat, ReadType, TempImage);
Brian Paul4f6d60e2000-03-23 19:47:25 +0000128 reads++;
129 endTime = glutGet(GLUT_ELAPSED_TIME);
130 } while (endTime - startTime < 4000); /* 4 seconds */
131 seconds = (double) (endTime - startTime) / 1000.0;
132 pixelsPerSecond = reads * ImgWidth * ImgHeight / seconds;
133 printf("Result: %d reads in %f seconds = %f pixels/sec\n",
134 reads, seconds, pixelsPerSecond);
135 Benchmark = GL_FALSE;
136 }
137 else {
Brian Paul1100b4d2000-10-16 21:24:39 +0000138 /* clear the temporary image to white (helpful for debugging */
139 memset(TempImage, 255, ImgWidth * ImgHeight * 4);
Brian Paul4f6d60e2000-03-23 19:47:25 +0000140 glReadPixels(APosX, APosY, ImgWidth, ImgHeight,
Brian Pauld3d72802000-03-31 01:01:31 +0000141 ReadFormat, ReadType, TempImage);
Brian Paul4f6d60e2000-03-23 19:47:25 +0000142 }
Brian Pauleca1bc92000-03-01 16:23:14 +0000143 glRasterPos2i(BPosX, BPosY);
144 glDisable(GL_DITHER);
145 SetupPixelTransfer(GL_FALSE);
Brian Pauld3d72802000-03-31 01:01:31 +0000146 glDrawPixels(ImgWidth, ImgHeight, ReadFormat, ReadType, TempImage);
Brian Pauleca1bc92000-03-01 16:23:14 +0000147
148 /* do copypixels */
149 glRasterPos2i(CPosX, 5);
150 PrintString("CopyPixels");
151 glRasterPos2i(CPosX, CPosY);
152 glDisable(GL_DITHER);
153 SetupPixelTransfer(ScaleAndBias);
Alan Hourihanea5cdf992002-05-02 09:17:59 +0000154 glCopyPixels(APosX, APosY, ImgWidth, ImgHeight, GL_COLOR);
Brian Pauleca1bc92000-03-01 16:23:14 +0000155
156 if (!DrawFront)
157 glutSwapBuffers();
Alan Hourihane056b3582002-05-02 09:15:22 +0000158 else
159 glFinish();
Brian Pauleca1bc92000-03-01 16:23:14 +0000160}
161
162
Brian Paul4f6d60e2000-03-23 19:47:25 +0000163static void
164Reshape( int width, int height )
Brian Pauleca1bc92000-03-01 16:23:14 +0000165{
166 glViewport( 0, 0, width, height );
167 glMatrixMode( GL_PROJECTION );
168 glLoadIdentity();
169 glOrtho( 0.0, width, 0.0, height, -1.0, 1.0 );
170 glMatrixMode( GL_MODELVIEW );
171 glLoadIdentity();
172}
173
174
Brian Paul4f6d60e2000-03-23 19:47:25 +0000175static void
176Key( unsigned char key, int x, int y )
Brian Pauleca1bc92000-03-01 16:23:14 +0000177{
178 (void) x;
179 (void) y;
180 switch (key) {
181 case 'b':
Brian Paul4f6d60e2000-03-23 19:47:25 +0000182 Benchmark = GL_TRUE;
183 break;
184 case 's':
Brian Pauleca1bc92000-03-01 16:23:14 +0000185 ScaleAndBias = !ScaleAndBias;
186 break;
187 case 'f':
188 DrawFront = !DrawFront;
Brian Paul4f6d60e2000-03-23 19:47:25 +0000189 if (DrawFront) {
Alan Hourihanea5cdf992002-05-02 09:17:59 +0000190 glDrawBuffer(GL_FRONT);
191 glReadBuffer(GL_FRONT);
Brian Paul4f6d60e2000-03-23 19:47:25 +0000192 }
193 else {
Alan Hourihanea5cdf992002-05-02 09:17:59 +0000194 glDrawBuffer(GL_BACK);
195 glReadBuffer(GL_BACK);
Brian Paul4f6d60e2000-03-23 19:47:25 +0000196 }
Brian Pauleca1bc92000-03-01 16:23:14 +0000197 printf("glDrawBuffer(%s)\n", DrawFront ? "GL_FRONT" : "GL_BACK");
198 break;
199 case 27:
200 exit(0);
201 break;
202 }
203 glutPostRedisplay();
204}
205
206
Brian Pauleca1bc92000-03-01 16:23:14 +0000207static void
208Init( GLboolean ciMode )
209{
Ian Romanick33899b72004-10-16 01:16:54 +0000210 GLboolean have_read_format = GL_FALSE;
211
Brian Pauleca1bc92000-03-01 16:23:14 +0000212 printf("GL_VERSION = %s\n", (char *) glGetString(GL_VERSION));
213 printf("GL_RENDERER = %s\n", (char *) glGetString(GL_RENDERER));
214
215 Image = LoadRGBImage( IMAGE_FILE, &ImgWidth, &ImgHeight, &ImgFormat );
216 if (!Image) {
217 printf("Couldn't read %s\n", IMAGE_FILE);
218 exit(0);
219 }
220
221 if (ciMode) {
222 /* Convert RGB image to grayscale */
Brian Paulf02a5f62002-07-12 15:54:01 +0000223 GLubyte *indexImage = (GLubyte *) malloc( ImgWidth * ImgHeight );
Brian Pauleca1bc92000-03-01 16:23:14 +0000224 GLint i;
225 for (i=0; i<ImgWidth*ImgHeight; i++) {
226 int gray = Image[i*3] + Image[i*3+1] + Image[i*3+2];
227 indexImage[i] = gray / 3;
228 }
229 free(Image);
230 Image = indexImage;
231 ImgFormat = GL_COLOR_INDEX;
232
233 for (i=0;i<255;i++) {
234 float g = i / 255.0;
235 glutSetColor(i, g, g, g);
236 }
237 }
238
Ian Romanick33899b72004-10-16 01:16:54 +0000239#ifdef GL_OES_read_format
240 if ( glutExtensionSupported( "GL_OES_read_format" ) ) {
241 glGetIntegerv( GL_IMPLEMENTATION_COLOR_READ_TYPE_OES, & ReadType );
242 glGetIntegerv( GL_IMPLEMENTATION_COLOR_READ_FORMAT_OES, & ReadFormat );
243
244 have_read_format = GL_TRUE;
245 }
246#endif
247
248 printf( "GL_OES_read_format %ssupported. "
249 "Using type / format = 0x%04x / 0x%04x\n",
250 (have_read_format) ? "" : "not ",
251 ReadType, ReadFormat );
252
Brian Pauleca1bc92000-03-01 16:23:14 +0000253 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}