132001f49Smrg/**
232001f49Smrg * Test/demo of Ian McEwan's simplex noise function.
332001f49Smrg * See https://github.com/ashima/webgl-noise
432001f49Smrg *
532001f49Smrg * Brian Paul
632001f49Smrg * 17 March 2011
732001f49Smrg */
832001f49Smrg
932001f49Smrg#include <assert.h>
1032001f49Smrg#include <string.h>
1132001f49Smrg#include <stdio.h>
1232001f49Smrg#include <stdlib.h>
1332001f49Smrg#include <math.h>
1432001f49Smrg#include <GL/glew.h>
1532001f49Smrg#include "glut_wrap.h"
1632001f49Smrg#include "shaderutil.h"
1732001f49Smrg
1832001f49Smrg
1932001f49Smrgstatic const char *VertShaderText =
2032001f49Smrg   "void main() {\n"
2132001f49Smrg   "   gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;\n"
2232001f49Smrg   "   gl_TexCoord[0] = gl_MultiTexCoord0;\n"
2332001f49Smrg   "}\n";
2432001f49Smrg
2532001f49Smrgstatic const char *FragShaderMainText =
2632001f49Smrg   "uniform float Slice;\n"
2732001f49Smrg   "void main()\n"
2832001f49Smrg   "{\n"
2932001f49Smrg   "   vec3 c = vec3(3.0 * gl_TexCoord[0].xy, Slice);\n"
3032001f49Smrg   "   float r = simplexNoise3(c); \n"
3132001f49Smrg   "   gl_FragColor = vec4(r, r, r, 1.0);;\n"
3232001f49Smrg   "}\n";
3332001f49Smrg
3432001f49Smrg
3532001f49Smrgstatic struct uniform_info Uniforms[] = {
3632001f49Smrg   { "pParam",   1, GL_FLOAT_VEC4, { 17*17, 3, 2, 3 }, -1 },
3732001f49Smrg   { "Slice",    1, GL_FLOAT, { 0.5, 0, 0, 0}, -1 },
3832001f49Smrg   END_OF_UNIFORMS
3932001f49Smrg};
4032001f49Smrg
4132001f49Smrg/* program/shader objects */
4232001f49Smrgstatic GLuint fragShader;
4332001f49Smrgstatic GLuint vertShader;
4432001f49Smrgstatic GLuint program;
4532001f49Smrg
4632001f49Smrgstatic GLint win = 0;
4732001f49Smrgstatic GLfloat xRot = 0.0f, yRot = 0.0f, zRot = 0.0f;
4832001f49Smrgstatic GLfloat Slice = 0.0;
4932001f49Smrgstatic GLboolean Anim = GL_TRUE;
5032001f49Smrgstatic GLint ParamUniform = -1, SliceUniform = -1;
5132001f49Smrg
5232001f49Smrg
5332001f49Smrgstatic void
5432001f49SmrgIdle(void)
5532001f49Smrg{
5632001f49Smrg   Slice = glutGet(GLUT_ELAPSED_TIME) * 0.001;
5732001f49Smrg   glutPostRedisplay();
5832001f49Smrg}
5932001f49Smrg
6032001f49Smrg
6132001f49Smrgstatic void
6232001f49SmrgRedisplay(void)
6332001f49Smrg{
6432001f49Smrg   glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
6532001f49Smrg
6632001f49Smrg   glUniform1f(SliceUniform, Slice);
6732001f49Smrg
6832001f49Smrg   glPushMatrix();
6932001f49Smrg   glRotatef(xRot, 1.0f, 0.0f, 0.0f);
7032001f49Smrg   glRotatef(yRot, 0.0f, 1.0f, 0.0f);
7132001f49Smrg   glRotatef(zRot, 0.0f, 0.0f, 1.0f);
7232001f49Smrg
7332001f49Smrg   glBegin(GL_POLYGON);
7432001f49Smrg   glTexCoord2f(0, 0);   glVertex2f(-2, -2);
7532001f49Smrg   glTexCoord2f(1, 0);   glVertex2f( 2, -2);
7632001f49Smrg   glTexCoord2f(1, 1);   glVertex2f( 2,  2);
7732001f49Smrg   glTexCoord2f(0, 1);   glVertex2f(-2,  2);
7832001f49Smrg   glEnd();
7932001f49Smrg
8032001f49Smrg   glPopMatrix();
8132001f49Smrg
8232001f49Smrg   glutSwapBuffers();
8332001f49Smrg}
8432001f49Smrg
8532001f49Smrg
8632001f49Smrgstatic void
8732001f49SmrgReshape(int width, int height)
8832001f49Smrg{
8932001f49Smrg   glViewport(0, 0, width, height);
9032001f49Smrg   glMatrixMode(GL_PROJECTION);
9132001f49Smrg   glLoadIdentity();
9232001f49Smrg   glFrustum(-1.0, 1.0, -1.0, 1.0, 5.0, 25.0);
9332001f49Smrg   glMatrixMode(GL_MODELVIEW);
9432001f49Smrg   glLoadIdentity();
9532001f49Smrg   glTranslatef(0.0f, 0.0f, -15.0f);
9632001f49Smrg}
9732001f49Smrg
9832001f49Smrg
9932001f49Smrgstatic void
10032001f49SmrgCleanUp(void)
10132001f49Smrg{
10232001f49Smrg   glDeleteShader(fragShader);
10332001f49Smrg   glDeleteShader(vertShader);
10432001f49Smrg   glDeleteProgram(program);
10532001f49Smrg   glutDestroyWindow(win);
10632001f49Smrg}
10732001f49Smrg
10832001f49Smrg
10932001f49Smrgstatic void
11032001f49SmrgKey(unsigned char key, int x, int y)
11132001f49Smrg{
11232001f49Smrg   const GLfloat step = 1.0;//0.01;
11332001f49Smrg  (void) x;
11432001f49Smrg  (void) y;
11532001f49Smrg
11632001f49Smrg   switch(key) {
11732001f49Smrg   case 'a':
11832001f49Smrg      Anim = !Anim;
11932001f49Smrg      glutIdleFunc(Anim ? Idle : NULL);
12032001f49Smrg      break;
12132001f49Smrg   case 's':
12232001f49Smrg      Slice -= step;
12332001f49Smrg      break;
12432001f49Smrg   case 'S':
12532001f49Smrg      Slice += step;
12632001f49Smrg      break;
12732001f49Smrg   case 'z':
12832001f49Smrg      zRot -= 1.0;
12932001f49Smrg      break;
13032001f49Smrg   case 'Z':
13132001f49Smrg      zRot += 1.0;
13232001f49Smrg      break;
13332001f49Smrg   case 27:
13432001f49Smrg      CleanUp();
13532001f49Smrg      exit(0);
13632001f49Smrg      break;
13732001f49Smrg   }
13832001f49Smrg   glutPostRedisplay();
13932001f49Smrg}
14032001f49Smrg
14132001f49Smrg
14232001f49Smrgstatic void
14332001f49SmrgSpecialKey(int key, int x, int y)
14432001f49Smrg{
14532001f49Smrg   const GLfloat step = 3.0f;
14632001f49Smrg
14732001f49Smrg  (void) x;
14832001f49Smrg  (void) y;
14932001f49Smrg
15032001f49Smrg   switch(key) {
15132001f49Smrg   case GLUT_KEY_UP:
15232001f49Smrg      xRot -= step;
15332001f49Smrg      break;
15432001f49Smrg   case GLUT_KEY_DOWN:
15532001f49Smrg      xRot += step;
15632001f49Smrg      break;
15732001f49Smrg   case GLUT_KEY_LEFT:
15832001f49Smrg      yRot -= step;
15932001f49Smrg      break;
16032001f49Smrg   case GLUT_KEY_RIGHT:
16132001f49Smrg      yRot += step;
16232001f49Smrg      break;
16332001f49Smrg   }
16432001f49Smrg   glutPostRedisplay();
16532001f49Smrg}
16632001f49Smrg
16732001f49Smrg
16832001f49Smrg
16932001f49Smrgstatic void
17032001f49SmrgInit(void)
17132001f49Smrg{
17232001f49Smrg   const char *filename = "simplex-noise.glsl";
17332001f49Smrg   char noiseText[10000];
17432001f49Smrg   FILE *f;
17532001f49Smrg   int len;
17632001f49Smrg
17732001f49Smrg   f = fopen(filename, "r");
17832001f49Smrg   if (!f) {
17932001f49Smrg      fprintf(stderr, "Unable to open %s\n", filename);
18032001f49Smrg      exit(1);
18132001f49Smrg   }
18232001f49Smrg
18332001f49Smrg   len = fread(noiseText, 1, sizeof(noiseText), f);
18432001f49Smrg   fclose(f);
18532001f49Smrg
18632001f49Smrg   /* append main() code onto buffer */
18732001f49Smrg   strcpy(noiseText + len, FragShaderMainText);
18832001f49Smrg
18932001f49Smrg   if (!ShadersSupported())
19032001f49Smrg      exit(1);
19132001f49Smrg
19232001f49Smrg   vertShader = CompileShaderText(GL_VERTEX_SHADER, VertShaderText);
19332001f49Smrg   fragShader = CompileShaderText(GL_FRAGMENT_SHADER, noiseText);
19432001f49Smrg   program = LinkShaders(vertShader, fragShader);
19532001f49Smrg
19632001f49Smrg   glUseProgram(program);
19732001f49Smrg
19832001f49Smrg   ParamUniform = glGetUniformLocation(program, "pParam");
19932001f49Smrg   SliceUniform = glGetUniformLocation(program, "Slice");
20032001f49Smrg
20132001f49Smrg   SetUniformValues(program, Uniforms);
20232001f49Smrg   PrintUniforms(Uniforms);
20332001f49Smrg
20432001f49Smrg   assert(glGetError() == 0);
20532001f49Smrg
20632001f49Smrg   glClearColor(0.4f, 0.4f, 0.8f, 0.0f);
20732001f49Smrg
20832001f49Smrg   printf("GL_RENDERER = %s\n",(const char *) glGetString(GL_RENDERER));
20932001f49Smrg
21032001f49Smrg   assert(glIsProgram(program));
21132001f49Smrg   assert(glIsShader(fragShader));
21232001f49Smrg   assert(glIsShader(vertShader));
21332001f49Smrg
21432001f49Smrg   glColor3f(1, 0, 0);
21532001f49Smrg}
21632001f49Smrg
21732001f49Smrg
21832001f49Smrgint
21932001f49Smrgmain(int argc, char *argv[])
22032001f49Smrg{
22132001f49Smrg   glutInit(&argc, argv);
22232001f49Smrg   glutInitWindowSize(400, 400);
22332001f49Smrg   glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
22432001f49Smrg   win = glutCreateWindow(argv[0]);
22532001f49Smrg   glewInit();
22632001f49Smrg   glutReshapeFunc(Reshape);
22732001f49Smrg   glutKeyboardFunc(Key);
22832001f49Smrg   glutSpecialFunc(SpecialKey);
22932001f49Smrg   glutDisplayFunc(Redisplay);
23032001f49Smrg   glutIdleFunc(Anim ? Idle : NULL);
23132001f49Smrg   Init();
23232001f49Smrg   glutMainLoop();
23332001f49Smrg   return 0;
23432001f49Smrg}
23532001f49Smrg
236