Skip to content

hipass7/Computer_Graphics

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

7 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Computer Graphics

2022-1 Computer Graphics OpenGL Project

I . 준비

1. 초기 화면

이번 프로젝트는 교수님께서 제공한 기초 파일에 주어진 공간 내에 3D 오브젝트를 불러와 공간을 채우는 과제이다. 따라서, 기초 파일이 처음에 어떤 식으로 모델링 되어 있는지 확인을 할 필요가 있고 구체적으로 확인을 해보았다.

1

같은 텍스처가 3군데에 반복되어 구성되어있는 것을 확인할 수 있다. (바닥은 고려하지 않는다.) 따라서, 해당 텍스처들이 어떤 좌표를 갖고 이루어져 있는지 확인을 하였다. 가장 기본적인 x,y,z축을 생각하면 해당하는 공간은 –0.2 < x, y < 0.2, 0.0 < z < 0.4의 공간을 사용하고 있다. 이후에 모델링을 할 때에도 이 공간 안에 배치되도록 Scale와 Translation을 이용해야한다. 다음 기본 텍스처를 구성하는 코드에 대해서는 다음과 같이 확인하였고 display 함수와 main 함수로 구분하여 확인할 수 있었다.

11

이렇게 코드를 바로 확인할 수 있었기 때문에 어떤 부분을 고쳐야 텍스처를 바꿀 수 있을지 바로 이해를 할 수 있었고 좌표도 확인하여 배치할 수 있었다. 사진에 첨부한 display 코드의 경우에는 바닥을 나타낸 것이기 때문에 연속해서 배치를 해야 해서 다음과 같은 반복문을 사용하였지만 벽을 나타낼 때는 반복문이 필요하지 않다는 특징이 있다.

2. Model 불러오기

모델을 불러오기 위해서는 초기 화면에 있는 벽과는 다른 과정이 필요하다. 우선 초기 화면에 있는 벽을 구성하기 위해서는 사진 파일을 불러와서 4개의 점을 찍고 이어서 새로운 평면을 만든 다음에 텍스처 이미지를 삽입하면 된다. 하지만 다운받은 3D Model을 불러오기 위해서는 obj파일이 필요하며 그것을 불러와서 정보를 저장할 함수가 따로 필요하다. 따라서 헤더 파일에 다음과 같은 함수를 구성하여 obj파일과 mtl파일 정보를 저장할 수 있도록 하였다.

1

코드가 길기 때문에 일부만 캡처하여 첨부한다. 해당 Class에서는 obj파일인 Model을 불러와 vertex들을 모두 저장하고 토폴로지를 형성해준다. 그리고 Material Class를 이용하여 mtl파일에서 material 관련된 정보를 저장한다. 주로 mtl파일에 사진 텍스처 정보도 포함이 되어있기 때문에 실습 시간에 사용한 사과 같은 텍스처를 구현하기 위해서는 반드시 필요하다. 이후 draw() method fuction을 통해 창에 display 할 수 있도록 구현해준다.

II . 오브젝트 구성

1. 배경 설정

배경이 어떤 식으로 이루어지는지 이전 단락에서 확인하였다. 따라서, 기존에 만들어져 있던 3개의 벽에 대해서는 이미지만 변경해주면 되었다. 그 방법이 맞는지 확인하기 위해 실습시간에 사용했던 이미지를 활용해 테스트해봤다. 아래 사진과 같이 정상적으로 이미지가 변경되는 것을 확인하고 실습의 시작을 알렸다.

1

이제 저 작은 공간 (0.4x0.4x0.4)을 어떻게 활용하여 꾸밀 것인지 생각을 해봤다. 이번 프로젝트의 목적이 이 공간을 어떻게 꾸밀 것인지보다는 3D Model을 불러와서 위치를 수정하고 배치할 수 있는지에 대한 평가에 더욱 목적이 있기 때문에 복잡하게 여러 3D Model을 불러오는 것보다는 깔끔하게 몇 개의 오브젝트만 넣어두고 보고서에 그 과정을 기입하는 것이 더 낫다고 생각했다. 따라서 간단하게 피규어 장식장 겸 차고를 만들어보기로 했다.

차고를 만들기 위해서는 벽면 인테리어와 바닥, 그리고 출입문이 포함되어야한다고 생각했다. 지붕은 가려버리면 아에 보이지가 않기 때문에 생략하였다. 그리고 출입문이 열리는 시뮬레이션까지 진행되면 좋겠다고 생각을 했기 때문에 텍스처 이미지의 변경, 새로운 평면을 구성함으로써 다음과 같은 공간을 만들어냈다.

1

벽돌로 쌓아올린 텍스처가 내부 벽을 담당하도록 하였고 바닥에는 대리석을 깔았다. (인터넷 검색을 통해 이미지를 다운로드했다.) 이후 차고 문처럼 생긴 이미지도 평면을 이용하여 문을 만들어주고 시간에 따라 열렸다 닫혔다를 반복하도록 설정하였다. 벽면 텍스처를 변경하고 바닥 텍스처를 만들어주는 방법은 초기 제공 코드와 비슷하고 불러오는 이미지만 변경을 하면 되기 때문에 코드 설명은 생략하며, 움직이는 차고 문에 대한 코드만 설명하겠다.

1

처음엔 다음과 같이 코드를 구성했다. 닫혀있는 차고문의 평면의 경우 바닥면이 (-0.2, 0.0, -0.2) 일 때, 열려있는 차고문의 평면의 경우에는 (-0.2, 0.4, -0.6)으로 변경된다. 따라서 변수를 사용해서 계속 변화하도록 설정해주었으나, 차고문 형태가 그대로 유지되면서 올라가는 것이 아니라, 중간에 차고문의 사이즈가 변형되는 문제가 생겼다. 따라서 대각선으로 변화하는 것이 아니라 원의 반지름을 따라서 차고문이 올라가도록 코드를 수정해주었다.

1

2. 오브젝트 배치

1

사용하고 싶은 3D model을 전부 모델링한 결과이다. 중심이 (0.0, 0.0, 0.0)으로 맞춰져있기 때문에 해당 위치를 기준으로 모두 생성되었다. 이후 과정에서 각 모델마다 위치와 크기, 회전을 조정하여서 공간 안에서 알맞은 자리에 배치해주도록 할 예정이다. 3D model을 잘 불러와서 모델링 할 수 있는지가 과제의 목적이기 때문에 많은 양의 3D model을 불러오지는 않았다. 따라서 다음과 같은 목록에 해당하는 오브젝트만 모델링 하였다.

  1. 사이보그 (사람 형체를 가진 로봇) -> 차고를 지키는 로봇 느낌
  2. 나무 -> 차고 실내의 조경을 위해 배치함
  3. 여우 -> 차고에서 생활하는 반려견을 모티브함
  4. 스포츠카 -> 차고의 메인 모델
  5. 그 외 장식

모든 모델을 불러오기 위한 과정을 하나하나씩 설명하는 것보다는 모두 같은 과정을 이용했기 때문에 이 단락에서 간략하게 설명하고, 각 모델을 새로운 단락으로 설명하면서 어떻게 배치하였는지만 소개하고자 한다. 아까 서론에서 언급한 모델을 불러오는 함수를 이용하여 아래 사진과 같이 코드를 배치해두면 된다.

1

오브젝트 파일 이름을 저장해주고, 아까 구성한 class를 선언해준다. 이후 초기화 함수를 따로 추가시켜 그 함수 내에서 아래 코드와 같이 obj 파일에 있는 정보를 선언해 준 객체에 저장할 수 있도록 불러온다.

1

1

이후 모델의 크기를 조정해가며 display 함수 내에 draw()함수를 불러옴으로써 화면에 모델이 나타나도록 해주면 된다. 기초 class를 잘 구성해두었기 때문에 모델을 편하게 수정하고 배치할 수 있다. obj 파일의 정보를 불러오는 방법은 참고 문헌에 기재한다.

3. 사이보그

1

사이보그는 차고의 오른편에 둬서 스포츠카가 있을 때, 운전석 앞에 위치되도록 만드는 것이 목적이다. 따라서 차고의 문을 향해 정면으로 서 있기 때문에 오른쪽으로 약간 translation을 시키고 시계방향으로 90도 회전을 해줘야한다. 이 두 함수를 이용해서 사이보그를 그 방향에 배치해보자.

11

다음과 같이 가운데에 서있던 사이보그를 오른쪽 벽으로 붙여보았다. glTranslatef 함수를 이용하여 오른쪽으로 옮겼고, glRotatef 함수를 이용하여 수직축으로 90도 회전시켜 위와 같은 모델을 만들었다. 또한, 사이보그 모델 자체 크기가 매우 커 차고에 넣을 수 없는 수준이었기 때문에 glScalef 함수를 이용하여 차고 안에 쏙 들어가도록 크기를 조정해주었다. 이와 같은 형식으로 계속 다음 모델들을 배치해나갔다. draw 함수를 두 번 사용한 이유는 가끔 텍스처가 제대로 저장이 되지 않아 이상하게 나오는 경우가 있어 그 경우를 방지하기 위해 지금은 코드 최적화를 목적으로 한 프로젝트가 아니기 때문에 텍스처가 정확히 나오도록 2번 사용해주었다.

4. 여우

1

아마 이번 프로젝트에서 가장 저퀄리티의 3D 모델이 아닐까 싶다. 사이보그를 하기 이전에 테스트하기 위해서 불러오던 모델인데 생각해보니 차고 공간 안에 두어도 어색함이 있지 않을 것 같아 배치하기로 결정했다. 사이보그의 반대편에서 앞뒤로 뛰어다니게 만들 생각이다. 코드를 작성해보자.

11

다음과 같이 코드를 구성함으로써 여우가 앞뒤로 움직이게 구현하였다. 그 외에 사이보그에서 했던 것처럼 여우를 회전시키고 크기를 줄여주는 과정이 필요하다. 따라서 4번의 과정을 거쳤는데 여우를 왼쪽으로 translation 하는 과정, 여우의 앞뒤를 바꿔주는 회전, 그리고 여우가 앞뒤로 움직이도록 변수를 이용하는 과정, 여우의 크기를 줄여주는 과정을 수행했다.

5. 나무

1

나무 하나만 넣어도 꽉 찰 정도로 큰 사이즈지만 꼭 한 번 넣어보고 싶었다. 앞선 과정과 모두 비슷하고 나무 같은 경우에는 고정을 시킬 것이기 때문에 이하 생략하고 나무의 배치와 코드를 설명하겠다.

11

나무의 사이즈가 매우 커서 어디에 배치해야할지 고민을 많이 했다. 그 결과 입구 쪽에 두기로 하였다. 나무 줄기는 작은 것에 비해서 잎들이 굉장히 컸기 때문에 작게 만들어주었다. 따라서 다음 코드처럼 glTranslatef 함수를 이용하여 위치를 조정해주고 glScalef 함수를 이용하여 크기를 대폭 줄여주었다. 이와중에 여우는 계속 앞뒤로 움직이고 있다. 추가적으로 나무를 회전시키기 위해 Rotation도 변수를 이용하여 추가해주었다.

6. 스포츠카

1

가장 중요한 요소인 스포츠카를 이제 차고에 넣어볼 것이다. 다른 모델들과 겹치지 않는 것을 최우선시 하였고, 문을 향해 정면을 향하도록 배치하고 또한 차고 문이 열림과 동시에 앞으로 나오도록 구현해보고 싶었다.

11

구현을 해냈다. 문이 열림과 동시에 차가 앞으로 나오도록 하며, 문이 다시 닫힐 때에는 차가 다시 들어가도록 했다. 문을 움직이면서 사용했던 코드 변수를 가져와서 문이 열린 것을 인지하면 차가 나가도록, 문이 닫히는 것을 인지하면 차가 다시 들어오도록 설정하였다. 그리고 스포츠카 모델도 크기가 매우 크기 때문에 줄여주었다. 이처럼 모델을 배치하고 움직이게 구현하는 것은 모두 해낼 수 있게 되었다.

III . 마무리

1. 결과 요약

1

처음에 만들면서 작은 공간을 어떤 컨셉으로 만들지 정했다. 차고를 만들어 차고 문이 열리면서 스포츠카가 앞으로 튀어나가게 만들고 싶었다. 하지만 그 목적은 달성함과 동시에 차고 내부가 허전한 것을 느끼고 여러 모델들을 배치하기 시작했다. 이 보고서에 기재는 하지 않았지만 마지막에는 공중에 별 하나가 빙빙 돌게 배치하였다. 따라서 openGL을 이용한 프로젝트 결과물은 위 사진과 같이 나올 수 있었다. 결과는 직접 코드를 돌려서 확인해야 움직임까지 확인을 할 수 있다.

2. 실행 매뉴얼

실행 코드는 backup.cpp 파일과 backup.h 파일에 구현되어 있으며 사용한 obj 모델 파일 목록은 다음과 같다.

  1. cyborg.obj
  2. Lowpoly_Fox.obj
  3. scrubPine.obj
  4. BMW_M3_GTR.obj
  5. estrellica.obj

obj 파일 뿐만 아니라 그와 연동되어있는 mtl 파일과 png 파일도 반드시 동봉되어야 함을 알립니다. 이 obj 파일은 따로 Library 폴더에 넣어 두었기 때문에 이 폴더는 반드시 cpp와 h와 함께 있는 폴더 안에 존재해야 한다. Library 폴더의 모든 내용물 또한 그대로 유지되어야 한다.

3. 고찰 및 소감

처음에 프로젝트를 시작하기에 앞서서 굉장히 막막했었다. 초기 구성되어 있는 코드에서 벽을 모델링 하는 것은 코드가 제공이 되어있기 때문에 평면을 만들고 그 위에 사진 텍스처를 씌우는 것은 꽤 쉽게 진행하였다. 이 코드에 대한 공부를 하면서 어떤 좌표를 사용하고 있는지 파악할 수 있었고 3D 모델들을 배치할 때에도 유용하게 사용하였다.

그 외에 obj 파일을 불러와서 openGL 창에 띄우는 것은 사과 실습뿐이었지만 사과 실습의 경우에도 material이 txt 파일로 따로 제공을 하는 경우였기 때문에 인터넷에서 찾은 obj 파일만으로 모델링하는 것은 쉽지 않았다. 하지만, obj 파일만 이용하여 openGL 창에 띄울 수 있는 방법을 찾아냈고 그 함수들을 적용해서 창에 띄우는 것은 성공하였다. 다만, 텍스처링이 이루어지지 않아 이 오류를 해결하는데 많은 시간을 소모했다. 그 문제는 다음과 같았다.

우선, 이미지 파일과 연동되어 있는 경우 그 확장자는 반드시 png 이어야 한다. 사용자가 직접 만든 함수로 3D model을 불러와야 하다 보니 주어진 확장자 이미지 파일 외에는 지원을 하지 않는 것 같았다. 따라서 jpg 이미지 파일로 존재하는 경우, mtl 파일도 텍스트 편집기를 이용하여 이미지 파일이 png로 연동되도록 수정해주고 이미지 파일의 확장자명도 바꾸어 주었다.

다음 문제는 mtl 파일의 내용을 읽어오면서 생기는 문제였다. 코드를 자세히 보면 텍스트 파일처럼 읽어와서 한 줄씩 내려가면서 vertex를 의미하는 경우에는 vertex 집합에 저장하고 하는 등의 형식이었다. 하지만 mtl 파일은 이제 모델의 material을 저장하게 되는데, 몇몇 다운로드 받은 mtl 파일들을 보면 불필요한 첫부분의 띄어쓰기가 존재했다. 그래서 이 띄어쓰기들을 없애고 실행하니 맨 앞에 있는 글자를 인식할 수 있게 되어 텍스처링이 정상적으로 이루어졌다.

openGL을 이용하여 3D 모델들을 구성하여 배치할 수 있는 능력을 키울 수 있었다. 수업을 통해 이론적인 부분을 습득하고 이렇게 기말 프로젝트를 통해서 직접 실습까지 하게 되어 많은 지식을 얻어간다고 생각한다. 결과물이 다소 허무해보일 수는 있으나, 같은 작업을 반복하는 것보다 이것을 어떻게 이루어냈는지 고찰하는 과정이 더 중요하다고 생각하였고 더 이상의 많은 모델링은 디자인적 문제라고 생각이 된다. 이렇게 프로젝트에서 요구한 기능을 수행하는 결과물을 성공적으로 만들어냈다!

1

4. 참고 문헌

  1. https://free3d.com/ko/3d-model/star-mobile-ready-60-tris-49986.html
  2. https://github.com/WHKnightZ/OpenGL-Load-Model
  3. Advisor : Kyunghee University Dr.Seungkyu_Lee

About

2022-1 Computer Graphics Project

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published