tests: test pseudo-XOR blend mode.
[mesa.git] / progs / tests / blendxor.c
1 /**
2 * Test XOR emulation with blending.
3 *
4 */
5
6 #define GL_GLEXT_PROTOTYPES
7 #include <stdio.h>
8 #include <stdlib.h>
9 #include <math.h>
10 #include <GL/glut.h>
11 #include "readtex.c"
12
13 #define IMAGE_FILE "../images/arch.rgb"
14
15 static int ImgWidth, ImgHeight;
16 static GLenum ImgFormat;
17 static GLubyte *Image = NULL;
18
19 static int Win;
20 static int Width = 600, Height = 600;
21
22 struct rect
23 {
24 int x0, y0, x1, y1;
25 };
26
27 static struct rect OldRect, NewRect;
28
29 static GLboolean ButtonDown = GL_FALSE;
30 static GLboolean LogicOp = 0*GL_TRUE;
31
32
33 static const GLfloat red[4] = {1.0, 0.2, 0.2, 1.0};
34 static const GLfloat green[4] = {0.2, 1.0, 0.2, 1.0};
35 static const GLfloat blue[4] = {0.2, 0.2, 1.0, 1.0};
36
37
38 static void
39 PrintString(const char *s)
40 {
41 while (*s) {
42 glutBitmapCharacter(GLUT_BITMAP_8_BY_13, (int) *s);
43 s++;
44 }
45 }
46
47
48 static void
49 Draw(void)
50 {
51 glClear(GL_COLOR_BUFFER_BIT);
52
53 glWindowPos2i((Width - ImgWidth) / 2, (Height - ImgHeight) / 2);
54 glDrawPixels(ImgWidth, ImgHeight, ImgFormat, GL_UNSIGNED_BYTE, Image);
55
56 /*
57 * Draw 2D XOR rects
58 */
59 glColor3f(1, 1, 1);
60
61 glWindowPos2i(100, Height - 20);
62 PrintString("XOR LogicOp:");
63 glLogicOp(GL_XOR);
64 glEnable(GL_COLOR_LOGIC_OP);
65 glRecti(100, 30, 250, Height - 30);
66 glDisable(GL_COLOR_LOGIC_OP);
67
68 glWindowPos2i(Width/2 + 10, Height - 20);
69 PrintString("Invert Blending:");
70 glBlendFunc(GL_ONE, GL_ONE);
71 glBlendEquation(GL_FUNC_SUBTRACT);
72 glEnable(GL_BLEND);
73 glRecti(Width / 2, 30, Width / 2 + 150, Height - 30);
74 glDisable(GL_BLEND);
75
76 glutSwapBuffers();
77 }
78
79
80 static void
81 Reshape(int width, int height)
82 {
83 Width = width;
84 Height = height;
85 glViewport(0, 0, width, height);
86 glMatrixMode(GL_PROJECTION);
87 glLoadIdentity();
88 glOrtho(0, Width, 0, Height, -1, 1);
89 glMatrixMode(GL_MODELVIEW);
90 glLoadIdentity();
91 }
92
93
94 static void
95 Key(unsigned char key, int x, int y)
96 {
97 (void) x;
98 (void) y;
99 switch (key) {
100 case 'b':
101 case 'B':
102 LogicOp = GL_FALSE;
103 break;
104 case 'l':
105 case 'L':
106 LogicOp = GL_TRUE;
107 break;
108 case 27:
109 glutDestroyWindow(Win);
110 exit(0);
111 break;
112 }
113 glutPostRedisplay();
114 }
115
116
117 static void
118 SpecialKey(int key, int x, int y)
119 {
120 (void) x;
121 (void) y;
122 switch (key) {
123 case GLUT_KEY_UP:
124 break;
125 case GLUT_KEY_DOWN:
126 break;
127 case GLUT_KEY_LEFT:
128 break;
129 case GLUT_KEY_RIGHT:
130 break;
131 }
132 glutPostRedisplay();
133 }
134
135
136 static void
137 MouseMotion(int x, int y)
138 {
139 if (ButtonDown) {
140 NewRect.x1 = x;
141 NewRect.y1 = y;
142 glutPostRedisplay();
143 }
144 }
145
146
147 static void
148 MouseButton(int button, int state, int x, int y)
149 {
150 if (button == GLUT_LEFT_BUTTON && state == GLUT_DOWN) {
151 ButtonDown = GL_TRUE;
152 NewRect.x0 = NewRect.x1 = x;
153 NewRect.y0 = NewRect.y1 = y;
154 OldRect = NewRect;
155 }
156 else if (button == GLUT_LEFT_BUTTON && state == GLUT_UP) {
157 ButtonDown = GL_FALSE;
158 }
159 }
160
161
162 static void
163 Init(void)
164 {
165 /*
166 * Load image and scale if needed.
167 */
168 Image = LoadRGBImage(IMAGE_FILE, &ImgWidth, &ImgHeight, &ImgFormat);
169 if (!Image) {
170 printf("Couldn't read %s\n", IMAGE_FILE);
171 exit(0);
172 }
173
174 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
175 glPixelStorei(GL_PACK_ALIGNMENT, 1);
176 }
177
178
179 int
180 main(int argc, char *argv[])
181 {
182 glutInit(&argc, argv);
183 glutInitWindowSize(Width, Height);
184 glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE);
185 Win = glutCreateWindow(argv[0]);
186 glutReshapeFunc(Reshape);
187 glutKeyboardFunc(Key);
188 glutSpecialFunc(SpecialKey);
189 glutMotionFunc(MouseMotion);
190 glutMouseFunc(MouseButton);
191 glutDisplayFunc(Draw);
192 Init();
193 glutPostRedisplay();
194 glutMainLoop();
195 return 0;
196 }