From 8ad43456cfe75bbe3aeffa68a58ebb0a76268c61 Mon Sep 17 00:00:00 2001 From: Robert Date: Mon, 31 Aug 2020 15:36:57 +0200 Subject: [PATCH] Added primitives --- CMakeLists.txt | 2 + src/CMakeLists.txt | 7 ++- src/ShaderProgram.hpp | 95 ++++++++++++++++++++++++++++++++++++ src/main.cpp | 37 ++++++++++++++ src/primitives/IDrawable.hpp | 18 +++++++ src/primitives/Quad.hpp | 50 +++++++++++++++++++ src/primitives/Triangle.hpp | 36 ++++++++++++++ src/shaders/triangle.frag | 8 +++ src/shaders/triangle.vert | 7 +++ src/util.hpp | 6 +++ 10 files changed, 265 insertions(+), 1 deletion(-) create mode 100644 src/ShaderProgram.hpp create mode 100644 src/primitives/IDrawable.hpp create mode 100644 src/primitives/Quad.hpp create mode 100644 src/primitives/Triangle.hpp create mode 100644 src/shaders/triangle.frag create mode 100644 src/shaders/triangle.vert create mode 100644 src/util.hpp diff --git a/CMakeLists.txt b/CMakeLists.txt index fcae861..9c5712e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2,6 +2,8 @@ cmake_minimum_required(VERSION 3.7) project("ComplexPlotting") +set(CMAKE_CXX_STANDARD 17) + find_package(OpenGL REQUIRED) find_package(glfw3 REQUIRED) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 7113837..feca1ad 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,7 +1,7 @@ add_executable(ComplexPlotting "main.cpp" -) + "ShaderProgram.hpp") file(GLOB vendor_SRC ${CMAKE_SOURCE_DIR}/vendor/src/*.c @@ -13,9 +13,14 @@ target_sources(ComplexPlotting PRIVATE target_include_directories(ComplexPlotting PRIVATE glfw + ./primitives ${CMAKE_SOURCE_DIR}/vendor/include ) target_link_libraries(ComplexPlotting glfw +) + +add_custom_command(TARGET ComplexPlotting POST_BUILD + COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_SOURCE_DIR}/src/shaders $/shaders ) \ No newline at end of file diff --git a/src/ShaderProgram.hpp b/src/ShaderProgram.hpp new file mode 100644 index 0000000..f604f1f --- /dev/null +++ b/src/ShaderProgram.hpp @@ -0,0 +1,95 @@ +#pragma once + +#include + +#include +#include + +class ShaderProgram +{ +public: + ShaderProgram() = default; + + ~ShaderProgram() + { + glDeleteShader(fragmentShader_id); + glDeleteShader(vertexShader_id); + } + + std::string VertexShader, FragmentShader; + + int Build(char** error) + { + int success; + + // Vertex Shader initialization + if (VertexShader != "") + { + vertexShader_id = glCreateShader(GL_VERTEX_SHADER); + char* source = new char; + LoadFile(VertexShader, &source); + glShaderSource(vertexShader_id, 1, &source, NULL); + glCompileShader(vertexShader_id); + + glGetShaderiv(vertexShader_id, GL_COMPILE_STATUS, &success); + if (!success) + { + glGetShaderInfoLog(vertexShader_id, 512, NULL, *error); + return success; + } + } + + // Fragment Shader initialization + if (FragmentShader != "") + { + fragmentShader_id = glCreateShader(GL_FRAGMENT_SHADER); + char* source = new char; + LoadFile(FragmentShader, &source); + glShaderSource(fragmentShader_id, 1, &source, NULL); + glCompileShader(fragmentShader_id); + + glGetShaderiv(fragmentShader_id, GL_COMPILE_STATUS, &success); + if (!success) + { + glGetShaderInfoLog(fragmentShader_id, 512, NULL, *error); + return success; + } + } + + // Link shaders + program_id = glCreateProgram(); + glAttachShader(program_id, vertexShader_id); + glAttachShader(program_id, fragmentShader_id); + glLinkProgram(program_id); + + glGetProgramiv(program_id, GL_LINK_STATUS, &success); + if (!success) + { + glGetProgramInfoLog(program_id, 512, NULL, *error); + return success; + } + + return 1; + } + + void Use() + { + glUseProgram(program_id); + } + +private: + void LoadFile(std::string path, char** source) + { + std::ifstream file(path); + std::string shader( + (std::istreambuf_iterator(file)), + std::istreambuf_iterator() + ); + size_t s = shader.size(); + *source = (char*)realloc(*source, s + sizeof(char)); + memcpy_s(*source, s, shader.c_str(), s); + (*source)[s] = '\0'; + } + + unsigned int vertexShader_id, fragmentShader_id, program_id; +}; \ No newline at end of file diff --git a/src/main.cpp b/src/main.cpp index b23ab2f..bec458a 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -3,6 +3,10 @@ #include +#include "ShaderProgram.hpp" +#include "Triangle.hpp" +#include "Quad.hpp" + void LogGLFWerror() { const char* error = new const char; @@ -42,6 +46,32 @@ int main(int argc, char** argv) glViewport(0, 0, 800, 800); glfwSetFramebufferSizeCallback(window, FramebufferSizeCallback); + // Create Shader Program + ShaderProgram program; + program.VertexShader = "shaders/triangle.vert"; + program.FragmentShader = "shaders/triangle.frag"; + + char* error = new char; + if (!program.Build(&error)) + { + std::cout << error << std::endl; + return -1; + } + + // Make triangle + Triangle t( + { -0.5f, -0.5f, 0.f }, + { 0.5f, -0.5f, 0.f }, + { 0.f, 0.5, 0.f } + ); + + Quad q( + { -0.5f, 0.5f, 0.0f }, + { 0.5f, 0.5f, 0.0f }, + { 0.5f, -0.5f, 0.0f }, + { -0.5f, -0.5f, 0.0f } + ); + while (!glfwWindowShouldClose(window)) { glfwPollEvents(); @@ -49,8 +79,15 @@ int main(int argc, char** argv) glClearColor(0.4f, 0.1f, 0.5f, 1.0f); glClear(GL_COLOR_BUFFER_BIT); + program.Use(); + q.Draw(); + glfwSwapBuffers(window); } + glfwDestroyWindow(window); + + glfwTerminate(); + return 0; } \ No newline at end of file diff --git a/src/primitives/IDrawable.hpp b/src/primitives/IDrawable.hpp new file mode 100644 index 0000000..4bdd78b --- /dev/null +++ b/src/primitives/IDrawable.hpp @@ -0,0 +1,18 @@ +#pragma once + +#include + +class IDrawable +{ +public: + virtual void Draw() = 0; + +protected: + IDrawable() + { + glCreateVertexArrays(1, &VAO); + glCreateBuffers(1, &VBO); + } + + unsigned int VBO, VAO; +}; \ No newline at end of file diff --git a/src/primitives/Quad.hpp b/src/primitives/Quad.hpp new file mode 100644 index 0000000..0fd6683 --- /dev/null +++ b/src/primitives/Quad.hpp @@ -0,0 +1,50 @@ +#pragma once +#include + +#include "IDrawable.hpp" +#include "util.hpp" + +class Quad : + public IDrawable +{ +public: + Quad(Vec3 topLeft, Vec3 topRight, Vec3 botRight, Vec3 botLeft) + { + memcpy_s(vertices + 0, sizeof(vertices), &topLeft, sizeof(topLeft)); + memcpy_s(vertices + 3, sizeof(vertices), &topRight, sizeof(topRight)); + memcpy_s(vertices + 6, sizeof(vertices), &botRight, sizeof(botRight)); + memcpy_s(vertices + 9, sizeof(vertices), &botLeft, sizeof(botLeft)); + + glGenBuffers(1, &EBO); + + glBindVertexArray(VAO); + + glBindBuffer(GL_ARRAY_BUFFER, VBO); + glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); + + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO); + glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW); + + glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0); + glEnableVertexAttribArray(0); + + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); + glBindBuffer(GL_ARRAY_BUFFER, 0); + glBindVertexArray(0); + } + + void Draw() override + { + glBindVertexArray(VAO); + glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, indices); + glBindVertexArray(0); + } + +private: + unsigned int EBO; + float vertices[3 * 4]; + inline static unsigned int indices[6] = { + 0, 1, 3, + 1, 2, 3 + }; +}; \ No newline at end of file diff --git a/src/primitives/Triangle.hpp b/src/primitives/Triangle.hpp new file mode 100644 index 0000000..6f0fd71 --- /dev/null +++ b/src/primitives/Triangle.hpp @@ -0,0 +1,36 @@ +#include + +#include "IDrawable.hpp" +#include "util.hpp" + +class Triangle : + public IDrawable +{ +public: + Triangle(Vec3 v1, Vec3 v2, Vec3 v3) + { + memcpy_s(vertices + 0, 9 * sizeof(float), &v1, 3 * sizeof(float)); + memcpy_s(vertices + 3, 9 * sizeof(float), &v2, 3 * sizeof(float)); + memcpy_s(vertices + 6, 9 * sizeof(float), &v3, 3 * sizeof(float)); + + glBindVertexArray(VAO); + 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); + } + + void Draw() override + { + glBindVertexArray(VAO); + glDrawArrays(GL_TRIANGLES, 0, 3); + glBindVertexArray(0); + } + +private: + float vertices[9]; +}; \ No newline at end of file diff --git a/src/shaders/triangle.frag b/src/shaders/triangle.frag new file mode 100644 index 0000000..c6bc8c8 --- /dev/null +++ b/src/shaders/triangle.frag @@ -0,0 +1,8 @@ +#version 460 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/src/shaders/triangle.vert b/src/shaders/triangle.vert new file mode 100644 index 0000000..e19ad4f --- /dev/null +++ b/src/shaders/triangle.vert @@ -0,0 +1,7 @@ +#version 460 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 diff --git a/src/util.hpp b/src/util.hpp new file mode 100644 index 0000000..5264dfa --- /dev/null +++ b/src/util.hpp @@ -0,0 +1,6 @@ +#pragma once + +typedef struct +{ + float x, y, z; +} Vec3; \ No newline at end of file