mesa/progs/tests/exactrast.c

203 lines
4.1 KiB
C

/**
* 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/glew.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 {
MODE_POINTS,
MODE_HLINES,
MODE_VLINES,
MODE_QUADS,
NUM_MODES
};
static int Mode = 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 == 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 == MODE_HLINES) {
glBegin(GL_LINES);
for (i = 0; i < Height; i += 2) {
glVertex2f(0, i);
glVertex2f(Width, i);
}
glEnd();
}
else if (Mode == MODE_VLINES) {
glBegin(GL_LINES);
for (i = 0; i < Width; i += 2) {
glVertex2f(i, 0 );
glVertex2f(i, Height);
}
glEnd();
}
else if (Mode == 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]);
glewInit();
glutReshapeFunc(Reshape);
glutKeyboardFunc(Key);
glutSpecialFunc(SpecialKey);
glutDisplayFunc(Draw);
Init();
Usage();
glutMainLoop();
return 0;
}