copypix.c revision 32001f49
1/** 2 * glCopyPixels test 3 * 4 * Brian Paul 5 * 14 Sep 2007 6 */ 7 8 9#include <stdio.h> 10#include <stdlib.h> 11#include <string.h> 12#include <GL/glew.h> 13#include "glut_wrap.h" 14 15#include "readtex.h" 16 17#define IMAGE_FILE DEMOS_DATA_DIR "arch.rgb" 18 19static int ImgWidth, ImgHeight; 20static GLenum ImgFormat; 21static GLubyte *Image = NULL; 22 23static int WinWidth = 800, WinHeight = 800; 24static int Xpos, Ypos; 25static int Scissor = 0; 26static float Xzoom, Yzoom; 27static GLboolean DrawFront = GL_FALSE; 28static GLboolean Dither = GL_TRUE; 29static GLboolean Invert = GL_FALSE; 30 31 32static void Reset( void ) 33{ 34 Xpos = Ypos = 20; 35 Scissor = 0; 36 Xzoom = Yzoom = 1.0; 37} 38 39 40static void Display( void ) 41{ 42 const int dx = (WinWidth - ImgWidth) / 2; 43 const int dy = (WinHeight - ImgHeight) / 2; 44 45 if (DrawFront) { 46 glDrawBuffer(GL_FRONT); 47 glReadBuffer(GL_FRONT); 48 } 49 else { 50 glDrawBuffer(GL_BACK); 51 glReadBuffer(GL_BACK); 52 } 53 54 glClear( GL_COLOR_BUFFER_BIT ); 55 56 /* draw original image */ 57 glWindowPos2iARB(dx, dy); 58 glDrawPixels(ImgWidth, ImgHeight, ImgFormat, GL_UNSIGNED_BYTE, Image); 59 60 if (Scissor) 61 glEnable(GL_SCISSOR_TEST); 62 63 if (Invert) { 64 glPixelTransferf(GL_RED_SCALE, -1.0); 65 glPixelTransferf(GL_GREEN_SCALE, -1.0); 66 glPixelTransferf(GL_BLUE_SCALE, -1.0); 67 glPixelTransferf(GL_RED_BIAS, 1.0); 68 glPixelTransferf(GL_GREEN_BIAS, 1.0); 69 glPixelTransferf(GL_BLUE_BIAS, 1.0); 70 } 71 72 /* draw copy */ 73 glPixelZoom(Xzoom, Yzoom); 74 glWindowPos2iARB(Xpos, Ypos); 75 glCopyPixels(dx, dy, ImgWidth, ImgHeight, GL_COLOR); 76 glPixelZoom(1, 1); 77 78 glDisable(GL_SCISSOR_TEST); 79 80 if (Invert) { 81 glPixelTransferf(GL_RED_SCALE, 1.0); 82 glPixelTransferf(GL_GREEN_SCALE, 1.0); 83 glPixelTransferf(GL_BLUE_SCALE, 1.0); 84 glPixelTransferf(GL_RED_BIAS, 0.0); 85 glPixelTransferf(GL_GREEN_BIAS, 0.0); 86 glPixelTransferf(GL_BLUE_BIAS, 0.0); 87 } 88 89 if (DrawFront) 90 glFinish(); 91 else 92 glutSwapBuffers(); 93} 94 95 96static void Reshape( int width, int height ) 97{ 98 WinWidth = width; 99 WinHeight = height; 100 101 glViewport( 0, 0, width, height ); 102 glMatrixMode( GL_PROJECTION ); 103 glLoadIdentity(); 104 glOrtho( 0.0, width, 0.0, height, 0.0, 2.0 ); 105 glMatrixMode( GL_MODELVIEW ); 106 glLoadIdentity(); 107 108 glScissor(width/4, height/4, width/2, height/2); 109} 110 111 112static void Key( unsigned char key, int x, int y ) 113{ 114 (void) x; 115 (void) y; 116 switch (key) { 117 case ' ': 118 Reset(); 119 break; 120 case 'd': 121 Dither = !Dither; 122 if (Dither) 123 glEnable(GL_DITHER); 124 else 125 glDisable(GL_DITHER); 126 break; 127 case 'i': 128 Invert = !Invert; 129 break; 130 case 's': 131 Scissor = !Scissor; 132 break; 133 case 'x': 134 Xzoom -= 0.1; 135 break; 136 case 'X': 137 Xzoom += 0.1; 138 break; 139 case 'y': 140 Yzoom -= 0.1; 141 break; 142 case 'Y': 143 Yzoom += 0.1; 144 break; 145 case 'f': 146 DrawFront = !DrawFront; 147 printf("glDrawBuffer(%s)\n", DrawFront ? "GL_FRONT" : "GL_BACK"); 148 break; 149 case 27: 150 exit(0); 151 break; 152 } 153 glutPostRedisplay(); 154} 155 156 157static void SpecialKey( int key, int x, int y ) 158{ 159 const int step = (glutGetModifiers() & GLUT_ACTIVE_SHIFT) ? 10 : 1; 160 (void) x; 161 (void) y; 162 switch (key) { 163 case GLUT_KEY_UP: 164 Ypos += step; 165 break; 166 case GLUT_KEY_DOWN: 167 Ypos -= step; 168 break; 169 case GLUT_KEY_LEFT: 170 Xpos -= step; 171 break; 172 case GLUT_KEY_RIGHT: 173 Xpos += step; 174 break; 175 } 176 glutPostRedisplay(); 177} 178 179 180static void Init( GLboolean ciMode, const char *filename ) 181{ 182 printf("GL_VERSION = %s\n", (char *) glGetString(GL_VERSION)); 183 printf("GL_RENDERER = %s\n", (char *) glGetString(GL_RENDERER)); 184 185 Image = LoadRGBImage( filename, &ImgWidth, &ImgHeight, &ImgFormat ); 186 if (!Image) { 187 printf("Couldn't read %s\n", filename); 188 exit(0); 189 } 190 191 if (ciMode) { 192 /* Convert RGB image to grayscale */ 193 GLubyte *indexImage = (GLubyte *) malloc( ImgWidth * ImgHeight ); 194 GLint i; 195 for (i=0; i<ImgWidth*ImgHeight; i++) { 196 int gray = Image[i*3] + Image[i*3+1] + Image[i*3+2]; 197 indexImage[i] = gray / 3; 198 } 199 free(Image); 200 Image = indexImage; 201 ImgFormat = GL_COLOR_INDEX; 202 203 for (i=0;i<255;i++) { 204 float g = i / 255.0; 205 glutSetColor(i, g, g, g); 206 } 207 } 208 209 printf("Loaded %d by %d image\n", ImgWidth, ImgHeight ); 210 211 glPixelStorei(GL_UNPACK_ALIGNMENT, 1); 212 glPixelStorei(GL_UNPACK_ROW_LENGTH, ImgWidth); 213 214 Reset(); 215} 216 217 218static void Usage(void) 219{ 220 printf("Keys:\n"); 221 printf(" SPACE Reset Parameters\n"); 222 printf(" Up/Down Move image up/down (SHIFT for large step)\n"); 223 printf(" Left/Right Move image left/right (SHIFT for large step)\n"); 224 printf(" x Decrease X-axis PixelZoom\n"); 225 printf(" X Increase X-axis PixelZoom\n"); 226 printf(" y Decrease Y-axis PixelZoom\n"); 227 printf(" Y Increase Y-axis PixelZoom\n"); 228 printf(" s Toggle GL_SCISSOR_TEST\n"); 229 printf(" f Toggle front/back buffer drawing\n"); 230 printf(" ESC Exit\n"); 231} 232 233 234int main( int argc, char *argv[] ) 235{ 236 GLboolean ciMode = GL_FALSE; 237 const char *filename = IMAGE_FILE; 238 int i = 1; 239 240 glutInitWindowSize( WinWidth, WinHeight ); 241 glutInit( &argc, argv ); 242 243 if (argc > i && strcmp(argv[i], "-ci")==0) { 244 ciMode = GL_TRUE; 245 i++; 246 } 247 if (argc > i) { 248 filename = argv[i]; 249 } 250 251 if (ciMode) 252 glutInitDisplayMode( GLUT_INDEX | GLUT_DOUBLE ); 253 else 254 glutInitDisplayMode( GLUT_RGB | GLUT_DOUBLE); 255 256 glutCreateWindow(argv[0]); 257 glewInit(); 258 259 Init(ciMode, filename); 260 Usage(); 261 262 glutReshapeFunc( Reshape ); 263 glutKeyboardFunc( Key ); 264 glutSpecialFunc( SpecialKey ); 265 glutDisplayFunc( Display ); 266 267 glutMainLoop(); 268 return 0; 269} 270