Clone of mesa.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

calibrate_rast.c 9.7KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395
  1. /*
  2. * Automatic primitive rasterization precision test.
  3. *
  4. * Draw prims at various sub-pixel offsets and examine where the quad is
  5. * actually drawn.
  6. * Check if the range of offsets which paint the right pixels falls within
  7. * OpenGL's specification.
  8. * In case of failures, report the coordinate bias needed to fix the problem.
  9. *
  10. * Note that even Mesa/swrast fails some line tests. This is because some
  11. * window coordinates wind up as 53.9999 instead of 54, for example. Enabling
  12. * the small translation factor below fixes that. Revisit someday...
  13. *
  14. * Brian Paul
  15. * 28 Feb 2008
  16. */
  17. #include <assert.h>
  18. #include <stdio.h>
  19. #include <stdlib.h>
  20. #include <GL/glut.h>
  21. static int Width = 100, Height = 100;
  22. static int Win;
  23. static float Step = 0.125;
  24. #if 0
  25. /* This tiny offset fixes errors in Mesa/Xlib */
  26. static float Xtrans = 0.5 * 0.125;
  27. static float Ytrans = 0.5 * 0.125;
  28. #else
  29. static float Xtrans = 0.0;
  30. static float Ytrans = 0.0;
  31. #endif
  32. static void
  33. PointCalibrate(int xpos, int ypos)
  34. {
  35. GLfloat rgba[4];
  36. float x, y;
  37. float xmin, ymin, xmax, ymax;
  38. xmin = ymin = 1000.0;
  39. xmax = ymax = -1000.0;
  40. for (y = -1.0; y <= 1.0; y += Step) {
  41. for (x = -1.0; x <= 1.0; x += Step) {
  42. glClear(GL_COLOR_BUFFER_BIT);
  43. glBegin(GL_POINTS);
  44. glVertex2f(xpos + x, ypos + y);
  45. glEnd();
  46. glReadPixels(xpos, ypos, 1, 1, GL_RGBA, GL_FLOAT, rgba);
  47. if (rgba[0] == 1.0 && rgba[1] == 1.0 && rgba[2] == 1.0) {
  48. /* hit */
  49. if (x < xmin)
  50. xmin = x;
  51. if (y < ymin)
  52. ymin = y;
  53. if (x > xmax)
  54. xmax = x;
  55. if (y > ymax)
  56. ymax = y;
  57. }
  58. }
  59. }
  60. printf("Point at (%2d, %2d) drawn for x in [%6.3f, %6.3f] and y in [%6.3f, %6.3f]\n",
  61. xpos, ypos,
  62. xpos + xmin, xpos + xmax,
  63. ypos + ymin, ypos + ymax);
  64. if (xmax - xmin != 1.0 - Step) {
  65. printf(" => Inconsistant X-axis rasterization!\n");
  66. }
  67. if (ymax - ymin != 1.0 - Step) {
  68. printf(" => Inconsistant Y-axis rasterization!\n");
  69. }
  70. if (xmin < 0.0) {
  71. printf(" => Points should be X biased by about %f\n", xmin);
  72. }
  73. if (ymin < 0.0) {
  74. printf(" => Points should be Y biased by about %f\n", ymin);
  75. }
  76. if (xmax > 1.0) {
  77. printf(" => Points should be X biased by about %f\n", 1.0 - xmax);
  78. }
  79. if (ymax > 1.0) {
  80. printf(" => Points should be Y biased by about %f\n", 1.0 - ymax);
  81. }
  82. }
  83. /**
  84. * XXX Implement VLineCalibrate() someday
  85. */
  86. static void
  87. HLineCalibrate(int xpos, int ypos, int len)
  88. {
  89. GLfloat rgba[2][4];
  90. float x, y;
  91. float ymin, ymax;
  92. float xmin_left, xmax_left, xmin_right, xmax_right;
  93. xmin_left = xmin_right = 1000.0;
  94. xmax_left = xmax_right = -1000.0;
  95. ymin = 1000;
  96. ymax = -1000.0;
  97. /*
  98. * First, check vertical positioning of the horizontal line
  99. */
  100. for (y = -1.0; y <= 1.0; y += Step) {
  101. glClear(GL_COLOR_BUFFER_BIT);
  102. glBegin(GL_LINES);
  103. glVertex2f(xpos, ypos + y);
  104. glVertex2f(xpos + len, ypos + y);
  105. glEnd();
  106. glReadPixels(xpos + len / 2, ypos, 1, 1, GL_RGBA, GL_FLOAT, rgba);
  107. if (rgba[0][0] == 1.0) {
  108. /* hit */
  109. if (y < ymin)
  110. ymin = y;
  111. if (y > ymax)
  112. ymax = y;
  113. }
  114. }
  115. printf("H-line at Y=%2d drawn for y in [%6.3f, %6.3f]\n",
  116. ypos,
  117. ypos + ymin, ypos + ymax);
  118. if (ymax - ymin != 1.0 - Step) {
  119. printf(" => Inconsistant Y-axis rasterization!\n");
  120. }
  121. if (ymin > 0.5 ) {
  122. printf(" => Lines should be Y biased by about %f\n", ymin - 0.5);
  123. }
  124. if (ymax < 0.5 ) {
  125. printf(" => Lines should be Y biased by about %f\n", 0.5 - ymax);
  126. }
  127. /*
  128. * Second, check endpoints (for Y at 1/2 pixel)
  129. */
  130. for (x = -1.0; x <= 1.0; x += Step) {
  131. glClear(GL_COLOR_BUFFER_BIT);
  132. glBegin(GL_LINES);
  133. glVertex2f(xpos + x, ypos + 0.5f);
  134. glVertex2f(xpos + x + len, ypos + 0.5f);
  135. glEnd();
  136. /* left end */
  137. glReadPixels(xpos - 1, ypos, 2, 1, GL_RGBA, GL_FLOAT, rgba);
  138. if (rgba[0][0] == 0.0 && rgba[1][0] == 1.0) {
  139. /* hit */
  140. if (x < xmin_left)
  141. xmin_left = x;
  142. if (x > xmax_left)
  143. xmax_left = x;
  144. }
  145. /* right end */
  146. glReadPixels(xpos + len - 1, ypos, 2, 1, GL_RGBA, GL_FLOAT, rgba);
  147. if (rgba[0][0] == 1.0 && rgba[1][0] == 0.0) {
  148. /* hit */
  149. if (x < xmin_right)
  150. xmin_right = x;
  151. if (x > xmax_right)
  152. xmax_right = x;
  153. }
  154. }
  155. printf("H-line [%d..%d) hit left end for x in [%6.3f, %6.3f] "
  156. "hit right end for x in [%6.3f, %6.3f]\n",
  157. xpos, xpos + len,
  158. xpos + xmin_left, xpos + xmax_left,
  159. xpos + len + xmin_right, xpos + len + xmax_right);
  160. if (xmax_left - xmin_left > 1.0 - Step) {
  161. printf(" => Inconsistant left-end rasterization!\n");
  162. }
  163. if (xmax_right - xmin_right > 1.0 - Step) {
  164. printf(" => Inconsistant right-end rasterization!\n");
  165. }
  166. if (xmin_left != xmin_right ||
  167. xmax_left != xmax_right) {
  168. printf(" => Inconsistant length!\n");
  169. }
  170. if (xmin_left < 0.0) {
  171. printf(" => Coords should be X biased by about %f\n", xmin_left );
  172. }
  173. if (xmin_right < 0.0) {
  174. printf(" => Coords should be X biased by about %f\n", xmin_right );
  175. }
  176. if (xmax_left >= 1.0) {
  177. printf(" => Coords should be X biased by about %f\n", -xmax_right + 1.0);
  178. }
  179. if (xmax_right >= 1.0) {
  180. printf(" => Coords should be X biased by about %f\n", -xmax_right + 1.0);
  181. }
  182. }
  183. static void
  184. QuadCalibrate(int xpos, int ypos, int width, int height)
  185. {
  186. GLfloat rgba1[2][4];
  187. GLfloat rgba2[2][4];
  188. float x, y;
  189. float xmin, ymin, xmax, ymax;
  190. xmin = ymin = 1000.0;
  191. xmax = ymax = -1000.0;
  192. for (y = -1.0; y <= 1.0; y += Step) {
  193. for (x = -1.0; x <= 1.0; x += Step) {
  194. glClear(GL_COLOR_BUFFER_BIT);
  195. glBegin(GL_QUADS);
  196. glVertex2f(xpos + x, ypos + y);
  197. glVertex2f(xpos + x + width, ypos + y);
  198. glVertex2f(xpos + x + width, ypos + y + height);
  199. glVertex2f(xpos + x, ypos + y + height);
  200. glEnd();
  201. /* horizontal measurement */
  202. glReadPixels(xpos - 1, ypos + 2, 2, 1, GL_RGBA, GL_FLOAT, rgba1);
  203. glReadPixels(xpos + width - 1, ypos + 2, 2, 1, GL_RGBA, GL_FLOAT, rgba2);
  204. if (rgba1[0][0] == 0.0 && rgba1[1][0] == 1.0 &&
  205. rgba2[0][0] == 1.0 && rgba2[1][0] == 0.0) {
  206. if (x < xmin)
  207. xmin = x;
  208. if (x > xmax)
  209. xmax = x;
  210. }
  211. /* vertical measurement */
  212. glReadPixels(xpos + 2, ypos - 1, 1, 2, GL_RGBA, GL_FLOAT, rgba1);
  213. glReadPixels(xpos + 2, ypos + height - 1, 1, 2, GL_RGBA, GL_FLOAT, rgba2);
  214. if (rgba1[0][0] == 0.0 && rgba1[1][0] == 1.0 &&
  215. rgba2[0][0] == 1.0 && rgba2[1][0] == 0.0) {
  216. if (y < ymin)
  217. ymin = y;
  218. if (y > ymax)
  219. ymax = y;
  220. }
  221. }
  222. }
  223. printf("Quad at (%2d, %2d)..(%2d, %2d) drawn"
  224. " for x in [%6.3f, %6.3f] and y in [%6.3f, %6.3f]\n",
  225. xpos, ypos,
  226. xpos + width, ypos + height,
  227. xpos + xmin, xpos + xmax,
  228. ypos + ymin, ypos + ymax);
  229. if (xmax - xmin != 1.0 - Step) {
  230. printf(" => Inconsistant X-axis rasterization/size!\n");
  231. }
  232. if (ymax - ymin != 1.0 - Step) {
  233. printf(" => Inconsistant Y-axis rasterization/size!\n");
  234. }
  235. if (xmin < -0.5) {
  236. printf(" => Coords should be X biased by about %f\n", 0.5 + xmin );
  237. }
  238. if (ymin < -0.5) {
  239. printf(" => Coords should be Y biased by about %f\n", 0.5 + ymin);
  240. }
  241. if (xmax > 0.5) {
  242. printf(" => Coords should be X biased by about %f\n", -xmax + 0.5);
  243. }
  244. if (ymax > 0.5) {
  245. printf(" => Coords should be Y biased by about %f\n", -ymax + 0.5);
  246. }
  247. }
  248. /**
  249. * Misc/disabled code for debugging.
  250. */
  251. static void
  252. DebugTest(void)
  253. {
  254. glClear(GL_COLOR_BUFFER_BIT);
  255. glEnable(GL_BLEND);
  256. glBlendFunc(GL_ONE, GL_ONE);
  257. glColor3f(.5, .5, .5);
  258. glBegin(GL_LINES);
  259. glVertex2f(30, 35.5);
  260. glVertex2f(54, 35.5);
  261. glVertex2f(54, 35.5);
  262. glVertex2f(66, 35.5);
  263. glEnd();
  264. glDisable(GL_BLEND);
  265. glColor3f(1,1,1);
  266. }
  267. static void
  268. Draw(void)
  269. {
  270. glClear(GL_COLOR_BUFFER_BIT);
  271. glPushMatrix();
  272. glTranslatef(Xtrans, Ytrans, 0);
  273. PointCalibrate(1, 1);
  274. PointCalibrate(50, 50);
  275. PointCalibrate(28, 17);
  276. PointCalibrate(17, 18);
  277. printf("\n");
  278. HLineCalibrate(5, 10, 10);
  279. HLineCalibrate(25, 22, 12);
  280. HLineCalibrate(54, 33, 12);
  281. HLineCalibrate(54+12, 33, 12);
  282. printf("\n");
  283. QuadCalibrate(2, 2, 10, 10);
  284. QuadCalibrate(50, 50, 10, 10);
  285. QuadCalibrate(28, 17, 12, 12);
  286. QuadCalibrate(17, 28, 12, 12);
  287. (void) DebugTest;
  288. glPopMatrix();
  289. glutSwapBuffers();
  290. }
  291. static void
  292. Reshape(int width, int height)
  293. {
  294. Width = width;
  295. Height = height;
  296. glViewport(0, 0, width, height);
  297. glMatrixMode(GL_PROJECTION);
  298. glLoadIdentity();
  299. glOrtho(0, width, 0, height, -1, 1);
  300. glMatrixMode(GL_MODELVIEW);
  301. glLoadIdentity();
  302. }
  303. static void
  304. Key(unsigned char key, int x, int y)
  305. {
  306. (void) x;
  307. (void) y;
  308. switch (key) {
  309. case 27:
  310. glutDestroyWindow(Win);
  311. exit(0);
  312. break;
  313. }
  314. glutPostRedisplay();
  315. }
  316. static void
  317. Init(void)
  318. {
  319. printf("Measurement/callibration for basic prim rasterization...\n");
  320. printf("GL_RENDERER: %s\n", (char*) glGetString(GL_RENDERER));
  321. }
  322. int
  323. main(int argc, char *argv[])
  324. {
  325. glutInit(&argc, argv);
  326. glutInitWindowPosition(0, 0);
  327. glutInitWindowSize(Width, Height);
  328. glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE);
  329. Win = glutCreateWindow(argv[0]);
  330. glutReshapeFunc(Reshape);
  331. glutKeyboardFunc(Key);
  332. glutDisplayFunc(Draw);
  333. Init();
  334. glutMainLoop();
  335. return 0;
  336. }