mandelbrot.c revision 32001f49
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
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 "glut_wrap.h"
14#include "shaderutil.h"
15
16
17static char *FragProgFile = "CH18-mandel.frag";
18static char *VertProgFile = "CH18-mandel.vert";
19
20/* program/shader objects */
21static GLuint fragShader;
22static GLuint vertShader;
23static GLuint program;
24
25
26static struct uniform_info Uniforms[] = {
27   /* vert */
28   { "LightPosition",        1, GL_FLOAT_VEC3, { 0.1, 0.1, 9.0, 0}, -1 },
29   { "SpecularContribution", 1, GL_FLOAT, { 0.5, 0, 0, 0 }, -1 },
30   { "DiffuseContribution",  1, GL_FLOAT, { 0.5, 0, 0, 0 }, -1 },
31   { "Shininess",            1, GL_FLOAT, { 20.0, 0, 0, 0 }, -1 },
32   /* frag */
33   { "MaxIterations",        1, GL_FLOAT, { 12, 0, 0, 0 }, -1 },
34   { "Zoom",                 1, GL_FLOAT, { 0.125, 0, 0, 0 }, -1 },
35   { "Xcenter",              1, GL_FLOAT, { -1.5, 0, 0, 0 }, -1 },
36   { "Ycenter",              1, GL_FLOAT, { .005, 0, 0, 0 }, -1 },
37   { "InnerColor",           1, GL_FLOAT_VEC3, { 1, 0, 0, 0 }, -1 },
38   { "OuterColor1",          1, GL_FLOAT_VEC3, { 0, 1, 0, 0 }, -1 },
39   { "OuterColor2",          1, GL_FLOAT_VEC3, { 0, 0, 1, 0 }, -1 },
40   END_OF_UNIFORMS
41};
42
43static GLint win = 0;
44
45static GLfloat xRot = 0.0f, yRot = 0.0f, zRot = 0.0f;
46
47static GLint uZoom, uXcenter, uYcenter;
48static GLfloat zoom = 1.0, xCenter = -1.5, yCenter = 0.0;
49
50
51static void
52Redisplay(void)
53{
54   glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
55
56   /* set interactive uniform parameters */
57   glUniform1fv(uZoom, 1, &zoom);
58   glUniform1fv(uXcenter, 1, &xCenter);
59   glUniform1fv(uYcenter, 1, &yCenter);
60
61   glPushMatrix();
62   glRotatef(xRot, 1.0f, 0.0f, 0.0f);
63   glRotatef(yRot, 0.0f, 1.0f, 0.0f);
64   glRotatef(zRot, 0.0f, 0.0f, 1.0f);
65
66   glBegin(GL_POLYGON);
67   glTexCoord2f(0, 0);   glVertex2f(-1, -1);
68   glTexCoord2f(1, 0);   glVertex2f( 1, -1);
69   glTexCoord2f(1, 1);   glVertex2f( 1,  1);
70   glTexCoord2f(0, 1);   glVertex2f(-1,  1);
71   glEnd();
72
73   glPopMatrix();
74
75   glutSwapBuffers();
76}
77
78
79static void
80Reshape(int width, int height)
81{
82   glViewport(0, 0, width, height);
83   glMatrixMode(GL_PROJECTION);
84   glLoadIdentity();
85   glFrustum(-1.0, 1.0, -1.0, 1.0, 5.0, 25.0);
86   glMatrixMode(GL_MODELVIEW);
87   glLoadIdentity();
88   glTranslatef(0.0f, 0.0f, -6.0f);
89}
90
91
92static void
93CleanUp(void)
94{
95   glDeleteShader(fragShader);
96   glDeleteShader(vertShader);
97   glDeleteProgram(program);
98   glutDestroyWindow(win);
99}
100
101
102static void
103Key(unsigned char key, int x, int y)
104{
105  (void) x;
106  (void) y;
107
108   switch(key) {
109   case 'z':
110      zoom *= 0.9;
111      break;
112   case 'Z':
113      zoom /= 0.9;
114      break;
115   case 27:
116      CleanUp();
117      exit(0);
118      break;
119   }
120   glutPostRedisplay();
121}
122
123
124static void
125SpecialKey(int key, int x, int y)
126{
127   const GLfloat step = 0.1 * zoom;
128
129  (void) x;
130  (void) y;
131
132   switch(key) {
133   case GLUT_KEY_UP:
134      yCenter += step;
135      break;
136   case GLUT_KEY_DOWN:
137      yCenter -= step;
138      break;
139   case GLUT_KEY_LEFT:
140      xCenter -= step;
141      break;
142   case GLUT_KEY_RIGHT:
143      xCenter += step;
144      break;
145   }
146   glutPostRedisplay();
147}
148
149
150static void
151Init(void)
152{
153   if (!ShadersSupported())
154      exit(1);
155
156   vertShader = CompileShaderFile(GL_VERTEX_SHADER, VertProgFile);
157   fragShader = CompileShaderFile(GL_FRAGMENT_SHADER, FragProgFile);
158   program = LinkShaders(vertShader, fragShader);
159
160   glUseProgram(program);
161
162   SetUniformValues(program, Uniforms);
163   PrintUniforms(Uniforms);
164
165   uZoom = glGetUniformLocation(program, "Zoom");
166   uXcenter = glGetUniformLocation(program, "Xcenter");
167   uYcenter = glGetUniformLocation(program, "Ycenter");
168
169   assert(glGetError() == 0);
170
171   glClearColor(0.4f, 0.4f, 0.8f, 0.0f);
172
173   printf("GL_RENDERER = %s\n",(const char *) glGetString(GL_RENDERER));
174
175   assert(glIsProgram(program));
176   assert(glIsShader(fragShader));
177   assert(glIsShader(vertShader));
178
179   glColor3f(1, 0, 0);
180}
181
182
183static void
184ParseOptions(int argc, char *argv[])
185{
186   int i;
187   for (i = 1; i < argc; i++) {
188      if (strcmp(argv[i], "-fs") == 0) {
189         FragProgFile = argv[i+1];
190      }
191      else if (strcmp(argv[i], "-vs") == 0) {
192         VertProgFile = argv[i+1];
193      }
194   }
195}
196
197
198int
199main(int argc, char *argv[])
200{
201   glutInit(&argc, argv);
202   glutInitWindowSize(400, 400);
203   glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
204   win = glutCreateWindow(argv[0]);
205   glewInit();
206   glutReshapeFunc(Reshape);
207   glutKeyboardFunc(Key);
208   glutSpecialFunc(SpecialKey);
209   glutDisplayFunc(Redisplay);
210   ParseOptions(argc, argv);
211   Init();
212   glutMainLoop();
213   return 0;
214}
215
216