blob: f78afd303815bf20b4a5af7bbf79e46918e8d604 [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>
Karl Schultz3d587f62002-01-16 00:57:54 +000014#ifdef _WIN32
15#include <windows.h>
16#endif
Brian Paul445ecdc2003-09-08 14:56:41 +000017#define GL_GLEXT_PROTOTYPES
jtgafb833d1999-08-19 00:55:39 +000018#include <GL/glut.h>
19
jtgafb833d1999-08-19 00:55:39 +000020GLenum doubleBuffer;
21static int dithering = 0;
Roland Scheidegger9e295362004-05-21 17:03:38 +000022int use11ops = 0;
23int supportlogops = 0;
jtgafb833d1999-08-19 00:55:39 +000024static int doPrint = 1;
25static int deltaY;
26GLint windW, windH;
27
28static void DrawString(const char *string)
29{
30 int i;
31
32 for (i = 0; string[i]; i++)
33 glutBitmapCharacter(GLUT_BITMAP_9_BY_15, string[i]);
34}
35
36static void Init(void)
37{
38
39 glDisable(GL_DITHER);
40 glShadeModel(GL_FLAT);
41}
42
43static void Reshape(int width, int height)
44{
45
46 windW = (GLint)width;
47 windH = (GLint)height;
48
49 glViewport(0, 0, (GLint)width, (GLint)height);
50 deltaY = windH /16;
51
52 glMatrixMode(GL_PROJECTION);
53 glLoadIdentity();
54 gluOrtho2D(0, windW, 0, windH);
55 glMatrixMode(GL_MODELVIEW);
56}
57
58static void Key(unsigned char key, int x, int y)
59{
60
61 switch (key) {
62 case 27:
63 exit(1);
64 case 'd':
65 dithering = !dithering;
66 break;
Roland Scheidegger9e295362004-05-21 17:03:38 +000067 case 'l':
68 if (supportlogops == 3)
69 use11ops = (!use11ops);
70 if (use11ops)
71 printf("Using GL 1.1 color logic ops.\n");
72 else printf("Using GL_EXT_blend_logic_op.\n");
73 break;
jtgafb833d1999-08-19 00:55:39 +000074 default:
75 return;
76 }
77
78 glutPostRedisplay();
79}
80
81static void PrintColorStrings( void )
82{
83 GLubyte ubbuf[3];
84 int i, xleft, xright;
85 char colorString[18];
86
87 xleft = 5 + windW/4;
88 xright = 5 + windW/2;
89
90 for (i = windH - deltaY + 4; i > 0; i-=deltaY) {
91 glReadPixels(xleft, i+10, 1, 1, GL_RGB, GL_UNSIGNED_BYTE, ubbuf);
92 sprintf(colorString, "(0x%x, 0x%x, 0x%x)",
93 ubbuf[0], ubbuf[1], ubbuf[2]);
94 glRasterPos2f(xleft, i);
95 DrawString(colorString);
96 glReadPixels(xright, i+10, 1, 1, GL_RGB, GL_UNSIGNED_BYTE, ubbuf);
97 sprintf(colorString, "(0x%x, 0x%x, 0x%x)",
98 ubbuf[0], ubbuf[1], ubbuf[2]);
99 glRasterPos2f(xright, i);
100 DrawString(colorString);
101 }
102}
103
104static void Draw(void)
105{
106 int stringOffset = 5, stringx = 8;
107 int x1, x2, xleft, xright;
108 int i;
109
110 (dithering) ? glEnable(GL_DITHER) : glDisable(GL_DITHER);
111 glDisable(GL_BLEND);
Roland Scheidegger9e295362004-05-21 17:03:38 +0000112 if (supportlogops & 2)
113 glDisable(GL_COLOR_LOGIC_OP);
jtgafb833d1999-08-19 00:55:39 +0000114
115 glClearColor(0.5, 0.6, 0.1, 1.0);
116 glClear(GL_COLOR_BUFFER_BIT);
117
118 /* Draw background */
119 glColor3f(0.1, 0.1, 1.0);
120 glRectf(0.0, 0.0, windW/2, windH);
121
122 /* Draw labels */
123 glColor3f(0.8, 0.8, 0.0);
124 i = windH - deltaY + stringOffset;
125 glRasterPos2f(stringx, i); i -= deltaY;
126 DrawString("SOURCE");
127 glRasterPos2f(stringx, i); i -= deltaY;
128 DrawString("DEST");
129 glRasterPos2f(stringx, i); i -= deltaY;
130 DrawString("min");
131 glRasterPos2f(stringx, i); i -= deltaY;
132 DrawString("max");
133 glRasterPos2f(stringx, i); i -= deltaY;
134 DrawString("subtract");
135 glRasterPos2f(stringx, i); i -= deltaY;
136 DrawString("reverse_subtract");
137 glRasterPos2f(stringx, i); i -= deltaY;
138 DrawString("clear");
139 glRasterPos2f(stringx, i); i -= deltaY;
140 DrawString("set");
141 glRasterPos2f(stringx, i); i -= deltaY;
142 DrawString("copy");
143 glRasterPos2f(stringx, i); i -= deltaY;
144 DrawString("noop");
145 glRasterPos2f(stringx, i); i -= deltaY;
146 DrawString("and");
147 glRasterPos2f(stringx, i); i -= deltaY;
148 DrawString("invert");
149 glRasterPos2f(stringx, i); i -= deltaY;
150 DrawString("or");
151 glRasterPos2f(stringx, i); i -= deltaY;
152 DrawString("xor");
153
154
155 i = windH - deltaY;
156 x1 = windW/4;
157 x2 = 3 * windW/4;
158 xleft = 5 + windW/4;
159 xright = 5 + windW/2;
160
161 /* Draw foreground color for comparison */
162 glColor3f(0.9, 0.2, 0.8);
163 glRectf(x1, i, x2, i+deltaY);
164
165 /* Leave one rectangle of background color */
166
167 /* Begin test cases */
168 glEnable(GL_BLEND);
169 glBlendFunc(GL_ONE, GL_ONE);
170
171 i -= 2*deltaY;
172 glBlendEquationEXT(GL_MIN_EXT);
173 glRectf(x1, i, x2, i+deltaY);
174
175 i -= deltaY;
176 glBlendEquationEXT(GL_MAX_EXT);
177 glRectf(x1, i, x2, i+deltaY);
178
179 i -= deltaY;
180 glBlendEquationEXT(GL_FUNC_SUBTRACT_EXT);
181 glRectf(x1, i, x2, i+deltaY);
182
183 i -= deltaY;
184 glBlendEquationEXT(GL_FUNC_REVERSE_SUBTRACT_EXT);
185 glRectf(x1, i, x2, i+deltaY);
186
187 glBlendFunc(GL_ONE, GL_ZERO);
188 i -= deltaY;
Roland Scheidegger9e295362004-05-21 17:03:38 +0000189 if (!use11ops)
190 glBlendEquationEXT(GL_LOGIC_OP);
191 else
192 glEnable(GL_COLOR_LOGIC_OP);
jtgafb833d1999-08-19 00:55:39 +0000193 glLogicOp(GL_CLEAR);
194 glRectf(x1, i, x2, i+deltaY);
195
196 i -= deltaY;
jtgafb833d1999-08-19 00:55:39 +0000197 glLogicOp(GL_SET);
198 glRectf(x1, i, x2, i+deltaY);
199
200 i -= deltaY;
jtgafb833d1999-08-19 00:55:39 +0000201 glLogicOp(GL_COPY);
202 glRectf(x1, i, x2, i+deltaY);
203
204 i -= deltaY;
jtgafb833d1999-08-19 00:55:39 +0000205 glLogicOp(GL_NOOP);
206 glRectf(x1, i, x2, i+deltaY);
207
208 i -= deltaY;
jtgafb833d1999-08-19 00:55:39 +0000209 glLogicOp(GL_AND);
210 glRectf(x1, i, x2, i+deltaY);
211
212 i -= deltaY;
jtgafb833d1999-08-19 00:55:39 +0000213 glLogicOp(GL_INVERT);
214 glRectf(x1, i, x2, i+deltaY);
215
216 i -= deltaY;
jtgafb833d1999-08-19 00:55:39 +0000217 glLogicOp(GL_OR);
218 glRectf(x1, i, x2, i+deltaY);
219
220 i -= deltaY;
jtgafb833d1999-08-19 00:55:39 +0000221 glLogicOp(GL_XOR);
222 glRectf(x1, i, x2, i+deltaY);
223 glRectf(x1, i+10, x2, i+5);
224
225 if (doPrint) {
226 glDisable(GL_BLEND);
Roland Scheidegger9e295362004-05-21 17:03:38 +0000227 if (supportlogops & 2)
228 glDisable(GL_COLOR_LOGIC_OP);
jtgafb833d1999-08-19 00:55:39 +0000229 glColor3f(1.0, 1.0, 1.0);
230 PrintColorStrings();
231 }
232 glFlush();
233
234 if (doubleBuffer) {
235 glutSwapBuffers();
236 }
237
238}
239
240static GLenum Args(int argc, char **argv)
241{
242 GLint i;
243
244 doubleBuffer = GL_FALSE;
245
246 for (i = 1; i < argc; i++) {
247 if (strcmp(argv[i], "-sb") == 0) {
248 doubleBuffer = GL_FALSE;
249 } else if (strcmp(argv[i], "-db") == 0) {
250 doubleBuffer = GL_TRUE;
251 } else {
252 printf("%s (Bad option).\n", argv[i]);
253 return GL_FALSE;
254 }
255 }
256 return GL_TRUE;
257}
258
259int main(int argc, char **argv)
260{
261 GLenum type;
262 char *s;
263 char *extName1 = "GL_EXT_blend_logic_op";
264 char *extName2 = "GL_EXT_blend_minmax";
265 char *extName3 = "GL_EXT_blend_subtract";
Roland Scheidegger9e295362004-05-21 17:03:38 +0000266 char *version;
jtgafb833d1999-08-19 00:55:39 +0000267
268 glutInit(&argc, argv);
269
270 if (Args(argc, argv) == GL_FALSE) {
271 exit(1);
272 }
273
274 glutInitWindowPosition(0, 0); glutInitWindowSize( 800, 400);
275
276 type = GLUT_RGB;
277 type |= (doubleBuffer) ? GLUT_DOUBLE : GLUT_SINGLE;
278 glutInitDisplayMode(type);
279
280 if (glutCreateWindow("Blend Equation") == GL_FALSE) {
281 exit(1);
282 }
283
284 /* Make sure blend_logic_op extension is there. */
285 s = (char *) glGetString(GL_EXTENSIONS);
Roland Scheidegger9e295362004-05-21 17:03:38 +0000286 version = (char*) glGetString(GL_VERSION);
jtgafb833d1999-08-19 00:55:39 +0000287 if (!s)
288 exit(1);
Roland Scheidegger9e295362004-05-21 17:03:38 +0000289 if (strstr(s,extName1)) {
290 supportlogops = 1;
291 use11ops = 0;
292 printf("blend_logic_op extension available.\n");
293 }
294 if (strncmp(version,"1.1",3)>=0) {
295 supportlogops += 2;
296 use11ops = 1;
297 printf("1.1 color logic ops available.\n");
298 }
299 if (supportlogops == 0) {
300 printf("Blend_logic_op extension and GL 1.1 not present.\n");
jtgafb833d1999-08-19 00:55:39 +0000301 exit(1);
302 }
303 if (strstr(s,extName2) == 0) {
304 printf("Blend_minmax extension is not present.\n");
305 exit(1);
306 }
307 if (strstr(s,extName3) == 0) {
308 printf("Blend_subtract extension is not present.\n");
309 exit(1);
310 }
311
312 Init();
313
314 glutReshapeFunc(Reshape);
315 glutKeyboardFunc(Key);
316 glutDisplayFunc(Draw);
317 glutMainLoop();
318 return 0;
319}