From a5d42995b26408c201e351aae2e5cade31481fd4 Mon Sep 17 00:00:00 2001 From: Hartmut Seichter Date: Sun, 14 Jul 2024 11:23:04 +0200 Subject: [PATCH] clean up some headers --- src/core/tests/pwcore_test_mesh.cpp | 9 + src/visual/include/pw/visual/renderer.hpp | 25 +- src/visual/include/pw/visual/shader.hpp | 70 ++--- src/visual/src/renderer.cpp | 158 ++++------ src/visual/src/shader.cpp | 347 +++++++++------------- 5 files changed, 251 insertions(+), 358 deletions(-) diff --git a/src/core/tests/pwcore_test_mesh.cpp b/src/core/tests/pwcore_test_mesh.cpp index d28f4a7..949a57c 100644 --- a/src/core/tests/pwcore_test_mesh.cpp +++ b/src/core/tests/pwcore_test_mesh.cpp @@ -14,6 +14,13 @@ struct geometry_n { std::vector indices{}; }; +struct mesh_n { + + geometry_n geometry{}; + + +}; + } // namespace pw auto main() -> int { @@ -27,6 +34,8 @@ auto main() -> int { std::print("({}) ",pw::serialize::to_string(geom.vertices[i])); } + + // pw::geometry geo; // pw::vector3_array vs = { diff --git a/src/visual/include/pw/visual/renderer.hpp b/src/visual/include/pw/visual/renderer.hpp index 8b0d2eb..ccd9a11 100644 --- a/src/visual/include/pw/visual/renderer.hpp +++ b/src/visual/include/pw/visual/renderer.hpp @@ -1,39 +1,36 @@ #ifndef PW_VISUAL_MESH_RENDERER_HPP #define PW_VISUAL_MESH_RENDERER_HPP -#include #include +#include namespace pw { -class geometry; +struct geometry; /** * @brief builds a renderer for geometry */ -class renderer { -public: - +struct renderer final { renderer(); renderer(const geometry& m); ~renderer(); - bool update(const geometry &m); - void release(); + bool update(const geometry& m); + void release(); - void draw(); - bool ready() const; + void draw(); + bool ready() const; uint64_t change_count() const; void set_change_count(uint64_t n); -protected: - - struct impl; - std::unique_ptr _impl; + protected: + struct impl; + std::unique_ptr _impl; }; -} +} // namespace pw #endif diff --git a/src/visual/include/pw/visual/shader.hpp b/src/visual/include/pw/visual/shader.hpp index cbf8b8f..970566c 100644 --- a/src/visual/include/pw/visual/shader.hpp +++ b/src/visual/include/pw/visual/shader.hpp @@ -1,11 +1,10 @@ #ifndef PW_VISUAL_SHADER_HPP #define PW_VISUAL_SHADER_HPP +#include #include #include #include -#include - #include #include @@ -13,77 +12,70 @@ namespace pw { -class shader { -public: - - shader(); +struct shader final { + shader(); ~shader(); - enum class code_type { - vertex, - fragment, - geometry, - compute - }; + enum class code_type { vertex, fragment, geometry, compute }; void set_source(code_type t, const std::string& c) { _source[t] = c; } - std::string source(code_type t) { return _source[t]; } + std::string source(code_type t) { return _source[t]; } - bool ready() const; + bool ready() const; - shader& set_uniform_at_location(int location,float v); + shader& set_uniform_at_location(int location, float v); shader& set_uniform_at_location(int location, uint32_t v); - shader &set_uniform_at_location(int location, int32_t v); - shader& set_uniform_at_location(int location,matrix4x4f const &v); - shader& set_uniform_at_location(int location,vector4f const &v); - shader& set_uniform_at_location(int location,texture const &t); + shader& set_uniform_at_location(int location, int32_t v); + shader& set_uniform_at_location(int location, matrix4x4f const& v); + shader& set_uniform_at_location(int location, vector4f const& v); + shader& set_uniform_at_location(int location, texture const& t); /** * @brief retrieves the position of a uniform * @param name of the uniform * @return position of the uniform or negative if it doesn't exist */ - int uniform_location(std::string const & name) const; + int uniform_location(std::string const& name) const; /** * @brief check if a uniform with the given name exists * @param name of the uniform * @return true if found */ - bool has_uniform(std::string const &name) const { return uniform_location(name) >= 0; } + bool has_uniform(std::string const& name) const { + return uniform_location(name) >= 0; + } /** * sets data of the */ - template - shader & set_uniform(std::string const & name, T &&value) - { - return set_uniform_at_location( uniform_location(name), std::forward(value) ); - } + template + shader& set_uniform(std::string const& name, T&& value) { + return set_uniform_at_location(uniform_location(name), + std::forward(value)); + } - bool build(); + bool build(); void use(); - using uniform_t = std::variant; - using uniform_entry_t = std::tuple; + using uniform_t = std::variant; + using uniform_entry_t = std::tuple; - using uniform_cache_t = std::vector; + using uniform_cache_t = std::vector; - void set_uniforms(uniform_cache_t c); + void set_uniforms(uniform_cache_t c); uint32_t native_handle() const; -protected: - - std::unordered_map _source; - - struct impl; - std::unique_ptr _impl; + protected: + std::unordered_map _source; + struct impl; + std::unique_ptr _impl; }; - -} +} // namespace pw #endif diff --git a/src/visual/src/renderer.cpp b/src/visual/src/renderer.cpp index 81a7b23..7157fc4 100644 --- a/src/visual/src/renderer.cpp +++ b/src/visual/src/renderer.cpp @@ -1,42 +1,35 @@ #include "pw/visual/renderer.hpp" -#include "pw/core/geometry.hpp" -#include "pw/core/size.hpp" #include "pw/core/debug.hpp" +#include "pw/core/geometry.hpp" #include "pw/core/matrix.hpp" +#include "pw/core/size.hpp" #include "glad/glad.h" #include - namespace pw { struct renderer::impl { - uint64_t _change_count { 0 }; + uint64_t _change_count{0}; - uint32_t _vao { 0 }; - uint32_t _ebo { 0 }; - std::vector _vbos { }; + uint32_t _vao{0}; + uint32_t _ebo{0}; + std::vector _vbos{}; - - GLint _mesh_elements = { 0 }; + GLint _mesh_elements = {0}; impl() = default; - ~impl() - { - release(); - } + ~impl() { release(); } - bool ready() const - { + bool ready() const { return glIsVertexArray != nullptr && GL_TRUE == glIsVertexArray(_vao); } - bool update(const geometry& m) - { + bool update(const geometry& m) { if (_change_count == m.change_count()) return false; @@ -47,82 +40,69 @@ struct renderer::impl { _mesh_elements = m.indices().size(); // - glGenVertexArrays(1,&_vao); + glGenVertexArrays(1, &_vao); glBindVertexArray(_vao); glGenBuffers(1, &_ebo); - // TODO binding separate VBOs to the // vertexarray should be avoided // indices glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _ebo); glBufferData(GL_ELEMENT_ARRAY_BUFFER, - m.indices().size() * sizeof (uint32_t), - m.indices().data(), + m.indices().size() * sizeof(uint32_t), m.indices().data(), GL_STATIC_DRAW); - - _vbos.resize(_vbos.size()+1); + _vbos.resize(_vbos.size() + 1); glGenBuffers(1, &_vbos.back()); - // vertices glBindBuffer(GL_ARRAY_BUFFER, _vbos.back()); - glVertexAttribPointer(_vbos.size()-1, vector3::coefficients, GL_FLOAT, GL_FALSE, 0, nullptr); - glBufferData(GL_ARRAY_BUFFER, - m.vertices().size() * sizeof(vector3), - m.vertices().data(), - GL_STATIC_DRAW); - glEnableVertexAttribArray(_vbos.size()-1); + glVertexAttribPointer(_vbos.size() - 1, vector3::coefficients, GL_FLOAT, + GL_FALSE, 0, nullptr); + glBufferData(GL_ARRAY_BUFFER, m.vertices().size() * sizeof(vector3), + m.vertices().data(), GL_STATIC_DRAW); + glEnableVertexAttribArray(_vbos.size() - 1); - debug::d() << "vertices at " << _vbos.size()-1; + debug::d() << "vertices at " << _vbos.size() - 1; - if (!m.normals().empty()) - { - _vbos.resize(_vbos.size()+1); + if (!m.normals().empty()) { + _vbos.resize(_vbos.size() + 1); glGenBuffers(1, &_vbos.back()); // normals - glBindBuffer(GL_ARRAY_BUFFER,_vbos.back()); - glVertexAttribPointer(_vbos.size()-1, vector3::coefficients, GL_FLOAT, GL_FALSE, 0, nullptr); - glBufferData(GL_ARRAY_BUFFER, - m.normals().size() * sizeof(vector3), - m.normals().data(), - GL_STATIC_DRAW); - glEnableVertexAttribArray(_vbos.size()-1); - - debug::d() << "normals at " << _vbos.size()-1; + glBindBuffer(GL_ARRAY_BUFFER, _vbos.back()); + glVertexAttribPointer(_vbos.size() - 1, vector3::coefficients, + GL_FLOAT, GL_FALSE, 0, nullptr); + glBufferData(GL_ARRAY_BUFFER, m.normals().size() * sizeof(vector3), + m.normals().data(), GL_STATIC_DRAW); + glEnableVertexAttribArray(_vbos.size() - 1); + debug::d() << "normals at " << _vbos.size() - 1; } - if (!m.texture_coordinates().empty()) - { - for (const auto& tc : m.texture_coordinates()) - { - _vbos.resize(_vbos.size()+1); + if (!m.texture_coordinates().empty()) { + for (const auto& tc : m.texture_coordinates()) { + _vbos.resize(_vbos.size() + 1); glGenBuffers(1, &_vbos.back()); // texture coordinates - glBindBuffer(GL_ARRAY_BUFFER,_vbos.back()); - glVertexAttribPointer(_vbos.size()-1, vector2::coefficients, GL_FLOAT, GL_FALSE, 0, nullptr); - glBufferData(GL_ARRAY_BUFFER, - tc.size() * sizeof(vector2), - tc.data(), - GL_STATIC_DRAW); - glEnableVertexAttribArray(_vbos.size()-1); + glBindBuffer(GL_ARRAY_BUFFER, _vbos.back()); + glVertexAttribPointer(_vbos.size() - 1, vector2::coefficients, + GL_FLOAT, GL_FALSE, 0, nullptr); + glBufferData(GL_ARRAY_BUFFER, tc.size() * sizeof(vector2), + tc.data(), GL_STATIC_DRAW); + glEnableVertexAttribArray(_vbos.size() - 1); - debug::d() << "texture coordinates at " << _vbos.size()-1; + debug::d() << "texture coordinates at " << _vbos.size() - 1; } } // stop binding glBindVertexArray(0); - - this->_change_count = m.change_count(); - + this->_change_count = m.change_count(); #if 1 // get errors @@ -136,19 +116,16 @@ struct renderer::impl { return ready(); } + void release() { - void release() - { + for (auto & vbo : _vbos) + glDeleteBuffers(1, &vbo); + glDeleteBuffers(1, &_ebo); - for (auto vbo : _vbos) - glDeleteBuffers(1,&vbo); - glDeleteBuffers(1,&_ebo); - - glDeleteVertexArrays(1,&_vao); + glDeleteVertexArrays(1, &_vao); } - void draw() - { + void draw() { glBindVertexArray(_vao); glDrawElements(GL_TRIANGLES, _mesh_elements, GL_UNSIGNED_INT, nullptr); glBindVertexArray(0); @@ -163,57 +140,32 @@ struct renderer::impl { } // GLint get_mode(vertex_array::) - }; // // Outer wrapper // -renderer::renderer() - : _impl(std::make_unique()) -{ -} +renderer::renderer() : _impl(std::make_unique()) {} -renderer::renderer(const geometry &m) -{ +renderer::renderer(const geometry& m) { renderer(); // directly update _impl->update(m); } -renderer::~renderer() -{ -} +renderer::~renderer() = default; -bool renderer::ready() const -{ - return _impl->ready(); -} +bool renderer::ready() const { return _impl->ready(); } -bool renderer::update(const geometry &m) -{ - return _impl->update(m); -} +bool renderer::update(const geometry& m) { return _impl->update(m); } -void renderer::release() -{ - _impl->release(); -} +void renderer::release() { _impl->release(); } -void renderer::draw() -{ - _impl->draw(); -} +void renderer::draw() { _impl->draw(); } -uint64_t renderer::change_count() const -{ - return _impl->_change_count; -} +uint64_t renderer::change_count() const { return _impl->_change_count; } -void renderer::set_change_count(uint64_t n) -{ - _impl->_change_count = n; -} +void renderer::set_change_count(uint64_t n) { _impl->_change_count = n; } -} +} // namespace pw diff --git a/src/visual/src/shader.cpp b/src/visual/src/shader.cpp index 630e428..d6ba365 100644 --- a/src/visual/src/shader.cpp +++ b/src/visual/src/shader.cpp @@ -6,297 +6,240 @@ namespace pw { -struct shader::impl -{ - shader& _shader; +struct shader::impl { + shader& _shader; - GLuint _shader_program; - std::vector _shader_stages; + GLuint _shader_program; + std::vector _shader_stages; - impl(shader& s) - : _shader(s) - { - } + impl(shader& s) : _shader(s) {} - ~impl() - { - destroy(); - } + ~impl() { destroy(); } - bool is_valid() - { + bool is_valid() { // we potentially haul in is_valid while no context is given return glIsProgram != nullptr && glIsProgram(_shader_program); - } + } - bool build() - { -// if (!is_valid()) return false; + bool build() { + // if (!is_valid()) return false; - for (const auto & [type,code] : _shader._source) - { - GLuint shader_type = 0; + for (const auto& [type, code] : _shader._source) { + GLuint shader_type = 0; switch (type) { - case shader::code_type::vertex: - shader_type = GL_VERTEX_SHADER; - break; - case shader::code_type::compute: - shader_type = GL_COMPUTE_SHADER; - break; - case shader::code_type::geometry: - shader_type = GL_GEOMETRY_SHADER; - break; - case shader::code_type::fragment: - shader_type = GL_FRAGMENT_SHADER; - break; + case shader::code_type::vertex: + shader_type = GL_VERTEX_SHADER; + break; + case shader::code_type::compute: + shader_type = GL_COMPUTE_SHADER; + break; + case shader::code_type::geometry: + shader_type = GL_GEOMETRY_SHADER; + break; + case shader::code_type::fragment: + shader_type = GL_FRAGMENT_SHADER; + break; default: debug::w() << " unknown shader type"; - } + } - GLuint shaderId = glCreateShader(shader_type); + GLuint shaderId = glCreateShader(shader_type); - char* src = const_cast(code.c_str()); + char* src = const_cast(code.c_str()); GLint size = static_cast(code.length()); - glShaderSource(shaderId , 1, &src, &size); + glShaderSource(shaderId, 1, &src, &size); - glCompileShader(shaderId); + glCompileShader(shaderId); - GLint is_compiled = GL_FALSE; - glGetShaderiv(shaderId, GL_COMPILE_STATUS, &is_compiled); - if(is_compiled == GL_FALSE) - { + GLint is_compiled = GL_FALSE; + glGetShaderiv(shaderId, GL_COMPILE_STATUS, &is_compiled); + if (is_compiled == GL_FALSE) { - GLint log_length; + GLint log_length; - glGetShaderiv(shaderId, GL_INFO_LOG_LENGTH, &log_length); + glGetShaderiv(shaderId, GL_INFO_LOG_LENGTH, &log_length); - std::vector log_buffer(static_cast(log_length)); + std::vector log_buffer(static_cast(log_length)); - glGetShaderInfoLog(shaderId, log_length, &log_length, log_buffer.data()); + glGetShaderInfoLog(shaderId, log_length, &log_length, + log_buffer.data()); - // TODO - handle errors! - debug::e() << log_buffer.data(); + // TODO - handle errors! + debug::e() << log_buffer.data(); - return false; - } + return false; + } - _shader_stages.push_back(shaderId); + _shader_stages.push_back(shaderId); + } - } - - _shader_program = glCreateProgram(); - - - for (auto s : _shader_stages) - glAttachShader(_shader_program,s); + _shader_program = glCreateProgram(); + for (auto s : _shader_stages) + glAttachShader(_shader_program, s); // TODO attribute binding ... - /* Bind attribute index 0 (coordinates) to in_Position and attribute index 1 (color) to in_Color */ - /* Attribute locations must be setup before calling glLinkProgram. */ - // glBindAttribLocation(shaderprogram, 0, "in_Position"); - // glBindAttribLocation(shaderprogram, 1, "in_Color"); + /* Bind attribute index 0 (coordinates) to in_Position and attribute + * index 1 (color) to in_Color */ + /* Attribute locations must be setup before calling glLinkProgram. */ + // glBindAttribLocation(shaderprogram, 0, "in_Position"); + // glBindAttribLocation(shaderprogram, 1, "in_Color"); - glLinkProgram(_shader_program); + glLinkProgram(_shader_program); - GLint is_linked = 0; - glGetProgramiv(_shader_program, GL_LINK_STATUS, &is_linked); - if(is_linked == GL_FALSE) - { + GLint is_linked = 0; + glGetProgramiv(_shader_program, GL_LINK_STATUS, &is_linked); + if (is_linked == GL_FALSE) { - GLint log_length; + GLint log_length; - /* Noticed that glGetProgramiv is used to get the length for a shader program, not glGetShaderiv. */ - glGetProgramiv(_shader_program, GL_INFO_LOG_LENGTH, &log_length); + /* Noticed that glGetProgramiv is used to get the length for a + * shader program, not glGetShaderiv. */ + glGetProgramiv(_shader_program, GL_INFO_LOG_LENGTH, &log_length); - /* The maxLength includes the NULL character */ - std::vector info_log(static_cast(log_length)); + /* The maxLength includes the NULL character */ + std::vector info_log(static_cast(log_length)); - /* Notice that glGetProgramInfoLog, not glGetShaderInfoLog. */ - glGetProgramInfoLog(_shader_program, log_length, &log_length, info_log.data()); + /* Notice that glGetProgramInfoLog, not glGetShaderInfoLog. */ + glGetProgramInfoLog(_shader_program, log_length, &log_length, + info_log.data()); - debug::e() << info_log.data(); + debug::e() << info_log.data(); - /* Handle the error in an appropriate way such as displaying a message or writing to a log file. */ - /* In this simple program, we'll just leave */ + /* Handle the error in an appropriate way such as displaying a + * message or writing to a log file. */ + /* In this simple program, we'll just leave */ - return false; - } + return false; + } - return true; - } + return true; + } + void use() { glUseProgram(_shader_program); } - void use() - { - glUseProgram(_shader_program); - } - - void destroy() - { + void destroy() { // potentially the GL driver hasn't been loaded if (is_valid()) { // deleting and detaching should happen much earlier - for (auto s : _shader_stages) - { - glDeleteShader(s); + for (auto s : _shader_stages) { + glDeleteShader(s); } // only program needs to be deleted glDeleteProgram(_shader_program); } - } - - int uniform_location(std::string const& name) const - { - return glGetUniformLocation(_shader_program,name.c_str()); - } - - void bind(int location,const matrix3x3f& m) - { - glUniformMatrix3fv(location,1,GL_FALSE,m.ptr()); - } - - void bind(int location,const matrix4x4f& m) - { - glUniformMatrix4fv(location,1,GL_FALSE,m.ptr()); - } - - void bind(int location,const vector4f& v) - { - glUniform4fv(location,1,v.ptr()); - } - - void bind(int location,const float& v) - { - glUniform1f(location,v); - } - - void bind(int location,const uint32_t& i) - { - glUniform1ui(location,i); } - void bind(int location,const int32_t& i) - { - glUniform1i(location,i); + int uniform_location(std::string const& name) const { + return glGetUniformLocation(_shader_program, name.c_str()); } - void bind(int location,const texture& v) - { - this->bind(location,(int)v.native_handle()); + void bind(int location, const matrix3x3f& m) { + glUniformMatrix3fv(location, 1, GL_FALSE, m.ptr()); + } + void bind(int location, const matrix4x4f& m) { + glUniformMatrix4fv(location, 1, GL_FALSE, m.ptr()); + } + + void bind(int location, const vector4f& v) { + glUniform4fv(location, 1, v.ptr()); + } + + void bind(int location, const float& v) { glUniform1f(location, v); } + + void bind(int location, const uint32_t& i) { glUniform1ui(location, i); } + + void bind(int location, const int32_t& i) { glUniform1i(location, i); } + + void bind(int location, const texture& v) { + this->bind(location, (int)v.native_handle()); } }; +shader::shader() { _impl = make_unique(*this); } -shader::shader() -{ - _impl = make_unique(*this); -} +shader::~shader() {} -shader::~shader() -{ +bool shader::ready() const { return _impl->is_valid(); } -} - -bool shader::ready() const -{ - return _impl->is_valid(); -} - -shader &shader::set_uniform_at_location(int location, float v) -{ - _impl->bind(location,v); +shader& shader::set_uniform_at_location(int location, float v) { + _impl->bind(location, v); return *this; } -shader &shader::set_uniform_at_location(int location, uint32_t v) -{ - _impl->bind(location,v); return *this; +shader& shader::set_uniform_at_location(int location, uint32_t v) { + _impl->bind(location, v); + return *this; } -shader &shader::set_uniform_at_location(int location, int32_t v) -{ - _impl->bind(location,v); return *this; +shader& shader::set_uniform_at_location(int location, int32_t v) { + _impl->bind(location, v); + return *this; } - -shader &shader::set_uniform_at_location(int location, vector4f const &v) -{ - _impl->bind(location,v); return *this; +shader& shader::set_uniform_at_location(int location, vector4f const& v) { + _impl->bind(location, v); + return *this; } -shader &shader::set_uniform_at_location(int location, matrix4x4f const &v) -{ - _impl->bind(location,v); return *this; +shader& shader::set_uniform_at_location(int location, matrix4x4f const& v) { + _impl->bind(location, v); + return *this; } - -shader &shader::set_uniform_at_location(int location, texture const &v) -{ - _impl->bind(location,v); return *this; +shader& shader::set_uniform_at_location(int location, texture const& v) { + _impl->bind(location, v); + return *this; } -bool shader::build() -{ - return _impl->build(); -} +bool shader::build() { return _impl->build(); } -void shader::use() -{ - _impl->use(); -} +void shader::use() { _impl->use(); } -void shader::set_uniforms(uniform_cache_t c) -{ +void shader::set_uniforms(uniform_cache_t c) { // TODO rewrite in proper C++17 - for (auto& u : c) { - // get name - std::string name = std::get<0>(u); - // get location - GLint loc = std::get<2>(u); + for (auto& u : c) { + // get name + std::string name = std::get<0>(u); + // get location + GLint loc = std::get<2>(u); - // if lower 0 check for location - if (loc < 0) { - loc = _impl->uniform_location(name); - std::get<2>(u) = loc; // cache location - } + // if lower 0 check for location + if (loc < 0) { + loc = _impl->uniform_location(name); + std::get<2>(u) = loc; // cache location + } - auto var = std::get<1>(u); - - std::visit([this,loc](auto&& arg) { + auto var = std::get<1>(u); + std::visit([this, loc](auto&& arg) { using T = std::decay_t; // TODO query the std::variant of uniform_t - if constexpr ((std::is_same_v) || - (std::is_same_v) || - (std::is_same_v) ) { - set_uniform_at_location( loc, std::forward(arg)); - } else { + if constexpr ((std::is_same_v) || + (std::is_same_v) || + (std::is_same_v)) { + set_uniform_at_location(loc, std::forward(arg)); + } else { debug::e() << "unknown uniform type"; - } - }, var); - } + } + }, var); + } } -uint32_t shader::native_handle() const -{ - return _impl->_shader_program; +uint32_t shader::native_handle() const { return _impl->_shader_program; } + +int shader::uniform_location(const std::string& name) const { + return _impl->uniform_location(name); } -int shader::uniform_location(const std::string &name) const -{ - return _impl->uniform_location(name); -} - - -} +} // namespace pw