2 ** blendeq.c - Demonstrates the use of the blend_minmax, blend_subtract,
3 ** and blend_logic_op extensions using glBlendEquationEXT.
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.
18 static int dithering
= 0;
20 int supportlogops
= 0;
21 static int doPrint
= 1;
30 { GL_COPY
, "GL_COPY" },
31 { GL_NOOP
, "GL_NOOP" },
33 { GL_INVERT
, "GL_INVERT" },
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" },
46 static void DrawString(const char *string
)
50 for (i
= 0; string
[i
]; i
++)
51 glutBitmapCharacter(GLUT_BITMAP_9_BY_15
, string
[i
]);
54 static void Init(void)
58 glShadeModel(GL_FLAT
);
61 static void Reshape(int width
, int height
)
65 windH
= (GLint
)height
;
67 glViewport(0, 0, (GLint
)width
, (GLint
)height
);
70 glMatrixMode(GL_PROJECTION
);
72 gluOrtho2D(0, windW
, 0, windH
);
73 glMatrixMode(GL_MODELVIEW
);
76 static void Key(unsigned char key
, int x
, int y
)
83 dithering
= !dithering
;
86 if (supportlogops
== 3)
87 use11ops
= (!use11ops
);
89 printf("Using GL 1.1 color logic ops.\n");
90 else printf("Using GL_EXT_blend_logic_op.\n");
99 static void PrintColorStrings( void )
102 int i
, xleft
, xright
;
103 char colorString
[100];
106 xright
= 5 + windW
/2;
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
);
122 static void Draw(void)
124 int stringOffset
= 5, stringx
= 8;
125 int x1
, x2
, xleft
, xright
;
128 (dithering
) ? glEnable(GL_DITHER
) : glDisable(GL_DITHER
);
130 if (supportlogops
& 2)
131 glDisable(GL_COLOR_LOGIC_OP
);
133 glClearColor(0.5, 0.6, 0.1, 1.0);
134 glClear(GL_COLOR_BUFFER_BIT
);
136 /* Draw background */
137 glColor3f(0.1, 0.1, 1.0);
138 glRectf(0.0, 0.0, windW
/2, windH
);
141 glColor3f(0.8, 0.8, 0.0);
142 i
= windH
- deltaY
+ stringOffset
;
144 glRasterPos2f(stringx
, i
); i
-= deltaY
;
145 DrawString("SOURCE");
146 glRasterPos2f(stringx
, i
); i
-= deltaY
;
148 glRasterPos2f(stringx
, i
); i
-= deltaY
;
150 glRasterPos2f(stringx
, i
); i
-= deltaY
;
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
;
159 for (k
= 0; LogicOpModes
[k
].name
; k
++) {
160 glRasterPos2f(stringx
, i
);
162 DrawString(LogicOpModes
[k
].name
);
169 xright
= 5 + windW
/2;
171 /* Draw foreground color for comparison */
172 glColor3f(0.9, 0.2, 0.8);
173 glRectf(x1
, i
, x2
, i
+deltaY
);
175 /* Leave one rectangle of background color */
177 /* Begin test cases */
179 glBlendFunc(GL_ONE
, GL_ONE
);
182 glBlendEquationEXT(GL_MIN_EXT
);
183 glRectf(x1
, i
, x2
, i
+deltaY
);
186 glBlendEquationEXT(GL_MAX_EXT
);
187 glRectf(x1
, i
, x2
, i
+deltaY
);
190 glBlendEquationEXT(GL_FUNC_SUBTRACT_EXT
);
191 glRectf(x1
, i
, x2
, i
+deltaY
);
194 glBlendEquationEXT(GL_FUNC_REVERSE_SUBTRACT_EXT
);
195 glRectf(x1
, i
, x2
, i
+deltaY
);
197 glBlendFunc(GL_ONE
, GL_ZERO
);
200 glBlendEquationEXT(GL_LOGIC_OP
);
202 glEnable(GL_COLOR_LOGIC_OP
);
204 glRectf(x1
, i
, x2
, i
+deltaY
);
206 for (k
= 0; LogicOpModes
[k
].name
; k
++) {
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);
217 if (supportlogops
& 2)
218 glDisable(GL_COLOR_LOGIC_OP
);
219 glColor3f(1.0, 1.0, 1.0);
230 static GLenum
Args(int argc
, char **argv
)
234 doubleBuffer
= GL_FALSE
;
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
;
242 printf("%s (Bad option).\n", argv
[i
]);
249 int main(int argc
, char **argv
)
253 char *extName1
= "GL_EXT_blend_logic_op";
254 char *extName2
= "GL_EXT_blend_minmax";
255 char *extName3
= "GL_EXT_blend_subtract";
258 glutInit(&argc
, argv
);
260 if (Args(argc
, argv
) == GL_FALSE
) {
264 glutInitWindowPosition(0, 0); glutInitWindowSize( 800, 520);
267 type
|= (doubleBuffer
) ? GLUT_DOUBLE
: GLUT_SINGLE
;
268 glutInitDisplayMode(type
);
270 if (glutCreateWindow("Blend Equation") == GL_FALSE
) {
276 /* Make sure blend_logic_op extension is there. */
277 s
= (char *) glGetString(GL_EXTENSIONS
);
278 version
= (char*) glGetString(GL_VERSION
);
281 if (strstr(s
,extName1
)) {
284 printf("blend_logic_op extension available.\n");
286 if (strncmp(version
,"1.1",3)>=0) {
289 printf("1.1 color logic ops available.\n");
291 if (supportlogops
== 0) {
292 printf("Blend_logic_op extension and GL 1.1 not present.\n");
295 if (strstr(s
,extName2
) == 0) {
296 printf("Blend_minmax extension is not present.\n");
299 if (strstr(s
,extName3
) == 0) {
300 printf("Blend_subtract extension is not present.\n");
306 glutReshapeFunc(Reshape
);
307 glutKeyboardFunc(Key
);
308 glutDisplayFunc(Draw
);