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 
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
Redisplay(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
Reshape(int width,int height)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
CleanUp(void)93 CleanUp(void)
94 {
95    glDeleteShader(fragShader);
96    glDeleteShader(vertShader);
97    glDeleteProgram(program);
98    glutDestroyWindow(win);
99 }
100 
101 
102 static void
Key(unsigned char key,int x,int y)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
SpecialKey(int key,int x,int y)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
Init(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
ParseOptions(int argc,char * argv[])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
main(int argc,char * argv[])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 
216