blob: 32225b7961c2b21ee4be8a1ef0562e7574ee2325 [file] [log] [blame]
Brian Pauld3d72802000-03-31 01:01:31 +00001/* $Id: readpix.c,v 1.3 2000/03/31 01:01:31 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 Pauld3d72802000-03-31 01:01:31 +000011 * Revision 1.3 2000/03/31 01:01:31 brianp
12 * tweaks to allow different read formats/types
13 *
Brian Paul4f6d60e2000-03-23 19:47:25 +000014 * Revision 1.2 2000/03/23 19:47:25 brianp
15 * added benchmarking
16 *
Brian Pauleca1bc92000-03-01 16:23:14 +000017 * Revision 1.1 2000/03/01 16:23:14 brianp
18 * test glDraw/Read/CopyPixels()
19 *
20 */
21
22
23#include <assert.h>
24#include <stdio.h>
25#include <stdlib.h>
26#include <math.h>
27#include <GL/glut.h>
28
29#include "../util/readtex.c" /* a hack, I know */
30
31#define IMAGE_FILE "../images/girl.rgb"
32
33static int ImgWidth, ImgHeight;
34static GLenum ImgFormat;
35static GLubyte *Image = NULL;
36
37static int APosX, APosY; /* simple drawpixels */
38static int BPosX, BPosY; /* read/draw pixels */
39static int CPosX, CPosY; /* copypixels */
40
41static GLboolean DrawFront = GL_FALSE;
42static GLboolean ScaleAndBias = GL_FALSE;
Brian Paul4f6d60e2000-03-23 19:47:25 +000043static GLboolean Benchmark = GL_FALSE;
Brian Pauleca1bc92000-03-01 16:23:14 +000044static GLubyte *TempImage = NULL;
45
Brian Pauld3d72802000-03-31 01:01:31 +000046#if 1
47#define ReadFormat ImgFormat
48#define ReadType GL_UNSIGNED_BYTE
49#endif
50#if 0
51static GLenum ReadFormat = GL_RGBA;
52static GLenum ReadType = GL_UNSIGNED_BYTE;
53#endif
54#if 0
55static GLenum ReadFormat = GL_RGB;
56static GLenum ReadType = GL_UNSIGNED_SHORT_5_6_5;
57#endif
58
Brian Pauleca1bc92000-03-01 16:23:14 +000059
60static void
61Reset( void )
62{
63 APosX = 5; APosY = 20;
64 BPosX = APosX + ImgWidth + 5; BPosY = 20;
65 CPosX = BPosX + ImgWidth + 5; CPosY = 20;
66}
67
68
69static void
70PrintString(const char *s)
71{
72 while (*s) {
73 glutBitmapCharacter(GLUT_BITMAP_8_BY_13, (int) *s);
74 s++;
75 }
76}
77
78
79static void
80SetupPixelTransfer(GLboolean invert)
81{
82 if (invert) {
83 glPixelTransferf(GL_RED_SCALE, -1.0);
84 glPixelTransferf(GL_RED_BIAS, 1.0);
85 glPixelTransferf(GL_GREEN_SCALE, -1.0);
86 glPixelTransferf(GL_GREEN_BIAS, 1.0);
87 glPixelTransferf(GL_BLUE_SCALE, -1.0);
88 glPixelTransferf(GL_BLUE_BIAS, 1.0);
89 }
90 else {
91 glPixelTransferf(GL_RED_SCALE, 1.0);
92 glPixelTransferf(GL_RED_BIAS, 0.0);
93 glPixelTransferf(GL_GREEN_SCALE, 1.0);
94 glPixelTransferf(GL_GREEN_BIAS, 0.0);
95 glPixelTransferf(GL_BLUE_SCALE, 1.0);
96 glPixelTransferf(GL_BLUE_BIAS, 0.0);
97 }
98}
99
100
101static void
102Display( void )
103{
104 glClear( GL_COLOR_BUFFER_BIT );
105
106 glRasterPos2i(5, ImgHeight+25);
Brian Paul4f6d60e2000-03-23 19:47:25 +0000107 PrintString("f = toggle front/back s = toggle scale/bias b = benchmark");
Brian Pauleca1bc92000-03-01 16:23:14 +0000108
109 /* draw original image */
110 glRasterPos2i(APosX, 5);
111 PrintString("Original");
112 glRasterPos2i(APosX, APosY);
113 glEnable(GL_DITHER);
114 SetupPixelTransfer(GL_FALSE);
115 glDrawPixels(ImgWidth, ImgHeight, ImgFormat, GL_UNSIGNED_BYTE, Image);
116
117 /* do readpixels, drawpixels */
118 glRasterPos2i(BPosX, 5);
119 PrintString("Read/DrawPixels");
120 SetupPixelTransfer(ScaleAndBias);
Brian Paul4f6d60e2000-03-23 19:47:25 +0000121 if (Benchmark) {
122 GLint reads = 0;
123 GLint endTime;
124 GLint startTime = glutGet(GLUT_ELAPSED_TIME);
125 GLdouble seconds, pixelsPerSecond;
126 printf("Benchmarking...\n");
127 do {
128 glReadPixels(APosX, APosY, ImgWidth, ImgHeight,
Brian Pauld3d72802000-03-31 01:01:31 +0000129 ReadFormat, ReadType, TempImage);
Brian Paul4f6d60e2000-03-23 19:47:25 +0000130 reads++;
131 endTime = glutGet(GLUT_ELAPSED_TIME);
132 } while (endTime - startTime < 4000); /* 4 seconds */
133 seconds = (double) (endTime - startTime) / 1000.0;
134 pixelsPerSecond = reads * ImgWidth * ImgHeight / seconds;
135 printf("Result: %d reads in %f seconds = %f pixels/sec\n",
136 reads, seconds, pixelsPerSecond);
137 Benchmark = GL_FALSE;
138 }
139 else {
140 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);
154 glCopyPixels(APosX, APosY, ImgWidth, ImgHeight, GL_COLOR);
155
156 if (!DrawFront)
157 glutSwapBuffers();
158}
159
160
Brian Paul4f6d60e2000-03-23 19:47:25 +0000161static void
162Reshape( int width, int height )
Brian Pauleca1bc92000-03-01 16:23:14 +0000163{
164 glViewport( 0, 0, width, height );
165 glMatrixMode( GL_PROJECTION );
166 glLoadIdentity();
167 glOrtho( 0.0, width, 0.0, height, -1.0, 1.0 );
168 glMatrixMode( GL_MODELVIEW );
169 glLoadIdentity();
170}
171
172
Brian Paul4f6d60e2000-03-23 19:47:25 +0000173static void
174Key( unsigned char key, int x, int y )
Brian Pauleca1bc92000-03-01 16:23:14 +0000175{
176 (void) x;
177 (void) y;
178 switch (key) {
179 case 'b':
Brian Paul4f6d60e2000-03-23 19:47:25 +0000180 Benchmark = GL_TRUE;
181 break;
182 case 's':
Brian Pauleca1bc92000-03-01 16:23:14 +0000183 ScaleAndBias = !ScaleAndBias;
184 break;
185 case 'f':
186 DrawFront = !DrawFront;
Brian Paul4f6d60e2000-03-23 19:47:25 +0000187 if (DrawFront) {
Brian Pauleca1bc92000-03-01 16:23:14 +0000188 glDrawBuffer(GL_FRONT);
Brian Paul4f6d60e2000-03-23 19:47:25 +0000189 glReadBuffer(GL_FRONT);
190 }
191 else {
Brian Pauleca1bc92000-03-01 16:23:14 +0000192 glDrawBuffer(GL_BACK);
Brian Paul4f6d60e2000-03-23 19:47:25 +0000193 glReadBuffer(GL_BACK);
194 }
Brian Pauleca1bc92000-03-01 16:23:14 +0000195 printf("glDrawBuffer(%s)\n", DrawFront ? "GL_FRONT" : "GL_BACK");
196 break;
197 case 27:
198 exit(0);
199 break;
200 }
201 glutPostRedisplay();
202}
203
204
Brian Pauleca1bc92000-03-01 16:23:14 +0000205static void
206Init( GLboolean ciMode )
207{
208 printf("GL_VERSION = %s\n", (char *) glGetString(GL_VERSION));
209 printf("GL_RENDERER = %s\n", (char *) glGetString(GL_RENDERER));
210
211 Image = LoadRGBImage( IMAGE_FILE, &ImgWidth, &ImgHeight, &ImgFormat );
212 if (!Image) {
213 printf("Couldn't read %s\n", IMAGE_FILE);
214 exit(0);
215 }
216
217 if (ciMode) {
218 /* Convert RGB image to grayscale */
219 GLubyte *indexImage = malloc( ImgWidth * ImgHeight );
220 GLint i;
221 for (i=0; i<ImgWidth*ImgHeight; i++) {
222 int gray = Image[i*3] + Image[i*3+1] + Image[i*3+2];
223 indexImage[i] = gray / 3;
224 }
225 free(Image);
226 Image = indexImage;
227 ImgFormat = GL_COLOR_INDEX;
228
229 for (i=0;i<255;i++) {
230 float g = i / 255.0;
231 glutSetColor(i, g, g, g);
232 }
233 }
234
235 printf("Loaded %d by %d image\n", ImgWidth, ImgHeight );
236
237 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
238 glPixelStorei(GL_UNPACK_ROW_LENGTH, ImgWidth);
239 glPixelStorei(GL_PACK_ALIGNMENT, 1);
240 glPixelStorei(GL_PACK_ROW_LENGTH, ImgWidth);
241
242 Reset();
243
244 TempImage = (GLubyte *) malloc(ImgWidth * ImgHeight * 4 * sizeof(GLubyte));
245 assert(TempImage);
246}
247
248
Brian Paul4f6d60e2000-03-23 19:47:25 +0000249int
250main( int argc, char *argv[] )
Brian Pauleca1bc92000-03-01 16:23:14 +0000251{
252 GLboolean ciMode = GL_FALSE;
Brian Pauleca1bc92000-03-01 16:23:14 +0000253 if (argc > 1 && strcmp(argv[1], "-ci")==0) {
254 ciMode = GL_TRUE;
255 }
Brian Pauleca1bc92000-03-01 16:23:14 +0000256 glutInit( &argc, argv );
257 glutInitWindowPosition( 0, 0 );
258 glutInitWindowSize( 750, 250 );
Brian Pauleca1bc92000-03-01 16:23:14 +0000259 if (ciMode)
260 glutInitDisplayMode( GLUT_INDEX | GLUT_DOUBLE );
261 else
262 glutInitDisplayMode( GLUT_RGB | GLUT_DOUBLE );
Brian Pauleca1bc92000-03-01 16:23:14 +0000263 glutCreateWindow(argv[0]);
Brian Pauleca1bc92000-03-01 16:23:14 +0000264 Init(ciMode);
Brian Pauleca1bc92000-03-01 16:23:14 +0000265 glutReshapeFunc( Reshape );
266 glutKeyboardFunc( Key );
Brian Pauleca1bc92000-03-01 16:23:14 +0000267 glutDisplayFunc( Display );
Brian Pauleca1bc92000-03-01 16:23:14 +0000268 glutMainLoop();
269 return 0;
270}