blob: 63b8336d97321c9132f397cf372fff2c7024c899 [file] [log] [blame]
Brian57864192007-11-09 17:02:12 -07001/**
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>
Keith Whitwella58065d2009-03-10 13:11:23 +000029#include <GL/glew.h>
Brian57864192007-11-09 17:02:12 -070030#include <GL/glut.h>
31
32static int Width = 400, Height = 400;
33static int Win;
34static float Xtrans = 0, Ytrans = 0;
35static float Step = 0.125;
36
37enum {
Keith Whitwella58065d2009-03-10 13:11:23 +000038 MODE_POINTS,
39 MODE_HLINES,
40 MODE_VLINES,
41 MODE_QUADS,
Brian57864192007-11-09 17:02:12 -070042 NUM_MODES
43};
44
Keith Whitwella58065d2009-03-10 13:11:23 +000045static int Mode = MODE_POINTS;
Brian57864192007-11-09 17:02:12 -070046
47
48static void
49Draw(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
Keith Whitwella58065d2009-03-10 13:11:23 +000062 if (Mode == MODE_POINTS) {
Brian57864192007-11-09 17:02:12 -070063 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 }
Keith Whitwella58065d2009-03-10 13:11:23 +000071 else if (Mode == MODE_HLINES) {
Brian57864192007-11-09 17:02:12 -070072 glBegin(GL_LINES);
73 for (i = 0; i < Height; i += 2) {
74 glVertex2f(0, i);
75 glVertex2f(Width, i);
76 }
77 glEnd();
78 }
Keith Whitwella58065d2009-03-10 13:11:23 +000079 else if (Mode == MODE_VLINES) {
Brian57864192007-11-09 17:02:12 -070080 glBegin(GL_LINES);
81 for (i = 0; i < Width; i += 2) {
82 glVertex2f(i, 0 );
83 glVertex2f(i, Height);
84 }
85 glEnd();
86 }
Keith Whitwella58065d2009-03-10 13:11:23 +000087 else if (Mode == MODE_QUADS) {
Brian57864192007-11-09 17:02:12 -070088 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
106static void
107Reshape(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
120static void
121Key(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
144static void
145SpecialKey(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
168static void
169Init(void)
170{
171}
172
173
174static void
175Usage(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
185int
186main(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]);
Keith Whitwella58065d2009-03-10 13:11:23 +0000193 glewInit();
Brian57864192007-11-09 17:02:12 -0700194 glutReshapeFunc(Reshape);
195 glutKeyboardFunc(Key);
196 glutSpecialFunc(SpecialKey);
197 glutDisplayFunc(Draw);
198 Init();
199 Usage();
200 glutMainLoop();
201 return 0;
202}