5
5
#include < iostream>
6
6
#include < fstream>
7
7
#include < sstream>
8
- #include < unordered_map>
9
8
10
- void OBJ::load_obj (std::string path, bool enable_group ) {
9
+ void OBJ::load_obj (std::string path, bool grouped ) {
11
10
std::ifstream file (path);
12
11
if (!file.is_open ()) {
13
12
std::cerr << " Failed to open file: " << path << ' \n ' ;
14
13
return ;
15
14
}
16
15
17
16
std::string line;
18
- int current_group = - 1 , grouped_face = 0 ;
17
+ unsigned int current_group = 0 ;
19
18
20
19
while (std::getline (file, line)) {
21
20
if (line.substr (0 , 2 ) == " v " ) {
@@ -37,21 +36,18 @@ void OBJ::load_obj(std::string path, bool enable_group) {
37
36
glm::uvec3 face = glm::uvec3 (indices[0 ], indices[i - 1 ], indices[i]);
38
37
faces.push_back (face);
39
38
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 );
43
40
}
44
41
} else if (line.substr (0 , 7 ) == " #group " ) {
45
42
std::istringstream s (line.substr (7 ));
46
43
unsigned int group;
47
44
s >> group;
48
- current_group = group;
45
+ if (grouped) current_group = group;
49
46
}
50
47
}
51
48
52
49
file.close ();
53
50
std::cout << " Loaded " << vertices.size () << " vertices, " << faces.size () << " faces.\n " ;
54
- std::cout << grouped_face << " faces grouped.\n " ;
55
51
}
56
52
57
53
static 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
79
75
return glm::normalize (norm) * contrib_w;
80
76
}
81
77
82
- void OBJ::draw_obj ( ) {
78
+ static void object_draw_flat_pass (OBJ const & obj ) {
83
79
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 ]);
89
84
90
85
glm::vec3 norm = compute_normal (a, b, c);
91
86
glNormal3fv (glm::value_ptr (norm));
@@ -94,38 +89,37 @@ void OBJ::draw_obj() {
94
89
glVertex3fv (glm::value_ptr (b));
95
90
glVertex3fv (glm::value_ptr (c));
96
91
}
97
-
98
92
CHECK_GL (glEnd ());
99
93
}
100
94
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 );
113
105
}
114
- for (auto & vn : vertexNormalBuffer ) {
106
+ for (auto & vn : vertex_normal_buffer ) {
115
107
vn = glm::normalize (vn);
116
108
}
109
+ }
117
110
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) {
119
112
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
+
129
123
glNormal3fv (glm::value_ptr (n0));
130
124
glVertex3fv (glm::value_ptr (a));
131
125
glNormal3fv (glm::value_ptr (n1));
@@ -136,6 +130,14 @@ void OBJ::draw_obj_smooth() {
136
130
CHECK_GL (glEnd ());
137
131
}
138
132
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
+ }
141
143
}
0 commit comments