blob: cd0474c5cea1da5b64885c2183b3d246dd6e254c [file] [log] [blame]
jtgafb833d1999-08-19 00:55:39 +00001/*
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>
José Fonseca52233f22009-02-10 20:27:49 +000014#include <GL/glew.h>
jtgafb833d1999-08-19 00:55:39 +000015#include <GL/glut.h>
16
jtgafb833d1999-08-19 00:55:39 +000017GLenum doubleBuffer;
18static int dithering = 0;
Roland Scheidegger9e295362004-05-21 17:03:38 +000019int use11ops = 0;
20int supportlogops = 0;
jtgafb833d1999-08-19 00:55:39 +000021static int doPrint = 1;
22static int deltaY;
23GLint windW, windH;
24
Brian92e40902007-11-26 11:39:17 -070025static 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
jtgafb833d1999-08-19 00:55:39 +000046static 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);
Brian92e40902007-11-26 11:39:17 -070068 deltaY = windH /20;
jtgafb833d1999-08-19 00:55:39 +000069
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;
Roland Scheidegger9e295362004-05-21 17:03:38 +000085 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;
jtgafb833d1999-08-19 00:55:39 +000092 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[18];
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;
Brian92e40902007-11-26 11:39:17 -0700126 int i, k;
jtgafb833d1999-08-19 00:55:39 +0000127
128 (dithering) ? glEnable(GL_DITHER) : glDisable(GL_DITHER);
129 glDisable(GL_BLEND);
Roland Scheidegger9e295362004-05-21 17:03:38 +0000130 if (supportlogops & 2)
131 glDisable(GL_COLOR_LOGIC_OP);
jtgafb833d1999-08-19 00:55:39 +0000132
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;
Brian92e40902007-11-26 11:39:17 -0700143
jtgafb833d1999-08-19 00:55:39 +0000144 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");
jtgafb833d1999-08-19 00:55:39 +0000158
Brian92e40902007-11-26 11:39:17 -0700159 for (k = 0; LogicOpModes[k].name; k++) {
160 glRasterPos2f(stringx, i);
161 i -= deltaY;
162 DrawString(LogicOpModes[k].name);
163 }
jtgafb833d1999-08-19 00:55:39 +0000164
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;
Roland Scheidegger9e295362004-05-21 17:03:38 +0000199 if (!use11ops)
200 glBlendEquationEXT(GL_LOGIC_OP);
201 else
202 glEnable(GL_COLOR_LOGIC_OP);
jtgafb833d1999-08-19 00:55:39 +0000203 glLogicOp(GL_CLEAR);
204 glRectf(x1, i, x2, i+deltaY);
205
Brian92e40902007-11-26 11:39:17 -0700206 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 }
jtgafb833d1999-08-19 00:55:39 +0000214
Brian92e40902007-11-26 11:39:17 -0700215 if (doPrint) {
216 glDisable(GL_BLEND);
217 if (supportlogops & 2)
Roland Scheidegger9e295362004-05-21 17:03:38 +0000218 glDisable(GL_COLOR_LOGIC_OP);
Brian92e40902007-11-26 11:39:17 -0700219 glColor3f(1.0, 1.0, 1.0);
220 PrintColorStrings();
221 }
222 glFlush();
jtgafb833d1999-08-19 00:55:39 +0000223
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";
Roland Scheidegger9e295362004-05-21 17:03:38 +0000256 char *version;
jtgafb833d1999-08-19 00:55:39 +0000257
258 glutInit(&argc, argv);
259
260 if (Args(argc, argv) == GL_FALSE) {
261 exit(1);
262 }
263
Brian92e40902007-11-26 11:39:17 -0700264 glutInitWindowPosition(0, 0); glutInitWindowSize( 800, 520);
jtgafb833d1999-08-19 00:55:39 +0000265
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
José Fonseca52233f22009-02-10 20:27:49 +0000274 glewInit();
275
jtgafb833d1999-08-19 00:55:39 +0000276 /* Make sure blend_logic_op extension is there. */
277 s = (char *) glGetString(GL_EXTENSIONS);
Roland Scheidegger9e295362004-05-21 17:03:38 +0000278 version = (char*) glGetString(GL_VERSION);
jtgafb833d1999-08-19 00:55:39 +0000279 if (!s)
280 exit(1);
Roland Scheidegger9e295362004-05-21 17:03:38 +0000281 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");
jtgafb833d1999-08-19 00:55:39 +0000293 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}