diff --git a/CMakeLists.txt b/CMakeLists.txt index 4106622..6b1968f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -15,6 +15,8 @@ add_executable(Fall-Fever Controller.cpp Window.cpp EventHandler.cpp + ShaderProgram.cpp + VertexBuffer.cpp ) target_link_libraries( diff --git a/Controller.cpp b/Controller.cpp index a2a0c8b..1e6e235 100644 --- a/Controller.cpp +++ b/Controller.cpp @@ -10,6 +10,9 @@ #endif #include "Controller.h" +#include "ShaderProgram.h" +#include "VertexBuffer.h" +#include "defines.h" Controller::Controller() { if(!glfwInit()) exit(-1); @@ -33,82 +36,40 @@ Controller::~Controller() { void Controller::run() { glClearColor(0.241f, 0.578f, 0.308f, 1.0f); - unsigned int vertexShader; - vertexShader = glCreateShader(GL_VERTEX_SHADER); - glShaderSource(vertexShader, 1, &vertexShaderSource, NULL); - glCompileShader(vertexShader); + ShaderProgram shaderProgram("res/shaders/old.vs", "res/shaders/old.fs"); + shaderProgram.bind(); - int success; - char infoLog[512]; - glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &success); - if(!success) { - glGetShaderInfoLog(vertexShader, 512, NULL, infoLog); - std::cout << "ERROR::SHADER::VERTEX::COMPILATION_FAILED\n" << infoLog << std::endl; - } - - unsigned int fragmentShader; - fragmentShader = glCreateShader(GL_FRAGMENT_SHADER); - glShaderSource(fragmentShader, 1, &fragmentShaderSource, NULL); - glCompileShader(fragmentShader); - glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &success); - if(!success) { - glGetShaderInfoLog(vertexShader, 512, NULL, infoLog); - std::cout << "ERROR::SHADER::FRAGMENT::COMPILATION_FAILED\n" << infoLog << std::endl; - } - - unsigned int shaderProgram; - shaderProgram = glCreateProgram(); - glAttachShader(shaderProgram, vertexShader); - glAttachShader(shaderProgram, fragmentShader); - glLinkProgram(shaderProgram); - glGetProgramiv(shaderProgram, GL_LINK_STATUS, &success); - if(!success) { - glGetProgramInfoLog(shaderProgram, 512, NULL, infoLog); - std::cout << "ERROR::SHADER::PROGRAM::LINKING_FAILED\n" << infoLog << std::endl; - } - glDeleteShader(vertexShader); - glDeleteShader(fragmentShader); - - unsigned int VBO, VAO; - glGenVertexArrays(1, &VAO); - glGenBuffers(1, &VBO); - - glBindVertexArray(VAO); - - float vertices[] = { - -0.5f, -0.5f, 0.0f, - 0.5f, -0.5f, 0.0f, - 0.0f, 0.5f, 0.0f + Vertex vertices[] = { + Vertex{-0.5f, -0.5f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f}, + Vertex{0.5f, -0.5f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f}, + Vertex{0.0f, 0.5f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f} }; + uint32_t numVertices = sizeof(vertices) / sizeof(Vertex); - glBindBuffer(GL_ARRAY_BUFFER, VBO); - glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); - - glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0); - glEnableVertexAttribArray(0); - - glBindBuffer(GL_ARRAY_BUFFER, 0); - glBindVertexArray(0); - + VertexBuffer vertexBuffer(vertices, numVertices); + vertexBuffer.unbind(); // This is the game loop while(!glfwWindowShouldClose(gameWindow->getGLFWwindow())) { // Timing limit_framerate(); - std::cout << "FPS: " << 1/deltaTime << std::endl; + static int slowdown = 0; + if(slowdown++ == 60) { + std::cout << "FPS: " << 1/deltaTime << std::endl; + slowdown = 0; + } // Update game // Render and buffer swap glClear(GL_COLOR_BUFFER_BIT); - glUseProgram(shaderProgram); - glBindVertexArray(VAO); + vertexBuffer.bind(); glDrawArrays(GL_TRIANGLES, 0, 3); + vertexBuffer.unbind(); glfwSwapBuffers(gameWindow->getGLFWwindow()); - // Check events, handle input gameEventHandler->handleEvents(gameWindow->getGLFWwindow()); } diff --git a/Controller.h b/Controller.h index fdc2ba0..525083f 100644 --- a/Controller.h +++ b/Controller.h @@ -26,17 +26,4 @@ private: double deltaTime; - const char *vertexShaderSource = "#version 330 core\n" - "layout (location = 0) in vec3 aPos;\n" - "void main() {\n" - " gl_Position = vec4(aPos.x, aPos.y, aPos.z, 1.0);\n" - "}\0"; - - - const char *fragmentShaderSource = "#version 330 core\n" - "out vec4 FragColor;\n" - "void main() {\n" - " FragColor = vec4(1.0f, 0.5f, 0.2f, 1.0f);\n" - "}\0"; - }; diff --git a/ShaderProgram.cpp b/ShaderProgram.cpp new file mode 100644 index 0000000..6f13278 --- /dev/null +++ b/ShaderProgram.cpp @@ -0,0 +1,84 @@ +#include +#include + +#include "ShaderProgram.h" + +ShaderProgram::ShaderProgram(const char* vertexShaderFilename, const char* fragmentShaderFilename) { + shaderProgramId = createShader(vertexShaderFilename, fragmentShaderFilename); +} + +ShaderProgram::~ShaderProgram() { + glDeleteProgram(shaderProgramId); +} + +void ShaderProgram::bind() { + glUseProgram(shaderProgramId); +} + +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 program = glCreateProgram(); + GLuint vs = compile(vertexShaderSource, GL_VERTEX_SHADER); + GLuint fs = compile(fragmentShaderSource, GL_FRAGMENT_SHADER); + + glAttachShader(program, vs); + glAttachShader(program, fs); + + glLinkProgram(program); + + #ifdef _RELEASE + glDetachShader(program, vs); + glDetachShader(program, fs); + + glDeleteShader(vs); + glDeleteShader(fs); + #endif + + return program; +} + +std::string ShaderProgram::parse(const char* filename) { + FILE* file; + file = fopen(filename, "rb"); + if(!file) { + std::cout << "File " << filename << " not found!" << std::endl; + exit(-1); + } + + std::string contents; + fseek(file, 0, SEEK_END); + size_t filesize = ftell(file); + rewind(file); + contents.resize(filesize); + + fread(&contents[0], 1, filesize, file); + fclose(file); + + return contents; +} + +GLuint ShaderProgram::compile(std::string shaderSource, GLenum type) { + GLuint shaderId = glCreateShader(type); + const char* src = shaderSource.c_str(); + glShaderSource(shaderId, 1, &src, 0); + glCompileShader(shaderId); + + int result; + glGetShaderiv(shaderId, GL_COMPILE_STATUS, &result); + if(result != GL_TRUE) { + int length; + glGetShaderiv(shaderId, GL_INFO_LOG_LENGTH, &length); + char* message = new char[length]; + glGetShaderInfoLog(shaderId, length, &length, message); + std::cout << "Shader compile error: " << message << std::endl; + delete[] message; + return 0; + } + return shaderId; +} diff --git a/ShaderProgram.h b/ShaderProgram.h new file mode 100644 index 0000000..36268d5 --- /dev/null +++ b/ShaderProgram.h @@ -0,0 +1,24 @@ +#pragma once + +#include +#include + +class ShaderProgram { + +public: + + ShaderProgram(const char* vertexShaderFilename, const char* framentShaderFilename); + ~ShaderProgram(); + + void bind(); + void unbind(); + +private: + + std::string parse(const char* filename); + GLuint compile(std::string shaderSource, GLenum type); + GLuint createShader(const char* vertexShaderFilename, const char* framentShaderFilename); + + GLuint shaderProgramId; + +}; \ No newline at end of file diff --git a/VertexBuffer.cpp b/VertexBuffer.cpp new file mode 100644 index 0000000..bb35623 --- /dev/null +++ b/VertexBuffer.cpp @@ -0,0 +1,32 @@ +#include + +#include "VertexBuffer.h" +#include "defines.h" + +VertexBuffer::VertexBuffer(void* data, uint32_t numVertices) { + glGenVertexArrays(1, &VAO); + glBindVertexArray(VAO); + + glGenBuffers(1, &bufferId); + glBindBuffer(GL_ARRAY_BUFFER, bufferId); + glBufferData(GL_ARRAY_BUFFER, numVertices * sizeof(Vertex), data, GL_STATIC_DRAW); + + glEnableVertexAttribArray(0); + glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*) offsetof(struct Vertex, x)); + glEnableVertexAttribArray(1); + glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*) offsetof(struct Vertex, r)); + + glBindVertexArray(0); +} + +VertexBuffer::~VertexBuffer() { + glDeleteBuffers(1, &bufferId); +} + +void VertexBuffer::bind() { + glBindVertexArray(VAO); +} + +void VertexBuffer::unbind() { + glBindVertexArray(0); +} diff --git a/VertexBuffer.h b/VertexBuffer.h new file mode 100644 index 0000000..7869c7e --- /dev/null +++ b/VertexBuffer.h @@ -0,0 +1,20 @@ +#pragma once + +#include + +class VertexBuffer { + +public: + + VertexBuffer(void* data, uint32_t numVertices); + ~VertexBuffer(); + + void bind(); + void unbind(); + +private: + + GLuint bufferId; + GLuint VAO; + +}; \ No newline at end of file diff --git a/res/shaders/old.fs b/res/shaders/old.fs new file mode 100644 index 0000000..59085e3 --- /dev/null +++ b/res/shaders/old.fs @@ -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/res/shaders/old.vs b/res/shaders/old.vs new file mode 100644 index 0000000..a50d935 --- /dev/null +++ b/res/shaders/old.vs @@ -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); +} \ No newline at end of file