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.

texaaline.c 7.4KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372
  1. /**
  2. * AA lines with texture mapped quads
  3. *
  4. * Brian Paul
  5. * 9 Feb 2008
  6. */
  7. #include <assert.h>
  8. #include <string.h>
  9. #include <stdio.h>
  10. #include <stdlib.h>
  11. #include <math.h>
  12. #include <GL/glew.h>
  13. #include <GL/glut.h>
  14. #ifndef M_PI
  15. #define M_PI 3.1415926535
  16. #endif
  17. static GLint WinWidth = 300, WinHeight = 300;
  18. static GLint win = 0;
  19. static GLfloat Width = 8.;
  20. /*
  21. * Quad strip for line from v0 to v1:
  22. *
  23. 1 3 5 7
  24. +---+---------------------+---+
  25. | |
  26. | *v0 v1* |
  27. | |
  28. +---+---------------------+---+
  29. 0 2 4 6
  30. */
  31. static void
  32. QuadLine(const GLfloat *v0, const GLfloat *v1, GLfloat width)
  33. {
  34. GLfloat dx = v1[0] - v0[0];
  35. GLfloat dy = v1[1] - v0[1];
  36. GLfloat len = sqrt(dx*dx + dy*dy);
  37. float dx0, dx1, dx2, dx3, dx4, dx5, dx6, dx7;
  38. float dy0, dy1, dy2, dy3, dy4, dy5, dy6, dy7;
  39. dx /= len;
  40. dy /= len;
  41. width *= 0.5; /* half width */
  42. dx = dx * (width + 0.0);
  43. dy = dy * (width + 0.0);
  44. dx0 = -dx+dy; dy0 = -dy-dx;
  45. dx1 = -dx-dy; dy1 = -dy+dx;
  46. dx2 = 0+dy; dy2 = -dx+0;
  47. dx3 = 0-dy; dy3 = +dx+0;
  48. dx4 = 0+dy; dy4 = -dx+0;
  49. dx5 = 0-dy; dy5 = +dx+0;
  50. dx6 = dx+dy; dy6 = dy-dx;
  51. dx7 = dx-dy; dy7 = dy+dx;
  52. /*
  53. printf("dx, dy = %g, %g\n", dx, dy);
  54. printf(" dx0, dy0: %g, %g\n", dx0, dy0);
  55. printf(" dx1, dy1: %g, %g\n", dx1, dy1);
  56. printf(" dx2, dy2: %g, %g\n", dx2, dy2);
  57. printf(" dx3, dy3: %g, %g\n", dx3, dy3);
  58. */
  59. glBegin(GL_QUAD_STRIP);
  60. glTexCoord2f(0, 0);
  61. glVertex2f(v0[0] + dx0, v0[1] + dy0);
  62. glTexCoord2f(0, 1);
  63. glVertex2f(v0[0] + dx1, v0[1] + dy1);
  64. glTexCoord2f(0.5, 0);
  65. glVertex2f(v0[0] + dx2, v0[1] + dy2);
  66. glTexCoord2f(0.5, 1);
  67. glVertex2f(v0[0] + dx3, v0[1] + dy3);
  68. glTexCoord2f(0.5, 0);
  69. glVertex2f(v1[0] + dx2, v1[1] + dy2);
  70. glTexCoord2f(0.5, 1);
  71. glVertex2f(v1[0] + dx3, v1[1] + dy3);
  72. glTexCoord2f(1, 0);
  73. glVertex2f(v1[0] + dx6, v1[1] + dy6);
  74. glTexCoord2f(1, 1);
  75. glVertex2f(v1[0] + dx7, v1[1] + dy7);
  76. glEnd();
  77. }
  78. static float Cos(float a)
  79. {
  80. return cos(a * M_PI / 180.);
  81. }
  82. static float Sin(float a)
  83. {
  84. return sin(a * M_PI / 180.);
  85. }
  86. static void
  87. Redisplay(void)
  88. {
  89. float cx = 0.5 * WinWidth, cy = 0.5 * WinHeight;
  90. float len = 0.5 * WinWidth - 20.0;
  91. int i;
  92. glClear(GL_COLOR_BUFFER_BIT);
  93. glColor3f(1, 1, 1);
  94. glEnable(GL_BLEND);
  95. glEnable(GL_TEXTURE_2D);
  96. for (i = 0; i < 360; i+=5) {
  97. float v0[2], v1[2];
  98. v0[0] = cx + 40 * Cos(i);
  99. v0[1] = cy + 40 * Sin(i);
  100. v1[0] = cx + len * Cos(i);
  101. v1[1] = cy + len * Sin(i);
  102. QuadLine(v0, v1, Width);
  103. }
  104. {
  105. float v0[2], v1[2], x;
  106. for (x = 0; x < 1.0; x += 0.2) {
  107. v0[0] = cx + x;
  108. v0[1] = cy + x * 40 - 20;
  109. v1[0] = cx + x + 5.0;
  110. v1[1] = cy + x * 40 - 20;
  111. QuadLine(v0, v1, Width);
  112. }
  113. }
  114. glDisable(GL_BLEND);
  115. glDisable(GL_TEXTURE_2D);
  116. glutSwapBuffers();
  117. }
  118. static void
  119. Reshape(int width, int height)
  120. {
  121. WinWidth = width;
  122. WinHeight = height;
  123. glViewport(0, 0, width, height);
  124. glMatrixMode(GL_PROJECTION);
  125. glLoadIdentity();
  126. glOrtho(0, width, 0, height, -1, 1);
  127. glMatrixMode(GL_MODELVIEW);
  128. glLoadIdentity();
  129. }
  130. static void
  131. CleanUp(void)
  132. {
  133. glutDestroyWindow(win);
  134. }
  135. static void
  136. Key(unsigned char key, int x, int y)
  137. {
  138. (void) x;
  139. (void) y;
  140. switch(key) {
  141. case 'w':
  142. Width -= 0.5;
  143. break;
  144. case 'W':
  145. Width += 0.5;
  146. break;
  147. case 27:
  148. CleanUp();
  149. exit(0);
  150. break;
  151. }
  152. #if 0
  153. if (Width < 3)
  154. Width = 3;
  155. #endif
  156. printf("Width = %g\n", Width);
  157. glutPostRedisplay();
  158. }
  159. static float
  160. ramp4(GLint i, GLint size)
  161. {
  162. float d;
  163. if (i < 4 ) {
  164. d = i / 4.0;
  165. }
  166. else if (i >= size - 5) {
  167. d = 1.0 - (i - (size - 5)) / 4.0;
  168. }
  169. else {
  170. d = 1.0;
  171. }
  172. return d;
  173. }
  174. static float
  175. ramp2(GLint i, GLint size)
  176. {
  177. float d;
  178. if (i < 2 ) {
  179. d = i / 2.0;
  180. }
  181. else if (i >= size - 3) {
  182. d = 1.0 - (i - (size - 3)) / 2.0;
  183. }
  184. else {
  185. d = 1.0;
  186. }
  187. return d;
  188. }
  189. static float
  190. ramp1(GLint i, GLint size)
  191. {
  192. float d;
  193. if (i == 0 || i == size-1) {
  194. d = 0.0;
  195. }
  196. else {
  197. d = 1.0;
  198. }
  199. return d;
  200. }
  201. /**
  202. * Make an alpha texture for antialiasing lines.
  203. * Just a linear fall-off ramp for now.
  204. * Should have a number of different textures for different line widths.
  205. * Could try a bell-like-curve....
  206. */
  207. static void
  208. MakeTexture(void)
  209. {
  210. #define SZ 8
  211. GLfloat tex[SZ][SZ]; /* alpha tex */
  212. int i, j;
  213. for (i = 0; i < SZ; i++) {
  214. for (j = 0; j < SZ; j++) {
  215. #if 0
  216. float k = (SZ-1) / 2.0;
  217. float dx = fabs(i - k) / k;
  218. float dy = fabs(j - k) / k;
  219. float d;
  220. dx = 1.0 - dx;
  221. dy = 1.0 - dy;
  222. d = dx * dy;
  223. #else
  224. float d = ramp1(i, SZ) * ramp1(j, SZ);
  225. printf("%d, %d: %g\n", i, j, d);
  226. #endif
  227. tex[i][j] = d;
  228. }
  229. }
  230. glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, SZ, SZ, 0, GL_ALPHA, GL_FLOAT, tex);
  231. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
  232. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
  233. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
  234. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  235. glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
  236. #undef SZ
  237. }
  238. static void
  239. MakeMipmap(void)
  240. {
  241. #define SZ 64
  242. GLfloat tex[SZ][SZ]; /* alpha tex */
  243. int level;
  244. glPixelStorei(GL_UNPACK_ROW_LENGTH, SZ);
  245. for (level = 0; level < 7; level++) {
  246. int sz = 1 << (6 - level);
  247. int i, j;
  248. for (i = 0; i < sz; i++) {
  249. for (j = 0; j < sz; j++) {
  250. if (level == 6)
  251. tex[i][j] = 1.0;
  252. else if (level == 5)
  253. tex[i][j] = 0.5;
  254. else
  255. tex[i][j] = ramp1(i, sz) * ramp1(j, sz);
  256. }
  257. }
  258. glTexImage2D(GL_TEXTURE_2D, level, GL_ALPHA,
  259. sz, sz, 0, GL_ALPHA, GL_FLOAT, tex);
  260. }
  261. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
  262. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
  263. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
  264. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  265. /* glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LOD, 4); */
  266. /* glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 5); */
  267. glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
  268. #undef SZ
  269. }
  270. static void
  271. Init(void)
  272. {
  273. const char *version;
  274. (void) MakeTexture;
  275. (void) ramp4;
  276. (void) ramp2;
  277. version = (const char *) glGetString(GL_VERSION);
  278. if (version[0] != '2' || version[1] != '.') {
  279. printf("This program requires OpenGL 2.x, found %s\n", version);
  280. exit(1);
  281. }
  282. glClearColor(0.3f, 0.3f, 0.3f, 0.0f);
  283. printf("GL_RENDERER = %s\n",(const char *) glGetString(GL_RENDERER));
  284. glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
  285. #if 0
  286. glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
  287. #elif 0
  288. MakeTexture();
  289. #else
  290. MakeMipmap();
  291. #endif
  292. }
  293. static void
  294. ParseOptions(int argc, char *argv[])
  295. {
  296. }
  297. int
  298. main(int argc, char *argv[])
  299. {
  300. glutInit(&argc, argv);
  301. glutInitWindowSize(WinWidth, WinHeight);
  302. glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE);
  303. win = glutCreateWindow(argv[0]);
  304. glewInit();
  305. glutReshapeFunc(Reshape);
  306. glutKeyboardFunc(Key);
  307. glutDisplayFunc(Redisplay);
  308. ParseOptions(argc, argv);
  309. Init();
  310. glutMainLoop();
  311. return 0;
  312. }