diff options
Diffstat (limited to 'progs')
| -rw-r--r-- | progs/demos/Makefile | 7 | ||||
| -rw-r--r-- | progs/demos/fslight.c | 385 | ||||
| -rw-r--r-- | progs/glsl/CH06-brick.frag.txt | 36 | ||||
| -rw-r--r-- | progs/glsl/CH06-brick.vert.txt | 41 | ||||
| -rw-r--r-- | progs/glsl/CH11-bumpmap.frag.txt | 41 | ||||
| -rw-r--r-- | progs/glsl/CH11-bumpmap.vert.txt | 38 | ||||
| -rw-r--r-- | progs/glsl/CH11-toyball.frag.txt | 75 | ||||
| -rw-r--r-- | progs/glsl/CH11-toyball.vert.txt | 24 | ||||
| -rw-r--r-- | progs/glsl/CH18-mandel.frag.txt | 55 | ||||
| -rw-r--r-- | progs/glsl/CH18-mandel.vert.txt | 35 | ||||
| -rw-r--r-- | progs/glsl/Makefile | 74 | ||||
| -rw-r--r-- | progs/glsl/brick.c | 311 | ||||
| -rw-r--r-- | progs/glsl/bump.c | 411 | ||||
| -rw-r--r-- | progs/glsl/cubemap.frag.txt | 18 | ||||
| -rw-r--r-- | progs/glsl/mandelbrot.c | 328 | ||||
| -rw-r--r-- | progs/glsl/noise.c | 297 | ||||
| -rw-r--r-- | progs/glsl/reflect.vert.txt | 19 | ||||
| -rw-r--r-- | progs/glsl/shadowtex.frag.txt | 21 | ||||
| -rw-r--r-- | progs/glsl/simple.vert.txt | 9 | ||||
| -rw-r--r-- | progs/glsl/texdemo1.c | 570 | ||||
| -rw-r--r-- | progs/glsl/toyball.c | 339 | ||||
| -rw-r--r-- | progs/util/extfuncs.h | 118 | 
22 files changed, 3200 insertions, 52 deletions
| diff --git a/progs/demos/Makefile b/progs/demos/Makefile index 4623d6c8d9..6369746f00 100644 --- a/progs/demos/Makefile +++ b/progs/demos/Makefile @@ -113,6 +113,10 @@ trackball.o: trackball.c trackball.h  	$(CC) -c -I$(INCDIR) $(CFLAGS) trackball.c +extfuncs.h:  $(TOP)/progs/util/extfuncs.h +	cp $< . + +  reflect: reflect.o showbuffer.o readtex.o  	$(CC) -I$(INCDIR) $(CFLAGS) reflect.o showbuffer.o readtex.o $(APP_LIB_DEPS) -o $@ @@ -141,6 +145,9 @@ engine.o: engine.c trackball.h  	$(CC) -c -I$(INCDIR) $(CFLAGS) engine.c +fslight.c: extfuncs.h + +  clean:  	-rm -f $(PROGS)  	-rm -f *.o *~ diff --git a/progs/demos/fslight.c b/progs/demos/fslight.c index 1c016cc75e..2fa25a0adf 100644 --- a/progs/demos/fslight.c +++ b/progs/demos/fslight.c @@ -20,46 +20,37 @@  #include <GL/gl.h>  #include <GL/glut.h>  #include <GL/glext.h> +#include "extfuncs.h" + + +static GLint CoordAttrib = 0; + +static char *FragProgFile = NULL; +static char *VertProgFile = NULL;  static GLfloat diffuse[4] = { 0.5f, 0.5f, 1.0f, 1.0f };  static GLfloat specular[4] = { 0.8f, 0.8f, 0.8f, 1.0f }; -static GLfloat lightPos[4] = { 0.0f, 10.0f, 20.0f, 1.0f }; +static GLfloat lightPos[4] = { 0.0f, 10.0f, 20.0f, 0.0f };  static GLfloat delta = 1.0f;  static GLuint fragShader;  static GLuint vertShader;  static GLuint program; -static GLint uLightPos;  static GLint uDiffuse;  static GLint uSpecular; +static GLint uTexture; +static GLuint SphereList, RectList, CurList;  static GLint win = 0; -static GLboolean anim = GL_TRUE; +static GLboolean anim = GL_FALSE;  static GLboolean wire = GL_FALSE;  static GLboolean pixelLight = GL_TRUE;  static GLint t0 = 0;  static GLint frames = 0; -static GLfloat xRot = 0.0f, yRot = 0.0f; - -static PFNGLCREATESHADERPROC glCreateShader_func = NULL; -static PFNGLSHADERSOURCEPROC glShaderSource_func = NULL; -static PFNGLGETSHADERSOURCEPROC glGetShaderSource_func = NULL; -static PFNGLCOMPILESHADERPROC glCompileShader_func = NULL; -static PFNGLCREATEPROGRAMPROC glCreateProgram_func = NULL; -static PFNGLDELETEPROGRAMPROC glDeleteProgram_func = NULL; -static PFNGLDELETESHADERPROC glDeleteShader_func = NULL; -static PFNGLATTACHSHADERPROC glAttachShader_func = NULL; -static PFNGLLINKPROGRAMPROC glLinkProgram_func = NULL; -static PFNGLUSEPROGRAMPROC glUseProgram_func = NULL; -static PFNGLGETUNIFORMLOCATIONPROC glGetUniformLocation_func = NULL; -static PFNGLISPROGRAMPROC glIsProgram_func = NULL; -static PFNGLISSHADERPROC glIsShader_func = NULL; -static PFNGLUNIFORM3FVPROC glUniform3fv_func = NULL; -static PFNGLUNIFORM3FVPROC glUniform4fv_func = NULL; - +static GLfloat xRot = 90.0f, yRot = 0.0f;  static void @@ -69,31 +60,37 @@ normalize(GLfloat *dst, const GLfloat *src)     dst[0] = src[0] / len;     dst[1] = src[1] / len;     dst[2] = src[2] / len; +   dst[3] = src[3];  }  static void  Redisplay(void)  { +   GLfloat vec[4]; +     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + +   /* update light position */ +   normalize(vec, lightPos); +   glLightfv(GL_LIGHT0, GL_POSITION, vec);     if (pixelLight) { -      GLfloat vec[3];        glUseProgram_func(program); -      normalize(vec, lightPos); -      glUniform3fv_func(uLightPos, 1, vec);        glDisable(GL_LIGHTING);     }     else {        glUseProgram_func(0); -      glLightfv(GL_LIGHT0, GL_POSITION, lightPos);        glEnable(GL_LIGHTING);     }     glPushMatrix();     glRotatef(xRot, 1.0f, 0.0f, 0.0f);     glRotatef(yRot, 0.0f, 1.0f, 0.0f); +   /*     glutSolidSphere(2.0, 10, 5); +   */ +   glCallList(CurList);     glPopMatrix();     glutSwapBuffers(); @@ -174,6 +171,12 @@ Key(unsigned char key, int x, int y)        else           glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);        break; +   case 'o': +      if (CurList == SphereList) +         CurList = RectList; +      else +         CurList = SphereList; +      break;     case 'p':        pixelLight = !pixelLight;        if (pixelLight) @@ -217,16 +220,246 @@ SpecialKey(int key, int x, int y)  static void +TestFunctions(void) +{ +   printf("Error 0x%x at line %d\n", glGetError(), __LINE__); +   { +      GLfloat pos[3]; +      printf("Error 0x%x at line %d\n", glGetError(), __LINE__); +      printf("Light pos %g %g %g\n", pos[0], pos[1], pos[2]); +   } + + +   { +      GLfloat m[16], result[16]; +      GLint mPos; +      int i; + +      for (i = 0; i < 16; i++) +         m[i] = (float) i; + +      mPos = glGetUniformLocation_func(program, "m"); +      printf("Error 0x%x at line %d\n", glGetError(), __LINE__); +      glUniformMatrix4fv_func(mPos, 1, GL_FALSE, m); +      printf("Error 0x%x at line %d\n", glGetError(), __LINE__); + +      glGetUniformfv_func(program, mPos, result); +      printf("Error 0x%x at line %d\n", glGetError(), __LINE__); + +      for (i = 0; i < 16; i++) { +         printf("%8g %8g\n", m[i], result[i]); +      } +   } + +   assert(glIsProgram_func(program)); +   assert(glIsShader_func(fragShader)); +   assert(glIsShader_func(vertShader)); + +   /* attached shaders */ +   { +      GLuint shaders[20]; +      GLsizei count; +      int i; +      glGetAttachedShaders_func(program, 20, &count, shaders); +      for (i = 0; i < count; i++) { +         printf("Attached: %u\n", shaders[i]); +         assert(shaders[i] == fragShader || +                shaders[i] == vertShader); +      } +   } + +   { +      GLchar log[1000]; +      GLsizei len; +      glGetShaderInfoLog_func(vertShader, 1000, &len, log); +      printf("Vert Shader Info Log: %s\n", log); +      glGetShaderInfoLog_func(fragShader, 1000, &len, log); +      printf("Frag Shader Info Log: %s\n", log); +      glGetProgramInfoLog_func(program, 1000, &len, log); +      printf("Program Info Log: %s\n", log); +   } +} + + +static void +MakeTexture(void) +{ +#define SZ0 128 +#define SZ1 64 +   GLubyte image0[SZ0][SZ0][SZ0][4]; +   GLubyte image1[SZ1][SZ1][SZ1][4]; +   GLuint i, j, k; + +   /* level 0: two-tone gray checkboard */ +   for (i = 0; i < SZ0; i++) { +      for (j = 0; j < SZ0; j++) { +         for (k = 0; k < SZ0; k++) { +            if ((i/8 + j/8 + k/8) & 1) { +               image0[i][j][k][0] =  +               image0[i][j][k][1] =  +               image0[i][j][k][2] = 200; +            } +            else { +               image0[i][j][k][0] =  +               image0[i][j][k][1] =  +               image0[i][j][k][2] = 100; +            } +            image0[i][j][k][3] = 255; +         } +      } +   } + +   /* level 1: two-tone green checkboard */ +   for (i = 0; i < SZ1; i++) { +      for (j = 0; j < SZ1; j++) { +         for (k = 0; k < SZ1; k++) { +            if ((i/8 + j/8 + k/8) & 1) { +               image1[i][j][k][0] = 0; +               image1[i][j][k][1] = 250; +               image1[i][j][k][2] = 0; +            } +            else { +               image1[i][j][k][0] = 0; +               image1[i][j][k][1] = 200; +               image1[i][j][k][2] = 0; +            } +            image1[i][j][k][3] = 255; +         } +      } +   } + +   glActiveTexture(GL_TEXTURE2); /* unit 2 */ +   glBindTexture(GL_TEXTURE_2D, 42); +   glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, SZ0, SZ0, 0, +                GL_RGBA, GL_UNSIGNED_BYTE, image0); +   glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA, SZ1, SZ1, 0, +                GL_RGBA, GL_UNSIGNED_BYTE, image1); +   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 1); +   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); +   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + +   glActiveTexture(GL_TEXTURE4); /* unit 4 */ +   glBindTexture(GL_TEXTURE_3D, 43); +   glTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA, SZ0, SZ0, SZ0, 0, +                GL_RGBA, GL_UNSIGNED_BYTE, image0); +   glTexImage3D(GL_TEXTURE_3D, 1, GL_RGBA, SZ1, SZ1, SZ1, 0, +                GL_RGBA, GL_UNSIGNED_BYTE, image1); +   glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAX_LEVEL, 1); +   glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); +   glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); +} + + +static void +MakeSphere(void) +{ +   GLUquadricObj *obj = gluNewQuadric(); +   SphereList = glGenLists(1); +   gluQuadricTexture(obj, GL_TRUE); +   glNewList(SphereList, GL_COMPILE); +   gluSphere(obj, 2.0f, 10, 5); +   glEndList(); +} + +static void +VertAttrib(GLint index, float x, float y) +{ +#if 1 +   glVertexAttrib2f_func(index, x, y); +#else +   glTexCoord2f(x, y); +#endif +} + +static void +MakeRect(void) +{ +   RectList = glGenLists(1); +   glNewList(RectList, GL_COMPILE); +   glNormal3f(0, 0, 1); +   glBegin(GL_POLYGON); +   VertAttrib(CoordAttrib, 0, 0);   glVertex2f(-2, -2); +   VertAttrib(CoordAttrib, 1, 0);   glVertex2f( 2, -2); +   VertAttrib(CoordAttrib, 1, 1);   glVertex2f( 2,  2); +   VertAttrib(CoordAttrib, 0, 1);   glVertex2f(-2,  2); +   glEnd();    /* XXX omit this and crash! */ +   glEndList(); +} + + + +static void +LoadAndCompileShader(GLuint shader, const char *text) +{ +   GLint stat; + +   glShaderSource_func(shader, 1, (const GLchar **) &text, NULL); + +   glCompileShader_func(shader); + +   glGetShaderiv_func(shader, GL_COMPILE_STATUS, &stat); +   if (!stat) { +      GLchar log[1000]; +      GLsizei len; +      glGetShaderInfoLog_func(shader, 1000, &len, log); +      fprintf(stderr, "fslight: problem compiling shader:\n%s\n", log); +      exit(1); +   } +} + + +/** + * Read a shader from a file. + */ +static void +ReadShader(GLuint shader, const char *filename) +{ +   const int max = 100*1000; +   int n; +   char *buffer = (char*) malloc(max); +   FILE *f = fopen(filename, "r"); +   if (!f) { +      fprintf(stderr, "fslight: Unable to open shader file %s\n", filename); +      exit(1); +   } + +   n = fread(buffer, 1, max, f); +   printf("fslight: read %d bytes from shader file %s\n", n, filename); +   if (n > 0) { +      buffer[n] = 0; +      LoadAndCompileShader(shader, buffer); +   } + +   fclose(f); +   free(buffer); +} + + +static void +CheckLink(GLuint prog) +{ +   GLint stat; +   glGetProgramiv_func(prog, GL_LINK_STATUS, &stat); +   if (!stat) { +      GLchar log[1000]; +      GLsizei len; +      glGetProgramInfoLog_func(prog, 1000, &len, log); +      fprintf(stderr, "Linker error:\n%s\n", log); +   } +} + + +static void  Init(void)  {     static const char *fragShaderText = -      "uniform vec3 lightPos;\n"        "uniform vec4 diffuse;\n"        "uniform vec4 specular;\n"        "varying vec3 normal;\n"        "void main() {\n"        "   // Compute dot product of light direction and normal vector\n" -      "   float dotProd = max(dot(lightPos, normalize(normal)), 0.0);\n" +      "   float dotProd = max(dot(gl_LightSource[0].position.xyz, \n" +      "                           normalize(normal)), 0.0);\n"        "   // Compute diffuse and specular contributions\n"        "   gl_FragColor = diffuse * dotProd + specular * pow(dotProd, 20.0);\n"        "}\n"; @@ -236,8 +469,6 @@ Init(void)        "   gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;\n"        "   normal = gl_NormalMatrix * gl_Normal;\n"        "}\n"; - -     const char *version;     version = (const char *) glGetString(GL_VERSION); @@ -246,43 +477,55 @@ Init(void)        /*exit(1);*/     } - -   glCreateShader_func = (PFNGLCREATESHADERPROC) glutGetProcAddress("glCreateShader"); -   glDeleteShader_func = (PFNGLDELETESHADERPROC) glutGetProcAddress("glDeleteShader"); -   glDeleteProgram_func = (PFNGLDELETEPROGRAMPROC) glutGetProcAddress("glDeleteProgram"); -   glShaderSource_func = (PFNGLSHADERSOURCEPROC) glutGetProcAddress("glShaderSource"); -   glGetShaderSource_func = (PFNGLGETSHADERSOURCEPROC) glutGetProcAddress("glGetShaderSource"); -   glCompileShader_func = (PFNGLCOMPILESHADERPROC) glutGetProcAddress("glCompileShader"); -   glCreateProgram_func = (PFNGLCREATEPROGRAMPROC) glutGetProcAddress("glCreateProgram"); -   glAttachShader_func = (PFNGLATTACHSHADERPROC) glutGetProcAddress("glAttachShader"); -   glLinkProgram_func = (PFNGLLINKPROGRAMPROC) glutGetProcAddress("glLinkProgram"); -   glUseProgram_func = (PFNGLUSEPROGRAMPROC) glutGetProcAddress("glUseProgram"); -   glGetUniformLocation_func = (PFNGLGETUNIFORMLOCATIONPROC) glutGetProcAddress("glGetUniformLocation"); -   glIsProgram_func = (PFNGLISPROGRAMPROC) glutGetProcAddress("glIsProgram"); -   glIsShader_func = (PFNGLISSHADERPROC) glutGetProcAddress("glIsShader"); -   glUniform3fv_func = (PFNGLUNIFORM3FVPROC) glutGetProcAddress("glUniform3fv"); -   glUniform4fv_func = (PFNGLUNIFORM3FVPROC) glutGetProcAddress("glUniform4fv"); +   GetExtensionFuncs();     fragShader = glCreateShader_func(GL_FRAGMENT_SHADER); -   glShaderSource_func(fragShader, 1, &fragShaderText, NULL); -   glCompileShader_func(fragShader); +   if (FragProgFile) +      ReadShader(fragShader, FragProgFile); +   else +      LoadAndCompileShader(fragShader, fragShaderText); +     vertShader = glCreateShader_func(GL_VERTEX_SHADER); -   glShaderSource_func(vertShader, 1, &vertShaderText, NULL); -   glCompileShader_func(vertShader); +   if (VertProgFile) +      ReadShader(vertShader, VertProgFile); +   else +      LoadAndCompileShader(vertShader, vertShaderText);     program = glCreateProgram_func();     glAttachShader_func(program, fragShader);     glAttachShader_func(program, vertShader);     glLinkProgram_func(program); +   CheckLink(program);     glUseProgram_func(program); -   uLightPos = glGetUniformLocation_func(program, "lightPos");     uDiffuse = glGetUniformLocation_func(program, "diffuse");     uSpecular = glGetUniformLocation_func(program, "specular"); +   uTexture = glGetUniformLocation_func(program, "texture"); +   printf("DiffusePos %d  SpecularPos %d  TexturePos %d\n", +          uDiffuse, uSpecular, uTexture);     glUniform4fv_func(uDiffuse, 1, diffuse);     glUniform4fv_func(uSpecular, 1, specular); +   assert(glGetError() == 0); +   glUniform1i_func(uTexture, 2);  /* use texture unit 2 */ +   /*assert(glGetError() == 0);*/ + +   if (CoordAttrib) { +      int i; +      glBindAttribLocation_func(program, CoordAttrib, "coord"); +      i = glGetAttribLocation_func(program, "coord"); +      assert(i >= 0); +      if (i != CoordAttrib) { +         printf("Hmmm, NVIDIA bug?\n"); +         CoordAttrib = i; +      } +      else { +         printf("Mesa bind attrib: coord = %d\n", i); +      } +   } + +   /*assert(glGetError() == 0);*/     glClearColor(0.3f, 0.3f, 0.3f, 0.0f);     glEnable(GL_DEPTH_TEST); @@ -292,11 +535,18 @@ Init(void)     glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, specular);     glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 20.0f); +   MakeSphere(); +   MakeRect(); + +   CurList = SphereList; + +   MakeTexture(); +     printf("GL_RENDERER = %s\n",(const char *) glGetString(GL_RENDERER));     printf("Press p to toggle between per-pixel and per-vertex lighting\n");     /* test glGetShaderSource() */ -   { +   if (0) {        GLsizei len = strlen(fragShaderText) + 1;        GLsizei lenOut;        GLchar *src =(GLchar *) malloc(len * sizeof(GLchar)); @@ -310,6 +560,35 @@ Init(void)     assert(glIsProgram_func(program));     assert(glIsShader_func(fragShader));     assert(glIsShader_func(vertShader)); + +   glColor3f(1, 0, 0); + +   /* for testing state vars */ +   { +      static GLfloat fc[4] = { 1, 1, 0, 0 }; +      static GLfloat amb[4] = { 1, 0, 1, 0 }; +      glFogfv(GL_FOG_COLOR, fc); +      glLightfv(GL_LIGHT1, GL_AMBIENT, amb); +   } + +#if 0 +   TestFunctions(); +#endif +} + + +static void +ParseOptions(int argc, char *argv[]) +{ +   int i; +   for (i = 1; i < argc; i++) { +      if (strcmp(argv[i], "-fs") == 0) { +         FragProgFile = argv[i+1]; +      } +      else if (strcmp(argv[i], "-vs") == 0) { +         VertProgFile = argv[i+1]; +      } +   }  } @@ -318,7 +597,7 @@ main(int argc, char *argv[])  {     glutInit(&argc, argv);     glutInitWindowPosition( 0, 0); -   glutInitWindowSize(200, 200); +   glutInitWindowSize(100, 100);     glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);     win = glutCreateWindow(argv[0]);     glutReshapeFunc(Reshape); @@ -327,8 +606,10 @@ main(int argc, char *argv[])     glutDisplayFunc(Redisplay);     if (anim)        glutIdleFunc(Idle); +   ParseOptions(argc, argv);     Init();     glutMainLoop();     return 0;  } + diff --git a/progs/glsl/CH06-brick.frag.txt b/progs/glsl/CH06-brick.frag.txt new file mode 100644 index 0000000000..06ef04e3af --- /dev/null +++ b/progs/glsl/CH06-brick.frag.txt @@ -0,0 +1,36 @@ +// +// Fragment shader for procedural bricks +// +// Authors: Dave Baldwin, Steve Koren, Randi Rost +//          based on a shader by Darwyn Peachey +// +// Copyright (c) 2002-2006 3Dlabs Inc. Ltd.  +// +// See 3Dlabs-License.txt for license information +// + +uniform vec3  BrickColor, MortarColor; +uniform vec2  BrickSize; +uniform vec2  BrickPct; + +varying vec2  MCposition; +varying float LightIntensity; + +void main() +{ +    vec3  color; +    vec2  position, useBrick; +     +    position = MCposition / BrickSize; + +    if (fract(position.y * 0.5) > 0.5) +        position.x += 0.5; + +    position = fract(position); + +    useBrick = step(position, BrickPct); + +    color  = mix(MortarColor, BrickColor, useBrick.x * useBrick.y); +    color *= LightIntensity; +    gl_FragColor = vec4(color, 1.0); +} diff --git a/progs/glsl/CH06-brick.vert.txt b/progs/glsl/CH06-brick.vert.txt new file mode 100644 index 0000000000..e95e6f42f0 --- /dev/null +++ b/progs/glsl/CH06-brick.vert.txt @@ -0,0 +1,41 @@ +// +// Vertex shader for procedural bricks +// +// Authors: Dave Baldwin, Steve Koren, Randi Rost +//          based on a shader by Darwyn Peachey +// +// Copyright (c) 2002-2006 3Dlabs Inc. Ltd.  +// +// See 3Dlabs-License.txt for license information +// + +uniform vec3 LightPosition; + +const float SpecularContribution = 0.3; +const float DiffuseContribution  = 1.0 - SpecularContribution; + +varying float LightIntensity; +varying vec2  MCposition; + +void main() +{ +    vec3 ecPosition = vec3(gl_ModelViewMatrix * gl_Vertex); +    vec3 tnorm      = normalize(gl_NormalMatrix * gl_Normal); +    vec3 lightVec   = normalize(LightPosition - ecPosition); +    vec3 reflectVec = reflect(-lightVec, tnorm); +    vec3 viewVec    = normalize(-ecPosition); +    float diffuse   = max(dot(lightVec, tnorm), 0.0); +    float spec      = 0.0; + +    if (diffuse > 0.0) +    { +        spec = max(dot(reflectVec, viewVec), 0.0); +        spec = pow(spec, 16.0); +    } + +    LightIntensity  = DiffuseContribution * diffuse + +                      SpecularContribution * spec; + +    MCposition      = gl_Vertex.xy; +    gl_Position     = ftransform(); +} diff --git a/progs/glsl/CH11-bumpmap.frag.txt b/progs/glsl/CH11-bumpmap.frag.txt new file mode 100644 index 0000000000..063576f5a3 --- /dev/null +++ b/progs/glsl/CH11-bumpmap.frag.txt @@ -0,0 +1,41 @@ +// +// Fragment shader for procedural bumps +// +// Authors: John Kessenich, Randi Rost +// +// Copyright (c) 2002-2006 3Dlabs Inc. Ltd.  +// +// See 3Dlabs-License.txt for license information +// + +varying vec3 LightDir; +varying vec3 EyeDir; + +uniform vec3  SurfaceColor;    // = (0.7, 0.6, 0.18) +uniform float BumpDensity;     // = 16.0 +uniform float BumpSize;        // = 0.15 +uniform float SpecularFactor;  // = 0.5 + +void main() +{ +    vec3 litColor; +    vec2 c = BumpDensity * gl_TexCoord[0].st; +    vec2 p = fract(c) - vec2(0.5); + +    float d, f; +    d = p.x * p.x + p.y * p.y; +    f = 1.0 / sqrt(d + 1.0); + +    if (d >= BumpSize) +        { p = vec2(0.0); f = 1.0; } + +    vec3 normDelta = vec3(p.x, p.y, 1.0) * f; +    litColor = SurfaceColor * max(dot(normDelta, LightDir), 0.0); +    vec3 reflectDir = reflect(LightDir, normDelta); +     +    float spec = max(dot(EyeDir, reflectDir), 0.0); +    spec *= SpecularFactor; +    litColor = min(litColor + spec, vec3(1.0)); + +    gl_FragColor = vec4(litColor, 1.0); +} diff --git a/progs/glsl/CH11-bumpmap.vert.txt b/progs/glsl/CH11-bumpmap.vert.txt new file mode 100644 index 0000000000..d3d19f62ac --- /dev/null +++ b/progs/glsl/CH11-bumpmap.vert.txt @@ -0,0 +1,38 @@ +// +// Vertex shader for procedural bumps +// +// Authors: Randi Rost, John Kessenich +// +// Copyright (c) 2002-2006 3Dlabs Inc. Ltd.  +// +// See 3Dlabs-License.txt for license information +// + +varying vec3 LightDir; +varying vec3 EyeDir; + +uniform vec3 LightPosition; + +attribute vec3 Tangent; + +void main()  +{ +    EyeDir         = vec3(gl_ModelViewMatrix * gl_Vertex); +    gl_Position    = ftransform(); +    gl_TexCoord[0] = gl_MultiTexCoord0; + +    vec3 n = normalize(gl_NormalMatrix * gl_Normal); +    vec3 t = normalize(gl_NormalMatrix * Tangent); +    vec3 b = cross(n, t); + +    vec3 v; +    v.x = dot(LightPosition, t); +    v.y = dot(LightPosition, b); +    v.z = dot(LightPosition, n); +    LightDir = normalize(v); + +    v.x = dot(EyeDir, t); +    v.y = dot(EyeDir, b); +    v.z = dot(EyeDir, n); +    EyeDir = normalize(v); +} diff --git a/progs/glsl/CH11-toyball.frag.txt b/progs/glsl/CH11-toyball.frag.txt new file mode 100644 index 0000000000..90ec1c27fc --- /dev/null +++ b/progs/glsl/CH11-toyball.frag.txt @@ -0,0 +1,75 @@ +// +// Fragment shader for procedurally generated toy ball +// +// Author: Bill Licea-Kane +// +// Copyright (c) 2002-2003 ATI Research  +// +// See ATI-License.txt for license information +// + +varying vec4 ECposition;   // surface position in eye coordinates +varying vec4 ECballCenter; // ball center in eye coordinates + +uniform vec4  LightDir;     // light direction, should be normalized +uniform vec4  HVector;      // reflection vector for infinite light source +uniform vec4  SpecularColor; +uniform vec4  Red, Yellow, Blue; + +uniform vec4  HalfSpace0;   // half-spaces used to define star pattern +uniform vec4  HalfSpace1; +uniform vec4  HalfSpace2; +uniform vec4  HalfSpace3; +uniform vec4  HalfSpace4; + +uniform float InOrOutInit;  // = -3 +uniform float StripeWidth;  // = 0.3 +uniform float FWidth;       // = 0.005 + +void main() +{ +    vec4  normal;              // Analytically computed normal +    vec4  p;                   // Point in shader space +    vec4  surfColor;           // Computed color of the surface +    float intensity;           // Computed light intensity +    vec4  distance;            // Computed distance values +    float inorout;             // Counter for computing star pattern + +    p.xyz = normalize(ECposition.xyz - ECballCenter.xyz);    // Calculate p +    p.w   = 1.0; + +    inorout = InOrOutInit;     // initialize inorout to -3 + +    distance[0] = dot(p, HalfSpace0); +    distance[1] = dot(p, HalfSpace1); +    distance[2] = dot(p, HalfSpace2); +    distance[3] = dot(p, HalfSpace3); + +    distance = smoothstep(-FWidth, FWidth, distance); +    inorout += dot(distance, vec4(1.0)); + +    distance.x = dot(p, HalfSpace4); +    distance.y = StripeWidth - abs(p.z); +    distance = smoothstep(-FWidth, FWidth, distance); +    inorout += distance.x; + +    inorout = clamp(inorout, 0.0, 1.0); + +    surfColor = mix(Yellow, Red, inorout); +    surfColor = mix(surfColor, Blue, distance.y); + +    // normal = point on surface for sphere at (0,0,0) +    normal = p; + +    // Per fragment diffuse lighting +    intensity  = 0.2; // ambient +    intensity += 0.8 * clamp(dot(LightDir, normal), 0.0, 1.0); +    surfColor *= intensity; + +    // Per fragment specular lighting +    intensity  = clamp(dot(HVector, normal), 0.0, 1.0); +    intensity  = pow(intensity, SpecularColor.a); +    surfColor += SpecularColor * intensity; + +    gl_FragColor = surfColor; +} diff --git a/progs/glsl/CH11-toyball.vert.txt b/progs/glsl/CH11-toyball.vert.txt new file mode 100644 index 0000000000..b7da3ac839 --- /dev/null +++ b/progs/glsl/CH11-toyball.vert.txt @@ -0,0 +1,24 @@ +// +// Fragment shader for procedurally generated toy ball +// +// Author: Bill Licea-Kane +// +// Copyright (c) 2002-2003 ATI Research  +// +// See ATI-License.txt for license information +// + +varying vec4 ECposition;   // surface position in eye coordinates +varying vec4 ECballCenter; // ball center in eye coordinates +uniform vec4 BallCenter;   // ball center in modelling coordinates + +void main() +{  +//orig:    ECposition   = gl_ModelViewMatrix * gl_Vertex; + +    ECposition = gl_TextureMatrix[0] * gl_Vertex; +    ECposition = gl_ModelViewMatrix * ECposition; + +    ECballCenter = gl_ModelViewMatrix * BallCenter; +    gl_Position  = ftransform(); +} diff --git a/progs/glsl/CH18-mandel.frag.txt b/progs/glsl/CH18-mandel.frag.txt new file mode 100644 index 0000000000..a472d81252 --- /dev/null +++ b/progs/glsl/CH18-mandel.frag.txt @@ -0,0 +1,55 @@ +// +// Fragment shader for drawing the Mandelbrot set +// +// Authors: Dave Baldwin, Steve Koren, Randi Rost +//          based on a shader by Michael Rivero +// +// Copyright (c) 2002-2005: 3Dlabs, Inc. +// +// See 3Dlabs-License.txt for license information +// + +varying vec3  Position; +varying float LightIntensity; + +uniform float MaxIterations; +uniform float Zoom; +uniform float Xcenter; +uniform float Ycenter; +uniform vec3  InnerColor; +uniform vec3  OuterColor1; +uniform vec3  OuterColor2; + +void main() +{ +    float   real  = Position.x * Zoom + Xcenter; +    float   imag  = Position.y * Zoom + Ycenter; +    float   Creal = real;   // Change this line... +    float   Cimag = imag;   // ...and this one to get a Julia set + +    float r2 = 0.0; +    float iter; + +//    for (iter = 0.0; iter < MaxIterations && r2 < 4.0; ++iter) +    for (iter = 0.0; iter < 12 && r2 < 4.0; ++iter) +    { +        float tempreal = real; + +        real = (tempreal * tempreal) - (imag * imag) + Creal; +        imag = 2.0 * tempreal * imag + Cimag; +        r2   = (real * real) + (imag * imag); +    } + +    // Base the color on the number of iterations + +    vec3 color; + +    if (r2 < 4.0) +        color = InnerColor; +    else +        color = mix(OuterColor1, OuterColor2, fract(iter * 0.05)); + +    color *= LightIntensity; + +    gl_FragColor = vec4(color, 1.0); +} diff --git a/progs/glsl/CH18-mandel.vert.txt b/progs/glsl/CH18-mandel.vert.txt new file mode 100644 index 0000000000..c4ca66405d --- /dev/null +++ b/progs/glsl/CH18-mandel.vert.txt @@ -0,0 +1,35 @@ +// +// Vertex shader for drawing the Mandelbrot set +// +// Authors: Dave Baldwin, Steve Koren, Randi Rost +//          based on a shader by Michael Rivero +// +// Copyright (c) 2002-2005: 3Dlabs, Inc. +// +// See 3Dlabs-License.txt for license information +// + +uniform vec3 LightPosition; +uniform float SpecularContribution; +uniform float DiffuseContribution; +uniform float Shininess; + +varying float LightIntensity; +varying vec3  Position; + +void main() +{ +    vec3 ecPosition = vec3(gl_ModelViewMatrix * gl_Vertex); +    vec3 tnorm      = normalize(gl_NormalMatrix * gl_Normal); +    vec3 lightVec   = normalize(LightPosition - ecPosition); +    vec3 reflectVec = reflect(-lightVec, tnorm); +    vec3 viewVec    = normalize(-ecPosition); +    float spec      = max(dot(reflectVec, viewVec), 0.0); +    spec            = pow(spec, Shininess); +    LightIntensity  = DiffuseContribution *  +                          max(dot(lightVec, tnorm), 0.0) + +                          SpecularContribution * spec; +    Position        = vec3(gl_MultiTexCoord0 - 0.5) * 5.0; +    gl_Position     = ftransform(); + +}
\ No newline at end of file diff --git a/progs/glsl/Makefile b/progs/glsl/Makefile new file mode 100644 index 0000000000..e08d4102c8 --- /dev/null +++ b/progs/glsl/Makefile @@ -0,0 +1,74 @@ +# progs/demos/Makefile + +TOP = ../.. +include $(TOP)/configs/current + +INCDIR = $(TOP)/include + +OSMESA_LIBS = -L$(TOP)/$(LIB_DIR) -lglut -lOSMesa -lGLU -lGL $(APP_LIB_DEPS) + +OSMESA16_LIBS = -L$(TOP)/$(LIB_DIR) -lglut -lOSMesa16 -lGLU -lGL $(APP_LIB_DEPS) + +OSMESA32_LIBS = -L$(TOP)/$(LIB_DIR) -lglut -lOSMesa32 -lGLU -lGL $(APP_LIB_DEPS) + +LIB_DEP = $(TOP)/$(LIB_DIR)/$(GL_LIB_NAME) $(TOP)/$(LIB_DIR)/$(GLU_LIB_NAME) $(TOP)/$(LIB_DIR)/$(GLUT_LIB_NAME) + +PROGS = \ +	brick \ +	bump \ +	mandelbrot \ +	noise \ +	toyball \ +	texdemo1 + + +##### RULES ##### + +.SUFFIXES: +.SUFFIXES: .c + + +# make executable from .c file: +.c: $(LIB_DEP) +	$(CC) -I$(INCDIR) $(CFLAGS) $< $(APP_LIB_DEPS) -o $@ + + +##### TARGETS ##### + +default: $(PROGS) + + + +##### Extra dependencies + +extfuncs.h:  $(TOP)/progs/util/extfuncs.h +	cp $< . + +readtex.c: $(TOP)/progs/util/readtex.c +	cp $< . + +readtex.h: $(TOP)/progs/util/readtex.h +	cp $< . + +readtex.o: readtex.c readtex.h +	$(CC) -c -I$(INCDIR) $(CFLAGS) readtex.c + +brick.c: extfuncs.h + +bump.c: extfuncs.h + +mandelbrot.c: extfuncs.h + +toyball.c: extfuncs.h + +texdemo1: texdemo1.o readtex.o +	$(CC) -I$(INCDIR) $(CFLAGS) texdemo1.o readtex.o $(APP_LIB_DEPS) -o $@ + +texdemo1.o: texdemo1.c readtex.h extfuncs.h +	$(CC) -c -I$(INCDIR) $(CFLAGS) texdemo1.c + + +clean: +	-rm -f $(PROGS) +	-rm -f *.o *~ +	-rm -f extfuncs.h diff --git a/progs/glsl/brick.c b/progs/glsl/brick.c new file mode 100644 index 0000000000..522698b5d4 --- /dev/null +++ b/progs/glsl/brick.c @@ -0,0 +1,311 @@ +/** + * "Brick" shader demo.  Uses the example shaders from chapter 6 of + * the OpenGL Shading Language "orange" book. + * 10 Jan 2007 + */ + +#include <assert.h> +#include <string.h> +#include <stdio.h> +#include <stdlib.h> +#include <math.h> +#include <GL/gl.h> +#include <GL/glut.h> +#include <GL/glext.h> +#include "extfuncs.h" + + +static char *FragProgFile = "CH06-brick.frag.txt"; +static char *VertProgFile = "CH06-brick.vert.txt"; + +/* program/shader objects */ +static GLuint fragShader; +static GLuint vertShader; +static GLuint program; + + +struct uniform_info { +   const char *name; +   GLuint size; +   GLint location; +   GLfloat value[4]; +}; + +static struct uniform_info Uniforms[] = { +   /* vert */ +   { "LightPosition",     3, -1, { 0.1, 0.1, 9.0, 0} }, +   /* frag */ +   { "BrickColor",        3, -1, { 0.8, 0.2, 0.2, 0 } }, +   { "MortarColor",       3, -1, { 0.6, 0.6, 0.6, 0 } }, +   { "BrickSize",         2, -1, { 1.0, 0.3, 0, 0 } }, +   { "BrickPct",          2, -1, { 0.9, 0.8, 0, 0 } }, +   { NULL, 0, 0, { 0, 0, 0, 0 } } +}; + +static GLint win = 0; + + +static GLfloat xRot = 0.0f, yRot = 0.0f, zRot = 0.0f; + + + + +static void +Redisplay(void) +{ +   glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); +    +   glPushMatrix(); +   glRotatef(xRot, 1.0f, 0.0f, 0.0f); +   glRotatef(yRot, 0.0f, 1.0f, 0.0f); +   glRotatef(zRot, 0.0f, 0.0f, 1.0f); + +   glBegin(GL_POLYGON); +   glTexCoord2f(0, 0);   glVertex2f(-2, -2); +   glTexCoord2f(1, 0);   glVertex2f( 2, -2); +   glTexCoord2f(1, 1);   glVertex2f( 2,  2); +   glTexCoord2f(0, 1);   glVertex2f(-2,  2); +   glEnd(); + +   glPopMatrix(); + +   glutSwapBuffers(); +} + + +static void +Reshape(int width, int height) +{ +   glViewport(0, 0, width, height); +   glMatrixMode(GL_PROJECTION); +   glLoadIdentity(); +   glFrustum(-1.0, 1.0, -1.0, 1.0, 5.0, 25.0); +   glMatrixMode(GL_MODELVIEW); +   glLoadIdentity(); +   glTranslatef(0.0f, 0.0f, -15.0f); +} + + +static void +CleanUp(void) +{ +   glDeleteShader_func(fragShader); +   glDeleteShader_func(vertShader); +   glDeleteProgram_func(program); +   glutDestroyWindow(win); +} + + +static void +Key(unsigned char key, int x, int y) +{ +  (void) x; +  (void) y; + +   switch(key) { +   case 'z': +      zRot -= 1.0; +      break; +   case 'Z': +      zRot += 1.0; +      break; +   case 27: +      CleanUp(); +      exit(0); +      break; +   } +   glutPostRedisplay(); +} + + +static void +SpecialKey(int key, int x, int y) +{ +   const GLfloat step = 3.0f; + +  (void) x; +  (void) y; + +   switch(key) { +   case GLUT_KEY_UP: +      xRot -= step; +      break; +   case GLUT_KEY_DOWN: +      xRot += step; +      break; +   case GLUT_KEY_LEFT: +      yRot -= step; +      break; +   case GLUT_KEY_RIGHT: +      yRot += step; +      break; +   } +   glutPostRedisplay(); +} + + + +static void +LoadAndCompileShader(GLuint shader, const char *text) +{ +   GLint stat; + +   glShaderSource_func(shader, 1, (const GLchar **) &text, NULL); + +   glCompileShader_func(shader); + +   glGetShaderiv_func(shader, GL_COMPILE_STATUS, &stat); +   if (!stat) { +      GLchar log[1000]; +      GLsizei len; +      glGetShaderInfoLog_func(shader, 1000, &len, log); +      fprintf(stderr, "brick: problem compiling shader: %s\n", log); +      exit(1); +   } +   else { +      printf("Shader compiled OK\n"); +   } +} + + +/** + * Read a shader from a file. + */ +static void +ReadShader(GLuint shader, const char *filename) +{ +   const int max = 100*1000; +   int n; +   char *buffer = (char*) malloc(max); +   FILE *f = fopen(filename, "r"); +   if (!f) { +      fprintf(stderr, "brick: Unable to open shader file %s\n", filename); +      exit(1); +   } + +   n = fread(buffer, 1, max, f); +   printf("brick: read %d bytes from shader file %s\n", n, filename); +   if (n > 0) { +      buffer[n] = 0; +      LoadAndCompileShader(shader, buffer); +   } + +   fclose(f); +   free(buffer); +} + + +static void +CheckLink(GLuint prog) +{ +   GLint stat; +   glGetProgramiv_func(prog, GL_LINK_STATUS, &stat); +   if (!stat) { +      GLchar log[1000]; +      GLsizei len; +      glGetProgramInfoLog_func(prog, 1000, &len, log); +      fprintf(stderr, "Linker error:\n%s\n", log); +   } +   else { +      fprintf(stderr, "Link success!\n"); +   } +} + + +static void +Init(void) +{ +   const char *version; +   GLint i; + +   version = (const char *) glGetString(GL_VERSION); +   if (version[0] != '2' || version[1] != '.') { +      printf("Warning: this program expects OpenGL 2.0\n"); +      /*exit(1);*/ +   } + +   GetExtensionFuncs(); + +   vertShader = glCreateShader_func(GL_VERTEX_SHADER); +   ReadShader(vertShader, VertProgFile); + +   fragShader = glCreateShader_func(GL_FRAGMENT_SHADER); +   ReadShader(fragShader, FragProgFile); + +   program = glCreateProgram_func(); +   glAttachShader_func(program, fragShader); +   glAttachShader_func(program, vertShader); +   glLinkProgram_func(program); +   CheckLink(program); +   glUseProgram_func(program); + +   for (i = 0; Uniforms[i].name; i++) { +      Uniforms[i].location +         = glGetUniformLocation_func(program, Uniforms[i].name); +      printf("Uniform %s location: %d\n", Uniforms[i].name, +             Uniforms[i].location); +      switch (Uniforms[i].size) { +      case 1: +         glUniform1fv_func(Uniforms[i].location, 1, Uniforms[i].value); +         break; +      case 2: +         glUniform2fv_func(Uniforms[i].location, 1, Uniforms[i].value); +         break; +      case 3: +         glUniform3fv_func(Uniforms[i].location, 1, Uniforms[i].value); +         break; +      case 4: +         glUniform4fv_func(Uniforms[i].location, 1, Uniforms[i].value); +         break; +      default: +         abort(); +      } +   } + +   assert(glGetError() == 0); + +   glClearColor(0.4f, 0.4f, 0.8f, 0.0f); + +   printf("GL_RENDERER = %s\n",(const char *) glGetString(GL_RENDERER)); + +   assert(glIsProgram_func(program)); +   assert(glIsShader_func(fragShader)); +   assert(glIsShader_func(vertShader)); + +   glColor3f(1, 0, 0); +} + + +static void +ParseOptions(int argc, char *argv[]) +{ +   int i; +   for (i = 1; i < argc; i++) { +      if (strcmp(argv[i], "-fs") == 0) { +         FragProgFile = argv[i+1]; +      } +      else if (strcmp(argv[i], "-vs") == 0) { +         VertProgFile = argv[i+1]; +      } +   } +} + + +int +main(int argc, char *argv[]) +{ +   glutInit(&argc, argv); +   glutInitWindowPosition( 0, 0); +   glutInitWindowSize(400, 400); +   glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH); +   win = glutCreateWindow(argv[0]); +   glutReshapeFunc(Reshape); +   glutKeyboardFunc(Key); +   glutSpecialFunc(SpecialKey); +   glutDisplayFunc(Redisplay); +   ParseOptions(argc, argv); +   Init(); +   glutMainLoop(); +   return 0; +} + diff --git a/progs/glsl/bump.c b/progs/glsl/bump.c new file mode 100644 index 0000000000..a6846acf7e --- /dev/null +++ b/progs/glsl/bump.c @@ -0,0 +1,411 @@ +/** + * Procedural Bump Mapping demo.  Uses the example shaders from + * chapter 11 of the OpenGL Shading Language "orange" book. + * 16 Jan 2007 + */ + +#include <assert.h> +#include <string.h> +#include <stdio.h> +#include <stdlib.h> +#include <math.h> +#include <GL/glut.h> +#include <GL/glu.h> +#include <GL/glext.h> +#include "extfuncs.h" + + +static char *FragProgFile = "CH11-bumpmap.frag.txt"; +static char *VertProgFile = "CH11-bumpmap.vert.txt"; + +/* program/shader objects */ +static GLuint fragShader; +static GLuint vertShader; +static GLuint program; + + +struct uniform_info { +   const char *name; +   GLuint size; +   GLint location; +   GLfloat value[4]; +}; + +static struct uniform_info Uniforms[] = { +   { "LightPosition",       3, -1, { 0.57737, 0.57735, 0.57735, 0.0 } }, +   { "SurfaceColor",        3, -1, { 0.8, 0.8, 0.2, 0 } }, +   { "BumpDensity",         1, -1, { 10.0, 0, 0, 0 } }, +   { "BumpSize",            1, -1, { 0.125, 0, 0, 0 } }, +   { "SpecularFactor",      1, -1, { 0.5, 0, 0, 0 } }, +   { NULL, 0, 0, { 0, 0, 0, 0 } } +}; + +static GLint win = 0; + +static GLfloat xRot = 20.0f, yRot = 0.0f, zRot = 0.0f; + +static GLuint tangentAttrib; + +static GLboolean Anim = GL_FALSE; + + +static void +CheckError(int line) +{ +   GLenum err = glGetError(); +   if (err) { +      printf("GL Error %s (0x%x) at line %d\n", +             gluErrorString(err), (int) err, line); +   } +} + +/* + * Draw a square, specifying normal and tangent vectors. + */ +static void +Square(GLfloat size) +{ +   glNormal3f(0, 0, 1); +   glVertexAttrib3f_func(tangentAttrib, 1, 0, 0); +   glBegin(GL_POLYGON); +   glTexCoord2f(0, 0);  glVertex2f(-size, -size); +   glTexCoord2f(1, 0);  glVertex2f( size, -size); +   glTexCoord2f(1, 1);  glVertex2f( size,  size); +   glTexCoord2f(0, 1);  glVertex2f(-size,  size); +   glEnd(); +} + + +static void +Cube(GLfloat size) +{ +   /* +X */ +   glPushMatrix(); +   glRotatef(90, 0, 1, 0); +   glTranslatef(0, 0, size); +   Square(size); +   glPopMatrix(); + +   /* -X */ +   glPushMatrix(); +   glRotatef(-90, 0, 1, 0); +   glTranslatef(0, 0, size); +   Square(size); +   glPopMatrix(); + +   /* +Y */ +   glPushMatrix(); +   glRotatef(90, 1, 0, 0); +   glTranslatef(0, 0, size); +   Square(size); +   glPopMatrix(); + +   /* -Y */ +   glPushMatrix(); +   glRotatef(-90, 1, 0, 0); +   glTranslatef(0, 0, size); +   Square(size); +   glPopMatrix(); + + +   /* +Z */ +   glPushMatrix(); +   glTranslatef(0, 0, size); +   Square(size); +   glPopMatrix(); + +   /* -Z */ +   glPushMatrix(); +   glRotatef(180, 0, 1, 0); +   glTranslatef(0, 0, size); +   Square(size); +   glPopMatrix(); + +} + + +static void +Idle(void) +{ +   GLint t = glutGet(GLUT_ELAPSED_TIME); +   yRot  = t * 0.05; +   glutPostRedisplay(); +} + + +static void +Redisplay(void) +{ +   glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); +    +   glPushMatrix(); +   glRotatef(xRot, 1.0f, 0.0f, 0.0f); +   glRotatef(yRot, 0.0f, 1.0f, 0.0f); +   glRotatef(zRot, 0.0f, 0.0f, 1.0f); + +   Cube(1.5); + +   glPopMatrix(); + +   glFinish(); +   glFlush(); + +   CheckError(__LINE__); + +   glutSwapBuffers(); +} + + +static void +Reshape(int width, int height) +{ +   glViewport(0, 0, width, height); +   glMatrixMode(GL_PROJECTION); +   glLoadIdentity(); +   glFrustum(-1.0, 1.0, -1.0, 1.0, 5.0, 25.0); +   glMatrixMode(GL_MODELVIEW); +   glLoadIdentity(); +   glTranslatef(0.0f, 0.0f, -15.0f); +} + + +static void +CleanUp(void) +{ +   glDeleteShader_func(fragShader); +   glDeleteShader_func(vertShader); +   glDeleteProgram_func(program); +   glutDestroyWindow(win); +} + + +static void +Key(unsigned char key, int x, int y) +{ +   const GLfloat step = 2.0; +  (void) x; +  (void) y; + +   switch(key) { +   case 'a': +      Anim = !Anim; +      glutIdleFunc(Anim ? Idle : NULL); +      break; +   case 'z': +      zRot += step; +      break; +   case 'Z': +      zRot -= step; +      break; +   case 27: +      CleanUp(); +      exit(0); +      break; +   } +   glutPostRedisplay(); +} + + +static void +SpecialKey(int key, int x, int y) +{ +   const GLfloat step = 2.0; + +  (void) x; +  (void) y; + +   switch(key) { +   case GLUT_KEY_UP: +      xRot += step; +      break; +   case GLUT_KEY_DOWN: +      xRot -= step; +      break; +   case GLUT_KEY_LEFT: +      yRot -= step; +      break; +   case GLUT_KEY_RIGHT: +      yRot += step; +      break; +   } +   glutPostRedisplay(); +} + + + +static void +LoadAndCompileShader(GLuint shader, const char *text) +{ +   GLint stat; + +   glShaderSource_func(shader, 1, (const GLchar **) &text, NULL); + +   glCompileShader_func(shader); + +   glGetShaderiv_func(shader, GL_COMPILE_STATUS, &stat); +   if (!stat) { +      GLchar log[1000]; +      GLsizei len; +      glGetShaderInfoLog_func(shader, 1000, &len, log); +      fprintf(stderr, "brick: problem compiling shader: %s\n", log); +      exit(1); +   } +   else { +      printf("Shader compiled OK\n"); +   } +} + + +/** + * Read a shader from a file. + */ +static void +ReadShader(GLuint shader, const char *filename) +{ +   const int max = 100*1000; +   int n; +   char *buffer = (char*) malloc(max); +   FILE *f = fopen(filename, "r"); +   if (!f) { +      fprintf(stderr, "brick: Unable to open shader file %s\n", filename); +      exit(1); +   } + +   n = fread(buffer, 1, max, f); +   printf("brick: read %d bytes from shader file %s\n", n, filename); +   if (n > 0) { +      buffer[n] = 0; +      LoadAndCompileShader(shader, buffer); +   } + +   fclose(f); +   free(buffer); +} + + +static void +CheckLink(GLuint prog) +{ +   GLint stat; +   glGetProgramiv_func(prog, GL_LINK_STATUS, &stat); +   if (!stat) { +      GLchar log[1000]; +      GLsizei len; +      glGetProgramInfoLog_func(prog, 1000, &len, log); +      fprintf(stderr, "Linker error:\n%s\n", log); +   } +   else { +      fprintf(stderr, "Link success!\n"); +   } +} + + +static void +Init(void) +{ +   const char *version; +   GLint i; + +   version = (const char *) glGetString(GL_VERSION); +   if (version[0] != '2' || version[1] != '.') { +      printf("Warning: this program expects OpenGL 2.0\n"); +      /*exit(1);*/ +   } +   printf("GL_RENDERER = %s\n",(const char *) glGetString(GL_RENDERER)); + +   GetExtensionFuncs(); + +   vertShader = glCreateShader_func(GL_VERTEX_SHADER); +   ReadShader(vertShader, VertProgFile); + +   fragShader = glCreateShader_func(GL_FRAGMENT_SHADER); +   ReadShader(fragShader, FragProgFile); + +   program = glCreateProgram_func(); +   glAttachShader_func(program, fragShader); +   glAttachShader_func(program, vertShader); +   glLinkProgram_func(program); +   CheckLink(program); +   glUseProgram_func(program); + +   assert(glIsProgram_func(program)); +   assert(glIsShader_func(fragShader)); +   assert(glIsShader_func(vertShader)); + +   assert(glGetError() == 0); + +   CheckError(__LINE__); + +   for (i = 0; Uniforms[i].name; i++) { +      Uniforms[i].location +         = glGetUniformLocation_func(program, Uniforms[i].name); +      printf("Uniform %s location: %d\n", Uniforms[i].name, +             Uniforms[i].location); +      switch (Uniforms[i].size) { +      case 1: +         glUniform1fv_func(Uniforms[i].location, 1, Uniforms[i].value); +         break; +      case 2: +         glUniform2fv_func(Uniforms[i].location, 1, Uniforms[i].value); +         break; +      case 3: +         glUniform3fv_func(Uniforms[i].location, 1, Uniforms[i].value); +         break; +      case 4: +         glUniform4fv_func(Uniforms[i].location, 1, Uniforms[i].value); +         break; +      default: +         abort(); +      } +   } + +   CheckError(__LINE__); + +   tangentAttrib = glGetAttribLocation_func(program, "Tangent"); +   printf("Tangent Attrib: %d\n", tangentAttrib); + +   assert(tangentAttrib >= 0); + +   CheckError(__LINE__); + +   glClearColor(0.4f, 0.4f, 0.8f, 0.0f); + +   glEnable(GL_DEPTH_TEST); + +   glColor3f(1, 0, 0); +} + + +static void +ParseOptions(int argc, char *argv[]) +{ +   int i; +   for (i = 1; i < argc; i++) { +      if (strcmp(argv[i], "-fs") == 0) { +         FragProgFile = argv[i+1]; +      } +      else if (strcmp(argv[i], "-vs") == 0) { +         VertProgFile = argv[i+1]; +      } +   } +} + + +int +main(int argc, char *argv[]) +{ +   glutInit(&argc, argv); +   glutInitWindowPosition( 0, 0); +   glutInitWindowSize(400, 400); +   glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH); +   win = glutCreateWindow(argv[0]); +   glutReshapeFunc(Reshape); +   glutKeyboardFunc(Key); +   glutSpecialFunc(SpecialKey); +   glutDisplayFunc(Redisplay); +   ParseOptions(argc, argv); +   Init(); +   glutMainLoop(); +   return 0; +} + diff --git a/progs/glsl/cubemap.frag.txt b/progs/glsl/cubemap.frag.txt new file mode 100644 index 0000000000..9c27648aaf --- /dev/null +++ b/progs/glsl/cubemap.frag.txt @@ -0,0 +1,18 @@ +// Fragment shader for cube-texture reflection mapping +// Brian Paul + + +uniform samplerCube cubeTex; +varying vec3 normal; +uniform vec3 lightPos; + +void main() +{ +   // simple diffuse, specular lighting: +   vec3 lp = normalize(lightPos); +   float dp = dot(lp, normalize(normal)); +   float spec = pow(dp, 5.0); + +   // final color: +   gl_FragColor = dp * textureCube(cubeTex, gl_TexCoord[0].xyz, 0.0) + spec; +} diff --git a/progs/glsl/mandelbrot.c b/progs/glsl/mandelbrot.c new file mode 100644 index 0000000000..7a2bad6dde --- /dev/null +++ b/progs/glsl/mandelbrot.c @@ -0,0 +1,328 @@ +/** + * "Mandelbrot" shader demo.  Uses the example shaders from + * chapter 15 (or 18) of the OpenGL Shading Language "orange" book. + * 15 Jan 2007 + */ + +#include <assert.h> +#include <string.h> +#include <stdio.h> +#include <stdlib.h> +#include <math.h> +#include <GL/gl.h> +#include <GL/glut.h> +#include <GL/glext.h> +#include "extfuncs.h" + + +static char *FragProgFile = "CH18-mandel.frag.txt"; +static char *VertProgFile = "CH18-mandel.vert.txt"; + +/* program/shader objects */ +static GLuint fragShader; +static GLuint vertShader; +static GLuint program; + + +struct uniform_info { +   const char *name; +   GLuint size; +   GLint location; +   GLfloat value[4]; +}; + +static struct uniform_info Uniforms[] = { +   /* vert */ +   { "LightPosition",        3, -1, { 0.1, 0.1, 9.0, 0} }, +   { "SpecularContribution", 1, -1, { 0.5, 0, 0, 0 } }, +   { "DiffuseContribution",  1, -1, { 0.5, 0, 0, 0 } }, +   { "Shininess",            1, -1, { 20.0, 0, 0, 0 } }, +   /* frag */ +   { "MaxIterations",        1, -1, { 12, 0, 0, 0 } }, +   { "Zoom",                 1, -1, { 0.125, 0, 0, 0 } }, +   { "Xcenter",              1, -1, { -1.5, 0, 0, 0 } }, +   { "Ycenter",              1, -1, { .005, 0, 0, 0 } }, +   { "InnerColor",           3, -1, { 1, 0, 0, 0 } }, +   { "OuterColor1",          3, -1, { 0, 1, 0, 0 } }, +   { "OuterColor2",          3, -1, { 0, 0, 1, 0 } }, +   { NULL, 0, 0, { 0, 0, 0, 0 } } +}; + +static GLint win = 0; + +static GLfloat xRot = 0.0f, yRot = 0.0f, zRot = 0.0f; + +static GLint uZoom, uXcenter, uYcenter; +static GLfloat zoom = 1.0, xCenter = -1.5, yCenter = 0.0; + + +static void +Redisplay(void) +{ +   glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); +    +   /* set interactive uniform parameters */ +   glUniform1fv_func(uZoom, 1, &zoom); +   glUniform1fv_func(uXcenter, 1, &xCenter); +   glUniform1fv_func(uYcenter, 1, &yCenter); + +   glPushMatrix(); +   glRotatef(xRot, 1.0f, 0.0f, 0.0f); +   glRotatef(yRot, 0.0f, 1.0f, 0.0f); +   glRotatef(zRot, 0.0f, 0.0f, 1.0f); + +   glBegin(GL_POLYGON); +   glTexCoord2f(0, 0);   glVertex2f(-1, -1); +   glTexCoord2f(1, 0);   glVertex2f( 1, -1); +   glTexCoord2f(1, 1);   glVertex2f( 1,  1); +   glTexCoord2f(0, 1);   glVertex2f(-1,  1); +   glEnd(); + +   glPopMatrix(); + +   glFinish(); +   glFlush(); +   glutSwapBuffers(); +} + + +static void +Reshape(int width, int height) +{ +   glViewport(0, 0, width, height); +   glMatrixMode(GL_PROJECTION); +   glLoadIdentity(); +   glFrustum(-1.0, 1.0, -1.0, 1.0, 5.0, 25.0); +   glMatrixMode(GL_MODELVIEW); +   glLoadIdentity(); +   glTranslatef(0.0f, 0.0f, -6.0f); +} + + +static void +CleanUp(void) +{ +   glDeleteShader_func(fragShader); +   glDeleteShader_func(vertShader); +   glDeleteProgram_func(program); +   glutDestroyWindow(win); +} + + +static void +Key(unsigned char key, int x, int y) +{ +  (void) x; +  (void) y; + +   switch(key) { +   case 'z': +      zoom *= 0.9; +      break; +   case 'Z': +      zoom /= 0.9; +      break; +   case 27: +      CleanUp(); +      exit(0); +      break; +   } +   glutPostRedisplay(); +} + + +static void +SpecialKey(int key, int x, int y) +{ +   const GLfloat step = 0.1 * zoom; + +  (void) x; +  (void) y; + +   switch(key) { +   case GLUT_KEY_UP: +      yCenter += step; +      break; +   case GLUT_KEY_DOWN: +      yCenter -= step; +      break; +   case GLUT_KEY_LEFT: +      xCenter -= step; +      break; +   case GLUT_KEY_RIGHT: +      xCenter += step; +      break; +   } +   glutPostRedisplay(); +} + + + +static void +LoadAndCompileShader(GLuint shader, const char *text) +{ +   GLint stat; + +   glShaderSource_func(shader, 1, (const GLchar **) &text, NULL); + +   glCompileShader_func(shader); + +   glGetShaderiv_func(shader, GL_COMPILE_STATUS, &stat); +   if (!stat) { +      GLchar log[1000]; +      GLsizei len; +      glGetShaderInfoLog_func(shader, 1000, &len, log); +      fprintf(stderr, "brick: problem compiling shader: %s\n", log); +      exit(1); +   } +   else { +      printf("Shader compiled OK\n"); +   } +} + + +/** + * Read a shader from a file. + */ +static void +ReadShader(GLuint shader, const char *filename) +{ +   const int max = 100*1000; +   int n; +   char *buffer = (char*) malloc(max); +   FILE *f = fopen(filename, "r"); +   if (!f) { +      fprintf(stderr, "brick: Unable to open shader file %s\n", filename); +      exit(1); +   } + +   n = fread(buffer, 1, max, f); +   printf("brick: read %d bytes from shader file %s\n", n, filename); +   if (n > 0) { +      buffer[n] = 0; +      LoadAndCompileShader(shader, buffer); +   } + +   fclose(f); +   free(buffer); +} + + +static void +CheckLink(GLuint prog) +{ +   GLint stat; +   glGetProgramiv_func(prog, GL_LINK_STATUS, &stat); +   if (!stat) { +      GLchar log[1000]; +      GLsizei len; +      glGetProgramInfoLog_func(prog, 1000, &len, log); +      fprintf(stderr, "Linker error:\n%s\n", log); +   } +   else { +      fprintf(stderr, "Link success!\n"); +   } +} + + +static void +Init(void) +{ +   const char *version; +   GLint i; + +   version = (const char *) glGetString(GL_VERSION); +   if (version[0] != '2' || version[1] != '.') { +      printf("Warning: this program expects OpenGL 2.0\n"); +      /*exit(1);*/ +   } + +   GetExtensionFuncs(); + +   vertShader = glCreateShader_func(GL_VERTEX_SHADER); +   ReadShader(vertShader, VertProgFile); + +   fragShader = glCreateShader_func(GL_FRAGMENT_SHADER); +   ReadShader(fragShader, FragProgFile); + +   program = glCreateProgram_func(); +   glAttachShader_func(program, fragShader); +   glAttachShader_func(program, vertShader); +   glLinkProgram_func(program); +   CheckLink(program); +   glUseProgram_func(program); + +   for (i = 0; Uniforms[i].name; i++) { +      Uniforms[i].location +         = glGetUniformLocation_func(program, Uniforms[i].name); +      printf("Uniform %s location: %d\n", Uniforms[i].name, +             Uniforms[i].location); +      switch (Uniforms[i].size) { +      case 1: +         glUniform1fv_func(Uniforms[i].location, 1, Uniforms[i].value); +         break; +      case 2: +         glUniform2fv_func(Uniforms[i].location, 1, Uniforms[i].value); +         break; +      case 3: +         glUniform3fv_func(Uniforms[i].location, 1, Uniforms[i].value); +         break; +      case 4: +         glUniform4fv_func(Uniforms[i].location, 1, Uniforms[i].value); +         break; +      default: +         abort(); +      } +   } + +   uZoom = glGetUniformLocation_func(program, "Zoom"); +   uXcenter = glGetUniformLocation_func(program, "Xcenter"); +   uYcenter = glGetUniformLocation_func(program, "Ycenter"); + +   assert(glGetError() == 0); + +   glClearColor(0.4f, 0.4f, 0.8f, 0.0f); + +   printf("GL_RENDERER = %s\n",(const char *) glGetString(GL_RENDERER)); + +   assert(glIsProgram_func(program)); +   assert(glIsShader_func(fragShader)); +   assert(glIsShader_func(vertShader)); + +   glColor3f(1, 0, 0); +} + + +static void +ParseOptions(int argc, char *argv[]) +{ +   int i; +   for (i = 1; i < argc; i++) { +      if (strcmp(argv[i], "-fs") == 0) { +         FragProgFile = argv[i+1]; +      } +      else if (strcmp(argv[i], "-vs") == 0) { +         VertProgFile = argv[i+1]; +      } +   } +} + + +int +main(int argc, char *argv[]) +{ +   glutInit(&argc, argv); +   glutInitWindowPosition( 0, 0); +   glutInitWindowSize(400, 400); +   glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH); +   win = glutCreateWindow(argv[0]); +   glutReshapeFunc(Reshape); +   glutKeyboardFunc(Key); +   glutSpecialFunc(SpecialKey); +   glutDisplayFunc(Redisplay); +   ParseOptions(argc, argv); +   Init(); +   glutMainLoop(); +   return 0; +} + diff --git a/progs/glsl/noise.c b/progs/glsl/noise.c new file mode 100644 index 0000000000..a26a805944 --- /dev/null +++ b/progs/glsl/noise.c @@ -0,0 +1,297 @@ +/** + * Test noise() functions. + * 28 Jan 2007 + */ + +#include <assert.h> +#include <string.h> +#include <stdio.h> +#include <stdlib.h> +#include <math.h> +#include <GL/gl.h> +#include <GL/glut.h> +#include <GL/glext.h> +#include "extfuncs.h" + + +static const char *VertShaderText = +   "void main() {\n" +   "   gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;\n" +   "   gl_TexCoord[0] = gl_MultiTexCoord0;\n" +   "}\n"; + +static const char *FragShaderText = +   "uniform vec4 Scale, Bias;\n" +   "uniform float Slice;\n" +   "void main()\n" +   "{\n" +   "   vec4 scale = vec4(5.0);\n" +   "   vec4 p;\n" +   "   p.xy = gl_TexCoord[0].xy;\n" +   "   p.z = Slice;\n" +   "   vec4 n = noise4(p * scale);\n" +   "   gl_FragColor = n * Scale + Bias;\n" +   "}\n"; + + +struct uniform_info { +   const char *name; +   GLuint size; +   GLint location; +   GLfloat value[4]; +}; + +static struct uniform_info Uniforms[] = { +   { "Scale",          4, -1, { 0.5, 0.4, 0.0, 0} }, +   { "Bias",           4, -1, { 0.5, 0.3, 0.0, 0} }, +   { "Slice",          1, -1, { 0.5, 0, 0, 0} }, +   { NULL, 0, 0, { 0, 0, 0, 0 } } +}; + +/* program/shader objects */ +static GLuint fragShader; +static GLuint vertShader; +static GLuint program; + +static GLint win = 0; +static GLfloat xRot = 0.0f, yRot = 0.0f, zRot = 0.0f; +static GLfloat Slice = 0.0; +static GLboolean Anim = GL_FALSE; + + +static void +Idle(void) +{ +   Slice += 0.01; +   glutPostRedisplay(); +} + + +static void +Redisplay(void) +{ +   glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); +    +   glUniform1fv_func(Uniforms[2].location, 1, &Slice); + +   glPushMatrix(); +   glRotatef(xRot, 1.0f, 0.0f, 0.0f); +   glRotatef(yRot, 0.0f, 1.0f, 0.0f); +   glRotatef(zRot, 0.0f, 0.0f, 1.0f); + +   glBegin(GL_POLYGON); +   glTexCoord2f(0, 0);   glVertex2f(-2, -2); +   glTexCoord2f(1, 0);   glVertex2f( 2, -2); +   glTexCoord2f(1, 1);   glVertex2f( 2,  2); +   glTexCoord2f(0, 1);   glVertex2f(-2,  2); +   glEnd(); + +   glPopMatrix(); + +   glutSwapBuffers(); +} + + +static void +Reshape(int width, int height) +{ +   glViewport(0, 0, width, height); +   glMatrixMode(GL_PROJECTION); +   glLoadIdentity(); +   glFrustum(-1.0, 1.0, -1.0, 1.0, 5.0, 25.0); +   glMatrixMode(GL_MODELVIEW); +   glLoadIdentity(); +   glTranslatef(0.0f, 0.0f, -15.0f); +} + + +static void +CleanUp(void) +{ +   glDeleteShader_func(fragShader); +   glDeleteShader_func(vertShader); +   glDeleteProgram_func(program); +   glutDestroyWindow(win); +} + + +static void +Key(unsigned char key, int x, int y) +{ +   const GLfloat step = 0.01; +  (void) x; +  (void) y; + +   switch(key) { +   case 'a': +      Anim = !Anim; +      glutIdleFunc(Anim ? Idle : NULL); +   case 's': +      Slice -= step; +      break; +   case 'S': +      Slice += step; +      break; +   case 'z': +      zRot -= 1.0; +      break; +   case 'Z': +      zRot += 1.0; +      break; +   case 27: +      CleanUp(); +      exit(0); +      break; +   } +   glutPostRedisplay(); +} + + +static void +SpecialKey(int key, int x, int y) +{ +   const GLfloat step = 3.0f; + +  (void) x; +  (void) y; + +   switch(key) { +   case GLUT_KEY_UP: +      xRot -= step; +      break; +   case GLUT_KEY_DOWN: +      xRot += step; +      break; +   case GLUT_KEY_LEFT: +      yRot -= step; +      break; +   case GLUT_KEY_RIGHT: +      yRot += step; +      break; +   } +   glutPostRedisplay(); +} + + + +static void +LoadAndCompileShader(GLuint shader, const char *text) +{ +   GLint stat; + +   glShaderSource_func(shader, 1, (const GLchar **) &text, NULL); + +   glCompileShader_func(shader); + +   glGetShaderiv_func(shader, GL_COMPILE_STATUS, &stat); +   if (!stat) { +      GLchar log[1000]; +      GLsizei len; +      glGetShaderInfoLog_func(shader, 1000, &len, log); +      fprintf(stderr, "brick: problem compiling shader: %s\n", log); +      exit(1); +   } +   else { +      printf("Shader compiled OK\n"); +   } +} + + +static void +CheckLink(GLuint prog) +{ +   GLint stat; +   glGetProgramiv_func(prog, GL_LINK_STATUS, &stat); +   if (!stat) { +      GLchar log[1000]; +      GLsizei len; +      glGetProgramInfoLog_func(prog, 1000, &len, log); +      fprintf(stderr, "Linker error:\n%s\n", log); +   } +   else { +      fprintf(stderr, "Link success!\n"); +   } +} + + +static void +Init(void) +{ +   const char *version; +   GLint i; + +   version = (const char *) glGetString(GL_VERSION); +   if (version[0] != '2' || version[1] != '.') { +      printf("Warning: this program expects OpenGL 2.0\n"); +      /*exit(1);*/ +   } + +   GetExtensionFuncs(); + +   vertShader = glCreateShader_func(GL_VERTEX_SHADER); +   LoadAndCompileShader(vertShader, VertShaderText); + +   fragShader = glCreateShader_func(GL_FRAGMENT_SHADER); +   LoadAndCompileShader(fragShader, FragShaderText); + +   program = glCreateProgram_func(); +   glAttachShader_func(program, fragShader); +   glAttachShader_func(program, vertShader); +   glLinkProgram_func(program); +   CheckLink(program); +   glUseProgram_func(program); + +   for (i = 0; Uniforms[i].name; i++) { +      Uniforms[i].location +         = glGetUniformLocation_func(program, Uniforms[i].name); +      printf("Uniform %s location: %d\n", Uniforms[i].name, +             Uniforms[i].location); +      switch (Uniforms[i].size) { +      case 1: +         glUniform1fv_func(Uniforms[i].location, 1, Uniforms[i].value); +         break; +      case 2: +         glUniform2fv_func(Uniforms[i].location, 1, Uniforms[i].value); +         break; +      case 3: +         glUniform3fv_func(Uniforms[i].location, 1, Uniforms[i].value); +         break; +      case 4: +         glUniform4fv_func(Uniforms[i].location, 1, Uniforms[i].value); +         break; +      default: +         abort(); +      } +   } + +   assert(glGetError() == 0); + +   glClearColor(0.4f, 0.4f, 0.8f, 0.0f); + +   printf("GL_RENDERER = %s\n",(const char *) glGetString(GL_RENDERER)); + +   assert(glIsProgram_func(program)); +   assert(glIsShader_func(fragShader)); +   assert(glIsShader_func(vertShader)); + +   glColor3f(1, 0, 0); +} + + +int +main(int argc, char *argv[]) +{ +   glutInit(&argc, argv); +   glutInitWindowPosition( 0, 0); +   glutInitWindowSize(400, 400); +   glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH); +   win = glutCreateWindow(argv[0]); +   glutReshapeFunc(Reshape); +   glutKeyboardFunc(Key); +   glutSpecialFunc(SpecialKey); +   glutDisplayFunc(Redisplay); +   Init(); +   glutMainLoop(); +   return 0; +} + diff --git a/progs/glsl/reflect.vert.txt b/progs/glsl/reflect.vert.txt new file mode 100644 index 0000000000..402be38bf7 --- /dev/null +++ b/progs/glsl/reflect.vert.txt @@ -0,0 +1,19 @@ +// Vertex shader for cube-texture reflection mapping +// Brian Paul + + +varying vec3 normal; + +void main()  +{ +   vec3 n = gl_NormalMatrix * gl_Normal; +   vec3 u = normalize(vec3(gl_ModelViewMatrix * gl_Vertex)); +   float two_n_dot_u = 2.0 * dot(n, u); +   vec4 f; +   f.xyz = u - n * two_n_dot_u; + +   // outputs +   normal = n; +   gl_TexCoord[0] = gl_TextureMatrix[0] * f; +   gl_Position = ftransform(); +} diff --git a/progs/glsl/shadowtex.frag.txt b/progs/glsl/shadowtex.frag.txt new file mode 100644 index 0000000000..a6a80da47f --- /dev/null +++ b/progs/glsl/shadowtex.frag.txt @@ -0,0 +1,21 @@ +// Fragment shader for 2D texture with shadow attenuation +// Brian Paul + + +uniform sampler2D tex2d; +uniform vec3 lightPos; + +void main() +{ +   // XXX should compute this from lightPos +   vec2 shadowCenter = vec2(-0.25, -0.25); + +   // d = distance from center +   float d = distance(gl_TexCoord[0].xy, shadowCenter); + +   // attenuate and clamp +   d = clamp(d * d * d, 0.0, 2.0); + +   // modulate texture by d for shadow effect +   gl_FragColor = d * texture2D(tex2d, gl_TexCoord[0].xy, 0.0); +} diff --git a/progs/glsl/simple.vert.txt b/progs/glsl/simple.vert.txt new file mode 100644 index 0000000000..a0abe0dc0b --- /dev/null +++ b/progs/glsl/simple.vert.txt @@ -0,0 +1,9 @@ +// Simple vertex shader +// Brian Paul + + +void main()  +{ +   gl_TexCoord[0] = gl_MultiTexCoord0; +   gl_Position = ftransform(); +} diff --git a/progs/glsl/texdemo1.c b/progs/glsl/texdemo1.c new file mode 100644 index 0000000000..d29ecf452b --- /dev/null +++ b/progs/glsl/texdemo1.c @@ -0,0 +1,570 @@ +/** + * Test texturing with GL shading language. + * + * Copyright (C) 2007  Brian Paul   All Rights Reserved. + *  + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + *  + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + *  + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL + * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + + + +#include <assert.h> +#include <math.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include "GL/glut.h" +#include "readtex.h" +#include "extfuncs.h" + +static const char *Demo = "texdemo1"; + +static const char *ReflectVertFile = "reflect.vert.txt"; +static const char *CubeFragFile = "cubemap.frag.txt"; + +static const char *SimpleVertFile = "simple.vert.txt"; +static const char *SimpleTexFragFile = "shadowtex.frag.txt"; + +static const char *GroundImage = "../images/tile.rgb"; + +static GLuint Program1, Program2; + +static GLfloat TexXrot = 0, TexYrot = 0; +static GLfloat Xrot = 20.0, Yrot = 20.0, Zrot = 0.0; +static GLfloat EyeDist = 10; +static GLboolean Anim = GL_TRUE; + + +struct uniform_info { +   const char *name; +   GLuint size; +   GLint location; +   GLenum type;  /**< GL_FLOAT or GL_INT */ +   GLfloat value[4]; +}; + +static struct uniform_info ReflectUniforms[] = { +   { "cubeTex",  1, -1, GL_INT, { 0, 0, 0, 0 } }, +   { "lightPos", 3, -1, GL_FLOAT, { 10, 10, 20, 0 } }, +   { NULL, 0, 0, 0, { 0, 0, 0, 0 } } +}; + +static struct uniform_info SimpleUniforms[] = { +   { "tex2d",    1, -1, GL_INT,   { 1, 0, 0, 0 } }, +   { "lightPos", 3, -1, GL_FLOAT, { 10, 10, 20, 0 } }, +   { NULL, 0, 0, 0, { 0, 0, 0, 0 } } +}; + + +static void +CheckError(int line) +{ +   GLenum err = glGetError(); +   if (err) { +      printf("GL Error %s (0x%x) at line %d\n", +             gluErrorString(err), (int) err, line); +   } +} + + +static void +DrawGround(GLfloat size) +{ +   glPushMatrix(); +   glRotatef(90, 1, 0, 0); +   glNormal3f(0, 0, 1); +   glBegin(GL_POLYGON); +   glTexCoord2f(-2, -2);  glVertex2f(-size, -size); +   glTexCoord2f( 2, -2);  glVertex2f( size, -size); +   glTexCoord2f( 2,  2);  glVertex2f( size,  size); +   glTexCoord2f(-2,  2);  glVertex2f(-size,  size); +   glEnd(); +   glPopMatrix(); +} + + +static void +draw(void) +{ +   glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + +   glEnable(GL_TEXTURE_2D); + +   glPushMatrix(); /* modelview matrix */ +      glTranslatef(0.0, 0.0, -EyeDist); +      glRotatef(Xrot, 1, 0, 0); +      glRotatef(Yrot, 0, 1, 0); +      glRotatef(Zrot, 0, 0, 1); + +      /* sphere w/ reflection map */ +      glPushMatrix(); +         glTranslatef(0, 1, 0); +         glUseProgram_func(Program1); + +         /* setup texture matrix */ +         glActiveTexture(GL_TEXTURE0); +         glMatrixMode(GL_TEXTURE); +         glLoadIdentity(); +         glRotatef(-TexYrot, 0, 1, 0); +         glRotatef(-TexXrot, 1, 0, 0); + +         glEnable(GL_TEXTURE_GEN_S); +         glEnable(GL_TEXTURE_GEN_T); +         glEnable(GL_TEXTURE_GEN_R); +         glutSolidSphere(2.0, 20, 20); + +         glLoadIdentity(); /* texture matrix */ +         glMatrixMode(GL_MODELVIEW); +      glPopMatrix(); + +      /* ground */ +      glUseProgram_func(Program2); +      glTranslatef(0, -1.0, 0); +      DrawGround(5); + +   glPopMatrix(); + +   glutSwapBuffers(); +} + + +static void +idle(void) +{ +   GLfloat t = 0.05 * glutGet(GLUT_ELAPSED_TIME); +   TexYrot = t; +   glutPostRedisplay(); +} + + +static void +key(unsigned char k, int x, int y) +{ +   (void) x; +   (void) y; +   switch (k) { +   case ' ': +   case 'a': +      Anim = !Anim; +      if (Anim) +         glutIdleFunc(idle); +      else +         glutIdleFunc(NULL); +      break; +   case 'z': +      EyeDist -= 0.5; +      if (EyeDist < 6.0) +         EyeDist = 6.0; +      break; +   case 'Z': +      EyeDist += 0.5; +      if (EyeDist > 90.0) +         EyeDist = 90; +      break; +   case 27: +      exit(0); +   } +   glutPostRedisplay(); +} + + +static void +specialkey(int key, int x, int y) +{ +   GLfloat step = 2.0; +   (void) x; +   (void) y; +   switch (key) { +   case GLUT_KEY_UP: +      Xrot += step; +      break; +   case GLUT_KEY_DOWN: +      Xrot -= step; +      break; +   case GLUT_KEY_LEFT: +      Yrot -= step; +      break; +   case GLUT_KEY_RIGHT: +      Yrot += step; +      break; +   } +   glutPostRedisplay(); +} + + +/* new window size or exposure */ +static void +Reshape(int width, int height) +{ +   GLfloat ar = (float) width / (float) height; +   glViewport(0, 0, (GLint)width, (GLint)height); +   glMatrixMode(GL_PROJECTION); +   glLoadIdentity(); +   glFrustum(-2.0*ar, 2.0*ar, -2.0, 2.0, 4.0, 100.0); +   glMatrixMode(GL_MODELVIEW); +   glLoadIdentity(); +} + + +static void +InitCheckers(void) +{ +#define CUBE_TEX_SIZE 64 +   GLubyte image[CUBE_TEX_SIZE][CUBE_TEX_SIZE][3]; +   static const GLubyte colors[6][3] = { +      { 255,   0,   0 },	/* face 0 - red */ +      {   0, 255, 255 },	/* face 1 - cyan */ +      {   0, 255,   0 },	/* face 2 - green */ +      { 255,   0, 255 },	/* face 3 - purple */ +      {   0,   0, 255 },	/* face 4 - blue */ +      { 255, 255,   0 }		/* face 5 - yellow */ +   }; +   static const GLenum targets[6] = { +      GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB, +      GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB, +      GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB, +      GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB, +      GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB, +      GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB +   }; + +   GLint i, j, f; + +   glPixelStorei(GL_UNPACK_ALIGNMENT, 1); + +   /* make colored checkerboard cube faces */ +   for (f = 0; f < 6; f++) { +      for (i = 0; i < CUBE_TEX_SIZE; i++) { +         for (j = 0; j < CUBE_TEX_SIZE; j++) { +            if ((i/4 + j/4) & 1) { +               image[i][j][0] = colors[f][0]; +               image[i][j][1] = colors[f][1]; +               image[i][j][2] = colors[f][2]; +            } +            else { +               image[i][j][0] = 255; +               image[i][j][1] = 255; +               image[i][j][2] = 255; +            } +         } +      } + +      glTexImage2D(targets[f], 0, GL_RGB, CUBE_TEX_SIZE, CUBE_TEX_SIZE, 0, +                   GL_RGB, GL_UNSIGNED_BYTE, image); +   } +} + + +static void +LoadFace(GLenum target, const char *filename, +         GLboolean flipTB, GLboolean flipLR) +{ +   GLint w, h; +   GLenum format; +   GLubyte *img = LoadRGBImage(filename, &w, &h, &format); +   if (!img) { +      printf("Error: couldn't load texture image %s\n", filename); +      exit(1); +   } +   assert(format == GL_RGB); + +   /* <sigh> the way the texture cube mapping works, we have to flip +    * images to make things look right. +    */ +   if (flipTB) { +      const int stride = 3 * w; +      GLubyte temp[3*1024]; +      int i; +      for (i = 0; i < h / 2; i++) { +         memcpy(temp, img + i * stride, stride); +         memcpy(img + i * stride, img + (h - i - 1) * stride, stride); +         memcpy(img + (h - i - 1) * stride, temp, stride); +      } +   } +   if (flipLR) { +      const int stride = 3 * w; +      GLubyte temp[3]; +      GLubyte *row; +      int i, j; +      for (i = 0; i < h; i++) { +         row = img + i * stride; +         for (j = 0; j < w / 2; j++) { +            int k = w - j - 1; +            temp[0] = row[j*3+0]; +            temp[1] = row[j*3+1]; +            temp[2] = row[j*3+2]; +            row[j*3+0] = row[k*3+0]; +            row[j*3+1] = row[k*3+1]; +            row[j*3+2] = row[k*3+2]; +            row[k*3+0] = temp[0]; +            row[k*3+1] = temp[1]; +            row[k*3+2] = temp[2]; +         } +      } +   } + +   gluBuild2DMipmaps(target, GL_RGB, w, h, format, GL_UNSIGNED_BYTE, img); +   free(img); +} + + +static void +LoadEnvmaps(void) +{ +   LoadFace(GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB, "right.rgb", GL_TRUE, GL_FALSE); +   LoadFace(GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB, "left.rgb", GL_TRUE, GL_FALSE); +   LoadFace(GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB, "top.rgb", GL_FALSE, GL_TRUE); +   LoadFace(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB, "bottom.rgb", GL_FALSE, GL_TRUE); +   LoadFace(GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB, "front.rgb", GL_TRUE, GL_FALSE); +   LoadFace(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB, "back.rgb", GL_TRUE, GL_FALSE); +} + + +static void +InitTextures(GLboolean useImageFiles) +{ +   GLenum filter; + +   /* +    * Env map +    */ +   glActiveTexture(GL_TEXTURE0); +   glBindTexture(GL_TEXTURE_CUBE_MAP, 1); +   if (useImageFiles) { +      LoadEnvmaps(); +      filter = GL_LINEAR; +   } +   else { +      InitCheckers(); +      filter = GL_NEAREST; +   } +   glTexParameteri(GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_MIN_FILTER, filter); +   glTexParameteri(GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_MAG_FILTER, filter); +   glTexParameteri(GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); +   glTexParameteri(GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + +   /* +    * Ground texture +    */ +   { +      GLint imgWidth, imgHeight; +      GLenum imgFormat; +      GLubyte *image = NULL; + +      image = LoadRGBImage(GroundImage, &imgWidth, &imgHeight, &imgFormat); +      if (!image) { +         printf("Couldn't read %s\n", GroundImage); +         exit(0); +      } + +      glActiveTexture(GL_TEXTURE1); +      glBindTexture(GL_TEXTURE_2D, 2); +      gluBuild2DMipmaps(GL_TEXTURE_2D, 3, imgWidth, imgHeight, +                        imgFormat, GL_UNSIGNED_BYTE, image); +      free(image); +       +      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); +      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); +      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); +      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); +   } +} + + +static void +LoadAndCompileShader(GLuint shader, const char *text) +{ +   GLint stat; + +   glShaderSource_func(shader, 1, (const GLchar **) &text, NULL); + +   glCompileShader_func(shader); + +   glGetShaderiv_func(shader, GL_COMPILE_STATUS, &stat); +   if (!stat) { +      GLchar log[1000]; +      GLsizei len; +      glGetShaderInfoLog_func(shader, 1000, &len, log); +      fprintf(stderr, "%s: problem compiling shader: %s\n", Demo, log); +      exit(1); +   } +   else { +      printf("Shader compiled OK\n"); +   } +} + + +/** + * Read a shader from a file. + */ +static void +ReadShader(GLuint shader, const char *filename) +{ +   const int max = 100*1000; +   int n; +   char *buffer = (char*) malloc(max); +   FILE *f = fopen(filename, "r"); +   if (!f) { +      fprintf(stderr, "%s: Unable to open shader file %s\n", Demo, filename); +      exit(1); +   } + +   n = fread(buffer, 1, max, f); +   printf("%s: read %d bytes from shader file %s\n", Demo, n, filename); +   if (n > 0) { +      buffer[n] = 0; +      LoadAndCompileShader(shader, buffer); +   } + +   fclose(f); +   free(buffer); +} + + +static void +CheckLink(GLuint prog) +{ +   GLint stat; +   glGetProgramiv_func(prog, GL_LINK_STATUS, &stat); +   if (!stat) { +      GLchar log[1000]; +      GLsizei len; +      glGetProgramInfoLog_func(prog, 1000, &len, log); +      fprintf(stderr, "Linker error:\n%s\n", log); +   } +   else { +      fprintf(stderr, "Link success!\n"); +   } +} + + +static GLuint +CreateProgram(const char *vertProgFile, const char *fragProgFile, +              struct uniform_info *uniforms) +{ +   GLuint fragShader = 0, vertShader = 0, program = 0; +   GLint i; + +   program = glCreateProgram_func(); +   if (vertProgFile) { +      vertShader = glCreateShader_func(GL_VERTEX_SHADER); +      ReadShader(vertShader, vertProgFile); +      glAttachShader_func(program, vertShader); +   } + +   if (fragProgFile) { +      fragShader = glCreateShader_func(GL_FRAGMENT_SHADER); +      ReadShader(fragShader, fragProgFile); +      glAttachShader_func(program, fragShader); +   } + +   glLinkProgram_func(program); +   CheckLink(program); + +   glUseProgram_func(program); + +   assert(glIsProgram_func(program)); +   assert(glIsShader_func(fragShader)); +   assert(glIsShader_func(vertShader)); + +   CheckError(__LINE__); +   for (i = 0; uniforms[i].name; i++) { +      uniforms[i].location +         = glGetUniformLocation_func(program, uniforms[i].name); +      printf("Uniform %s location: %d\n", uniforms[i].name, +             uniforms[i].location); + +      switch (uniforms[i].size) { +      case 1: +         if (uniforms[i].type == GL_INT) +            glUniform1i_func(uniforms[i].location, +                             (GLint) uniforms[i].value[0]); +         else +            glUniform1fv_func(uniforms[i].location, 1, uniforms[i].value); +         break; +      case 2: +         glUniform2fv_func(uniforms[i].location, 1, uniforms[i].value); +         break; +      case 3: +         glUniform3fv_func(uniforms[i].location, 1, uniforms[i].value); +         break; +      case 4: +         glUniform4fv_func(uniforms[i].location, 1, uniforms[i].value); +         break; +      default: +         abort(); +      } +   } + +   CheckError(__LINE__); + +   return program; +} + + +static void +InitPrograms(void) +{ +   Program1 = CreateProgram(ReflectVertFile, CubeFragFile, ReflectUniforms); +   Program2 = CreateProgram(SimpleVertFile, SimpleTexFragFile, SimpleUniforms); +} + + +static void +Init(GLboolean useImageFiles) +{ +   const char *version = (const char *) glGetString(GL_VERSION); + +   if (version[0] != '2' || version[1] != '.') { +      printf("Warning: this program expects OpenGL 2.0\n"); +      /*exit(1);*/ +   } +   printf("GL_RENDERER = %s\n",(const char *) glGetString(GL_RENDERER)); + +   GetExtensionFuncs(); + +   InitTextures(useImageFiles); +   InitPrograms(); + +   glEnable(GL_DEPTH_TEST); + +   glClearColor(.6, .6, .9, 0); +   glColor3f(1.0, 1.0, 1.0); +} + + +int +main(int argc, char *argv[]) +{ +   glutInit(&argc, argv); +   glutInitWindowSize(500, 400); +   glutInitDisplayMode(GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE); +   glutCreateWindow(Demo); +   glutReshapeFunc(Reshape); +   glutKeyboardFunc(key); +   glutSpecialFunc(specialkey); +   glutDisplayFunc(draw); +   if (Anim) +      glutIdleFunc(idle); +   if (argc > 1 && strcmp(argv[1] , "-i") == 0) +      Init(1); +   else +      Init(0); +   glutMainLoop(); +   return 0; +} diff --git a/progs/glsl/toyball.c b/progs/glsl/toyball.c new file mode 100644 index 0000000000..cef52c04a6 --- /dev/null +++ b/progs/glsl/toyball.c @@ -0,0 +1,339 @@ +/** + * "Toy Ball" shader demo.  Uses the example shaders from + * chapter 11 of the OpenGL Shading Language "orange" book. + * 16 Jan 2007 + */ + +#include <assert.h> +#include <string.h> +#include <stdio.h> +#include <stdlib.h> +#include <math.h> +#include <GL/gl.h> +#include <GL/glut.h> +#include <GL/glext.h> +#include "extfuncs.h" + + +static char *FragProgFile = "CH11-toyball.frag.txt"; +static char *VertProgFile = "CH11-toyball.vert.txt"; + +/* program/shader objects */ +static GLuint fragShader; +static GLuint vertShader; +static GLuint program; + + +struct uniform_info { +   const char *name; +   GLuint size; +   GLint location; +   GLfloat value[4]; +}; + +static struct uniform_info Uniforms[] = { +   { "LightDir",       4, -1, { 0.57737, 0.57735, 0.57735, 0.0 } }, +   { "HVector",        4, -1, { 0.32506, 0.32506, 0.88808, 0.0 } }, +   { "BallCenter",     4, -1, { 0.0, 0.0, 0.0, 1.0 } }, +   { "SpecularColor",  4, -1, { 0.4, 0.4, 0.4, 60.0 } }, +   { "Red",            4, -1, { 0.6, 0.0, 0.0, 1.0 } }, +   { "Blue",           4, -1, { 0.0, 0.3, 0.6, 1.0 } }, +   { "Yellow",         4, -1, { 0.6, 0.5, 0.0, 1.0 } }, +   { "HalfSpace0",     4, -1, { 1.0, 0.0, 0.0, 0.2 } }, +   { "HalfSpace1",     4, -1, { 0.309016994, 0.951056516, 0.0, 0.2 } }, +   { "HalfSpace2",     4, -1, { -0.809016994, 0.587785252, 0.0, 0.2 } }, +   { "HalfSpace3",     4, -1, { -0.809016994, -0.587785252, 0.0, 0.2 } }, +   { "HalfSpace4",     4, -1, { 0.309116994, -0.951056516, 0.0, 0.2 } }, +   { "InOrOutInit",    1, -1, { -3.0, 0, 0, 0 } }, +   { "StripeWidth",    1, -1, {  0.3, 0, 0, 0 } }, +   { "FWidth",         1, -1, { 0.005, 0, 0, 0 } }, +   { NULL, 0, 0, { 0, 0, 0, 0 } } +}; + +static GLint win = 0; +static GLboolean Anim = GL_FALSE; +static GLfloat TexRot = 0.0; +static GLfloat xRot = 0.0f, yRot = 0.0f, zRot = 0.0f; + + +static void +Idle(void) +{ +   TexRot += 2.0; +   if (TexRot > 360.0) +      TexRot -= 360.0; +   glutPostRedisplay(); +} + + +static void +Redisplay(void) +{ +   glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); +    +   glPushMatrix(); +   glRotatef(xRot, 1.0f, 0.0f, 0.0f); +   glRotatef(yRot, 0.0f, 1.0f, 0.0f); +   glRotatef(zRot, 0.0f, 0.0f, 1.0f); + +   glMatrixMode(GL_TEXTURE); +   glLoadIdentity(); +   glRotatef(TexRot, 0.0f, 1.0f, 0.0f); +   glMatrixMode(GL_MODELVIEW); + +   glutSolidSphere(2.0, 20, 10); + +   glPopMatrix(); + +   glFinish(); +   glFlush(); +   glutSwapBuffers(); +} + + +static void +Reshape(int width, int height) +{ +   glViewport(0, 0, width, height); +   glMatrixMode(GL_PROJECTION); +   glLoadIdentity(); +   glFrustum(-1.0, 1.0, -1.0, 1.0, 5.0, 25.0); +   glMatrixMode(GL_MODELVIEW); +   glLoadIdentity(); +   glTranslatef(0.0f, 0.0f, -15.0f); +} + + +static void +CleanUp(void) +{ +   glDeleteShader_func(fragShader); +   glDeleteShader_func(vertShader); +   glDeleteProgram_func(program); +   glutDestroyWindow(win); +} + + +static void +Key(unsigned char key, int x, int y) +{ +   const GLfloat step = 2.0; +  (void) x; +  (void) y; + +   switch(key) { +   case 'a': +      Anim = !Anim; +      if (Anim) +         glutIdleFunc(Idle); +      else +         glutIdleFunc(NULL); +      break; +   case 'z': +      zRot += step; +      break; +   case 'Z': +      zRot -= step; +      break; +   case 27: +      CleanUp(); +      exit(0); +      break; +   } +   glutPostRedisplay(); +} + + +static void +SpecialKey(int key, int x, int y) +{ +   const GLfloat step = 2.0; + +  (void) x; +  (void) y; + +   switch(key) { +   case GLUT_KEY_UP: +      xRot += step; +      break; +   case GLUT_KEY_DOWN: +      xRot -= step; +      break; +   case GLUT_KEY_LEFT: +      yRot -= step; +      break; +   case GLUT_KEY_RIGHT: +      yRot += step; +      break; +   } +   glutPostRedisplay(); +} + + + +static void +LoadAndCompileShader(GLuint shader, const char *text) +{ +   GLint stat; + +   glShaderSource_func(shader, 1, (const GLchar **) &text, NULL); + +   glCompileShader_func(shader); + +   glGetShaderiv_func(shader, GL_COMPILE_STATUS, &stat); +   if (!stat) { +      GLchar log[1000]; +      GLsizei len; +      glGetShaderInfoLog_func(shader, 1000, &len, log); +      fprintf(stderr, "brick: problem compiling shader: %s\n", log); +      exit(1); +   } +   else { +      printf("Shader compiled OK\n"); +   } +} + + +/** + * Read a shader from a file. + */ +static void +ReadShader(GLuint shader, const char *filename) +{ +   const int max = 100*1000; +   int n; +   char *buffer = (char*) malloc(max); +   FILE *f = fopen(filename, "r"); +   if (!f) { +      fprintf(stderr, "brick: Unable to open shader file %s\n", filename); +      exit(1); +   } + +   n = fread(buffer, 1, max, f); +   printf("brick: read %d bytes from shader file %s\n", n, filename); +   if (n > 0) { +      buffer[n] = 0; +      LoadAndCompileShader(shader, buffer); +   } + +   fclose(f); +   free(buffer); +} + + +static void +CheckLink(GLuint prog) +{ +   GLint stat; +   glGetProgramiv_func(prog, GL_LINK_STATUS, &stat); +   if (!stat) { +      GLchar log[1000]; +      GLsizei len; +      glGetProgramInfoLog_func(prog, 1000, &len, log); +      fprintf(stderr, "Linker error:\n%s\n", log); +   } +   else { +      fprintf(stderr, "Link success!\n"); +   } +} + + +static void +Init(void) +{ +   const char *version; +   GLint i; + +   version = (const char *) glGetString(GL_VERSION); +   if (version[0] != '2' || version[1] != '.') { +      printf("Warning: this program expects OpenGL 2.0\n"); +      /*exit(1);*/ +   } +   printf("GL_RENDERER = %s\n",(const char *) glGetString(GL_RENDERER)); + +   GetExtensionFuncs(); + +   vertShader = glCreateShader_func(GL_VERTEX_SHADER); +   ReadShader(vertShader, VertProgFile); + +   fragShader = glCreateShader_func(GL_FRAGMENT_SHADER); +   ReadShader(fragShader, FragProgFile); + +   program = glCreateProgram_func(); +   glAttachShader_func(program, fragShader); +   glAttachShader_func(program, vertShader); +   glLinkProgram_func(program); +   CheckLink(program); +   glUseProgram_func(program); + +   assert(glIsProgram_func(program)); +   assert(glIsShader_func(fragShader)); +   assert(glIsShader_func(vertShader)); + + +   for (i = 0; Uniforms[i].name; i++) { +      Uniforms[i].location +         = glGetUniformLocation_func(program, Uniforms[i].name); +      printf("Uniform %s location: %d\n", Uniforms[i].name, +             Uniforms[i].location); +      switch (Uniforms[i].size) { +      case 1: +         glUniform1fv_func(Uniforms[i].location, 1, Uniforms[i].value); +         break; +      case 2: +         glUniform2fv_func(Uniforms[i].location, 1, Uniforms[i].value); +         break; +      case 3: +         glUniform3fv_func(Uniforms[i].location, 1, Uniforms[i].value); +         break; +      case 4: +         glUniform4fv_func(Uniforms[i].location, 1, Uniforms[i].value); +         break; +      default: +         abort(); +      } +   } + +   assert(glGetError() == 0); + +   glClearColor(0.4f, 0.4f, 0.8f, 0.0f); + +   glEnable(GL_DEPTH_TEST); + +   glColor3f(1, 0, 0); +} + + +static void +ParseOptions(int argc, char *argv[]) +{ +   int i; +   for (i = 1; i < argc; i++) { +      if (strcmp(argv[i], "-fs") == 0) { +         FragProgFile = argv[i+1]; +      } +      else if (strcmp(argv[i], "-vs") == 0) { +         VertProgFile = argv[i+1]; +      } +   } +} + + +int +main(int argc, char *argv[]) +{ +   glutInit(&argc, argv); +   glutInitWindowPosition( 0, 0); +   glutInitWindowSize(400, 400); +   glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH); +   win = glutCreateWindow(argv[0]); +   glutReshapeFunc(Reshape); +   glutKeyboardFunc(Key); +   glutSpecialFunc(SpecialKey); +   glutDisplayFunc(Redisplay); +   ParseOptions(argc, argv); +   Init(); +   glutMainLoop(); +   return 0; +} + diff --git a/progs/util/extfuncs.h b/progs/util/extfuncs.h new file mode 100644 index 0000000000..f5ea5feaa8 --- /dev/null +++ b/progs/util/extfuncs.h @@ -0,0 +1,118 @@ +/** + * Utility for getting OpenGL extension function pointers + * Meant to be #included. + */ + +/* OpenGL 2.0 */ +static PFNGLATTACHSHADERPROC glAttachShader_func = NULL; +static PFNGLBINDATTRIBLOCATIONPROC glBindAttribLocation_func = NULL; +static PFNGLCOMPILESHADERPROC glCompileShader_func = NULL; +static PFNGLCREATEPROGRAMPROC glCreateProgram_func = NULL; +static PFNGLCREATESHADERPROC glCreateShader_func = NULL; +static PFNGLDELETEPROGRAMPROC glDeleteProgram_func = NULL; +static PFNGLDELETESHADERPROC glDeleteShader_func = NULL; +static PFNGLGETATTACHEDSHADERSPROC glGetAttachedShaders_func = NULL; +static PFNGLGETATTRIBLOCATIONPROC glGetAttribLocation_func = NULL; +static PFNGLGETPROGRAMINFOLOGPROC glGetProgramInfoLog_func = NULL; +static PFNGLGETSHADERINFOLOGPROC glGetShaderInfoLog_func = NULL; +static PFNGLGETSHADERIVPROC glGetShaderiv_func = NULL; +static PFNGLGETPROGRAMIVPROC glGetProgramiv_func = NULL; +static PFNGLGETSHADERSOURCEPROC glGetShaderSource_func = NULL; +static PFNGLGETUNIFORMFVPROC glGetUniformfv_func = NULL; +static PFNGLGETUNIFORMLOCATIONPROC glGetUniformLocation_func = NULL; +static PFNGLISPROGRAMPROC glIsProgram_func = NULL; +static PFNGLISSHADERPROC glIsShader_func = NULL; +static PFNGLLINKPROGRAMPROC glLinkProgram_func = NULL; +static PFNGLSHADERSOURCEPROC glShaderSource_func = NULL; +static PFNGLUNIFORM1IPROC glUniform1i_func = NULL; +static PFNGLUNIFORM1FVPROC glUniform1fv_func = NULL; +static PFNGLUNIFORM2FVPROC glUniform2fv_func = NULL; +static PFNGLUNIFORM3FVPROC glUniform3fv_func = NULL; +static PFNGLUNIFORM4FVPROC glUniform4fv_func = NULL; +static PFNGLUNIFORMMATRIX2FVPROC glUniformMatrix2fv_func = NULL; +static PFNGLUNIFORMMATRIX3FVPROC glUniformMatrix3fv_func = NULL; +static PFNGLUNIFORMMATRIX4FVPROC glUniformMatrix4fv_func = NULL; +static PFNGLUSEPROGRAMPROC glUseProgram_func = NULL; +static PFNGLVERTEXATTRIB1FPROC glVertexAttrib1f_func = NULL; +static PFNGLVERTEXATTRIB2FPROC glVertexAttrib2f_func = NULL; +static PFNGLVERTEXATTRIB3FPROC glVertexAttrib3f_func = NULL; +static PFNGLVERTEXATTRIB4FPROC glVertexAttrib4f_func = NULL; + + +/* GL_ARB_vertex/fragment_program */ +static PFNGLBINDPROGRAMARBPROC glBindProgramARB_func = NULL; +static PFNGLDELETEPROGRAMSARBPROC glDeleteProgramsARB_func = NULL; +static PFNGLGENPROGRAMSARBPROC glGenProgramsARB_func = NULL; +static PFNGLGETPROGRAMLOCALPARAMETERDVARBPROC glGetProgramLocalParameterdvARB_func = NULL; +static PFNGLISPROGRAMARBPROC glIsProgramARB_func = NULL; +static PFNGLPROGRAMLOCALPARAMETER4DARBPROC glProgramLocalParameter4dARB_func = NULL; +static PFNGLPROGRAMLOCALPARAMETER4FVARBPROC glProgramLocalParameter4fvARB_func = NULL; +static PFNGLPROGRAMSTRINGARBPROC glProgramStringARB_func = NULL; +static PFNGLVERTEXATTRIB1FARBPROC glVertexAttrib1fARB_func = NULL; + +/* GL_APPLE_vertex_array_object */ +static PFNGLBINDVERTEXARRAYAPPLEPROC glBindVertexArrayAPPLE_func = NULL; +static PFNGLDELETEVERTEXARRAYSAPPLEPROC glDeleteVertexArraysAPPLE_func = NULL; +static PFNGLGENVERTEXARRAYSAPPLEPROC glGenVertexArraysAPPLE_func = NULL; +static PFNGLISVERTEXARRAYAPPLEPROC glIsVertexArrayAPPLE_func = NULL; + + + +static void +GetExtensionFuncs(void) +{ +   /* OpenGL 2.0 */ +   glAttachShader_func = (PFNGLATTACHSHADERPROC) glutGetProcAddress("glAttachShader"); +   glBindAttribLocation_func = (PFNGLBINDATTRIBLOCATIONPROC) glutGetProcAddress("glBindAttribLocation"); +   glCompileShader_func = (PFNGLCOMPILESHADERPROC) glutGetProcAddress("glCompileShader"); +   glCreateProgram_func = (PFNGLCREATEPROGRAMPROC) glutGetProcAddress("glCreateProgram"); +   glCreateShader_func = (PFNGLCREATESHADERPROC) glutGetProcAddress("glCreateShader"); +   glDeleteProgram_func = (PFNGLDELETEPROGRAMPROC) glutGetProcAddress("glDeleteProgram"); +   glDeleteShader_func = (PFNGLDELETESHADERPROC) glutGetProcAddress("glDeleteShader"); +   glGetAttachedShaders_func = (PFNGLGETATTACHEDSHADERSPROC) glutGetProcAddress("glGetAttachedShaders"); +   glGetAttribLocation_func = (PFNGLGETATTRIBLOCATIONPROC) glutGetProcAddress("glGetAttribLocation"); +   glGetProgramInfoLog_func = (PFNGLGETPROGRAMINFOLOGPROC) glutGetProcAddress("glGetProgramInfoLog"); +   glGetShaderInfoLog_func = (PFNGLGETSHADERINFOLOGPROC) glutGetProcAddress("glGetShaderInfoLog"); +   glGetProgramiv_func = (PFNGLGETPROGRAMIVPROC) glutGetProcAddress("glGetProgramiv"); +   glGetShaderiv_func = (PFNGLGETSHADERIVPROC) glutGetProcAddress("glGetShaderiv"); +   glGetShaderSource_func = (PFNGLGETSHADERSOURCEPROC) glutGetProcAddress("glGetShaderSource"); +   glGetUniformLocation_func = (PFNGLGETUNIFORMLOCATIONPROC) glutGetProcAddress("glGetUniformLocation"); +   glGetUniformfv_func = (PFNGLGETUNIFORMFVPROC) glutGetProcAddress("glGetUniformfv"); +   glIsProgram_func = (PFNGLISPROGRAMPROC) glutGetProcAddress("glIsProgram"); +   glIsShader_func = (PFNGLISSHADERPROC) glutGetProcAddress("glIsShader"); +   glLinkProgram_func = (PFNGLLINKPROGRAMPROC) glutGetProcAddress("glLinkProgram"); +   glShaderSource_func = (PFNGLSHADERSOURCEPROC) glutGetProcAddress("glShaderSource"); +   glUniform1i_func = (PFNGLUNIFORM1IPROC) glutGetProcAddress("glUniform1i"); +   glUniform1fv_func = (PFNGLUNIFORM1FVPROC) glutGetProcAddress("glUniform1fv"); +   glUniform2fv_func = (PFNGLUNIFORM2FVPROC) glutGetProcAddress("glUniform2fv"); +   glUniform3fv_func = (PFNGLUNIFORM3FVPROC) glutGetProcAddress("glUniform3fv"); +   glUniform4fv_func = (PFNGLUNIFORM3FVPROC) glutGetProcAddress("glUniform4fv"); +   glUniformMatrix2fv_func = (PFNGLUNIFORMMATRIX2FVPROC) glutGetProcAddress("glUniformMatrix2fv"); +   glUniformMatrix3fv_func = (PFNGLUNIFORMMATRIX3FVPROC) glutGetProcAddress("glUniformMatrix3fv"); +   glUniformMatrix4fv_func = (PFNGLUNIFORMMATRIX4FVPROC) glutGetProcAddress("glUniformMatrix4fv"); +   glUseProgram_func = (PFNGLUSEPROGRAMPROC) glutGetProcAddress("glUseProgram"); +   glVertexAttrib1f_func = (PFNGLVERTEXATTRIB1FPROC) glutGetProcAddress("glVertexAttrib1f"); +   glVertexAttrib2f_func = (PFNGLVERTEXATTRIB2FPROC) glutGetProcAddress("glVertexAttrib2f"); +   glVertexAttrib3f_func = (PFNGLVERTEXATTRIB3FPROC) glutGetProcAddress("glVertexAttrib3f"); +   glVertexAttrib4f_func = (PFNGLVERTEXATTRIB4FPROC) glutGetProcAddress("glVertexAttrib4f"); + + +   /* GL_ARB_vertex/fragment_program */ +   glBindProgramARB_func = (PFNGLBINDPROGRAMARBPROC) glutGetProcAddress("glBindProgramARB"); +   glDeleteProgramsARB_func = (PFNGLDELETEPROGRAMSARBPROC) glutGetProcAddress("glDeleteProgramsARB"); +   glGenProgramsARB_func = (PFNGLGENPROGRAMSARBPROC) glutGetProcAddress("glGenProgramsARB"); +   glGetProgramLocalParameterdvARB_func = (PFNGLGETPROGRAMLOCALPARAMETERDVARBPROC) glutGetProcAddress("glGetProgramLocalParameterdvARB"); +   glIsProgramARB_func = (PFNGLISPROGRAMARBPROC) glutGetProcAddress("glIsProgramARB"); +   glProgramLocalParameter4dARB_func = (PFNGLPROGRAMLOCALPARAMETER4DARBPROC) glutGetProcAddress("glProgramLocalParameter4dARB"); +   glProgramLocalParameter4fvARB_func = (PFNGLPROGRAMLOCALPARAMETER4FVARBPROC) glutGetProcAddress("glProgramLocalParameter4fvARB"); +   glProgramStringARB_func = (PFNGLPROGRAMSTRINGARBPROC) glutGetProcAddress("glProgramStringARB"); +   glVertexAttrib1fARB_func = (PFNGLVERTEXATTRIB1FARBPROC) glutGetProcAddress("glVertexAttrib1fARB"); + +   /* GL_APPLE_vertex_array_object */ +   glBindVertexArrayAPPLE_func = (PFNGLBINDVERTEXARRAYAPPLEPROC) glutGetProcAddress("glBindVertexArrayAPPLE"); +   glDeleteVertexArraysAPPLE_func = (PFNGLDELETEVERTEXARRAYSAPPLEPROC) glutGetProcAddress("glDeleteVertexArraysAPPLE"); +   glGenVertexArraysAPPLE_func = (PFNGLGENVERTEXARRAYSAPPLEPROC) glutGetProcAddress("glGenVertexArraysAPPLE"); +   glIsVertexArrayAPPLE_func = (PFNGLISVERTEXARRAYAPPLEPROC) glutGetProcAddress("glIsVertexArrayAPPLE"); + +} + | 
