[haiku-commits] r37921 - in haiku/trunk/src/tests/kits/opengl: . glsl

  • From: philippe.houdoin@xxxxxxxxx
  • To: haiku-commits@xxxxxxxxxxxxx
  • Date: Thu, 5 Aug 2010 12:46:08 +0200 (CEST)

Author: phoudoin
Date: 2010-08-05 12:46:08 +0200 (Thu, 05 Aug 2010)
New Revision: 37921
Changeset: http://dev.haiku-os.org/changeset/37921

Added:
   haiku/trunk/src/tests/kits/opengl/glsl/
   haiku/trunk/src/tests/kits/opengl/glsl/CH06-brick.frag
   haiku/trunk/src/tests/kits/opengl/glsl/CH06-brick.vert
   haiku/trunk/src/tests/kits/opengl/glsl/Jamfile
   haiku/trunk/src/tests/kits/opengl/glsl/brick.c
   haiku/trunk/src/tests/kits/opengl/glsl/shaderutil.c
   haiku/trunk/src/tests/kits/opengl/glsl/shaderutil.h
Modified:
   haiku/trunk/src/tests/kits/opengl/Jamfile
Log:
Import GLSL brick demo (small change: no glew, which one day we should support 
though).



Modified: haiku/trunk/src/tests/kits/opengl/Jamfile
===================================================================
--- haiku/trunk/src/tests/kits/opengl/Jamfile   2010-08-05 10:43:56 UTC (rev 
37920)
+++ haiku/trunk/src/tests/kits/opengl/Jamfile   2010-08-05 10:46:08 UTC (rev 
37921)
@@ -3,3 +3,5 @@
 SubInclude HAIKU_TOP src tests kits opengl direct_mode ;
 SubInclude HAIKU_TOP src tests kits opengl demos ;
 SubInclude HAIKU_TOP src tests kits opengl glut ;
+SubInclude HAIKU_TOP src tests kits opengl glsl ;
+

Added: haiku/trunk/src/tests/kits/opengl/glsl/CH06-brick.frag
===================================================================
--- haiku/trunk/src/tests/kits/opengl/glsl/CH06-brick.frag                      
        (rev 0)
+++ haiku/trunk/src/tests/kits/opengl/glsl/CH06-brick.frag      2010-08-05 
10:46:08 UTC (rev 37921)
@@ -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);
+}

Added: haiku/trunk/src/tests/kits/opengl/glsl/CH06-brick.vert
===================================================================
--- haiku/trunk/src/tests/kits/opengl/glsl/CH06-brick.vert                      
        (rev 0)
+++ haiku/trunk/src/tests/kits/opengl/glsl/CH06-brick.vert      2010-08-05 
10:46:08 UTC (rev 37921)
@@ -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();
+}

Added: haiku/trunk/src/tests/kits/opengl/glsl/Jamfile
===================================================================
--- haiku/trunk/src/tests/kits/opengl/glsl/Jamfile                              
(rev 0)
+++ haiku/trunk/src/tests/kits/opengl/glsl/Jamfile      2010-08-05 10:46:08 UTC 
(rev 37921)
@@ -0,0 +1,19 @@
+SubDir HAIKU_TOP src tests kits opengl glsl ;
+
+SetSubDirSupportedPlatformsBeOSCompatible ;
+
+if $(TARGET_PLATFORM) != haiku {
+       # Needed for <GL/glut.h>, not present in R5.
+       # Unfortunately we also get the other headers there,
+       # that we don't really want.
+       UsePublicHeaders opengl ;
+}
+
+StaticLibrary libshaderutil.a :
+       shaderutil.c
+;
+
+SimpleTest brick :
+       brick.c
+       : libshaderutil.a be GL
+;

Added: haiku/trunk/src/tests/kits/opengl/glsl/brick.c
===================================================================
--- haiku/trunk/src/tests/kits/opengl/glsl/brick.c                              
(rev 0)
+++ haiku/trunk/src/tests/kits/opengl/glsl/brick.c      2010-08-05 10:46:08 UTC 
(rev 37921)
@@ -0,0 +1,201 @@
+/**
+ * "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/glew.h>
+#include <GL/glut.h>
+#include <GL/glext.h>
+#include "shaderutil.h"
+
+
+static char *FragProgFile = "CH06-brick.frag";
+static char *VertProgFile = "CH06-brick.vert";
+
+/* program/shader objects */
+static GLuint fragShader;
+static GLuint vertShader;
+static GLuint program;
+
+static struct uniform_info Uniforms[] = {
+   /* vert */
+   { "LightPosition",     1, GL_FLOAT_VEC3, { 0.1, 0.1, 9.0, 0}, -1 },
+   /* frag */
+   { "BrickColor",        1, GL_FLOAT_VEC3, { 0.8, 0.2, 0.2, 0 }, -1 },
+   { "MortarColor",       1, GL_FLOAT_VEC3, { 0.6, 0.6, 0.6, 0 }, -1 },
+   { "BrickSize",         1, GL_FLOAT_VEC2, { 1.0, 0.3, 0, 0 }, -1 },
+   { "BrickPct",          1, GL_FLOAT_VEC2, { 0.9, 0.8, 0, 0 }, -1 },
+   END_OF_UNIFORMS
+};
+
+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(fragShader);
+   glDeleteShader(vertShader);
+   glDeleteProgram(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
+Init(void)
+{
+   if (!ShadersSupported())
+      exit(1);
+
+   vertShader = CompileShaderFile(GL_VERTEX_SHADER, VertProgFile);
+   fragShader = CompileShaderFile(GL_FRAGMENT_SHADER, FragProgFile);
+   program = LinkShaders(vertShader, fragShader);
+
+   glUseProgram(program);
+
+   SetUniformValues(program, Uniforms);
+   PrintUniforms(Uniforms);
+
+   assert(glGetError() == 0);
+
+   glClearColor(0.4f, 0.4f, 0.8f, 0.0f);
+
+   printf("GL_RENDERER = %s\n",(const char *) glGetString(GL_RENDERER));
+
+   assert(glIsProgram(program));
+   assert(glIsShader(fragShader));
+   assert(glIsShader(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);
+   glutInitWindowSize(400, 400);
+   glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
+   win = glutCreateWindow(argv[0]);
+   // glewInit();
+   glutReshapeFunc(Reshape);
+   glutKeyboardFunc(Key);
+   glutSpecialFunc(SpecialKey);
+   glutDisplayFunc(Redisplay);
+   ParseOptions(argc, argv);
+   Init();
+   glutMainLoop();
+   return 0;
+}
+

Added: haiku/trunk/src/tests/kits/opengl/glsl/shaderutil.c
===================================================================
--- haiku/trunk/src/tests/kits/opengl/glsl/shaderutil.c                         
(rev 0)
+++ haiku/trunk/src/tests/kits/opengl/glsl/shaderutil.c 2010-08-05 10:46:08 UTC 
(rev 37921)
@@ -0,0 +1,323 @@
+/**
+ * Utilities for OpenGL shading language
+ *
+ * Brian Paul
+ * 9 April 2008
+ */
+
+
+#include <assert.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+// #include <GL/glew.h>
+#include <GL/glut.h>
+#include "shaderutil.h"
+
+/** time to compile previous shader */
+static GLdouble CompileTime = 0.0;
+
+/** time to linke previous program */
+static GLdouble LinkTime = 0.0;
+
+
+GLboolean
+ShadersSupported(void)
+{
+   const char *version = (const char *) glGetString(GL_VERSION);
+
+   /* NVIDIA binary drivers will return "3.0.0", and they clearly support
+    * shaders.
+    */
+   if (version[0] >= '2' && version[1] == '.') {
+      return GL_TRUE;
+   }
+   else if (glutExtensionSupported("GL_ARB_vertex_shader")
+            && glutExtensionSupported("GL_ARB_fragment_shader")
+            && glutExtensionSupported("GL_ARB_shader_objects")) {
+      fprintf(stderr, "Warning: Trying ARB GLSL instead of OpenGL 2.x.  This 
may not work.\n");
+      return GL_TRUE;
+   }
+   fprintf(stderr, "Sorry, GLSL not supported with this OpenGL.\n");
+   return GL_FALSE;
+}
+
+
+GLuint
+CompileShaderText(GLenum shaderType, const char *text)
+{
+   GLuint shader;
+   GLint stat;
+   GLdouble t0, t1;
+
+   shader = glCreateShader(shaderType);
+   glShaderSource(shader, 1, (const GLchar **) &text, NULL);
+
+   t0 = glutGet(GLUT_ELAPSED_TIME) * 0.001;
+   glCompileShader(shader);
+   t1 = glutGet(GLUT_ELAPSED_TIME) * 0.001;
+
+   CompileTime = t1 - t0;
+
+   glGetShaderiv(shader, GL_COMPILE_STATUS, &stat);
+   if (!stat) {
+      GLchar log[1000];
+      GLsizei len;
+      glGetShaderInfoLog(shader, 1000, &len, log);
+      fprintf(stderr, "Error: problem compiling shader: %s\n", log);
+      exit(1);
+   }
+   else {
+      /*printf("Shader compiled OK\n");*/
+   }
+   return shader;
+}
+
+
+/**
+ * Read a shader from a file.
+ */
+GLuint
+CompileShaderFile(GLenum shaderType, const char *filename)
+{
+   const int max = 100*1000;
+   int n;
+   char *buffer = (char*) malloc(max);
+   GLuint shader;
+   FILE *f;
+
+   f = fopen(filename, "r");
+   if (!f) {
+      fprintf(stderr, "Unable to open shader file %s\n", filename);
+      free(buffer);
+      return 0;
+   }
+
+   n = fread(buffer, 1, max, f);
+   /*printf("read %d bytes from shader file %s\n", n, filename);*/
+   if (n > 0) {
+      buffer[n] = 0;
+      shader = CompileShaderText(shaderType, buffer);
+   }
+   else {
+      fclose(f);
+      free(buffer);
+      return 0;
+   }
+
+   fclose(f);
+   free(buffer);
+
+   return shader;
+}
+
+
+GLuint
+LinkShaders(GLuint vertShader, GLuint fragShader)
+{
+   GLuint program = glCreateProgram();
+   GLdouble t0, t1;
+
+   assert(vertShader || fragShader);
+
+   if (fragShader)
+      glAttachShader(program, fragShader);
+   if (vertShader)
+      glAttachShader(program, vertShader);
+
+   t0 = glutGet(GLUT_ELAPSED_TIME) * 0.001;
+   glLinkProgram(program);
+   t1 = glutGet(GLUT_ELAPSED_TIME) * 0.001;
+
+   LinkTime = t1 - t0;
+
+   /* check link */
+   {
+      GLint stat;
+      glGetProgramiv(program, GL_LINK_STATUS, &stat);
+      if (!stat) {
+         GLchar log[1000];
+         GLsizei len;
+         glGetProgramInfoLog(program, 1000, &len, log);
+         fprintf(stderr, "Shader link error:\n%s\n", log);
+         return 0;
+      }
+   }
+
+   return program;
+}
+
+
+GLboolean
+ValidateShaderProgram(GLuint program)
+{
+   GLint stat;
+   glValidateProgramARB(program);
+   glGetProgramiv(program, GL_VALIDATE_STATUS, &stat);
+
+   if (!stat) {
+      GLchar log[1000];
+      GLsizei len;
+      glGetProgramInfoLog(program, 1000, &len, log);
+      fprintf(stderr, "Program validation error:\n%s\n", log);
+      return 0;
+   }
+
+   return (GLboolean) stat;
+}
+
+
+GLdouble
+GetShaderCompileTime(void)
+{
+   return CompileTime;
+}
+
+
+GLdouble
+GetShaderLinkTime(void)
+{
+   return LinkTime;
+}
+
+
+void
+SetUniformValues(GLuint program, struct uniform_info uniforms[])
+{
+   GLuint i;
+
+   for (i = 0; uniforms[i].name; i++) {
+      uniforms[i].location
+         = glGetUniformLocation(program, uniforms[i].name);
+
+      switch (uniforms[i].type) {
+      case GL_INT:
+      case GL_SAMPLER_1D:
+      case GL_SAMPLER_2D:
+      case GL_SAMPLER_3D:
+      case GL_SAMPLER_CUBE:
+      case GL_SAMPLER_2D_RECT_ARB:
+         assert(uniforms[i].value[0] >= 0.0F);
+         glUniform1i(uniforms[i].location,
+                     (GLint) uniforms[i].value[0]);
+         break;
+      case GL_FLOAT:
+         glUniform1fv(uniforms[i].location, 1, uniforms[i].value);
+         break;
+      case GL_FLOAT_VEC2:
+         glUniform2fv(uniforms[i].location, 1, uniforms[i].value);
+         break;
+      case GL_FLOAT_VEC3:
+         glUniform3fv(uniforms[i].location, 1, uniforms[i].value);
+         break;
+      case GL_FLOAT_VEC4:
+         glUniform4fv(uniforms[i].location, 1, uniforms[i].value);
+         break;
+      default:
+         if (strncmp(uniforms[i].name, "gl_", 3) == 0) {
+            /* built-in uniform: ignore */
+         }
+         else {
+            fprintf(stderr,
+                    "Unexpected uniform data type in SetUniformValues\n");
+            abort();
+         }
+      }
+   }
+}
+
+
+/** Get list of uniforms used in the program */
+GLuint
+GetUniforms(GLuint program, struct uniform_info uniforms[])
+{
+   GLint n, max, i;
+
+   glGetProgramiv(program, GL_ACTIVE_UNIFORMS, &n);
+   glGetProgramiv(program, GL_ACTIVE_UNIFORM_MAX_LENGTH, &max);
+
+   for (i = 0; i < n; i++) {
+      GLint size, len;
+      GLenum type;
+      char name[100];
+
+      glGetActiveUniform(program, i, 100, &len, &size, &type, name);
+
+      uniforms[i].name = strdup(name);
+      uniforms[i].size = size;
+      uniforms[i].type = type;
+      uniforms[i].location = glGetUniformLocation(program, name);
+   }
+
+   uniforms[i].name = NULL; /* end of list */
+
+   return n;
+}
+
+
+void
+PrintUniforms(const struct uniform_info uniforms[])
+{
+   GLint i;
+
+   printf("Uniforms:\n");
+
+   for (i = 0; uniforms[i].name; i++) {
+      printf("  %d: %s size=%d type=0x%x loc=%d value=%g, %g, %g, %g\n",
+             i,
+             uniforms[i].name,
+             uniforms[i].size,
+             uniforms[i].type,
+             uniforms[i].location,
+             uniforms[i].value[0],
+             uniforms[i].value[1],
+             uniforms[i].value[2],
+             uniforms[i].value[3]);
+   }
+}
+
+
+/** Get list of attribs used in the program */
+GLuint
+GetAttribs(GLuint program, struct attrib_info attribs[])
+{
+   GLint n, max, i;
+
+   glGetProgramiv(program, GL_ACTIVE_ATTRIBUTES, &n);
+   glGetProgramiv(program, GL_ACTIVE_ATTRIBUTE_MAX_LENGTH, &max);
+
+   for (i = 0; i < n; i++) {
+      GLint size, len;
+      GLenum type;
+      char name[100];
+
+      glGetActiveAttrib(program, i, 100, &len, &size, &type, name);
+
+      attribs[i].name = strdup(name);
+      attribs[i].size = size;
+      attribs[i].type = type;
+      attribs[i].location = glGetAttribLocation(program, name);
+   }
+
+   attribs[i].name = NULL; /* end of list */
+
+   return n;
+}
+
+
+void
+PrintAttribs(const struct attrib_info attribs[])
+{
+   GLint i;
+
+   printf("Attribs:\n");
+
+   for (i = 0; attribs[i].name; i++) {
+      printf("  %d: %s size=%d type=0x%x loc=%d\n",
+             i,
+             attribs[i].name,
+             attribs[i].size,
+             attribs[i].type,
+             attribs[i].location);
+   }
+}

Added: haiku/trunk/src/tests/kits/opengl/glsl/shaderutil.h
===================================================================
--- haiku/trunk/src/tests/kits/opengl/glsl/shaderutil.h                         
(rev 0)
+++ haiku/trunk/src/tests/kits/opengl/glsl/shaderutil.h 2010-08-05 10:46:08 UTC 
(rev 37921)
@@ -0,0 +1,63 @@
+#ifndef SHADER_UTIL_H
+#define SHADER_UTIL_H
+
+
+
+struct uniform_info
+{
+   const char *name;
+   GLuint size;  /**< number of value[] elements: 1, 2, 3 or 4 */
+   GLenum type;  /**< GL_FLOAT, GL_FLOAT_VEC4, GL_INT, etc */
+   GLfloat value[4];
+   GLint location;  /**< filled in by InitUniforms() */
+};
+
+#define END_OF_UNIFORMS   { NULL, 0, GL_NONE, { 0, 0, 0, 0 }, -1 }
+
+
+struct attrib_info
+{
+   const char *name;
+   GLuint size;  /**< number of value[] elements: 1, 2, 3 or 4 */
+   GLenum type;  /**< GL_FLOAT, GL_FLOAT_VEC4, GL_INT, etc */
+   GLint location;
+};
+
+
+extern GLboolean
+ShadersSupported(void);
+
+extern GLuint
+CompileShaderText(GLenum shaderType, const char *text);
+
+extern GLuint
+CompileShaderFile(GLenum shaderType, const char *filename);
+
+extern GLuint
+LinkShaders(GLuint vertShader, GLuint fragShader);
+
+extern GLboolean
+ValidateShaderProgram(GLuint program);
+
+extern GLdouble
+GetShaderCompileTime(void);
+
+extern GLdouble
+GetShaderLinkTime(void);
+
+extern void
+SetUniformValues(GLuint program, struct uniform_info uniforms[]);
+
+extern GLuint
+GetUniforms(GLuint program, struct uniform_info uniforms[]);
+
+extern void
+PrintUniforms(const struct uniform_info uniforms[]);
+
+extern GLuint
+GetAttribs(GLuint program, struct attrib_info attribs[]);
+
+extern void
+PrintAttribs(const struct attrib_info attribs[]);
+
+#endif /* SHADER_UTIL_H */


Other related posts: