diff --git a/Engine/Engine.sln b/Engine/Engine.sln
new file mode 100644
index 0000000..58502f8
--- /dev/null
+++ b/Engine/Engine.sln
@@ -0,0 +1,31 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 17
+VisualStudioVersion = 17.5.33516.290
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Engine", "Engine\Engine.vcxproj", "{3BEE640E-71B2-4D18-9D8C-8B6B85CAE21A}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|x64 = Debug|x64
+ Debug|x86 = Debug|x86
+ Release|x64 = Release|x64
+ Release|x86 = Release|x86
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {3BEE640E-71B2-4D18-9D8C-8B6B85CAE21A}.Debug|x64.ActiveCfg = Debug|x64
+ {3BEE640E-71B2-4D18-9D8C-8B6B85CAE21A}.Debug|x64.Build.0 = Debug|x64
+ {3BEE640E-71B2-4D18-9D8C-8B6B85CAE21A}.Debug|x86.ActiveCfg = Debug|Win32
+ {3BEE640E-71B2-4D18-9D8C-8B6B85CAE21A}.Debug|x86.Build.0 = Debug|Win32
+ {3BEE640E-71B2-4D18-9D8C-8B6B85CAE21A}.Release|x64.ActiveCfg = Release|x64
+ {3BEE640E-71B2-4D18-9D8C-8B6B85CAE21A}.Release|x64.Build.0 = Release|x64
+ {3BEE640E-71B2-4D18-9D8C-8B6B85CAE21A}.Release|x86.ActiveCfg = Release|Win32
+ {3BEE640E-71B2-4D18-9D8C-8B6B85CAE21A}.Release|x86.Build.0 = Release|Win32
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ SolutionGuid = {25B3C080-617C-4BEA-9F36-818FB47E657F}
+ EndGlobalSection
+EndGlobal
diff --git a/Engine/Engine/Engine.vcxproj b/Engine/Engine/Engine.vcxproj
new file mode 100644
index 0000000..93be4d1
--- /dev/null
+++ b/Engine/Engine/Engine.vcxproj
@@ -0,0 +1,158 @@
+
+
+
+
+ Debug
+ Win32
+
+
+ Release
+ Win32
+
+
+ Debug
+ x64
+
+
+ Release
+ x64
+
+
+
+ 16.0
+ Win32Proj
+ {3bee640e-71b2-4d18-9d8c-8b6b85cae21a}
+ Engine
+ 10.0
+
+
+
+ Application
+ true
+ v143
+ Unicode
+
+
+ Application
+ false
+ v143
+ true
+ Unicode
+
+
+ Application
+ true
+ v143
+ Unicode
+
+
+ Application
+ false
+ v143
+ true
+ Unicode
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ T:\Privat\Daniel\Selfmade\libraries\glad\include;T:\Privat\Daniel\Selfmade\libraries\glfw\include;$(IncludePath)
+ T:\Privat\Daniel\Selfmade\libraries\glfw\lib;$(LibraryPath)
+
+
+ C:\Users\Daniel\Documents\SelfmadeProgramme\libraries\glad\include;C:\Users\Daniel\Documents\SelfmadeProgramme\libraries\glfw\include;$(IncludePath)
+ C:\Users\Daniel\Documents\SelfmadeProgramme\libraries\glfw\lib;$(LibraryPath)
+
+
+
+ Level3
+ true
+ WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)
+ true
+
+
+ Console
+ true
+
+
+
+
+ Level3
+ true
+ true
+ true
+ WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)
+ true
+
+
+ Console
+ true
+ true
+ true
+
+
+
+
+ Level3
+ true
+ _DEBUG;_CONSOLE;%(PreprocessorDefinitions)
+ true
+
+
+ Console
+ true
+ glfw3.lib;opengl32.lib;%(AdditionalDependencies)
+
+
+
+
+ Level3
+ true
+ true
+ true
+ NDEBUG;_CONSOLE;%(PreprocessorDefinitions)
+ true
+
+
+ Console
+ true
+ true
+ true
+ glfw3.lib;opengl32.lib;%(AdditionalDependencies)
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Engine/Engine/Engine.vcxproj.filters b/Engine/Engine/Engine.vcxproj.filters
new file mode 100644
index 0000000..e12aec4
--- /dev/null
+++ b/Engine/Engine/Engine.vcxproj.filters
@@ -0,0 +1,51 @@
+
+
+
+
+ {4FC737F1-C7A5-4376-A066-2A32D752A2FF}
+ cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx
+
+
+ {93995380-89BD-4b04-88EB-625FBE52EBFB}
+ h;hh;hpp;hxx;h++;hm;inl;inc;ipp;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
+
+
+ Source Files
+
+
+ Source Files
+
+
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+
+
+ Resource Files
+
+
+
+
\ No newline at end of file
diff --git a/Engine/Engine/exceptions/IOException.h b/Engine/Engine/exceptions/IOException.h
new file mode 100644
index 0000000..8b70dbc
--- /dev/null
+++ b/Engine/Engine/exceptions/IOException.h
@@ -0,0 +1,22 @@
+#pragma once
+#include
+
+namespace Nebulix
+{
+ ///
+ /// This exception will be thrown if there is an error to do with its IO. For example opening the file
+ ///
+ class IOException : public std::runtime_error
+ {
+ public:
+ using runtime_error::runtime_error;
+
+ IOException() : runtime_error{ "ERROR::FILE::IO" } {}
+ ///
+ /// Overrides the default error message
+ ///
+ IOException(std::string message) : runtime_error{ message } {}
+
+ private:
+ };
+}
diff --git a/Engine/Engine/exceptions/shaders/CreateProgramException.h b/Engine/Engine/exceptions/shaders/CreateProgramException.h
new file mode 100644
index 0000000..22aaf8c
--- /dev/null
+++ b/Engine/Engine/exceptions/shaders/CreateProgramException.h
@@ -0,0 +1,15 @@
+#pragma once
+#include
+
+namespace Nebulix
+{
+ class CreateProgramException : public std::runtime_error
+ {
+ public:
+ using runtime_error::runtime_error;
+
+ CreateProgramException(std::string &message) : runtime_error{ "ERROR::SHADER::CREATE_PROGRAM\n" + message } {}
+
+ private:
+ };
+}
diff --git a/Engine/Engine/exceptions/shaders/ShaderCompileException.h b/Engine/Engine/exceptions/shaders/ShaderCompileException.h
new file mode 100644
index 0000000..ee5b18a
--- /dev/null
+++ b/Engine/Engine/exceptions/shaders/ShaderCompileException.h
@@ -0,0 +1,39 @@
+#pragma once
+#include
+#include "../../shaders/Enums.h"
+
+namespace Nebulix
+{
+ class ShaderCompileException: public std::exception
+ {
+ public:
+ ShaderCompileException() = delete;
+
+ ShaderCompileException(Nebulix::ShaderType shaderType, std::string compileMessage)
+ {
+ std::string shader;
+
+ switch (shaderType)
+ {
+ case Nebulix::ShaderType::Vertex:
+ shader = std::string{"VERTEX"};
+ break;
+ case Nebulix::ShaderType::Fragment:
+ shader = std::string{ "FRAGMENT" };
+ break;
+ default:
+ shader = std::string{ "UNKNOWN" };
+ break;
+ }
+ _message = "ERROR::SHADER::" + shader + "::COMPILATION_FAILED\n Error message -> " + compileMessage;
+ }
+
+ virtual const char* what() const override
+ {
+ return _message.c_str();
+ }
+
+ private:
+ std::string _message;
+ };
+}
diff --git a/Engine/Engine/main.cpp b/Engine/Engine/main.cpp
new file mode 100644
index 0000000..9bdaac2
--- /dev/null
+++ b/Engine/Engine/main.cpp
@@ -0,0 +1,131 @@
+#include
+#include
+#include
+#include
+#include
+
+#include "shaders/Shader.h"
+
+// Continue: https://learnopengl.com/Getting-started/Shaders
+// Chapter: Not yet started
+//
+
+
+//
+// HOW TO redirect error output to file
+// Maybe it is possible to redirect to another stream object which adds infos like thread id/time etc.?
+//
+// std::ofstream errorFile("error.log");
+// std::streambuf* originalCerrBuffer = std::cerr.rdbuf(); // Save original buffer
+// Redirect cerr to the error file
+// std::cerr.rdbuf(errorFile.rdbuf());
+
+#define WINDOW_WIDTH 800
+#define WINDOW_HEIGHT 600
+
+
+void OnWindowResize(GLFWwindow* window, int width, int height)
+{
+ glViewport(0, 0, width, height);
+}
+
+void ProcessInput(GLFWwindow* window)
+{
+ if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS)
+ glfwSetWindowShouldClose(window, true);
+}
+
+int main()
+{
+ glfwInit();
+ glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
+ glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
+ glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
+
+ GLFWwindow* window = glfwCreateWindow(WINDOW_WIDTH, WINDOW_HEIGHT, "Henlo worl", nullptr, nullptr);
+
+ if (window == nullptr)
+ {
+ std::cerr << "Failed to create GLFW window";
+ glfwTerminate();
+
+ return -1;
+ }
+
+ glfwMakeContextCurrent(window);
+
+ if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress))
+ {
+ std::cerr << "Failed to initialise GLAD";
+ return -1;
+ }
+
+ OnWindowResize(window, WINDOW_WIDTH, WINDOW_HEIGHT);
+ glfwSetFramebufferSizeCallback(window, OnWindowResize);
+
+ GLfloat vertices[] = {
+ 0.5f, 0.5f, 0.0f, // top right
+ 0.5f, -0.5f, 0.0f, // bottom right
+ -0.5f, -0.5f, 0.0f, // bottom left
+ -0.5f, 0.5f, 0.0f // top left
+ };
+ GLuint indices[]{
+ 0, 1, 3,
+ 1, 2, 3
+ };
+
+ GLuint vertexBufferObject, elementBufferObject, vertexArrayObject;
+ glGenVertexArrays(1, &vertexArrayObject);
+ glGenBuffers(1, &vertexBufferObject);
+ glGenBuffers(1, &elementBufferObject);
+
+ glBindVertexArray(vertexArrayObject);
+
+ glBindBuffer(GL_ARRAY_BUFFER, vertexBufferObject);
+ glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
+
+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, elementBufferObject);
+ glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);
+
+ glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);
+ glEnableVertexAttribArray(0);
+ // I could unbind the VAO, but this is usually not needed because when creating a new VAO we need to bind that to change it anyway, so there shouldn't be a problem
+
+ std::string vertexPath = "shaders/default/default.vert";
+ std::string fragmentPath = "shaders/default/default.frag";
+
+ std::unique_ptr shader;
+ try
+ {
+ shader = std::make_unique(vertexPath, fragmentPath);
+ }
+ catch (const std::exception &e)
+ {
+ std::cerr << e.what();
+ return -1;
+ }
+ glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
+
+ // main loop
+ while(!glfwWindowShouldClose(window))
+ {
+ glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
+ glClear(GL_COLOR_BUFFER_BIT);
+
+ ProcessInput(window);
+
+ shader->Use();
+ glBindVertexArray(vertexArrayObject);
+ glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
+
+ glfwSwapBuffers(window);
+ glfwPollEvents();
+ }
+
+ // optional, as we are at the end of the program.
+ glDeleteVertexArrays(1, &vertexArrayObject);
+ glDeleteBuffers(1, &elementBufferObject);
+
+ glfwTerminate();
+ return 0;
+}
\ No newline at end of file
diff --git a/Engine/Engine/shaders/Enums.h b/Engine/Engine/shaders/Enums.h
new file mode 100644
index 0000000..2615192
--- /dev/null
+++ b/Engine/Engine/shaders/Enums.h
@@ -0,0 +1,12 @@
+#pragma once
+
+namespace Nebulix
+{
+ enum class ShaderType
+ {
+ Vertex,
+ Fragment,
+ Unknown
+ // TODO: Add compute etc in future
+ };
+}
\ No newline at end of file
diff --git a/Engine/Engine/shaders/Shader.cpp b/Engine/Engine/shaders/Shader.cpp
new file mode 100644
index 0000000..bf9298f
--- /dev/null
+++ b/Engine/Engine/shaders/Shader.cpp
@@ -0,0 +1,98 @@
+#include
+#include
+#include "Shader.h"
+
+#include "../Exceptions/IOException.h"
+#include "../Exceptions/Shaders/ShaderCompileException.h"
+#include "../exceptions/shaders/CreateProgramException.h"
+
+namespace Nebulix
+{
+
+ const char* vertexShaderSourceCode = "#version 330 core\n"
+ "layout (location = 0) in vec3 aPos;\n"
+ "void main()\n"
+ "{\n"
+ " gl_Position = vec4(aPos.x, aPos.y, aPos.z, 1.0);\n"
+ "}\0";
+ const char* fragmentShaderSourceCode = "#version 330 core\n"
+ "out vec4 FragColor;\n"
+ "void main()\n"
+ "{\n"
+ " FragColor = vec4(1.0f, 0.5f, 0.2f, 1.0f);\n"
+ "}\n\0";
+
+ Shader::Shader(std::string& vertexShaderfile, std::string& fragmentShaderfile): _vertexFile{vertexShaderfile}, _fragmentFile{fragmentShaderfile}
+ {
+ std::ifstream vertexShaderSource(vertexShaderfile), fragmentShaderSource(fragmentShaderfile);
+ GLuint vertexShader = 0, fragmentShader = 0;
+
+ CompileShadercode(vertexShaderSource, vertexShader, ShaderType::Vertex);
+ CompileShadercode(fragmentShaderSource, fragmentShader, ShaderType::Fragment);
+
+ CreateProgram(vertexShader, fragmentShader);
+ }
+
+ void Shader::CompileShadercode(std::ifstream& shaderSource, GLuint& shaderObject, ShaderType type)
+ {
+ if (!shaderSource.is_open())
+ {
+ throw IOException("ERROR::SHADER::CANNOT_OPEN_FILE");
+ }
+
+ const char* shader;
+
+ shaderSource.exceptions(std::ifstream::failbit | std::ifstream::badbit);
+ try
+ {
+ std::stringstream sourceCode;
+ sourceCode << shaderSource.rdbuf();
+ shaderSource.close();
+ std::string code = sourceCode.str();
+ shader = code.c_str();
+ }
+ catch (const std::exception&)
+ {
+ throw Nebulix::IOException("ERROR::SHADER::READ_FILE");
+ }
+
+
+ if (type == ShaderType::Vertex)
+ shaderObject = glCreateShader(GL_VERTEX_SHADER);
+ else if (type == ShaderType::Fragment)
+ shaderObject = glCreateShader(GL_FRAGMENT_SHADER);
+ else
+ throw std::runtime_error("ERROR::SHADER::TYPE \nCannot create shader program with the given shader type '" + std::to_string((int)type) + "'");
+
+ glShaderSource(shaderObject, 1, &shader, NULL);
+ glCompileShader(shaderObject);
+
+ int success;
+ char infoLog[512];
+ glGetShaderiv(shaderObject, GL_COMPILE_STATUS, &success);
+ if (!success)
+ {
+ glGetShaderInfoLog(shaderObject, 512, NULL, infoLog);
+ throw Nebulix::ShaderCompileException(type, infoLog);
+ }
+ }
+
+ void Shader::CreateProgram(GLuint& vertexShader, GLuint& fragmentShader)
+ {
+ shaderId = glCreateProgram();
+ glAttachShader(shaderId, vertexShader);
+ glAttachShader(shaderId, fragmentShader);
+ glLinkProgram(shaderId);
+
+ int success;
+ char infoLog[512];
+ glGetProgramiv(shaderId, GL_LINK_STATUS, &success);
+ if (!success) {
+ glGetProgramInfoLog(shaderId, 512, NULL, infoLog);
+ throw Nebulix::CreateProgramException(infoLog);
+ }
+
+ glDeleteShader(vertexShader);
+ glDeleteShader(fragmentShader);
+ }
+}
diff --git a/Engine/Engine/shaders/Shader.h b/Engine/Engine/shaders/Shader.h
new file mode 100644
index 0000000..dbb4c0f
--- /dev/null
+++ b/Engine/Engine/shaders/Shader.h
@@ -0,0 +1,46 @@
+#pragma once
+#include
+#include
+#include
+#include
+#include "Enums.h"
+
+
+namespace Nebulix
+{
+ class Shader
+ {
+ public:
+ Shader() = delete;
+ Shader(std::string& vertexShaderfile, std::string& fragmentShaderfile);
+ ~Shader()
+ {
+ glDeleteProgram(shaderId);
+ }
+
+ ///
+ /// To actually use and activate the shader, call this.
+ ///
+ void Use() { glUseProgram(shaderId); }
+
+ void setBool(const std::string& name, bool value) const
+ {
+ glUniform1i(glGetUniformLocation(shaderId, name.c_str()), (int)value);
+ }
+ void setInt(const std::string& name, int value) const
+ {
+ glUniform1i(glGetUniformLocation(shaderId, name.c_str()), value);
+ }
+ void setFloat(const std::string& name, float value) const
+ {
+ glUniform1f(glGetUniformLocation(shaderId, name.c_str()), value);
+ }
+
+ private:
+ std::string &_vertexFile, &_fragmentFile;
+ GLuint shaderId;
+
+ void CompileShadercode(std::ifstream& shaderSource, GLuint& shaderId, ShaderType type);
+ void CreateProgram(GLuint& vertexShader, GLuint& fragmentShader);
+ };
+}
diff --git a/Engine/Engine/shaders/default/default.frag b/Engine/Engine/shaders/default/default.frag
new file mode 100644
index 0000000..2ccfb50
--- /dev/null
+++ b/Engine/Engine/shaders/default/default.frag
@@ -0,0 +1,7 @@
+#version 330 core
+out vec4 FragColor;
+
+void main()
+{
+ FragColor = vec4(1.0f, 0.5f, 0.2f, 1.0f);
+}
\ No newline at end of file
diff --git a/Engine/Engine/shaders/default/default.vert b/Engine/Engine/shaders/default/default.vert
new file mode 100644
index 0000000..d7bd59a
--- /dev/null
+++ b/Engine/Engine/shaders/default/default.vert
@@ -0,0 +1,7 @@
+#version 330 core
+layout (location = 0) in vec3 aPos;
+
+void main()
+{
+ gl_Position = vec4(aPos.x, aPos.y, aPos.z, 1.0);
+}