From 3157af8064dc178356c6888fabbaee50b1607916 Mon Sep 17 00:00:00 2001 From: Vitor Fernandes Date: Sat, 20 Jun 2020 01:30:40 +0100 Subject: [PATCH] Loading files from shader files --- CMakeLists.txt | 2 +- src/opengl/CMakeLists.txt | 12 +++ src/opengl/gl1.cpp | 137 ++++++++++++++++++++++++++-- src/opengl/res/shaders/Basic.shader | 15 +++ 4 files changed, 158 insertions(+), 8 deletions(-) create mode 100644 src/opengl/res/shaders/Basic.shader diff --git a/CMakeLists.txt b/CMakeLists.txt index febd846..668fa7b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,5 +1,5 @@ project(cpplab) -cmake_minimum_required(VERSION 2.8) +cmake_minimum_required(VERSION 3.17) set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib) set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib) diff --git a/src/opengl/CMakeLists.txt b/src/opengl/CMakeLists.txt index d5cd85d..fabf75d 100644 --- a/src/opengl/CMakeLists.txt +++ b/src/opengl/CMakeLists.txt @@ -1,5 +1,17 @@ +# Search for glfw find_package(glfw3 3.3 REQUIRED) +# Search for glew +find_package(GLEW REQUIRED) +# Search for OpenGL find_package(OpenGL REQUIRED) + + +# Add gl1 executable build from gl1.cpp add_executable(gl1 gl1.cpp) + +# Link gl1 with glfw lib target_link_libraries(gl1 glfw) +# Link gl1 with OpenGL target_link_libraries(gl1 OpenGL::GL) +# Link gl1 with glew +#target_link_libraries(gl1 glew) diff --git a/src/opengl/gl1.cpp b/src/opengl/gl1.cpp index 1ba9af8..e4bdb1c 100644 --- a/src/opengl/gl1.cpp +++ b/src/opengl/gl1.cpp @@ -1,15 +1,111 @@ #include +#include +#include +#include +#include + +typedef unsigned int uint; + +struct ShaderProgramSource{ + std::string VertexSource; + std::string FragmentSource; +}; + +const std::string SHADERS_PATH="src/opengl/res/shaders/Basic.shader"; + +static ShaderProgramSource ParseShader(const std::string path) +{ + std::ifstream stream(path); + std::string line; + enum class ShaderType { + NONE=-1,VERTEX=0,FRAGMENT=1 + }; + std::stringstream ss[2]; + ShaderType type = ShaderType::NONE; + while (getline(stream, line)) + { + if (line.find("#shader") != std::string::npos) + { + if (line.find("vertex") != std::string::npos) + { + //vertex + type=ShaderType::VERTEX; + } + else if (line.find("fragment") != std::string::npos) + { + //Fragment + type=ShaderType::FRAGMENT; + } + }else + { + ss[(int)type] << line << '\n'; + } + } + return {ss[0].str(),ss[1].str()}; +} + +static uint CompileShader(uint type, const std::string &source) +{ + uint id = glCreateShader(type); + std::cout << "Shader ID: " << id << std::endl; + const char *const src = source.c_str(); + + //std::cout << "Source: " << std::endl << src << std::endl << std::endl; + glShaderSource(id, 1, &src, nullptr); + + int result; + glGetShaderiv(id, GL_COMPILE_STATUS, &result); + + if (result == GL_FALSE) + { + int length; + glGetShaderiv(id, GL_INFO_LOG_LENGTH, &length); + std::cout << "Length: " << length << std::endl; + char *message = (char *)malloc(length * sizeof(char)); + glGetShaderInfoLog(id, length, &length, message); + + std::cout << "Failed to compile " + << (type == GL_VERTEX_SHADER ? "vertex" : "fragment") << " shader: " << std::endl; + + std::cout << message << std::endl; + free(message); + glDeleteProgram(id); + return 0; + } + + return id; +}; + +/** + * Creates both shaders, links them and returns an identifier + */ +static uint CreateShader(const std::string &vertexShader, const std::string &fragmentShader) +{ + uint program = glCreateProgram(); + uint vs = CompileShader(GL_VERTEX_SHADER, vertexShader); + uint fs = CompileShader(GL_FRAGMENT_SHADER, fragmentShader); + + glAttachShader(program, vs); + glAttachShader(program, fs); + glLinkProgram(program); + glValidateProgram(program); + + glDeleteShader(vs); + glDeleteShader(fs); + + return program; +}; int main(void) { - GLFWwindow* window; + GLFWwindow *window; /* Initialize the library */ if (!glfwInit()) return -1; /* Create a windowed mode window and its OpenGL context */ - window = glfwCreateWindow(640, 480, "Hello World", NULL, NULL); + window = glfwCreateWindow(640, 480, "OpenGL Window", NULL, NULL); if (!window) { glfwTerminate(); @@ -19,17 +115,44 @@ int main(void) /* Make the window's context current */ glfwMakeContextCurrent(window); + //Print opengl version + std::cout << glGetString(GL_VERSION) << std::endl; + + float positions[6] = {-1.0f, -1.0f, 0.0f, 1.0f, 1.0f, -1.0f}; + + //Create buffer + //Buffer id + unsigned int buffer; + glGenBuffers(1, &buffer); + glBindBuffer(GL_ARRAY_BUFFER, buffer); + glBufferData(GL_ARRAY_BUFFER, 6 * sizeof(float), positions, GL_STATIC_DRAW); + glEnableVertexAttribArray(0); + glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(float) * 2, 0); + + ShaderProgramSource source = ParseShader(SHADERS_PATH); + + std::cout << "Shaders: " << source.VertexSource << std::endl; + std::cout << std::endl; + std::cout << source.FragmentSource << std::endl; + + uint shader = CreateShader(source.VertexSource, source.FragmentSource); + glUseProgram(shader); + /* Loop until the user closes the window */ while (!glfwWindowShouldClose(window)) { /* Render here */ glClear(GL_COLOR_BUFFER_BIT); - glBegin(GL_TRIANGLES); - glVertex2f(-1.0f,-1.0f); - glVertex2f(0.0f,1.0f); - glVertex2f(1.0f,-1.0f); - glEnd(); + // Legacy OpenGL + //glBegin(GL_TRIANGLES); + //glVertex2f(-1.0f, -1.0f); + //glVertex2f(0.0f, 1.0f); + //glVertex2f(1.0f, -1.0f); + //glEnd(); + + //Modern OpenGL + glDrawArrays(GL_TRIANGLES, 0, 3); /* Swap front and back buffers */ glfwSwapBuffers(window); diff --git a/src/opengl/res/shaders/Basic.shader b/src/opengl/res/shaders/Basic.shader new file mode 100644 index 0000000..230a944 --- /dev/null +++ b/src/opengl/res/shaders/Basic.shader @@ -0,0 +1,15 @@ +#shader vertex +#version 330 core +layout(location = 0) in vec4 position; + +void main(){ + gl_Position=position; +} + +#shader fragment +#version 330 core +layout(location = 0) out vec4 color; + +void main(){ + color=vec4(1.0,0.0,0.0,1.0); +} \ No newline at end of file