Abstract asset loading to asset manager
This commit is contained in:
parent
d08cc4621b
commit
7295d4712c
@ -120,17 +120,21 @@
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="src\AssetManager.cpp" />
|
||||
<ClCompile Include="src\dengine.cpp" />
|
||||
<ClCompile Include="src\Shader.cpp" />
|
||||
<ClCompile Include="src\Texture.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="data\shaders\default.frag.glsl" />
|
||||
<None Include="data\shaders\default.vert.glsl" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="src\include\Dengine\AssetManager.h" />
|
||||
<ClInclude Include="src\include\Dengine\Common.h" />
|
||||
<ClInclude Include="src\include\Dengine\OpenGL.h" />
|
||||
<ClInclude Include="src\include\Dengine\Shader.h" />
|
||||
<ClInclude Include="src\include\Dengine\Texture.h" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
|
@ -21,6 +21,12 @@
|
||||
<ClCompile Include="src\Shader.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\Texture.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\AssetManager.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="data\shaders\default.vert.glsl" />
|
||||
@ -36,5 +42,11 @@
|
||||
<ClInclude Include="src\include\Dengine\OpenGL.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\include\Dengine\Texture.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\include\Dengine\AssetManager.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
</Project>
|
118
src/AssetManager.cpp
Normal file
118
src/AssetManager.cpp
Normal file
@ -0,0 +1,118 @@
|
||||
#include <Dengine\AssetManager.h>
|
||||
|
||||
#define STBI_FAILURE_USERMSG
|
||||
#define STB_IMAGE_IMPLEMENTATION
|
||||
#include <STB/stb_image.h>
|
||||
#include <fstream>
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
}
|
@ -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); }
|
||||
}
|
||||
|
42
src/Texture.cpp
Normal file
42
src/Texture.cpp
Normal file
@ -0,0 +1,42 @@
|
||||
#include <Dengine\Texture.h>
|
||||
|
||||
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); }
|
||||
}
|
@ -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
|
||||
|
@ -1,10 +1,8 @@
|
||||
#include <Dengine/OpenGL.h>
|
||||
#include <Dengine/Common.h>
|
||||
#include <Dengine/Shader.h>
|
||||
#include <Dengine/AssetManager.h>
|
||||
|
||||
#define STBI_FAILURE_USERMSG
|
||||
#define STB_IMAGE_IMPLEMENTATION
|
||||
#include <STB/stb_image.h>
|
||||
#include <glm/glm.hpp>
|
||||
#include <glm/gtc/matrix_transform.hpp>
|
||||
#include <glm/gtc/type_ptr.hpp>
|
||||
@ -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));
|
||||
|
34
src/include/Dengine/AssetManager.h
Normal file
34
src/include/Dengine/AssetManager.h
Normal file
@ -0,0 +1,34 @@
|
||||
#ifndef DENGINE_ASSET_MANAGER_H
|
||||
#define DENGINE_ASSET_MANAGER_H
|
||||
|
||||
#include <Dengine\Common.h>
|
||||
#include <Dengine\Texture.h>
|
||||
#include <Dengine\Shader.h>
|
||||
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
|
||||
namespace Dengine
|
||||
{
|
||||
class AssetManager
|
||||
{
|
||||
public:
|
||||
AssetManager();
|
||||
~AssetManager();
|
||||
|
||||
/* Texture */
|
||||
Texture *getTexture(std::string name);
|
||||
i32 loadTextureImage(std::string path, std::string name);
|
||||
|
||||
/* Shaders */
|
||||
Shader *getShader(std::string name);
|
||||
i32 loadShaderFiles(std::string vertexPath, std::string fragmentPath,
|
||||
std::string name);
|
||||
|
||||
private:
|
||||
std::map<std::string, Texture> mTextures;
|
||||
std::map<std::string, Shader> mShaders;
|
||||
};
|
||||
}
|
||||
#endif
|
@ -7,17 +7,18 @@
|
||||
|
||||
namespace Dengine
|
||||
{
|
||||
class Shader
|
||||
{
|
||||
public:
|
||||
class Shader
|
||||
{
|
||||
public:
|
||||
GLuint mProgram;
|
||||
|
||||
Shader(std::string vertexPath, std::string fragmentPath);
|
||||
Shader();
|
||||
~Shader();
|
||||
|
||||
void use();
|
||||
i32 loadProgram(GLuint vertexShader, GLuint fragmentShader);
|
||||
|
||||
};
|
||||
void use();
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
|
43
src/include/Dengine/Texture.h
Normal file
43
src/include/Dengine/Texture.h
Normal file
@ -0,0 +1,43 @@
|
||||
#ifndef DENGINE_TEXTURE_H
|
||||
#define DENGINE_TEXTURE_H
|
||||
|
||||
#include <Dengine\OpenGL.h>
|
||||
#include <Dengine\Common.h>
|
||||
|
||||
namespace Dengine
|
||||
{
|
||||
class Texture
|
||||
{
|
||||
public:
|
||||
// Holds the ID of the texture object, used for all texture operations to
|
||||
// reference to this particlar texture
|
||||
GLuint mId;
|
||||
|
||||
// Texture image dimensions
|
||||
GLuint mWidth;
|
||||
GLuint mHeight;
|
||||
|
||||
// Texture Format
|
||||
GLuint mInternalFormat; // Format of texture object
|
||||
GLuint mImageFormat; // Format of loaded image
|
||||
|
||||
// Texture configuration
|
||||
GLuint mWrapS; // Wrapping mode on S axis
|
||||
GLuint mWrapT; // Wrapping mode on T axis
|
||||
|
||||
// Filtering mode if texture pixels < screen pixels
|
||||
GLuint mFilterMinification;
|
||||
// Filtering mode if texture pixels > screen pixels
|
||||
GLuint mFilterMagnification;
|
||||
|
||||
// Constructor (sets default texture modes)
|
||||
Texture();
|
||||
|
||||
// Generates texture from image data
|
||||
void generate(GLuint width, GLuint height, unsigned char *data);
|
||||
|
||||
// Binds the texture as the current active GL_TEXTURE_2D texture object
|
||||
void bind() const;
|
||||
};
|
||||
}
|
||||
#endif
|
Loading…
Reference in New Issue
Block a user