You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: kr/beginners-tutorials/tutorial-7-model-loading/index.markdown
+37-62Lines changed: 37 additions & 62 deletions
Original file line number
Diff line number
Diff line change
@@ -11,19 +11,15 @@ tags: []
11
11
language: kr
12
12
---
13
13
14
-
지금까지, 우리는 소스코드에 큐브를 하드코딩했어요. 그게 꽤 끔찍하고, 그리 괜찮은 일이 아니라는 것이라는 걸 여러분도 이해했으리라 믿어요.
15
-
Until now, we hardcoded our cube directly in the source code. I'm sure you will agree that this was cumbersome and not very handy.
14
+
지금까지, 우리는 소스코드에 큐브를 하드코딩했어요. 그게 꽤 끔찍하고, 그리 괜찮은 일이 아니라는 것이라는 걸 여러분도 느꼈다고 믿고 있어요.
16
15
17
-
이번 튜토리얼에서는 파일에서 3D 메쉬를 불러오는 법을 배울거에요. 텍스처 로딩에서 했던 것처럼 : 아주 제한적이고, 아주 작은 로더를 만들 거고. 실제 라이브러리들은 우리보다 괜찮을 거라고 확신할게요. 그러니까 나중에는 그 라이브러리 쓰는 방법도 알려줄게요.
18
-
In this tutorial we will learn how to load 3D meshes from files. We will do this just like we did for the textures : we will write a tiny, very limited loader, and I'll give you some pointers to actual libraries that can do this better that us.
16
+
이번 튜토리얼에서는 파일에서 3D 메쉬를 불러오는 법을 배울거에요. 텍스처 로딩에서 했던 것처럼 : 아주 제한적이고, 아주 작은 로더를 만들 거고- 그래서 실제 라이브러리들은 우리보다 괜찮을 거라고 확신해요. 그러니까 나중에는 라이브러리들 소개도 시켜드릴게요.
19
17
20
18
이 튜토리얼을 가능한 한 심플하게 만들기 위해, 우리는 OBJ 파일 포맷을 사용할 거에요. 아주 간단하고 일반적인 포멧이죠. 그리고 마찬가지 이유로. 우리는 버텍스당 UV 좌표 하나, normal 좌표 하나만을 가지는 OBJ 파일만 불러올 거에요. (normal에 대해선 아직 알 필요가 없어요.)
21
-
To keep this tutorial as simple as possible, we'll use the OBJ file format, which is both very simple and very common. And once again, to keep things simple, we will only deal with OBJ files with 1 UV coordinate and 1 normal per vertex (you don't have to know what a normal is right now).
22
19
23
20
# OBJ 로딩하기
24
21
25
22
우리 함수는, 코드는 common/objloader.cpp에. 정의는 common/objloader.hpp에 있을거에요 - 아래 시그네쳐에요. :
26
-
Our function, located in common/objloader.cpp and declared in common/objloader.hpp, will have the following signature :
27
23
28
24
```cpp
29
25
boolloadOBJ(
@@ -34,16 +30,13 @@ bool loadOBJ(
34
30
)
35
31
```
36
32
37
-
우리는 loadOBJ가 파일 "path(경로)" 를 읽기 원하고, 그 경로에서 out_vertices/out_uvs/out_normals등의 데이터를 쓰기를 원할거고. 뭐가 잘못되었으면 false 값을 돌려줬으면 좋겠어요. std::vector 는 C++에 있는, 언제든지 크기를 수정할수 있는 배열이고. 템플릿이라는 것을 통해 지금은 glm::vec3 자료형을 보관중이에요. : 아. 이거는 수학적인 벡터가 아니에요. 그냥 배열이라니까요? 진짜로요. 마지막으로 알아볼건 & 인데. 이거는 '참조'라고 std::vector를 수정할 수 있다는 말이에요.
33
+
우리는 loadOBJ가 파일 "path(경로)" 를 읽기 원하고, 그 경로에서 out_vertices/out_uvs/out_normals등의 데이터를 쓰기를 원할거고. 뭐가 잘못되었으면 false 값을 돌려줬으면 좋겠어요. std::vector 는 C++에 있는 언제든지 크기를 수정할수 있는 배열이고. 템플릿이라는 것을 통해 지금은 glm::vec3 자료형을 보관중이에요. (아. 이거는 수학적인 벡터가 아니에요. 그냥 배열이라니까요? 진짜로요.) 마지막으로 알아볼건 & 인데. 이거는 '참조'라고 std::vector를 수정할 수 있다는 뜻이에요.
38
34
39
-
(역주 : JAVA등을 하던 사람은 이상하게 생각하겠지만, C++은 기본적으로 '모든' 변수를 '값'만 전달합니다. )
40
-
41
-
We want loadOBJ to read the file "path", write the data in out_vertices/out_uvs/out_normals, and return false if something went wrong. std::vector is the C++ way to declare an array of glm::vec3 which size can be modified at will: it has nothing to do with a mathematical vector. Just an array, really. And finally, the & means that function will be able to modify the std::vectors.
35
+
(역주 : JAVA등을 하던 사람은 이상하게 생각하겠지만, C++은 기본적으로 *모든* 변수를 **값**만 전달합니다. 참조형만이 순수한 call-by-reference입니다. 다만 참조형은 compile 시점에 결정되기에, 가리키는 대상을 바꿀 수 없음을 유의하세요. 바꾸고 싶으시다면, 포인터를 사용하세요.)
42
36
43
37
## 예제 OBJ 파일
44
38
45
39
OBJ 파일은 대체로 이것보다 길거나 - 더 짧아요. :
46
-
An OBJ file looks more or less like this :
47
40
48
41
```
49
42
# Blender3D v249 OBJ File: untitled.blend
@@ -96,24 +89,17 @@ f 1/2/8 3/13/8 4/14/8
96
89
```
97
90
98
91
그래서, 뭔 뜻일까요?:
92
+
99
93
So :
100
94
101
-
*'#' 은 그냥 주석이에요. C++로 치면 '//' 같은거요.
95
+
*`#` 은 그냥 주석이에요. C++로 치면 '//' 같은거요.
102
96
* usemtl 과 mtllib는 모델이 어떻게 보여지는지 묘사하지만. 이번 튜토리얼에서는 안 쓸거에요.
103
97
* v은 정점이고.
104
98
* vt은 정점의 텍스쳐 좌표.
105
99
* vn은 정점의 normal 좌표고요.
106
100
* f는 면이에요.
107
101
108
-
*`#` is a comment, just like // in C++
109
-
* usemtl and mtllib describe the look of the model. We won't use this in this tutorial.
110
-
* v is a vertex
111
-
* vt is the texture coordinate of one vertex
112
-
* vn is the normal of one vertex
113
-
* f is a face
114
-
115
102
v, vt 그리고 vn은 쉽게 이해할 수 있겠지만. f는 조금 더 까다로워요. 그러니까 예제를 들어봐요! 만약 f 8/11/7 7/12/7 6/10/7이 있다고 해봅시다.
116
-
v, vt and vn are simple to understand. f is more tricky. So, for f 8/11/7 7/12/7 6/10/7 :
117
103
118
104
* 8/11/7은 삼각형의 첫 번째 정점을 표현한거에요.
119
105
* 7/12/7은 삼각형의 두 번째 정점을 표현한거에요.
@@ -122,33 +108,20 @@ v, vt and vn are simple to understand. f is more tricky. So, for f 8/11/7 7/12/7
122
108
* 11은 사용한 텍스쳐 좌표의 위치에요. 그러면 0.748355 0.998230가 되겠네요.
123
109
* 7은 사용할 normal 좌표의 위치에요. 그러면 0.000000 1.000000 -0.000000이겠네요.
124
110
125
-
* 8/11/7 describes the first vertex of the triangle
126
-
* 7/12/7 describes the second vertex of the triangle
127
-
* 6/10/7 describes the third vertex of the triangle (duh)
128
-
* For the first vertex, 8 says which vertex to use. So in this case, -1.000000 1.000000 -1.000000 (index start to 1, not to 0 like in C++)
129
-
* 11 says which texture coordinate to use. So in this case, 0.748355 0.998230
130
-
* 7 says which normal to use. So in this case, 0.000000 1.000000 -0.000000
131
-
132
111
이 숫자들은 'indices(인덱스들)' 라고 불려요. 이 방식은 꽤 똑똑한 방식인데 - 만약 같은 위치에 있는 정점을 공유하려면. 그냥 파일에서 v 하나를 척은 다음에 여러 번 돌려쓰면 되는 거죠. 메모리도 아끼고요.
133
112
134
-
These numbers are called indices. It's handy because if several vertices share the same position, you just have to write one "v" in the file, and use it several times. This saves memory.
135
113
136
114
나쁜 소식은 텍스처에는 다른 인덱스를 쓰라하고, normal에는 다른 인덱스를 쓰라하고, position에는 다른 인덱스를 쓰라고 할 수 없다는거죠. 그래서 이 튜토리얼에서는 인덱스 안된 메쉬를 사용할게요. 인덱싱은 나중에 - 튜토리얼 9에서 해요. 그때는 어떻게 돌아가는 지 알려드릴게요.
137
115
138
-
The bad news is that OpenGL can't be told to use one index for the position, another for the texture, and another for the normal. So the approach I took for this tutorial is to make a standard, non-indexed mesh, and deal with indexing later, in Tutorial 9, which will explain how to work around this.
139
-
140
116
## Blender에서 OBJ 파일 만들기
141
117
142
-
143
118
우리의 작은 로더는 심각하게 기능이 제한되어 있어서, Blender에서 파일을 뽑을때 정확한 옵션인지 특별히 주의를 기울이셔야 해요. 여기, 어떻게 Blender에서 뽑는지 보일거에요 :
144
-
Since our toy loader will be severely limited, we have to be extra careful to set the right options when exporting the file. Here's how it should look in Blender :
i.e : If the first word of the line is "v", then the rest has to be 3 floats, so create a glm::vec3 out of them, and add it to the vector.
169
+
즉, 만약 첫 단어가 "v" 라면, 3개의 float들이 뒤에 있을거에요. 그러니 glm::vec3를 하나 만들고, vector에 추가해줍시다.
196
170
197
171
```cpp
198
172
}elseif ( strcmp( lineHeader, "vt" ) == 0 ){
@@ -201,9 +175,9 @@ i.e : If the first word of the line is "v", then the rest has to be 3 floats, so
201
175
temp_uvs.push_back(uv);
202
176
```
203
177
204
-
i.e if it's not a "v" but a "vt", then the rest has to be 2 floats, so create a glm::vec2 and add it to the vector.
178
+
즉, 만약 "v" 가 아니라 "vt"라면, 2개의 float들이 뒤에 있을거에요. 그러니 glm::vec2를 하나 만들고, vector에 추가해줍시다.
205
179
206
-
same thing for the normals :
180
+
normals도 똑같이 해주세요 :
207
181
208
182
``` cpp
209
183
}else if ( strcmp( lineHeader, "vn" ) == 0 ){
@@ -212,7 +186,7 @@ same thing for the normals :
212
186
temp_normals.push_back(normal);
213
187
```
214
188
215
-
And now the "f", which is more difficult :
189
+
마지막은 "f"인데. 이건 꽤 어려워요:
216
190
217
191
```cpp
218
192
}elseif ( strcmp( lineHeader, "f" ) == 0 ){
@@ -234,66 +208,67 @@ And now the "f", which is more difficult :
234
208
normalIndices.push_back(normalIndex[2]);
235
209
```
236
210
237
-
This code is in fact very similar to the previous one, except that there is more data to read.
211
+
이 코드는 읽을 데이터가 꽤 많다는 건 빼곤, 예전에 파일을 읽는 코드들과 꽤 비슷하죠?
238
212
239
-
## Processing the data
213
+
## 데이터 처리하기
240
214
241
-
So what we did there was simply to change the "shape" of the data. We had a string, we now have a set of std::vectors. But it's not enough, we have to put this into a form that OpenGL likes. Namely, removing the indexes and have plain glm::vec3 instead. This operation is called indexing.
215
+
자. 이제 우리는 간단하게나마 데이터의 "모양"을 바꿨어요. 아까까지는 문자열이었지만, 지금은 std::vector들에 있죠. 하지만 이걸로는 충분하지 않아요. 우리는 이걸 OpenGL이 좋아할 만한 형태로 바꿔야해요. 그러니까 indexes들을 날리고, glm::vec3를 대신 넣어야하죠. 이 작업을 indexing(인덱싱)이라고 해요.
242
216
243
-
We go through each vertex ( each v/vt/vn ) of each triangle ( each line with a "f" ) :
217
+
각 삼각형의 정점(v/vt/vn 같은 것들이요.) 들을 한번씩 돌아볼거에요. 루프를 통해서 말이죠. ( 각 라인의 "f" 마다. ) :
244
218
245
219
``` cpp
246
-
// For each vertex of each triangle
220
+
// For each vertex of each triangle (각 삼각형의 각 꼭지점을 순회합니다. )
247
221
for( unsigned int i=0; i<vertexIndices.size(); i++ ){
248
222
```
249
223
250
-
the index to the vertex position is vertexIndices[i] :
224
+
정점 좌표의 index는 vertexIndices[i]에 있었죠. :
251
225
252
226
```cpp
253
227
unsignedint vertexIndex = vertexIndices[i];
254
228
```
255
229
256
-
so the position is temp_vertices[vertexIndex-1 ] (there is a -1 because C++ indexing starts at 0 and OBJ indexing starts at 1, remember ?) :
230
+
그래서 좌표를 tmpe_vertices[vertexIndex - 1]에 담을거에요. ( -1을 빼는 이유는 C++은 index가 0부터 시작하지만, OBJ는 1부터 시작하기 때문이에요. 기억나요?)
The same is applied for UVs and normals, and we're done !
242
+
그리고 이 일을 UV 좌표들과, normal 좌표들에게도 적용하면 끝이에요!
269
243
270
-
# Using the loaded data
244
+
# 읽어온 데이터 활용하기
271
245
272
-
Once we've got this, almost nothing changes. Instead of declaring our usual static const GLfloat g_vertex_buffer_data[] = {...}, you declare a std::vector vertices instead (same thing for UVS and normals). You call loadOBJ with the right parameters :
246
+
여기까지 해냈는데, 아직 바뀐 건 하나도 없어요. 이제 바꿔봐요. static const GLfloat g_vertex_buffer_data[] = {...} 를 선언하는 대신에 std::vector 정점들(텍스쳐 좌표와, normal 좌표도 똑같이요.)을 선언합시다. 그리고 loadOBJ 함수를 정확한 파라미터로 호출해봐요. :
273
247
274
248
```cpp
275
-
//Read our .obj file
249
+
//우리의 .obj 파일을 읽습니다.
276
250
std::vector< glm::vec3 > vertices;
277
251
std::vector< glm::vec2 > uvs;
278
-
std::vector< glm::vec3 > normals; //Won't be used at the moment.
252
+
std::vector< glm::vec3 > normals; //지금은 안쓸거에요.
279
253
bool res = loadOBJ("cube.obj", vertices, uvs, normals);
280
254
```
281
255
282
-
and give your vectors to OpenGL instead of your arrays :
우리가 만든 작은 로더는 초심자인 우리에게는 적합하지만, 실무에서 쓰기에는 전혀 아니죠. 한번 [유용한 링크 & 도구들](http://www.opengl-tutorial.org/miscellaneous/useful-tools-links/) 페이지를 살펴보면서 사용할 만한 도구가 있는지 확인해보세요. 아. 그렇지만 *진짜로* 쓰기 전에. 튜토리얼 9까지는 참아주세요.
298
274
299
-
This tiny loader should give you enough to get started, but won't want to use this in real life. Have a look at our [Useful Links & Tools](http://www.opengl-tutorial.org/miscellaneous/useful-tools-links/) page for some tools you can use. Note, however, that you'd better wait for tutorial 9 before *actually *trying to use them.
0 commit comments