diff --git a/CMakeLists.txt b/CMakeLists.txt index 1ab4fee..221174e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -19,6 +19,7 @@ add_executable(Fall-Fever EventHandler.cpp ShaderProgram.cpp VertexBuffer.cpp + Texture.cpp ) target_link_libraries( diff --git a/Controller.cpp b/Controller.cpp index 711ad21..c0b2ba6 100644 --- a/Controller.cpp +++ b/Controller.cpp @@ -10,6 +10,7 @@ #endif #include "Controller.h" +#include "Texture.h" Controller::Controller() { if(!glfwInit()) exit(-1); @@ -40,13 +41,23 @@ void Controller::run() { shaderProgram.bind(); Vertex vertices[] = { - Vertex{-0.5f, -0.5f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f}, - Vertex{0.5f, -0.5f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f}, - Vertex{0.0f, 0.5f, 0.0f, 0.0f, 0.0f, 1.0f, 1.0f} + Vertex{-0.5f, -0.5f, 0.0f, + 0.0f, 0.0f, + 1.0f, 0.0f, 0.0f, 1.0f}, + Vertex{0.5f, -0.5f, 0.0f, + 1.0f, 0.0f, + 0.0f, 1.0f,0.0f, 1.0f}, + Vertex{-0.5f, 0.5f, 0.0f, + 0.0f, 1.0f, + 0.0f, 0.0f, 1.0f, 1.0f}, + Vertex{0.5f, 0.5f, 0.0f, + 1.0f, 1.0f, + 0.0f, 0.0f, 1.0f, 1.0f} }; uint32_t indices[] = { - 0, 1, 2 + 0, 1, 2, + 1, 2, 3 }; uint32_t numVertices = sizeof(vertices) / sizeof(Vertex); @@ -54,6 +65,8 @@ void Controller::run() { VertexBuffer vertexBuffer(vertices, indices, numVertices, numIndices); + Texture tex1("res/tex.png", shaderProgram.getShaderProgramId()); + // This is the game loop while(!glfwWindowShouldClose(gameWindow->getGLFWwindow())) { // Timing @@ -74,7 +87,9 @@ void Controller::run() { glClear(GL_COLOR_BUFFER_BIT); vertexBuffer.bind(); + tex1.bind(0); glDrawElements(GL_TRIANGLES, numIndices, GL_UNSIGNED_INT, 0); + tex1.unbind(); vertexBuffer.unbind(); glfwSwapBuffers(gameWindow->getGLFWwindow()); diff --git a/ShaderProgram.cpp b/ShaderProgram.cpp index 8d80902..bab97a8 100644 --- a/ShaderProgram.cpp +++ b/ShaderProgram.cpp @@ -3,8 +3,8 @@ #include "ShaderProgram.h" -ShaderProgram::ShaderProgram(const char* vertexShaderFilename, const char* fragmentShaderFilename) { - shaderProgramId = createShader(vertexShaderFilename, fragmentShaderFilename); +ShaderProgram::ShaderProgram(const char* vertexShaderPath, const char* fragmentShaderPath) { + shaderProgramId = createShader(vertexShaderPath, fragmentShaderPath); } ShaderProgram::~ShaderProgram() { @@ -19,9 +19,9 @@ void ShaderProgram::unbind() { glUseProgram(0); } -GLuint ShaderProgram::createShader(const char* vertexShaderFilename, const char* framentShaderFilename) { - std::string vertexShaderSource = parse(vertexShaderFilename); - std::string fragmentShaderSource = parse(framentShaderFilename); +GLuint ShaderProgram::createShader(const char* vertexShaderPath, const char* framentShaderPath) { + std::string vertexShaderSource = parse(vertexShaderPath); + std::string fragmentShaderSource = parse(framentShaderPath); GLuint program = glCreateProgram(); GLuint vs = compile(vertexShaderSource, GL_VERTEX_SHADER); diff --git a/ShaderProgram.h b/ShaderProgram.h index b8fb7d8..c55ad24 100644 --- a/ShaderProgram.h +++ b/ShaderProgram.h @@ -7,7 +7,7 @@ class ShaderProgram { public: - ShaderProgram(const char* vertexShaderFilename, const char* framentShaderFilename); + ShaderProgram(const char* vertexShaderPath, const char* framentShaderPath); ~ShaderProgram(); void bind(); @@ -18,11 +18,13 @@ public: void setInt(const char *name, int value) const; void setFloat(const char *name, float value) const; + GLuint getShaderProgramId() { return shaderProgramId; } + private: std::string parse(const char* filename); GLuint compile(std::string shaderSource, GLenum type); - GLuint createShader(const char* vertexShaderFilename, const char* framentShaderFilename); + GLuint createShader(const char* vertexShaderPath, const char* framentShaderPath); GLuint shaderProgramId; diff --git a/Texture.cpp b/Texture.cpp new file mode 100644 index 0000000..0715581 --- /dev/null +++ b/Texture.cpp @@ -0,0 +1,54 @@ +#include "Texture.h" + +#include +#include + +Texture::Texture(const char* texturePath, GLuint shaderProgramId) { + this->shaderProgramId = shaderProgramId; + + stbi_set_flip_vertically_on_load(1); + stbi_uc *textureBuffer = stbi_load(texturePath, &textureWidth, &textureHeight, &bitsPerPixel, 4); + + // Push texture to grahics card; + glGenTextures(1, &textureId); + glBindTexture(GL_TEXTURE_2D, textureId); + + //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + + + if(textureBuffer) { + + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, textureWidth, textureHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, textureBuffer); + //glGenerateMipmap(GL_TEXTURE_2D); + + + } else { + + std::cout << "[Warning] Texture " << texturePath << " not found!" << std::endl; + + } + + stbi_image_free(textureBuffer); + glBindTexture(GL_TEXTURE_2D, 0); + +} + +Texture::~Texture() { + glDeleteTextures(1, &textureId); +} + +void Texture::bind(uint8_t textureUnit) { + GLint uniformLoc = glGetUniformLocation(shaderProgramId, "u_texture"); + glUniform1i(uniformLoc, textureUnit); + glActiveTexture(GL_TEXTURE0 + textureUnit); + glBindTexture(GL_TEXTURE_2D, textureId); +} + +void Texture::unbind() { + glBindTexture(GL_TEXTURE_2D, 0); +} diff --git a/Texture.h b/Texture.h new file mode 100644 index 0000000..28c2f27 --- /dev/null +++ b/Texture.h @@ -0,0 +1,26 @@ +#pragma once + +#include +#include + +class Texture { + +public: + + Texture(const char* texturePath, GLuint shaderProgramId); + ~Texture(); + + void bind(uint8_t textureUnit); + void unbind(); + +private: + + int32_t textureWidth; + int32_t textureHeight; + int32_t bitsPerPixel; + + GLuint textureId; + + GLuint shaderProgramId; + +}; \ No newline at end of file diff --git a/VertexBuffer.cpp b/VertexBuffer.cpp index 2aff8e4..d9b38f5 100644 --- a/VertexBuffer.cpp +++ b/VertexBuffer.cpp @@ -16,10 +16,17 @@ VertexBuffer::VertexBuffer(void *vertexData, void *indexData, uint32_t numVertic glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO); glBufferData(GL_ELEMENT_ARRAY_BUFFER, numIndices * sizeof(uint32_t), indexData, GL_STATIC_DRAW); + // Position glEnableVertexAttribArray(0); glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*) offsetof(struct Vertex, x)); + + // UV Texture Mapping glEnableVertexAttribArray(1); - glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*) offsetof(struct Vertex, r)); + glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*) offsetof(struct Vertex, u)); + + // Color + glEnableVertexAttribArray(2); + glVertexAttribPointer(2, 4, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*) offsetof(struct Vertex, r)); // This will also unbind the vertex buffer glBindVertexArray(0); diff --git a/defines.h b/defines.h index 8f7812e..a1f61ee 100644 --- a/defines.h +++ b/defines.h @@ -1,10 +1,16 @@ #pragma once struct Vertex { + // Postition float x; float y; float z; + // UV Texture Mapping + float u; + float v; + + // Color float r; float g; float b; diff --git a/res/shaders/basic.fs b/res/shaders/basic.fs index ec27dd9..a116e09 100644 --- a/res/shaders/basic.fs +++ b/res/shaders/basic.fs @@ -3,7 +3,12 @@ layout(location = 0) out vec4 f_color; in vec4 v_color; +in vec2 v_texCoord; + +uniform sampler2D u_texture; void main() { - f_color = v_color; + //f_color = v_color; + vec4 texColor = texture(u_texture, v_texCoord); + f_color = texColor; } diff --git a/res/shaders/basic.vs b/res/shaders/basic.vs index 4a0a60f..7cf64f2 100644 --- a/res/shaders/basic.vs +++ b/res/shaders/basic.vs @@ -1,12 +1,15 @@ #version 330 core layout(location = 0) in vec3 a_position; -layout(location = 1) in vec4 a_color; +layout(location = 1) in vec2 a_texCoord; +layout(location = 2) in vec4 a_color; out vec4 v_color; +out vec2 v_texCoord; void main() { gl_Position = vec4(a_position, 1.0f); //gl_Position = vec4(a_position.x, -a_position.y, a_position.z, 1.0f); + v_texCoord = a_texCoord; v_color = a_color; } diff --git a/res/tex.png b/res/tex.png new file mode 100644 index 0000000..1549425 Binary files /dev/null and b/res/tex.png differ