diff --git a/Dengine.vcxproj b/Dengine.vcxproj index 19c88bf..98c47dd 100644 --- a/Dengine.vcxproj +++ b/Dengine.vcxproj @@ -124,12 +124,15 @@ + + + @@ -137,6 +140,7 @@ + diff --git a/Dengine.vcxproj.filters b/Dengine.vcxproj.filters index e49228a..813b7cf 100644 --- a/Dengine.vcxproj.filters +++ b/Dengine.vcxproj.filters @@ -33,10 +33,15 @@ Source Files + + Source Files + + + @@ -57,5 +62,8 @@ Header Files + + Header Files + \ No newline at end of file diff --git a/data/shaders/sprite.frag.glsl b/data/shaders/sprite.frag.glsl new file mode 100644 index 0000000..23d71ca --- /dev/null +++ b/data/shaders/sprite.frag.glsl @@ -0,0 +1,11 @@ +#version 330 core +in vec2 texCoord; + +out vec4 color; + +uniform sampler2D texture; + +void main() +{ + color = texture(texture, texCoord); +} diff --git a/data/shaders/sprite.vert.glsl b/data/shaders/sprite.vert.glsl new file mode 100644 index 0000000..566851a --- /dev/null +++ b/data/shaders/sprite.vert.glsl @@ -0,0 +1,10 @@ +#version 330 core +layout (location = 0) in vec4 data; // (vec2)pos, (vec2)texCoord + +out vec2 texCoord; + +void main() +{ + gl_Position = vec4(data.xy, 0.0f, 1.0f); + texCoord = data.zw; +} diff --git a/src/Sprite.cpp b/src/Sprite.cpp new file mode 100644 index 0000000..9f06b56 --- /dev/null +++ b/src/Sprite.cpp @@ -0,0 +1,76 @@ +#include +#include + +namespace Dengine +{ + +Sprite::Sprite() +: mPos(0, 0), +mTex(nullptr) +{ +} + +Sprite::~Sprite() {} + +b32 Sprite::loadSprite(Texture *tex, glm::vec2 pos) +{ + if (!tex) return -1; + + mTex = tex; + mPos = pos; + + // NOTE(doyle): We encode in a vec4 (vec2)pos, (vec2)texCoords + glm::vec4 spriteVertex[] = { + // x y s t + {+0.5f, +0.5f, 1.0f, 1.0f}, // Top right + {+0.5f, -0.5f, 1.0f, 0.0f}, // Bottom right + {-0.5f, +0.5f, 0.0f, 1.0f}, // Top left + {-0.5f, -0.5f, 0.0f, 0.0f}, // Bottom left + }; + + glGenBuffers(1, &mVbo); + glBindBuffer(GL_ARRAY_BUFFER, mVbo); + glBufferData(GL_ARRAY_BUFFER, sizeof(spriteVertex), spriteVertex, + GL_DYNAMIC_DRAW); + glBindBuffer(GL_ARRAY_BUFFER, 0); + + return 0; +} + +void Sprite::initVertexArrayObject(GLuint vao) +{ + // NOTE(doyle): Set the VAO object attributes to match a sprite's + // vertex composition + glBindVertexArray(vao); + + i32 numElementsInVertex = 4; + i32 vertexSize = sizeof(glm::vec4); + glEnableVertexAttribArray(0); + glVertexAttribPointer(0, numElementsInVertex, GL_FLOAT, GL_FALSE, + vertexSize, (GLvoid *)(0)); + + /* Unbind */ + glBindVertexArray(0); + +} + +void Sprite::render(Shader *shader, GLuint spriteVAO) +{ + // NOTE(doyle): Associate the VAO with this sprites VBO + glBindVertexArray(spriteVAO); + glBindBuffer(GL_ARRAY_BUFFER, mVbo); + + /* Set texture */ + glActiveTexture(GL_TEXTURE0); + mTex->bind(); + glUniform1i(glGetUniformLocation(shader->mProgram, "texture"), 0); + + /* Render */ + glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); + + // Unbind + glBindBuffer(GL_ARRAY_BUFFER, 0); + glBindVertexArray(0); +} + +} diff --git a/src/dengine.cpp b/src/dengine.cpp index 97a0d37..820bbc6 100644 --- a/src/dengine.cpp +++ b/src/dengine.cpp @@ -3,6 +3,7 @@ #include #include #include +#include #include @@ -124,6 +125,7 @@ int main() glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED); glEnable(GL_CULL_FACE | GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glCullFace(GL_BACK); @@ -135,9 +137,9 @@ int main() Dengine::AssetManager assetManager; i32 result = 0; - result = assetManager.loadShaderFiles("data/shaders/default.vert.glsl", - "data/shaders/default.frag.glsl", - "default"); + result = assetManager.loadShaderFiles("data/shaders/sprite.vert.glsl", + "data/shaders/sprite.frag.glsl", + "sprite"); if (result) return result; /* Load a texture */ @@ -149,13 +151,24 @@ int main() "wall"); if (result) return result; + result = assetManager.loadTextureImage("data/textures/awesomeface.png" + , "awesomeface"); + if (result) return result; + Dengine::Texture *containerTex = assetManager.getTexture("container"); Dengine::Texture *wallTex = assetManager.getTexture("wall"); - Dengine::Shader *shader = assetManager.getShader("default"); + Dengine::Shader *shader = assetManager.getShader("sprite"); + Dengine::Texture *awesomeTex = assetManager.getTexture("awesomeface"); f32 deltaTime = 0.0f; // Time between current frame and last frame f32 lastFrame = 0.0f; // Time of last frame + GLuint spriteVao; + glGenVertexArrays(1, &spriteVao); + Dengine::Sprite sprite = Dengine::Sprite(); + sprite.loadSprite(awesomeTex, glm::vec2(0, 0)); + sprite.initVertexArrayObject(spriteVao); + /* Main game loop */ while (!glfwWindowShouldClose(window)) { @@ -176,6 +189,8 @@ int main() shader->use(); game.render(); + sprite.render(shader, spriteVao); + /* Swap the buffers */ glfwSwapBuffers(window); } diff --git a/src/include/Dengine/Sprite.h b/src/include/Dengine/Sprite.h new file mode 100644 index 0000000..d3498c9 --- /dev/null +++ b/src/include/Dengine/Sprite.h @@ -0,0 +1,27 @@ +#ifndef DENGINE_SPRITE_H +#define DENGINE_SPRITE_H + +#include +#include +#include +#include + +namespace Dengine { +class Sprite +{ +public: + Sprite(); + ~Sprite(); + + b32 loadSprite(Texture *tex, glm::vec2 pos); + + void initVertexArrayObject(GLuint vao); + void render(Shader *shader, GLuint shaderVao); +private: + glm::vec2 mPos; + Texture *mTex; + GLuint mVbo; +}; +} + +#endif