diff options
Diffstat (limited to 'progs/tests/exactrast.c')
-rw-r--r-- | progs/tests/exactrast.c | 200 |
1 files changed, 200 insertions, 0 deletions
diff --git a/progs/tests/exactrast.c b/progs/tests/exactrast.c new file mode 100644 index 000000000..56c0c79c3 --- /dev/null +++ b/progs/tests/exactrast.c @@ -0,0 +1,200 @@ +/** + * Test for exact point/line/polygon rasterization, or at least rasterization + * that fits the tolerance of the OpenGL spec. + * + * Brian Paul + * 9 Nov 2007 + */ + +/* + * Notes: + * - 'm' to cycle through point, hline, vline and quad drawing + * - Use cursor keys to translate coordinates (z to reset) + * - Resize window to check for proper rasterization + * - Make sure your LCD is running in its native resolution + * + * If translation is (0,0): + * a point will be drawn where x%2==0 and y%2==0, + * a horizontal line will be drawn where x%2==0, + * a vertical line will be drawn where y%2==0, + * for quads, pixels will be set where (x%4)!=3 and (y%4)!=3 + * + * XXX todo: do glReadPixels and test that the results are what's expected. + * Upon failure, iterate over sub-pixel translations to find the ideal offset. + */ + + +#include <stdio.h> +#include <stdlib.h> +#include <GL/glut.h> + +static int Width = 400, Height = 400; +static int Win; +static float Xtrans = 0, Ytrans = 0; +static float Step = 0.125; + +enum { + POINTS, + HLINES, + VLINES, + QUADS, + NUM_MODES +}; + +static int Mode = POINTS; + + +static void +Draw(void) +{ + /* See the OpenGL Programming Guide, Appendix H, "OpenGL Correctness Tips" + * for information about the 0.375 translation factor. + */ + float tx = 0.375, ty = 0.375; + int i, j; + + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + glPushMatrix(); + glTranslatef(tx + Xtrans, ty + Ytrans, 0); + + if (Mode == POINTS) { + glBegin(GL_POINTS); + for (j = 0; j < Height; j += 2) { + for (i = 0; i < Width; i += 2) { + glVertex2f(i, j); + } + } + glEnd(); + } + else if (Mode == HLINES) { + glBegin(GL_LINES); + for (i = 0; i < Height; i += 2) { + glVertex2f(0, i); + glVertex2f(Width, i); + } + glEnd(); + } + else if (Mode == VLINES) { + glBegin(GL_LINES); + for (i = 0; i < Width; i += 2) { + glVertex2f(i, 0 ); + glVertex2f(i, Height); + } + glEnd(); + } + else if (Mode == QUADS) { + glBegin(GL_QUADS); + for (j = 0; j < Height; j += 4) { + for (i = 0; i < Width; i += 4) { + glVertex2f(i, j ); + glVertex2f(i + 3, j ); + glVertex2f(i + 3, j + 3); + glVertex2f(i, j + 3); + } + } + glEnd(); + } + + glPopMatrix(); + + glutSwapBuffers(); +} + + +static void +Reshape(int width, int height) +{ + Width = width; + Height = height; + glViewport(0, 0, width, height); + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + glOrtho(0, width, 0, height, -1, 1); + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); +} + + +static void +Key(unsigned char key, int x, int y) +{ + (void) x; + (void) y; + switch (key) { + case 'm': + case 'M': + Mode = (Mode + 1) % NUM_MODES; + break; + case 'z': + case 'Z': + Xtrans = Ytrans = 0; + printf("Translation: %f, %f\n", Xtrans, Ytrans); + break; + case 27: + glutDestroyWindow(Win); + exit(0); + break; + } + glutPostRedisplay(); +} + + +static void +SpecialKey(int key, int x, int y) +{ + (void) x; + (void) y; + switch (key) { + case GLUT_KEY_UP: + Ytrans += Step; + break; + case GLUT_KEY_DOWN: + Ytrans -= Step; + break; + case GLUT_KEY_LEFT: + Xtrans -= Step; + break; + case GLUT_KEY_RIGHT: + Xtrans += Step; + break; + } + glutPostRedisplay(); + printf("Translation: %f, %f\n", Xtrans, Ytrans); +} + + +static void +Init(void) +{ +} + + +static void +Usage(void) +{ + printf("Keys:\n"); + printf(" up/down/left/right - translate by %f\n", Step); + printf(" z - reset translation to zero\n"); + printf(" m - change rendering mode (points, hlines, vlines, quads)\n"); + printf(" Esc - exit\n"); +} + + +int +main(int argc, char *argv[]) +{ + glutInit(&argc, argv); + glutInitWindowPosition(0, 0); + glutInitWindowSize(Width, Height); + glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE); + Win = glutCreateWindow(argv[0]); + glutReshapeFunc(Reshape); + glutKeyboardFunc(Key); + glutSpecialFunc(SpecialKey); + glutDisplayFunc(Draw); + Init(); + Usage(); + glutMainLoop(); + return 0; +} |