| @@ -0,0 +1,253 @@ | |||
| /* $Id: readpix.c,v 1.1 2000/03/01 16:23:14 brianp Exp $ */ | |||
| /* | |||
| * glReadPixels and glCopyPixels test | |||
| * | |||
| * Brian Paul March 1, 2000 This file is in the public domain. | |||
| */ | |||
| /* | |||
| * $Log: readpix.c,v $ | |||
| * Revision 1.1 2000/03/01 16:23:14 brianp | |||
| * test glDraw/Read/CopyPixels() | |||
| * | |||
| */ | |||
| #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 GLubyte *TempImage = NULL; | |||
| 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 ) | |||
| { | |||
| glClear( GL_COLOR_BUFFER_BIT ); | |||
| glRasterPos2i(5, ImgHeight+25); | |||
| PrintString("f = toggle front/back b = toggle scale/bias"); | |||
| /* draw original image */ | |||
| glRasterPos2i(APosX, 5); | |||
| PrintString("Original"); | |||
| glRasterPos2i(APosX, APosY); | |||
| glEnable(GL_DITHER); | |||
| SetupPixelTransfer(GL_FALSE); | |||
| glDrawPixels(ImgWidth, ImgHeight, ImgFormat, GL_UNSIGNED_BYTE, Image); | |||
| /* do readpixels, drawpixels */ | |||
| glRasterPos2i(BPosX, 5); | |||
| PrintString("Read/DrawPixels"); | |||
| SetupPixelTransfer(ScaleAndBias); | |||
| glReadPixels(APosX, APosY, ImgWidth, ImgHeight, | |||
| ImgFormat, GL_UNSIGNED_BYTE, TempImage); | |||
| glRasterPos2i(BPosX, BPosY); | |||
| glDisable(GL_DITHER); | |||
| SetupPixelTransfer(GL_FALSE); | |||
| glDrawPixels(ImgWidth, ImgHeight, ImgFormat, GL_UNSIGNED_BYTE, 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(); | |||
| } | |||
| 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': | |||
| ScaleAndBias = !ScaleAndBias; | |||
| break; | |||
| case 'f': | |||
| DrawFront = !DrawFront; | |||
| if (DrawFront) | |||
| glDrawBuffer(GL_FRONT); | |||
| else | |||
| glDrawBuffer(GL_BACK); | |||
| printf("glDrawBuffer(%s)\n", DrawFront ? "GL_FRONT" : "GL_BACK"); | |||
| break; | |||
| case 27: | |||
| exit(0); | |||
| break; | |||
| } | |||
| glutPostRedisplay(); | |||
| } | |||
| static void SpecialKey( int key, int x, int y ) | |||
| { | |||
| (void) x; | |||
| (void) y; | |||
| #if 0 | |||
| switch (key) { | |||
| case GLUT_KEY_UP: | |||
| Ypos += 1; | |||
| break; | |||
| case GLUT_KEY_DOWN: | |||
| Ypos -= 1; | |||
| break; | |||
| case GLUT_KEY_LEFT: | |||
| Xpos -= 1; | |||
| break; | |||
| case GLUT_KEY_RIGHT: | |||
| Xpos += 1; | |||
| break; | |||
| } | |||
| #endif | |||
| glutPostRedisplay(); | |||
| } | |||
| static void | |||
| Init( GLboolean ciMode ) | |||
| { | |||
| 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 = 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); | |||
| } | |||
| } | |||
| printf("Loaded %d by %d image\n", ImgWidth, ImgHeight ); | |||
| glPixelStorei(GL_UNPACK_ALIGNMENT, 1); | |||
| glPixelStorei(GL_UNPACK_ROW_LENGTH, ImgWidth); | |||
| glPixelStorei(GL_PACK_ALIGNMENT, 1); | |||
| glPixelStorei(GL_PACK_ROW_LENGTH, ImgWidth); | |||
| Reset(); | |||
| TempImage = (GLubyte *) malloc(ImgWidth * ImgHeight * 4 * sizeof(GLubyte)); | |||
| 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 ); | |||
| glutSpecialFunc( SpecialKey ); | |||
| glutDisplayFunc( Display ); | |||
| glutMainLoop(); | |||
| return 0; | |||
| } | |||