Clone of mesa.
您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257
  1. /**
  2. * Implement smooth (AA) points with shaders.
  3. * A simple variation could be used for sprite points.
  4. * Brian Paul
  5. * 29 July 2007
  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. #include "shaderutil.h"
  15. static GLuint FragShader;
  16. static GLuint VertShader;
  17. static GLuint Program;
  18. static GLint Win = 0;
  19. static GLint WinWidth = 500, WinHeight = 200;
  20. static GLfloat Xpos = 0.0f, Ypos = 0.0f;
  21. static GLint uViewportInv;
  22. static GLboolean Smooth = GL_TRUE, Blend = GL_TRUE;
  23. /**
  24. * Issue vertices for a "shader point".
  25. * The position is duplicated, only texcoords (or other vertex attrib) change.
  26. * The vertex program will compute the "real" quad corners.
  27. */
  28. static void
  29. PointVertex3f(GLfloat x, GLfloat y, GLfloat z)
  30. {
  31. glTexCoord2f(-1, -1);
  32. glVertex3f(x, y, z);
  33. glTexCoord2f( 1, -1);
  34. glVertex3f(x, y, z);
  35. glTexCoord2f( 1, 1);
  36. glVertex3f(x, y, z);
  37. glTexCoord2f(-1, 1);
  38. glVertex3f(x, y, z);
  39. }
  40. static void
  41. DrawPoints(GLboolean shaderPoints)
  42. {
  43. int i;
  44. for (i = 0; i < 9; i++) {
  45. GLfloat x = i - 4, y = 0, z = 0;
  46. /* note: can't call glPointSize inside Begin/End :( */
  47. glPointSize( 2 + i * 5 );
  48. if (shaderPoints) {
  49. glBegin(GL_QUADS);
  50. PointVertex3f(x, y, z);
  51. glEnd();
  52. }
  53. else {
  54. glBegin(GL_POINTS);
  55. glVertex3f(x, y, z);
  56. glEnd();
  57. }
  58. }
  59. }
  60. /**
  61. * Top row of points rendered convetionally,
  62. * bottom row rendered with shaders.
  63. */
  64. static void
  65. Redisplay(void)
  66. {
  67. glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  68. if (Smooth)
  69. glEnable(GL_POINT_SMOOTH);
  70. else
  71. glDisable(GL_POINT_SMOOTH);
  72. if (Blend)
  73. glEnable(GL_BLEND);
  74. else
  75. glDisable(GL_BLEND);
  76. glPushMatrix();
  77. glTranslatef(Xpos, Ypos, 0);
  78. /*
  79. * regular points
  80. */
  81. glPushMatrix();
  82. glTranslatef(0, 1.2, 0);
  83. glUseProgram(0);
  84. DrawPoints(GL_FALSE);
  85. glPopMatrix();
  86. /*
  87. * shader points
  88. */
  89. glPushMatrix();
  90. glTranslatef(0, -1.2, 0);
  91. glUseProgram(Program);
  92. if (uViewportInv != -1) {
  93. glUniform2f(uViewportInv, 1.0 / WinWidth, 1.0 / WinHeight);
  94. }
  95. DrawPoints(GL_TRUE);
  96. glPopMatrix();
  97. glPopMatrix();
  98. glutSwapBuffers();
  99. }
  100. static void
  101. Reshape(int width, int height)
  102. {
  103. WinWidth = width;
  104. WinHeight = height;
  105. glViewport(0, 0, width, height);
  106. glMatrixMode(GL_PROJECTION);
  107. glLoadIdentity();
  108. glFrustum(-1.0, 1.0, -1.0, 1.0, 4.0, 30.0);
  109. glMatrixMode(GL_MODELVIEW);
  110. glLoadIdentity();
  111. glTranslatef(0.0f, 0.0f, -20.0f);
  112. }
  113. static void
  114. Key(unsigned char key, int x, int y)
  115. {
  116. (void) x;
  117. (void) y;
  118. switch(key) {
  119. case 'b':
  120. Blend = !Blend;
  121. break;
  122. case 's':
  123. Smooth = !Smooth;
  124. break;
  125. case 27:
  126. glDeleteShader(FragShader);
  127. glDeleteShader(VertShader);
  128. glDeleteProgram(Program);
  129. glutDestroyWindow(Win);
  130. exit(0);
  131. }
  132. glutPostRedisplay();
  133. }
  134. static void
  135. SpecialKey(int key, int x, int y)
  136. {
  137. const GLfloat step = 1/100.0;
  138. switch(key) {
  139. case GLUT_KEY_UP:
  140. Ypos += step;
  141. break;
  142. case GLUT_KEY_DOWN:
  143. Ypos -= step;
  144. break;
  145. case GLUT_KEY_LEFT:
  146. Xpos -= step;
  147. break;
  148. case GLUT_KEY_RIGHT:
  149. Xpos += step;
  150. break;
  151. }
  152. glutPostRedisplay();
  153. }
  154. static void
  155. Init(void)
  156. {
  157. /* Fragment shader: compute distance of fragment from center of point
  158. * (we're using texcoords but another varying could be used).
  159. * if dist > 1, discard (coverage==0)
  160. * if dist < k, coverage = 1
  161. * else, coverage = func(dist)
  162. * Note: length() uses sqrt() and may be expensive. The distance could
  163. * be squared instead (with adjustments to the threshold (k) test)
  164. */
  165. static const char *fragShaderText =
  166. "void main() {\n"
  167. " float cover; \n"
  168. " float k = 2.0 / gl_Point.size; \n"
  169. " float d = length(gl_TexCoord[0].xy); \n"
  170. " if (d >= 1.0) \n"
  171. " discard; \n"
  172. " if (d < 1.0 - k) \n"
  173. " cover = 1.0; \n"
  174. " else \n"
  175. " cover = (1.0 - d) * 0.5 * gl_Point.size; \n"
  176. " gl_FragColor.rgb = gl_Color.rgb; \n"
  177. " gl_FragColor.a = cover; \n"
  178. "}\n";
  179. /* Vertex shader: compute new vertex position based on incoming vertex pos,
  180. * texcoords, point size, and inverse viewport scale factor.
  181. * Note: should compute point size attenuation here too.
  182. */
  183. static const char *vertShaderText =
  184. "uniform vec2 viewportInv; \n"
  185. "void main() {\n"
  186. " vec4 pos = gl_ModelViewProjectionMatrix * gl_Vertex;\n"
  187. " gl_Position.xy = pos.xy + gl_MultiTexCoord0.xy * viewportInv \n"
  188. " * gl_Point.size * pos.w; \n"
  189. " gl_Position.zw = pos.zw; \n"
  190. " gl_TexCoord[0] = gl_MultiTexCoord0; \n"
  191. " gl_FrontColor = gl_Color; \n"
  192. "}\n";
  193. if (!ShadersSupported())
  194. exit(1);
  195. VertShader = CompileShaderText(GL_VERTEX_SHADER, vertShaderText);
  196. FragShader = CompileShaderText(GL_FRAGMENT_SHADER, fragShaderText);
  197. Program = LinkShaders(VertShader, FragShader);
  198. glUseProgram(Program);
  199. uViewportInv = glGetUniformLocation(Program, "viewportInv");
  200. glUseProgram(0);
  201. glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
  202. }
  203. int
  204. main(int argc, char *argv[])
  205. {
  206. glutInit(&argc, argv);
  207. glutInitWindowSize(WinWidth, WinHeight);
  208. glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
  209. Win = glutCreateWindow(argv[0]);
  210. glewInit();
  211. glutReshapeFunc(Reshape);
  212. glutKeyboardFunc(Key);
  213. glutSpecialFunc(SpecialKey);
  214. glutDisplayFunc(Redisplay);
  215. Init();
  216. glutMainLoop();
  217. return 0;
  218. }