rubberband.c revision 7ec3b29a
1/** 2 * Test rubber-band selection box w/ logicops and blend. 3 */ 4 5#include <stdio.h> 6#include <stdlib.h> 7#include <math.h> 8#include <GL/glew.h> 9#include "glut_wrap.h" 10#include "readtex.c" 11 12#define IMAGE_FILE DEMOS_DATA_DIR "arch.rgb" 13 14static int ImgWidth, ImgHeight; 15static GLenum ImgFormat; 16static GLubyte *Image = NULL; 17 18static int Win; 19static int Width = 512, Height = 512; 20 21struct rect 22{ 23 int x0, y0, x1, y1; 24}; 25 26static struct rect OldRect, NewRect; 27 28static GLboolean ButtonDown = GL_FALSE; 29static GLboolean LogicOp = GL_TRUE; 30 31static GLboolean RedrawBackground = GL_TRUE; 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 37static int color = 0; 38 39 40/* 41 * Draw rubberband box in front buffer 42 */ 43static void 44DrawRect(const struct rect *r) 45{ 46 glDrawBuffer(GL_FRONT); 47 48 if (LogicOp) { 49 glLogicOp(GL_XOR); 50 glEnable(GL_COLOR_LOGIC_OP); 51 52 if (color == 0) 53 glColor3f(1, 1, 1); 54 else 55 glColor3ub(152, 105, 58); 56 } 57 else { 58 glEnable(GL_BLEND); 59 glBlendFunc(GL_ONE, GL_ONE); 60 glBlendEquation(GL_FUNC_SUBTRACT); 61 glColor3f(1, 1, 1); 62 } 63 64 glBegin(GL_LINE_LOOP); 65 glVertex2i(r->x0, r->y0); 66 glVertex2i(r->x1, r->y0); 67 glVertex2i(r->x1, r->y1); 68 glVertex2i(r->x0, r->y1); 69 glEnd(); 70 71 glDisable(GL_COLOR_LOGIC_OP); 72 glDisable(GL_BLEND); 73 74 /* Need this to ensure the front buffer drawing is actually displayed */ 75 glFlush(); 76 77 glDrawBuffer(GL_BACK); 78} 79 80 81static void 82PrintString(const char *s) 83{ 84 while (*s) { 85 glutBitmapCharacter(GLUT_BITMAP_8_BY_13, (int) *s); 86 s++; 87 } 88} 89 90 91static void 92DrawBackground(void) 93{ 94 char s[100]; 95 96 sprintf(s, "[L/B] %s mode. Use mouse to make selection box.", 97 LogicOp ? "LogicOp" : "Blend"); 98 99 glClear(GL_COLOR_BUFFER_BIT); 100 101 glWindowPos2i((Width - ImgWidth) / 2, (Height - ImgHeight) / 2); 102 glDrawPixels(ImgWidth, ImgHeight, ImgFormat, GL_UNSIGNED_BYTE, Image); 103 104 glColor3f(1, 1, 1); 105 glWindowPos2i(10, 10); 106 PrintString(s); 107 108 glutSwapBuffers(); 109} 110 111 112static void 113Draw(void) 114{ 115 if (RedrawBackground) { 116 DrawBackground(); 117 } 118 119 if (ButtonDown) { 120 if (!RedrawBackground) 121 DrawRect(&OldRect); /* erase old */ 122 123 DrawRect(&NewRect); /* draw new */ 124 125 OldRect = NewRect; 126 } 127 128 RedrawBackground = GL_FALSE; 129} 130 131 132static void 133Reshape(int width, int height) 134{ 135 Width = width; 136 Height = height; 137 138 glViewport(0, 0, width, height); 139 140 glMatrixMode(GL_PROJECTION); 141 glLoadIdentity(); 142 glOrtho(0, Width, Height, 0, -1, 1); /* Inverted Y! */ 143 144 glMatrixMode(GL_MODELVIEW); 145 glLoadIdentity(); 146 147 RedrawBackground = GL_TRUE; 148} 149 150 151static void 152Key(unsigned char key, int x, int y) 153{ 154 (void) x; 155 (void) y; 156 switch (key) { 157 case '1': 158 glLineWidth(1); 159 break; 160 case '2': 161 glLineWidth(2); 162 break; 163 case '3': 164 glLineWidth(3); 165 break; 166 case '4': 167 glLineWidth(4); 168 break; 169 case 'b': 170 case 'B': 171 LogicOp = GL_FALSE; 172 break; 173 case 'c': 174 case 'C': 175 color = !color; 176 printf("using color %d\n", color); 177 fflush(stdout); 178 break; 179 case 'l': 180 case 'L': 181 LogicOp = GL_TRUE; 182 break; 183 case 27: 184 glutDestroyWindow(Win); 185 exit(0); 186 break; 187 } 188 RedrawBackground = GL_TRUE; 189 glutPostRedisplay(); 190} 191 192 193static void 194SpecialKey(int key, int x, int y) 195{ 196 (void) x; 197 (void) y; 198 switch (key) { 199 case GLUT_KEY_UP: 200 break; 201 case GLUT_KEY_DOWN: 202 break; 203 case GLUT_KEY_LEFT: 204 break; 205 case GLUT_KEY_RIGHT: 206 break; 207 } 208 glutPostRedisplay(); 209} 210 211 212static void 213MouseMotion(int x, int y) 214{ 215 if (ButtonDown) { 216 NewRect.x1 = x; 217 NewRect.y1 = y; 218 glutPostRedisplay(); 219 } 220} 221 222 223static void 224MouseButton(int button, int state, int x, int y) 225{ 226 if (button == GLUT_LEFT_BUTTON && state == GLUT_DOWN) { 227 ButtonDown = GL_TRUE; 228 RedrawBackground = GL_TRUE; 229 NewRect.x0 = NewRect.x1 = x; 230 NewRect.y0 = NewRect.y1 = y; 231 OldRect = NewRect; 232 } 233 else if (button == GLUT_LEFT_BUTTON && state == GLUT_UP) { 234 ButtonDown = GL_FALSE; 235 } 236 glutPostRedisplay(); 237} 238 239 240static void 241Init(void) 242{ 243 Image = LoadRGBImage(IMAGE_FILE, &ImgWidth, &ImgHeight, &ImgFormat); 244 if (!Image) { 245 printf("Couldn't read %s\n", IMAGE_FILE); 246 exit(0); 247 } 248 249 glPixelStorei(GL_UNPACK_ALIGNMENT, 1); 250 glPixelStorei(GL_PACK_ALIGNMENT, 1); 251 glLineWidth(3); 252} 253 254 255int 256main(int argc, char *argv[]) 257{ 258 glutInit(&argc, argv); 259 glutInitWindowSize(Width, Height); 260 glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE); 261 Win = glutCreateWindow(argv[0]); 262 glewInit(); 263 glutReshapeFunc(Reshape); 264 glutKeyboardFunc(Key); 265 glutSpecialFunc(SpecialKey); 266 glutMotionFunc(MouseMotion); 267 glutMouseFunc(MouseButton); 268 glutDisplayFunc(Draw); 269 Init(); 270 glutPostRedisplay(); 271 glutMainLoop(); 272 return 0; 273} 274