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.

vp-tris.c 6.8KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313
  1. #include <assert.h>
  2. #include <string.h>
  3. #include <stdio.h>
  4. #include <stdlib.h>
  5. #include <math.h>
  6. #define GL_GLEXT_PROTOTYPES
  7. #include <GL/glut.h>
  8. static const char *filename = NULL;
  9. static GLuint nr_steps = 4;
  10. static GLuint fragShader;
  11. static GLuint vertShader;
  12. static GLuint program;
  13. static void usage( char *name )
  14. {
  15. fprintf( stderr, "usage: %s [ options ] shader_filename\n", name );
  16. fprintf( stderr, "\n" );
  17. fprintf( stderr, "options:\n" );
  18. fprintf( stderr, " -f flat shaded\n" );
  19. fprintf( stderr, " -nNr subdivision steps\n" );
  20. }
  21. static void load_and_compile_shader(GLuint shader, const char *text)
  22. {
  23. GLint stat;
  24. glShaderSource(shader, 1, (const GLchar **) &text, NULL);
  25. glCompileShader(shader);
  26. glGetShaderiv(shader, GL_COMPILE_STATUS, &stat);
  27. if (!stat) {
  28. GLchar log[1000];
  29. GLsizei len;
  30. glGetShaderInfoLog(shader, 1000, &len, log);
  31. fprintf(stderr, "vp-tris: problem compiling shader:\n%s\n", log);
  32. exit(1);
  33. }
  34. }
  35. static void read_shader(GLuint shader, const char *filename)
  36. {
  37. const int max = 100*1000;
  38. int n;
  39. char *buffer = (char*) malloc(max);
  40. FILE *f = fopen(filename, "r");
  41. if (!f) {
  42. fprintf(stderr, "vp-tris: Unable to open shader file %s\n", filename);
  43. exit(1);
  44. }
  45. n = fread(buffer, 1, max, f);
  46. printf("vp-tris: read %d bytes from shader file %s\n", n, filename);
  47. if (n > 0) {
  48. buffer[n] = 0;
  49. load_and_compile_shader(shader, buffer);
  50. }
  51. fclose(f);
  52. free(buffer);
  53. }
  54. static void check_link(GLuint prog)
  55. {
  56. GLint stat;
  57. glGetProgramiv(prog, GL_LINK_STATUS, &stat);
  58. if (!stat) {
  59. GLchar log[1000];
  60. GLsizei len;
  61. glGetProgramInfoLog(prog, 1000, &len, log);
  62. fprintf(stderr, "Linker error:\n%s\n", log);
  63. }
  64. }
  65. static void setup_uniforms()
  66. {
  67. {
  68. GLuint loc1f = glGetUniformLocationARB(program, "Offset1f");
  69. GLuint loc2f = glGetUniformLocationARB(program, "Offset2f");
  70. GLuint loc4f = glGetUniformLocationARB(program, "Offset4f");
  71. GLfloat vecKer[] =
  72. { 1.0, 0.0, 0.0, 1.0,
  73. 0.0, 1.0, 0.0, 1.0,
  74. 1.0, 0.0, 0.0, 1.0,
  75. 0.0, 0.0, 0.0, 1.0
  76. };
  77. if (loc1f >= 0)
  78. glUniform1fv(loc1f, 16, vecKer);
  79. if (loc2f >= 0)
  80. glUniform2fv(loc2f, 8, vecKer);
  81. if (loc4f >= 0)
  82. glUniform4fv(loc4f, 4, vecKer);
  83. }
  84. GLuint loc1f = glGetUniformLocationARB(program, "KernelValue1f");
  85. GLuint loc2f = glGetUniformLocationARB(program, "KernelValue2f");
  86. GLuint loc4f = glGetUniformLocationARB(program, "KernelValue4f");
  87. GLfloat vecKer[] =
  88. { 1.0, 0.0, 0.0, 0.25,
  89. 0.0, 1.0, 0.0, 0.25,
  90. 0.0, 0.0, 1.0, 0.25,
  91. 0.0, 0.0, 0.0, 0.25,
  92. 0.5, 0.0, 0.0, 0.35,
  93. 0.0, 0.5, 0.0, 0.35,
  94. 0.0, 0.0, 0.5, 0.35,
  95. 0.0, 0.0, 0.0, 0.35
  96. };
  97. if (loc1f >= 0)
  98. glUniform1fv(loc1f, 16, vecKer);
  99. if (loc2f >= 0)
  100. glUniform2fv(loc2f, 8, vecKer);
  101. if (loc4f >= 0)
  102. glUniform4fv(loc4f, 4, vecKer);
  103. }
  104. static void prepare_shaders()
  105. {
  106. static const char *fragShaderText =
  107. "void main() {\n"
  108. " gl_FragColor = gl_Color;\n"
  109. "}\n";
  110. static const char *vertShaderText =
  111. "void main() {\n"
  112. " gl_FrontColor = gl_Color;\n"
  113. " gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;\n"
  114. "}\n";
  115. fragShader = glCreateShader(GL_FRAGMENT_SHADER);
  116. load_and_compile_shader(fragShader, fragShaderText);
  117. vertShader = glCreateShader(GL_VERTEX_SHADER);
  118. if (filename)
  119. read_shader(vertShader, filename);
  120. else
  121. load_and_compile_shader(vertShader, vertShaderText);
  122. program = glCreateProgram();
  123. glAttachShader(program, fragShader);
  124. glAttachShader(program, vertShader);
  125. glLinkProgram(program);
  126. check_link(program);
  127. glUseProgram(program);
  128. setup_uniforms();
  129. }
  130. static void args(int argc, char *argv[])
  131. {
  132. GLint i;
  133. for (i = 1; i < argc; i++) {
  134. if (strncmp(argv[i], "-n", 2) == 0) {
  135. nr_steps = atoi((argv[i]) + 2);
  136. }
  137. else if (strcmp(argv[i], "-f") == 0) {
  138. glShadeModel(GL_FLAT);
  139. }
  140. else if (i == argc - 1) {
  141. filename = argv[i];
  142. }
  143. else {
  144. usage(argv[0]);
  145. exit(1);
  146. }
  147. }
  148. if (!filename) {
  149. usage(argv[0]);
  150. exit(1);
  151. }
  152. }
  153. union vert {
  154. struct {
  155. GLfloat color[3];
  156. GLfloat pos[3];
  157. } v;
  158. GLfloat f[6];
  159. };
  160. static void make_midpoint( union vert *out,
  161. const union vert *v0,
  162. const union vert *v1)
  163. {
  164. int i;
  165. for (i = 0; i < 6; i++)
  166. out->f[i] = v0->f[i] + .5 * (v1->f[i] - v0->f[i]);
  167. }
  168. static void subdiv( union vert *v0,
  169. union vert *v1,
  170. union vert *v2,
  171. GLuint depth )
  172. {
  173. if (depth == 0) {
  174. glColor3fv(v0->v.color);
  175. glVertex3fv(v0->v.pos);
  176. glColor3fv(v1->v.color);
  177. glVertex3fv(v1->v.pos);
  178. glColor3fv(v2->v.color);
  179. glVertex3fv(v2->v.pos);
  180. }
  181. else {
  182. union vert m[3];
  183. make_midpoint(&m[0], v0, v1);
  184. make_midpoint(&m[1], v1, v2);
  185. make_midpoint(&m[2], v2, v0);
  186. subdiv(&m[0], &m[2], v0, depth-1);
  187. subdiv(&m[1], &m[0], v1, depth-1);
  188. subdiv(&m[2], &m[1], v2, depth-1);
  189. subdiv(&m[0], &m[1], &m[2], depth-1);
  190. }
  191. }
  192. /** Assignment */
  193. #define ASSIGN_3V( V, V0, V1, V2 ) \
  194. do { \
  195. V[0] = V0; \
  196. V[1] = V1; \
  197. V[2] = V2; \
  198. } while(0)
  199. static void Display( void )
  200. {
  201. glClearColor(0.3, 0.3, 0.3, 1);
  202. glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
  203. glUseProgram(program);
  204. glBegin(GL_TRIANGLES);
  205. {
  206. union vert v[3];
  207. ASSIGN_3V(v[0].v.color, 0,0,1);
  208. ASSIGN_3V(v[0].v.pos, 0.9, -0.9, 0.0);
  209. ASSIGN_3V(v[1].v.color, 1,0,0);
  210. ASSIGN_3V(v[1].v.pos, 0.9, 0.9, 0.0);
  211. ASSIGN_3V(v[2].v.color, 0,1,0);
  212. ASSIGN_3V(v[2].v.pos, -0.9, 0, 0.0);
  213. subdiv(&v[0], &v[1], &v[2], nr_steps);
  214. }
  215. glEnd();
  216. glFlush();
  217. }
  218. static void Reshape( int width, int height )
  219. {
  220. glViewport( 0, 0, width, height );
  221. glMatrixMode( GL_PROJECTION );
  222. glLoadIdentity();
  223. glOrtho(-1.0, 1.0, -1.0, 1.0, -0.5, 1000.0);
  224. glMatrixMode( GL_MODELVIEW );
  225. glLoadIdentity();
  226. /*glTranslatef( 0.0, 0.0, -15.0 );*/
  227. }
  228. static void CleanUp(void)
  229. {
  230. glDeleteShader(fragShader);
  231. glDeleteShader(vertShader);
  232. glDeleteProgram(program);
  233. }
  234. static void Key( unsigned char key, int x, int y )
  235. {
  236. (void) x;
  237. (void) y;
  238. switch (key) {
  239. case 27:
  240. CleanUp();
  241. exit(0);
  242. break;
  243. }
  244. glutPostRedisplay();
  245. }
  246. int main( int argc, char *argv[] )
  247. {
  248. glutInit( &argc, argv );
  249. glutInitWindowPosition( 0, 0 );
  250. glutInitWindowSize( 250, 250 );
  251. glutInitDisplayMode( GLUT_RGB | GLUT_SINGLE | GLUT_DEPTH );
  252. glutCreateWindow(argv[0]);
  253. glutReshapeFunc( Reshape );
  254. glutKeyboardFunc( Key );
  255. glutDisplayFunc( Display );
  256. args( argc, argv );
  257. prepare_shaders();
  258. glutMainLoop();
  259. return 0;
  260. }