From 318a070aca307cae4a15d60dba481eba97a1d885 Mon Sep 17 00:00:00 2001 From: Ruixiang Du Date: Sat, 2 Nov 2024 22:45:02 +0800 Subject: [PATCH] component: added shader and shader_program class --- .github/workflows/default.yml | 4 +- data/glsl/fragment_shader.glsl | 6 ++ data/glsl/vertex_shader.glsl | 6 ++ src/app/panels/main_docking_panel.hpp | 2 +- src/imview/CMakeLists.txt | 16 ++-- .../details => component}/cairo_context.hpp | 0 .../details => component}/cairo_draw.hpp | 0 .../frame_buffer.hpp} | 22 ++--- .../{utils => component}/image_utils.hpp | 0 .../{widget/details => component}/shader.hpp | 22 +++-- .../imview/component/shader_program.hpp | 45 +++++++++ .../include/imview/widget/cairo_widget.hpp | 4 +- .../include/imview/widget/gl_scene_widget.hpp | 35 ------- .../include/imview/widget/gl_widget.hpp | 35 +++++++ .../details => component}/cairo_context.cpp | 2 +- .../details => component}/cairo_draw.cpp | 2 +- .../frame_buffer.cpp} | 20 ++-- .../src/{utils => component}/image_utils.cpp | 2 +- src/imview/src/component/shader.cpp | 75 +++++++++++++++ src/imview/src/component/shader_program.cpp | 75 +++++++++++++++ .../src/widget/buffered_cv_image_widget.cpp | 2 +- src/imview/src/widget/cv_image_widget.cpp | 2 +- src/imview/src/widget/details/shader.cpp | 11 --- .../{gl_scene_widget.cpp => gl_widget.cpp} | 12 +-- src/imview/src/window.cpp | 4 +- src/imview/test/CMakeLists.txt | 3 + .../test/feature/test_gl_scene_widget.cpp | 6 +- src/imview/test/test_framebuffer.cpp | 5 +- src/imview/test/test_shader.cpp | 91 +++++++++++++++++++ 29 files changed, 402 insertions(+), 107 deletions(-) create mode 100644 data/glsl/fragment_shader.glsl create mode 100644 data/glsl/vertex_shader.glsl rename src/imview/include/imview/{widget/details => component}/cairo_context.hpp (100%) rename src/imview/include/imview/{widget/details => component}/cairo_draw.hpp (100%) rename src/imview/include/imview/{widget/details/gl_frame_buffer.hpp => component/frame_buffer.hpp} (63%) rename src/imview/include/imview/{utils => component}/image_utils.hpp (100%) rename src/imview/include/imview/{widget/details => component}/shader.hpp (56%) create mode 100644 src/imview/include/imview/component/shader_program.hpp delete mode 100644 src/imview/include/imview/widget/gl_scene_widget.hpp create mode 100644 src/imview/include/imview/widget/gl_widget.hpp rename src/imview/src/{widget/details => component}/cairo_context.cpp (98%) rename src/imview/src/{widget/details => component}/cairo_draw.cpp (98%) rename src/imview/src/{widget/details/gl_frame_buffer.cpp => component/frame_buffer.cpp} (81%) rename src/imview/src/{utils => component}/image_utils.cpp (96%) create mode 100644 src/imview/src/component/shader.cpp create mode 100644 src/imview/src/component/shader_program.cpp delete mode 100644 src/imview/src/widget/details/shader.cpp rename src/imview/src/widget/{gl_scene_widget.cpp => gl_widget.cpp} (74%) create mode 100644 src/imview/test/test_shader.cpp diff --git a/.github/workflows/default.yml b/.github/workflows/default.yml index 5ffaf5a..cf89464 100644 --- a/.github/workflows/default.yml +++ b/.github/workflows/default.yml @@ -20,7 +20,9 @@ jobs: - name: Checkout submodules run: git submodule update --init --recursive - name: Install Dependencies - run: sudo apt-get update && sudo apt-get install -y libgl1-mesa-dev libglfw3-dev libcairo2-dev libopencv-dev + run: | + sudo apt-get update && sudo apt-get install -y libgl1-mesa-dev \ + libglfw3-dev libcairo2-dev libopencv-dev libglm-dev - name: Create Build Environment run: cmake -E make_directory ${{runner.workspace}}/build - name: Configure CMake (Ubuntu 20.04) diff --git a/data/glsl/fragment_shader.glsl b/data/glsl/fragment_shader.glsl new file mode 100644 index 0000000..07d1335 --- /dev/null +++ b/data/glsl/fragment_shader.glsl @@ -0,0 +1,6 @@ +#version 330 core +out vec4 FragColor; +void main() +{ + FragColor = vec4(0.2, 0.5, 0.8, 1.0); +} diff --git a/data/glsl/vertex_shader.glsl b/data/glsl/vertex_shader.glsl new file mode 100644 index 0000000..75215ea --- /dev/null +++ b/data/glsl/vertex_shader.glsl @@ -0,0 +1,6 @@ +#version 330 core +layout (location = 0) in vec3 aPos; +void main() +{ + gl_Position = vec4(aPos, 1.0); +} diff --git a/src/app/panels/main_docking_panel.hpp b/src/app/panels/main_docking_panel.hpp index 615627d..1d51b0a 100644 --- a/src/app/panels/main_docking_panel.hpp +++ b/src/app/panels/main_docking_panel.hpp @@ -11,7 +11,7 @@ #include "imview/panel.hpp" -#include "imview/widget/gl_scene_widget.hpp" +#include "imview/widget/gl_widget.hpp" #include "panels/menu_bar.hpp" #include "panels/config_panel.hpp" diff --git a/src/imview/CMakeLists.txt b/src/imview/CMakeLists.txt index fa93889..55dd257 100644 --- a/src/imview/CMakeLists.txt +++ b/src/imview/CMakeLists.txt @@ -24,19 +24,19 @@ add_library(imview src/panel.cpp src/layer.cpp ${AUTO_LAYOUT_SRC} - # src/popup.cpp - # utils - src/utils/image_utils.cpp # widgets src/widget/cv_image_widget.cpp src/widget/buffered_cv_image_widget.cpp src/widget/cairo_widget.cpp - src/widget/details/cairo_context.cpp - src/widget/details/cairo_draw.cpp src/widget/rt_line_plot_widget.cpp - src/widget/gl_scene_widget.cpp - src/widget/details/gl_frame_buffer.cpp - src/widget/details/shader.cpp + src/widget/gl_widget.cpp + # components + src/component/cairo_context.cpp + src/component/cairo_draw.cpp + src/component/image_utils.cpp + src/component/shader.cpp + src/component/shader_program.cpp + src/component/frame_buffer.cpp # data buffer src/buffer/buffer_registry.cpp src/buffer/scrolling_plot_buffer.cpp diff --git a/src/imview/include/imview/widget/details/cairo_context.hpp b/src/imview/include/imview/component/cairo_context.hpp similarity index 100% rename from src/imview/include/imview/widget/details/cairo_context.hpp rename to src/imview/include/imview/component/cairo_context.hpp diff --git a/src/imview/include/imview/widget/details/cairo_draw.hpp b/src/imview/include/imview/component/cairo_draw.hpp similarity index 100% rename from src/imview/include/imview/widget/details/cairo_draw.hpp rename to src/imview/include/imview/component/cairo_draw.hpp diff --git a/src/imview/include/imview/widget/details/gl_frame_buffer.hpp b/src/imview/include/imview/component/frame_buffer.hpp similarity index 63% rename from src/imview/include/imview/widget/details/gl_frame_buffer.hpp rename to src/imview/include/imview/component/frame_buffer.hpp index 1ac8758..a97205a 100644 --- a/src/imview/include/imview/widget/details/gl_frame_buffer.hpp +++ b/src/imview/include/imview/component/frame_buffer.hpp @@ -1,27 +1,27 @@ /* - * @file gl_frame_buffer.hpp + * @file frame_buffer.hpp * @date 10/29/24 * @brief * * @copyright Copyright (c) 2024 Ruixiang Du (rdu) */ -#ifndef XMOTION_GL_FRAME_BUFFER_HPP -#define XMOTION_GL_FRAME_BUFFER_HPP +#ifndef XMOTION_FRAME_BUFFER_HPP +#define XMOTION_FRAME_BUFFER_HPP #include namespace quickviz { -class GlFrameBuffer { +class FrameBuffer { public: - GlFrameBuffer(uint32_t width, uint32_t height); - ~GlFrameBuffer(); + FrameBuffer(uint32_t width, uint32_t height); + ~FrameBuffer(); // do not allow copy or move - GlFrameBuffer(const GlFrameBuffer&) = delete; - GlFrameBuffer& operator=(const GlFrameBuffer&) = delete; - GlFrameBuffer(GlFrameBuffer&&) = delete; - GlFrameBuffer& operator=(GlFrameBuffer&&) = delete; + FrameBuffer(const FrameBuffer&) = delete; + FrameBuffer& operator=(const FrameBuffer&) = delete; + FrameBuffer(FrameBuffer&&) = delete; + FrameBuffer& operator=(FrameBuffer&&) = delete; // public methods void Bind(bool keep_aspect_ratio = true) const; @@ -45,4 +45,4 @@ class GlFrameBuffer { }; } // namespace quickviz -#endif // XMOTION_GL_FRAME_BUFFER_HPP \ No newline at end of file +#endif // XMOTION_FRAME_BUFFER_HPP \ No newline at end of file diff --git a/src/imview/include/imview/utils/image_utils.hpp b/src/imview/include/imview/component/image_utils.hpp similarity index 100% rename from src/imview/include/imview/utils/image_utils.hpp rename to src/imview/include/imview/component/image_utils.hpp diff --git a/src/imview/include/imview/widget/details/shader.hpp b/src/imview/include/imview/component/shader.hpp similarity index 56% rename from src/imview/include/imview/widget/details/shader.hpp rename to src/imview/include/imview/component/shader.hpp index 1b3f8eb..a329006 100644 --- a/src/imview/include/imview/widget/details/shader.hpp +++ b/src/imview/include/imview/component/shader.hpp @@ -9,35 +9,39 @@ #ifndef XMOTION_SHADER_HPP #define XMOTION_SHADER_HPP +#include #include #include -#include - -#include "glad/glad.h" - namespace quickviz { class Shader { public: - enum class Type { + enum class Type : uint32_t { kUnknown = 0, kVertex, kFragment, }; public: - Shader(const std::string& source, Type type); + Shader(const std::string& source_file, Type type); ~Shader(); + // do not allow copy + Shader(const Shader&) = delete; + Shader& operator=(const Shader&) = delete; + // public methods - void Compile(); - GLuint GetShaderID() const { return shader_id_; } + void Print() const; + bool Compile(); + uint32_t GetShaderID() const { return shader_id_; } private: std::string LoadSourceFile(const std::string& file_path); - GLuint shader_id_; + std::string source_file_; Type type_; + std::string source_code_; + uint32_t shader_id_; }; } // namespace quickviz diff --git a/src/imview/include/imview/component/shader_program.hpp b/src/imview/include/imview/component/shader_program.hpp new file mode 100644 index 0000000..ef3afd2 --- /dev/null +++ b/src/imview/include/imview/component/shader_program.hpp @@ -0,0 +1,45 @@ +/* + * @file shader_program.hpp + * @date 11/2/24 + * @brief + * + * @copyright Copyright (c) 2024 Ruixiang Du (rdu) + */ + +#ifndef QUICKVIZ_SHADER_PROGRAM_HPP +#define QUICKVIZ_SHADER_PROGRAM_HPP + +#include + +#include +#include + +#include "imview/component/shader.hpp" + +namespace quickviz { +class ShaderProgram { + public: + ShaderProgram(); + ~ShaderProgram(); + + // public methods + void AttachShader(const Shader& shader); + bool LinkProgram(); + void Use() const; + + // Uniform setting functions + void SetUniform(const std::string& name, bool value); + void SetUniform(const std::string& name, int value); + void SetUniform(const std::string& name, float value); + void SetUniform(const std::string& name, const glm::vec3& vector); + void SetUniform(const std::string& name, const glm::mat4& matrix); + + private: + uint32_t GetUniformLocation(const std::string& name); + + uint32_t program_id_; + std::unordered_map uniform_location_cache_; +}; +} // namespace quickviz + +#endif // QUICKVIZ_SHADER_PROGRAM_HPP \ No newline at end of file diff --git a/src/imview/include/imview/widget/cairo_widget.hpp b/src/imview/include/imview/widget/cairo_widget.hpp index 7422f34..c556426 100644 --- a/src/imview/include/imview/widget/cairo_widget.hpp +++ b/src/imview/include/imview/widget/cairo_widget.hpp @@ -21,8 +21,8 @@ #include "imgui.h" #include "imview/panel.hpp" -#include "imview/widget/details/cairo_context.hpp" -#include "imview/widget/details/cairo_draw.hpp" +#include "imview/component/cairo_context.hpp" +#include "imview/component/cairo_draw.hpp" namespace quickviz { class CairoWidget : public Panel { diff --git a/src/imview/include/imview/widget/gl_scene_widget.hpp b/src/imview/include/imview/widget/gl_scene_widget.hpp deleted file mode 100644 index d3d791b..0000000 --- a/src/imview/include/imview/widget/gl_scene_widget.hpp +++ /dev/null @@ -1,35 +0,0 @@ -/* - * @file gl_scene_widget.hpp - * @date 10/29/24 - * @brief - * - * @copyright Copyright (c) 2024 Ruixiang Du (rdu) - */ - -#ifndef XMOTION_GL_SCENE_WIDGET_HPP -#define XMOTION_GL_SCENE_WIDGET_HPP - -#include -#include - -#include "imview/panel.hpp" -#include "imview/widget/details/gl_frame_buffer.hpp" - -namespace quickviz { -class GlSceneWidget : public Panel { - public: - GlSceneWidget(const std::string& widget_name); - ~GlSceneWidget() = default; - - // public methods - using GlRenderFunction = std::function; - void SetGlRenderFunction(GlRenderFunction func); - void Draw() override; - - private: - GlRenderFunction render_function_; - std::unique_ptr frame_buffer_; -}; -} // namespace quickviz - -#endif // XMOTION_GL_SCENE_WIDGET_HPP \ No newline at end of file diff --git a/src/imview/include/imview/widget/gl_widget.hpp b/src/imview/include/imview/widget/gl_widget.hpp new file mode 100644 index 0000000..5680434 --- /dev/null +++ b/src/imview/include/imview/widget/gl_widget.hpp @@ -0,0 +1,35 @@ +/* + * @file gl_widget.hpp + * @date 10/29/24 + * @brief + * + * @copyright Copyright (c) 2024 Ruixiang Du (rdu) + */ + +#ifndef XMOTION_GL_WIDGET_HPP +#define XMOTION_GL_WIDGET_HPP + +#include +#include + +#include "imview/panel.hpp" +#include "imview/component/frame_buffer.hpp" + +namespace quickviz { +class GlWidget : public Panel { + public: + GlWidget(const std::string& widget_name); + ~GlWidget() = default; + + // public methods + using GlRenderFunction = std::function; + void SetGlRenderFunction(GlRenderFunction func); + void Draw() override; + + private: + GlRenderFunction render_function_; + std::unique_ptr frame_buffer_; +}; +} // namespace quickviz + +#endif // XMOTION_GL_WIDGET_HPP \ No newline at end of file diff --git a/src/imview/src/widget/details/cairo_context.cpp b/src/imview/src/component/cairo_context.cpp similarity index 98% rename from src/imview/src/widget/details/cairo_context.cpp rename to src/imview/src/component/cairo_context.cpp index 78b76bf..d4dccfb 100644 --- a/src/imview/src/widget/details/cairo_context.cpp +++ b/src/imview/src/component/cairo_context.cpp @@ -7,7 +7,7 @@ * Copyright (c) 2021 Ruixiang Du (rdu) */ -#include "imview/widget/details/cairo_context.hpp" +#include "imview/component/cairo_context.hpp" #include diff --git a/src/imview/src/widget/details/cairo_draw.cpp b/src/imview/src/component/cairo_draw.cpp similarity index 98% rename from src/imview/src/widget/details/cairo_draw.cpp rename to src/imview/src/component/cairo_draw.cpp index 2f5f3b0..1b18325 100644 --- a/src/imview/src/widget/details/cairo_draw.cpp +++ b/src/imview/src/component/cairo_draw.cpp @@ -7,7 +7,7 @@ * Copyright (c) 2021 Ruixiang Du (rdu) */ -#include "imview/widget/details/cairo_draw.hpp" +#include "imview/component/cairo_draw.hpp" #include diff --git a/src/imview/src/widget/details/gl_frame_buffer.cpp b/src/imview/src/component/frame_buffer.cpp similarity index 81% rename from src/imview/src/widget/details/gl_frame_buffer.cpp rename to src/imview/src/component/frame_buffer.cpp index 09578c7..d154192 100644 --- a/src/imview/src/widget/details/gl_frame_buffer.cpp +++ b/src/imview/src/component/frame_buffer.cpp @@ -1,19 +1,19 @@ /* - * @file gl_frame_buffer.cpp + * @file frame_buffer.cpp * @date 10/29/24 * @brief * * @copyright Copyright (c) 2024 Ruixiang Du (rdu) */ -#include "imview/widget/details/gl_frame_buffer.hpp" +#include "imview/component/frame_buffer.hpp" #include #include "glad/glad.h" namespace quickviz { -GlFrameBuffer::GlFrameBuffer(uint32_t width, uint32_t height) +FrameBuffer::FrameBuffer(uint32_t width, uint32_t height) : width_(width), height_(height), frame_buffer_(0), @@ -22,9 +22,9 @@ GlFrameBuffer::GlFrameBuffer(uint32_t width, uint32_t height) CreateBuffers(); } -GlFrameBuffer::~GlFrameBuffer() { DestroyBuffers(); } +FrameBuffer::~FrameBuffer() { DestroyBuffers(); } -void GlFrameBuffer::CreateBuffers() { +void FrameBuffer::CreateBuffers() { // generate and bind the framebuffer glGenFramebuffers(1, &frame_buffer_); glBindFramebuffer(GL_FRAMEBUFFER, frame_buffer_); @@ -54,7 +54,7 @@ void GlFrameBuffer::CreateBuffers() { glBindFramebuffer(GL_FRAMEBUFFER, 0); } -void GlFrameBuffer::DestroyBuffers() { +void FrameBuffer::DestroyBuffers() { glDeleteFramebuffers(1, &frame_buffer_); glDeleteTextures(1, &texture_buffer_); glDeleteRenderbuffers(1, &render_buffer_); @@ -63,7 +63,7 @@ void GlFrameBuffer::DestroyBuffers() { render_buffer_ = 0; } -void GlFrameBuffer::Bind(bool keep_aspect_ratio) const { +void FrameBuffer::Bind(bool keep_aspect_ratio) const { glBindFramebuffer(GL_FRAMEBUFFER, frame_buffer_); if (keep_aspect_ratio) { float square_size = std::min(width_, height_); @@ -76,14 +76,14 @@ void GlFrameBuffer::Bind(bool keep_aspect_ratio) const { glEnable(GL_DEPTH_TEST); } -void GlFrameBuffer::Unbind() const { glBindFramebuffer(GL_FRAMEBUFFER, 0); } +void FrameBuffer::Unbind() const { glBindFramebuffer(GL_FRAMEBUFFER, 0); } -void GlFrameBuffer::Clear(float r, float g, float b, float a) const { +void FrameBuffer::Clear(float r, float g, float b, float a) const { glClearColor(r, g, b, a); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); } -void GlFrameBuffer::Resize(uint32_t width, uint32_t height) { +void FrameBuffer::Resize(uint32_t width, uint32_t height) { if (width == width_ && height == height_) return; width_ = width; diff --git a/src/imview/src/utils/image_utils.cpp b/src/imview/src/component/image_utils.cpp similarity index 96% rename from src/imview/src/utils/image_utils.cpp rename to src/imview/src/component/image_utils.cpp index 275d5bc..23e6ae6 100644 --- a/src/imview/src/utils/image_utils.cpp +++ b/src/imview/src/component/image_utils.cpp @@ -6,7 +6,7 @@ * @copyright Copyright (c) 2024 Ruixiang Du (rdu) */ -#include "imview/utils/image_utils.hpp" +#include "imview/component/image_utils.hpp" namespace quickviz { cv::Mat GenerateRandomMat(int width, int height) { diff --git a/src/imview/src/component/shader.cpp b/src/imview/src/component/shader.cpp new file mode 100644 index 0000000..faf2880 --- /dev/null +++ b/src/imview/src/component/shader.cpp @@ -0,0 +1,75 @@ +/* + * @file shader.cpp + * @date 11/2/24 + * @brief + * + * @copyright Copyright (c) 2024 Ruixiang Du (rdu) + */ + +#include "imview/component/shader.hpp" + +#include +#include +#include + +#include "glad/glad.h" + +namespace quickviz { +namespace { +std::string LoadShaderSource(const std::string& file_path) { + std::ifstream file; + file.exceptions(std::ifstream::failbit | std::ifstream::badbit); + try { + file.open(file_path); + std::stringstream buffer; + buffer << file.rdbuf(); + file.close(); + return buffer.str(); + } catch (std::ifstream::failure e) { + std::cout << "ERROR::SHADER::FILE_NOT_SUCCESSFULLY_READ" << std::endl; + } + return ""; +} +} // namespace + +Shader::Shader(const std::string& source_file, Shader::Type type) + : source_file_(source_file), type_(type) { + source_code_ = LoadShaderSource(source_file_); + if (type_ == Shader::Type::kVertex) + shader_id_ = glCreateShader(GL_VERTEX_SHADER); + else if (type_ == Shader::Type::kFragment) + shader_id_ = glCreateShader(GL_FRAGMENT_SHADER); + const char* code = source_code_.c_str(); + glShaderSource(shader_id_, 1, &code, NULL); +} + +Shader::~Shader() { glDeleteShader(shader_id_); } + +void Shader::Print() const { + std::cout << "Shader source file: " << source_file_ << std::endl; + std::cout << "Shader type: " << static_cast(type_) << std::endl; + std::cout << "Shader source code: " << std::endl; + std::cout << "------ start ------" << std::endl; + std::cout << source_code_ << std::endl; + std::cout << "------ end ------" << std::endl; +} + +bool Shader::Compile() { + glCompileShader(shader_id_); + + GLint success; + GLchar infoLog[512]; + glGetShaderiv(shader_id_, GL_COMPILE_STATUS, &success); + if (!success) { + glGetShaderInfoLog(shader_id_, 512, NULL, infoLog); + std::cout << "ERROR::SHADER::VERTEX::COMPILATION_FAILED\n" + << infoLog << std::endl; + return false; + } + return success; +} + +std::string Shader::LoadSourceFile(const std::string& file_path) { + return std::string(); +} +} // namespace quickviz \ No newline at end of file diff --git a/src/imview/src/component/shader_program.cpp b/src/imview/src/component/shader_program.cpp new file mode 100644 index 0000000..ba2d617 --- /dev/null +++ b/src/imview/src/component/shader_program.cpp @@ -0,0 +1,75 @@ +/* + * @file shader_program.cpp + * @date 11/2/24 + * @brief + * + * @copyright Copyright (c) 2024 Ruixiang Du (rdu) + */ + +#include "imview/component/shader_program.hpp" + +#include + +#include "glad/glad.h" + +namespace quickviz { +ShaderProgram::ShaderProgram() { program_id_ = glCreateProgram(); } + +ShaderProgram::~ShaderProgram() { glDeleteProgram(program_id_); } + +void ShaderProgram::AttachShader(const Shader& shader) { + glAttachShader(program_id_, shader.GetShaderID()); +} + +bool ShaderProgram::LinkProgram() { + glLinkProgram(program_id_); + GLint success; + glGetProgramiv(program_id_, GL_LINK_STATUS, &success); + if (!success) { + GLchar infoLog[512]; + glGetProgramInfoLog(program_id_, 512, NULL, infoLog); + std::cout << "ERROR::SHADER::PROGRAM::LINKING_FAILED\n" + << infoLog << std::endl; + return false; + } + return true; +} + +void ShaderProgram::Use() const { glUseProgram(program_id_); } + +void ShaderProgram::SetUniform(const std::string& name, bool value) { + glUniform1i(GetUniformLocation(name), static_cast(value)); +} + +void ShaderProgram::SetUniform(const std::string& name, int value) { + glUniform1i(GetUniformLocation(name), value); +} + +void ShaderProgram::SetUniform(const std::string& name, float value) { + glUniform1f(GetUniformLocation(name), value); +} + +void ShaderProgram::SetUniform(const std::string& name, + const glm::vec3& vector) { + glUniform3fv(GetUniformLocation(name), 1, &vector[0]); +} + +void ShaderProgram::SetUniform(const std::string& name, + const glm::mat4& matrix) { + glUniformMatrix4fv(GetUniformLocation(name), 1, GL_FALSE, &matrix[0][0]); +} + +uint32_t ShaderProgram::GetUniformLocation(const std::string& name) { + // Use cache if location already retrieved + if (uniform_location_cache_.find(name) != uniform_location_cache_.end()) + return uniform_location_cache_[name]; + + // Query location and cache it + GLint location = glGetUniformLocation(program_id_, name.c_str()); + if (location == -1) { + throw std::runtime_error("Trying to access non-existent uniform: " + name); + } + uniform_location_cache_[name] = location; + return location; +} +} // namespace quickviz \ No newline at end of file diff --git a/src/imview/src/widget/buffered_cv_image_widget.cpp b/src/imview/src/widget/buffered_cv_image_widget.cpp index eeeb833..78f9b54 100644 --- a/src/imview/src/widget/buffered_cv_image_widget.cpp +++ b/src/imview/src/widget/buffered_cv_image_widget.cpp @@ -8,7 +8,7 @@ #include "imview/widget/buffered_cv_image_widget.hpp" -#include "imview/utils/image_utils.hpp" +#include "imview/component/image_utils.hpp" namespace quickviz { BufferedCvImageWidget::BufferedCvImageWidget(const std::string& widget_name, diff --git a/src/imview/src/widget/cv_image_widget.cpp b/src/imview/src/widget/cv_image_widget.cpp index d080851..d019423 100644 --- a/src/imview/src/widget/cv_image_widget.cpp +++ b/src/imview/src/widget/cv_image_widget.cpp @@ -9,7 +9,7 @@ #include "imview/widget/cv_image_widget.hpp" #include "glad/glad.h" -#include "imview/utils/image_utils.hpp" +#include "imview/component/image_utils.hpp" namespace quickviz { CvImageWidget::CvImageWidget(const std::string& widget_name) diff --git a/src/imview/src/widget/details/shader.cpp b/src/imview/src/widget/details/shader.cpp deleted file mode 100644 index cedcbd0..0000000 --- a/src/imview/src/widget/details/shader.cpp +++ /dev/null @@ -1,11 +0,0 @@ -/* - * @file shader.cpp - * @date 11/2/24 - * @brief - * - * @copyright Copyright (c) 2024 Ruixiang Du (rdu) - */ - -#include "imview/widget/details/shader.hpp" - -namespace quickviz {} // namespace quickviz \ No newline at end of file diff --git a/src/imview/src/widget/gl_scene_widget.cpp b/src/imview/src/widget/gl_widget.cpp similarity index 74% rename from src/imview/src/widget/gl_scene_widget.cpp rename to src/imview/src/widget/gl_widget.cpp index a56d3af..b760c5c 100644 --- a/src/imview/src/widget/gl_scene_widget.cpp +++ b/src/imview/src/widget/gl_widget.cpp @@ -1,28 +1,28 @@ /* - * @file gl_scene_widget.cpp + * @file gl_widget.cpp * @date 10/29/24 * @brief * * @copyright Copyright (c) 2024 Ruixiang Du (rdu) */ -#include "imview/widget/gl_scene_widget.hpp" +#include "imview/widget/gl_widget.hpp" namespace quickviz { -GlSceneWidget::GlSceneWidget(const std::string& widget_name) +GlWidget::GlWidget(const std::string& widget_name) : Panel(widget_name) { this->SetAutoLayout(false); this->SetWindowNoMenuButton(); this->SetNoBackground(true); - frame_buffer_ = std::make_unique(100, 50); + frame_buffer_ = std::make_unique(100, 50); } -void GlSceneWidget::SetGlRenderFunction(GlSceneWidget::GlRenderFunction func) { +void GlWidget::SetGlRenderFunction(GlWidget::GlRenderFunction func) { render_function_ = func; } -void GlSceneWidget::Draw() { +void GlWidget::Draw() { Begin(); { ImVec2 contentSize = ImGui::GetContentRegionAvail(); diff --git a/src/imview/src/window.cpp b/src/imview/src/window.cpp index 704e1ad..dba6ae3 100644 --- a/src/imview/src/window.cpp +++ b/src/imview/src/window.cpp @@ -66,9 +66,9 @@ void Window::ApplyWindowHints(uint32_t window_hints) { glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); // 3.2+ only glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); // Required on Mac #else - // GL 3.0 + GLSL 130 + // GL 3.3 glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); - glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 0); + glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); // glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); // 3.2+ only // glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); // 3.0+ only #endif diff --git a/src/imview/test/CMakeLists.txt b/src/imview/test/CMakeLists.txt index 613d684..c83ede2 100644 --- a/src/imview/test/CMakeLists.txt +++ b/src/imview/test/CMakeLists.txt @@ -22,6 +22,9 @@ target_link_libraries(test_async_event PRIVATE imview) add_executable(test_framebuffer test_framebuffer.cpp) target_link_libraries(test_framebuffer PRIVATE imview) +add_executable(test_shader test_shader.cpp) +target_link_libraries(test_shader PRIVATE imview) + find_package(OpenCV QUIET) if (OpenCV_FOUND) add_executable(test_double_buffer test_double_buffer.cpp) diff --git a/src/imview/test/feature/test_gl_scene_widget.cpp b/src/imview/test/feature/test_gl_scene_widget.cpp index 0665377..9fb8ded 100644 --- a/src/imview/test/feature/test_gl_scene_widget.cpp +++ b/src/imview/test/feature/test_gl_scene_widget.cpp @@ -13,11 +13,11 @@ #include #include "imview/viewer.hpp" -#include "imview/widget/gl_scene_widget.hpp" +#include "imview/widget/gl_widget.hpp" using namespace quickviz; -void RenderGL(const GlFrameBuffer& frame_buffer) { +void RenderGL(const FrameBuffer& frame_buffer) { frame_buffer.Clear(); // Define shapes enclosed within a pair of glBegin and glEnd @@ -74,7 +74,7 @@ void RenderGL(const GlFrameBuffer& frame_buffer) { int main(int argc, char* argv[]) { Viewer viewer; - auto gl_widget = std::make_shared("OpenGL Scene"); + auto gl_widget = std::make_shared("OpenGL Scene"); gl_widget->OnResize(300, 200); gl_widget->SetPosition(0, 0); gl_widget->SetGlRenderFunction(RenderGL); diff --git a/src/imview/test/test_framebuffer.cpp b/src/imview/test/test_framebuffer.cpp index 9728186..6717262 100644 --- a/src/imview/test/test_framebuffer.cpp +++ b/src/imview/test/test_framebuffer.cpp @@ -7,12 +7,11 @@ * Copyright (c) 2021 Ruixiang Du (rdu) */ -#include #include #include "glad/glad.h" #include "imview/window.hpp" -#include "imview/widget/details/gl_frame_buffer.hpp" +#include "imview/component/frame_buffer.hpp" using namespace quickviz; @@ -22,7 +21,7 @@ int main(int argc, char* argv[]) { Window win("Test Window", width, height); // Create a framebuffer - auto frame_buffer = std::make_unique(width, height); + auto frame_buffer = std::make_unique(width, height); while (!win.ShouldClose()) { win.PollEvents(); diff --git a/src/imview/test/test_shader.cpp b/src/imview/test/test_shader.cpp new file mode 100644 index 0000000..e1b39d2 --- /dev/null +++ b/src/imview/test/test_shader.cpp @@ -0,0 +1,91 @@ +/* + * @file test_shader.cpp + * @date 11/2/24 + * @brief + * + * @copyright Copyright (c) 2024 Ruixiang Du (rdu) + */ + +#include + +#include "imview/window.hpp" +#include "imview/component/shader.hpp" +#include "imview/component/shader_program.hpp" + +using namespace quickviz; + +int main(int argc, char* argv[]) { + int width = 1920; + int height = 1080; + Window win("Test Window", width, height); + + Shader vertex_shader("../data/glsl/vertex_shader.glsl", + Shader::Type::kVertex); + // vertex_shader.Print(); + if (vertex_shader.Compile()) + std::cout << "Vertex shader compiled successfully" << std::endl; + else + std::cout << "Vertex shader compilation failed" << std::endl; + + Shader fragment_shader("../data/glsl/fragment_shader.glsl", + Shader::Type::kFragment); + if (fragment_shader.Compile()) + std::cout << "Fragment shader compiled successfully" << std::endl; + else + std::cout << "Fragment shader compilation failed" << std::endl; + + ShaderProgram shader_program; + shader_program.AttachShader(vertex_shader); + shader_program.AttachShader(fragment_shader); + if (shader_program.LinkProgram()) + std::cout << "Shader program linked successfully" << std::endl; + else + std::cout << "Shader program linking failed" << std::endl; + + ///////////////////////////////////////////////////////////////////////////// + + // data in main memory + float vertices[] = { + 0.0f, 0.5f, 0.0f, // Top vertex + -0.5f, -0.5f, 0.0f, // Bottom-left vertex + 0.5f, -0.5f, 0.0f // Bottom-right vertex + }; + + // transfer data to GPU + GLuint VBO, VAO; + glGenVertexArrays(1, &VAO); + glGenBuffers(1, &VBO); + + 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); + + while (!win.ShouldClose()) { + win.PollEvents(); + + glViewport(0, 0, width, height); + + glClearColor(0.3, 0.3, 0.3, 0.5); + glClear(GL_COLOR_BUFFER_BIT); + + shader_program.Use(); + glBindVertexArray(VAO); + glDrawArrays(GL_TRIANGLES, 0, 3); + + win.SwapBuffers(); + } + + glDeleteVertexArrays(1, &VAO); + glDeleteBuffers(1, &VBO); + + return 0; +} \ No newline at end of file