diff --git a/Dengine.vcxproj b/Dengine.vcxproj
index e8d995e..24fa02b 100644
--- a/Dengine.vcxproj
+++ b/Dengine.vcxproj
@@ -120,17 +120,21 @@
+
+
+
+
diff --git a/Dengine.vcxproj.filters b/Dengine.vcxproj.filters
index 552a6bd..4129db9 100644
--- a/Dengine.vcxproj.filters
+++ b/Dengine.vcxproj.filters
@@ -21,6 +21,12 @@
Source Files
+
+ Source Files
+
+
+ Source Files
+
@@ -36,5 +42,11 @@
Header Files
+
+ Header Files
+
+
+ Header Files
+
\ No newline at end of file
diff --git a/src/AssetManager.cpp b/src/AssetManager.cpp
new file mode 100644
index 0000000..c2e90d7
--- /dev/null
+++ b/src/AssetManager.cpp
@@ -0,0 +1,118 @@
+#include
+
+#define STBI_FAILURE_USERMSG
+#define STB_IMAGE_IMPLEMENTATION
+#include
+#include
+
+namespace Dengine
+{
+
+ AssetManager::AssetManager(){}
+ AssetManager::~AssetManager(){}
+
+ Texture *AssetManager::getTexture(std::string name)
+ {
+ // NOTE(doyle): Since we're using a map, the count of an object can
+ // only be 1 or 0
+ if (mTextures.count(name) == 1)
+ return &mTextures[name];
+
+ return nullptr;
+ }
+
+ i32 AssetManager::loadTextureImage(std::string path, std::string name)
+ {
+ /* Open the texture image */
+ i32 imgWidth, imgHeight, bytesPerPixel;
+ stbi_set_flip_vertically_on_load(TRUE);
+ u8 *image =
+ stbi_load(path.c_str(), &imgWidth, &imgHeight, &bytesPerPixel, 0);
+
+ if (!image)
+ {
+ std::cerr << "stdbi_load() failed: " << stbi_failure_reason()
+ << std::endl;
+ return -1;
+ }
+
+ Texture tex;
+ tex.generate(imgWidth, imgHeight, image);
+ stbi_image_free(image);
+
+ mTextures[name] = tex;
+ return 0;
+ }
+
+ Shader *AssetManager::getShader(std::string name)
+ {
+ if (mShaders.count(name) == 1)
+ return &mShaders[name];
+
+ return nullptr;
+ }
+
+ INTERNAL std::string stringFromFile(const std::string &filename)
+ {
+ std::ifstream file;
+ file.open(filename.c_str(), std::ios::in | std::ios::binary);
+
+ std::string output;
+ std::string line;
+
+ if (!file.is_open())
+ {
+ std::runtime_error(std::string("Failed to open file: ") + filename);
+ }
+ else
+ {
+ while (file.good())
+ {
+ std::getline(file, line);
+ output.append(line + "\n");
+ }
+ }
+ file.close();
+ return output;
+ }
+
+ INTERNAL GLuint createShaderFromPath(std::string path, GLuint shadertype)
+ {
+ std::string shaderSource = stringFromFile(path);
+ const GLchar *source = shaderSource.c_str();
+
+ GLuint result = glCreateShader(shadertype);
+ glShaderSource(result, 1, &source, NULL);
+ glCompileShader(result);
+
+ GLint success;
+ GLchar infoLog[512];
+ glGetShaderiv(result, GL_COMPILE_STATUS, &success);
+ if (!success)
+ {
+ glGetShaderInfoLog(result, 512, NULL, infoLog);
+ std::cout << "glCompileShader failed: " << infoLog << std::endl;
+ }
+
+ return result;
+ }
+
+ i32 AssetManager::loadShaderFiles(std::string vertexPath,
+ std::string fragmentPath, std::string name)
+ {
+
+ GLuint vertexShader =
+ createShaderFromPath(vertexPath, GL_VERTEX_SHADER);
+ GLuint fragmentShader =
+ createShaderFromPath(fragmentPath, GL_FRAGMENT_SHADER);
+
+ Shader shader;
+ i32 result = shader.loadProgram(vertexShader, fragmentShader);
+ if (result)
+ return result;
+
+ mShaders[name] = shader;
+ return 0;
+ }
+
+}
diff --git a/src/Shader.cpp b/src/Shader.cpp
index 9701c30..21ae18f 100644
--- a/src/Shader.cpp
+++ b/src/Shader.cpp
@@ -5,63 +5,23 @@
namespace Dengine
{
-INTERNAL std::string stringFromFile(const std::string &filename)
+Shader::Shader()
+: mProgram(0)
{
- std::ifstream file;
- file.open(filename.c_str(), std::ios::in | std::ios::binary);
-
- std::string output;
- std::string line;
-
- if (!file.is_open())
- {
- std::runtime_error(std::string("Failed to open file: ") + filename);
- }
- else
- {
- while (file.good())
- {
- std::getline(file, line);
- output.append(line + "\n");
- }
- }
- file.close();
- return output;
}
-INTERNAL GLuint createShaderFromPath(std::string path, GLuint shadertype)
+Shader::~Shader() {}
+
+i32 Shader::loadProgram(GLuint vertexShader, GLuint fragmentShader)
{
- std::string shaderSource = stringFromFile(path);
- const GLchar *source = shaderSource.c_str();
-
- GLuint result = glCreateShader(shadertype);
- glShaderSource(result, 1, &source, NULL);
- glCompileShader(result);
-
- GLint success;
- GLchar infoLog[512];
- glGetShaderiv(result, GL_COMPILE_STATUS, &success);
- if (!success)
- {
- glGetShaderInfoLog(result, 512, NULL, infoLog);
- std::cout << "glCompileShader failed: " << infoLog << std::endl;
- }
-
- return result;
-}
-
-Shader::Shader(std::string vertexPath, std::string fragmentPath)
-{
-
- GLuint vertexShader = createShaderFromPath(vertexPath, GL_VERTEX_SHADER);
- GLuint fragmentShader =
- createShaderFromPath(fragmentPath, GL_FRAGMENT_SHADER);
-
mProgram = glCreateProgram();
glAttachShader(mProgram, vertexShader);
glAttachShader(mProgram, fragmentShader);
glLinkProgram(mProgram);
+ glDeleteShader(fragmentShader);
+ glDeleteShader(vertexShader);
+
GLint success;
GLchar infoLog[512];
glGetProgramiv(mProgram, GL_LINK_STATUS, &success);
@@ -69,13 +29,12 @@ Shader::Shader(std::string vertexPath, std::string fragmentPath)
{
glGetProgramInfoLog(mProgram, 512, NULL, infoLog);
std::cout << "glLinkProgram failed: " << infoLog << std::endl;
+ return -1;
}
- glDeleteShader(fragmentShader);
- glDeleteShader(vertexShader);
-}
+ return 0;
-Shader::~Shader() {}
+}
void Shader::use() { glUseProgram(mProgram); }
}
diff --git a/src/Texture.cpp b/src/Texture.cpp
new file mode 100644
index 0000000..6043846
--- /dev/null
+++ b/src/Texture.cpp
@@ -0,0 +1,42 @@
+#include
+
+namespace Dengine
+{
+Texture::Texture()
+: mId(0)
+, mWidth(0)
+, mHeight(0)
+, mInternalFormat(GL_RGB)
+, mImageFormat(GL_RGB)
+, mWrapS(GL_REPEAT)
+, mWrapT(GL_REPEAT)
+, mFilterMinification(GL_LINEAR)
+, mFilterMagnification(GL_LINEAR)
+{
+ glGenTextures(1, &mId);
+}
+
+void Texture::generate(GLuint width, GLuint height, u8 *image)
+{
+ mWidth = width;
+ mHeight = height;
+
+ glBindTexture(GL_TEXTURE_2D, mId);
+
+ /* Load image into texture */
+ glTexImage2D(GL_TEXTURE_2D, 0, mInternalFormat, mWidth, mHeight, 0,
+ mImageFormat, GL_UNSIGNED_BYTE, image);
+ glGenerateMipmap(GL_TEXTURE_2D);
+
+ /* Set parameter of currently bound texture */
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, mWrapS);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, mWrapT);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, mFilterMinification);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, mFilterMagnification);
+
+ /* Unbind and clean up */
+ glBindTexture(GL_TEXTURE_2D, 0);
+}
+
+void Texture::bind() const { glBindTexture(GL_TEXTURE_2D, mId); }
+}
diff --git a/src/build.bat b/src/build.bat
index b645bf5..3cb7e2f 100644
--- a/src/build.bat
+++ b/src/build.bat
@@ -18,8 +18,9 @@ set includeFlags=/I ..\src\include /I %GLEW%\include /I %GLFW%\include /I %STB%\
REM Link libraries
set linkLibraries=/link opengl32.lib %GLFW%\lib-vc2015\glfw3.lib %GLEW%\lib\Release\Win32\glew32s.lib gdi32.lib user32.lib shell32.lib
+set ignoreLibraries=/NODEFAULTLIB:"libc.lib" /NODEFAULTLIB:"libcmt.lib" /NODEFAULTLIB:"libcd.lib" /NODEFAULTLIB:"libcmtd.lib" /NODEFAULTLIB:"msvcrtd.lib"
-cl %compileFlags% ..\src\*.cpp %includeFlags% %linkLibraries%
+cl %compileFlags% ..\src\*.cpp %includeFlags% %linkLibraries% %ignoreLibraries% /OUT:"Dengine.exe"
REM /SUBSYSTEM:CONSOLE
popd
diff --git a/src/dengine.cpp b/src/dengine.cpp
index 8a318b8..09e899d 100644
--- a/src/dengine.cpp
+++ b/src/dengine.cpp
@@ -1,10 +1,8 @@
#include
#include
#include
+#include
-#define STBI_FAILURE_USERMSG
-#define STB_IMAGE_IMPLEMENTATION
-#include
#include
#include
#include
@@ -130,6 +128,42 @@ void scroll_callback(GLFWwindow *window, double xOffset, double yOffset)
fov = 45.0f;
}
+GLenum glCheckError_(const char *file, int line)
+{
+ GLenum errorCode;
+ while ((errorCode = glGetError()) != GL_NO_ERROR)
+ {
+ std::string error;
+ switch (errorCode)
+ {
+ case GL_INVALID_ENUM:
+ error = "INVALID_ENUM";
+ break;
+ case GL_INVALID_VALUE:
+ error = "INVALID_VALUE";
+ break;
+ case GL_INVALID_OPERATION:
+ error = "INVALID_OPERATION";
+ break;
+ case GL_STACK_OVERFLOW:
+ error = "STACK_OVERFLOW";
+ break;
+ case GL_STACK_UNDERFLOW:
+ error = "STACK_UNDERFLOW";
+ break;
+ case GL_OUT_OF_MEMORY:
+ error = "OUT_OF_MEMORY";
+ break;
+ case GL_INVALID_FRAMEBUFFER_OPERATION:
+ error = "INVALID_FRAMEBUFFER_OPERATION";
+ break;
+ }
+ std::cout << error << " | " << file << " (" << line << ")" << std::endl;
+ }
+ return errorCode;
+}
+#define glCheckError() glCheckError_(__FILE__, __LINE__)
+
int main()
{
glfwInit();
@@ -173,41 +207,22 @@ int main()
glEnable(GL_DEPTH_TEST);
/* Initialise shaders */
- Dengine::Shader shader = Dengine::Shader("data/shaders/default.vert.glsl",
- "data/shaders/default.frag.glsl");
- GLuint texture;
- glGenTextures(1, &texture);
- glBindTexture(GL_TEXTURE_2D, texture);
+ Dengine::AssetManager assetManager;
+ i32 result = 0;
- // Set texture wrapping parameters
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
-
- // Set texture filtering parameters
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ result = assetManager.loadShaderFiles("data/shaders/default.vert.glsl",
+ "data/shaders/default.frag.glsl",
+ "default");
+ if (result) return result;
/* Load a texture */
- i32 imgWidth, imgHeight, bytesPerPixel;
- stbi_set_flip_vertically_on_load(TRUE);
- u8 *image = stbi_load("data/textures/container.jpg", &imgWidth, &imgHeight,
- &bytesPerPixel, 0);
+ result = assetManager.loadTextureImage("data/textures/container.jpg",
+ "container");
+ if (result) return result;
- if (!image)
- {
- std::cerr << "stdbi_load() failed: " << stbi_failure_reason()
- << std::endl;
- }
-
- glTexImage2D(GL_TEXTURE_2D, 0,
- getGLFormat((BytesPerPixel)bytesPerPixel, FALSE), imgWidth,
- imgHeight, 0, getGLFormat((BytesPerPixel)bytesPerPixel, FALSE),
- GL_UNSIGNED_BYTE, image);
- glGenerateMipmap(GL_TEXTURE_2D);
-
- // Unbind texture
- glBindTexture(GL_TEXTURE_2D, 0);
- stbi_image_free(image);
+ Dengine::Texture *containerTex = assetManager.getTexture("container");
+ Dengine::Shader *shader = assetManager.getShader("default");
+ //if (!containerTex) return -1;
/* Create OGL Vertex objects */
GLfloat vertices[] = {
@@ -275,11 +290,11 @@ int main()
-0.5f, -0.5f, +0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, // Bottom left
-0.5f, +0.5f, +0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, // Top left
};
-#endif
GLuint indices[] = {
0, 1, 3, // First triangle
1, 2, 3, // First triangle
};
+#endif
GLuint vbo, vao;
@@ -355,10 +370,10 @@ int main()
/* Bind textures */
glActiveTexture(GL_TEXTURE0);
- glBindTexture(GL_TEXTURE_2D, texture);
- glUniform1i(glGetUniformLocation(shader.mProgram, "ourTexture"), 0);
+ glBindTexture(GL_TEXTURE_2D, containerTex->mId);
+ glUniform1i(glGetUniformLocation(shader->mProgram, "ourTexture"), 0);
- shader.use();
+ shader->use();
/* Camera/View transformation */
glm::mat4 view;
@@ -372,9 +387,9 @@ int main()
0.1f, 100.0f);
/* Get shader uniform locations */
- GLuint modelLoc = glGetUniformLocation(shader.mProgram, "model");
- GLuint viewLoc = glGetUniformLocation(shader.mProgram, "view");
- GLuint projectionLoc = glGetUniformLocation(shader.mProgram, "projection");
+ GLuint modelLoc = glGetUniformLocation(shader->mProgram, "model");
+ GLuint viewLoc = glGetUniformLocation(shader->mProgram, "view");
+ GLuint projectionLoc = glGetUniformLocation(shader->mProgram, "projection");
/* Pass matrices to the shader */
glUniformMatrix4fv(viewLoc, 1, GL_FALSE, glm::value_ptr(view));
diff --git a/src/include/Dengine/AssetManager.h b/src/include/Dengine/AssetManager.h
new file mode 100644
index 0000000..429c059
--- /dev/null
+++ b/src/include/Dengine/AssetManager.h
@@ -0,0 +1,34 @@
+#ifndef DENGINE_ASSET_MANAGER_H
+#define DENGINE_ASSET_MANAGER_H
+
+#include
+#include
+#include
+
+#include