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