diff options
author | Thierry Reding <[email protected]> | 2006-10-14 03:46:41 +0000 |
---|---|---|
committer | Thierry Reding <[email protected]> | 2006-10-14 03:46:41 +0000 |
commit | 1ddf606332a188e46a47607cd41eb5d81bdf4c8a (patch) | |
tree | 8cb51078803106d87aedeae7bbd7a762a0d369d1 /progs/demos/readpix.c |
Import Mesa 6.5.1 (MesaLib, MesaDemos, MesaGLUT).
Diffstat (limited to 'progs/demos/readpix.c')
-rw-r--r-- | progs/demos/readpix.c | 344 |
1 files changed, 344 insertions, 0 deletions
diff --git a/progs/demos/readpix.c b/progs/demos/readpix.c new file mode 100644 index 00000000000..75ba45c1e5f --- /dev/null +++ b/progs/demos/readpix.c @@ -0,0 +1,344 @@ + +/* + * glReadPixels and glCopyPixels test + * + * Brian Paul March 1, 2000 This file is in the public domain. + */ + +#include <assert.h> +#include <stdio.h> +#include <stdlib.h> +#include <math.h> +#include <string.h> +#include <GL/glut.h> + +#include "readtex.h" + +#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 GLubyte *TempImage = NULL; + +#if 0 +#define ReadFormat ImgFormat +#define ReadType GL_UNSIGNED_BYTE +#endif +#if 1 +static GLenum ReadFormat = GL_RGBA; +static GLenum ReadType = GL_UNSIGNED_BYTE; +#endif +#if 0 +static GLenum ReadFormat = GL_RGB; +static GLenum ReadType = GL_UNSIGNED_BYTE; +#endif +#if 0 +static GLenum ReadFormat = GL_RGB; +static GLenum ReadType = GL_UNSIGNED_SHORT_5_6_5; +#endif +#if 0 +static GLenum ReadFormat = GL_RGBA; +static GLenum ReadType = GL_UNSIGNED_SHORT_1_5_5_5_REV; +#endif +#if 0 +static GLenum ReadFormat = GL_BGRA; +static GLenum ReadType = GL_UNSIGNED_SHORT_5_5_5_1; +#endif +#if 0 +static GLenum ReadFormat = GL_BGRA; +static GLenum ReadType = GL_UNSIGNED_SHORT_4_4_4_4_REV; +#endif + + +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); + } +} + + +/** + * Exercise Pixel Pack parameters by reading the image in four pieces. + */ +static void +ComplexReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, + GLenum format, GLenum type, GLvoid *pixels) +{ + const GLsizei width0 = width / 2; + const GLsizei width1 = width - width0; + const GLsizei height0 = height / 2; + const GLsizei height1 = height - height0; + + glPixelStorei(GL_PACK_ROW_LENGTH, width); + + /* lower-left quadrant */ + glReadPixels(x, y, width0, height0, format, type, pixels); + + /* lower-right quadrant */ + glPixelStorei(GL_PACK_SKIP_PIXELS, width0); + glReadPixels(x + width0, y, width1, height0, format, type, pixels); + + /* upper-left quadrant */ + glPixelStorei(GL_PACK_SKIP_PIXELS, 0); + glPixelStorei(GL_PACK_SKIP_ROWS, height0); + glReadPixels(x, y + height0, width0, height1, format, type, pixels); + + /* upper-right quadrant */ + glPixelStorei(GL_PACK_SKIP_PIXELS, width0); + glPixelStorei(GL_PACK_SKIP_ROWS, height0); + glReadPixels(x + width0, y + height0, width1, height1, format, type, pixels); + + /* restore defaults */ + glPixelStorei(GL_PACK_SKIP_PIXELS, 0); + glPixelStorei(GL_PACK_SKIP_ROWS, 0); + glPixelStorei(GL_PACK_ROW_LENGTH, ImgWidth); +} + + + +static void +Display( void ) +{ + glClearColor(.3, .3, .3, 1); + glClear( GL_COLOR_BUFFER_BIT ); + + glRasterPos2i(5, ImgHeight+25); + PrintString("f = toggle front/back s = toggle scale/bias b = benchmark"); + + /* draw original image */ + glRasterPos2i(APosX, 5); + PrintString("Original"); + glRasterPos2i(APosX, APosY); + glEnable(GL_DITHER); + SetupPixelTransfer(GL_FALSE); + glPixelStorei(GL_UNPACK_ALIGNMENT, 1); + glDrawPixels(ImgWidth, ImgHeight, ImgFormat, GL_UNSIGNED_BYTE, Image); + + /* might try alignment=4 here for testing */ + glPixelStorei(GL_UNPACK_ALIGNMENT, 1); + glPixelStorei(GL_PACK_ALIGNMENT, 1); + + /* do readpixels, drawpixels */ + glRasterPos2i(BPosX, 5); + PrintString("Read/DrawPixels"); + SetupPixelTransfer(ScaleAndBias); + 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, TempImage); + 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 { + /* clear the temporary image to white (helpful for debugging */ + memset(TempImage, 255, ImgWidth * ImgHeight * 4); +#if 1 + glReadPixels(APosX, APosY, ImgWidth, ImgHeight, + ReadFormat, ReadType, TempImage); + (void) ComplexReadPixels; +#else + /* you might use this when debugging */ + ComplexReadPixels(APosX, APosY, ImgWidth, ImgHeight, + ReadFormat, ReadType, TempImage); +#endif + } + glRasterPos2i(BPosX, BPosY); + glDisable(GL_DITHER); + SetupPixelTransfer(GL_FALSE); + glDrawPixels(ImgWidth, ImgHeight, ReadFormat, ReadType, TempImage); + + /* do copypixels */ + glRasterPos2i(CPosX, 5); + PrintString("CopyPixels"); + glRasterPos2i(CPosX, CPosY); + glDisable(GL_DITHER); + SetupPixelTransfer(ScaleAndBias); + glCopyPixels(APosX, APosY, ImgWidth, ImgHeight, GL_COLOR); + + 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( GLboolean ciMode ) +{ + GLboolean have_read_format = GL_FALSE; + + printf("GL_VERSION = %s\n", (char *) glGetString(GL_VERSION)); + printf("GL_RENDERER = %s\n", (char *) glGetString(GL_RENDERER)); + + Image = LoadRGBImage( IMAGE_FILE, &ImgWidth, &ImgHeight, &ImgFormat ); + if (!Image) { + printf("Couldn't read %s\n", IMAGE_FILE); + exit(0); + } + + if (ciMode) { + /* Convert RGB image to grayscale */ + GLubyte *indexImage = (GLubyte *) malloc( ImgWidth * ImgHeight ); + GLint i; + for (i=0; i<ImgWidth*ImgHeight; i++) { + int gray = Image[i*3] + Image[i*3+1] + Image[i*3+2]; + indexImage[i] = gray / 3; + } + free(Image); + Image = indexImage; + ImgFormat = GL_COLOR_INDEX; + + for (i=0;i<255;i++) { + float g = i / 255.0; + glutSetColor(i, g, g, g); + } + } + +#ifdef GL_OES_read_format + if ( glutExtensionSupported( "GL_OES_read_format" ) ) { + glGetIntegerv(GL_IMPLEMENTATION_COLOR_READ_TYPE_OES, (GLint *) &ReadType); + glGetIntegerv(GL_IMPLEMENTATION_COLOR_READ_FORMAT_OES, (GLint *) &ReadFormat); + + have_read_format = GL_TRUE; + } +#endif + + printf( "GL_OES_read_format %ssupported. " + "Using type / format = 0x%04x / 0x%04x\n", + (have_read_format) ? "" : "not ", + ReadType, ReadFormat ); + + printf("Loaded %d by %d image\n", ImgWidth, ImgHeight ); + + glPixelStorei(GL_UNPACK_ROW_LENGTH, ImgWidth); + glPixelStorei(GL_PACK_ROW_LENGTH, ImgWidth); + + Reset(); + + /* allocate an extra 1KB in case we're tinkering with pack alignment */ + TempImage = (GLubyte *) malloc(ImgWidth * ImgHeight * 4 * sizeof(GLubyte) + + 1000); + assert(TempImage); +} + + +int +main( int argc, char *argv[] ) +{ + GLboolean ciMode = GL_FALSE; + if (argc > 1 && strcmp(argv[1], "-ci")==0) { + ciMode = GL_TRUE; + } + glutInit( &argc, argv ); + glutInitWindowPosition( 0, 0 ); + glutInitWindowSize( 750, 250 ); + if (ciMode) + glutInitDisplayMode( GLUT_INDEX | GLUT_DOUBLE ); + else + glutInitDisplayMode( GLUT_RGB | GLUT_DOUBLE ); + glutCreateWindow(argv[0]); + Init(ciMode); + glutReshapeFunc( Reshape ); + glutKeyboardFunc( Key ); + glutDisplayFunc( Display ); + glutMainLoop(); + return 0; +} |