55#include < iostream>
66#include < fstream>
77#include < sstream>
8- #include < unordered_map>
98
10- void OBJ::load_obj (std::string path, bool enable_group ) {
9+ void OBJ::load_obj (std::string path, bool grouped ) {
1110 std::ifstream file (path);
1211 if (!file.is_open ()) {
1312 std::cerr << " Failed to open file: " << path << ' \n ' ;
1413 return ;
1514 }
1615
1716 std::string line;
18- int current_group = - 1 , grouped_face = 0 ;
17+ unsigned int current_group = 0 ;
1918
2019 while (std::getline (file, line)) {
2120 if (line.substr (0 , 2 ) == " v " ) {
@@ -37,21 +36,18 @@ void OBJ::load_obj(std::string path, bool enable_group) {
3736 glm::uvec3 face = glm::uvec3 (indices[0 ], indices[i - 1 ], indices[i]);
3837 faces.push_back (face);
3938
40- if (!enable_group && current_group >= 0 ) continue ;
41- face_groups[current_group].push_back (faces.size () - 1 );
42- grouped_face++;
39+ smoothing_groups[current_group].push_back (faces.size () - 1 );
4340 }
4441 } else if (line.substr (0 , 7 ) == " #group " ) {
4542 std::istringstream s (line.substr (7 ));
4643 unsigned int group;
4744 s >> group;
48- current_group = group;
45+ if (grouped) current_group = group;
4946 }
5047 }
5148
5249 file.close ();
5350 std::cout << " Loaded " << vertices.size () << " vertices, " << faces.size () << " faces.\n " ;
54- std::cout << grouped_face << " faces grouped.\n " ;
5551}
5652
5753static glm::vec3 perspective_divide (glm::vec4 pos) {
@@ -79,13 +75,12 @@ static glm::vec3 compute_contrib_normal(glm::vec3 v0, glm::vec3 v1, glm::vec3 v2
7975 return glm::normalize (norm) * contrib_w;
8076}
8177
82- void OBJ::draw_obj ( ) {
78+ static void object_draw_flat_pass (OBJ const & obj ) {
8379 glBegin (GL_TRIANGLES);
84-
85- for (auto face : faces) {
86- auto const &a = vertices.at (face[0 ]);
87- auto const &b = vertices.at (face[1 ]);
88- auto const &c = vertices.at (face[2 ]);
80+ for (auto face : obj.faces ) {
81+ auto const & a = obj.vertices .at (face[0 ]);
82+ auto const & b = obj.vertices .at (face[1 ]);
83+ auto const & c = obj.vertices .at (face[2 ]);
8984
9085 glm::vec3 norm = compute_normal (a, b, c);
9186 glNormal3fv (glm::value_ptr (norm));
@@ -94,38 +89,37 @@ void OBJ::draw_obj() {
9489 glVertex3fv (glm::value_ptr (b));
9590 glVertex3fv (glm::value_ptr (c));
9691 }
97-
9892 CHECK_GL (glEnd ());
9993}
10094
101- void OBJ::draw_obj_smooth () {
102- std::vector<glm::vec3> vertexNormalBuffer (vertices.size ());
103-
104- // NormalComputePass
105- for (auto & face : faces) {
106- auto const & a = vertices.at (face[0 ]);
107- auto const & b = vertices.at (face[1 ]);
108- auto const & c = vertices.at (face[2 ]);
109-
110- vertexNormalBuffer[face[0 ]] += compute_contrib_normal (a, b, c, 0 );
111- vertexNormalBuffer[face[1 ]] += compute_contrib_normal (a, b, c, 1 );
112- vertexNormalBuffer[face[2 ]] += compute_contrib_normal (a, b, c, 2 );
95+ static void normal_compute_pass (OBJ const & obj, std::vector<unsigned int > const & face_indices, std::vector<glm::vec3>& vertex_normal_buffer) {
96+ for (auto const & index : face_indices) {
97+ auto const & face = obj.faces .at (index);
98+ auto const & a = obj.vertices .at (face[0 ]);
99+ auto const & b = obj.vertices .at (face[1 ]);
100+ auto const & c = obj.vertices .at (face[2 ]);
101+
102+ vertex_normal_buffer[face[0 ]] += compute_contrib_normal (a, b, c, 0 );
103+ vertex_normal_buffer[face[1 ]] += compute_contrib_normal (a, b, c, 1 );
104+ vertex_normal_buffer[face[2 ]] += compute_contrib_normal (a, b, c, 2 );
113105 }
114- for (auto & vn : vertexNormalBuffer ) {
106+ for (auto & vn : vertex_normal_buffer ) {
115107 vn = glm::normalize (vn);
116108 }
109+ }
117110
118- // ObjectDrawPass
111+ static void object_draw_smooth_pass (OBJ const & obj, std::vector< unsigned int > const & face_indices, std::vector<glm::vec3> const & vertex_normal_buffer) {
119112 glBegin (GL_TRIANGLES);
120- for (auto const & face : faces) {
121- auto const & a = vertices.at (face[0 ]);
122- auto const & b = vertices.at (face[1 ]);
123- auto const & c = vertices.at (face[2 ]);
124-
125- auto const & n0 = vertexNormalBuffer.at (face[0 ]);
126- auto const & n1 = vertexNormalBuffer.at (face[1 ]);
127- auto const & n2 = vertexNormalBuffer.at (face[2 ]);
128-
113+ for (auto const & index : face_indices) {
114+ auto const & face = obj.faces .at (index);
115+ auto const & a = obj.vertices .at (face[0 ]);
116+ auto const & b = obj.vertices .at (face[1 ]);
117+ auto const & c = obj.vertices .at (face[2 ]);
118+
119+ auto const & n0 = vertex_normal_buffer.at (face[0 ]);
120+ auto const & n1 = vertex_normal_buffer.at (face[1 ]);
121+ auto const & n2 = vertex_normal_buffer.at (face[2 ]);
122+
129123 glNormal3fv (glm::value_ptr (n0));
130124 glVertex3fv (glm::value_ptr (a));
131125 glNormal3fv (glm::value_ptr (n1));
@@ -136,6 +130,14 @@ void OBJ::draw_obj_smooth() {
136130 CHECK_GL (glEnd ());
137131}
138132
139- void OBJ::draw_obj_group_smooth () {
140- // TODO
133+ void OBJ::draw_obj () {
134+ object_draw_flat_pass (*this );
135+ }
136+
137+ void OBJ::draw_obj_smooth () {
138+ for (auto const & [i, group] : smoothing_groups) {
139+ std::vector<glm::vec3> vert_norm_buffer (vertices.size (), glm::vec3 (0 .0f ));
140+ normal_compute_pass (*this , group, vert_norm_buffer);
141+ object_draw_smooth_pass (*this , group, vert_norm_buffer);
142+ }
141143}
0 commit comments