1/**
2 * Test XOR emulation with blending.
3 *
4 */
5
6#include <stdio.h>
7#include <stdlib.h>
8#include <math.h>
9#include <GL/glew.h>
10#include "glut_wrap.h"
11#include "readtex.c"
12
13#define IMAGE_FILE DEMOS_DATA_DIR "arch.rgb"
14
15static int ImgWidth, ImgHeight;
16static GLenum ImgFormat;
17static GLubyte *Image = NULL;
18
19static int Win;
20static int Width = 600, Height = 600;
21
22struct rect
23{
24   int x0, y0, x1, y1;
25};
26
27static struct rect OldRect, NewRect;
28
29static GLboolean ButtonDown = GL_FALSE;
30static GLboolean LogicOp = 0*GL_TRUE;
31
32
33static const GLfloat red[4] = {1.0, 0.2, 0.2, 1.0};
34static const GLfloat green[4] = {0.2, 1.0, 0.2, 1.0};
35static const GLfloat blue[4] = {0.2, 0.2, 1.0, 1.0};
36
37
38static void
39PrintString(const char *s)
40{
41   while (*s) {
42      glutBitmapCharacter(GLUT_BITMAP_8_BY_13, (int) *s);
43      s++;
44   }
45}
46
47
48static void
49Draw(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
80static void
81Reshape(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
94static void
95Key(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
117static void
118SpecialKey(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
136static void
137MouseMotion(int x, int y)
138{
139   if (ButtonDown) {
140      NewRect.x1 = x;
141      NewRect.y1 = y;
142      glutPostRedisplay();
143   }
144}
145
146
147static void
148MouseButton(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
162static void
163Init(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
179int
180main(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   glewInit();
187   glutReshapeFunc(Reshape);
188   glutKeyboardFunc(Key);
189   glutSpecialFunc(SpecialKey);
190   glutMotionFunc(MouseMotion);
191   glutMouseFunc(MouseButton);
192   glutDisplayFunc(Draw);
193   Init();
194   glutPostRedisplay();
195   glutMainLoop();
196   return 0;
197}
198