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