diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index ae94f15..c232a6b 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -9,7 +9,7 @@ add_subdirectory(core) #add_subdirectory(ui) # add_subdirectory(binding) -# add_subdirectory(visual) +add_subdirectory(visual) # add_subdirectory(geometry) # add_subdirectory(runtime) diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index bd7b93b..7c77e34 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -17,7 +17,7 @@ set(hdrs include/pw/core/serialize.hpp include/pw/core/size.hpp include/pw/core/time.hpp - include/pw/core/geometry.hpp + include/pw/core/primitives.hpp include/pw/core/image.hpp include/pw/core/vector.hpp include/pw/core/matrix_transform.hpp diff --git a/src/core/include/pw/core/color.hpp b/src/core/include/pw/core/color.hpp index 6af8e64..6f017ec 100644 --- a/src/core/include/pw/core/color.hpp +++ b/src/core/include/pw/core/color.hpp @@ -29,7 +29,7 @@ namespace pw { -struct color { +struct color final { vector4f rgba{vector4f::all(1)}; diff --git a/src/core/include/pw/core/frustum.hpp b/src/core/include/pw/core/frustum.hpp index 1587894..7e66a97 100644 --- a/src/core/include/pw/core/frustum.hpp +++ b/src/core/include/pw/core/frustum.hpp @@ -36,7 +36,8 @@ template struct frustum final { Scalar aspect_ratio, Scalar z_near, Scalar z_far) -> frustum { - const auto tangent_half{std::tan(pw::deg_to_rad(fov_h_deg / Scalar{2}))}; + const auto tangent_half{ + std::tan(pw::deg_to_rad(fov_h_deg / Scalar{2}))}; const auto top{tangent_half * z_near}; const auto right{top * aspect_ratio}; diff --git a/src/core/include/pw/core/matrix.hpp b/src/core/include/pw/core/matrix.hpp index 38e91f4..864dbf8 100644 --- a/src/core/include/pw/core/matrix.hpp +++ b/src/core/include/pw/core/matrix.hpp @@ -258,6 +258,22 @@ constexpr auto operator*(const matrix& A, return result; } +// +// matrix aliases +// + +template using matrix2x2 = matrix; +template using matrix3x3 = matrix; +template using matrix4x4 = matrix; + +using matrix2x2f = matrix2x2; +using matrix3x3f = matrix3x3; +using matrix4x4f = matrix4x4; + +using matrix2x2d = matrix2x2; +using matrix3x3d = matrix3x3; +using matrix4x4d = matrix4x4; + } // namespace pw // diff --git a/src/core/include/pw/core/mesh.hpp b/src/core/include/pw/core/mesh.hpp index 8559dfc..9492013 100644 --- a/src/core/include/pw/core/mesh.hpp +++ b/src/core/include/pw/core/mesh.hpp @@ -8,8 +8,8 @@ * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -24,9 +24,41 @@ #define PW_CORE_MESH_HPP #include +#include + +#include namespace pw { +struct attribute final { + using mask_type = std::vector; + using int8_type = std::vector; + using int32_type = std::vector; + using float_type = std::vector; + using vector2_type = std::vector>; + using vector3_type = std::vector>; + using vector4_type = std::vector>; + + using attribute_data = + std::variant; + + enum attribute_type { + normals, + texture_coordinates, + }; + + attribute_type type{}; + attribute_data data{}; +}; + +struct mesh { + primitives geometry{}; + std::vector attributes; + + std::atomic change_count{0}; +}; + } // namespace pw #endif diff --git a/src/core/include/pw/core/point.hpp b/src/core/include/pw/core/point.hpp index d01e05f..f85e4a6 100644 --- a/src/core/include/pw/core/point.hpp +++ b/src/core/include/pw/core/point.hpp @@ -8,8 +8,8 @@ * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -27,25 +27,18 @@ namespace pw { -template -struct point_ { +template struct point final { - using value_type = T_; + using value_type = Scalar; - T_ x {0}, y {0}; - - template - point_ cast() const { return point_(static_cast(x),static_cast(y)); } + Scalar x{}, y{}; + template + constexpr auto cast() const noexcept -> point { + return {.x{ScalarOut(x)}, .y{ScalarOut(y)}}; + } }; -using point = point_; - -using pointf = point_; -using pointd = point_; -using pointi = point_; - - -} +} // namespace pw #endif diff --git a/src/core/include/pw/core/rectangle.hpp b/src/core/include/pw/core/rectangle.hpp index 96eef21..3e86420 100644 --- a/src/core/include/pw/core/rectangle.hpp +++ b/src/core/include/pw/core/rectangle.hpp @@ -8,8 +8,8 @@ * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -23,53 +23,28 @@ #ifndef PW_CORE_RECTANGLE_HPP #define PW_CORE_RECTANGLE_HPP -#include - #include #include namespace pw { -template -struct rectangle_ { +template struct rectangle final { - point_ position; - size_ size; + point position{}; + size size{}; - rectangle_() = default; - - rectangle_(const T_ l[4]) - : position(point_(l[0],l[1])) - , size(size_(l[2],l[3])) - { - } - - rectangle_(const T_(&l)[4]) - : position(point_(l[0],l[1])) - , size(size_(l[2],l[3])) - { - } - - rectangle_(point_ const & p,size_ const & s) : size(s), position(p) {} - - bool contains(const point_& p) const noexcept - { + constexpr bool contains(const point& p) const noexcept { return p.x >= position.x && p.x <= position.x + size.width && - p.y >= position.y && p.y <= position.y + size.height; + p.y >= position.y && p.y <= position.y + size.height; } - template - rectangle_ cast() const - { - return rectangle_(position.template cast(),size.template cast()); + template + constexpr auto cast() const noexcept -> rectangle { + return {.position = position.template cast(), + .size = size.template cast()}; } }; -using rectangle = rectangle_; -using rectanglei = rectangle_; -using rectanglef = rectangle_; -using rectangled = rectangle_; - -} +} // namespace pw #endif diff --git a/src/core/include/pw/core/size.hpp b/src/core/include/pw/core/size.hpp index 70f21ca..f1afa2f 100644 --- a/src/core/include/pw/core/size.hpp +++ b/src/core/include/pw/core/size.hpp @@ -42,8 +42,15 @@ template struct size { } } - template constexpr auto operator()() const noexcept { - return Other{width, height}; + template + constexpr auto cast(this auto&& self) noexcept -> size { + return {.width = ScalarOut(self.width), + .height = ScalarOut(self.height)}; + } + + template + constexpr auto operator()(this auto&& self) noexcept { + return Other{self.width, self.height}; } }; diff --git a/src/core/tests/pwcore_test_mesh.cpp b/src/core/tests/pwcore_test_mesh.cpp index 0e19c12..308deef 100644 --- a/src/core/tests/pwcore_test_mesh.cpp +++ b/src/core/tests/pwcore_test_mesh.cpp @@ -3,6 +3,7 @@ #include #include #include +#include #include #include @@ -10,33 +11,6 @@ namespace pw { -struct attribute final { - using mask_type = std::vector; - using int8_type = std::vector; - using int32_type = std::vector; - using float_type = std::vector; - using vector2_type = std::vector>; - using vector3_type = std::vector>; - using vector4_type = std::vector>; - - using attribute_data = - std::variant; - - enum attribute_type { - normals, - texture_coordinates, - }; - - attribute_type type{}; - attribute_data data{}; -}; - -struct mesh_n { - primitives geometry{}; - std::vector attributes; -}; - } // namespace pw auto main() -> int { @@ -48,7 +22,7 @@ auto main() -> int { .indices = {0, 1, 2}, .topology = pw::primitives::topology_type::triangle_list}; - auto mesh = pw::mesh_n{.geometry = geom}; + auto mesh = pw::mesh{.geometry = geom}; mesh.attributes.emplace_back( pw::attribute{.type = pw::attribute::normals, diff --git a/src/visual/include/pw/visual/context.hpp b/src/visual/include/pw/visual/context.hpp index 5da31d4..c007528 100644 --- a/src/visual/include/pw/visual/context.hpp +++ b/src/visual/include/pw/visual/context.hpp @@ -8,8 +8,8 @@ * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -24,17 +24,15 @@ #ifndef PW_VISUAL_CONTEXT_HPP #define PW_VISUAL_CONTEXT_HPP +#include #include +#include #include #include -#include -#include - namespace pw { -class context { -public: +struct context final { context(); ~context(); @@ -42,24 +40,24 @@ public: void set_blend(); void set_depth(); - void set_viewport(const rectangle& v); - rectangle viewport() const; + void set_viewport(const rectangle& v); + rectangle viewport() const; - size viewport_size() const; - point viewport_origin() const; + size viewport_size() const; + point viewport_origin() const; - void set_clearcolor(const color &c); + void set_clearcolor(const color& c); color clearcolor() const; void clear(); uint32_t get_error() const; -protected: + protected: struct impl; std::unique_ptr _impl; }; -} +} // namespace pw #endif diff --git a/src/visual/include/pw/visual/framebuffer.hpp b/src/visual/include/pw/visual/framebuffer.hpp index 2052fa9..9423a09 100644 --- a/src/visual/include/pw/visual/framebuffer.hpp +++ b/src/visual/include/pw/visual/framebuffer.hpp @@ -6,22 +6,20 @@ namespace pw { -class framebuffer { -public: +struct framebuffer final { framebuffer(); ~framebuffer(); - bool create(const size& s); + bool create(const size& s); void bind(); void blit(); void unbind(); -protected: - + protected: struct impl; std::unique_ptr _impl; }; -} +} // namespace pw #endif diff --git a/src/visual/include/pw/visual/renderer.hpp b/src/visual/include/pw/visual/renderer.hpp index ccd9a11..8748bdd 100644 --- a/src/visual/include/pw/visual/renderer.hpp +++ b/src/visual/include/pw/visual/renderer.hpp @@ -6,26 +6,23 @@ namespace pw { -struct geometry; +struct mesh; /** - * @brief builds a renderer for geometry + * @brief builds a renderer for meshes */ struct renderer final { renderer(); - renderer(const geometry& m); + renderer(const mesh& m); ~renderer(); - bool update(const geometry& m); + bool update(const mesh& m); void release(); void draw(); bool ready() const; - uint64_t change_count() const; - void set_change_count(uint64_t n); - protected: struct impl; std::unique_ptr _impl; diff --git a/src/visual/src/context.cpp b/src/visual/src/context.cpp index 49cff8b..801a670 100644 --- a/src/visual/src/context.cpp +++ b/src/visual/src/context.cpp @@ -2,6 +2,7 @@ #include "pw/core/vector.hpp" #include "glad/glad.h" +#include namespace pw { @@ -10,16 +11,16 @@ struct context::impl { vector4f _clear_color { 0, 1, 0, 1}; - void set_viewport(const rectangle& v) + void set_viewport(const rectangle& v) { glViewport(v.position.x,v.position.y,v.size.width,v.size.height); } - const rectangle viewport() + const rectangle viewport() { - float _viewport[4] = {0,0,1,1}; - glGetFloatv(GL_VIEWPORT,&_viewport[0]); - return rectangle(_viewport); + auto vp = rectangle{0,0,1,1}; + glGetFloatv(GL_VIEWPORT,static_cast(&vp.position.x)); + return vp.cast(); } void clear() @@ -56,12 +57,12 @@ void context::set_blend() } -void context::set_viewport(const rectangle& v) +void context::set_viewport(const rectangle& v) { _impl->set_viewport(v); } -rectangle context::viewport() const +rectangle context::viewport() const { return _impl->viewport(); } @@ -78,15 +79,14 @@ u_int32_t context::get_error() const color context::clearcolor() const { - return _impl->_clear_color; + // return _impl->_clear_color; + return color{}; } void context::set_clearcolor(const color& c) { - _impl->_clear_color = c; + // _impl->_clear_color = c; } } - - diff --git a/src/visual/src/framebuffer.cpp b/src/visual/src/framebuffer.cpp index d0719c5..d3c39c4 100644 --- a/src/visual/src/framebuffer.cpp +++ b/src/visual/src/framebuffer.cpp @@ -5,6 +5,7 @@ #include "glad/glad.h" +#include #include namespace pw { @@ -13,7 +14,7 @@ namespace pw { struct framebuffer::impl { - size _size; + size _size; GLuint _fbo_draw { std::numeric_limits::max() }; GLuint _fbo_msaa { std::numeric_limits::max() }; @@ -21,7 +22,7 @@ struct framebuffer::impl { GLuint _rbo_color { std::numeric_limits::max() }; GLuint _rbo_depth { std::numeric_limits::max() }; - bool create(const size &s) + bool create(const size &s) { // TODO mak color resolution and _size = s; @@ -107,7 +108,7 @@ framebuffer::~framebuffer() { } -bool framebuffer::create(const size &s) +bool framebuffer::create(const size &s) { return _impl->create(s); } diff --git a/src/visual/src/renderer.cpp b/src/visual/src/renderer.cpp index 7157fc4..e85188d 100644 --- a/src/visual/src/renderer.cpp +++ b/src/visual/src/renderer.cpp @@ -1,19 +1,21 @@ #include "pw/visual/renderer.hpp" #include "pw/core/debug.hpp" -#include "pw/core/geometry.hpp" #include "pw/core/matrix.hpp" +#include "pw/core/mesh.hpp" +#include "pw/core/primitives.hpp" #include "pw/core/size.hpp" #include "glad/glad.h" #include +#include namespace pw { struct renderer::impl { - uint64_t _change_count{0}; + std::atomic change_count{}; uint32_t _vao{0}; uint32_t _ebo{0}; @@ -29,15 +31,15 @@ struct renderer::impl { return glIsVertexArray != nullptr && GL_TRUE == glIsVertexArray(_vao); } - bool update(const geometry& m) { - if (_change_count == m.change_count()) + bool update(const mesh& m) { + if (this->change_count == m.change_count) return false; // reset if the renderer already in use if (ready()) release(); - _mesh_elements = m.indices().size(); + _mesh_elements = m.geometry.indices.size(); // glGenVertexArrays(1, &_vao); @@ -51,31 +53,34 @@ struct renderer::impl { // indices glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _ebo); glBufferData(GL_ELEMENT_ARRAY_BUFFER, - m.indices().size() * sizeof(uint32_t), m.indices().data(), - GL_STATIC_DRAW); + m.geometry.indices.size() * sizeof(uint32_t), + m.geometry.indices.data(), GL_STATIC_DRAW); _vbos.resize(_vbos.size() + 1); glGenBuffers(1, &_vbos.back()); // vertices glBindBuffer(GL_ARRAY_BUFFER, _vbos.back()); - glVertexAttribPointer(_vbos.size() - 1, vector3::coefficients, GL_FLOAT, + glVertexAttribPointer(_vbos.size() - 1, vector3f::coefficients, GL_FLOAT, GL_FALSE, 0, nullptr); - glBufferData(GL_ARRAY_BUFFER, m.vertices().size() * sizeof(vector3), - m.vertices().data(), GL_STATIC_DRAW); + glBufferData(GL_ARRAY_BUFFER, + m.geometry.vertices.size() * sizeof(vector3f), + m.geometry.vertices.data(), GL_STATIC_DRAW); glEnableVertexAttribArray(_vbos.size() - 1); debug::d() << "vertices at " << _vbos.size() - 1; +#if 0 + 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, + glVertexAttribPointer(_vbos.size() - 1, vector3f::coefficients, GL_FLOAT, GL_FALSE, 0, nullptr); - glBufferData(GL_ARRAY_BUFFER, m.normals().size() * sizeof(vector3), + glBufferData(GL_ARRAY_BUFFER, m.normals().size() * sizeof(vector3f), m.normals().data(), GL_STATIC_DRAW); glEnableVertexAttribArray(_vbos.size() - 1); @@ -99,10 +104,12 @@ struct renderer::impl { } } +#endif + // stop binding glBindVertexArray(0); - this->_change_count = m.change_count(); + this->change_count.store(m.change_count.load()); #if 1 // get errors @@ -118,7 +125,7 @@ struct renderer::impl { void release() { - for (auto & vbo : _vbos) + for (auto& vbo : _vbos) glDeleteBuffers(1, &vbo); glDeleteBuffers(1, &_ebo); @@ -148,7 +155,7 @@ struct renderer::impl { renderer::renderer() : _impl(std::make_unique()) {} -renderer::renderer(const geometry& m) { +renderer::renderer(const mesh& m) { renderer(); // directly update _impl->update(m); @@ -158,14 +165,10 @@ renderer::~renderer() = default; bool renderer::ready() const { return _impl->ready(); } -bool renderer::update(const geometry& m) { return _impl->update(m); } +bool renderer::update(const mesh& m) { return _impl->update(m); } void renderer::release() { _impl->release(); } void renderer::draw() { _impl->draw(); } -uint64_t renderer::change_count() const { return _impl->_change_count; } - -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 d6ba365..2c7c286 100644 --- a/src/visual/src/shader.cpp +++ b/src/visual/src/shader.cpp @@ -141,15 +141,15 @@ struct shader::impl { } void bind(int location, const matrix3x3f& m) { - glUniformMatrix3fv(location, 1, GL_FALSE, m.ptr()); + glUniformMatrix3fv(location, 1, GL_FALSE, m.data()); } void bind(int location, const matrix4x4f& m) { - glUniformMatrix4fv(location, 1, GL_FALSE, m.ptr()); + glUniformMatrix4fv(location, 1, GL_FALSE, m.data()); } void bind(int location, const vector4f& v) { - glUniform4fv(location, 1, v.ptr()); + glUniform4fv(location, 1, v.data()); } void bind(int location, const float& v) { glUniform1f(location, v); }