blob: 784e4c88d7b81c39112217cac8d35c602810d526 [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{
210 printf("GL_VERSION = %s\n", (char *) glGetString(GL_VERSION));
211 printf("GL_RENDERER = %s\n", (char *) glGetString(GL_RENDERER));
212
213 Image = LoadRGBImage( IMAGE_FILE, &ImgWidth, &ImgHeight, &ImgFormat );
214 if (!Image) {
215 printf("Couldn't read %s\n", IMAGE_FILE);
216 exit(0);
217 }
218
219 if (ciMode) {
220 /* Convert RGB image to grayscale */
Brian Paulf02a5f62002-07-12 15:54:01 +0000221 GLubyte *indexImage = (GLubyte *) malloc( ImgWidth * ImgHeight );
Brian Pauleca1bc92000-03-01 16:23:14 +0000222 GLint i;
223 for (i=0; i<ImgWidth*ImgHeight; i++) {
224 int gray = Image[i*3] + Image[i*3+1] + Image[i*3+2];
225 indexImage[i] = gray / 3;
226 }
227 free(Image);
228 Image = indexImage;
229 ImgFormat = GL_COLOR_INDEX;
230
231 for (i=0;i<255;i++) {
232 float g = i / 255.0;
233 glutSetColor(i, g, g, g);
234 }
235 }
236
237 printf("Loaded %d by %d image\n", ImgWidth, ImgHeight );
238
239 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
240 glPixelStorei(GL_UNPACK_ROW_LENGTH, ImgWidth);
241 glPixelStorei(GL_PACK_ALIGNMENT, 1);
242 glPixelStorei(GL_PACK_ROW_LENGTH, ImgWidth);
243
244 Reset();
245
246 TempImage = (GLubyte *) malloc(ImgWidth * ImgHeight * 4 * sizeof(GLubyte));
247 assert(TempImage);
248}
249
250
Brian Paul4f6d60e2000-03-23 19:47:25 +0000251int
252main( int argc, char *argv[] )
Brian Pauleca1bc92000-03-01 16:23:14 +0000253{
254 GLboolean ciMode = GL_FALSE;
Brian Pauleca1bc92000-03-01 16:23:14 +0000255 if (argc > 1 && strcmp(argv[1], "-ci")==0) {
256 ciMode = GL_TRUE;
257 }
Brian Pauleca1bc92000-03-01 16:23:14 +0000258 glutInit( &argc, argv );
259 glutInitWindowPosition( 0, 0 );
260 glutInitWindowSize( 750, 250 );
Brian Pauleca1bc92000-03-01 16:23:14 +0000261 if (ciMode)
262 glutInitDisplayMode( GLUT_INDEX | GLUT_DOUBLE );
263 else
264 glutInitDisplayMode( GLUT_RGB | GLUT_DOUBLE );
Brian Pauleca1bc92000-03-01 16:23:14 +0000265 glutCreateWindow(argv[0]);
Brian Pauleca1bc92000-03-01 16:23:14 +0000266 Init(ciMode);
Brian Pauleca1bc92000-03-01 16:23:14 +0000267 glutReshapeFunc( Reshape );
268 glutKeyboardFunc( Key );
Brian Pauleca1bc92000-03-01 16:23:14 +0000269 glutDisplayFunc( Display );
Brian Pauleca1bc92000-03-01 16:23:14 +0000270 glutMainLoop();
271 return 0;
272}