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.

mandelbrot.c 7.1KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328
  1. /**
  2. * "Mandelbrot" shader demo. Uses the example shaders from
  3. * chapter 15 (or 18) of the OpenGL Shading Language "orange" book.
  4. * 15 Jan 2007
  5. */
  6. #include <assert.h>
  7. #include <string.h>
  8. #include <stdio.h>
  9. #include <stdlib.h>
  10. #include <math.h>
  11. #include <GL/gl.h>
  12. #include <GL/glut.h>
  13. #include <GL/glext.h>
  14. #include "extfuncs.h"
  15. static char *FragProgFile = "CH18-mandel.frag.txt";
  16. static char *VertProgFile = "CH18-mandel.vert.txt";
  17. /* program/shader objects */
  18. static GLuint fragShader;
  19. static GLuint vertShader;
  20. static GLuint program;
  21. struct uniform_info {
  22. const char *name;
  23. GLuint size;
  24. GLint location;
  25. GLfloat value[4];
  26. };
  27. static struct uniform_info Uniforms[] = {
  28. /* vert */
  29. { "LightPosition", 3, -1, { 0.1, 0.1, 9.0, 0} },
  30. { "SpecularContribution", 1, -1, { 0.5, 0, 0, 0 } },
  31. { "DiffuseContribution", 1, -1, { 0.5, 0, 0, 0 } },
  32. { "Shininess", 1, -1, { 20.0, 0, 0, 0 } },
  33. /* frag */
  34. { "MaxIterations", 1, -1, { 12, 0, 0, 0 } },
  35. { "Zoom", 1, -1, { 0.125, 0, 0, 0 } },
  36. { "Xcenter", 1, -1, { -1.5, 0, 0, 0 } },
  37. { "Ycenter", 1, -1, { .005, 0, 0, 0 } },
  38. { "InnerColor", 3, -1, { 1, 0, 0, 0 } },
  39. { "OuterColor1", 3, -1, { 0, 1, 0, 0 } },
  40. { "OuterColor2", 3, -1, { 0, 0, 1, 0 } },
  41. { NULL, 0, 0, { 0, 0, 0, 0 } }
  42. };
  43. static GLint win = 0;
  44. static GLfloat xRot = 0.0f, yRot = 0.0f, zRot = 0.0f;
  45. static GLint uZoom, uXcenter, uYcenter;
  46. static GLfloat zoom = 1.0, xCenter = -1.5, yCenter = 0.0;
  47. static void
  48. Redisplay(void)
  49. {
  50. glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  51. /* set interactive uniform parameters */
  52. glUniform1fv_func(uZoom, 1, &zoom);
  53. glUniform1fv_func(uXcenter, 1, &xCenter);
  54. glUniform1fv_func(uYcenter, 1, &yCenter);
  55. glPushMatrix();
  56. glRotatef(xRot, 1.0f, 0.0f, 0.0f);
  57. glRotatef(yRot, 0.0f, 1.0f, 0.0f);
  58. glRotatef(zRot, 0.0f, 0.0f, 1.0f);
  59. glBegin(GL_POLYGON);
  60. glTexCoord2f(0, 0); glVertex2f(-1, -1);
  61. glTexCoord2f(1, 0); glVertex2f( 1, -1);
  62. glTexCoord2f(1, 1); glVertex2f( 1, 1);
  63. glTexCoord2f(0, 1); glVertex2f(-1, 1);
  64. glEnd();
  65. glPopMatrix();
  66. glFinish();
  67. glFlush();
  68. glutSwapBuffers();
  69. }
  70. static void
  71. Reshape(int width, int height)
  72. {
  73. glViewport(0, 0, width, height);
  74. glMatrixMode(GL_PROJECTION);
  75. glLoadIdentity();
  76. glFrustum(-1.0, 1.0, -1.0, 1.0, 5.0, 25.0);
  77. glMatrixMode(GL_MODELVIEW);
  78. glLoadIdentity();
  79. glTranslatef(0.0f, 0.0f, -6.0f);
  80. }
  81. static void
  82. CleanUp(void)
  83. {
  84. glDeleteShader_func(fragShader);
  85. glDeleteShader_func(vertShader);
  86. glDeleteProgram_func(program);
  87. glutDestroyWindow(win);
  88. }
  89. static void
  90. Key(unsigned char key, int x, int y)
  91. {
  92. (void) x;
  93. (void) y;
  94. switch(key) {
  95. case 'z':
  96. zoom *= 0.9;
  97. break;
  98. case 'Z':
  99. zoom /= 0.9;
  100. break;
  101. case 27:
  102. CleanUp();
  103. exit(0);
  104. break;
  105. }
  106. glutPostRedisplay();
  107. }
  108. static void
  109. SpecialKey(int key, int x, int y)
  110. {
  111. const GLfloat step = 0.1 * zoom;
  112. (void) x;
  113. (void) y;
  114. switch(key) {
  115. case GLUT_KEY_UP:
  116. yCenter += step;
  117. break;
  118. case GLUT_KEY_DOWN:
  119. yCenter -= step;
  120. break;
  121. case GLUT_KEY_LEFT:
  122. xCenter -= step;
  123. break;
  124. case GLUT_KEY_RIGHT:
  125. xCenter += step;
  126. break;
  127. }
  128. glutPostRedisplay();
  129. }
  130. static void
  131. LoadAndCompileShader(GLuint shader, const char *text)
  132. {
  133. GLint stat;
  134. glShaderSource_func(shader, 1, (const GLchar **) &text, NULL);
  135. glCompileShader_func(shader);
  136. glGetShaderiv_func(shader, GL_COMPILE_STATUS, &stat);
  137. if (!stat) {
  138. GLchar log[1000];
  139. GLsizei len;
  140. glGetShaderInfoLog_func(shader, 1000, &len, log);
  141. fprintf(stderr, "brick: problem compiling shader: %s\n", log);
  142. exit(1);
  143. }
  144. else {
  145. printf("Shader compiled OK\n");
  146. }
  147. }
  148. /**
  149. * Read a shader from a file.
  150. */
  151. static void
  152. ReadShader(GLuint shader, const char *filename)
  153. {
  154. const int max = 100*1000;
  155. int n;
  156. char *buffer = (char*) malloc(max);
  157. FILE *f = fopen(filename, "r");
  158. if (!f) {
  159. fprintf(stderr, "brick: Unable to open shader file %s\n", filename);
  160. exit(1);
  161. }
  162. n = fread(buffer, 1, max, f);
  163. printf("brick: read %d bytes from shader file %s\n", n, filename);
  164. if (n > 0) {
  165. buffer[n] = 0;
  166. LoadAndCompileShader(shader, buffer);
  167. }
  168. fclose(f);
  169. free(buffer);
  170. }
  171. static void
  172. CheckLink(GLuint prog)
  173. {
  174. GLint stat;
  175. glGetProgramiv_func(prog, GL_LINK_STATUS, &stat);
  176. if (!stat) {
  177. GLchar log[1000];
  178. GLsizei len;
  179. glGetProgramInfoLog_func(prog, 1000, &len, log);
  180. fprintf(stderr, "Linker error:\n%s\n", log);
  181. }
  182. else {
  183. fprintf(stderr, "Link success!\n");
  184. }
  185. }
  186. static void
  187. Init(void)
  188. {
  189. const char *version;
  190. GLint i;
  191. version = (const char *) glGetString(GL_VERSION);
  192. if (version[0] != '2' || version[1] != '.') {
  193. printf("Warning: this program expects OpenGL 2.0\n");
  194. /*exit(1);*/
  195. }
  196. GetExtensionFuncs();
  197. vertShader = glCreateShader_func(GL_VERTEX_SHADER);
  198. ReadShader(vertShader, VertProgFile);
  199. fragShader = glCreateShader_func(GL_FRAGMENT_SHADER);
  200. ReadShader(fragShader, FragProgFile);
  201. program = glCreateProgram_func();
  202. glAttachShader_func(program, fragShader);
  203. glAttachShader_func(program, vertShader);
  204. glLinkProgram_func(program);
  205. CheckLink(program);
  206. glUseProgram_func(program);
  207. for (i = 0; Uniforms[i].name; i++) {
  208. Uniforms[i].location
  209. = glGetUniformLocation_func(program, Uniforms[i].name);
  210. printf("Uniform %s location: %d\n", Uniforms[i].name,
  211. Uniforms[i].location);
  212. switch (Uniforms[i].size) {
  213. case 1:
  214. glUniform1fv_func(Uniforms[i].location, 1, Uniforms[i].value);
  215. break;
  216. case 2:
  217. glUniform2fv_func(Uniforms[i].location, 1, Uniforms[i].value);
  218. break;
  219. case 3:
  220. glUniform3fv_func(Uniforms[i].location, 1, Uniforms[i].value);
  221. break;
  222. case 4:
  223. glUniform4fv_func(Uniforms[i].location, 1, Uniforms[i].value);
  224. break;
  225. default:
  226. abort();
  227. }
  228. }
  229. uZoom = glGetUniformLocation_func(program, "Zoom");
  230. uXcenter = glGetUniformLocation_func(program, "Xcenter");
  231. uYcenter = glGetUniformLocation_func(program, "Ycenter");
  232. assert(glGetError() == 0);
  233. glClearColor(0.4f, 0.4f, 0.8f, 0.0f);
  234. printf("GL_RENDERER = %s\n",(const char *) glGetString(GL_RENDERER));
  235. assert(glIsProgram_func(program));
  236. assert(glIsShader_func(fragShader));
  237. assert(glIsShader_func(vertShader));
  238. glColor3f(1, 0, 0);
  239. }
  240. static void
  241. ParseOptions(int argc, char *argv[])
  242. {
  243. int i;
  244. for (i = 1; i < argc; i++) {
  245. if (strcmp(argv[i], "-fs") == 0) {
  246. FragProgFile = argv[i+1];
  247. }
  248. else if (strcmp(argv[i], "-vs") == 0) {
  249. VertProgFile = argv[i+1];
  250. }
  251. }
  252. }
  253. int
  254. main(int argc, char *argv[])
  255. {
  256. glutInit(&argc, argv);
  257. glutInitWindowPosition( 0, 0);
  258. glutInitWindowSize(400, 400);
  259. glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
  260. win = glutCreateWindow(argv[0]);
  261. glutReshapeFunc(Reshape);
  262. glutKeyboardFunc(Key);
  263. glutSpecialFunc(SpecialKey);
  264. glutDisplayFunc(Redisplay);
  265. ParseOptions(argc, argv);
  266. Init();
  267. glutMainLoop();
  268. return 0;
  269. }