blob: b05ef37fae1f3c374b9689a47aeaafbf39e41c2b [file] [log] [blame]
Brian2ccd2642007-01-15 17:27:24 -07001/**
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>
Keith Whitwellb799af92009-06-29 14:13:58 +010012#include <GL/glew.h>
Brian2ccd2642007-01-15 17:27:24 -070013#include <GL/glut.h>
Brian2dca3372008-04-09 22:28:23 -060014#include "shaderutil.h"
Brian2ccd2642007-01-15 17:27:24 -070015
16
Brian Paulc0dd9122008-08-16 09:36:46 -060017static char *FragProgFile = "CH18-mandel.frag";
18static char *VertProgFile = "CH18-mandel.vert";
Brian2ccd2642007-01-15 17:27:24 -070019
20/* program/shader objects */
21static GLuint fragShader;
22static GLuint vertShader;
23static GLuint program;
24
25
Brian2ccd2642007-01-15 17:27:24 -070026static struct uniform_info Uniforms[] = {
27 /* vert */
Brian Paulfdfb0d42009-08-12 17:25:49 -060028 { "LightPosition", 1, GL_FLOAT_VEC3, { 0.1, 0.1, 9.0, 0}, -1 },
Brian2dca3372008-04-09 22:28:23 -060029 { "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 },
Brian2ccd2642007-01-15 17:27:24 -070032 /* frag */
Brian2dca3372008-04-09 22:28:23 -060033 { "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 },
Brian Paulfdfb0d42009-08-12 17:25:49 -060037 { "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 },
Brian2dca3372008-04-09 22:28:23 -060040 END_OF_UNIFORMS
Brian2ccd2642007-01-15 17:27:24 -070041};
42
43static GLint win = 0;
44
Brian2ccd2642007-01-15 17:27:24 -070045static GLfloat xRot = 0.0f, yRot = 0.0f, zRot = 0.0f;
46
Brian0d553462007-01-15 17:48:19 -070047static GLint uZoom, uXcenter, uYcenter;
48static GLfloat zoom = 1.0, xCenter = -1.5, yCenter = 0.0;
Brian2ccd2642007-01-15 17:27:24 -070049
50
51static void
52Redisplay(void)
53{
54 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
55
Brian0d553462007-01-15 17:48:19 -070056 /* set interactive uniform parameters */
Brian Paulee0b1bc2009-07-17 13:23:11 -060057 glUniform1fv(uZoom, 1, &zoom);
58 glUniform1fv(uXcenter, 1, &xCenter);
59 glUniform1fv(uYcenter, 1, &yCenter);
Brian0d553462007-01-15 17:48:19 -070060
Brian2ccd2642007-01-15 17:27:24 -070061 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{
Brian Paulee0b1bc2009-07-17 13:23:11 -060095 glDeleteShader(fragShader);
96 glDeleteShader(vertShader);
97 glDeleteProgram(program);
Brian2ccd2642007-01-15 17:27:24 -070098 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':
Brian0d553462007-01-15 17:48:19 -0700110 zoom *= 0.9;
Brian2ccd2642007-01-15 17:27:24 -0700111 break;
112 case 'Z':
Brian0d553462007-01-15 17:48:19 -0700113 zoom /= 0.9;
Brian2ccd2642007-01-15 17:27:24 -0700114 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{
Brian0d553462007-01-15 17:48:19 -0700127 const GLfloat step = 0.1 * zoom;
Brian2ccd2642007-01-15 17:27:24 -0700128
129 (void) x;
130 (void) y;
131
132 switch(key) {
133 case GLUT_KEY_UP:
Brian0d553462007-01-15 17:48:19 -0700134 yCenter += step;
Brian2ccd2642007-01-15 17:27:24 -0700135 break;
136 case GLUT_KEY_DOWN:
Brian0d553462007-01-15 17:48:19 -0700137 yCenter -= step;
Brian2ccd2642007-01-15 17:27:24 -0700138 break;
139 case GLUT_KEY_LEFT:
Brian0d553462007-01-15 17:48:19 -0700140 xCenter -= step;
Brian2ccd2642007-01-15 17:27:24 -0700141 break;
142 case GLUT_KEY_RIGHT:
Brian0d553462007-01-15 17:48:19 -0700143 xCenter += step;
Brian2ccd2642007-01-15 17:27:24 -0700144 break;
145 }
146 glutPostRedisplay();
147}
148
149
Brian2ccd2642007-01-15 17:27:24 -0700150static void
151Init(void)
152{
Brian2dca3372008-04-09 22:28:23 -0600153 if (!ShadersSupported())
154 exit(1);
Brian2ccd2642007-01-15 17:27:24 -0700155
Brian2dca3372008-04-09 22:28:23 -0600156 vertShader = CompileShaderFile(GL_VERTEX_SHADER, VertProgFile);
157 fragShader = CompileShaderFile(GL_FRAGMENT_SHADER, FragProgFile);
158 program = LinkShaders(vertShader, fragShader);
Brian2ccd2642007-01-15 17:27:24 -0700159
Brian Paulee0b1bc2009-07-17 13:23:11 -0600160 glUseProgram(program);
Brian2ccd2642007-01-15 17:27:24 -0700161
Brian Paul684049d2009-08-12 13:53:56 -0600162 SetUniformValues(program, Uniforms);
163 PrintUniforms(Uniforms);
Brian2ccd2642007-01-15 17:27:24 -0700164
Brian Paulee0b1bc2009-07-17 13:23:11 -0600165 uZoom = glGetUniformLocation(program, "Zoom");
166 uXcenter = glGetUniformLocation(program, "Xcenter");
167 uYcenter = glGetUniformLocation(program, "Ycenter");
Brian0d553462007-01-15 17:48:19 -0700168
Brian2ccd2642007-01-15 17:27:24 -0700169 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
Brian Paulee0b1bc2009-07-17 13:23:11 -0600175 assert(glIsProgram(program));
176 assert(glIsShader(fragShader));
177 assert(glIsShader(vertShader));
Brian2ccd2642007-01-15 17:27:24 -0700178
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);
Brian2ccd2642007-01-15 17:27:24 -0700202 glutInitWindowSize(400, 400);
203 glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
204 win = glutCreateWindow(argv[0]);
Keith Whitwellb799af92009-06-29 14:13:58 +0100205 glewInit();
Brian2ccd2642007-01-15 17:27:24 -0700206 glutReshapeFunc(Reshape);
207 glutKeyboardFunc(Key);
208 glutSpecialFunc(SpecialKey);
209 glutDisplayFunc(Redisplay);
210 ParseOptions(argc, argv);
211 Init();
212 glutMainLoop();
213 return 0;
214}
215