1/** 2 * Test XOR emulation with blending. 3 * 4 */ 5 6#include <stdio.h> 7#include <stdlib.h> 8#include <math.h> 9#include <GL/glew.h> 10#include "glut_wrap.h" 11#include "readtex.c" 12 13#define IMAGE_FILE DEMOS_DATA_DIR "arch.rgb" 14 15static int ImgWidth, ImgHeight; 16static GLenum ImgFormat; 17static GLubyte *Image = NULL; 18 19static int Win; 20static int Width = 600, Height = 600; 21 22struct rect 23{ 24 int x0, y0, x1, y1; 25}; 26 27static struct rect OldRect, NewRect; 28 29static GLboolean ButtonDown = GL_FALSE; 30static GLboolean LogicOp = 0*GL_TRUE; 31 32 33static const GLfloat red[4] = {1.0, 0.2, 0.2, 1.0}; 34static const GLfloat green[4] = {0.2, 1.0, 0.2, 1.0}; 35static const GLfloat blue[4] = {0.2, 0.2, 1.0, 1.0}; 36 37 38static void 39PrintString(const char *s) 40{ 41 while (*s) { 42 glutBitmapCharacter(GLUT_BITMAP_8_BY_13, (int) *s); 43 s++; 44 } 45} 46 47 48static void 49Draw(void) 50{ 51 glClear(GL_COLOR_BUFFER_BIT); 52 53 glWindowPos2i((Width - ImgWidth) / 2, (Height - ImgHeight) / 2); 54 glDrawPixels(ImgWidth, ImgHeight, ImgFormat, GL_UNSIGNED_BYTE, Image); 55 56 /* 57 * Draw 2D XOR rects 58 */ 59 glColor3f(1, 1, 1); 60 61 glWindowPos2i(100, Height - 20); 62 PrintString("XOR LogicOp:"); 63 glLogicOp(GL_XOR); 64 glEnable(GL_COLOR_LOGIC_OP); 65 glRecti(100, 30, 250, Height - 30); 66 glDisable(GL_COLOR_LOGIC_OP); 67 68 glWindowPos2i(Width/2 + 10, Height - 20); 69 PrintString("Invert Blending:"); 70 glBlendFunc(GL_ONE, GL_ONE); 71 glBlendEquation(GL_FUNC_SUBTRACT); 72 glEnable(GL_BLEND); 73 glRecti(Width / 2, 30, Width / 2 + 150, Height - 30); 74 glDisable(GL_BLEND); 75 76 glutSwapBuffers(); 77} 78 79 80static void 81Reshape(int width, int height) 82{ 83 Width = width; 84 Height = height; 85 glViewport(0, 0, width, height); 86 glMatrixMode(GL_PROJECTION); 87 glLoadIdentity(); 88 glOrtho(0, Width, 0, Height, -1, 1); 89 glMatrixMode(GL_MODELVIEW); 90 glLoadIdentity(); 91} 92 93 94static void 95Key(unsigned char key, int x, int y) 96{ 97 (void) x; 98 (void) y; 99 switch (key) { 100 case 'b': 101 case 'B': 102 LogicOp = GL_FALSE; 103 break; 104 case 'l': 105 case 'L': 106 LogicOp = GL_TRUE; 107 break; 108 case 27: 109 glutDestroyWindow(Win); 110 exit(0); 111 break; 112 } 113 glutPostRedisplay(); 114} 115 116 117static void 118SpecialKey(int key, int x, int y) 119{ 120 (void) x; 121 (void) y; 122 switch (key) { 123 case GLUT_KEY_UP: 124 break; 125 case GLUT_KEY_DOWN: 126 break; 127 case GLUT_KEY_LEFT: 128 break; 129 case GLUT_KEY_RIGHT: 130 break; 131 } 132 glutPostRedisplay(); 133} 134 135 136static void 137MouseMotion(int x, int y) 138{ 139 if (ButtonDown) { 140 NewRect.x1 = x; 141 NewRect.y1 = y; 142 glutPostRedisplay(); 143 } 144} 145 146 147static void 148MouseButton(int button, int state, int x, int y) 149{ 150 if (button == GLUT_LEFT_BUTTON && state == GLUT_DOWN) { 151 ButtonDown = GL_TRUE; 152 NewRect.x0 = NewRect.x1 = x; 153 NewRect.y0 = NewRect.y1 = y; 154 OldRect = NewRect; 155 } 156 else if (button == GLUT_LEFT_BUTTON && state == GLUT_UP) { 157 ButtonDown = GL_FALSE; 158 } 159} 160 161 162static void 163Init(void) 164{ 165 /* 166 * Load image and scale if needed. 167 */ 168 Image = LoadRGBImage(IMAGE_FILE, &ImgWidth, &ImgHeight, &ImgFormat); 169 if (!Image) { 170 printf("Couldn't read %s\n", IMAGE_FILE); 171 exit(0); 172 } 173 174 glPixelStorei(GL_UNPACK_ALIGNMENT, 1); 175 glPixelStorei(GL_PACK_ALIGNMENT, 1); 176} 177 178 179int 180main(int argc, char *argv[]) 181{ 182 glutInit(&argc, argv); 183 glutInitWindowSize(Width, Height); 184 glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE); 185 Win = glutCreateWindow(argv[0]); 186 glewInit(); 187 glutReshapeFunc(Reshape); 188 glutKeyboardFunc(Key); 189 glutSpecialFunc(SpecialKey); 190 glutMotionFunc(MouseMotion); 191 glutMouseFunc(MouseButton); 192 glutDisplayFunc(Draw); 193 Init(); 194 glutPostRedisplay(); 195 glutMainLoop(); 196 return 0; 197} 198