Merge commit 'origin/gallium-0.1' into gallium-0.2
[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/glut.h>
30
31 static int Width = 400, Height = 400;
32 static int Win;
33 static float Xtrans = 0, Ytrans = 0;
34 static float Step = 0.125;
35
36 enum {
37 POINTS,
38 HLINES,
39 VLINES,
40 QUADS,
41 NUM_MODES
42 };
43
44 static int Mode = POINTS;
45
46
47 static void
48 Draw(void)
49 {
50 /* See the OpenGL Programming Guide, Appendix H, "OpenGL Correctness Tips"
51 * for information about the 0.375 translation factor.
52 */
53 float tx = 0.375, ty = 0.375;
54 int i, j;
55
56 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
57
58 glPushMatrix();
59 glTranslatef(tx + Xtrans, ty + Ytrans, 0);
60
61 if (Mode == POINTS) {
62 glBegin(GL_POINTS);
63 for (j = 0; j < Height; j += 2) {
64 for (i = 0; i < Width; i += 2) {
65 glVertex2f(i, j);
66 }
67 }
68 glEnd();
69 }
70 else if (Mode == HLINES) {
71 glBegin(GL_LINES);
72 for (i = 0; i < Height; i += 2) {
73 glVertex2f(0, i);
74 glVertex2f(Width, i);
75 }
76 glEnd();
77 }
78 else if (Mode == VLINES) {
79 glBegin(GL_LINES);
80 for (i = 0; i < Width; i += 2) {
81 glVertex2f(i, 0 );
82 glVertex2f(i, Height);
83 }
84 glEnd();
85 }
86 else if (Mode == QUADS) {
87 glBegin(GL_QUADS);
88 for (j = 0; j < Height; j += 4) {
89 for (i = 0; i < Width; i += 4) {
90 glVertex2f(i, j );
91 glVertex2f(i + 3, j );
92 glVertex2f(i + 3, j + 3);
93 glVertex2f(i, j + 3);
94 }
95 }
96 glEnd();
97 }
98
99 glPopMatrix();
100
101 glutSwapBuffers();
102 }
103
104
105 static void
106 Reshape(int width, int height)
107 {
108 Width = width;
109 Height = height;
110 glViewport(0, 0, width, height);
111 glMatrixMode(GL_PROJECTION);
112 glLoadIdentity();
113 glOrtho(0, width, 0, height, -1, 1);
114 glMatrixMode(GL_MODELVIEW);
115 glLoadIdentity();
116 }
117
118
119 static void
120 Key(unsigned char key, int x, int y)
121 {
122 (void) x;
123 (void) y;
124 switch (key) {
125 case 'm':
126 case 'M':
127 Mode = (Mode + 1) % NUM_MODES;
128 break;
129 case 'z':
130 case 'Z':
131 Xtrans = Ytrans = 0;
132 printf("Translation: %f, %f\n", Xtrans, Ytrans);
133 break;
134 case 27:
135 glutDestroyWindow(Win);
136 exit(0);
137 break;
138 }
139 glutPostRedisplay();
140 }
141
142
143 static void
144 SpecialKey(int key, int x, int y)
145 {
146 (void) x;
147 (void) y;
148 switch (key) {
149 case GLUT_KEY_UP:
150 Ytrans += Step;
151 break;
152 case GLUT_KEY_DOWN:
153 Ytrans -= Step;
154 break;
155 case GLUT_KEY_LEFT:
156 Xtrans -= Step;
157 break;
158 case GLUT_KEY_RIGHT:
159 Xtrans += Step;
160 break;
161 }
162 glutPostRedisplay();
163 printf("Translation: %f, %f\n", Xtrans, Ytrans);
164 }
165
166
167 static void
168 Init(void)
169 {
170 }
171
172
173 static void
174 Usage(void)
175 {
176 printf("Keys:\n");
177 printf(" up/down/left/right - translate by %f\n", Step);
178 printf(" z - reset translation to zero\n");
179 printf(" m - change rendering mode (points, hlines, vlines, quads)\n");
180 printf(" Esc - exit\n");
181 }
182
183
184 int
185 main(int argc, char *argv[])
186 {
187 glutInit(&argc, argv);
188 glutInitWindowPosition(0, 0);
189 glutInitWindowSize(Width, Height);
190 glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE);
191 Win = glutCreateWindow(argv[0]);
192 glutReshapeFunc(Reshape);
193 glutKeyboardFunc(Key);
194 glutSpecialFunc(SpecialKey);
195 glutDisplayFunc(Draw);
196 Init();
197 Usage();
198 glutMainLoop();
199 return 0;
200 }