blob: eeea4eb52ae2b6d259adee89598d4f4e5477d0e2 [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/gl.h>
14#include <GL/glut.h>
15#include <GL/glext.h>
16#include "extfuncs.h"
Brian2dca3372008-04-09 22:28:23 -060017#include "shaderutil.h"
Brian2ccd2642007-01-15 17:27:24 -070018
19
Brian Paulc0dd9122008-08-16 09:36:46 -060020static char *FragProgFile = "CH18-mandel.frag";
21static char *VertProgFile = "CH18-mandel.vert";
Brian2ccd2642007-01-15 17:27:24 -070022
23/* program/shader objects */
24static GLuint fragShader;
25static GLuint vertShader;
26static GLuint program;
27
28
Brian2ccd2642007-01-15 17:27:24 -070029static struct uniform_info Uniforms[] = {
30 /* vert */
Brian2dca3372008-04-09 22:28:23 -060031 { "LightPosition", 3, GL_FLOAT, { 0.1, 0.1, 9.0, 0}, -1 },
32 { "SpecularContribution", 1, GL_FLOAT, { 0.5, 0, 0, 0 }, -1 },
33 { "DiffuseContribution", 1, GL_FLOAT, { 0.5, 0, 0, 0 }, -1 },
34 { "Shininess", 1, GL_FLOAT, { 20.0, 0, 0, 0 }, -1 },
Brian2ccd2642007-01-15 17:27:24 -070035 /* frag */
Brian2dca3372008-04-09 22:28:23 -060036 { "MaxIterations", 1, GL_FLOAT, { 12, 0, 0, 0 }, -1 },
37 { "Zoom", 1, GL_FLOAT, { 0.125, 0, 0, 0 }, -1 },
38 { "Xcenter", 1, GL_FLOAT, { -1.5, 0, 0, 0 }, -1 },
39 { "Ycenter", 1, GL_FLOAT, { .005, 0, 0, 0 }, -1 },
40 { "InnerColor", 3, GL_FLOAT, { 1, 0, 0, 0 }, -1 },
41 { "OuterColor1", 3, GL_FLOAT, { 0, 1, 0, 0 }, -1 },
42 { "OuterColor2", 3, GL_FLOAT, { 0, 0, 1, 0 }, -1 },
43 END_OF_UNIFORMS
Brian2ccd2642007-01-15 17:27:24 -070044};
45
46static GLint win = 0;
47
Brian2ccd2642007-01-15 17:27:24 -070048static GLfloat xRot = 0.0f, yRot = 0.0f, zRot = 0.0f;
49
Brian0d553462007-01-15 17:48:19 -070050static GLint uZoom, uXcenter, uYcenter;
51static GLfloat zoom = 1.0, xCenter = -1.5, yCenter = 0.0;
Brian2ccd2642007-01-15 17:27:24 -070052
53
54static void
55Redisplay(void)
56{
57 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
58
Brian0d553462007-01-15 17:48:19 -070059 /* set interactive uniform parameters */
60 glUniform1fv_func(uZoom, 1, &zoom);
61 glUniform1fv_func(uXcenter, 1, &xCenter);
62 glUniform1fv_func(uYcenter, 1, &yCenter);
63
Brian2ccd2642007-01-15 17:27:24 -070064 glPushMatrix();
65 glRotatef(xRot, 1.0f, 0.0f, 0.0f);
66 glRotatef(yRot, 0.0f, 1.0f, 0.0f);
67 glRotatef(zRot, 0.0f, 0.0f, 1.0f);
68
69 glBegin(GL_POLYGON);
70 glTexCoord2f(0, 0); glVertex2f(-1, -1);
71 glTexCoord2f(1, 0); glVertex2f( 1, -1);
72 glTexCoord2f(1, 1); glVertex2f( 1, 1);
73 glTexCoord2f(0, 1); glVertex2f(-1, 1);
74 glEnd();
75
76 glPopMatrix();
77
78 glutSwapBuffers();
79}
80
81
82static void
83Reshape(int width, int height)
84{
85 glViewport(0, 0, width, height);
86 glMatrixMode(GL_PROJECTION);
87 glLoadIdentity();
88 glFrustum(-1.0, 1.0, -1.0, 1.0, 5.0, 25.0);
89 glMatrixMode(GL_MODELVIEW);
90 glLoadIdentity();
91 glTranslatef(0.0f, 0.0f, -6.0f);
92}
93
94
95static void
96CleanUp(void)
97{
98 glDeleteShader_func(fragShader);
99 glDeleteShader_func(vertShader);
100 glDeleteProgram_func(program);
101 glutDestroyWindow(win);
102}
103
104
105static void
106Key(unsigned char key, int x, int y)
107{
108 (void) x;
109 (void) y;
110
111 switch(key) {
112 case 'z':
Brian0d553462007-01-15 17:48:19 -0700113 zoom *= 0.9;
Brian2ccd2642007-01-15 17:27:24 -0700114 break;
115 case 'Z':
Brian0d553462007-01-15 17:48:19 -0700116 zoom /= 0.9;
Brian2ccd2642007-01-15 17:27:24 -0700117 break;
118 case 27:
119 CleanUp();
120 exit(0);
121 break;
122 }
123 glutPostRedisplay();
124}
125
126
127static void
128SpecialKey(int key, int x, int y)
129{
Brian0d553462007-01-15 17:48:19 -0700130 const GLfloat step = 0.1 * zoom;
Brian2ccd2642007-01-15 17:27:24 -0700131
132 (void) x;
133 (void) y;
134
135 switch(key) {
136 case GLUT_KEY_UP:
Brian0d553462007-01-15 17:48:19 -0700137 yCenter += step;
Brian2ccd2642007-01-15 17:27:24 -0700138 break;
139 case GLUT_KEY_DOWN:
Brian0d553462007-01-15 17:48:19 -0700140 yCenter -= step;
Brian2ccd2642007-01-15 17:27:24 -0700141 break;
142 case GLUT_KEY_LEFT:
Brian0d553462007-01-15 17:48:19 -0700143 xCenter -= step;
Brian2ccd2642007-01-15 17:27:24 -0700144 break;
145 case GLUT_KEY_RIGHT:
Brian0d553462007-01-15 17:48:19 -0700146 xCenter += step;
Brian2ccd2642007-01-15 17:27:24 -0700147 break;
148 }
149 glutPostRedisplay();
150}
151
152
Brian2ccd2642007-01-15 17:27:24 -0700153static void
154Init(void)
155{
Brian2dca3372008-04-09 22:28:23 -0600156 if (!ShadersSupported())
157 exit(1);
Brian2ccd2642007-01-15 17:27:24 -0700158
159 GetExtensionFuncs();
160
Brian2dca3372008-04-09 22:28:23 -0600161 vertShader = CompileShaderFile(GL_VERTEX_SHADER, VertProgFile);
162 fragShader = CompileShaderFile(GL_FRAGMENT_SHADER, FragProgFile);
163 program = LinkShaders(vertShader, fragShader);
Brian2ccd2642007-01-15 17:27:24 -0700164
Brian2ccd2642007-01-15 17:27:24 -0700165 glUseProgram_func(program);
166
Brian26f0b8f2008-04-09 22:29:33 -0600167 InitUniforms(program, Uniforms);
Brian2ccd2642007-01-15 17:27:24 -0700168
Brian0d553462007-01-15 17:48:19 -0700169 uZoom = glGetUniformLocation_func(program, "Zoom");
170 uXcenter = glGetUniformLocation_func(program, "Xcenter");
171 uYcenter = glGetUniformLocation_func(program, "Ycenter");
172
Brian2ccd2642007-01-15 17:27:24 -0700173 assert(glGetError() == 0);
174
175 glClearColor(0.4f, 0.4f, 0.8f, 0.0f);
176
177 printf("GL_RENDERER = %s\n",(const char *) glGetString(GL_RENDERER));
178
179 assert(glIsProgram_func(program));
180 assert(glIsShader_func(fragShader));
181 assert(glIsShader_func(vertShader));
182
183 glColor3f(1, 0, 0);
184}
185
186
187static void
188ParseOptions(int argc, char *argv[])
189{
190 int i;
191 for (i = 1; i < argc; i++) {
192 if (strcmp(argv[i], "-fs") == 0) {
193 FragProgFile = argv[i+1];
194 }
195 else if (strcmp(argv[i], "-vs") == 0) {
196 VertProgFile = argv[i+1];
197 }
198 }
199}
200
201
202int
203main(int argc, char *argv[])
204{
205 glutInit(&argc, argv);
206 glutInitWindowPosition( 0, 0);
207 glutInitWindowSize(400, 400);
208 glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
209 win = glutCreateWindow(argv[0]);
Keith Whitwellb799af92009-06-29 14:13:58 +0100210 glewInit();
Brian2ccd2642007-01-15 17:27:24 -0700211 glutReshapeFunc(Reshape);
212 glutKeyboardFunc(Key);
213 glutSpecialFunc(SpecialKey);
214 glutDisplayFunc(Redisplay);
215 ParseOptions(argc, argv);
216 Init();
217 glutMainLoop();
218 return 0;
219}
220