1/** 2 * Test/demo of Ian McEwan's simplex noise function. 3 * See https://github.com/ashima/webgl-noise 4 * 5 * Brian Paul 6 * 17 March 2011 7 */ 8 9#include <assert.h> 10#include <string.h> 11#include <stdio.h> 12#include <stdlib.h> 13#include <math.h> 14#include <GL/glew.h> 15#include "glut_wrap.h" 16#include "shaderutil.h" 17 18 19static const char *VertShaderText = 20 "void main() {\n" 21 " gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;\n" 22 " gl_TexCoord[0] = gl_MultiTexCoord0;\n" 23 "}\n"; 24 25static const char *FragShaderMainText = 26 "uniform float Slice;\n" 27 "void main()\n" 28 "{\n" 29 " vec3 c = vec3(3.0 * gl_TexCoord[0].xy, Slice);\n" 30 " float r = simplexNoise3(c); \n" 31 " gl_FragColor = vec4(r, r, r, 1.0);;\n" 32 "}\n"; 33 34 35static struct uniform_info Uniforms[] = { 36 { "pParam", 1, GL_FLOAT_VEC4, { 17*17, 3, 2, 3 }, -1 }, 37 { "Slice", 1, GL_FLOAT, { 0.5, 0, 0, 0}, -1 }, 38 END_OF_UNIFORMS 39}; 40 41/* program/shader objects */ 42static GLuint fragShader; 43static GLuint vertShader; 44static GLuint program; 45 46static GLint win = 0; 47static GLfloat xRot = 0.0f, yRot = 0.0f, zRot = 0.0f; 48static GLfloat Slice = 0.0; 49static GLboolean Anim = GL_TRUE; 50static GLint ParamUniform = -1, SliceUniform = -1; 51 52 53static void 54Idle(void) 55{ 56 Slice = glutGet(GLUT_ELAPSED_TIME) * 0.001; 57 glutPostRedisplay(); 58} 59 60 61static void 62Redisplay(void) 63{ 64 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 65 66 glUniform1f(SliceUniform, Slice); 67 68 glPushMatrix(); 69 glRotatef(xRot, 1.0f, 0.0f, 0.0f); 70 glRotatef(yRot, 0.0f, 1.0f, 0.0f); 71 glRotatef(zRot, 0.0f, 0.0f, 1.0f); 72 73 glBegin(GL_POLYGON); 74 glTexCoord2f(0, 0); glVertex2f(-2, -2); 75 glTexCoord2f(1, 0); glVertex2f( 2, -2); 76 glTexCoord2f(1, 1); glVertex2f( 2, 2); 77 glTexCoord2f(0, 1); glVertex2f(-2, 2); 78 glEnd(); 79 80 glPopMatrix(); 81 82 glutSwapBuffers(); 83} 84 85 86static void 87Reshape(int width, int height) 88{ 89 glViewport(0, 0, width, height); 90 glMatrixMode(GL_PROJECTION); 91 glLoadIdentity(); 92 glFrustum(-1.0, 1.0, -1.0, 1.0, 5.0, 25.0); 93 glMatrixMode(GL_MODELVIEW); 94 glLoadIdentity(); 95 glTranslatef(0.0f, 0.0f, -15.0f); 96} 97 98 99static void 100CleanUp(void) 101{ 102 glDeleteShader(fragShader); 103 glDeleteShader(vertShader); 104 glDeleteProgram(program); 105 glutDestroyWindow(win); 106} 107 108 109static void 110Key(unsigned char key, int x, int y) 111{ 112 const GLfloat step = 1.0;//0.01; 113 (void) x; 114 (void) y; 115 116 switch(key) { 117 case 'a': 118 Anim = !Anim; 119 glutIdleFunc(Anim ? Idle : NULL); 120 break; 121 case 's': 122 Slice -= step; 123 break; 124 case 'S': 125 Slice += step; 126 break; 127 case 'z': 128 zRot -= 1.0; 129 break; 130 case 'Z': 131 zRot += 1.0; 132 break; 133 case 27: 134 CleanUp(); 135 exit(0); 136 break; 137 } 138 glutPostRedisplay(); 139} 140 141 142static void 143SpecialKey(int key, int x, int y) 144{ 145 const GLfloat step = 3.0f; 146 147 (void) x; 148 (void) y; 149 150 switch(key) { 151 case GLUT_KEY_UP: 152 xRot -= step; 153 break; 154 case GLUT_KEY_DOWN: 155 xRot += step; 156 break; 157 case GLUT_KEY_LEFT: 158 yRot -= step; 159 break; 160 case GLUT_KEY_RIGHT: 161 yRot += step; 162 break; 163 } 164 glutPostRedisplay(); 165} 166 167 168 169static void 170Init(void) 171{ 172 const char *filename = "simplex-noise.glsl"; 173 char noiseText[10000]; 174 FILE *f; 175 int len; 176 177 f = fopen(filename, "r"); 178 if (!f) { 179 fprintf(stderr, "Unable to open %s\n", filename); 180 exit(1); 181 } 182 183 len = fread(noiseText, 1, sizeof(noiseText), f); 184 fclose(f); 185 186 /* append main() code onto buffer */ 187 strcpy(noiseText + len, FragShaderMainText); 188 189 if (!ShadersSupported()) 190 exit(1); 191 192 vertShader = CompileShaderText(GL_VERTEX_SHADER, VertShaderText); 193 fragShader = CompileShaderText(GL_FRAGMENT_SHADER, noiseText); 194 program = LinkShaders(vertShader, fragShader); 195 196 glUseProgram(program); 197 198 ParamUniform = glGetUniformLocation(program, "pParam"); 199 SliceUniform = glGetUniformLocation(program, "Slice"); 200 201 SetUniformValues(program, Uniforms); 202 PrintUniforms(Uniforms); 203 204 assert(glGetError() == 0); 205 206 glClearColor(0.4f, 0.4f, 0.8f, 0.0f); 207 208 printf("GL_RENDERER = %s\n",(const char *) glGetString(GL_RENDERER)); 209 210 assert(glIsProgram(program)); 211 assert(glIsShader(fragShader)); 212 assert(glIsShader(vertShader)); 213 214 glColor3f(1, 0, 0); 215} 216 217 218int 219main(int argc, char *argv[]) 220{ 221 glutInit(&argc, argv); 222 glutInitWindowSize(400, 400); 223 glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH); 224 win = glutCreateWindow(argv[0]); 225 glewInit(); 226 glutReshapeFunc(Reshape); 227 glutKeyboardFunc(Key); 228 glutSpecialFunc(SpecialKey); 229 glutDisplayFunc(Redisplay); 230 glutIdleFunc(Anim ? Idle : NULL); 231 Init(); 232 glutMainLoop(); 233 return 0; 234} 235 236