132001f49Smrg/** 232001f49Smrg * glCopyPixels test 332001f49Smrg * 432001f49Smrg * Brian Paul 532001f49Smrg * 14 Sep 2007 632001f49Smrg */ 732001f49Smrg 832001f49Smrg 932001f49Smrg#include <stdio.h> 1032001f49Smrg#include <stdlib.h> 1132001f49Smrg#include <string.h> 1232001f49Smrg#include <GL/glew.h> 1332001f49Smrg#include "glut_wrap.h" 1432001f49Smrg 1532001f49Smrg#include "readtex.h" 1632001f49Smrg 1732001f49Smrg#define IMAGE_FILE DEMOS_DATA_DIR "arch.rgb" 1832001f49Smrg 1932001f49Smrgstatic int ImgWidth, ImgHeight; 2032001f49Smrgstatic GLenum ImgFormat; 2132001f49Smrgstatic GLubyte *Image = NULL; 2232001f49Smrg 2332001f49Smrgstatic int WinWidth = 800, WinHeight = 800; 2432001f49Smrgstatic int Xpos, Ypos; 2532001f49Smrgstatic int Scissor = 0; 2632001f49Smrgstatic float Xzoom, Yzoom; 2732001f49Smrgstatic GLboolean DrawFront = GL_FALSE; 2832001f49Smrgstatic GLboolean Dither = GL_TRUE; 2932001f49Smrgstatic GLboolean Invert = GL_FALSE; 3032001f49Smrg 3132001f49Smrg 3232001f49Smrgstatic void Reset( void ) 3332001f49Smrg{ 3432001f49Smrg Xpos = Ypos = 20; 3532001f49Smrg Scissor = 0; 3632001f49Smrg Xzoom = Yzoom = 1.0; 3732001f49Smrg} 3832001f49Smrg 3932001f49Smrg 4032001f49Smrgstatic void Display( void ) 4132001f49Smrg{ 4232001f49Smrg const int dx = (WinWidth - ImgWidth) / 2; 4332001f49Smrg const int dy = (WinHeight - ImgHeight) / 2; 4432001f49Smrg 4532001f49Smrg if (DrawFront) { 4632001f49Smrg glDrawBuffer(GL_FRONT); 4732001f49Smrg glReadBuffer(GL_FRONT); 4832001f49Smrg } 4932001f49Smrg else { 5032001f49Smrg glDrawBuffer(GL_BACK); 5132001f49Smrg glReadBuffer(GL_BACK); 5232001f49Smrg } 5332001f49Smrg 5432001f49Smrg glClear( GL_COLOR_BUFFER_BIT ); 5532001f49Smrg 5632001f49Smrg /* draw original image */ 5732001f49Smrg glWindowPos2iARB(dx, dy); 5832001f49Smrg glDrawPixels(ImgWidth, ImgHeight, ImgFormat, GL_UNSIGNED_BYTE, Image); 5932001f49Smrg 6032001f49Smrg if (Scissor) 6132001f49Smrg glEnable(GL_SCISSOR_TEST); 6232001f49Smrg 6332001f49Smrg if (Invert) { 6432001f49Smrg glPixelTransferf(GL_RED_SCALE, -1.0); 6532001f49Smrg glPixelTransferf(GL_GREEN_SCALE, -1.0); 6632001f49Smrg glPixelTransferf(GL_BLUE_SCALE, -1.0); 6732001f49Smrg glPixelTransferf(GL_RED_BIAS, 1.0); 6832001f49Smrg glPixelTransferf(GL_GREEN_BIAS, 1.0); 6932001f49Smrg glPixelTransferf(GL_BLUE_BIAS, 1.0); 7032001f49Smrg } 7132001f49Smrg 7232001f49Smrg /* draw copy */ 7332001f49Smrg glPixelZoom(Xzoom, Yzoom); 7432001f49Smrg glWindowPos2iARB(Xpos, Ypos); 7532001f49Smrg glCopyPixels(dx, dy, ImgWidth, ImgHeight, GL_COLOR); 7632001f49Smrg glPixelZoom(1, 1); 7732001f49Smrg 7832001f49Smrg glDisable(GL_SCISSOR_TEST); 7932001f49Smrg 8032001f49Smrg if (Invert) { 8132001f49Smrg glPixelTransferf(GL_RED_SCALE, 1.0); 8232001f49Smrg glPixelTransferf(GL_GREEN_SCALE, 1.0); 8332001f49Smrg glPixelTransferf(GL_BLUE_SCALE, 1.0); 8432001f49Smrg glPixelTransferf(GL_RED_BIAS, 0.0); 8532001f49Smrg glPixelTransferf(GL_GREEN_BIAS, 0.0); 8632001f49Smrg glPixelTransferf(GL_BLUE_BIAS, 0.0); 8732001f49Smrg } 8832001f49Smrg 8932001f49Smrg if (DrawFront) 9032001f49Smrg glFinish(); 9132001f49Smrg else 9232001f49Smrg glutSwapBuffers(); 9332001f49Smrg} 9432001f49Smrg 9532001f49Smrg 9632001f49Smrgstatic void Reshape( int width, int height ) 9732001f49Smrg{ 9832001f49Smrg WinWidth = width; 9932001f49Smrg WinHeight = height; 10032001f49Smrg 10132001f49Smrg glViewport( 0, 0, width, height ); 10232001f49Smrg glMatrixMode( GL_PROJECTION ); 10332001f49Smrg glLoadIdentity(); 10432001f49Smrg glOrtho( 0.0, width, 0.0, height, 0.0, 2.0 ); 10532001f49Smrg glMatrixMode( GL_MODELVIEW ); 10632001f49Smrg glLoadIdentity(); 10732001f49Smrg 10832001f49Smrg glScissor(width/4, height/4, width/2, height/2); 10932001f49Smrg} 11032001f49Smrg 11132001f49Smrg 11232001f49Smrgstatic void Key( unsigned char key, int x, int y ) 11332001f49Smrg{ 11432001f49Smrg (void) x; 11532001f49Smrg (void) y; 11632001f49Smrg switch (key) { 11732001f49Smrg case ' ': 11832001f49Smrg Reset(); 11932001f49Smrg break; 12032001f49Smrg case 'd': 12132001f49Smrg Dither = !Dither; 12232001f49Smrg if (Dither) 12332001f49Smrg glEnable(GL_DITHER); 12432001f49Smrg else 12532001f49Smrg glDisable(GL_DITHER); 12632001f49Smrg break; 12732001f49Smrg case 'i': 12832001f49Smrg Invert = !Invert; 12932001f49Smrg break; 13032001f49Smrg case 's': 13132001f49Smrg Scissor = !Scissor; 13232001f49Smrg break; 13332001f49Smrg case 'x': 13432001f49Smrg Xzoom -= 0.1; 13532001f49Smrg break; 13632001f49Smrg case 'X': 13732001f49Smrg Xzoom += 0.1; 13832001f49Smrg break; 13932001f49Smrg case 'y': 14032001f49Smrg Yzoom -= 0.1; 14132001f49Smrg break; 14232001f49Smrg case 'Y': 14332001f49Smrg Yzoom += 0.1; 14432001f49Smrg break; 14532001f49Smrg case 'f': 14632001f49Smrg DrawFront = !DrawFront; 14732001f49Smrg printf("glDrawBuffer(%s)\n", DrawFront ? "GL_FRONT" : "GL_BACK"); 14832001f49Smrg break; 14932001f49Smrg case 27: 15032001f49Smrg exit(0); 15132001f49Smrg break; 15232001f49Smrg } 15332001f49Smrg glutPostRedisplay(); 15432001f49Smrg} 15532001f49Smrg 15632001f49Smrg 15732001f49Smrgstatic void SpecialKey( int key, int x, int y ) 15832001f49Smrg{ 15932001f49Smrg const int step = (glutGetModifiers() & GLUT_ACTIVE_SHIFT) ? 10 : 1; 16032001f49Smrg (void) x; 16132001f49Smrg (void) y; 16232001f49Smrg switch (key) { 16332001f49Smrg case GLUT_KEY_UP: 16432001f49Smrg Ypos += step; 16532001f49Smrg break; 16632001f49Smrg case GLUT_KEY_DOWN: 16732001f49Smrg Ypos -= step; 16832001f49Smrg break; 16932001f49Smrg case GLUT_KEY_LEFT: 17032001f49Smrg Xpos -= step; 17132001f49Smrg break; 17232001f49Smrg case GLUT_KEY_RIGHT: 17332001f49Smrg Xpos += step; 17432001f49Smrg break; 17532001f49Smrg } 17632001f49Smrg glutPostRedisplay(); 17732001f49Smrg} 17832001f49Smrg 17932001f49Smrg 18032001f49Smrgstatic void Init( GLboolean ciMode, const char *filename ) 18132001f49Smrg{ 18232001f49Smrg printf("GL_VERSION = %s\n", (char *) glGetString(GL_VERSION)); 18332001f49Smrg printf("GL_RENDERER = %s\n", (char *) glGetString(GL_RENDERER)); 18432001f49Smrg 18532001f49Smrg Image = LoadRGBImage( filename, &ImgWidth, &ImgHeight, &ImgFormat ); 18632001f49Smrg if (!Image) { 18732001f49Smrg printf("Couldn't read %s\n", filename); 18832001f49Smrg exit(0); 18932001f49Smrg } 19032001f49Smrg 19132001f49Smrg if (ciMode) { 19232001f49Smrg /* Convert RGB image to grayscale */ 19332001f49Smrg GLubyte *indexImage = (GLubyte *) malloc( ImgWidth * ImgHeight ); 19432001f49Smrg GLint i; 19532001f49Smrg for (i=0; i<ImgWidth*ImgHeight; i++) { 19632001f49Smrg int gray = Image[i*3] + Image[i*3+1] + Image[i*3+2]; 19732001f49Smrg indexImage[i] = gray / 3; 19832001f49Smrg } 19932001f49Smrg free(Image); 20032001f49Smrg Image = indexImage; 20132001f49Smrg ImgFormat = GL_COLOR_INDEX; 20232001f49Smrg 20332001f49Smrg for (i=0;i<255;i++) { 20432001f49Smrg float g = i / 255.0; 20532001f49Smrg glutSetColor(i, g, g, g); 20632001f49Smrg } 20732001f49Smrg } 20832001f49Smrg 20932001f49Smrg printf("Loaded %d by %d image\n", ImgWidth, ImgHeight ); 21032001f49Smrg 21132001f49Smrg glPixelStorei(GL_UNPACK_ALIGNMENT, 1); 21232001f49Smrg glPixelStorei(GL_UNPACK_ROW_LENGTH, ImgWidth); 21332001f49Smrg 21432001f49Smrg Reset(); 21532001f49Smrg} 21632001f49Smrg 21732001f49Smrg 21832001f49Smrgstatic void Usage(void) 21932001f49Smrg{ 22032001f49Smrg printf("Keys:\n"); 22132001f49Smrg printf(" SPACE Reset Parameters\n"); 22232001f49Smrg printf(" Up/Down Move image up/down (SHIFT for large step)\n"); 22332001f49Smrg printf(" Left/Right Move image left/right (SHIFT for large step)\n"); 22432001f49Smrg printf(" x Decrease X-axis PixelZoom\n"); 22532001f49Smrg printf(" X Increase X-axis PixelZoom\n"); 22632001f49Smrg printf(" y Decrease Y-axis PixelZoom\n"); 22732001f49Smrg printf(" Y Increase Y-axis PixelZoom\n"); 22832001f49Smrg printf(" s Toggle GL_SCISSOR_TEST\n"); 22932001f49Smrg printf(" f Toggle front/back buffer drawing\n"); 23032001f49Smrg printf(" ESC Exit\n"); 23132001f49Smrg} 23232001f49Smrg 23332001f49Smrg 23432001f49Smrgint main( int argc, char *argv[] ) 23532001f49Smrg{ 23632001f49Smrg GLboolean ciMode = GL_FALSE; 23732001f49Smrg const char *filename = IMAGE_FILE; 23832001f49Smrg int i = 1; 23932001f49Smrg 24032001f49Smrg glutInitWindowSize( WinWidth, WinHeight ); 24132001f49Smrg glutInit( &argc, argv ); 24232001f49Smrg 24332001f49Smrg if (argc > i && strcmp(argv[i], "-ci")==0) { 24432001f49Smrg ciMode = GL_TRUE; 24532001f49Smrg i++; 24632001f49Smrg } 24732001f49Smrg if (argc > i) { 24832001f49Smrg filename = argv[i]; 24932001f49Smrg } 25032001f49Smrg 25132001f49Smrg if (ciMode) 25232001f49Smrg glutInitDisplayMode( GLUT_INDEX | GLUT_DOUBLE ); 25332001f49Smrg else 25432001f49Smrg glutInitDisplayMode( GLUT_RGB | GLUT_DOUBLE); 25532001f49Smrg 25632001f49Smrg glutCreateWindow(argv[0]); 25732001f49Smrg glewInit(); 25832001f49Smrg 25932001f49Smrg Init(ciMode, filename); 26032001f49Smrg Usage(); 26132001f49Smrg 26232001f49Smrg glutReshapeFunc( Reshape ); 26332001f49Smrg glutKeyboardFunc( Key ); 26432001f49Smrg glutSpecialFunc( SpecialKey ); 26532001f49Smrg glutDisplayFunc( Display ); 26632001f49Smrg 26732001f49Smrg glutMainLoop(); 26832001f49Smrg return 0; 26932001f49Smrg} 270