blendeq.c revision 32001f49
1/* 2** blendeq.c - Demonstrates the use of the blend_minmax, blend_subtract, 3** and blend_logic_op extensions using glBlendEquationEXT. 4** 5** Over a two-color backround, draw rectangles using twelve blend 6** options. The values are read back as UNSIGNED_BYTE and printed 7** in hex over each value. These values are useful for logic 8** op comparisons when channels are 8 bits deep. 9*/ 10 11#include <string.h> 12#include <stdlib.h> 13#include <stdio.h> 14#include <GL/glew.h> 15#include "glut_wrap.h" 16 17GLenum doubleBuffer; 18static int dithering = 0; 19int use11ops = 0; 20int supportlogops = 0; 21static int doPrint = 1; 22static int deltaY; 23GLint windW, windH; 24 25static const struct { 26 GLenum mode; 27 const char *name; 28} LogicOpModes[] = { 29 { GL_SET, "GL_SET" }, 30 { GL_COPY, "GL_COPY" }, 31 { GL_NOOP, "GL_NOOP" }, 32 { GL_AND, "GL_AND" }, 33 { GL_INVERT, "GL_INVERT" }, 34 { GL_OR, "GL_OR" }, 35 { GL_XOR, "GL_XOR" }, 36 { GL_NOR, "GL_NOR" }, 37 { GL_NAND, "GL_NAND" }, 38 { GL_OR_REVERSE, "GL_OR_REVERSE" }, 39 { GL_OR_INVERTED, "GL_OR_INVERTED" }, 40 { GL_AND_INVERTED, "GL_AND_INVERTED" }, 41 { 0, NULL } 42}; 43 44 45 46static void DrawString(const char *string) 47{ 48 int i; 49 50 for (i = 0; string[i]; i++) 51 glutBitmapCharacter(GLUT_BITMAP_9_BY_15, string[i]); 52} 53 54static void Init(void) 55{ 56 57 glDisable(GL_DITHER); 58 glShadeModel(GL_FLAT); 59} 60 61static void Reshape(int width, int height) 62{ 63 64 windW = (GLint)width; 65 windH = (GLint)height; 66 67 glViewport(0, 0, (GLint)width, (GLint)height); 68 deltaY = windH /20; 69 70 glMatrixMode(GL_PROJECTION); 71 glLoadIdentity(); 72 gluOrtho2D(0, windW, 0, windH); 73 glMatrixMode(GL_MODELVIEW); 74} 75 76static void Key(unsigned char key, int x, int y) 77{ 78 79 switch (key) { 80 case 27: 81 exit(1); 82 case 'd': 83 dithering = !dithering; 84 break; 85 case 'l': 86 if (supportlogops == 3) 87 use11ops = (!use11ops); 88 if (use11ops) 89 printf("Using GL 1.1 color logic ops.\n"); 90 else printf("Using GL_EXT_blend_logic_op.\n"); 91 break; 92 default: 93 return; 94 } 95 96 glutPostRedisplay(); 97} 98 99static void PrintColorStrings( void ) 100{ 101 GLubyte ubbuf[3]; 102 int i, xleft, xright; 103 char colorString[100]; 104 105 xleft = 5 + windW/4; 106 xright = 5 + windW/2; 107 108 for (i = windH - deltaY + 4; i > 0; i-=deltaY) { 109 glReadPixels(xleft, i+10, 1, 1, GL_RGB, GL_UNSIGNED_BYTE, ubbuf); 110 sprintf(colorString, "(0x%x, 0x%x, 0x%x)", 111 ubbuf[0], ubbuf[1], ubbuf[2]); 112 glRasterPos2f(xleft, i); 113 DrawString(colorString); 114 glReadPixels(xright, i+10, 1, 1, GL_RGB, GL_UNSIGNED_BYTE, ubbuf); 115 sprintf(colorString, "(0x%x, 0x%x, 0x%x)", 116 ubbuf[0], ubbuf[1], ubbuf[2]); 117 glRasterPos2f(xright, i); 118 DrawString(colorString); 119 } 120} 121 122static void Draw(void) 123{ 124 int stringOffset = 5, stringx = 8; 125 int x1, x2, xleft, xright; 126 int i, k; 127 128 (dithering) ? glEnable(GL_DITHER) : glDisable(GL_DITHER); 129 glDisable(GL_BLEND); 130 if (supportlogops & 2) 131 glDisable(GL_COLOR_LOGIC_OP); 132 133 glClearColor(0.5, 0.6, 0.1, 1.0); 134 glClear(GL_COLOR_BUFFER_BIT); 135 136 /* Draw background */ 137 glColor3f(0.1, 0.1, 1.0); 138 glRectf(0.0, 0.0, windW/2, windH); 139 140 /* Draw labels */ 141 glColor3f(0.8, 0.8, 0.0); 142 i = windH - deltaY + stringOffset; 143 144 glRasterPos2f(stringx, i); i -= deltaY; 145 DrawString("SOURCE"); 146 glRasterPos2f(stringx, i); i -= deltaY; 147 DrawString("DEST"); 148 glRasterPos2f(stringx, i); i -= deltaY; 149 DrawString("min"); 150 glRasterPos2f(stringx, i); i -= deltaY; 151 DrawString("max"); 152 glRasterPos2f(stringx, i); i -= deltaY; 153 DrawString("subtract"); 154 glRasterPos2f(stringx, i); i -= deltaY; 155 DrawString("reverse_subtract"); 156 glRasterPos2f(stringx, i); i -= deltaY; 157 DrawString("clear"); 158 159 for (k = 0; LogicOpModes[k].name; k++) { 160 glRasterPos2f(stringx, i); 161 i -= deltaY; 162 DrawString(LogicOpModes[k].name); 163 } 164 165 i = windH - deltaY; 166 x1 = windW/4; 167 x2 = 3 * windW/4; 168 xleft = 5 + windW/4; 169 xright = 5 + windW/2; 170 171 /* Draw foreground color for comparison */ 172 glColor3f(0.9, 0.2, 0.8); 173 glRectf(x1, i, x2, i+deltaY); 174 175 /* Leave one rectangle of background color */ 176 177 /* Begin test cases */ 178 glEnable(GL_BLEND); 179 glBlendFunc(GL_ONE, GL_ONE); 180 181 i -= 2*deltaY; 182 glBlendEquationEXT(GL_MIN_EXT); 183 glRectf(x1, i, x2, i+deltaY); 184 185 i -= deltaY; 186 glBlendEquationEXT(GL_MAX_EXT); 187 glRectf(x1, i, x2, i+deltaY); 188 189 i -= deltaY; 190 glBlendEquationEXT(GL_FUNC_SUBTRACT_EXT); 191 glRectf(x1, i, x2, i+deltaY); 192 193 i -= deltaY; 194 glBlendEquationEXT(GL_FUNC_REVERSE_SUBTRACT_EXT); 195 glRectf(x1, i, x2, i+deltaY); 196 197 glBlendFunc(GL_ONE, GL_ZERO); 198 i -= deltaY; 199 if (!use11ops) 200 glBlendEquationEXT(GL_LOGIC_OP); 201 else 202 glEnable(GL_COLOR_LOGIC_OP); 203 glLogicOp(GL_CLEAR); 204 glRectf(x1, i, x2, i+deltaY); 205 206 for (k = 0; LogicOpModes[k].name; k++) { 207 i -= deltaY; 208 glLogicOp(LogicOpModes[k].mode); 209 glRectf(x1, i, x2, i+deltaY); 210 if (LogicOpModes[k].mode == GL_XOR) { 211 glRectf(x1, i+10, x2, i+5); 212 } 213 } 214 215 if (doPrint) { 216 glDisable(GL_BLEND); 217 if (supportlogops & 2) 218 glDisable(GL_COLOR_LOGIC_OP); 219 glColor3f(1.0, 1.0, 1.0); 220 PrintColorStrings(); 221 } 222 glFlush(); 223 224 if (doubleBuffer) { 225 glutSwapBuffers(); 226 } 227 228} 229 230static GLenum Args(int argc, char **argv) 231{ 232 GLint i; 233 234 doubleBuffer = GL_FALSE; 235 236 for (i = 1; i < argc; i++) { 237 if (strcmp(argv[i], "-sb") == 0) { 238 doubleBuffer = GL_FALSE; 239 } else if (strcmp(argv[i], "-db") == 0) { 240 doubleBuffer = GL_TRUE; 241 } else { 242 printf("%s (Bad option).\n", argv[i]); 243 return GL_FALSE; 244 } 245 } 246 return GL_TRUE; 247} 248 249int main(int argc, char **argv) 250{ 251 GLenum type; 252 char *s; 253 char *extName1 = "GL_EXT_blend_logic_op"; 254 char *extName2 = "GL_EXT_blend_minmax"; 255 char *extName3 = "GL_EXT_blend_subtract"; 256 char *version; 257 258 glutInit(&argc, argv); 259 260 if (Args(argc, argv) == GL_FALSE) { 261 exit(1); 262 } 263 264 glutInitWindowPosition(0, 0); glutInitWindowSize( 800, 520); 265 266 type = GLUT_RGB; 267 type |= (doubleBuffer) ? GLUT_DOUBLE : GLUT_SINGLE; 268 glutInitDisplayMode(type); 269 270 if (glutCreateWindow("Blend Equation") == GL_FALSE) { 271 exit(1); 272 } 273 274 glewInit(); 275 276 /* Make sure blend_logic_op extension is there. */ 277 s = (char *) glGetString(GL_EXTENSIONS); 278 version = (char*) glGetString(GL_VERSION); 279 if (!s) 280 exit(1); 281 if (strstr(s,extName1)) { 282 supportlogops = 1; 283 use11ops = 0; 284 printf("blend_logic_op extension available.\n"); 285 } 286 if (strncmp(version,"1.1",3)>=0) { 287 supportlogops += 2; 288 use11ops = 1; 289 printf("1.1 color logic ops available.\n"); 290 } 291 if (supportlogops == 0) { 292 printf("Blend_logic_op extension and GL 1.1 not present.\n"); 293 exit(1); 294 } 295 if (strstr(s,extName2) == 0) { 296 printf("Blend_minmax extension is not present.\n"); 297 exit(1); 298 } 299 if (strstr(s,extName3) == 0) { 300 printf("Blend_subtract extension is not present.\n"); 301 exit(1); 302 } 303 304 Init(); 305 306 glutReshapeFunc(Reshape); 307 glutKeyboardFunc(Key); 308 glutDisplayFunc(Draw); 309 glutMainLoop(); 310 return 0; 311} 312