위의 그림에서 왼쪽의 3D 물체는 와이어프레임으로 출력되고 있다. 이 물체를 구성하는 폴리곤들의 표면에 가운데에 있는 2D 이미지를 씌운다고 생각하자. 그 결과는 오른쪽과 같이 지구처럼 나타날 것이다. 3D 구와 구에 덮어씌울 2D 이미지 한 장으로 지구를 만들었다. 이처럼 텍스처 맵핑은 단순하지만 효과적으로 사실성을 표현할 수 있는 기법 중 하나이다.
DirectX9에서 텍스처 맵핑을 하는 과정은 다음과 같다.
- Direct3DTexture9 인터페이스 선언: 텍스처를 사용하기 위한 변수
- 텍스처 좌표를 갖는 정점 선언: 사용자 정의 정점 구조체에서 선언
- 텍스처 생성: 일반적으로 파일을 읽어서 생성
- 텍스처 스테이지 설정: 텍스처 스테이지는 텍스처의 좌표 생성 및 랩핑 모드 등 텍스처 제어에 관한 설정
- 그려질 텍스처를 지정: D3D 디바이스에 텍스처를 알린다.
- 메시 그리기
각각의 과정에 대해서 좀더 살펴보면 정점 버퍼를 생성할 때도 인터페이스가 필요했듯이, 텍스처를 사용하기 위해서도 텍스처 인터페이스가 필요하다. 그리고 사용자 정의 정점 구조체의 정점이 텍스처 상의 uv 좌표계에서 어디에 맵핑될지도 설정하여야 한다. 사용자 정의 정점 구조체에 텍스처 좌표값을 위한 변수가 추가되었으므로 FVF 플래그도 변경해주어야 한다. 그 다음 텍스처를 생성한다. 텍스처는 D3D 디바이스를 통해 D3DXCreateTextureFromFile() 함수를 호출하여 생성할 수 있다. 텍스처를 생성한 후, 텍스처를 어떻게 제어할 것인지에 관한 정보를 텍스처 스테이지를 통해 설정한다. 텍스처와 정점의 색을 섞을지 말지 등을 결정한다. 그리고 생성한 텍스처에 인덱스를 부여하여 D3D가 텍스처를 관리할 수 있도록 한다.
지금까지 설명한 과정을 코드로 다시 살펴보자. 아래의 코드는 텍스처 맵핑을 하는 핵심적인 부분들을 발췌한 것이다. 완성된 코드가 아님을 알려둔다.
아래의 이미지는 텍스처로 활용한 이미지이다. 텍스처를 생성할 때 파일명을 "sami.jpg"로 지정하였으므로 확인하도록 하자.
참고로 텍스처로 사용할 파일은 main 함수가 실행되는 소스 파일과 같은 경우에 있거나, 그보다 한 단계 상위 폴더에 위치해야 한다. 이는 OS가 제공하는 현재 디렉토리(Current Directory) 개념과 관련이 있으므로 생소한 사람은 찾아보면 좋을 것 같다.
원통에 위의 이미지를 씌워보자
#ifdef...#endif 선언이 자주 눈에 띌 것이다. 모르는 사람은 #ifdef...#endif에 대한 포스트을 확인하도록 하자. 어려운 것이 아니므로 금방 이해할 수 있을 것이다. SHOW_HOW_TO_USE_TCI가 선언되어 있는지 여부에 따라 컴파일이 달라진다. SHOW_HOW_TO_USE_TCI가 선언되지 않는 경우에는 알고리즘을 통해서 각각 정점에 해당하는 uv 좌표를 하나하나 설정해주고 있다. 위 이미지의 해상도는 100 * 100이다. uz 좌표계에서 (100, 0) 픽셀은 (1, 0)에 맵핑된다. (100, 100) 픽셀은 (1, 1)에 맵핑된다.
원기둥에 텍스처는 어떻게 맵핑되는지 살펴보자. 정점 버퍼 0번째 정점의 uv 좌표는 (0, 1)이다. 1번째 정점의 uv 좌표는 (0, 0)이다. 2번째 정점의 uv 좌표는 (1/49, 1), 3번째 정점의 uv 좌표는 (1/49, 0)이 된다. 결국 정점의 uv 좌표는 텍스처 이미지를 세로로 50등분한 수치가 정점에 맵핑된다.
참고로 텍스처로 사용할 파일은 main 함수가 실행되는 소스 파일과 같은 경우에 있거나, 그보다 한 단계 상위 폴더에 위치해야 한다. 이는 OS가 제공하는 현재 디렉토리(Current Directory) 개념과 관련이 있으므로 생소한 사람은 찾아보면 좋을 것 같다.
정리하면
- 텍스처 이미지는 uv 좌표를 가진다.
- 텍스처 맵핑을 하기 위해서 필요한 과정을 숙지해두자.
댓글 없음:
댓글 쓰기