From dc320edc4a56335496cd5792f9b88c15a8e08444 Mon Sep 17 00:00:00 2001 From: KerelOlivier Date: Tue, 3 May 2022 23:06:13 +0200 Subject: [PATCH] add: shader class --- CMakeLists.txt | 2 +- main.cpp | 51 +++++++++++++++++++++++ src/Shader.cpp | 92 +++++++++++++++++++++++++++++++++++++++++ src/Shader.h | 29 +++++++++++++ src/shaders/shader.frag | 8 ++++ src/shaders/shader.vert | 11 +++++ 6 files changed, 192 insertions(+), 1 deletion(-) create mode 100644 src/Shader.cpp create mode 100644 src/Shader.h create mode 100644 src/shaders/shader.frag create mode 100644 src/shaders/shader.vert diff --git a/CMakeLists.txt b/CMakeLists.txt index 619d188..18dd039 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -5,5 +5,5 @@ set(CMAKE_CXX_STANDARD 20) include_directories(include) add_compile_options(-lglfw3 -lGL -lX11 -lpthread -lXrandr -lXi -ldl) -add_executable(app main.cpp src/glad.c) +add_executable(app main.cpp src/Shader.cpp src/glad.c) target_link_libraries(app glfw) \ No newline at end of file diff --git a/main.cpp b/main.cpp index df7b340..ca8eecd 100644 --- a/main.cpp +++ b/main.cpp @@ -6,6 +6,7 @@ #include #include +#include "src/Shader.h" void framebuffer_size_callback(GLFWwindow* window, int width, int height); @@ -38,12 +39,62 @@ int main() { glViewport(0, 0, 800, 600); glfwSetFramebufferSizeCallback(window, framebuffer_size_callback); + //// Setup geometry + float vertices[] = { + 0.5f, 0.5f, 0.0f, 1.0f, 1.0f, 0.0f, // top right + 0.5f, -0.5f, 0.0f, 0.0f, 1.0f, 0.0f, // bottom right + -0.5f, -0.5f, 0.0f,0.0f, 0.0f, 1.0f, // bottom left + -0.5f, 0.5f, 0.0f,1.0f, 0.0f, 0.0f // top left + }; + unsigned int indices[] = { + 0, 1, 3, // first triangle + 1, 2, 3 // second triangle + }; + + unsigned int VBO, VAO, EBO; + + + //generate buffers + glGenBuffers(1, &VBO); + glGenVertexArrays(1, &VAO); + glGenBuffers(1, &EBO); + + //Bind buffers + glBindBuffer(GL_ARRAY_BUFFER, VBO); + glBindVertexArray(VAO); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO); + + //copy data to buffers + glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); + glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW); + + //SetVertexAttribPointer + glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), nullptr); + glEnableVertexAttribArray(0); + glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (void*)(3*sizeof(float))); + glEnableVertexAttribArray(1); + + + //Create shaders + Shader ourShader("src/shaders/shader.vert", "src/shaders/shader.frag"); + ourShader.use(); + + + + // Render loop while(!glfwWindowShouldClose(window)) { // Render glClearColor(0.2f, 0.3f, 0.3f, 1.0f); glClear(GL_COLOR_BUFFER_BIT); + ourShader.use(); + glBindVertexArray(VAO); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO); + + glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, nullptr); + + // Swap buffers glfwSwapBuffers(window); glfwPollEvents(); diff --git a/src/Shader.cpp b/src/Shader.cpp new file mode 100644 index 0000000..2c48848 --- /dev/null +++ b/src/Shader.cpp @@ -0,0 +1,92 @@ +// +// Created by olivier on 5/3/22. +// + +#include "Shader.h" + +Shader::Shader(const char* vertexPath, const char* fragmentPath){ + // 1. retrieve the vertex/fragment source code from filePath + std::string vertexCode; + std::string fragmentCode; + std::ifstream vShaderFile; + std::ifstream fShaderFile; + // ensure ifstream objects can throw exceptions: + vShaderFile.exceptions (std::ifstream::failbit | std::ifstream::badbit); + fShaderFile.exceptions (std::ifstream::failbit | std::ifstream::badbit); + try{ + // open files + vShaderFile.open(vertexPath); + fShaderFile.open(fragmentPath); + std::stringstream vShaderStream, fShaderStream; + // read file's buffer contents into streams + vShaderStream << vShaderFile.rdbuf(); + fShaderStream << fShaderFile.rdbuf(); + // close file handlers + vShaderFile.close(); + fShaderFile.close(); + // convert stream into string + vertexCode = vShaderStream.str(); + fragmentCode = fShaderStream.str(); + } + catch (std::ifstream::failure &e){ + std::cout << "ERROR::SHADER::FILE_NOT_SUCCESFULLY_READ" << std::endl; + } + const char* vShaderCode = vertexCode.c_str(); + const char* fShaderCode = fragmentCode.c_str(); + // 2. compile shaders + unsigned int vertex, fragment; + int success; + char infoLog[512]; + // vertex shader + vertex = glCreateShader(GL_VERTEX_SHADER); + glShaderSource(vertex, 1, &vShaderCode, nullptr); + glCompileShader(vertex); + // check for shader compile errors + glGetShaderiv(vertex, GL_COMPILE_STATUS, &success); + if (!success){ + glGetShaderInfoLog(vertex, 512, nullptr, infoLog); + std::cout << vShaderCode << std::endl; + std::cout << "ERROR::SHADER::VERTEX::COMPILATION_FAILED\n" << infoLog << std::endl; + } + // fragment shader + fragment = glCreateShader(GL_FRAGMENT_SHADER); + glShaderSource(fragment, 1, &fShaderCode, nullptr); + glCompileShader(fragment); + // check for shader compile errors + glGetShaderiv(fragment, GL_COMPILE_STATUS, &success); + if (!success){ + glGetShaderInfoLog(fragment, 512, nullptr, infoLog); + std::cout << fShaderCode << std::endl; + std::cout << "ERROR::SHADER::FRAGMENT::COMPILATION_FAILED\n" << infoLog << std::endl; + } + // shader program + ID = glCreateProgram(); + glAttachShader(ID, vertex); + glAttachShader(ID, fragment); + glLinkProgram(ID); + // check for linking errors + if (!success){ + glGetProgramiv(ID, GL_LINK_STATUS, &success); + if (!success){ + glGetProgramInfoLog(ID, 512, nullptr, infoLog); + std::cout << "ERROR::SHADER::PROGRAM::LINKING_FAILED\n" << infoLog << std::endl; + } + } + // delete the shaders as they're linked into our program now and no longer necessery + glDeleteShader(vertex); + glDeleteShader(fragment); +} + +void Shader::use(){ + glUseProgram(ID); +} + +void Shader::setBool(const std::string &name, bool value) const { + glUniform1i(glGetUniformLocation(ID, name.c_str()), (int)value); +} +void Shader::setInt(const std::string &name, int value) const { + glUniform1i(glGetUniformLocation(ID, name.c_str()), value); +} +void Shader::setFloat(const std::string &name, float value) const { + glUniform1f(glGetUniformLocation(ID, name.c_str()), value); +} \ No newline at end of file diff --git a/src/Shader.h b/src/Shader.h new file mode 100644 index 0000000..79ddf9a --- /dev/null +++ b/src/Shader.h @@ -0,0 +1,29 @@ +// +// Created by olivier on 5/3/22. +// + +#ifndef OPENGL_TEMPLATE_SHADER_H +#define OPENGL_TEMPLATE_SHADER_H + + +#include +#include +#include +#include +#include "glad/glad.h" + +class Shader { +public: + unsigned int ID; + + Shader(const char* vertexPath, const char* fragmentPath); + // activate the shader + void use(); + // utility uniform functions + void setBool(const std::string &name, bool value) const; + void setInt(const std::string &name, int value) const; + void setFloat(const std::string &name, float value) const; +}; + + +#endif //OPENGL_TEMPLATE_SHADER_H diff --git a/src/shaders/shader.frag b/src/shaders/shader.frag new file mode 100644 index 0000000..2d660ac --- /dev/null +++ b/src/shaders/shader.frag @@ -0,0 +1,8 @@ +#version 330 core +out vec4 FragColor; +in vec3 ourColor; + +void main() +{ + FragColor = vec4(ourColor, 1.0); +} \ No newline at end of file diff --git a/src/shaders/shader.vert b/src/shaders/shader.vert new file mode 100644 index 0000000..38dc7f0 --- /dev/null +++ b/src/shaders/shader.vert @@ -0,0 +1,11 @@ +#version 330 core +layout (location = 0) in vec3 aPos; // the position variable has attribute position 0 +layout (location = 1) in vec3 aColor; // the color variable has attribute position 1 + +out vec3 ourColor; // output a color to the fragment shader + +void main() +{ + gl_Position = vec4(aPos, 1.0); + ourColor = aColor; // set ourColor to the input color we got from the vertex data +} \ No newline at end of file