From 256e288ccecd3e24d9ba0e2948ad224a5dc153d3 Mon Sep 17 00:00:00 2001
From: Ansgar Philippsen <ansgar.philippsen@gmail.com>
Date: Tue, 31 Aug 2010 18:36:08 -0400
Subject: [PATCH] extended Shader interface for external addition of programs

---
 modules/gfx/src/glext_include.hh |  4 +-
 modules/gfx/src/shader.cc        | 67 +++++++++++++++++++++-----------
 modules/gfx/src/shader.hh        |  9 +++++
 3 files changed, 57 insertions(+), 23 deletions(-)

diff --git a/modules/gfx/src/glext_include.hh b/modules/gfx/src/glext_include.hh
index 3eda5fb9a..4ac3d6ec8 100644
--- a/modules/gfx/src/glext_include.hh
+++ b/modules/gfx/src/glext_include.hh
@@ -47,6 +47,8 @@
 // hardcode the value here...
 #define OST_GL_VERSION_2_0 1
 #else
-#define OST_GL_VERSION_2_0 GLEW_VERSION_2_0
+#ifdef GLEW_VERSION_2_0
+#define OST_GL_VERSION_2_0 1
+#endif
 #endif
 #endif
diff --git a/modules/gfx/src/shader.cc b/modules/gfx/src/shader.cc
index b82bae72b..e95bdf25b 100644
--- a/modules/gfx/src/shader.cc
+++ b/modules/gfx/src/shader.cc
@@ -67,9 +67,8 @@ void Shader::PreGLInit()
 #endif
 }
 
-namespace {
-
-bool compile_shader(String shader_name, String shader_code, GLenum shader_type, GLuint& shader_id)
+bool Shader::Compile(std::string shader_name, std::string shader_code, 
+                     GLenum shader_type, GLuint& shader_id)
 {
   shader_id = glCreateShader(shader_type);
   const char* tmp_ptr[] = {0};
@@ -92,7 +91,7 @@ bool compile_shader(String shader_name, String shader_code, GLenum shader_type,
   return true;
 }
 
-bool link_shader(const std::vector<GLuint>& code_list, String pr_name, GLuint& shader_pr)
+bool Shader::Link(const std::vector<GLuint>& code_list, std::string pr_name, GLuint& shader_pr)
 {
   shader_pr = glCreateProgram();
   for(std::vector<GLuint>::const_iterator it=code_list.begin();it!=code_list.end();++it) {
@@ -120,8 +119,32 @@ bool link_shader(const std::vector<GLuint>& code_list, String pr_name, GLuint& s
   return true;
 }
 
+bool Shader::Add(const std::string& name, const std::string& vs_code, const std::string& fs_code)
+{
+  GLuint vs_id=0;
+  if(!Shader::Compile(name,vs_code,GL_VERTEX_SHADER,vs_id)) {
+    return false;
+  }
+  
+  GLuint fs_id=0;
+  if(!Shader::Compile(name,fs_code,GL_FRAGMENT_SHADER,fs_id)) {
+    return false;
+  }
+  
+  std::vector<GLuint> shader_program_list;
+  GLuint id;
+
+  shader_program_list.push_back(vs_id);
+  shader_program_list.push_back(fs_id);
+  if(!Shader::Link(shader_program_list,"hatch",id)) {
+    return false;
+  }
+
+  shader_program_map_[name]=id;
+  return true;
 }
 
+
 void Shader::Setup() 
 {
   if(!OST_GL_VERSION_2_0) return;
@@ -186,7 +209,7 @@ void Shader::Setup()
     }
 
     GLuint shader_id;
-    if(compile_shader(shader_name,shader_code,shader_list[i].type,shader_id)) {
+    if(Shader::Compile(shader_name,shader_code,shader_list[i].type,shader_id)) {
       shader_code_map_[shader_name]=shader_id;
     } else {
       shader_code_map_[shader_name]=0;
@@ -198,119 +221,119 @@ void Shader::Setup()
   // basic shader
   shader_program_list.push_back(shader_code_map_["basic_vs.glsl"]);
   shader_program_list.push_back(shader_code_map_["basic_fs.glsl"]);
-  if(link_shader(shader_program_list,"basic",shader_program_id)) {
+  if(Shader::Link(shader_program_list,"basic",shader_program_id)) {
     shader_program_map_["basic"]=shader_program_id;
   }
   // fraglight shader
   shader_program_list.clear();
   shader_program_list.push_back(shader_code_map_["fraglight_vs.glsl"]);
   shader_program_list.push_back(shader_code_map_["fraglight_fs.glsl"]);
-  if(link_shader(shader_program_list,"fraglight",shader_program_id)) {
+  if(Shader::Link(shader_program_list,"fraglight",shader_program_id)) {
     shader_program_map_["fraglight"]=shader_program_id;
   }
   // basic hemisphere lighting shader
   shader_program_list.clear();
   shader_program_list.push_back(shader_code_map_["basic_hf_vs.glsl"]);
   shader_program_list.push_back(shader_code_map_["basic_fs.glsl"]);
-  if(link_shader(shader_program_list,"hemilight",shader_program_id)) {
+  if(Shader::Link(shader_program_list,"hemilight",shader_program_id)) {
     shader_program_map_["hemilight"]=shader_program_id;
   }
   // selfx shader
   shader_program_list.clear();
   shader_program_list.push_back(shader_code_map_["selfx_vs.glsl"]);
   shader_program_list.push_back(shader_code_map_["selfx_fs.glsl"]);
-  if(link_shader(shader_program_list,"selfx",shader_program_id)) {
+  if(Shader::Link(shader_program_list,"selfx",shader_program_id)) {
     shader_program_map_["selfx"]=shader_program_id;
   }
   // toon shader
   shader_program_list.clear();
   shader_program_list.push_back(shader_code_map_["toon_vs.glsl"]);
   shader_program_list.push_back(shader_code_map_["toon_fs.glsl"]);
-  if(link_shader(shader_program_list,"toon1",shader_program_id)) {
+  if(Shader::Link(shader_program_list,"toon1",shader_program_id)) {
     shader_program_map_["toon1"]=shader_program_id;
   }
   // toon2 shader
   shader_program_list.clear();
   shader_program_list.push_back(shader_code_map_["toon_vs.glsl"]);
   shader_program_list.push_back(shader_code_map_["toon2_fs.glsl"]);
-  if(link_shader(shader_program_list,"toon2",shader_program_id)) {
+  if(Shader::Link(shader_program_list,"toon2",shader_program_id)) {
     shader_program_map_["toon2"]=shader_program_id;
   }
   // line shader
   shader_program_list.clear();
   shader_program_list.push_back(shader_code_map_["basic_vs.glsl"]);
   shader_program_list.push_back(shader_code_map_["aaline_fs.glsl"]);
-  if(link_shader(shader_program_list,"aaline",shader_program_id)) {
+  if(Shader::Link(shader_program_list,"aaline",shader_program_id)) {
     shader_program_map_["aaline"]=shader_program_id;
   }
   // iso shader
   shader_program_list.clear();
   shader_program_list.push_back(shader_code_map_["iso_vs.glsl"]);
   shader_program_list.push_back(shader_code_map_["iso_fs.glsl"]);
-  if(link_shader(shader_program_list,"iso",shader_program_id)) {
+  if(Shader::Link(shader_program_list,"iso",shader_program_id)) {
     shader_program_map_["iso"]=shader_program_id;
   }
   // fast sphere shader
   shader_program_list.clear();
   shader_program_list.push_back(shader_code_map_["fast_sphere_vs.glsl"]);
   shader_program_list.push_back(shader_code_map_["fast_sphere_fs.glsl"]);
-  if(link_shader(shader_program_list,"fast_sphere",shader_program_id)) {
+  if(Shader::Link(shader_program_list,"fast_sphere",shader_program_id)) {
     shader_program_map_["fast_sphere"]=shader_program_id;
   }
   // outline shader
   shader_program_list.clear();
   shader_program_list.push_back(shader_code_map_["outline_vs.glsl"]);
   shader_program_list.push_back(shader_code_map_["basic_fs.glsl"]);
-  if(link_shader(shader_program_list,"outline",shader_program_id)) {
+  if(Shader::Link(shader_program_list,"outline",shader_program_id)) {
     shader_program_map_["outline"]=shader_program_id;
   }
   // dumpnorm shader
   shader_program_list.clear();
   shader_program_list.push_back(shader_code_map_["dumpnorm_vs.glsl"]);
   shader_program_list.push_back(shader_code_map_["dumpnorm_fs.glsl"]);
-  if(link_shader(shader_program_list,"dumpnorm",shader_program_id)) {
+  if(Shader::Link(shader_program_list,"dumpnorm",shader_program_id)) {
     shader_program_map_["dumpnorm"]=shader_program_id;
   }
   // convolute1 shader
   shader_program_list.clear();
   shader_program_list.push_back(shader_code_map_["quadpp_vs.glsl"]);
   shader_program_list.push_back(shader_code_map_["convolute1_fs.glsl"]);
-  if(link_shader(shader_program_list,"convolute1",shader_program_id)) {
+  if(Shader::Link(shader_program_list,"convolute1",shader_program_id)) {
     shader_program_map_["convolute1"]=shader_program_id;
   }
   // amboccl shader
   shader_program_list.clear();
   shader_program_list.push_back(shader_code_map_["quadpp_vs.glsl"]);
   shader_program_list.push_back(shader_code_map_["amboccl_fs.glsl"]);
-  if(link_shader(shader_program_list,"amboccl",shader_program_id)) {
+  if(Shader::Link(shader_program_list,"amboccl",shader_program_id)) {
     shader_program_map_["amboccl"]=shader_program_id;
   }
   // beacon shader
   shader_program_list.clear();
   shader_program_list.push_back(shader_code_map_["scenefx_vs.glsl"]);
   shader_program_list.push_back(shader_code_map_["beacon_fs.glsl"]);
-  if(link_shader(shader_program_list,"beacon",shader_program_id)) {
+  if(Shader::Link(shader_program_list,"beacon",shader_program_id)) {
     shader_program_map_["beacon"]=shader_program_id;
   }
   // scenefx shader
   shader_program_list.clear();
   shader_program_list.push_back(shader_code_map_["scenefx_vs.glsl"]);
   shader_program_list.push_back(shader_code_map_["scenefx_fs.glsl"]);
-  if(link_shader(shader_program_list,"scenefx",shader_program_id)) {
+  if(Shader::Link(shader_program_list,"scenefx",shader_program_id)) {
     shader_program_map_["scenefx"]=shader_program_id;
   }
   // screen blur shader
   shader_program_list.clear();
   shader_program_list.push_back(shader_code_map_["quadpp_vs.glsl"]);
   shader_program_list.push_back(shader_code_map_["screenblur4_fs.glsl"]);
-  if(link_shader(shader_program_list,"screenblur4",shader_program_id)) {
+  if(Shader::Link(shader_program_list,"screenblur4",shader_program_id)) {
     shader_program_map_["screenblur4"]=shader_program_id;
   }
   // test tex shader
   shader_program_list.clear();
   shader_program_list.push_back(shader_code_map_["fraglight_vs.glsl"]);
   shader_program_list.push_back(shader_code_map_["test_tex_fs.glsl"]);
-  if(link_shader(shader_program_list,"test_tex",shader_program_id)) {
+  if(Shader::Link(shader_program_list,"test_tex",shader_program_id)) {
     shader_program_map_["test_tex"]=shader_program_id;
   }
 
diff --git a/modules/gfx/src/shader.hh b/modules/gfx/src/shader.hh
index f61aeeb97..ecd457beb 100644
--- a/modules/gfx/src/shader.hh
+++ b/modules/gfx/src/shader.hh
@@ -28,6 +28,8 @@
 #include <string>
 #include <map>
 #include <stack>
+#include <vector>
+
 #include <ost/gfx/module_config.hh>
 #include "glext_include.hh"
 
@@ -38,6 +40,13 @@ public:
   // singleton implementation
   static Shader& Instance();
 
+  static bool Compile(std::string shader_name, std::string shader_code,
+                      GLenum shader_type, GLuint& shader_id);
+
+  static bool Link(const std::vector<GLuint>& code_list, std::string pr_name, GLuint& shader_pr);
+
+  bool Add(const std::string& name, const std::string& vs_code, const std::string& fs_code);
+
   void PreGLInit();
   void Setup();
   void Activate(const String& name);
-- 
GitLab