123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395 |
- /*
- * Automatic primitive rasterization precision test.
- *
- * Draw prims at various sub-pixel offsets and examine where the quad is
- * actually drawn.
- * Check if the range of offsets which paint the right pixels falls within
- * OpenGL's specification.
- * In case of failures, report the coordinate bias needed to fix the problem.
- *
- * Note that even Mesa/swrast fails some line tests. This is because some
- * window coordinates wind up as 53.9999 instead of 54, for example. Enabling
- * the small translation factor below fixes that. Revisit someday...
- *
- * Brian Paul
- * 28 Feb 2008
- */
-
-
- #include <assert.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <GL/glut.h>
-
-
- static int Width = 100, Height = 100;
- static int Win;
- static float Step = 0.125;
- #if 0
- /* This tiny offset fixes errors in Mesa/Xlib */
- static float Xtrans = 0.5 * 0.125;
- static float Ytrans = 0.5 * 0.125;
- #else
- static float Xtrans = 0.0;
- static float Ytrans = 0.0;
- #endif
-
-
- static void
- PointCalibrate(int xpos, int ypos)
- {
- GLfloat rgba[4];
- float x, y;
- float xmin, ymin, xmax, ymax;
-
- xmin = ymin = 1000.0;
- xmax = ymax = -1000.0;
-
- for (y = -1.0; y <= 1.0; y += Step) {
- for (x = -1.0; x <= 1.0; x += Step) {
- glClear(GL_COLOR_BUFFER_BIT);
- glBegin(GL_POINTS);
- glVertex2f(xpos + x, ypos + y);
- glEnd();
- glReadPixels(xpos, ypos, 1, 1, GL_RGBA, GL_FLOAT, rgba);
- if (rgba[0] == 1.0 && rgba[1] == 1.0 && rgba[2] == 1.0) {
- /* hit */
- if (x < xmin)
- xmin = x;
- if (y < ymin)
- ymin = y;
- if (x > xmax)
- xmax = x;
- if (y > ymax)
- ymax = y;
- }
- }
- }
-
- printf("Point at (%2d, %2d) drawn for x in [%6.3f, %6.3f] and y in [%6.3f, %6.3f]\n",
- xpos, ypos,
- xpos + xmin, xpos + xmax,
- ypos + ymin, ypos + ymax);
-
- if (xmax - xmin != 1.0 - Step) {
- printf(" => Inconsistant X-axis rasterization!\n");
- }
- if (ymax - ymin != 1.0 - Step) {
- printf(" => Inconsistant Y-axis rasterization!\n");
- }
- if (xmin < 0.0) {
- printf(" => Points should be X biased by about %f\n", xmin);
- }
- if (ymin < 0.0) {
- printf(" => Points should be Y biased by about %f\n", ymin);
- }
- if (xmax > 1.0) {
- printf(" => Points should be X biased by about %f\n", 1.0 - xmax);
- }
- if (ymax > 1.0) {
- printf(" => Points should be Y biased by about %f\n", 1.0 - ymax);
- }
-
- }
-
-
- /**
- * XXX Implement VLineCalibrate() someday
- */
- static void
- HLineCalibrate(int xpos, int ypos, int len)
- {
- GLfloat rgba[2][4];
- float x, y;
- float ymin, ymax;
- float xmin_left, xmax_left, xmin_right, xmax_right;
-
- xmin_left = xmin_right = 1000.0;
- xmax_left = xmax_right = -1000.0;
- ymin = 1000;
- ymax = -1000.0;
-
- /*
- * First, check vertical positioning of the horizontal line
- */
- for (y = -1.0; y <= 1.0; y += Step) {
- glClear(GL_COLOR_BUFFER_BIT);
- glBegin(GL_LINES);
- glVertex2f(xpos, ypos + y);
- glVertex2f(xpos + len, ypos + y);
- glEnd();
-
- glReadPixels(xpos + len / 2, ypos, 1, 1, GL_RGBA, GL_FLOAT, rgba);
- if (rgba[0][0] == 1.0) {
- /* hit */
- if (y < ymin)
- ymin = y;
- if (y > ymax)
- ymax = y;
- }
- }
-
- printf("H-line at Y=%2d drawn for y in [%6.3f, %6.3f]\n",
- ypos,
- ypos + ymin, ypos + ymax);
-
- if (ymax - ymin != 1.0 - Step) {
- printf(" => Inconsistant Y-axis rasterization!\n");
- }
-
- if (ymin > 0.5 ) {
- printf(" => Lines should be Y biased by about %f\n", ymin - 0.5);
- }
-
- if (ymax < 0.5 ) {
- printf(" => Lines should be Y biased by about %f\n", 0.5 - ymax);
- }
-
- /*
- * Second, check endpoints (for Y at 1/2 pixel)
- */
- for (x = -1.0; x <= 1.0; x += Step) {
- glClear(GL_COLOR_BUFFER_BIT);
- glBegin(GL_LINES);
- glVertex2f(xpos + x, ypos + 0.5f);
- glVertex2f(xpos + x + len, ypos + 0.5f);
- glEnd();
-
- /* left end */
- glReadPixels(xpos - 1, ypos, 2, 1, GL_RGBA, GL_FLOAT, rgba);
- if (rgba[0][0] == 0.0 && rgba[1][0] == 1.0) {
- /* hit */
- if (x < xmin_left)
- xmin_left = x;
- if (x > xmax_left)
- xmax_left = x;
- }
-
- /* right end */
- glReadPixels(xpos + len - 1, ypos, 2, 1, GL_RGBA, GL_FLOAT, rgba);
- if (rgba[0][0] == 1.0 && rgba[1][0] == 0.0) {
- /* hit */
- if (x < xmin_right)
- xmin_right = x;
- if (x > xmax_right)
- xmax_right = x;
- }
- }
-
- printf("H-line [%d..%d) hit left end for x in [%6.3f, %6.3f] "
- "hit right end for x in [%6.3f, %6.3f]\n",
- xpos, xpos + len,
- xpos + xmin_left, xpos + xmax_left,
- xpos + len + xmin_right, xpos + len + xmax_right);
-
- if (xmax_left - xmin_left > 1.0 - Step) {
- printf(" => Inconsistant left-end rasterization!\n");
- }
- if (xmax_right - xmin_right > 1.0 - Step) {
- printf(" => Inconsistant right-end rasterization!\n");
- }
-
- if (xmin_left != xmin_right ||
- xmax_left != xmax_right) {
- printf(" => Inconsistant length!\n");
- }
-
- if (xmin_left < 0.0) {
- printf(" => Coords should be X biased by about %f\n", xmin_left );
- }
- if (xmin_right < 0.0) {
- printf(" => Coords should be X biased by about %f\n", xmin_right );
- }
- if (xmax_left >= 1.0) {
- printf(" => Coords should be X biased by about %f\n", -xmax_right + 1.0);
- }
- if (xmax_right >= 1.0) {
- printf(" => Coords should be X biased by about %f\n", -xmax_right + 1.0);
- }
-
- }
-
-
- static void
- QuadCalibrate(int xpos, int ypos, int width, int height)
- {
- GLfloat rgba1[2][4];
- GLfloat rgba2[2][4];
- float x, y;
- float xmin, ymin, xmax, ymax;
-
- xmin = ymin = 1000.0;
- xmax = ymax = -1000.0;
-
- for (y = -1.0; y <= 1.0; y += Step) {
- for (x = -1.0; x <= 1.0; x += Step) {
- glClear(GL_COLOR_BUFFER_BIT);
- glBegin(GL_QUADS);
- glVertex2f(xpos + x, ypos + y);
- glVertex2f(xpos + x + width, ypos + y);
- glVertex2f(xpos + x + width, ypos + y + height);
- glVertex2f(xpos + x, ypos + y + height);
- glEnd();
-
- /* horizontal measurement */
- glReadPixels(xpos - 1, ypos + 2, 2, 1, GL_RGBA, GL_FLOAT, rgba1);
- glReadPixels(xpos + width - 1, ypos + 2, 2, 1, GL_RGBA, GL_FLOAT, rgba2);
- if (rgba1[0][0] == 0.0 && rgba1[1][0] == 1.0 &&
- rgba2[0][0] == 1.0 && rgba2[1][0] == 0.0) {
- if (x < xmin)
- xmin = x;
- if (x > xmax)
- xmax = x;
- }
-
- /* vertical measurement */
- glReadPixels(xpos + 2, ypos - 1, 1, 2, GL_RGBA, GL_FLOAT, rgba1);
- glReadPixels(xpos + 2, ypos + height - 1, 1, 2, GL_RGBA, GL_FLOAT, rgba2);
- if (rgba1[0][0] == 0.0 && rgba1[1][0] == 1.0 &&
- rgba2[0][0] == 1.0 && rgba2[1][0] == 0.0) {
- if (y < ymin)
- ymin = y;
- if (y > ymax)
- ymax = y;
- }
- }
- }
-
- printf("Quad at (%2d, %2d)..(%2d, %2d) drawn"
- " for x in [%6.3f, %6.3f] and y in [%6.3f, %6.3f]\n",
- xpos, ypos,
- xpos + width, ypos + height,
- xpos + xmin, xpos + xmax,
- ypos + ymin, ypos + ymax);
-
- if (xmax - xmin != 1.0 - Step) {
- printf(" => Inconsistant X-axis rasterization/size!\n");
- }
- if (ymax - ymin != 1.0 - Step) {
- printf(" => Inconsistant Y-axis rasterization/size!\n");
- }
-
- if (xmin < -0.5) {
- printf(" => Coords should be X biased by about %f\n", 0.5 + xmin );
- }
- if (ymin < -0.5) {
- printf(" => Coords should be Y biased by about %f\n", 0.5 + ymin);
- }
- if (xmax > 0.5) {
- printf(" => Coords should be X biased by about %f\n", -xmax + 0.5);
- }
- if (ymax > 0.5) {
- printf(" => Coords should be Y biased by about %f\n", -ymax + 0.5);
- }
- }
-
-
- /**
- * Misc/disabled code for debugging.
- */
- static void
- DebugTest(void)
- {
- glClear(GL_COLOR_BUFFER_BIT);
- glEnable(GL_BLEND);
- glBlendFunc(GL_ONE, GL_ONE);
-
- glColor3f(.5, .5, .5);
-
- glBegin(GL_LINES);
- glVertex2f(30, 35.5);
- glVertex2f(54, 35.5);
- glVertex2f(54, 35.5);
- glVertex2f(66, 35.5);
- glEnd();
-
- glDisable(GL_BLEND);
- glColor3f(1,1,1);
- }
-
-
- static void
- Draw(void)
- {
- glClear(GL_COLOR_BUFFER_BIT);
-
- glPushMatrix();
- glTranslatef(Xtrans, Ytrans, 0);
-
- PointCalibrate(1, 1);
- PointCalibrate(50, 50);
- PointCalibrate(28, 17);
- PointCalibrate(17, 18);
- printf("\n");
-
- HLineCalibrate(5, 10, 10);
- HLineCalibrate(25, 22, 12);
- HLineCalibrate(54, 33, 12);
- HLineCalibrate(54+12, 33, 12);
- printf("\n");
-
- QuadCalibrate(2, 2, 10, 10);
- QuadCalibrate(50, 50, 10, 10);
- QuadCalibrate(28, 17, 12, 12);
- QuadCalibrate(17, 28, 12, 12);
-
- (void) DebugTest;
-
- 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 27:
- glutDestroyWindow(Win);
- exit(0);
- break;
- }
- glutPostRedisplay();
- }
-
-
- static void
- Init(void)
- {
- printf("Measurement/callibration for basic prim rasterization...\n");
- printf("GL_RENDERER: %s\n", (char*) glGetString(GL_RENDERER));
- }
-
-
- 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);
- glutDisplayFunc(Draw);
- Init();
- glutMainLoop();
- return 0;
- }
|