diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index 91a1209..a721baa 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -12,6 +12,7 @@ set(hdrs include/pw/core/quaternion.hpp include/pw/core/image.hpp include/pw/core/point.hpp + include/pw/core/resource.hpp include/pw/core/rectangle.hpp include/pw/core/serialize.hpp include/pw/core/size.hpp @@ -30,10 +31,11 @@ set(misc set(srcs # src/buffer.cpp + src/core.cpp src/image.cpp src/debug.cpp - src/mesh.cpp - src/core.cpp + src/mesh.cpp + src/resource.cpp src/serialize.cpp src/time.cpp src/image.cpp diff --git a/src/core/include/pw/core/math.hpp b/src/core/include/pw/core/math.hpp index 677d6cf..b24e6e6 100644 --- a/src/core/include/pw/core/math.hpp +++ b/src/core/include/pw/core/math.hpp @@ -31,6 +31,7 @@ namespace pw { const static double __PW_PI = 3.1415926535897932384626433832795028841971693993751058209; +const static double __PW_PI_DOUBLE = 2.0 * __PW_PI; template inline const T pi() { return static_cast(__PW_PI); } @@ -59,6 +60,11 @@ inline T ping_pong(const T& t,const T& length) { return length - std::abs(tn - length); } +template +inline T wrap_angle(const T& angle_in_radian) { + using std::floor; + return angle_in_radian - __PW_PI_DOUBLE * floor( angle_in_radian / __PW_PI_DOUBLE ); +} //void extractRotation(const matrix &A, Quaterniond &q,const unsigned int maxIter) //{ diff --git a/src/core/include/pw/core/matrixbase.hpp b/src/core/include/pw/core/matrixbase.hpp index e6c3260..c9be8e5 100644 --- a/src/core/include/pw/core/matrixbase.hpp +++ b/src/core/include/pw/core/matrixbase.hpp @@ -72,6 +72,10 @@ struct matrixbase_ { return *this / this->norm() ; } + inline void normalize() { + *this /= this->norm(); + } + using iterator = T*; using const_iterator = const T*; iterator begin() { return &derived().data[0]; } @@ -88,8 +92,12 @@ struct matrixbase_ { } static T dot(const Derived &a,const Derived &b) { +#if 0 Derived r; for (size_t i = 0;i < a.size();i++) r[i] = a[i] * b[i]; return std::accumulate(std::begin(r), std::end(r), T(0)); +#else + return std::inner_product(std::begin(a),std::end(a),std::begin(b),T(0)); +#endif } static const Derived lerp(const Derived &a,const Derived &b,const T& t) { @@ -97,16 +105,18 @@ struct matrixbase_ { } -// inline Derived& operator *= (const T& b) { for (auto & e : *this) e *= b; return derived(); } -// inline Derived& operator /= (const T& b) { for (auto & e : *this) e /= b; return derived(); } -// inline Derived& operator += (const T& b) { for (auto & e : *this) e += b; return derived(); } -// inline Derived& operator -= (const T& b) { for (auto & e : *this) e -= b; return derived(); } + inline void operator *= (const T& b) { for (auto & e : *this) e *= b; } + inline void operator /= (const T& b) { for (auto & e : *this) e /= b; } + inline void operator += (const T& b) { for (auto & e : *this) e += b; } + inline void operator -= (const T& b) { for (auto & e : *this) e -= b; } inline const Derived operator * (const T& b) const { Derived r(derived()); for (auto & e : r) e *= b; return r; } inline const Derived operator / (const T& b) const { Derived r(derived()); for (auto & e : r) e /= b; return r; } inline const Derived operator + (const T& b) const { Derived r(derived()); for (auto & e : r) e += b; return r; } inline const Derived operator - (const T& b) const { Derived r(derived()); for (auto & e : r) e -= b; return r; } + + }; // diff --git a/src/core/include/pw/core/mesh.hpp b/src/core/include/pw/core/mesh.hpp index 50b262c..73d8103 100644 --- a/src/core/include/pw/core/mesh.hpp +++ b/src/core/include/pw/core/mesh.hpp @@ -26,6 +26,7 @@ #include #include #include +#include namespace pw { @@ -64,6 +65,11 @@ public: aabb aabb() const { return _aabb; } + void compute_normals(); + + void set_normals(const mesh::vertex3array_t &v); + const mesh::vertex3array_t& normals() const; + protected: diff --git a/src/core/include/pw/core/resource.hpp b/src/core/include/pw/core/resource.hpp new file mode 100644 index 0000000..3158690 --- /dev/null +++ b/src/core/include/pw/core/resource.hpp @@ -0,0 +1,45 @@ +/* + * Copyright (c) 1999-2019 Hartmut Seichter + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * 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 SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + */ +#ifndef PW_CORE_RESOURCE_HPP +#define PW_CORE_RESOURCE_HPP + +#include +#include + +namespace pw { + +class resource { +public: + using change_t = std::atomic_int_fast64_t; + + int64_t changecount() { return _changecount; } + void dirty() { ++_changecount; }; + +protected: + + change_t _changecount; +}; + +} + +#endif diff --git a/src/core/include/pw/core/time.hpp b/src/core/include/pw/core/time.hpp index e8127c1..22c5f63 100644 --- a/src/core/include/pw/core/time.hpp +++ b/src/core/include/pw/core/time.hpp @@ -35,7 +35,7 @@ namespace pw { class time { public: - typedef std::chrono::time_point tick_t; + using tick_t = std::chrono::time_point ; time(); /// c'tor ~time(); /// d'tor diff --git a/src/core/src/mesh.cpp b/src/core/src/mesh.cpp index b35d66b..cbd4377 100644 --- a/src/core/src/mesh.cpp +++ b/src/core/src/mesh.cpp @@ -1,4 +1,6 @@ #include "pw/core/mesh.hpp" +#include "pw/core/debug.hpp" +#include "pw/core/serialize.hpp" namespace pw { @@ -6,6 +8,58 @@ mesh::mesh() { } +void mesh::compute_normals() +{ + + // assumption is that we have some array as the vertices + vertex3array_t normals; normals.resize(_vertices.size()); + + // for indexed-faceset + for (auto i = 1; i < _indices.size()-1;i++) + { + // left index and right index + auto il = (i - 1 + _indices.size()) % _indices.size(); + auto ir = (i + 1 + _indices.size()) % _indices.size(); + + // translate to actual indices + auto ci = _indices[ i]; + auto li = _indices[il]; + auto ri = _indices[ir]; + + // calculate delta vectors + auto dL = vector3( _vertices[li] - _vertices[ci] ); + auto dR = vector3( _vertices[ri] - _vertices[ci] ); + + auto N = dR.cross(dL).normalized(); + + //auto dV = _vertices[idx0].cross(_vertices[idx1]); + + // NOTE that addition is ugly + normals[ci] = N + normals[ci]; + normals[li] = N + normals[li]; + normals[ri] = N + normals[ri]; + } + + for (auto & n : normals) { + n.normalize(); + } + + this->set_normals(normals); + + for (auto N : normals) { + debug::s() << "( " << serialize::matrix(N.transposed()) << ") "; + } + + + // for triangle-strip + + + // for triangle-fan + + + // now set back +} + void mesh::set_vertices(const mesh::vertex3array_t &v) { // first set vertices @@ -15,12 +69,26 @@ void mesh::set_vertices(const mesh::vertex3array_t &v) compute_bounds(); } +void mesh::set_normals(const mesh::vertex3array_t &v) +{ + _normals = v; +} + +const mesh::vertex3array_t &mesh::normals() const +{ + return _normals; +} + void mesh::apply(const matrix4x4 &m) { // apply transformation to all vertices for (auto &v : _vertices) v = vector4(m * v.homogenous()).project(); + // apply to normals + for(auto &n : _normals) + n = vector4(m * n.homogenous(0)).xyz(); + // recompute bounds compute_bounds(); } diff --git a/src/core/src/resource.cpp b/src/core/src/resource.cpp new file mode 100644 index 0000000..589d0a9 --- /dev/null +++ b/src/core/src/resource.cpp @@ -0,0 +1,5 @@ +#include "pw/core/resource.hpp" + +namespace pw { + +} diff --git a/src/visual/src/pipeline.cpp b/src/visual/src/pipeline.cpp index 522e663..ffbe7ee 100644 --- a/src/visual/src/pipeline.cpp +++ b/src/visual/src/pipeline.cpp @@ -56,7 +56,7 @@ struct triangle_renderer #if 0 mesh::vertex3array_t vertices = { - { 0.0f, 0.5f, z_val} // 0 + { 0.0f, 0.5f, z_val} // 0 ,{ 0.5f, 0.0f, z_val} // 1 ,{-0.5f, 0.0f, z_val} // 2 }; @@ -74,7 +74,7 @@ struct triangle_renderer // geometry mesh::vertex3array_t vertices = { - {-s, s, z_val} // 0 + {-s, s, z_val} // 0 ,{ s, s, z_val} // 1 ,{-s, -s, z_val} // 2 ,{ s, -s, z_val} // 3 @@ -90,6 +90,8 @@ struct triangle_renderer amesh.set_indices(indices); amesh.set_vertices(vertices); + amesh.compute_normals(); + amesh_renderer.create(amesh); const char* vertex_shader_2 = R"( @@ -101,8 +103,8 @@ struct triangle_renderer in vec3 vertex_p; void main() { - gl_Position = projection * view * model * vec4(vertex_p, 1.0); -// gl_Position = model * vec4(vertex_p, 1.0); + gl_Position = projection * view * model * vec4(vertex_p, 1.0); + // gl_Position = model * vec4(vertex_p, 1.0); } )"; @@ -111,7 +113,7 @@ struct triangle_renderer uniform vec4 input_color = vec4(1.0, 0.0, 0.0, 1.0); out vec4 frag_colour; void main() { - frag_colour = input_color; + frag_colour = input_color; })"; shader_p.set_source(vertex_shader_2,shader::code_type::vertex); @@ -138,8 +140,8 @@ struct triangle_renderer model_mat = rot.to_matrix(); matrix4x4f view_mat = matrix_transform::look_at(vector3({0,0,0}), - vector3::forward(), - vector3::up()); + vector3::forward(), + vector3::up()); // materials should carry this #if 1 glEnable(GL_CULL_FACE); @@ -148,15 +150,15 @@ struct triangle_renderer #endif -#if 0 +#if 1 auto proj_mat = matrix_transform::orthographic_projection(1.3,1.0, 0.2f,100.f); #else auto proj_mat = matrix_transform::perspective_projection(deg_to_rad(60.f), - 1.3f, - 0.2f,1000.f); + 1.3f, + 0.2f,1000.f); #endif // highly inefficient - should be cached - @@ -165,11 +167,17 @@ struct triangle_renderer shader_p.set("view",view_mat); shader_p.set("projection",proj_mat); +#if 0 // new version with ... shader::uniform_set us; us["input_color"] = col; + us["model"] = model_mat; + us["view"] = view_mat; + us["projection"] = proj_mat; -// shader_p.set_uniforms(us); + shader_p.set_uniforms(us); + +#endif amesh_renderer.draw(); @@ -274,10 +282,10 @@ void pipeline::impl::draw() glBindFramebuffer(GL_DRAW_FRAMEBUFFER, _fbo_msaa); -// glClearColor(0,0,0,1); -// glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + // glClearColor(0,0,0,1); + // glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); -// glViewport(0,0,800,600); + // glViewport(0,0,800,600); // // draw pass diff --git a/src/visual/src/shader.cpp b/src/visual/src/shader.cpp index 3a2a164..ddb29e4 100644 --- a/src/visual/src/shader.cpp +++ b/src/visual/src/shader.cpp @@ -220,6 +220,7 @@ void shader::set_uniforms(shader::uniform_set s) std::visit([u](auto&& arg) { using T = std::decay_t; if constexpr (std::is_same_v) +// set(arg); std::cout << "vec4f with type " << typeid(arg).name() << " " << serialize::matrix(arg) << '\n'; else std::cout << "can't" << std::endl; diff --git a/src/visual/src/vertex_array.cpp b/src/visual/src/vertex_array.cpp index 2747d5b..ee0fe91 100644 --- a/src/visual/src/vertex_array.cpp +++ b/src/visual/src/vertex_array.cpp @@ -13,7 +13,7 @@ struct vertex_array::impl { GLuint _vao = 0; std::vector _vbos; - std::size_t _mesh_elements = {0}; + GLint _mesh_elements = {0}; impl() { @@ -37,6 +37,8 @@ struct vertex_array::impl { } glGenVertexArrays(1,&_vao); + + glBindVertexArray(_vao); size_t arrays_needed = 0; @@ -56,7 +58,9 @@ struct vertex_array::impl { // vertices glBindBuffer(GL_ARRAY_BUFFER, _vbos[0]); - glBufferData(GL_ARRAY_BUFFER, sizeof(m.vertices().front()) * m.vertices().size(), m.vertices().data(), + glBufferData(GL_ARRAY_BUFFER, + sizeof(m.vertices().front()) * m.vertices().size(), + m.vertices().data(), GL_STATIC_DRAW); glEnableVertexAttribArray(0); @@ -86,6 +90,8 @@ struct vertex_array::impl { { glBindVertexArray(_vao); glDrawElements(GL_TRIANGLES, _mesh_elements, GL_UNSIGNED_INT, nullptr); + glBindVertexArray(0); + } // GLint get_mode(vertex_array::)