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.
17 #define GL_GLEXT_PROTOTYPES
21 static int dithering
= 0;
23 int supportlogops
= 0;
24 static int doPrint
= 1;
33 { GL_COPY
, "GL_COPY" },
34 { GL_NOOP
, "GL_NOOP" },
36 { GL_INVERT
, "GL_INVERT" },
40 { GL_NAND
, "GL_NAND" },
41 { GL_OR_REVERSE
, "GL_OR_REVERSE" },
42 { GL_OR_INVERTED
, "GL_OR_INVERTED" },
43 { GL_AND_INVERTED
, "GL_AND_INVERTED" },
49 static void DrawString(const char *string
)
53 for (i
= 0; string
[i
]; i
++)
54 glutBitmapCharacter(GLUT_BITMAP_9_BY_15
, string
[i
]);
57 static void Init(void)
61 glShadeModel(GL_FLAT
);
64 static void Reshape(int width
, int height
)
68 windH
= (GLint
)height
;
70 glViewport(0, 0, (GLint
)width
, (GLint
)height
);
73 glMatrixMode(GL_PROJECTION
);
75 gluOrtho2D(0, windW
, 0, windH
);
76 glMatrixMode(GL_MODELVIEW
);
79 static void Key(unsigned char key
, int x
, int y
)
86 dithering
= !dithering
;
89 if (supportlogops
== 3)
90 use11ops
= (!use11ops
);
92 printf("Using GL 1.1 color logic ops.\n");
93 else printf("Using GL_EXT_blend_logic_op.\n");
102 static void PrintColorStrings( void )
105 int i
, xleft
, xright
;
106 char colorString
[18];
109 xright
= 5 + windW
/2;
111 for (i
= windH
- deltaY
+ 4; i
> 0; i
-=deltaY
) {
112 glReadPixels(xleft
, i
+10, 1, 1, GL_RGB
, GL_UNSIGNED_BYTE
, ubbuf
);
113 sprintf(colorString
, "(0x%x, 0x%x, 0x%x)",
114 ubbuf
[0], ubbuf
[1], ubbuf
[2]);
115 glRasterPos2f(xleft
, i
);
116 DrawString(colorString
);
117 glReadPixels(xright
, i
+10, 1, 1, GL_RGB
, GL_UNSIGNED_BYTE
, ubbuf
);
118 sprintf(colorString
, "(0x%x, 0x%x, 0x%x)",
119 ubbuf
[0], ubbuf
[1], ubbuf
[2]);
120 glRasterPos2f(xright
, i
);
121 DrawString(colorString
);
125 static void Draw(void)
127 int stringOffset
= 5, stringx
= 8;
128 int x1
, x2
, xleft
, xright
;
131 (dithering
) ? glEnable(GL_DITHER
) : glDisable(GL_DITHER
);
133 if (supportlogops
& 2)
134 glDisable(GL_COLOR_LOGIC_OP
);
136 glClearColor(0.5, 0.6, 0.1, 1.0);
137 glClear(GL_COLOR_BUFFER_BIT
);
139 /* Draw background */
140 glColor3f(0.1, 0.1, 1.0);
141 glRectf(0.0, 0.0, windW
/2, windH
);
144 glColor3f(0.8, 0.8, 0.0);
145 i
= windH
- deltaY
+ stringOffset
;
147 glRasterPos2f(stringx
, i
); i
-= deltaY
;
148 DrawString("SOURCE");
149 glRasterPos2f(stringx
, i
); i
-= deltaY
;
151 glRasterPos2f(stringx
, i
); i
-= deltaY
;
153 glRasterPos2f(stringx
, i
); i
-= deltaY
;
155 glRasterPos2f(stringx
, i
); i
-= deltaY
;
156 DrawString("subtract");
157 glRasterPos2f(stringx
, i
); i
-= deltaY
;
158 DrawString("reverse_subtract");
159 glRasterPos2f(stringx
, i
); i
-= deltaY
;
162 for (k
= 0; LogicOpModes
[k
].name
; k
++) {
163 glRasterPos2f(stringx
, i
);
165 DrawString(LogicOpModes
[k
].name
);
172 xright
= 5 + windW
/2;
174 /* Draw foreground color for comparison */
175 glColor3f(0.9, 0.2, 0.8);
176 glRectf(x1
, i
, x2
, i
+deltaY
);
178 /* Leave one rectangle of background color */
180 /* Begin test cases */
182 glBlendFunc(GL_ONE
, GL_ONE
);
185 glBlendEquationEXT(GL_MIN_EXT
);
186 glRectf(x1
, i
, x2
, i
+deltaY
);
189 glBlendEquationEXT(GL_MAX_EXT
);
190 glRectf(x1
, i
, x2
, i
+deltaY
);
193 glBlendEquationEXT(GL_FUNC_SUBTRACT_EXT
);
194 glRectf(x1
, i
, x2
, i
+deltaY
);
197 glBlendEquationEXT(GL_FUNC_REVERSE_SUBTRACT_EXT
);
198 glRectf(x1
, i
, x2
, i
+deltaY
);
200 glBlendFunc(GL_ONE
, GL_ZERO
);
203 glBlendEquationEXT(GL_LOGIC_OP
);
205 glEnable(GL_COLOR_LOGIC_OP
);
207 glRectf(x1
, i
, x2
, i
+deltaY
);
209 for (k
= 0; LogicOpModes
[k
].name
; k
++) {
211 glLogicOp(LogicOpModes
[k
].mode
);
212 glRectf(x1
, i
, x2
, i
+deltaY
);
213 if (LogicOpModes
[k
].mode
== GL_XOR
) {
214 glRectf(x1
, i
+10, x2
, i
+5);
220 if (supportlogops
& 2)
221 glDisable(GL_COLOR_LOGIC_OP
);
222 glColor3f(1.0, 1.0, 1.0);
233 static GLenum
Args(int argc
, char **argv
)
237 doubleBuffer
= GL_FALSE
;
239 for (i
= 1; i
< argc
; i
++) {
240 if (strcmp(argv
[i
], "-sb") == 0) {
241 doubleBuffer
= GL_FALSE
;
242 } else if (strcmp(argv
[i
], "-db") == 0) {
243 doubleBuffer
= GL_TRUE
;
245 printf("%s (Bad option).\n", argv
[i
]);
252 int main(int argc
, char **argv
)
256 char *extName1
= "GL_EXT_blend_logic_op";
257 char *extName2
= "GL_EXT_blend_minmax";
258 char *extName3
= "GL_EXT_blend_subtract";
261 glutInit(&argc
, argv
);
263 if (Args(argc
, argv
) == GL_FALSE
) {
267 glutInitWindowPosition(0, 0); glutInitWindowSize( 800, 520);
270 type
|= (doubleBuffer
) ? GLUT_DOUBLE
: GLUT_SINGLE
;
271 glutInitDisplayMode(type
);
273 if (glutCreateWindow("Blend Equation") == GL_FALSE
) {
277 /* Make sure blend_logic_op extension is there. */
278 s
= (char *) glGetString(GL_EXTENSIONS
);
279 version
= (char*) glGetString(GL_VERSION
);
282 if (strstr(s
,extName1
)) {
285 printf("blend_logic_op extension available.\n");
287 if (strncmp(version
,"1.1",3)>=0) {
290 printf("1.1 color logic ops available.\n");
292 if (supportlogops
== 0) {
293 printf("Blend_logic_op extension and GL 1.1 not present.\n");
296 if (strstr(s
,extName2
) == 0) {
297 printf("Blend_minmax extension is not present.\n");
300 if (strstr(s
,extName3
) == 0) {
301 printf("Blend_subtract extension is not present.\n");
307 glutReshapeFunc(Reshape
);
308 glutKeyboardFunc(Key
);
309 glutDisplayFunc(Draw
);