Przeglądaj źródła

Step 3: Convert shader and shader_program to use the new manager::compile function instead of the graphics::shaders::init free function. (1/2)

Sam Jaffe 6 lat temu
rodzic
commit
822612096e

+ 4 - 4
graphics/graphics.xcodeproj/project.pbxproj

@@ -16,7 +16,7 @@
 		CD3AC7191D2C0950002B4BB0 /* shader_program.cpp in Sources */ = {isa = PBXBuildFile; fileRef = CD3AC7171D2C0950002B4BB0 /* shader_program.cpp */; };
 		CD3AC7261D2C0C63002B4BB0 /* object.cpp in Sources */ = {isa = PBXBuildFile; fileRef = CD3AC7241D2C0C63002B4BB0 /* object.cpp */; settings = {COMPILER_FLAGS = "-fvisibility=default"; }; };
 		CD62FCF72290DC9000376440 /* helper.hpp in Headers */ = {isa = PBXBuildFile; fileRef = CD62FCF52290DC9000376440 /* helper.hpp */; };
-		CD62FCF82290DC9000376440 /* helper.cxx in Sources */ = {isa = PBXBuildFile; fileRef = CD62FCF62290DC9000376440 /* helper.cxx */; };
+		CD62FCF82290DC9000376440 /* opengl_manager.cxx in Sources */ = {isa = PBXBuildFile; fileRef = CD62FCF62290DC9000376440 /* opengl_manager.cxx */; };
 		CD62FCFA2290E2E500376440 /* OpenGL.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CD62FCF92290E2E500376440 /* OpenGL.framework */; };
 		CD62FD062291970F00376440 /* libgameutils.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = CD62FD052291970F00376440 /* libgameutils.dylib */; };
 		CD62FD1E2292412900376440 /* renderer.cxx in Sources */ = {isa = PBXBuildFile; fileRef = CD62FD1C2292412900376440 /* renderer.cxx */; settings = {COMPILER_FLAGS = "-fvisibility=default"; }; };
@@ -88,7 +88,7 @@
 		CD3AC7241D2C0C63002B4BB0 /* object.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = object.cpp; sourceTree = "<group>"; };
 		CD62FCD722904AD100376440 /* GoogleMock.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = GoogleMock.xcodeproj; path = "../../gmock-xcode-master/GoogleMock.xcodeproj"; sourceTree = "<group>"; };
 		CD62FCF52290DC9000376440 /* helper.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = helper.hpp; sourceTree = "<group>"; };
-		CD62FCF62290DC9000376440 /* helper.cxx */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = helper.cxx; sourceTree = "<group>"; };
+		CD62FCF62290DC9000376440 /* opengl_manager.cxx */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = opengl_manager.cxx; sourceTree = "<group>"; };
 		CD62FCF92290E2E500376440 /* OpenGL.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = OpenGL.framework; path = System/Library/Frameworks/OpenGL.framework; sourceTree = SDKROOT; };
 		CD62FD052291970F00376440 /* libgameutils.dylib */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; path = libgameutils.dylib; sourceTree = BUILT_PRODUCTS_DIR; };
 		CD62FD1C2292412900376440 /* renderer.cxx */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = renderer.cxx; sourceTree = "<group>"; };
@@ -131,7 +131,7 @@
 			children = (
 				CDED9C5322A465DB00AE5CE5 /* opengl_renderer.h */,
 				CD62FD212292C76B00376440 /* opengl_renderer.cxx */,
-				CD62FCF62290DC9000376440 /* helper.cxx */,
+				CD62FCF62290DC9000376440 /* opengl_manager.cxx */,
 				CD1C840D2299B81500825C4E /* error_formatter.cxx */,
 			);
 			path = openGL;
@@ -401,7 +401,7 @@
 				CD3AC6F81D2C0518002B4BB0 /* texture.cpp in Sources */,
 				CD3AC7261D2C0C63002B4BB0 /* object.cpp in Sources */,
 				CD1C83E922998E2600825C4E /* manager.cxx in Sources */,
-				CD62FCF82290DC9000376440 /* helper.cxx in Sources */,
+				CD62FCF82290DC9000376440 /* opengl_manager.cxx in Sources */,
 				CD62FD232292C76B00376440 /* opengl_renderer.cxx in Sources */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;

+ 1 - 1
graphics/include/game/graphics/shader.hpp

@@ -13,7 +13,7 @@
 
 namespace graphics {
   struct shader : public identity<shader> {
-    shader(shaders::type, std::string const &);
+    shader(unsigned int id, shaders::type, std::string const &);
 
     shaders::type type;
     std::string path;

+ 1 - 1
graphics/include/game/graphics/shader_program.hpp

@@ -13,7 +13,7 @@
 
 namespace graphics {
   struct shader_program : public identity<shader_program> {
-    shader_program(identity<shader>, identity<shader>);
+    shader_program(unsigned int id, identity<shader>, identity<shader>);
 
     void activate() const;
 

+ 86 - 78
graphics/src/openGL/helper.cxx

@@ -7,6 +7,7 @@
 //
 
 #include "helper.hpp"
+#include "opengl_renderer.h"
 
 #include <iostream>
 #include <memory>
@@ -20,6 +21,7 @@
 
 #include "game/graphics/material.hpp"
 #include "game/graphics/shader.hpp"
+#include "game/graphics/shader_program.hpp"
 #include "game/util/env.hpp"
 #include "game/util/files.hpp"
 #include "game/util/time.hpp"
@@ -28,18 +30,43 @@ namespace graphics {
   extern void print_shader_error(GLuint, std::string const &);
   extern void print_shader_program_error(GLuint, std::string const &,
                                          std::string const &);
+
+  struct file_read_error : std::runtime_error {
+    using std::runtime_error::runtime_error;
+  };
+
+  struct compilation_error : std::runtime_error {
+    using std::runtime_error::runtime_error;
+  };
+
+  struct linker_error : std::runtime_error {
+    using std::runtime_error::runtime_error;
+  };
 }
 
-namespace graphics { namespace textures {
-  static int glfmt(format color_fmt) {
+using namespace graphics;
+
+namespace {
+  int glfmt(textures::format color_fmt) {
     switch (color_fmt) {
-    case format::RGB:
+    case textures::format::RGB:
       return GL_RGB;
-    case format::RGBA:
+    case textures::format::RGBA:
       return GL_RGBA;
     }
   }
 
+  int gltype(shaders::type tp) {
+    switch (tp) {
+    case shaders::type::FRAGMENT:
+      return GL_FRAGMENT_SHADER;
+    case shaders::type::VERTEX:
+      return GL_VERTEX_SHADER;
+    }
+  }
+}
+
+namespace graphics { namespace textures {
   unsigned int init(format color_fmt, math::vec2i dimension,
                     void const * data) {
     unsigned int id;
@@ -107,91 +134,72 @@ namespace graphics { namespace textures {
   }
 }}
 
-namespace graphics { namespace shaders {
-  struct file_read_error : std::runtime_error {
-    using std::runtime_error::runtime_error;
-  };
-
-  struct compilation_error : std::runtime_error {
-    using std::runtime_error::runtime_error;
-  };
-
-  struct linker_error : std::runtime_error {
-    using std::runtime_error::runtime_error;
-  };
+shader opengl_manager::compile(shaders::type tp,
+                               std::string const & path) const {
+  std::unique_ptr<char const[]> buffer;
 
-  static int gltype(type tp) {
-    switch (tp) {
-    case type::FRAGMENT:
-      return GL_FRAGMENT_SHADER;
-    case type::VERTEX:
-      return GL_VERTEX_SHADER;
-    }
+  // 1. Load the vertex shader code (text file) to a new memory buffer
+  std::string const abs_path = env::resource_file(path);
+  if (!(buffer = files::load(abs_path))) {
+    throw file_read_error("Could not load shader file " + abs_path);
   }
 
-  unsigned int init(type tp, std::string const & path) {
-    std::unique_ptr<char const[]> buffer;
-
-    // 1. Load the vertex shader code (text file) to a new memory buffer
-    std::string const abs_path = env::resource_file(path);
-    if (!(buffer = files::load(abs_path))) {
-      throw file_read_error("Could not load shader file " + abs_path);
-    }
-
-    // 2. Create a new shader ID
-    // GL_VERTEX_SHADER or GL_FRAGMENT_SHADER
-    unsigned int id = glCreateShader(gltype(tp));
+  // 2. Create a new shader ID
+  // GL_VERTEX_SHADER or GL_FRAGMENT_SHADER
+  unsigned int id = glCreateShader(gltype(tp));
 
-    // 3. Associate the shader code with the new shader ID
-    char const * buffer_ptr = buffer.get();
-    glShaderSource(id, 1, &buffer_ptr, NULL);
+  // 3. Associate the shader code with the new shader ID
+  char const * buffer_ptr = buffer.get();
+  glShaderSource(id, 1, &buffer_ptr, NULL);
 
-    // 4. Compile the shader (the shader compiler is built in to your graphics
-    //    card driver)
-    glCompileShader(id);
+  // 4. Compile the shader (the shader compiler is built in to your graphics
+  //    card driver)
+  glCompileShader(id);
 
-    // 5. Check for compile errors
-    int return_code;
-    glGetShaderiv(id, GL_COMPILE_STATUS, &return_code);
+  // 5. Check for compile errors
+  int return_code;
+  glGetShaderiv(id, GL_COMPILE_STATUS, &return_code);
 
-    if (return_code != GL_TRUE) {
-      print_shader_error(id, abs_path);
-      throw compilation_error("Could not compile the shader file");
-    }
-    return id;
+  if (return_code != GL_TRUE) {
+    print_shader_error(id, abs_path);
+    throw compilation_error("Could not compile the shader file");
   }
 
-  unsigned int init(identity<shader> const & fragmentShader,
-                    identity<shader> const & vertexShader) {
-    // 9. Create a new shader program ID
-    unsigned int id = glCreateProgram();
-
-    // 10. Attach the vertex and fragment shaders to the new shader program
-    glAttachShader(id, vertexShader.id);
-    glAttachShader(id, fragmentShader.id);
-
-    // 11. Do some other advanced stuff we'll do later on (like setting generic
-    // vertex attrib locations)
-    glBindAttribLocation(id, 0, "a_position");
-    glBindAttribLocation(id, 1, "a_color");
-    glBindAttribLocation(id, 2, "a_texCoords");
-    glBindAttribLocation(id, 3, "a_normal");
-
-    // 12. Link the program
-    glLinkProgram(id);
-
-    // 13. Check for link errors
-    int return_code;
-    glGetProgramiv(id, GL_LINK_STATUS, &return_code);
-
-    if (return_code != GL_TRUE) {
-      //      print_shader_program_error(id, fragmentShader.actual().path,
-      //                                 vertexShader.actual().path);
-      throw linker_error("Could not link shader program");
-    }
-    return id;
+  return shader{id, tp, path};
+}
+
+shader_program opengl_manager::compile(identity<shader> fragmentShader,
+                                       identity<shader> vertexShader) const {
+  // 9. Create a new shader program ID
+  unsigned int id = glCreateProgram();
+
+  // 10. Attach the vertex and fragment shaders to the new shader program
+  glAttachShader(id, vertexShader.id);
+  glAttachShader(id, fragmentShader.id);
+
+  // 11. Do some other advanced stuff we'll do later on (like setting generic
+  // vertex attrib locations)
+  glBindAttribLocation(id, 0, "a_position");
+  glBindAttribLocation(id, 1, "a_color");
+  glBindAttribLocation(id, 2, "a_texCoords");
+  glBindAttribLocation(id, 3, "a_normal");
+
+  // 12. Link the program
+  glLinkProgram(id);
+
+  // 13. Check for link errors
+  int return_code;
+  glGetProgramiv(id, GL_LINK_STATUS, &return_code);
+
+  if (return_code != GL_TRUE) {
+    //      print_shader_program_error(id, fragmentShader.actual().path,
+    //                                 vertexShader.actual().path);
+    throw linker_error("Could not link shader program");
   }
+  return shader_program{id, fragmentShader, vertexShader};
+}
 
+namespace graphics { namespace shaders {
   void activate(identity<shader_program> program) {
     // 100. Use the shader program ID to "turn it on" for all subsequent drawing
     glUseProgram(program.id);

+ 2 - 4
graphics/src/shader.cpp

@@ -7,9 +7,7 @@
 
 #include "game/graphics/shader.hpp"
 
-#include "helper.hpp"
-
 using namespace graphics;
 
-shader::shader(shaders::type type, std::string const & path)
-    : identity<shader>(shaders::init(type, path)), type(type), path(path) {}
+shader::shader(unsigned int id, shaders::type type, std::string const & path)
+    : identity<shader>(id), type(type), path(path) {}

+ 4 - 4
graphics/src/shader_program.cpp

@@ -7,13 +7,13 @@
 
 #include "game/graphics/shader_program.hpp"
 
-#include "game/graphics/shader.hpp"
 #include "helper.hpp"
 
 using namespace graphics;
 
-shader_program::shader_program(identity<shader> frag, identity<shader> vert)
-    : identity<shader_program>(shaders::init(frag, vert)),
-      fragment_shader(frag), vertex_shader(vert) {}
+shader_program::shader_program(unsigned int id, identity<shader> frag,
+                               identity<shader> vert)
+    : identity<shader_program>(id), fragment_shader(frag), vertex_shader(vert) {
+}
 
 void shader_program::activate() const { shaders::activate(id); }