Browse Source

added file -> string function and example,
better comments on pathinfo, basename, dirname,
added functions to assist creation, loading of GLSL shaders (some of which is translated from Denis Kovacs's NYU code)


Former-commit-id: 36947b1cd191801d21171b027f437ccb2b7e4ab6

jalec 14 years ago
parent
commit
57d8e1844b

+ 2 - 0
basename.h

@@ -9,6 +9,8 @@ namespace igl
   // Input:
   // Input:
   //  path  string containing input path
   //  path  string containing input path
   // Returns string containing basename (see php's basename)
   // Returns string containing basename (see php's basename)
+  //
+  // See also: dirname, pathinfo
   std::string basename(const std::string & path);
   std::string basename(const std::string & path);
 }
 }
 
 

+ 90 - 0
create_shader_program.h

@@ -0,0 +1,90 @@
+#ifndef IGL_CREATE_SHADER_PROGRAM_H
+#define IGL_CREATE_SHADER_PROGRAM_H
+#include <string>
+#include <map>
+
+#ifdef __APPLE__
+#   include <OpenGL/gl.h>
+#else
+#   include <GL/gl.h>
+#endif
+
+namespace igl
+{
+  // Create a shader program with a vertex and fragments shader loading from
+  // source strings and vertex attributes assigned from a map before linking the
+  // shaders to the program, making it ready to use with glUseProgram(id)
+  // Inputs:
+  //   vert_source  string containing source code of vertex shader
+  //   frag_source  string containing source code of fragment shader
+  //   attrib  map containing table of vertex attribute strings add their
+  //   correspondingly ids (generated previously using glBindAttribLocation)
+  // Outputs:
+  //   id  index id of created shader, set to 0 on error
+  // Returns true on success, false on error
+  //
+  // Note: Caller is responsible for making sure that current value of id is not
+  // leaking a shader (since it will be overwritten)
+  //
+  // See also: destroy_shader_program
+  inline bool create_shader_program(
+    const std::string vert_source,
+    const std::string frag_source,
+    const std::map<std::string,GLuint> attrib,
+    GLuint & id);
+}
+
+// Implementation
+#include "load_shader.h"
+#include "print_program_info_log.h"
+#include <cstdio>
+
+inline bool igl::create_shader_program(
+  const std::string vert_source,
+  const std::string frag_source,
+  const std::map<std::string,GLuint> attrib,
+  GLuint & id)
+{
+  // load vertex shader
+  GLuint v = igl::load_shader(vert_source.c_str(),GL_VERTEX_SHADER);
+  if(v == 0)
+  {
+    return false;
+  }
+  // load fragment shader
+  GLuint f = igl::load_shader(frag_source.c_str(),GL_FRAGMENT_SHADER);
+  if(f == 0)
+  {
+    return false;
+  }
+  // create program
+  id = glCreateProgram();
+  if(id == 0)
+  {
+    fprintf(
+      stderr,
+      "Error: create_shader_program() could not create shader program.\n");
+    return false;
+  }
+  // Attach vertex and frag shaders to program
+  glAttachShader(id,v);
+  glAttachShader(id,f);
+  // loop over attributes
+  for(
+    std::map<std::string,GLuint>::const_iterator ait = attrib.begin();
+    ait != attrib.end();
+    ait++)
+  {
+    glBindAttribLocation(
+      id,
+      (*ait).second,
+      (*ait).first.c_str());
+  }
+  // Link program
+  glLinkProgram(id);
+  // print log if any
+  igl::print_program_info_log(id);
+
+  return true;
+}
+#endif

+ 56 - 0
destroy_shader_program.h

@@ -0,0 +1,56 @@
+#ifndef IGL_DESTROY_SHADER_PROGRAM_H
+#define IGL_DESTROY_SHADER_PROGRAM_H
+
+#ifdef __APPLE__
+#   include <OpenGL/gl.h>
+#else
+#   include <GL/gl.h>
+#endif
+
+namespace igl
+{
+  // Properly destroy a shader program. Detach and delete each of its shaders
+  // and delete it
+  // Inputs:
+  //   id  index id of created shader, set to 0 on error
+  // Returns true on success, false on error
+  // 
+  // Note: caller is responsible for making sure he doesn't foolishly continue
+  // to use id as if it still contains a program
+  // 
+  // See also: create_shader_program
+  inline bool destroy_shader_program(const GLuint id);
+}
+
+// Implementation
+inline bool igl::destroy_shader_program(const GLuint id)
+{
+  // Don't try to destroy id == 0 (no shader program)
+  if(id == 0)
+  {
+    fprintf(stderr,"Error: destroy_shader_program() id = %d"
+      " but must should be positive\n",id);
+    return false;
+  }
+  // Get each attached shader one by one and detach and delete it
+  GLsizei count;
+  // shader id
+  GLuint s;
+  do
+  {
+    // Try to get at most *1* attached shader
+    glGetAttachedShaders(id,1,&count,&s);
+    // Check that we actually got *1*
+    if(count == 1)
+    {
+      // Detach and delete this shader
+      glDetachShader(id,s);
+      glDeleteShader(s);
+    }
+  }while(count > 0);
+  // Now that all of the shaders are gone we can just delete the program
+  glDeleteProgram(id);
+  return true;
+}
+
+#endif

+ 2 - 0
dirname.h

@@ -9,6 +9,8 @@ namespace igl
   // Input:
   // Input:
   //  path  string containing input path
   //  path  string containing input path
   // Returns string containing dirname (see php's dirname)
   // Returns string containing dirname (see php's dirname)
+  //
+  // See also: basename, pathinfo
   std::string dirname(const std::string & path);
   std::string dirname(const std::string & path);
 }
 }
 
 

+ 22 - 0
examples/file_contents_as_string/Makefile

@@ -0,0 +1,22 @@
+
+.PHONY: all
+
+all: example
+
+.PHONY: example
+
+igl_lib=../../
+
+CFLAGS=-g
+inc=-I$(igl_lib)
+lib=
+
+example: example.o
+	g++ $(CFLAGS) -o example example.o $(lib)
+	rm example.o
+
+example.o: example.cpp
+	g++ $(CFLAGS) -c example.cpp -o example.o $(inc)
+clean:
+	rm -f example.o
+	rm -f example

+ 14 - 0
examples/file_contents_as_string/README

@@ -0,0 +1,14 @@
+This is a simple example program that shows how to use the
+file_contents_as_string function in the igl library.
+
+
+To Build:
+  make
+
+To Run:
+  ./example [path_1] [path_2] ... [path_n]
+
+Example Run #1:
+  Issuing:
+    ./example example.cpp | diff - example.cpp
+  Should produce no differences

+ 26 - 0
examples/file_contents_as_string/example.cpp

@@ -0,0 +1,26 @@
+#include "file_contents_as_string.h"
+using namespace igl;
+#include <cstdio>
+#include <string>
+using namespace std;
+
+int main(int argc, char * argv[])
+{
+  if(argc <= 1)
+  {
+    printf("USAGE:\n  ./example [path_1] [path_2] ... [path_n]\n");
+    return 1;
+  }
+  // loop over arguments
+  for(int i = 1; i < argc; i++)
+  {
+    string content;
+    bool success = file_contents_as_string(argv[i],content);
+    if(!success)
+    {
+      return 1;
+    }
+    printf("%s",content.c_str());
+  }
+  return 0;
+}

+ 42 - 0
file_contents_as_string.h

@@ -0,0 +1,42 @@
+#ifndef FILE_CONTENTS_AS_STRING_H
+#define FILE_CONTENTS_AS_STRING_H
+
+#include <string>
+namespace igl
+{
+  // Read a files contents as plain text into a given string
+  // Inputs:
+  //   file_name  path to file to be read
+  // Outputs:
+  //   content  output string containing contents of the given file
+  // Returns true on succes, false on error
+  inline bool file_contents_as_string(
+    const std::string file_name,
+    std::string & content);
+}
+
+// Implementation
+#include <fstream>
+#include <cstdio>
+
+inline bool igl::file_contents_as_string(
+  const std::string file_name,
+  std::string & content)
+{
+  std::ifstream ifs(file_name.c_str());
+  // Check that opening the stream worked successfully
+  if(!ifs.good())
+  {
+    fprintf(
+      stderr,
+      "IOError: file_contents_as_string() cannot open %s\n",
+      file_name.c_str());
+    return false;
+  }
+  // Stream file contents into string
+  content = std::string(
+    (std::istreambuf_iterator<char>(ifs)),
+    (std::istreambuf_iterator<char>()));
+  return true;
+}
+#endif

+ 44 - 0
load_shader.h

@@ -0,0 +1,44 @@
+#ifndef IGL_LOAD_SHADER_H 
+#define IGL_LOAD_SHADER_H 
+
+#ifdef __APPLE__
+#   include <OpenGL/gl.h>
+#else
+#   include <GL/gl.h>
+#endif
+
+namespace igl
+{
+  // Creates and compiles a shader from a given string
+  // Inputs:
+  //   src  string containing GLSL shader code
+  //   type  GLSL type of shader, one of:
+  //     GL_VERTEX_SHADER
+  //     GL_FRAGMENT_SHADER
+  //     GL_GEOMETRY_SHADER
+  // Returns  index id of the newly created shader, 0 on error
+  GLuint load_shader(const char *src,const GLenum type);
+}
+
+// Implmentation
+// Copyright Denis Kovacs 4/10/08
+#include "print_shader_info_log.h"
+#include <cstdio>
+GLuint igl::load_shader(const char *src,const GLenum type)
+{
+  GLuint s = glCreateShader(type);
+  if(s == 0)
+  {
+    fprintf(stderr,"Error: load_shader() failed to create shader.\n");
+    return 0;
+  }
+  // Pass shader source string
+  glShaderSource(s, 1, &src, NULL);
+  glCompileShader(s);
+  // Print info log (if any)
+  igl::print_shader_info_log(s);
+  return s;
+}
+
+#endif
+

+ 2 - 0
pathinfo.h

@@ -21,6 +21,8 @@ namespace igl
   //  extension  string containing extension (characters after last '.')
   //  extension  string containing extension (characters after last '.')
   //  filename  string containing extension (characters of basename before last
   //  filename  string containing extension (characters of basename before last
   //    '.')
   //    '.')
+  //
+  //  See also: basename, dirname
   void pathinfo(
   void pathinfo(
     const std::string & path,
     const std::string & path,
     std::string & dirname,
     std::string & dirname,

+ 35 - 0
print_program_info_log.h

@@ -0,0 +1,35 @@
+#ifndef  IGL_PRINT_PROGRAM_INFO_LOG_H
+#define IGL_PRINT_PROGRAM_INFO_LOG_H
+
+#ifdef __APPLE__
+#   include <OpenGL/gl.h>
+#else
+#   include <GL/gl.h>
+#endif
+namespace igl
+{
+  // Inputs:
+  //   obj  OpenGL index of program to print info log about
+  inline void print_program_info_log(const GLuint obj);
+}
+
+// Implmentation
+#include <cstdio>
+// Copyright Denis Kovacs 4/10/08
+inline void igl::print_program_info_log(const GLuint obj)
+{
+  GLint infologLength = 0;
+  GLint charsWritten  = 0;
+  char *infoLog;
+  
+  glGetProgramiv(obj, GL_INFO_LOG_LENGTH,&infologLength);
+  
+  if (infologLength > 0)
+  {
+    infoLog = (char *)malloc(infologLength);
+    glGetProgramInfoLog(obj, infologLength, &charsWritten, infoLog);
+    printf("%s\n",infoLog);
+    free(infoLog);
+  }
+}
+#endif 

+ 37 - 0
print_shader_info_log.h

@@ -0,0 +1,37 @@
+#ifndef  IGL_PRINT_SHADER_INFO_LOG_H
+#define IGL_PRINT_SHADER_INFO_LOG_H
+
+#ifdef __APPLE__
+#   include <OpenGL/gl.h>
+#else
+#   include <GL/gl.h>
+#endif
+
+namespace igl
+{
+  // Inputs:
+  //   obj  OpenGL index of shader to print info log about
+  inline void print_shader_info_log(const GLuint obj);
+}
+
+// Implmentation
+#include <cstdio>
+// Copyright Denis Kovacs 4/10/08
+inline void igl::print_shader_info_log(const GLuint obj)
+{
+  GLint infologLength = 0;
+  GLint charsWritten  = 0;
+  char *infoLog;
+  
+  // Get shader info log from opengl
+  glGetShaderiv(obj, GL_INFO_LOG_LENGTH,&infologLength);
+  // Only print if there is something in the log
+  if (infologLength > 0)
+  {
+    infoLog = (char *)malloc(infologLength);
+    glGetShaderInfoLog(obj, infologLength, &charsWritten, infoLog);
+    printf("%s\n",infoLog);
+    free(infoLog);
+  }
+}
+#endif