1/* 2** blendxor.c - Demonstrates the use of the blend_logic_op 3** extension to draw hilights. Using XOR to draw the same 4** image twice restores the background to its original value. 5*/ 6 7#include <stdio.h> 8#include <string.h> 9#ifndef _WIN32 10#include <unistd.h> 11#endif 12#include <stdlib.h> 13#include <GL/glew.h> 14#include "glut_wrap.h" 15 16 17GLenum doubleBuffer; 18int dithering = 0; 19int use11ops = 0; 20int supportlogops = 0; 21GLint windW, windH; 22 23static void Init(void) 24{ 25 glDisable(GL_DITHER); 26 glShadeModel(GL_FLAT); 27} 28 29static void Reshape(int width, int height) 30{ 31 32 windW = (GLint)width; 33 windH = (GLint)height; 34 35 glViewport(0, 0, (GLint)width, (GLint)height); 36 37 glMatrixMode(GL_PROJECTION); 38 glLoadIdentity(); 39 gluOrtho2D(0, 400, 0, 400); 40 glMatrixMode(GL_MODELVIEW); 41} 42 43static void Key(unsigned char key, int x, int y) 44{ 45 46 switch (key) { 47 case 27: 48 exit(1); 49 case 'd': 50 dithering = !dithering; 51 break; 52 case 'l': 53 if (supportlogops == 3) 54 use11ops = (!use11ops); 55 if (use11ops) 56 printf("Using GL 1.1 color logic ops.\n"); 57 else printf("Using GL_EXT_blend_logic_op.\n"); 58 break; 59 default: 60 return; 61 } 62 63 glutPostRedisplay(); 64} 65 66static void Draw(void) 67{ 68 int i; 69 70 glDisable(GL_BLEND); 71 if (supportlogops & 2) 72 glDisable(GL_COLOR_LOGIC_OP); 73 74 (dithering) ? glEnable(GL_DITHER) : glDisable(GL_DITHER); 75 76 glClearColor(0.5, 0.6, 0.1, 1.0); 77 glClear(GL_COLOR_BUFFER_BIT); 78 79 /* Draw background prims */ 80 glColor3f(0.1, 0.1, 1.0); 81 glBegin(GL_TRIANGLES); 82 glVertex2i(5, 5); 83 glVertex2i(130, 50); 84 glVertex2i(100, 300); 85 glEnd(); 86 glColor3f(0.5, 0.2, 0.9); 87 glBegin(GL_TRIANGLES); 88 glVertex2i(200, 100); 89 glVertex2i(330, 50); 90 glVertex2i(340, 400); 91 glEnd(); 92 93 glEnable(GL_BLEND); 94 if (!use11ops) 95 glBlendEquationEXT(GL_LOGIC_OP); 96 else 97 glEnable(GL_COLOR_LOGIC_OP); 98 glLogicOp(GL_XOR); 99 100 /* Draw a set of rectangles across the window */ 101 glColor3f(0.9, 0.2, 0.8); 102 for(i = 0; i < 400; i+=60) { 103 glBegin(GL_POLYGON); 104 glVertex2i(i, 100); 105 glVertex2i(i+50, 100); 106 glVertex2i(i+50, 200); 107 glVertex2i(i, 200); 108 glEnd(); 109 } 110 glFlush(); /* Added by Brian Paul */ 111#ifndef _WIN32 112 sleep(2); 113#endif 114 115 /* Redraw the rectangles, which should erase them */ 116 for(i = 0; i < 400; i+=60) { 117 glBegin(GL_POLYGON); 118 glVertex2i(i, 100); 119 glVertex2i(i+50, 100); 120 glVertex2i(i+50, 200); 121 glVertex2i(i, 200); 122 glEnd(); 123 } 124 glFlush(); 125 126 127 if (doubleBuffer) { 128 glutSwapBuffers(); 129 } 130} 131 132static GLenum Args(int argc, char **argv) 133{ 134 GLint i; 135 136 doubleBuffer = GL_FALSE; 137 138 for (i = 1; i < argc; i++) { 139 if (strcmp(argv[i], "-sb") == 0) { 140 doubleBuffer = GL_FALSE; 141 } else if (strcmp(argv[i], "-db") == 0) { 142 doubleBuffer = GL_TRUE; 143 } else { 144 printf("%s (Bad option).\n", argv[i]); 145 return GL_FALSE; 146 } 147 } 148 return GL_TRUE; 149} 150 151int main(int argc, char **argv) 152{ 153 GLenum type; 154 char *s; 155 char *extName = "GL_EXT_blend_logic_op"; 156 char *version; 157 158 glutInit(&argc, argv); 159 160 if (Args(argc, argv) == GL_FALSE) { 161 exit(1); 162 } 163 164 glutInitWindowPosition(0, 0); glutInitWindowSize( 400, 400); 165 166 type = GLUT_RGB; 167 type |= (doubleBuffer) ? GLUT_DOUBLE : GLUT_SINGLE; 168 glutInitDisplayMode(type); 169 170 if (glutCreateWindow("Blend XOR") == GL_FALSE) { 171 exit(1); 172 } 173 174 glewInit(); 175 176 /* Make sure blend_logic_op extension is there. */ 177 s = (char *) glGetString(GL_EXTENSIONS); 178 version = (char*) glGetString(GL_VERSION); 179 if (!s) 180 exit(1); 181 if (strstr(s,extName)) { 182 supportlogops = 1; 183 use11ops = 0; 184 printf("blend_logic_op extension available.\n"); 185 } 186 if (strncmp(version,"1.1",3)>=0) { 187 supportlogops += 2; 188 use11ops = 1; 189 printf("1.1 color logic ops available.\n"); 190 } 191 if (supportlogops == 0) { 192 printf("Blend_logic_op extension and GL 1.1 not present.\n"); 193 exit(1); 194 } 195 196 Init(); 197 198 glutReshapeFunc(Reshape); 199 glutKeyboardFunc(Key); 200 glutDisplayFunc(Draw); 201 glutMainLoop(); 202 return 0; 203} 204