st/xorg: Work around cursor reference counting bugs in older X servers.
[mesa.git] / progs / tests / exactrast.c
1 /**
2 * Test for exact point/line/polygon rasterization, or at least rasterization
3 * that fits the tolerance of the OpenGL spec.
4 *
5 * Brian Paul
6 * 9 Nov 2007
7 */
8
9 /*
10 * Notes:
11 * - 'm' to cycle through point, hline, vline and quad drawing
12 * - Use cursor keys to translate coordinates (z to reset)
13 * - Resize window to check for proper rasterization
14 * - Make sure your LCD is running in its native resolution
15 *
16 * If translation is (0,0):
17 * a point will be drawn where x%2==0 and y%2==0,
18 * a horizontal line will be drawn where x%2==0,
19 * a vertical line will be drawn where y%2==0,
20 * for quads, pixels will be set where (x%4)!=3 and (y%4)!=3
21 *
22 * XXX todo: do glReadPixels and test that the results are what's expected.
23 * Upon failure, iterate over sub-pixel translations to find the ideal offset.
24 */
25
26
27 #include <stdio.h>
28 #include <stdlib.h>
29 #include <GL/glew.h>
30 #include <GL/glut.h>
31
32 static int Width = 400, Height = 400;
33 static int Win;
34 static float Xtrans = 0, Ytrans = 0;
35 static float Step = 0.125;
36
37 enum {
38 MODE_POINTS,
39 MODE_HLINES,
40 MODE_VLINES,
41 MODE_QUADS,
42 NUM_MODES
43 };
44
45 static int Mode = MODE_POINTS;
46
47
48 static void
49 Draw(void)
50 {
51 /* See the OpenGL Programming Guide, Appendix H, "OpenGL Correctness Tips"
52 * for information about the 0.375 translation factor.
53 */
54 float tx = 0.375, ty = 0.375;
55 int i, j;
56
57 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
58
59 glPushMatrix();
60 glTranslatef(tx + Xtrans, ty + Ytrans, 0);
61
62 if (Mode == MODE_POINTS) {
63 glBegin(GL_POINTS);
64 for (j = 0; j < Height; j += 2) {
65 for (i = 0; i < Width; i += 2) {
66 glVertex2f(i, j);
67 }
68 }
69 glEnd();
70 }
71 else if (Mode == MODE_HLINES) {
72 glBegin(GL_LINES);
73 for (i = 0; i < Height; i += 2) {
74 glVertex2f(0, i);
75 glVertex2f(Width, i);
76 }
77 glEnd();
78 }
79 else if (Mode == MODE_VLINES) {
80 glBegin(GL_LINES);
81 for (i = 0; i < Width; i += 2) {
82 glVertex2f(i, 0 );
83 glVertex2f(i, Height);
84 }
85 glEnd();
86 }
87 else if (Mode == MODE_QUADS) {
88 glBegin(GL_QUADS);
89 for (j = 0; j < Height; j += 4) {
90 for (i = 0; i < Width; i += 4) {
91 glVertex2f(i, j );
92 glVertex2f(i + 3, j );
93 glVertex2f(i + 3, j + 3);
94 glVertex2f(i, j + 3);
95 }
96 }
97 glEnd();
98 }
99
100 glPopMatrix();
101
102 glutSwapBuffers();
103 }
104
105
106 static void
107 Reshape(int width, int height)
108 {
109 Width = width;
110 Height = height;
111 glViewport(0, 0, width, height);
112 glMatrixMode(GL_PROJECTION);
113 glLoadIdentity();
114 glOrtho(0, width, 0, height, -1, 1);
115 glMatrixMode(GL_MODELVIEW);
116 glLoadIdentity();
117 }
118
119
120 static void
121 Key(unsigned char key, int x, int y)
122 {
123 (void) x;
124 (void) y;
125 switch (key) {
126 case 'm':
127 case 'M':
128 Mode = (Mode + 1) % NUM_MODES;
129 break;
130 case 'z':
131 case 'Z':
132 Xtrans = Ytrans = 0;
133 printf("Translation: %f, %f\n", Xtrans, Ytrans);
134 break;
135 case 27:
136 glutDestroyWindow(Win);
137 exit(0);
138 break;
139 }
140 glutPostRedisplay();
141 }
142
143
144 static void
145 SpecialKey(int key, int x, int y)
146 {
147 (void) x;
148 (void) y;
149 switch (key) {
150 case GLUT_KEY_UP:
151 Ytrans += Step;
152 break;
153 case GLUT_KEY_DOWN:
154 Ytrans -= Step;
155 break;
156 case GLUT_KEY_LEFT:
157 Xtrans -= Step;
158 break;
159 case GLUT_KEY_RIGHT:
160 Xtrans += Step;
161 break;
162 }
163 glutPostRedisplay();
164 printf("Translation: %f, %f\n", Xtrans, Ytrans);
165 }
166
167
168 static void
169 Init(void)
170 {
171 }
172
173
174 static void
175 Usage(void)
176 {
177 printf("Keys:\n");
178 printf(" up/down/left/right - translate by %f\n", Step);
179 printf(" z - reset translation to zero\n");
180 printf(" m - change rendering mode (points, hlines, vlines, quads)\n");
181 printf(" Esc - exit\n");
182 }
183
184
185 int
186 main(int argc, char *argv[])
187 {
188 glutInit(&argc, argv);
189 glutInitWindowPosition(0, 0);
190 glutInitWindowSize(Width, Height);
191 glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE);
192 Win = glutCreateWindow(argv[0]);
193 glewInit();
194 glutReshapeFunc(Reshape);
195 glutKeyboardFunc(Key);
196 glutSpecialFunc(SpecialKey);
197 glutDisplayFunc(Draw);
198 Init();
199 Usage();
200 glutMainLoop();
201 return 0;
202 }