pbo.c revision 32001f49
1/* 2 * GL_EXT_pixel_buffer_object test 3 * 4 * Brian Paul 5 * 11 March 2004 6 */ 7 8 9#include <assert.h> 10#include <stdio.h> 11#include <stdlib.h> 12#include <math.h> 13#include <GL/glew.h> 14#include "glut_wrap.h" 15 16#include "../util/readtex.c" /* a hack, I know */ 17 18#define IMAGE_FILE DEMOS_DATA_DIR "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 35static GLenum ReadFormat = GL_BGRA; 36static GLenum ReadType = GL_UNSIGNED_INT_8_8_8_8_REV; 37 38 39 40static 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 49 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 97 CheckError(__LINE__); 98 99 /** 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); 106 PrintString("GL_EXT_pixel_buffer_object test"); 107 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); 117 glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_EXT, 0); 118 119 CheckError(__LINE__); 120 121 /* 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); 127 CheckError(__LINE__); 128 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 } 150 CheckError(__LINE__); 151 glRasterPos2i(BPosX, BPosY); 152 glDisable(GL_DITHER); 153 SetupPixelTransfer(GL_FALSE); 154 155 CheckError(__LINE__); 156 157 /*** draw from the Temp PBO */ 158 glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_EXT, TempPBO); 159 glDrawPixels(ImgWidth, ImgHeight, ReadFormat, ReadType, 0); 160 glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_EXT, 0); 161 162 CheckError(__LINE__); 163 164 /* 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 172 CheckError(__LINE__); 173 174 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 226Init(void) 227{ 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 242 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; 254 } 255 free(Image); 256 Image = image2; 257 ImgFormat = GL_RGBA; 258 } 259 260 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{ 285 glutInit( &argc, argv ); 286 glutInitWindowPosition( 0, 0 ); 287 glutInitWindowSize( 750, 250 ); 288 glutInitDisplayMode( GLUT_RGB | GLUT_DOUBLE ); 289 glutCreateWindow(argv[0]); 290 glewInit(); 291 Init(); 292 glutReshapeFunc( Reshape ); 293 glutKeyboardFunc( Key ); 294 glutDisplayFunc( Display ); 295 glutMainLoop(); 296 return 0; 297} 298