Fix issues related to the 'continue' statement.
[mesa.git] / progs / samples / blendeq.c
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 #ifdef _WIN32
15 #include <windows.h>
16 #endif
17 #define GL_GLEXT_PROTOTYPES
18 #include <GL/glut.h>
19
20 GLenum doubleBuffer;
21 static int dithering = 0;
22 int use11ops = 0;
23 int supportlogops = 0;
24 static int doPrint = 1;
25 static int deltaY;
26 GLint windW, windH;
27
28 static 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
36 static void Init(void)
37 {
38
39 glDisable(GL_DITHER);
40 glShadeModel(GL_FLAT);
41 }
42
43 static 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
58 static 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;
67 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;
74 default:
75 return;
76 }
77
78 glutPostRedisplay();
79 }
80
81 static 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
104 static 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);
112 if (supportlogops & 2)
113 glDisable(GL_COLOR_LOGIC_OP);
114
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;
189 if (!use11ops)
190 glBlendEquationEXT(GL_LOGIC_OP);
191 else
192 glEnable(GL_COLOR_LOGIC_OP);
193 glLogicOp(GL_CLEAR);
194 glRectf(x1, i, x2, i+deltaY);
195
196 i -= deltaY;
197 glLogicOp(GL_SET);
198 glRectf(x1, i, x2, i+deltaY);
199
200 i -= deltaY;
201 glLogicOp(GL_COPY);
202 glRectf(x1, i, x2, i+deltaY);
203
204 i -= deltaY;
205 glLogicOp(GL_NOOP);
206 glRectf(x1, i, x2, i+deltaY);
207
208 i -= deltaY;
209 glLogicOp(GL_AND);
210 glRectf(x1, i, x2, i+deltaY);
211
212 i -= deltaY;
213 glLogicOp(GL_INVERT);
214 glRectf(x1, i, x2, i+deltaY);
215
216 i -= deltaY;
217 glLogicOp(GL_OR);
218 glRectf(x1, i, x2, i+deltaY);
219
220 i -= deltaY;
221 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);
227 if (supportlogops & 2)
228 glDisable(GL_COLOR_LOGIC_OP);
229 glColor3f(1.0, 1.0, 1.0);
230 PrintColorStrings();
231 }
232 glFlush();
233
234 if (doubleBuffer) {
235 glutSwapBuffers();
236 }
237
238 }
239
240 static 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
259 int 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";
266 char *version;
267
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);
286 version = (char*) glGetString(GL_VERSION);
287 if (!s)
288 exit(1);
289 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");
301 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 }