diff --git a/Escape-the-Dawn.sln b/Escape-the-Dawn.sln index db93554..75bbb7b 100644 --- a/Escape-the-Dawn.sln +++ b/Escape-the-Dawn.sln @@ -5,6 +5,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Escape-the-Dawn", "Escape-t EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Tests", "Tests\Tests.vcxproj", "{B9A8F4AA-BE85-45EA-84DD-652D13DD22BE}" EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Executable", "Executable\Executable.vcxproj", "{A9755CAA-62DC-442D-B82C-F548546CFD38}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Win32 = Debug|Win32 @@ -19,6 +21,10 @@ Global {B9A8F4AA-BE85-45EA-84DD-652D13DD22BE}.Debug|Win32.Build.0 = Debug|Win32 {B9A8F4AA-BE85-45EA-84DD-652D13DD22BE}.Release|Win32.ActiveCfg = Release|Win32 {B9A8F4AA-BE85-45EA-84DD-652D13DD22BE}.Release|Win32.Build.0 = Release|Win32 + {A9755CAA-62DC-442D-B82C-F548546CFD38}.Debug|Win32.ActiveCfg = Debug|Win32 + {A9755CAA-62DC-442D-B82C-F548546CFD38}.Debug|Win32.Build.0 = Debug|Win32 + {A9755CAA-62DC-442D-B82C-F548546CFD38}.Release|Win32.ActiveCfg = Release|Win32 + {A9755CAA-62DC-442D-B82C-F548546CFD38}.Release|Win32.Build.0 = Release|Win32 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/Escape-the-Dawn/Components/Transform.h b/Escape-the-Dawn/Components/TransformComponent.h similarity index 100% rename from Escape-the-Dawn/Components/Transform.h rename to Escape-the-Dawn/Components/TransformComponent.h diff --git a/Escape-the-Dawn/Engine.h b/Escape-the-Dawn/Engine.h new file mode 100644 index 0000000..a93eb0f --- /dev/null +++ b/Escape-the-Dawn/Engine.h @@ -0,0 +1,63 @@ +#include +#include + +#include +#define GLFW_INCLUDE_GLU +#include +#include + +#include "logging.h" +#include "glerror.h" + +#include "World.h" + +class Engine +{ +public: + Engine(int argc, char* argv[]) + { + // Initialize GLFW + if (!glfwInit()) { + LOG_ERROR("GLFW: Initialization failed"); + exit(EXIT_FAILURE); + } + + // Create a window + m_Window = glfwCreateWindow(1280, 720, "OpenGL", nullptr, nullptr); + if (!m_Window) { + LOG_ERROR("GLFW: Failed to create window"); + exit(EXIT_FAILURE); + } + glfwMakeContextCurrent(m_Window); + + // GL version info + glGetIntegerv(GL_MAJOR_VERSION, &glVersion[0]); + glGetIntegerv(GL_MINOR_VERSION, &glVersion[1]); + glVendor = (GLchar*)glGetString(GL_VENDOR); + std::stringstream ss; + ss << glVendor << " OpenGL " << glVersion[0] << "." << glVersion[1]; +#ifdef DEBUG + ss << " DEBUG"; +#endif + LOG_INFO(ss.str().c_str()); + glfwSetWindowTitle(m_Window, ss.str().c_str()); + + // Initialize GLEW + if (glewInit() != GLEW_OK) { + LOG_ERROR("GLEW: Initialization failed"); + exit(EXIT_FAILURE); + } + } + + bool Running() const { return !glfwWindowShouldClose(m_Window); } + + void Tick() + { + glfwPollEvents(); + } + +private: + GLFWwindow* m_Window; + GLint glVersion[2]; + GLchar* glVendor; +}; \ No newline at end of file diff --git a/Escape-the-Dawn/Escape-the-Dawn.vcxproj b/Escape-the-Dawn/Escape-the-Dawn.vcxproj index 246db81..133bbc3 100644 --- a/Escape-the-Dawn/Escape-the-Dawn.vcxproj +++ b/Escape-the-Dawn/Escape-the-Dawn.vcxproj @@ -16,13 +16,13 @@ - Application + StaticLibrary true MultiByte v110 - Application + StaticLibrary false true MultiByte @@ -42,7 +42,7 @@ $(SolutionDir)\Libraries\glew-1.10.0\lib\Debug\Win32;$(SolutionDir)\Libraries\glfw-3.0.4\lib\Debug;$(LibraryPath) $(SolutionDir)bin\ - $(SolutionDir)build\$(Configuration)\ + $(SolutionDir)obj\$(ProjectName)\ $(ProjectName)-$(Configuration) $(ProjectDir);$(SolutionDir)\Libraries;$(SolutionDir)\Libraries\glew-1.10.0\include;$(SolutionDir)\Libraries\glfw-3.0.4\include;$(SolutionDir)\Libraries\glm-0.9.5.2;$(IncludePath) @@ -52,7 +52,7 @@ $(SolutionDir)\Libraries\glew-1.10.0\lib\Release\Win32;$(SolutionDir)\Libraries\glfw-3.0.4\lib\Release;$(LibraryPath) $(SolutionDir)bin\ - $(SolutionDir)build\$(Configuration)\ + $(SolutionDir)obj\$(ProjectName)\ $(ProjectName)-$(Configuration) @@ -69,6 +69,12 @@ + + opengl32.lib;glu32.lib;glew32sd.lib;glfw3.lib + + + + @@ -86,8 +92,12 @@ true opengl32.lib;glu32.lib;glew32s.lib;glfw3.lib;%(AdditionalDependencies) + + opengl32.lib;glu32.lib;glew32s.lib;glfw3.lib; + + @@ -125,6 +135,7 @@ + diff --git a/Escape-the-Dawn/Escape-the-Dawn.vcxproj.filters b/Escape-the-Dawn/Escape-the-Dawn.vcxproj.filters index 48d76c2..65cd581 100644 --- a/Escape-the-Dawn/Escape-the-Dawn.vcxproj.filters +++ b/Escape-the-Dawn/Escape-the-Dawn.vcxproj.filters @@ -26,6 +26,7 @@ Systems + @@ -58,10 +59,11 @@ Systems + Components - + Components diff --git a/Escape-the-Dawn/Renderer/Renderer.cpp b/Escape-the-Dawn/Renderer/Renderer.cpp index 62d014a..2821bb5 100644 --- a/Escape-the-Dawn/Renderer/Renderer.cpp +++ b/Escape-the-Dawn/Renderer/Renderer.cpp @@ -2,7 +2,7 @@ Renderer::Renderer() { - + glEnable(GL_DEPTH_TEST); } void Renderer::Draw() @@ -10,7 +10,7 @@ void Renderer::Draw() glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glClearColor(1.0f, 1.0f, 0.0f, 1.0f); - glUseProgram(shaderProgram); + m_ShaderProgram->Bind(); } void Renderer::DrawText() @@ -32,65 +32,7 @@ void Renderer::AddObjectToDraw() void Renderer::LoadContent() { - glEnable(GL_DEPTH_TEST); - LOG_INFO("Compiling Shader"); - - GLuint vertexShader = CompileShader(GL_VERTEX_SHADER, "Shaders/Vertex.glsl"); - GLuint fragmentShader = CompileShader(GL_FRAGMENT_SHADER, "Shaders\Fragment.glsl"); - - shaderProgram = glCreateProgram(); - glAttachShader(shaderProgram, vertexShader); - glAttachShader(shaderProgram, fragmentShader); - LOG_INFO("Linking shader program..."); - glLinkProgram(shaderProgram); - if(GLERROR("glLinkProgram")) - exit(EXIT_FAILURE); - + m_ShaderProgram->AddShader(std::unique_ptr(new VertexShader("Shaders/Vertex.glsl"))); + m_ShaderProgram->AddShader(std::unique_ptr(new FragmentShader("Shaders/Fragment.glsl"))); + m_ShaderProgram->Link(); } - -GLuint Renderer::CompileShader(GLenum shaderType, std::string fileName) -{ - std::string shaderFile; - std::ifstream in(fileName, std::ios::in); - - if(!in) - { - LOG_ERROR("Error: Failed to open shader file %s", fileName); - return 0; - } - in.seekg(0, std::ios::end); - shaderFile.resize((int)in.tellg()); - in.seekg(0, std::ios::beg); - in.read(&shaderFile[0], shaderFile.size()); - in.close(); - - GLuint shader = glCreateShader(shaderType); //GL_VERTEX_SHADER, GL_FRAGMENT_SHADER - if(GLERROR("glCreateShader")) - return 0; - - const GLchar* shaderFiles = shaderFile.c_str(); - const GLint length = shaderFile.length(); - glShaderSource(shader, 1, &shaderFiles, &length); - if(GLERROR("glShaderSource")) - return 0; - - glCompileShader(shader); - GLint compileStatus; - glGetShaderiv(shader, GL_COMPILE_STATUS, &compileStatus); - if(compileStatus != GL_TRUE) - { - GLsizei infoLogLength; - glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infoLogLength); - GLchar* infolog = new GLchar[infoLogLength]; - glGetShaderInfoLog(shader, infoLogLength, &infoLogLength, infolog); - std::cerr << infolog << std::endl; - delete[] infolog; - } - - if(GLERROR("glCompileShader")) - return 0; - - return shader; - -} - diff --git a/Escape-the-Dawn/Renderer/Renderer.h b/Escape-the-Dawn/Renderer/Renderer.h index a7224d2..77f37f5 100644 --- a/Escape-the-Dawn/Renderer/Renderer.h +++ b/Escape-the-Dawn/Renderer/Renderer.h @@ -16,12 +16,12 @@ #include #include "glerror.h" - +#include "ShaderProgram.h" class Renderer { public: - GLuint shaderProgram; + std::shared_ptr m_ShaderProgram; GLuint VAO; std::vector> Vertices; diff --git a/Escape-the-Dawn/ShaderProgram.cpp b/Escape-the-Dawn/ShaderProgram.cpp new file mode 100644 index 0000000..2aee783 --- /dev/null +++ b/Escape-the-Dawn/ShaderProgram.cpp @@ -0,0 +1,149 @@ +#include "ShaderProgram.h" + +GLuint Shader::CompileShader(GLenum shaderType, std::string fileName) +{ + LOG_INFO("Compiling shader \"%s\"", fileName.c_str()); + + std::string shaderFile; + std::ifstream in(fileName, std::ios::in); + if(!in) + { + LOG_ERROR("Error: Failed to open shader file \"%s\"", fileName.c_str()); + return 0; + } + in.seekg(0, std::ios::end); + shaderFile.resize((int)in.tellg()); + in.seekg(0, std::ios::beg); + in.read(&shaderFile[0], shaderFile.size()); + in.close(); + + GLuint shader = glCreateShader(shaderType); + if(GLERROR("glCreateShader")) + return 0; + + const GLchar* shaderFiles = shaderFile.c_str(); + const GLint length = shaderFile.length(); + glShaderSource(shader, 1, &shaderFiles, &length); + if(GLERROR("glShaderSource")) + return 0; + + glCompileShader(shader); + + GLint compileStatus; + glGetShaderiv(shader, GL_COMPILE_STATUS, &compileStatus); + if(compileStatus != GL_TRUE) + { + LOG_ERROR("Shader compilation failed"); + GLsizei infoLogLength; + glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infoLogLength); + GLchar* infolog = new GLchar[infoLogLength]; + glGetShaderInfoLog(shader, infoLogLength, &infoLogLength, infolog); + LOG_ERROR(infolog); + delete[] infolog; + } + + if(GLERROR("glCompileShader")) + return 0; + + return shader; +} + +Shader::Shader(GLenum shaderType, std::string fileName) : m_ShaderType(shaderType), m_FileName(fileName) +{ + m_ShaderHandle = 0; +} + +Shader::~Shader() +{ + glDeleteShader(m_ShaderHandle); +} + +GLuint Shader::Compile() +{ + m_ShaderHandle = CompileShader(m_ShaderType, m_FileName); + return m_ShaderHandle; +} + +GLenum Shader::GetType() const +{ + return m_ShaderType; +} + +std::string Shader::GetFileName() const +{ + return m_FileName; +} + +GLuint Shader::GetHandle() const +{ + return m_ShaderHandle; +} + +bool Shader::IsCompiled() const +{ + return m_ShaderHandle != 0; +} + +ShaderProgram::ShaderProgram() +{ + Initialize(); +} + +ShaderProgram::ShaderProgram(std::string vertexShaderFile, std::string fragmentShaderFile) +{ + AddShader(std::unique_ptr(new VertexShader(vertexShaderFile))); + AddShader(std::unique_ptr(new VertexShader(fragmentShaderFile))); + Initialize(); +} + +ShaderProgram::~ShaderProgram() +{ + Unbind(); + glDeleteProgram(m_ShaderProgramHandle); +} + +void ShaderProgram::AddShader(std::unique_ptr shader) +{ + if (!shader->IsCompiled()) { + shader->Compile(); + } + + m_Shaders.push_back(std::move(shader)); +} + +GLuint ShaderProgram::Link() +{ + LOG_INFO("Linking shader program"); + m_ShaderProgramHandle = glCreateProgram(); + for (auto &shader : m_Shaders) { + glAttachShader(m_ShaderProgramHandle, shader->GetHandle()); + } + glLinkProgram(m_ShaderProgramHandle); + if (GLERROR("glLinkProgram")) + return 0; + + for (auto &shader : m_Shaders) { + shader.release(); + } + m_Shaders.clear(); + + return m_ShaderProgramHandle; +} + +void ShaderProgram::Bind() +{ + if (m_ShaderProgramHandle == 0) + return; + + glUseProgram(m_ShaderProgramHandle); +} + +void ShaderProgram::Unbind() +{ + glActiveShaderProgram(0, 0); +} + +void ShaderProgram::Initialize() +{ + m_ShaderProgramHandle = 0; +} diff --git a/Escape-the-Dawn/ShaderProgram.h b/Escape-the-Dawn/ShaderProgram.h new file mode 100644 index 0000000..e46d89d --- /dev/null +++ b/Escape-the-Dawn/ShaderProgram.h @@ -0,0 +1,91 @@ +#ifndef ShaderProgram_h__ +#define ShaderProgram_h__ + +#include +#include +#include +#include + +#define _CRT_SECURE_NO_WARNINGS +#include +#define GLFW_INCLUDE_GLU +#include +#include + +#include "glerror.h" + +class Shader +{ +public: + static GLuint CompileShader(GLenum shaderType, std::string fileName); + + Shader(GLenum shaderType, std::string fileName); + + virtual ~Shader(); + + GLuint Compile(); + + GLenum GetType() const; + std::string GetFileName() const; + GLuint GetHandle() const; + bool IsCompiled() const; + +protected: + GLenum m_ShaderType; + std::string m_FileName; + GLint m_ShaderHandle; +}; + +template +class ShaderType : public Shader +{ +public: + ShaderType(std::string fileName) + : Shader(SHADERTYPE, fileName) { } +}; + +class VertexShader : public ShaderType +{ +public: + VertexShader(std::string fileName) + : ShaderType(fileName) { } +}; + +class FragmentShader : public ShaderType +{ +public: + FragmentShader(std::string fileName) + : ShaderType(fileName) { } +}; + +class GeometryShader : public ShaderType +{ +public: + GeometryShader(std::string fileName) + : ShaderType(fileName) { } +}; + +class ShaderProgram +{ +public: + ShaderProgram(); + ~ShaderProgram(); + + ShaderProgram(std::string vertexShaderFile, std::string fragmentShaderFile); + + void AddShader(std::unique_ptr shader); + + GLuint Link(); + + void Bind(); + + void Unbind(); + +private: + GLuint m_ShaderProgramHandle; + std::vector> m_Shaders; + + void Initialize(); +}; + +#endif // ShaderProgram_h__ \ No newline at end of file diff --git a/Escape-the-Dawn/Shaders/Fragment.glsl b/Escape-the-Dawn/Shaders/Fragment.glsl index e69de29..e71149a 100644 --- a/Escape-the-Dawn/Shaders/Fragment.glsl +++ b/Escape-the-Dawn/Shaders/Fragment.glsl @@ -0,0 +1,18 @@ +#version 440 + +uniform mat4 MVP; +uniform sampler2D texture0; + +in VertexData { + vec3 Position; + vec3 Color; + vec2 TextureCoord; +} Input; + +out vec4 FragmentColor; + +void main() +{ + vec4 texel = texture2D(texture0, Input.TextureCoord); + FragmentColor = texel * vec4(Input.Color, 0); +} \ No newline at end of file diff --git a/Escape-the-Dawn/Shaders/Vertex.glsl b/Escape-the-Dawn/Shaders/Vertex.glsl index e69de29..92b8723 100644 --- a/Escape-the-Dawn/Shaders/Vertex.glsl +++ b/Escape-the-Dawn/Shaders/Vertex.glsl @@ -0,0 +1,22 @@ +#version 440 + +uniform mat4 MVP; + +layout(location = 0) in vec3 Position; +layout(location = 1) in vec3 Normal; +layout(location = 2) in vec2 TextureCoord; + +out VertexData { + vec3 Position; + vec3 Normal; + vec2 TextureCoord; +} Output; + +void main() +{ + gl_Position = MVP * vec4(Position, 1.0); + + Output.Position = Position; + Output.Normal = Normal; + Output.TextureCoord = TextureCoord; +} \ No newline at end of file diff --git a/Escape-the-Dawn/Systems/CollisionSystem.h b/Escape-the-Dawn/Systems/CollisionSystem.h index c5c1bdd..008115a 100644 --- a/Escape-the-Dawn/Systems/CollisionSystem.h +++ b/Escape-the-Dawn/Systems/CollisionSystem.h @@ -4,7 +4,7 @@ #include "System.h" #include "logging.h" -#include "Components/Transform.h" +#include "Components/TransformComponent.h" namespace Systems diff --git a/Escape-the-Dawn/main.cpp b/Escape-the-Dawn/main.cpp deleted file mode 100644 index c9bc467..0000000 --- a/Escape-the-Dawn/main.cpp +++ /dev/null @@ -1,62 +0,0 @@ -#include -#include - -#include -#define GLFW_INCLUDE_GLU -#include -#include - -#include "logging.h" -#include "glerror.h" - -#include "World.h" - -GLFWwindow* window; -GLint glVersion[2]; -GLchar* glVendor; - -int main(int argc, char* argv[]) -{ - // Initialize GLFW - if (!glfwInit()) - { - LOG_ERROR("GLFW: Initialization failed"); - return 1; - } - - // Create a window - window = glfwCreateWindow(1280, 720, "OpenGL", nullptr, nullptr); - if (!window) - { - LOG_ERROR("GLFW: Failed to create window"); - return 1; - } - glfwMakeContextCurrent(window); - - // GL version info - glGetIntegerv(GL_MAJOR_VERSION, &glVersion[0]); - glGetIntegerv(GL_MINOR_VERSION, &glVersion[1]); - glVendor = (GLchar*)glGetString(GL_VENDOR); - std::stringstream ss; - ss << glVendor << " OpenGL " << glVersion[0] << "." << glVersion[1]; -#ifdef DEBUG - ss << " DEBUG"; -#endif - LOG_INFO(ss.str().c_str()); - glfwSetWindowTitle(window, ss.str().c_str()); - - // Initialize GLEW - if (glewInit() != GLEW_OK) - { - LOG_ERROR("GLEW: Initialization failed"); - return 1; - } - - // Main loop - while (!glfwWindowShouldClose(window)) - { - glfwPollEvents(); - } - - return 0; -} \ No newline at end of file diff --git a/Executable/Executable.vcxproj b/Executable/Executable.vcxproj new file mode 100644 index 0000000..249515e --- /dev/null +++ b/Executable/Executable.vcxproj @@ -0,0 +1,90 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + + {A9755CAA-62DC-442D-B82C-F548546CFD38} + Executable + + + + Application + true + v110 + MultiByte + + + Application + false + v110 + true + MultiByte + + + + + + + + + + + + + $(SolutionDir)\Escape-the-Dawn;$(SolutionDir)\Libraries;$(SolutionDir)\Libraries\glew-1.10.0\include;$(SolutionDir)\Libraries\glfw-3.0.4\include;$(SolutionDir)\Libraries\glm-0.9.5.2;$(IncludePath) + $(SolutionDir)bin\ + $(SolutionName)-$(Configuration) + $(SolutionDir)obj\$(ProjectName)\ + + + $(SolutionDir)\Escape-the-Dawn;$(SolutionDir)\Libraries;$(SolutionDir)\Libraries\glew-1.10.0\include;$(SolutionDir)\Libraries\glfw-3.0.4\include;$(SolutionDir)\Libraries\glm-0.9.5.2;$(IncludePath) + $(SolutionDir)bin\ + $(SolutionName)-$(Configuration) + $(SolutionDir)obj\$(ProjectName)\ + + + + Level3 + Disabled + true + GLEW_STATIC;DEBUG;_MBCS;%(PreprocessorDefinitions) + + + true + + + + + Level3 + MaxSpeed + true + true + true + GLEW_STATIC;_MBCS;%(PreprocessorDefinitions) + + + true + true + true + + + + + + + + {fe405cfa-8fce-4867-92cf-797e73b36482} + + + + + + \ No newline at end of file diff --git a/Executable/Executable.vcxproj.filters b/Executable/Executable.vcxproj.filters new file mode 100644 index 0000000..8755a3a --- /dev/null +++ b/Executable/Executable.vcxproj.filters @@ -0,0 +1,22 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + Source Files + + + \ No newline at end of file diff --git a/Executable/main.cpp b/Executable/main.cpp new file mode 100644 index 0000000..8b6c4e5 --- /dev/null +++ b/Executable/main.cpp @@ -0,0 +1,10 @@ +#include "Engine.h" + +int main(int argc, char* argv[]) +{ + Engine engine(argc, argv); + while (engine.Running()) + engine.Tick(); + + return EXIT_SUCCESS; +} \ No newline at end of file diff --git a/Tests/Tests.vcxproj b/Tests/Tests.vcxproj index b6294b2..75763b5 100644 --- a/Tests/Tests.vcxproj +++ b/Tests/Tests.vcxproj @@ -42,11 +42,13 @@ $(SolutionDir)\Escape-the-Dawn\;$(SolutionDir)\Libraries;$(SolutionDir)\Libraries\glew-1.10.0\include;$(SolutionDir)\Libraries\glfw-3.0.4\include;$(SolutionDir)\Libraries\glm-0.9.5.2;$(BOOST_ROOT);$(IncludePath) $(BOOST_ROOT)\lib32-msvc-11.0;$(LibraryPath) $(ProjectDir)$(Configuration)\ + $(SolutionDir)obj\$(ProjectName)\ $(SolutionDir)\Escape-the-Dawn\;$(SolutionDir)\Libraries;$(SolutionDir)\Libraries\glew-1.10.0\include;$(SolutionDir)\Libraries\glfw-3.0.4\include;$(SolutionDir)\Libraries\glm-0.9.5.2;$(BOOST_ROOT);$(IncludePath) $(BOOST_ROOT)\lib32-msvc-11.0;$(LibraryPath) $(ProjectDir)$(Configuration)\ + $(SolutionDir)obj\$(ProjectName)\ @@ -83,11 +85,6 @@ {fe405cfa-8fce-4867-92cf-797e73b36482} - true - true - false - true - false diff --git a/Tests/main.cpp b/Tests/main.cpp index bc0a4f0..4668e93 100644 --- a/Tests/main.cpp +++ b/Tests/main.cpp @@ -1,5 +1,5 @@ #include "World.h" -#include "Components/Transform.h" +#include "Components/TransformComponent.h" #define BOOST_TEST_MODULE World #define BOOST_TEST_DYN_LINK