diff options
Diffstat (limited to 'progs/tests/pbo.c')
-rw-r--r-- | progs/tests/pbo.c | 296 |
1 files changed, 296 insertions, 0 deletions
diff --git a/progs/tests/pbo.c b/progs/tests/pbo.c new file mode 100644 index 00000000000..b31b36cc121 --- /dev/null +++ b/progs/tests/pbo.c @@ -0,0 +1,296 @@ +/* + * GL_EXT_pixel_buffer_object test + * + * Brian Paul + * 11 March 2004 + */ + +#define GL_GLEXT_PROTOTYPES + +#include <assert.h> +#include <stdio.h> +#include <stdlib.h> +#include <math.h> +#include <GL/glut.h> + +#include "../util/readtex.c" /* a hack, I know */ + +#define IMAGE_FILE "../images/girl.rgb" + +static int ImgWidth, ImgHeight; +static GLenum ImgFormat; +static GLubyte *Image = NULL; + +static int APosX, APosY; /* simple drawpixels */ +static int BPosX, BPosY; /* read/draw pixels */ +static int CPosX, CPosY; /* copypixels */ + +static GLboolean DrawFront = GL_FALSE; +static GLboolean ScaleAndBias = GL_FALSE; +static GLboolean Benchmark = GL_FALSE; + +static GLuint DrawPBO, TempPBO; + + +static GLenum ReadFormat = GL_BGRA; +static GLenum ReadType = GL_UNSIGNED_INT_8_8_8_8_REV; + + + +static void +CheckError(int line) +{ + GLenum err = glGetError(); + if (err) { + printf("GL Error 0x%x at line %d\n", (int) err, line); + } +} + + +static void +Reset( void ) +{ + APosX = 5; APosY = 20; + BPosX = APosX + ImgWidth + 5; BPosY = 20; + CPosX = BPosX + ImgWidth + 5; CPosY = 20; +} + + +static void +PrintString(const char *s) +{ + while (*s) { + glutBitmapCharacter(GLUT_BITMAP_8_BY_13, (int) *s); + s++; + } +} + + +static void +SetupPixelTransfer(GLboolean invert) +{ + if (invert) { + glPixelTransferf(GL_RED_SCALE, -1.0); + glPixelTransferf(GL_RED_BIAS, 1.0); + glPixelTransferf(GL_GREEN_SCALE, -1.0); + glPixelTransferf(GL_GREEN_BIAS, 1.0); + glPixelTransferf(GL_BLUE_SCALE, -1.0); + glPixelTransferf(GL_BLUE_BIAS, 1.0); + } + else { + glPixelTransferf(GL_RED_SCALE, 1.0); + glPixelTransferf(GL_RED_BIAS, 0.0); + glPixelTransferf(GL_GREEN_SCALE, 1.0); + glPixelTransferf(GL_GREEN_BIAS, 0.0); + glPixelTransferf(GL_BLUE_SCALE, 1.0); + glPixelTransferf(GL_BLUE_BIAS, 0.0); + } +} + + +static void +Display( void ) +{ + glClearColor(.3, .3, .3, 1); + glClear( GL_COLOR_BUFFER_BIT ); + + CheckError(__LINE__); + + /** Unbind UNPACK pixel buffer before calling glBitmap */ + glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_EXT, 0); + + glRasterPos2i(5, ImgHeight+25); + PrintString("f = toggle front/back s = toggle scale/bias b = benchmark"); + + glRasterPos2i(5, ImgHeight+40); + PrintString("GL_EXT_pixel_buffer_object test"); + + /* draw original image */ + glRasterPos2i(APosX, 5); + PrintString("Original"); + glRasterPos2i(APosX, APosY); + glEnable(GL_DITHER); + SetupPixelTransfer(GL_FALSE); + /*** Draw from the DrawPBO */ + glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_EXT, DrawPBO); + glDrawPixels(ImgWidth, ImgHeight, ImgFormat, GL_UNSIGNED_BYTE, 0); + glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_EXT, 0); + + CheckError(__LINE__); + + /* do readpixels, drawpixels */ + glRasterPos2i(BPosX, 5); + PrintString("Read/DrawPixels"); + SetupPixelTransfer(ScaleAndBias); + /*** read into the Temp PBO */ + glBindBufferARB(GL_PIXEL_PACK_BUFFER_EXT, TempPBO); + CheckError(__LINE__); + if (Benchmark) { + GLint reads = 0; + GLint endTime; + GLint startTime = glutGet(GLUT_ELAPSED_TIME); + GLdouble seconds, pixelsPerSecond; + printf("Benchmarking...\n"); + do { + glReadPixels(APosX, APosY, ImgWidth, ImgHeight, + ReadFormat, ReadType, 0); + reads++; + endTime = glutGet(GLUT_ELAPSED_TIME); + } while (endTime - startTime < 4000); /* 4 seconds */ + seconds = (double) (endTime - startTime) / 1000.0; + pixelsPerSecond = reads * ImgWidth * ImgHeight / seconds; + printf("Result: %d reads in %f seconds = %f pixels/sec\n", + reads, seconds, pixelsPerSecond); + Benchmark = GL_FALSE; + } + else { + glReadPixels(APosX, APosY, ImgWidth, ImgHeight, + ReadFormat, ReadType, 0); + } + CheckError(__LINE__); + glRasterPos2i(BPosX, BPosY); + glDisable(GL_DITHER); + SetupPixelTransfer(GL_FALSE); + + CheckError(__LINE__); + + /*** draw from the Temp PBO */ + glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_EXT, TempPBO); + glDrawPixels(ImgWidth, ImgHeight, ReadFormat, ReadType, 0); + glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_EXT, 0); + + CheckError(__LINE__); + + /* do copypixels */ + glRasterPos2i(CPosX, 5); + PrintString("CopyPixels"); + glRasterPos2i(CPosX, CPosY); + glDisable(GL_DITHER); + SetupPixelTransfer(ScaleAndBias); + glCopyPixels(APosX, APosY, ImgWidth, ImgHeight, GL_COLOR); + + CheckError(__LINE__); + + if (!DrawFront) + glutSwapBuffers(); + else + glFinish(); +} + + +static void +Reshape( int width, int height ) +{ + glViewport( 0, 0, width, height ); + glMatrixMode( GL_PROJECTION ); + glLoadIdentity(); + glOrtho( 0.0, width, 0.0, height, -1.0, 1.0 ); + glMatrixMode( GL_MODELVIEW ); + glLoadIdentity(); +} + + +static void +Key( unsigned char key, int x, int y ) +{ + (void) x; + (void) y; + switch (key) { + case 'b': + Benchmark = GL_TRUE; + break; + case 's': + ScaleAndBias = !ScaleAndBias; + break; + case 'f': + DrawFront = !DrawFront; + if (DrawFront) { + glDrawBuffer(GL_FRONT); + glReadBuffer(GL_FRONT); + } + else { + glDrawBuffer(GL_BACK); + glReadBuffer(GL_BACK); + } + printf("glDrawBuffer(%s)\n", DrawFront ? "GL_FRONT" : "GL_BACK"); + break; + case 27: + exit(0); + break; + } + glutPostRedisplay(); +} + + +static void +Init(void) +{ + printf("GL_VERSION = %s\n", (char *) glGetString(GL_VERSION)); + printf("GL_RENDERER = %s\n", (char *) glGetString(GL_RENDERER)); + + if (!glutExtensionSupported("GL_EXT_pixel_buffer_object")) { + printf("Sorry, this demo requires GL_EXT_pixel_buffer_object\n"); + exit(0); + } + + Image = LoadRGBImage( IMAGE_FILE, &ImgWidth, &ImgHeight, &ImgFormat ); + if (!Image) { + printf("Couldn't read %s\n", IMAGE_FILE); + exit(0); + } + + printf("Loaded %d by %d image\n", ImgWidth, ImgHeight ); + + if (ImgFormat == GL_RGB) { + /* convert to RGBA */ + int i; + GLubyte *image2 = (GLubyte *) malloc(ImgWidth * ImgHeight * 4); + printf("Converting RGB image to RGBA\n"); + for (i = 0; i < ImgWidth * ImgHeight; i++) { + image2[i*4+0] = Image[i*3+0]; + image2[i*4+1] = Image[i*3+1]; + image2[i*4+2] = Image[i*3+2]; + image2[i*4+3] = 255; + } + free(Image); + Image = image2; + ImgFormat = GL_RGBA; + } + + glPixelStorei(GL_UNPACK_ALIGNMENT, 1); + glPixelStorei(GL_UNPACK_ROW_LENGTH, ImgWidth); + glPixelStorei(GL_PACK_ALIGNMENT, 1); + glPixelStorei(GL_PACK_ROW_LENGTH, ImgWidth); + + Reset(); + + /* put image into DrawPBO */ + glGenBuffersARB(1, &DrawPBO); + glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_EXT, DrawPBO); + glBufferDataARB(GL_PIXEL_UNPACK_BUFFER_EXT, + ImgWidth * ImgHeight * 4, Image, GL_STATIC_DRAW); + + /* Setup TempPBO - used for glReadPixels & glDrawPixels */ + glGenBuffersARB(1, &TempPBO); + glBindBufferARB(GL_PIXEL_PACK_BUFFER_EXT, TempPBO); + glBufferDataARB(GL_PIXEL_PACK_BUFFER_EXT, + ImgWidth * ImgHeight * 4, NULL, GL_DYNAMIC_COPY); + +} + + +int +main( int argc, char *argv[] ) +{ + glutInit( &argc, argv ); + glutInitWindowPosition( 0, 0 ); + glutInitWindowSize( 750, 250 ); + glutInitDisplayMode( GLUT_RGB | GLUT_DOUBLE ); + glutCreateWindow(argv[0]); + Init(); + glutReshapeFunc( Reshape ); + glutKeyboardFunc( Key ); + glutDisplayFunc( Display ); + glutMainLoop(); + return 0; +} |