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