blob: 24e1992665565e70dcbc780771d4efd20b2e42f6 [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>
12#include <GL/gl.h>
13#include <GL/glut.h>
14#include <GL/glext.h>
15#include "extfuncs.h"
Brian2dca3372008-04-09 22:28:23 -060016#include "shaderutil.h"
Brian2ccd2642007-01-15 17:27:24 -070017
18
Brian Paulc0dd9122008-08-16 09:36:46 -060019static char *FragProgFile = "CH18-mandel.frag";
20static char *VertProgFile = "CH18-mandel.vert";
Brian2ccd2642007-01-15 17:27:24 -070021
22/* program/shader objects */
23static GLuint fragShader;
24static GLuint vertShader;
25static GLuint program;
26
27
Brian2ccd2642007-01-15 17:27:24 -070028static struct uniform_info Uniforms[] = {
29 /* vert */
Brian2dca3372008-04-09 22:28:23 -060030 { "LightPosition", 3, GL_FLOAT, { 0.1, 0.1, 9.0, 0}, -1 },
31 { "SpecularContribution", 1, GL_FLOAT, { 0.5, 0, 0, 0 }, -1 },
32 { "DiffuseContribution", 1, GL_FLOAT, { 0.5, 0, 0, 0 }, -1 },
33 { "Shininess", 1, GL_FLOAT, { 20.0, 0, 0, 0 }, -1 },
Brian2ccd2642007-01-15 17:27:24 -070034 /* frag */
Brian2dca3372008-04-09 22:28:23 -060035 { "MaxIterations", 1, GL_FLOAT, { 12, 0, 0, 0 }, -1 },
36 { "Zoom", 1, GL_FLOAT, { 0.125, 0, 0, 0 }, -1 },
37 { "Xcenter", 1, GL_FLOAT, { -1.5, 0, 0, 0 }, -1 },
38 { "Ycenter", 1, GL_FLOAT, { .005, 0, 0, 0 }, -1 },
39 { "InnerColor", 3, GL_FLOAT, { 1, 0, 0, 0 }, -1 },
40 { "OuterColor1", 3, GL_FLOAT, { 0, 1, 0, 0 }, -1 },
41 { "OuterColor2", 3, GL_FLOAT, { 0, 0, 1, 0 }, -1 },
42 END_OF_UNIFORMS
Brian2ccd2642007-01-15 17:27:24 -070043};
44
45static GLint win = 0;
46
Brian2ccd2642007-01-15 17:27:24 -070047static GLfloat xRot = 0.0f, yRot = 0.0f, zRot = 0.0f;
48
Brian0d553462007-01-15 17:48:19 -070049static GLint uZoom, uXcenter, uYcenter;
50static GLfloat zoom = 1.0, xCenter = -1.5, yCenter = 0.0;
Brian2ccd2642007-01-15 17:27:24 -070051
52
53static void
54Redisplay(void)
55{
56 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
57
Brian0d553462007-01-15 17:48:19 -070058 /* set interactive uniform parameters */
59 glUniform1fv_func(uZoom, 1, &zoom);
60 glUniform1fv_func(uXcenter, 1, &xCenter);
61 glUniform1fv_func(uYcenter, 1, &yCenter);
62
Brian2ccd2642007-01-15 17:27:24 -070063 glPushMatrix();
64 glRotatef(xRot, 1.0f, 0.0f, 0.0f);
65 glRotatef(yRot, 0.0f, 1.0f, 0.0f);
66 glRotatef(zRot, 0.0f, 0.0f, 1.0f);
67
68 glBegin(GL_POLYGON);
69 glTexCoord2f(0, 0); glVertex2f(-1, -1);
70 glTexCoord2f(1, 0); glVertex2f( 1, -1);
71 glTexCoord2f(1, 1); glVertex2f( 1, 1);
72 glTexCoord2f(0, 1); glVertex2f(-1, 1);
73 glEnd();
74
75 glPopMatrix();
76
77 glutSwapBuffers();
78}
79
80
81static void
82Reshape(int width, int height)
83{
84 glViewport(0, 0, width, height);
85 glMatrixMode(GL_PROJECTION);
86 glLoadIdentity();
87 glFrustum(-1.0, 1.0, -1.0, 1.0, 5.0, 25.0);
88 glMatrixMode(GL_MODELVIEW);
89 glLoadIdentity();
90 glTranslatef(0.0f, 0.0f, -6.0f);
91}
92
93
94static void
95CleanUp(void)
96{
97 glDeleteShader_func(fragShader);
98 glDeleteShader_func(vertShader);
99 glDeleteProgram_func(program);
100 glutDestroyWindow(win);
101}
102
103
104static void
105Key(unsigned char key, int x, int y)
106{
107 (void) x;
108 (void) y;
109
110 switch(key) {
111 case 'z':
Brian0d553462007-01-15 17:48:19 -0700112 zoom *= 0.9;
Brian2ccd2642007-01-15 17:27:24 -0700113 break;
114 case 'Z':
Brian0d553462007-01-15 17:48:19 -0700115 zoom /= 0.9;
Brian2ccd2642007-01-15 17:27:24 -0700116 break;
117 case 27:
118 CleanUp();
119 exit(0);
120 break;
121 }
122 glutPostRedisplay();
123}
124
125
126static void
127SpecialKey(int key, int x, int y)
128{
Brian0d553462007-01-15 17:48:19 -0700129 const GLfloat step = 0.1 * zoom;
Brian2ccd2642007-01-15 17:27:24 -0700130
131 (void) x;
132 (void) y;
133
134 switch(key) {
135 case GLUT_KEY_UP:
Brian0d553462007-01-15 17:48:19 -0700136 yCenter += step;
Brian2ccd2642007-01-15 17:27:24 -0700137 break;
138 case GLUT_KEY_DOWN:
Brian0d553462007-01-15 17:48:19 -0700139 yCenter -= step;
Brian2ccd2642007-01-15 17:27:24 -0700140 break;
141 case GLUT_KEY_LEFT:
Brian0d553462007-01-15 17:48:19 -0700142 xCenter -= step;
Brian2ccd2642007-01-15 17:27:24 -0700143 break;
144 case GLUT_KEY_RIGHT:
Brian0d553462007-01-15 17:48:19 -0700145 xCenter += step;
Brian2ccd2642007-01-15 17:27:24 -0700146 break;
147 }
148 glutPostRedisplay();
149}
150
151
Brian2ccd2642007-01-15 17:27:24 -0700152static void
153Init(void)
154{
Brian2dca3372008-04-09 22:28:23 -0600155 if (!ShadersSupported())
156 exit(1);
Brian2ccd2642007-01-15 17:27:24 -0700157
158 GetExtensionFuncs();
159
Brian2dca3372008-04-09 22:28:23 -0600160 vertShader = CompileShaderFile(GL_VERTEX_SHADER, VertProgFile);
161 fragShader = CompileShaderFile(GL_FRAGMENT_SHADER, FragProgFile);
162 program = LinkShaders(vertShader, fragShader);
Brian2ccd2642007-01-15 17:27:24 -0700163
Brian2ccd2642007-01-15 17:27:24 -0700164 glUseProgram_func(program);
165
Brian26f0b8f2008-04-09 22:29:33 -0600166 InitUniforms(program, Uniforms);
Brian2ccd2642007-01-15 17:27:24 -0700167
Brian0d553462007-01-15 17:48:19 -0700168 uZoom = glGetUniformLocation_func(program, "Zoom");
169 uXcenter = glGetUniformLocation_func(program, "Xcenter");
170 uYcenter = glGetUniformLocation_func(program, "Ycenter");
171
Brian2ccd2642007-01-15 17:27:24 -0700172 assert(glGetError() == 0);
173
174 glClearColor(0.4f, 0.4f, 0.8f, 0.0f);
175
176 printf("GL_RENDERER = %s\n",(const char *) glGetString(GL_RENDERER));
177
178 assert(glIsProgram_func(program));
179 assert(glIsShader_func(fragShader));
180 assert(glIsShader_func(vertShader));
181
182 glColor3f(1, 0, 0);
183}
184
185
186static void
187ParseOptions(int argc, char *argv[])
188{
189 int i;
190 for (i = 1; i < argc; i++) {
191 if (strcmp(argv[i], "-fs") == 0) {
192 FragProgFile = argv[i+1];
193 }
194 else if (strcmp(argv[i], "-vs") == 0) {
195 VertProgFile = argv[i+1];
196 }
197 }
198}
199
200
201int
202main(int argc, char *argv[])
203{
204 glutInit(&argc, argv);
205 glutInitWindowPosition( 0, 0);
206 glutInitWindowSize(400, 400);
207 glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
208 win = glutCreateWindow(argv[0]);
209 glutReshapeFunc(Reshape);
210 glutKeyboardFunc(Key);
211 glutSpecialFunc(SpecialKey);
212 glutDisplayFunc(Redisplay);
213 ParseOptions(argc, argv);
214 Init();
215 glutMainLoop();
216 return 0;
217}
218