|
@@ -7,6 +7,7 @@
|
|
|
//
|
|
//
|
|
|
|
|
|
|
|
#include "helper.hpp"
|
|
#include "helper.hpp"
|
|
|
|
|
+#include "opengl_renderer.h"
|
|
|
|
|
|
|
|
#include <iostream>
|
|
#include <iostream>
|
|
|
#include <memory>
|
|
#include <memory>
|
|
@@ -20,6 +21,7 @@
|
|
|
|
|
|
|
|
#include "game/graphics/material.hpp"
|
|
#include "game/graphics/material.hpp"
|
|
|
#include "game/graphics/shader.hpp"
|
|
#include "game/graphics/shader.hpp"
|
|
|
|
|
+#include "game/graphics/shader_program.hpp"
|
|
|
#include "game/util/env.hpp"
|
|
#include "game/util/env.hpp"
|
|
|
#include "game/util/files.hpp"
|
|
#include "game/util/files.hpp"
|
|
|
#include "game/util/time.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_error(GLuint, std::string const &);
|
|
|
extern void print_shader_program_error(GLuint, std::string const &,
|
|
extern void print_shader_program_error(GLuint, std::string const &,
|
|
|
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) {
|
|
switch (color_fmt) {
|
|
|
- case format::RGB:
|
|
|
|
|
|
|
+ case textures::format::RGB:
|
|
|
return GL_RGB;
|
|
return GL_RGB;
|
|
|
- case format::RGBA:
|
|
|
|
|
|
|
+ case textures::format::RGBA:
|
|
|
return GL_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,
|
|
unsigned int init(format color_fmt, math::vec2i dimension,
|
|
|
void const * data) {
|
|
void const * data) {
|
|
|
unsigned int id;
|
|
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) {
|
|
void activate(identity<shader_program> program) {
|
|
|
// 100. Use the shader program ID to "turn it on" for all subsequent drawing
|
|
// 100. Use the shader program ID to "turn it on" for all subsequent drawing
|
|
|
glUseProgram(program.id);
|
|
glUseProgram(program.id);
|