blob: 9974486db39211de3faee5425e309108785b2aaf [file] [log] [blame]
Brian Paul746e59f2004-03-13 18:31:14 +00001/*
2 * GL_EXT_pixel_buffer_object test
3 *
4 * Brian Paul
5 * 11 March 2004
6 */
7
Brian Paul746e59f2004-03-13 18:31:14 +00008
9#include <assert.h>
10#include <stdio.h>
11#include <stdlib.h>
12#include <math.h>
Keith Whitwella58065d2009-03-10 13:11:23 +000013#include <GL/glew.h>
Brian Paul746e59f2004-03-13 18:31:14 +000014#include <GL/glut.h>
15
Brian Paul746e59f2004-03-13 18:31:14 +000016#include "../util/readtex.c" /* a hack, I know */
17
18#define IMAGE_FILE "../images/girl.rgb"
19
20static int ImgWidth, ImgHeight;
21static GLenum ImgFormat;
22static GLubyte *Image = NULL;
23
24static int APosX, APosY; /* simple drawpixels */
25static int BPosX, BPosY; /* read/draw pixels */
26static int CPosX, CPosY; /* copypixels */
27
28static GLboolean DrawFront = GL_FALSE;
29static GLboolean ScaleAndBias = GL_FALSE;
30static GLboolean Benchmark = GL_FALSE;
31
32static GLuint DrawPBO, TempPBO;
33
34
Brian Paul1d886a82006-04-13 19:45:42 +000035static GLenum ReadFormat = GL_BGRA;
36static GLenum ReadType = GL_UNSIGNED_INT_8_8_8_8_REV;
Brian Paul746e59f2004-03-13 18:31:14 +000037
38
39
Brian Paul1d886a82006-04-13 19:45:42 +000040static void
41CheckError(int line)
42{
43 GLenum err = glGetError();
44 if (err) {
45 printf("GL Error 0x%x at line %d\n", (int) err, line);
46 }
47}
48
Brian Paul746e59f2004-03-13 18:31:14 +000049
50static void
51Reset( void )
52{
53 APosX = 5; APosY = 20;
54 BPosX = APosX + ImgWidth + 5; BPosY = 20;
55 CPosX = BPosX + ImgWidth + 5; CPosY = 20;
56}
57
58
59static void
60PrintString(const char *s)
61{
62 while (*s) {
63 glutBitmapCharacter(GLUT_BITMAP_8_BY_13, (int) *s);
64 s++;
65 }
66}
67
68
69static void
70SetupPixelTransfer(GLboolean invert)
71{
72 if (invert) {
73 glPixelTransferf(GL_RED_SCALE, -1.0);
74 glPixelTransferf(GL_RED_BIAS, 1.0);
75 glPixelTransferf(GL_GREEN_SCALE, -1.0);
76 glPixelTransferf(GL_GREEN_BIAS, 1.0);
77 glPixelTransferf(GL_BLUE_SCALE, -1.0);
78 glPixelTransferf(GL_BLUE_BIAS, 1.0);
79 }
80 else {
81 glPixelTransferf(GL_RED_SCALE, 1.0);
82 glPixelTransferf(GL_RED_BIAS, 0.0);
83 glPixelTransferf(GL_GREEN_SCALE, 1.0);
84 glPixelTransferf(GL_GREEN_BIAS, 0.0);
85 glPixelTransferf(GL_BLUE_SCALE, 1.0);
86 glPixelTransferf(GL_BLUE_BIAS, 0.0);
87 }
88}
89
90
91static void
92Display( void )
93{
94 glClearColor(.3, .3, .3, 1);
95 glClear( GL_COLOR_BUFFER_BIT );
96
Brian Paul1d886a82006-04-13 19:45:42 +000097 CheckError(__LINE__);
98
Brian Paul746e59f2004-03-13 18:31:14 +000099 /** Unbind UNPACK pixel buffer before calling glBitmap */
100 glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_EXT, 0);
101
102 glRasterPos2i(5, ImgHeight+25);
103 PrintString("f = toggle front/back s = toggle scale/bias b = benchmark");
104
105 glRasterPos2i(5, ImgHeight+40);
Brian Paul1fd4a552004-09-23 17:32:12 +0000106 PrintString("GL_EXT_pixel_buffer_object test");
Brian Paul746e59f2004-03-13 18:31:14 +0000107
108 /* draw original image */
109 glRasterPos2i(APosX, 5);
110 PrintString("Original");
111 glRasterPos2i(APosX, APosY);
112 glEnable(GL_DITHER);
113 SetupPixelTransfer(GL_FALSE);
114 /*** Draw from the DrawPBO */
115 glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_EXT, DrawPBO);
116 glDrawPixels(ImgWidth, ImgHeight, ImgFormat, GL_UNSIGNED_BYTE, 0);
Brian Paulc6136ea2004-10-31 15:27:12 +0000117 glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_EXT, 0);
Brian Paul746e59f2004-03-13 18:31:14 +0000118
Brian Paul1d886a82006-04-13 19:45:42 +0000119 CheckError(__LINE__);
120
Brian Paul746e59f2004-03-13 18:31:14 +0000121 /* do readpixels, drawpixels */
122 glRasterPos2i(BPosX, 5);
123 PrintString("Read/DrawPixels");
124 SetupPixelTransfer(ScaleAndBias);
125 /*** read into the Temp PBO */
126 glBindBufferARB(GL_PIXEL_PACK_BUFFER_EXT, TempPBO);
Brian Paul1d886a82006-04-13 19:45:42 +0000127 CheckError(__LINE__);
Brian Paul746e59f2004-03-13 18:31:14 +0000128 if (Benchmark) {
129 GLint reads = 0;
130 GLint endTime;
131 GLint startTime = glutGet(GLUT_ELAPSED_TIME);
132 GLdouble seconds, pixelsPerSecond;
133 printf("Benchmarking...\n");
134 do {
135 glReadPixels(APosX, APosY, ImgWidth, ImgHeight,
136 ReadFormat, ReadType, 0);
137 reads++;
138 endTime = glutGet(GLUT_ELAPSED_TIME);
139 } while (endTime - startTime < 4000); /* 4 seconds */
140 seconds = (double) (endTime - startTime) / 1000.0;
141 pixelsPerSecond = reads * ImgWidth * ImgHeight / seconds;
142 printf("Result: %d reads in %f seconds = %f pixels/sec\n",
143 reads, seconds, pixelsPerSecond);
144 Benchmark = GL_FALSE;
145 }
146 else {
147 glReadPixels(APosX, APosY, ImgWidth, ImgHeight,
148 ReadFormat, ReadType, 0);
149 }
Brian Paul1d886a82006-04-13 19:45:42 +0000150 CheckError(__LINE__);
Brian Paul746e59f2004-03-13 18:31:14 +0000151 glRasterPos2i(BPosX, BPosY);
152 glDisable(GL_DITHER);
153 SetupPixelTransfer(GL_FALSE);
Brian Paul1d886a82006-04-13 19:45:42 +0000154
155 CheckError(__LINE__);
156
Brian Paul746e59f2004-03-13 18:31:14 +0000157 /*** draw from the Temp PBO */
158 glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_EXT, TempPBO);
159 glDrawPixels(ImgWidth, ImgHeight, ReadFormat, ReadType, 0);
Brian Paulc6136ea2004-10-31 15:27:12 +0000160 glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_EXT, 0);
Brian Paul746e59f2004-03-13 18:31:14 +0000161
Brian Paul1d886a82006-04-13 19:45:42 +0000162 CheckError(__LINE__);
163
Brian Paul746e59f2004-03-13 18:31:14 +0000164 /* do copypixels */
165 glRasterPos2i(CPosX, 5);
166 PrintString("CopyPixels");
167 glRasterPos2i(CPosX, CPosY);
168 glDisable(GL_DITHER);
169 SetupPixelTransfer(ScaleAndBias);
170 glCopyPixels(APosX, APosY, ImgWidth, ImgHeight, GL_COLOR);
171
Brian Paul1d886a82006-04-13 19:45:42 +0000172 CheckError(__LINE__);
173
Brian Paul746e59f2004-03-13 18:31:14 +0000174 if (!DrawFront)
175 glutSwapBuffers();
176 else
177 glFinish();
178}
179
180
181static void
182Reshape( int width, int height )
183{
184 glViewport( 0, 0, width, height );
185 glMatrixMode( GL_PROJECTION );
186 glLoadIdentity();
187 glOrtho( 0.0, width, 0.0, height, -1.0, 1.0 );
188 glMatrixMode( GL_MODELVIEW );
189 glLoadIdentity();
190}
191
192
193static void
194Key( unsigned char key, int x, int y )
195{
196 (void) x;
197 (void) y;
198 switch (key) {
199 case 'b':
200 Benchmark = GL_TRUE;
201 break;
202 case 's':
203 ScaleAndBias = !ScaleAndBias;
204 break;
205 case 'f':
206 DrawFront = !DrawFront;
207 if (DrawFront) {
208 glDrawBuffer(GL_FRONT);
209 glReadBuffer(GL_FRONT);
210 }
211 else {
212 glDrawBuffer(GL_BACK);
213 glReadBuffer(GL_BACK);
214 }
215 printf("glDrawBuffer(%s)\n", DrawFront ? "GL_FRONT" : "GL_BACK");
216 break;
217 case 27:
218 exit(0);
219 break;
220 }
221 glutPostRedisplay();
222}
223
224
225static void
Brian Paul1d886a82006-04-13 19:45:42 +0000226Init(void)
Brian Paul746e59f2004-03-13 18:31:14 +0000227{
228 printf("GL_VERSION = %s\n", (char *) glGetString(GL_VERSION));
229 printf("GL_RENDERER = %s\n", (char *) glGetString(GL_RENDERER));
230
231 if (!glutExtensionSupported("GL_EXT_pixel_buffer_object")) {
232 printf("Sorry, this demo requires GL_EXT_pixel_buffer_object\n");
233 exit(0);
234 }
235
236 Image = LoadRGBImage( IMAGE_FILE, &ImgWidth, &ImgHeight, &ImgFormat );
237 if (!Image) {
238 printf("Couldn't read %s\n", IMAGE_FILE);
239 exit(0);
240 }
241
Brian Paul1d886a82006-04-13 19:45:42 +0000242 printf("Loaded %d by %d image\n", ImgWidth, ImgHeight );
243
244 if (ImgFormat == GL_RGB) {
245 /* convert to RGBA */
246 int i;
247 GLubyte *image2 = (GLubyte *) malloc(ImgWidth * ImgHeight * 4);
248 printf("Converting RGB image to RGBA\n");
249 for (i = 0; i < ImgWidth * ImgHeight; i++) {
250 image2[i*4+0] = Image[i*3+0];
251 image2[i*4+1] = Image[i*3+1];
252 image2[i*4+2] = Image[i*3+2];
253 image2[i*4+3] = 255;
Brian Paul746e59f2004-03-13 18:31:14 +0000254 }
255 free(Image);
Brian Paul1d886a82006-04-13 19:45:42 +0000256 Image = image2;
257 ImgFormat = GL_RGBA;
Brian Paul746e59f2004-03-13 18:31:14 +0000258 }
259
Brian Paul746e59f2004-03-13 18:31:14 +0000260 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
261 glPixelStorei(GL_UNPACK_ROW_LENGTH, ImgWidth);
262 glPixelStorei(GL_PACK_ALIGNMENT, 1);
263 glPixelStorei(GL_PACK_ROW_LENGTH, ImgWidth);
264
265 Reset();
266
267 /* put image into DrawPBO */
268 glGenBuffersARB(1, &DrawPBO);
269 glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_EXT, DrawPBO);
270 glBufferDataARB(GL_PIXEL_UNPACK_BUFFER_EXT,
271 ImgWidth * ImgHeight * 4, Image, GL_STATIC_DRAW);
272
273 /* Setup TempPBO - used for glReadPixels & glDrawPixels */
274 glGenBuffersARB(1, &TempPBO);
275 glBindBufferARB(GL_PIXEL_PACK_BUFFER_EXT, TempPBO);
276 glBufferDataARB(GL_PIXEL_PACK_BUFFER_EXT,
277 ImgWidth * ImgHeight * 4, NULL, GL_DYNAMIC_COPY);
278
279}
280
281
282int
283main( int argc, char *argv[] )
284{
Brian Paul746e59f2004-03-13 18:31:14 +0000285 glutInit( &argc, argv );
286 glutInitWindowPosition( 0, 0 );
287 glutInitWindowSize( 750, 250 );
Brian Paul1d886a82006-04-13 19:45:42 +0000288 glutInitDisplayMode( GLUT_RGB | GLUT_DOUBLE );
Brian Paul746e59f2004-03-13 18:31:14 +0000289 glutCreateWindow(argv[0]);
Keith Whitwella58065d2009-03-10 13:11:23 +0000290 glewInit();
Brian Paul1d886a82006-04-13 19:45:42 +0000291 Init();
Brian Paul746e59f2004-03-13 18:31:14 +0000292 glutReshapeFunc( Reshape );
293 glutKeyboardFunc( Key );
294 glutDisplayFunc( Display );
295 glutMainLoop();
296 return 0;
297}