1/*
2 * Draw lines in XOR mode.
3 * Note that the last pixel in a line segment should not be drawn by GL
4 * so that pixels aren't touched twice at the shared vertex of connected lines.
5 *
6 * Brian Paul
7 * 7 Oct 2010
8 */
9
10
11#include <stdio.h>
12#include <string.h>
13#include <stdlib.h>
14#include "glut_wrap.h"
15
16
17static GLboolean xor = GL_TRUE;
18
19
20static void
21Reshape(int width, int height)
22{
23   glViewport(0, 0, (GLint)width, (GLint)height);
24
25   glMatrixMode(GL_PROJECTION);
26   glLoadIdentity();
27   glOrtho(-1.0, 1.0, -1.0, 1.0, -1.0, 1.0);
28   glMatrixMode(GL_MODELVIEW);
29}
30
31
32static void
33Key(unsigned char key, int x, int y)
34{
35   if (key == 'x') {
36      xor = !xor;
37      printf("XOR mode: %s\n", xor ? "on" : "off");
38   }
39   else if (key == 27)
40      exit(0);
41   glutPostRedisplay();
42}
43
44
45static void
46Draw(void)
47{
48   glClear(GL_COLOR_BUFFER_BIT);
49
50   glLogicOp(GL_XOR);
51   if (xor)
52      glEnable(GL_COLOR_LOGIC_OP);
53   else
54      glDisable(GL_COLOR_LOGIC_OP);
55
56   glColor3f(0, 1, 0);
57
58   /* outer line rect */
59   glBegin(GL_LINE_LOOP);
60   glVertex2f(-0.9, -0.9);
61   glVertex2f( 0.9, -0.9);
62   glVertex2f( 0.9,  0.9);
63   glVertex2f(-0.9,  0.9);
64   glEnd();
65
66   /* middle line rect */
67   glBegin(GL_LINE_STRIP);
68   glVertex2f(-0.8, -0.8);
69   glVertex2f( 0.8, -0.8);
70   glVertex2f( 0.8,  0.8);
71   glVertex2f(-0.8,  0.8);
72   glVertex2f(-0.8, -0.8);
73   glEnd();
74
75   /* inner line rect */
76   glBegin(GL_LINES);
77   glVertex2f(-0.7, -0.7);
78   glVertex2f( 0.7, -0.7);
79
80   glVertex2f( 0.7, -0.7);
81   glVertex2f( 0.7,  0.7);
82
83   glVertex2f( 0.7,  0.7);
84   glVertex2f(-0.7,  0.7);
85
86   glVertex2f(-0.7,  0.7);
87   glVertex2f(-0.7, -0.7);
88   glEnd();
89
90   /* inner + pattern */
91   glBegin(GL_LINES);
92   glVertex2f(-0.6,  0.0);
93   glVertex2f( 0.6,  0.0);
94   glVertex2f( 0.0,  0.6);
95   glVertex2f( 0.0, -0.6);
96   glEnd();
97
98
99   glutSwapBuffers();
100}
101
102
103int
104main(int argc, char **argv)
105{
106   glutInit(&argc, argv);
107
108   glutInitWindowSize(250, 250);
109
110   glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE);
111   glutCreateWindow(argv[0]);
112   glutReshapeFunc(Reshape);
113   glutKeyboardFunc(Key);
114   glutDisplayFunc(Draw);
115
116   fprintf(stderr, "GL_RENDERER   = %s\n", (char *) glGetString(GL_RENDERER));
117   fprintf(stderr, "GL_VERSION    = %s\n", (char *) glGetString(GL_VERSION));
118   fprintf(stderr, "GL_VENDOR     = %s\n", (char *) glGetString(GL_VENDOR));
119   fprintf(stderr, "NOTE: there should be no pixels missing at the corners"
120           " of the line loops.\n");
121   fprintf(stderr, "There should be a missing pixel at the center of the '+'.\n");
122   fprintf(stderr, "Resize the window to check for any pixel drop-outs.\n");
123   fprintf(stderr, "Press 'x' to toggle XOR mode on/off.\n");
124
125   glutMainLoop();
126
127   return 0;
128}
129