diff --git a/CMakeLists.txt b/CMakeLists.txt index b73fa2f42..bf14b41a3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -13,7 +13,7 @@ foreach(p CMP0048 # version CMP0054 # CMake 3.1 CMP0072 # opengl - CMP0092 # remove /W3 by default in MSVC + CMP0092 # remove /W3 by default in MSVC ) if(POLICY ${p}) cmake_policy(SET ${p} NEW) diff --git a/cgogn/modeling/apps/CMakeLists.txt b/cgogn/modeling/apps/CMakeLists.txt index 6491493ce..46329e5a7 100644 --- a/cgogn/modeling/apps/CMakeLists.txt +++ b/cgogn/modeling/apps/CMakeLists.txt @@ -1,5 +1,3 @@ -cmake_minimum_required(VERSION 3.0 FATAL_ERROR) - project(cgogn_rendering_examples LANGUAGES CXX ) diff --git a/cgogn/rendering/CMakeLists.txt b/cgogn/rendering/CMakeLists.txt index ee0110a9b..62f035869 100644 --- a/cgogn/rendering/CMakeLists.txt +++ b/cgogn/rendering/CMakeLists.txt @@ -131,6 +131,10 @@ set(src_list "${CMAKE_CURRENT_LIST_DIR}/shape_drawer.h" "${CMAKE_CURRENT_LIST_DIR}/shape_drawer.cpp" + + "${CMAKE_CURRENT_LIST_DIR}/skelshape.h" + "${CMAKE_CURRENT_LIST_DIR}/skelshape.cpp" + ) target_sources(${PROJECT_NAME} PRIVATE ${src_list}) source_group(TREE ${CMAKE_CURRENT_LIST_DIR} FILES ${src_list}) diff --git a/cgogn/rendering/apps/CMakeLists.txt b/cgogn/rendering/apps/CMakeLists.txt index a94baaf24..ece2aec22 100644 --- a/cgogn/rendering/apps/CMakeLists.txt +++ b/cgogn/rendering/apps/CMakeLists.txt @@ -1,5 +1,3 @@ -cmake_minimum_required(VERSION 3.0 FATAL_ERROR) - project(cgogn_rendering_examples LANGUAGES CXX ) @@ -113,6 +111,15 @@ target_link_libraries(obj_tex_viewer ${APPLE_LINK} ) +add_executable(test_skel_shapes test_skel_shapes.cpp) +target_link_libraries(test_skel_shapes + cgogn::core + cgogn::ui + cgogn::rendering + ${CMAKE_DL_LIBS} + ${APPLE_LINK} +) + #if(APPLE) # find_library(CORE_FOUNDATION CoreFoundation) # find_library(CARBON Carbon) diff --git a/cgogn/rendering/apps/test_skel_shapes.cpp b/cgogn/rendering/apps/test_skel_shapes.cpp new file mode 100644 index 000000000..60fe4573c --- /dev/null +++ b/cgogn/rendering/apps/test_skel_shapes.cpp @@ -0,0 +1,103 @@ +/******************************************************************************* + * CGoGN: Combinatorial and Geometric modeling with Generic N-dimensional Maps * + * Copyright (C), IGG Group, ICube, University of Strasbourg, France * + * * + * This library is free software; you can redistribute it and/or modify it * + * under the terms of the GNU Lesser General Public License as published by the * + * Free Software Foundation; either version 2.1 of the License, or (at your * + * option) any later version. * + * * + * This library is distributed in the hope that it will be useful, but WITHOUT * + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * + * for more details. * + * * + * You should have received a copy of the GNU Lesser General Public License * + * along with this library; if not, write to the Free Software Foundation, * + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * + * * + * Web site: http://cgogn.unistra.fr/ * + * Contact information: cgogn@unistra.fr * + * * + *******************************************************************************/ + +#include +#include +#include +#include + +#include + + +using namespace ::cgogn; +using namespace ::cgogn::rendering; + +class MySkelRender : public ui::ViewModule +{ +public: + MySkelRender(const ui::App& app) + : ViewModule(app, "Test skel Shape"), app_(app) + { + } + + ~MySkelRender() + { + } + + void init() override + { + app_.current_view()->set_scene_radius(4.0f); + app_.current_view()->set_scene_center(GLVec3(0, 0, 0)); + + skel_drawer_.set_color({1, 0, 1, 1}); + skel_drawer_.set_subdiv(40); + + // 2 first in double others in float to check on the fly conversion + GLVec4d C00 = {-2.5, -2.0, 0.9, 0.3}; + GLVec4d C0 = {-2.0, 0.0, 0.4, 0.2}; + + GLVec4 C1 = {-0.5f, 0.0f, 0.0f, 0.4f}; + GLVec4 C2 = {0.4f, 1.0f, 0.2f, 0.7f}; + GLVec4 C3 = {1.0f, -1.0f, -0.5f, 0.2f}; + skel_drawer_.add_vertex(C00.topRows<3>(), C00[3]); // just to test version with radius parameter + skel_drawer_.add_vertex(GLVec3d{-2.0, 0.0, 0.4}, 0.2); + skel_drawer_.add_vertex(C1); + skel_drawer_.add_vertex(C2); + skel_drawer_.add_vertex(C3); + skel_drawer_.add_edge(C00, C0); + skel_drawer_.add_edge(C0, C1); + skel_drawer_.add_edge(C1, C2); + skel_drawer_.add_edge(C2, C3); + skel_drawer_.add_edge(C3, C1); + skel_drawer_.add_triangle(C1, C2, C3); + skel_drawer_.update(); + } + + void draw(ui::View* view) override + { + const GLMat4& proj_matrix = view->projection_matrix(); + const GLMat4& view_matrix = view->modelview_matrix(); + skel_drawer_.draw(proj_matrix, view_matrix); + } + +private: + const ui::App& app_; + SkelShapeDrawer skel_drawer_; +}; + + +int main(int argc, char** argv) +{ + cgogn::ui::App app; + app.set_window_title("Simple Shape Test"); + app.set_window_size(1000, 800); + + // declare a local module and link it + MySkelRender sr(app); + app.init_modules(); + app.current_view()->link_module(&sr); + + //no need gui here + //app.show_gui(false); + return app.launch(); +} diff --git a/cgogn/rendering/skelshape.cpp b/cgogn/rendering/skelshape.cpp new file mode 100644 index 000000000..0903eb8d8 --- /dev/null +++ b/cgogn/rendering/skelshape.cpp @@ -0,0 +1,411 @@ +/******************************************************************************* + * CGoGN: Combinatorial and Geometric modeling with Generic N-dimensional Maps * + * Copyright (C), IGG Group, ICube, University of Strasbourg, France * + * * + * This library is free software; you can redistribute it and/or modify it * + * under the terms of the GNU Lesser General Public License as published by the * + * Free Software Foundation; either version 2.1 of the License, or (at your * + * option) any later version. * + * * + * This library is distributed in the hope that it will be useful, but WITHOUT * + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * + * for more details. * + * * + * You should have received a copy of the GNU Lesser General Public License * + * along with this library; if not, write to the Free Software Foundation, * + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * + * * + * Web site: http://cgogn.unistra.fr/ * + * Contact information: cgogn@unistra.fr * + * * + *******************************************************************************/ + +#include + +namespace cgogn +{ + +namespace rendering +{ +const char* skel_shape_fragment_shader_source = R"( +#version 330 + +uniform vec4 color; +uniform vec3 light_position; + +in vec3 Po; +in vec3 No; +out vec4 frag_out; + +void main() +{ + vec3 N = normalize(No); + vec3 L = normalize(light_position-Po); + float lamb = 0.2+0.8*max(0.0,dot(N,L)); + vec3 E = normalize(-Po); + vec3 R = reflect(-L,N); + float spec = pow(max(0.0,dot(E,R)),20.0); + + vec3 colamb = color.rgb*lamb; + vec3 specol = mix(colamb,vec3(1),0.1); + vec3 renderColor = mix(colamb,specol,spec); + frag_out = vec4(renderColor, 1); +} +)"; + + +ShaderParamSkelShape::ShaderParamSkelShape(ShaderProgram* prg) + : nbs_(16), color_(0.8f, 0, 0, 1), light_position_(10, 100, 1000), + ShaderParam(prg) +{ +} + +ShaderSkelSphere* ShaderSkelSphere::instance_ = nullptr; + +ShaderSkelSphere::ShaderSkelSphere() +{ + const char* vertex_shader_source = R"( +#version 330 +uniform int nbs; +uniform mat4 projection_matrix; +uniform mat4 model_view_matrix; +uniform mat3 normal_matrix; + +in vec4 center; + +out vec3 Po; +out vec3 No; + +const float PI = acos(-1.0); + +void main() +{ + float db = PI/float(nbs); + float b = -PI/2.0 + db*float(gl_InstanceID%nbs + gl_VertexID%2); + float a = 2.0*PI*float(gl_VertexID/2)/float(nbs); + vec2 Cir = vec2(cos(a),sin(a)); + vec3 Ps = vec3(cos(b)*Cir,sin(b)); + vec4 P4 = model_view_matrix * vec4(center.xyz+center.w*Ps,1); + Po = P4.xyz; + No = normal_matrix * Ps; + gl_Position = projection_matrix * P4; +} +)"; + + load2_bind(vertex_shader_source, skel_shape_fragment_shader_source, "center"); + get_uniforms("nbs", "color", "light_position"); +} + +void ShaderParamSkelSphere::set_uniforms() +{ + shader_->set_uniforms_values(nbs_, color_, light_position_); +} + +void ShaderParamSkelSphere::draw_inst(const GLMat4& projection, const GLMat4& view, uint32 nbi) +{ + this->bind(projection, view); + glDrawArraysInstanced(GL_TRIANGLE_STRIP, 0, 2 * nbs_ + 2, nbs_ * nbi); + this->release(); +} + + +SkelSphereDrawer::SkelSphereDrawer() +{ + param_ = ShaderSkelSphere::generate_param(); + vbo_.set_divisor(param_->nbs_); +} + +void SkelSphereDrawer::set_vertices_spheres(const std::vector& spheres) +{ + update_vbo(spheres, &vbo_); + param_->set_vbos({&vbo_}); +} + +void SkelSphereDrawer::draw(const GLMat4& projection, const GLMat4& view) +{ + param_->draw_inst(projection, view, vbo_.size()); +} + +void SkelSphereDrawer::set_subdiv(uint32 ssub) +{ + param_->set_subdiv(ssub); + vbo_.set_divisor(param_->nbs_); +} + + +ShaderSkelCone* ShaderSkelCone::instance_ = nullptr; + +ShaderSkelCone::ShaderSkelCone() +{ +const char* vertex_shader_source = R"( +#version 330 +uniform int nbs; +uniform mat4 projection_matrix; +uniform mat4 model_view_matrix; +uniform mat3 normal_matrix; + +in vec4 P1; +in vec4 P2; +in vec3 N1; +in vec3 N2; + +out vec3 Po; +out vec3 No; + +const float PI = acos(-1.0); + +void main() +{ + float a = 2.0*PI*float(gl_VertexID/2)/float(nbs); + vec3 Q = cos(a) * N1 + sin(a) * N2; + + vec4 Px = mix(P1,P2,float(gl_VertexID%2)); + vec4 P4 = model_view_matrix * vec4(Px.xyz + Px.w * Q, 1); + + Po = P4.xyz; + float b = (P1.w-P2.w)/length(P2.xyz-P1.xyz); + No = normal_matrix * normalize(Q + b*cross(N1,N2)); + gl_Position = projection_matrix * P4; +} +)"; + + load2_bind(vertex_shader_source, skel_shape_fragment_shader_source, "P1","P2","N1","N2"); + get_uniforms("nbs", "color", "light_position"); +} + +void ShaderParamSkelCone::set_uniforms() +{ + shader_->set_uniforms_values(nbs_, color_, light_position_); +} + +void ShaderParamSkelCone::draw_inst(const GLMat4& projection, const GLMat4& view, uint32 nbi) +{ + this->bind(projection, view); + glDrawArraysInstanced(GL_TRIANGLE_STRIP, 0, 2 * nbs_ + 2, nbs_ * nbi); + this->release(); +} + +SkelConeDrawer::SkelConeDrawer() +{ + param_ = ShaderSkelCone::generate_param(); + vbo1_.set_divisor(1); + vbo2_.set_divisor(1); + vbo3_.set_divisor(1); + vbo4_.set_divisor(1); +} + + + +void SkelConeDrawer::set_real_cones(const std::vector& P1, const std::vector& P2, const std::vector& N1, const std::vector& N2) +{ + update_vbo(P1, &vbo1_); + update_vbo(P2, &vbo2_); + update_vbo(N1, &vbo3_); + update_vbo(N2, &vbo4_); + param_->set_vbos({&vbo1_,&vbo2_,&vbo3_,&vbo4_}); +} + +//void SkelConeDrawer::set_cones(const std::vector& P1, const std::vector& P2) +//{ +// std::vector A; +// std::vector B; +// std::vector N1; +// std::vector N2; +// std::size_t n = P1.size(); +// A.resize(n); +// B.resize(n); +// N1.resize(n); +// N2.resize(n); +// for (std::size_t i = 0; i < n; ++i) +// { +// compute_skel_cone(P1[i], P2[i], A[i], B[i], N1[i], N2[i]); +// } +// set_real_cones(A, B, N1, N2); +// +//} + +void SkelConeDrawer::set_edges_cones(const std::vector& edges) +{ + std::vector A; + std::vector B; + std::vector N1; + std::vector N2; + std::size_t n = edges.size()/2u; + A.resize(n); + B.resize(n); + N1.resize(n); + N2.resize(n); + for (std::size_t i = 0; i < n; ++i) + compute_skel_cone(edges[2 * i], edges[2 * i+1], A[i], B[i], N1[i], N2[i]); + set_real_cones(A, B, N1, N2); +} + +void SkelConeDrawer::draw(const GLMat4& projection, const GLMat4& view) +{ + param_->draw_inst(projection, view, vbo1_.size()); +} + +void SkelConeDrawer::compute_skel_cone(const GLVec4& A, const GLVec4& B, GLVec4& P1, GLVec4& P2, GLVec3& N1, GLVec3& N2) +{ + GLVec4 AB = B-A; + + if (abs(AB.z())<0.7f) + N1 = AB.topRows<3>().cross(GLVec3(0,0,1)).normalized(); + else + N1 = AB.topRows<3>().cross(GLVec3(1,0,0)).normalized(); + N2 = AB.topRows<3>().cross(N1).normalized(); + + const GLVec3& AB3 = AB.topRows<3>(); + float d = AB3.norm(); + float k = AB[3]/(d*d) ; + P1.topRows<3>() = A.topRows<3>() - AB3 * (k*A[3]); + P2.topRows<3>() = B.topRows<3>() - AB3 * (k*B[3]); + float kk = std::sqrt(1.0f-(AB[3]*AB[3]/(d*d))); + P1[3] = A[3] * kk ; + P2[3] = B[3] * kk ; +} + +ShaderSkelTri* ShaderSkelTri::instance_ = nullptr; + +ShaderSkelTri::ShaderSkelTri() +{ + const char* vertex_shader_source = R"( +#version 330 +uniform mat4 projection_matrix; +uniform mat4 model_view_matrix; +uniform mat3 normal_matrix; + +in vec3 P; +in vec3 N; + +out vec3 Po; +out vec3 No; + +void main() +{ + vec4 P4 = model_view_matrix * vec4(P, 1); + Po = P4.xyz; + No = normal_matrix * N; + gl_Position = projection_matrix * P4; +} +)"; + + load2_bind(vertex_shader_source, skel_shape_fragment_shader_source, "P", "N"); + get_uniforms("color", "light_position"); +} + +void ShaderParamSkelTri::set_uniforms() +{ + shader_->set_uniforms_values(color_, light_position_); +} + +void ShaderParamSkelTri::draw_inst(const GLMat4& projection, const GLMat4& view, uint32 nbi) +{ + this->bind(projection, view); + glDrawArrays(GL_TRIANGLES, 0, nbi); + this->release(); +} + + +SkelTriDrawer::SkelTriDrawer() +{ + param_ = ShaderSkelTri::generate_param(); + vbo_p_.set_divisor(0); + vbo_n_.set_divisor(0); +} + + + +void SkelTriDrawer::compute_CDisk(const GLVec4& sphA, const GLVec4& sphB, GLVec3& centerA, GLVec3& centerB) +{ + GLVec4 AB = sphB - sphA; + const GLVec3& AB3 = AB.topRows<3>(); + float d = AB3.norm(); + float k = AB[3] / (d * d); + + centerA = sphA.topRows<3>() - AB3 * (k * sphA[3]); + centerB = sphB.topRows<3>() - AB3 * (k * sphB[3]); +} + +void SkelTriDrawer::interPPS(const GLVec4& planeA, const GLVec4& planeB, const GLVec4& Sph, + GLVec3& I1, GLVec3& I2) +{ + const GLVec3& Na = planeA.topRows<3>(); + const GLVec3& Nb = planeB.topRows<3>(); + + GLVec3 U = Na.cross(Nb).normalized(); + + float dp = Na.dot(Nb); + float c1 = (-planeA[3] + planeB[3] * dp); + float c2 = (-planeB[3] + planeA[3] * dp); + GLVec3 O = (c1 * Na + c2 * Nb) / (1.0f - dp * dp); + + GLVec3 CO = O - Sph.topRows<3>(); + dp = U.dot(CO); + float delta = dp * dp - (CO.dot(CO) - Sph[3] * Sph[3]); + float k1 = -dp + std::sqrt(delta); + float k2 = -dp - std::sqrt(delta); + + I1 = O + k1 * U; + I2 = O + k2 * U; +} + +void SkelTriDrawer::compute_tri2(const GLVec4& Sph1, const GLVec4& Sph2, const GLVec4& Sph3, GLVec3* I) +{ + std::array centers; + + compute_CDisk(Sph1, Sph2, centers[1], centers[2]); + GLVec3 N1 = (Sph2.topRows<3>() - Sph1.topRows<3>()).normalized(); + compute_CDisk(Sph2, Sph3, centers[3], centers[4]); + GLVec3 N2 = (Sph3.topRows<3>() - Sph2.topRows<3>()).normalized(); + compute_CDisk(Sph3, Sph1, centers[5], centers[0]); + GLVec3 N3 = (Sph1.topRows<3>() - Sph3.topRows<3>()).normalized(); + + interPPS({N1[0], N1[1], N1[2], -N1.dot(centers[1])}, {-N3[0], -N3[1], -N3[2], N3.dot(centers[0])}, Sph1, I[0], + I[3]); + interPPS({N2[0], N2[1], N2[2], -N2.dot(centers[3])}, {-N1[0], -N1[1], -N1[2], N1.dot(centers[2])}, Sph2, I[1], + I[5]); + interPPS({N3[0], N3[1], N3[2], -N3.dot(centers[5])}, {-N2[0], -N2[1], -N2[2], N2.dot(centers[4])}, Sph3, I[2], + I[4]); +} + + + +void SkelTriDrawer::set_tris_faces(const std::vector& pts) +{ + assert(pts.size() % 3 == 0); + std::size_t n = pts.size()/3; + + std::vector tris; + tris.resize(6 * n); + for (std::size_t i = 0; i < n; ++i) + compute_tri2(pts[3 * i], pts[3 * i + 1], pts[3 * i + 2], &(tris[6 * i])); + + update_vbo(tris, &vbo_p_); + + n *= 2; + std::vector no_tris; + no_tris.resize(3 * n); + + for (std::size_t i = 0; i < n; ++i) + { + std::size_t j = 3 * i; + GLVec3 N = (tris[j + 1] - tris[j]).cross(tris[j + 2] - tris[j]).normalized(); + no_tris[j] = N; + no_tris[j + 1] = N; + no_tris[j + 2] = N; + } + update_vbo(no_tris, &vbo_n_); + + param_->set_vbos({&vbo_p_, &vbo_n_}); +} + + +void SkelTriDrawer::draw(const GLMat4& projection, const GLMat4& view) +{ + param_->draw_inst(projection, view, vbo_p_.size()); +} + +} // namespace rendering +} // namespace cgogn \ No newline at end of file diff --git a/cgogn/rendering/skelshape.h b/cgogn/rendering/skelshape.h new file mode 100644 index 000000000..4b533a600 --- /dev/null +++ b/cgogn/rendering/skelshape.h @@ -0,0 +1,291 @@ +/******************************************************************************* + * CGoGN: Combinatorial and Geometric modeling with Generic N-dimensional Maps * + * Copyright (C), IGG Group, ICube, University of Strasbourg, France * + * * + * This library is free software; you can redistribute it and/or modify it * + * under the terms of the GNU Lesser General Public License as published by the * + * Free Software Foundation; either version 2.1 of the License, or (at your * + * option) any later version. * + * * + * This library is distributed in the hope that it will be useful, but WITHOUT * + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * + * for more details. * + * * + * You should have received a copy of the GNU Lesser General Public License * + * along with this library; if not, write to the Free Software Foundation, * + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * + * * + * Web site: http://cgogn.unistra.fr/ * + * Contact information: cgogn@unistra.fr * + * * + *******************************************************************************/ + +#ifndef CGOGN_RENDERING_SKEL_SHAPE_DRAWER_H_ +#define CGOGN_RENDERING_SKEL_SHAPE_DRAWER_H_ + +#include +#include +#include + +namespace cgogn +{ + +namespace rendering +{ +/* +ajouter: +void ShaderParam::set_vbos_inst(const std::vector& vbos) +void VBO::associate(GLuint attrib, int32 stride = 0, uint32 first = 0, uint32 divisor = 0 ) +*/ +class ShaderParamSkelShape : public ShaderParam +{ +public: + //subdiv + int nbs_; + //color RBGA + GLColor color_; + + GLVec3 light_position_; + + std::unique_ptr inst_vao_; + + ShaderParamSkelShape(ShaderProgram* prg); + + virtual void draw_inst(const GLMat4& projection, const GLMat4& view, uint32 nbi) = 0; + + inline void set_subdiv(int32 nb) + { + nbs_ = nb; + } + + inline void set_light_pos(const GLVec3& lp) + { + light_position_ = lp; + } + + inline void set_color(const GLColor& col) + { + color_ = col; + } + +}; + + +DECLARE_SHADER_CLASS(SkelSphere, false, CGOGN_STR(SkelSphere)) + +class CGOGN_RENDERING_EXPORT ShaderParamSkelSphere : public ShaderParamSkelShape +{ + void set_uniforms() override; + +public: + + using ShaderType = ShaderSkelSphere; + + inline ShaderParamSkelSphere(ShaderType* sh): + ShaderParamSkelShape(sh) + {} + + inline ~ShaderParamSkelSphere() override {} + + void draw_inst(const GLMat4& projection, const GLMat4& view, uint32 nbi) override; +}; + +class SkelSphereDrawer +{ + VBO vbo_; +public: + std::unique_ptr param_; + SkelSphereDrawer(); + void set_vertices_spheres(const std::vector& P1); + void set_subdiv(uint32 sub); + void draw(const GLMat4& projection, const GLMat4& view); +}; + + + +DECLARE_SHADER_CLASS(SkelCone, false, CGOGN_STR(SkelCone)) + +class CGOGN_RENDERING_EXPORT ShaderParamSkelCone : public ShaderParamSkelShape +{ + + void set_uniforms() override; + +public: + + using ShaderType = ShaderSkelCone; + + inline ShaderParamSkelCone(ShaderType* sh): + ShaderParamSkelShape(sh) + {} + + inline ~ShaderParamSkelCone() override {} + + void draw_inst(const GLMat4& projection, const GLMat4& view, uint32 nbi) override; +}; + +class SkelConeDrawer +{ + VBO vbo1_; + VBO vbo2_; + VBO vbo3_; + VBO vbo4_; + + void set_real_cones(const std::vector& P1, const std::vector& P2, const std::vector& N1, + const std::vector& N2); + void compute_skel_cone(const GLVec4& A, const GLVec4& B, GLVec4& P1, GLVec4& P2, GLVec3& N1, GLVec3& N2); + +public: + std::unique_ptr param_; + + SkelConeDrawer(); + + void set_edges_cones(const std::vector& edges); + + void draw(const GLMat4& projection, const GLMat4& view); + +}; + + +DECLARE_SHADER_CLASS(SkelTri, false, CGOGN_STR(SkelTri)) + +class CGOGN_RENDERING_EXPORT ShaderParamSkelTri : public ShaderParamSkelShape +{ + void set_uniforms() override; +public: + + using ShaderType = ShaderSkelTri; + + inline ShaderParamSkelTri(ShaderType* sh): + ShaderParamSkelShape(sh) + {} + + inline ~ShaderParamSkelTri() override {} + + void draw_inst(const GLMat4& projection, const GLMat4& view, uint32 nbi) override; +}; + +class SkelTriDrawer +{ + VBO vbo_p_; + VBO vbo_n_; + + void compute_CDisk(const GLVec4& A, const GLVec4& B, GLVec3& P1, GLVec3& P2); + void interPPS(const GLVec4& Pa, const GLVec4& Pb, + const GLVec4& Sph, GLVec3& I1, GLVec3& I2); + void compute_tri2(const GLVec4& P1, const GLVec4& P2, const GLVec4& P3, GLVec3* I); + +public: + std::unique_ptr param_; + SkelTriDrawer(); + void set_tris_faces(const std::vector& pts); + void draw(const GLMat4& projection, const GLMat4& view); +}; + + +/* + must be created with correct OGL context ! + usage: + 1 fill the buffers with add_vertex add_edge and add tri + (parameter can be any type of VEC which offer [] operator and good number of components. + 2 call update + 3 draw +*/ +class SkelShapeDrawer +{ + std::vector vertices_; + std::vector edges_; + std::vector triangles_; + + SkelSphereDrawer sphere_drawer_; + SkelConeDrawer cone_drawer_; + SkelTriDrawer tri_drawer_; + +public: + inline SkelShapeDrawer() + {} + + + template + void add_vertex(const VEC4& v) + { + vertices_.emplace_back(float(v[0]), float(v[1]), float(v[2]), float(v[3])); + } + + template + inline void add_vertex(const VEC3& v, SCAL r) + { + vertices_.emplace_back(float(v[0]), float(v[1]), float(v[2]), float(r)); + } + + template + void add_edge(const VEC4_1& e1, const VEC4_2& e2) + { + edges_.emplace_back(float(e1[0]), float(e1[1]), float(e1[2]), float(e1[3])); + edges_.emplace_back(float(e2[0]), float(e2[1]), float(e2[2]), float(e2[3])); + } + + template + void add_edge(const VEC3_1& e1, SCAL_1 r1, const VEC3_2& e2, SCAL_2 r2) + { + edges_.emplace_back(float(e1[0]), float(e1[1]), float(e1[2]), float(r1)); + edges_.emplace_back(float(e2[0]), float(e2[1]), float(e2[2]), float(r2)); + } + + template + void add_triangle(const VEC4_1& t1, const VEC4_2& t2, const VEC4_3& t3) + { + triangles_.emplace_back(float(t1[0]), float(t1[1]), float(t1[2]), float(t1[3])); + triangles_.emplace_back(float(t2[0]), float(t2[1]), float(t2[2]), float(t2[3])); + triangles_.emplace_back(float(t3[0]), float(t3[1]), float(t3[2]), float(t3[3])); + } + + template + void add_triangle(const VEC3_1& t1, SCAL_1 r1, const VEC3_2& t2, SCAL_2 r2, const VEC3_3& t3, SCAL_3 r3) + { + triangles_.emplace_back(float(t1[0]), float(t1[1]), float(t1[2]), float(r1)); + triangles_.emplace_back(float(t2[0]), float(t2[1]), float(t2[2]), float(r2)); + triangles_.emplace_back(float(t3[0]), float(t3[1]), float(t3[2]), float(r3)); + } + + /* + * eed to be called after filling the buffers (and before calling draw) + */ + inline void update() + { + sphere_drawer_.set_vertices_spheres(vertices_); + cone_drawer_.set_edges_cones(edges_); + tri_drawer_.set_tris_faces(triangles_); + } + + inline void draw(const GLMat4& proj_matrix, const GLMat4& view_matrix) + { + sphere_drawer_.draw(proj_matrix, view_matrix); + cone_drawer_.draw(proj_matrix, view_matrix); + tri_drawer_.draw(proj_matrix, view_matrix); + } + + inline void set_subdiv(uint32 nbs) + { + sphere_drawer_.set_subdiv(nbs); + cone_drawer_.param_->set_subdiv(nbs); + } + + inline void set_color(const GLColor col) + { + sphere_drawer_.param_->set_color(col); + cone_drawer_.param_->set_color(col); + tri_drawer_.param_->set_color(col); + } +}; + + +} // namespace rendering + +} // namespace cgogn + +#endif // CGOGN_RENDERING_SHAPE3_DRAWER_H_ + + + + diff --git a/cgogn/rendering/vbo.h b/cgogn/rendering/vbo.h index 5e3965c3b..ef8219f73 100644 --- a/cgogn/rendering/vbo.h +++ b/cgogn/rendering/vbo.h @@ -49,13 +49,19 @@ class CGOGN_RENDERING_EXPORT VBO std::size_t nb_vectors_; int32 vector_dimension_; std::string name_; + uint32 divisor_; public: - inline VBO(int32 vec_dim = 3) : id_texture_buffer_(0), nb_vectors_(0), vector_dimension_(vec_dim) + inline VBO(int32 vec_dim = 3) : id_texture_buffer_(0), nb_vectors_(0), vector_dimension_(vec_dim), divisor_(0) { glGenBuffers(1, &id_); } + inline void set_divisor(uint32 d) + { + divisor_ = d; + } + inline ~VBO() { glDeleteBuffers(1, &id_); @@ -180,6 +186,7 @@ class CGOGN_RENDERING_EXPORT VBO glEnableVertexAttribArray(attrib); glVertexAttribPointer(attrib, vector_dimension(), GL_FLOAT, GL_FALSE, stride * vector_dimension() * 4, reinterpret_cast(first * uint64(vector_dimension()) * 4u)); + glVertexAttribDivisor(attrib, divisor_); release(); } }; diff --git a/cgogn/simulation/apps/CMakeLists.txt b/cgogn/simulation/apps/CMakeLists.txt index 1a5eeba3a..bf7d38169 100644 --- a/cgogn/simulation/apps/CMakeLists.txt +++ b/cgogn/simulation/apps/CMakeLists.txt @@ -1,5 +1,3 @@ -cmake_minimum_required(VERSION 3.0 FATAL_ERROR) - project(cgogn_rendering_examples LANGUAGES CXX )