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