From 880c7b0aac3a44e3edc27e0401af2f1b6bb22cd5 Mon Sep 17 00:00:00 2001 From: hodasemi Date: Thu, 17 May 2018 18:59:31 +0200 Subject: [PATCH] Add gl wrapper classes --- .vscode/settings.json | 8 ++- CGII/glsl/skinning.glgs | 4 +- CGII/src/Bone.cpp | 54 ++++++++------ CGII/src/GLClasses/buffer.h | 32 +++++++++ CGII/src/GLClasses/program.h | 133 +++++++++++++++++++++++++++++++++++ CGII/src/SkeletonViewer.cpp | 73 ++++++++++--------- CGII/src/SkeletonViewer.h | 32 +++++---- CGII/src/main.cpp | 12 ++-- 8 files changed, 272 insertions(+), 76 deletions(-) create mode 100644 CGII/src/GLClasses/buffer.h create mode 100644 CGII/src/GLClasses/program.h diff --git a/.vscode/settings.json b/.vscode/settings.json index 843b664..30cec68 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -2,5 +2,11 @@ "C_Cpp.default.includePath": [ "CGII/src/", "framework/include/" - ] + ], + "files.associations": { + "array": "cpp", + "initializer_list": "cpp", + "string_view": "cpp", + "valarray": "cpp" + } } \ No newline at end of file diff --git a/CGII/glsl/skinning.glgs b/CGII/glsl/skinning.glgs index 5aa683c..6efb20a 100644 --- a/CGII/glsl/skinning.glgs +++ b/CGII/glsl/skinning.glgs @@ -1,4 +1,4 @@ -#version 330 compatibility +#version 150 layout(triangles) in; layout(triangle_strip, max_vertices = 3) out; @@ -16,7 +16,7 @@ void main(void) gl_Position = modelviewproj * position[0]; EmitVertex(); - + gl_Position = modelviewproj * position[1]; EmitVertex(); diff --git a/CGII/src/Bone.cpp b/CGII/src/Bone.cpp index 07dd568..62b44ed 100644 --- a/CGII/src/Bone.cpp +++ b/CGII/src/Bone.cpp @@ -1,5 +1,5 @@ -// This source code is property of the Computer Graphics and Visualization -// chair of the TU Dresden. Do not distribute! +// This source code is property of the Computer Graphics and Visualization +// chair of the TU Dresden. Do not distribute! // Copyright (C) CGV TU Dresden - All Rights Reserved // #include "Bone.h" @@ -11,7 +11,8 @@ Bone::Bone() : parent(nullptr), length(0.0f), direction_in_world_space(0.0, 0.0, 0.0), translationTransforms(0) -{} +{ +} Bone::~Bone() { @@ -26,17 +27,30 @@ Bone::~Bone() orientation.clear(); } +void print_mat4(Mat4 &m) +{ + for (int x = 0; x < 4; x++) + { + for (int y = 0; y < 4; y++) + { + std::cout << m[x * 4 + y] << " "; + } + + std::cout << std::endl; + } +} + void Bone::calculate_matrices() { orientationTransformGlobalToLocal.identity(); - std::for_each(orientation.begin(), orientation.end(), [&](AtomicTransform* t) { + std::for_each(orientation.begin(), orientation.end(), [&](AtomicTransform *t) { orientationTransformGlobalToLocal = orientationTransformGlobalToLocal * t->calculate_matrix(); }); orientationTransformLocalToGlobal = cgv::math::inv(orientationTransformGlobalToLocal); /*Task 2.1: Implement matrix calculation */ - /*Task 4.6: Implement matrix calculation */ + /*Task 4.6: Implement matrix calculation */ } Mat4 Bone::calculate_transform_prev_to_current_with_dofs() @@ -55,10 +69,10 @@ Mat4 Bone::calculate_transform_prev_to_current_without_dofs() return t; } -void Bone::add_dof(AtomicTransform* dof) +void Bone::add_dof(AtomicTransform *dof) { - dof->set_index_in_amc(dofs.size()); - if (dynamic_cast(dof)) + dof->set_index_in_amc(dofs.size()); + if (dynamic_cast(dof)) { dofs.push_front(std::shared_ptr(dof)); ++translationTransforms; @@ -67,40 +81,40 @@ void Bone::add_dof(AtomicTransform* dof) dofs.insert(dofs.begin() + translationTransforms, std::shared_ptr(dof)); } -void Bone::set_name(const std::string& name) { this->name = name; } -const std::string& Bone::get_name() const { return name; } +void Bone::set_name(const std::string &name) { this->name = name; } +const std::string &Bone::get_name() const { return name; } -void Bone::set_direction_in_world_space(const Vec3& direction) { this->direction_in_world_space = direction; } -const Vec3& Bone::get_direction_in_world_space() const { return direction_in_world_space; } +void Bone::set_direction_in_world_space(const Vec3 &direction) { this->direction_in_world_space = direction; } +const Vec3 &Bone::get_direction_in_world_space() const { return direction_in_world_space; } void Bone::set_length(float l) { this->length = l; } float Bone::get_length() const { return length; } -void Bone::add_axis_rotation(AtomicTransform* transform) { orientation.push_front(transform); } -void Bone::add_child(Bone* child) +void Bone::add_axis_rotation(AtomicTransform *transform) { orientation.push_front(transform); } +void Bone::add_child(Bone *child) { child->set_parent(this); children.push_back(child); } -Bone* Bone::child_at(int i) const { return children[i]; } +Bone *Bone::child_at(int i) const { return children[i]; } int Bone::childCount() const { return children.size(); } -void Bone::set_parent(Bone* parent) +void Bone::set_parent(Bone *parent) { this->parent = parent; } -Bone* Bone::get_parent() const { return parent; } +Bone *Bone::get_parent() const { return parent; } int Bone::dof_count() const { return dofs.size(); } std::shared_ptr Bone::get_dof(int dofIndex) const { return dofs[dofIndex]; } -const Mat4& Bone::get_binding_pose_matrix() const +const Mat4 &Bone::get_binding_pose_matrix() const { return transformLocalToGlobal; } -const Mat4& Bone::get_translation_transform_current_joint_to_next() const { return translationTransformCurrentJointToNext; } -const Mat4& Bone::get_orientation_transform_prev_joint_to_current() const { return orientationTransformPrevJointToCurrent; } +const Mat4 &Bone::get_translation_transform_current_joint_to_next() const { return translationTransformCurrentJointToNext; } +const Mat4 &Bone::get_orientation_transform_prev_joint_to_current() const { return orientationTransformPrevJointToCurrent; } Vec4 Bone::get_bone_local_root_position() const { return Vec4(0, 0, 0, 1); } Vec4 Bone::get_bone_local_tip_position() const { return translationTransformCurrentJointToNext * Vec4(0, 0, 0, 1); } \ No newline at end of file diff --git a/CGII/src/GLClasses/buffer.h b/CGII/src/GLClasses/buffer.h new file mode 100644 index 0000000..9fc8ac4 --- /dev/null +++ b/CGII/src/GLClasses/buffer.h @@ -0,0 +1,32 @@ +#ifndef BUFFER +#define BUFFER + +#include +#include + +template +unsigned int sizevec(const std::vector &p_vec) { return sizeof(T) * p_vec.size(); } + +class Buffer +{ + public: + Buffer() + { + glGenBuffers(1, &m_vbo); + } + + ~Buffer() + { + glDeleteBuffers(1, &m_vbo); + } + + GLuint getBuffer() + { + return m_vbo; + } + + private: + GLuint m_vbo; +}; + +#endif // BUFFER diff --git a/CGII/src/GLClasses/program.h b/CGII/src/GLClasses/program.h new file mode 100644 index 0000000..18099fc --- /dev/null +++ b/CGII/src/GLClasses/program.h @@ -0,0 +1,133 @@ +#ifndef PROGRAM +#define PROGRAM + +#include +#include +#include + +#include + +class Program +{ + public: + Program() + { + } + + ~Program() + { + glDeleteProgram(m_prog); + } + + void createProgram(const char *vs, const char *fs) + { + GLuint vert = createShader(vs, GL_VERTEX_SHADER); + GLuint frag = createShader(fs, GL_FRAGMENT_SHADER); + + if ((vert == 0) || (frag == 0)) + { + return; + } + + m_prog = glCreateProgram(); + glAttachShader(m_prog, vert); + glAttachShader(m_prog, frag); + glLinkProgram(m_prog); + + glDeleteShader(vert); + glDeleteShader(frag); + } + + void createProgram(const char *vs, const char *gs, const char *fs) + { + GLuint vert = createShader(vs, GL_VERTEX_SHADER); + GLuint geom = createShader(gs, GL_GEOMETRY_SHADER); + GLuint frag = createShader(fs, GL_FRAGMENT_SHADER); + + if ((vert == 0) || (frag == 0) || (geom == 0)) + { + return; + } + + m_prog = glCreateProgram(); + glAttachShader(m_prog, vert); + glAttachShader(m_prog, geom); + glAttachShader(m_prog, frag); + glLinkProgram(m_prog); + + glDeleteShader(vert); + glDeleteShader(geom); + glDeleteShader(frag); + } + + void createProgram(const std::string vs, const std::string fs) + { + createProgram(vs.c_str(), fs.c_str()); + } + + GLuint getProgram() + { + return m_prog; + } + + private: + inline std::string loadShaderText(const char *path) + { + std::ifstream is(path); + std::string s_save; + + if (is.is_open()) + { + s_save.assign(std::istreambuf_iterator(is), std::istreambuf_iterator()); + is.close(); + } + else + { + std::cout << "could not open " << path << std::endl; + } + + return s_save; + } + + inline GLuint createShader(const char *path, GLenum shadertype) + { + std::string s_source = loadShaderText(path); + + if (s_source.empty()) + { + return 0; + } + + const char *c_source = s_source.c_str(); + + GLuint shader = glCreateShader(shadertype); + glShaderSource(shader, 1, (const char **)&c_source, NULL); + glCompileShader(shader); + + GLint shaderCompiled = GL_FALSE; + glGetShaderiv(shader, GL_COMPILE_STATUS, &shaderCompiled); + if (shaderCompiled != GL_TRUE) + { + GLint log_length = 0; + glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &log_length); + + char *log = new char[log_length]; + + glGetShaderInfoLog(shader, (GLsizei)log_length, NULL, log); + + std::cout << "error compiling shader( " << path << " ): " << std::endl + << log << std::endl; + + delete[] log; + + glDeleteShader(shader); + shader = 0; + } + + return shader; + } + + GLuint m_prog; +}; + +#endif // PROGRAM diff --git a/CGII/src/SkeletonViewer.cpp b/CGII/src/SkeletonViewer.cpp index b20c1b1..1d6145e 100644 --- a/CGII/src/SkeletonViewer.cpp +++ b/CGII/src/SkeletonViewer.cpp @@ -1,5 +1,5 @@ -// This source code is property of the Computer Graphics and Visualization -// chair of the TU Dresden. Do not distribute! +// This source code is property of the Computer Graphics and Visualization +// chair of the TU Dresden. Do not distribute! // Copyright (C) CGV TU Dresden - All Rights Reserved // #include "SkeletonViewer.h" @@ -18,19 +18,27 @@ using namespace cgv::utils; cgv::render::shader_program Mesh::prog; // The constructor of this class -SkeletonViewer::SkeletonViewer(DataStore* data) +SkeletonViewer::SkeletonViewer(DataStore *data) : node("Skeleton Viewer"), data(data) - -{ + +{ + program.createProgram("CGII/glsl/skinning.glvs", "CGII/glsl/skinning.glgs", "CGII/glsl/skinning.glfs"); + connect(data->skeleton_changed, this, &SkeletonViewer::skeleton_changed); connect(get_animation_trigger().shoot, this, &SkeletonViewer::timer_event); } //draws a part of a skeleton, represented by the given root node -void SkeletonViewer::draw_skeleton_subtree(Bone* node, const Mat4& global_to_parent_local) +void SkeletonViewer::draw_skeleton_subtree(Bone *node, const Mat4 &global_to_parent_local) { //Task: Draw skeleton + Mat4 transform; + + for (int i = 0; i < node->childCount(); i++) + { + draw_skeleton_subtree(node->child_at(i), transform); + } } void SkeletonViewer::timer_event(double, double dt) @@ -48,7 +56,7 @@ void SkeletonViewer::stop_animation() //Task: Implement animation } -void SkeletonViewer::skeleton_changed(std::shared_ptr s) +void SkeletonViewer::skeleton_changed(std::shared_ptr s) { // This function is called whenever the according signal of the // data store has been called. @@ -57,9 +65,10 @@ void SkeletonViewer::skeleton_changed(std::shared_ptr s) generate_tree_view_nodes(); //Fit view to skeleton - std::vector view_ptrs; + std::vector view_ptrs; cgv::base::find_interface(get_node(), view_ptrs); - if (view_ptrs.empty()) { + if (view_ptrs.empty()) + { // If there is no view, we cannot update it cgv::gui::message("could not find a view to adjust!!"); } @@ -69,15 +78,15 @@ void SkeletonViewer::skeleton_changed(std::shared_ptr s) view_ptrs[0]->set_focus(center.x(), center.y(), center.z()); // Set the scene's size at the focus point view_ptrs[0]->set_y_extent_at_focus(s->getMax().y() - s->getMin().y()); - } + } - //connect signals - recursive_connect_signals(s->get_root()); + //connect signals + recursive_connect_signals(s->get_root()); post_redraw(); } -void SkeletonViewer::recursive_connect_signals(Bone* b) +void SkeletonViewer::recursive_connect_signals(Bone *b) { for (int i = 0; i < b->dof_count(); ++i) connect(b->get_dof(i)->changed_signal, this, &SkeletonViewer::dof_changed); @@ -103,7 +112,7 @@ void SkeletonViewer::generate_tree_view_nodes() generate_tree_view_nodes(tree_view, data->get_skeleton()->get_root()); } -void SkeletonViewer::generate_tree_view_nodes(gui_group_ptr parent, Bone* bone) +void SkeletonViewer::generate_tree_view_nodes(gui_group_ptr parent, Bone *bone) { if (bone->childCount() == 0) { @@ -123,7 +132,7 @@ void SkeletonViewer::generate_tree_view_nodes(gui_group_ptr parent, Bone* bone) void SkeletonViewer::start_choose_base() { - Bone* b = data->get_endeffector(); + Bone *b = data->get_endeffector(); data->set_endeffector(nullptr); data->set_base(b); } @@ -132,9 +141,9 @@ void SkeletonViewer::tree_selection_changed(base_ptr p, bool select) { bone_group->remove_all_children(); - if (select) + if (select) { - Bone* bone = gui_to_bone.at(p); + Bone *bone = gui_to_bone.at(p); generate_bone_gui(bone); data->set_endeffector(bone); } @@ -194,7 +203,7 @@ void SkeletonViewer::load_pinocchio() std::string filename = cgv::gui::file_open_dialog("Open", "Pinocchio skeleton (*.out):*.out"); if (!filename.empty()) { - data->get_skeleton()->read_pinocchio_file(filename); + data->get_skeleton()->read_pinocchio_file(filename); skeleton_changed(data->get_skeleton()); } } @@ -216,13 +225,13 @@ void SkeletonViewer::load_animation() // Create the gui elements void SkeletonViewer::create_gui() -{ +{ //Bone tree view - parent_group->multi_set("layout='table';rows=3;spacings='normal';"); + parent_group->multi_set("layout='table';rows=3;spacings='normal';"); - tree_view = add_group("", "tree_group", "h=300;column_heading_0='Bones';column_width_0=-1", "f"); + tree_view = add_group("", "tree_group", "h=300;column_heading_0='Bones';column_width_0=-1", "f"); bone_group = add_group("", "align_group", "h=150", "f"); - + auto dock_group = add_group("", "dockable_group", "", "fF"); connect(tree_view->on_selection_change, this, &SkeletonViewer::tree_selection_changed); @@ -233,28 +242,28 @@ void SkeletonViewer::create_gui() auto gui_group = dock_group->add_group("", "align_group", "", "f"); connect_copy(gui_group->add_button("Load ASF skeleton", "", "\n")->click, - rebind(this, &SkeletonViewer::load_skeleton)); + rebind(this, &SkeletonViewer::load_skeleton)); connect_copy(gui_group->add_button("Load Animation", "", "\n")->click, - rebind(this, &SkeletonViewer::load_animation)); + rebind(this, &SkeletonViewer::load_animation)); connect_copy(gui_group->add_button("Start Animation", "", "\n")->click, - rebind(this, &SkeletonViewer::start_animation)); + rebind(this, &SkeletonViewer::start_animation)); connect_copy(gui_group->add_button("Stop Animation", "", "\n")->click, - rebind(this, &SkeletonViewer::stop_animation)); + rebind(this, &SkeletonViewer::stop_animation)); connect_copy(gui_group->add_button("Choose IK Base", "", "\n")->click, - rebind(this, &SkeletonViewer::start_choose_base)); - + rebind(this, &SkeletonViewer::start_choose_base)); + connect_copy(gui_group->add_button("Write Pinocchio skeleton", "", "\n")->click, - rebind(this, &SkeletonViewer::write_pinocchio)); + rebind(this, &SkeletonViewer::write_pinocchio)); connect_copy(gui_group->add_button("Load Pinocchio skeleton", "", "\n")->click, - rebind(this, &SkeletonViewer::load_pinocchio)); + rebind(this, &SkeletonViewer::load_pinocchio)); } -void SkeletonViewer::generate_bone_gui(Bone* bone) +void SkeletonViewer::generate_bone_gui(Bone *bone) { // Add bone-specific gui elements to bone_group. // Use the layout "\n" to specify vertical alignment @@ -270,7 +279,7 @@ void SkeletonViewer::generate_bone_gui(Bone* bone) } } -void SkeletonViewer::draw(context& c) +void SkeletonViewer::draw(context &c) { glDisable(GL_LIGHTING); glDisable(GL_CULL_FACE); diff --git a/CGII/src/SkeletonViewer.h b/CGII/src/SkeletonViewer.h index 898940d..40950b3 100644 --- a/CGII/src/SkeletonViewer.h +++ b/CGII/src/SkeletonViewer.h @@ -1,5 +1,5 @@ -// This source code is property of the Computer Graphics and Visualization -// chair of the TU Dresden. Do not distribute! +// This source code is property of the Computer Graphics and Visualization +// chair of the TU Dresden. Do not distribute! // Copyright (C) CGV TU Dresden - All Rights Reserved // #pragma once @@ -7,6 +7,9 @@ #include "common.h" #include "DataStore.h" +#include "GLClasses/buffer.h" +#include "GLClasses/program.h" + #include #include #include @@ -23,23 +26,23 @@ using namespace cgv::utils; class SkeletonViewer : public node, public drawable, public provider { -private: - DataStore* data; + private: + DataStore *data; gui_group_ptr tree_view; gui_group_ptr bone_group; // Maps gui elements in the tree view to a specific bone - std::map gui_to_bone; + std::map gui_to_bone; // slot for the signal void timer_event(double, double dt); void skeleton_changed(std::shared_ptr); void generate_tree_view_nodes(); - void generate_tree_view_nodes(gui_group_ptr parent, Bone* bone); + void generate_tree_view_nodes(gui_group_ptr parent, Bone *bone); void tree_selection_changed(base_ptr p, bool select); - void generate_bone_gui(Bone* bone); + void generate_bone_gui(Bone *bone); void load_skeleton(); void write_pinocchio(); @@ -47,25 +50,24 @@ private: void load_animation(); void start_choose_base(); - void draw_skeleton_subtree(Bone* node, const Mat4& global_to_parent_local); + void draw_skeleton_subtree(Bone *node, const Mat4 &global_to_parent_local); void dof_changed(double new_value); - void recursive_connect_signals(Bone* b); - - + void recursive_connect_signals(Bone *b); void start_animation(); void stop_animation(); -public: + public: // The constructor of this class - SkeletonViewer(DataStore*); + SkeletonViewer(DataStore *); // Create the gui elements void create_gui(); // Draw the scene - void draw(context& c); + void draw(context &c); std::string get_parent_type() const; -}; + Program program; +}; diff --git a/CGII/src/main.cpp b/CGII/src/main.cpp index bce9ef6..4671f98 100644 --- a/CGII/src/main.cpp +++ b/CGII/src/main.cpp @@ -1,5 +1,5 @@ -// This source code is property of the Computer Graphics and Visualization -// chair of the TU Dresden. Do not distribute! +// This source code is property of the Computer Graphics and Visualization +// chair of the TU Dresden. Do not distribute! // Copyright (C) CGV TU Dresden - All Rights Reserved // // The main file of the plugin. It defines a global register variable @@ -16,15 +16,15 @@ using namespace cgv::base; struct Initializer { - DataStore* data; + DataStore *data; Initializer() - { - register_object(base_ptr(new CGVDemo()), ""); + { + //register_object(base_ptr(new CGVDemo()), ""); data = new DataStore(); - /*register_object(base_ptr(new SkeletonViewer(data)), "");*/ + register_object(base_ptr(new SkeletonViewer(data)), ""); /*register_object(base_ptr(new IKViewer(data)), "");*/