Merge branch '7.8'
[mesa.git] / progs / glsl / mandelbrot.c
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 <GL/glut.h>
14 #include "shaderutil.h"
15
16
17 static char *FragProgFile = "CH18-mandel.frag";
18 static char *VertProgFile = "CH18-mandel.vert";
19
20 /* program/shader objects */
21 static GLuint fragShader;
22 static GLuint vertShader;
23 static GLuint program;
24
25
26 static 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
43 static GLint win = 0;
44
45 static GLfloat xRot = 0.0f, yRot = 0.0f, zRot = 0.0f;
46
47 static GLint uZoom, uXcenter, uYcenter;
48 static GLfloat zoom = 1.0, xCenter = -1.5, yCenter = 0.0;
49
50
51 static void
52 Redisplay(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
79 static void
80 Reshape(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
92 static void
93 CleanUp(void)
94 {
95 glDeleteShader(fragShader);
96 glDeleteShader(vertShader);
97 glDeleteProgram(program);
98 glutDestroyWindow(win);
99 }
100
101
102 static void
103 Key(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
124 static void
125 SpecialKey(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
150 static void
151 Init(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
183 static void
184 ParseOptions(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
198 int
199 main(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