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

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