엔진안의 열거체를 클라이언트 디파인으로 이동
각 레벨의 NativeConstruct에서 현재 레벨에 사용할 객체(플레이어 , 몬스터 ,건물, 지형) 들을 생성할것
각 객체에게 장치를 전달한다(이를 위해 레벨이 장치를 가지고있는게 좋음)
MainAPP의 클래스의 멤버변수로 장치를 선언하고 넣어줌
그래픽 디바이스의 레디부분을 수정해서 장치의 더블포인터를 인자로받고 생성된 장치의 주소를 넣어주자 (디폴트 매개변수 선언)
이때 레퍼런스 카운트도 늘려줘야함
(감소는 MainAPp이 삭제될때)
다음 레디 그래픽 디바이스의 안에서 ppGraphic_Device의 인자가 nullptr로 들어오지 않았다면 인자에 넣어줌
게임인스턴스에서도 똑같은 함수의 형태로 바꿔주자
완료되었다면 셋업레벨함수 인자를 nullptr에서 생성한 장치를 넘겨줄수있게 변경
틱함수 : 매 프레임 호출될 함수. 가지고 있는 장치중에 매 프레임 호출해줘여할 함수가 있다면 호출해주는 함수
이를 위해 레벨매니저에도 Tick()함수 구현
다음 게임인스턴스의 tick함수에 레벨매니저의 tick 호출
우선 현재 레벨이 널포인트인지 확인하는 습관 가지는게 좋음
현재 레벨의 tick()을 호출해주자!
씬의 렌더안에서는 현재 씬에서 보여줘야할 객체들의 렌더함수를 호출하는게 주역할이였다. -> 이제 이역할을 없애버린다
이유? : 지형의 순서를 그리기가 애매함 굴곡이있는 지형이라면?
그래픽장치를 초기화할때 백버퍼를 하나 만듬
그리고 같은 크기의 뎁스(z버퍼)를 만듬
800 X 600의 버퍼가있다면 가로로 800개 세로 600개으 픽셀이 존재한다
뭔가 그릴때마다 그래픽 디바이스의 렌더비긴함수호출
이때 그리기직전에 백버퍼와 z버프를 초기화함
이때 이떄 각각 초기화를 어떤 값으로 할지를 결정
백버퍼는 색깔 깊이버퍼는 숫자값 1일경우 깊이버퍼를 1로 초기화하겠다.
각 픽셀마다 깊이값이 있다!
3D에서는 이 그리는 순서를 알아서 처리해줌
A가 B보다 가까이있다면?
네모는 4개의 점으로 이루어져있음 점은 벡터다 벡터는 XYZ로 이뤄져있다.
두 사각형이 Z값을 비교 멀리있는 사각형으 Z값이 크다 B가 멀리있다
이를 위해 여러 변환과정을 거쳐서 정점의 Z값을 카메라에서 가장 가까운애를 0으로 만듬 다음 카메라가 보여줄수있는 최대 거리에있는것을 1로 만듬
값은 자유롭게 줄수있음 원하다면 0~5000으로 줘도됨 컴퓨터가 자동으로 0~1사이의 값을 보정(왜? z버퍼의 값으로 사용하기위해)
버퍼는 메모리공간이라는 의미를 가짐
Z값을 저장하기 위한 메모리공간이 Z버퍼 이를 1로 초기화한다?
카메라가 보여줄수있는 최대값으로 초기화하겠다.
특정 부분의 값이 바뀌는건 내가 그린다는 이야기를 하기 직전에 갱신됨
깊이가 0.3 0.7인인 사각형이 있을때 각 사각형의 모든 픽셀의 깊이값을 가져옴.
모든 정점의 값이 0.7이면 모든 픽셀은 0.7
각 z버퍼의 픽셀의 값은자신보다 작은 값을 그릴떄 갱신됨
즉 0.7사각형을 그릴때 그 픽셀에 해당하는 값은 0.7로 갱신됨
그리고 이때 갱신된 애들만 그려짐
B사각형이 완료됬으면 A사각형을 그리자 이떄 이 구역은 0.3으로 갱신됨 0.7인칸은 0.3값으로 갱신됨!(갱신된다는 그린다는뜻)
결국 덮여서 그려진다.
하지만 이방식으로인해 생기는 문제가있다.
카메라가 바라보는만큼(파란색만큼) 그려져야함
지형을 먼저 그리든 플레이어를 먼저 그리든 상관없음
플레이어의 정수리 픽셀이 지형의 픽셀값이 작을것이기때문에
플레이어 뒤에 지형은 절대로 그려지지않음
카메라가 위를 쳐다볼수도있음
빨간공간은 스카이박스
이를 표현하기위해 스카이박스를 카메라를 감싸게해서 그림
하늘이 가까우니깐 플레이보다 먼저 그려진다
하늘은 겁나 키워서 지형보다 크게한다해도 하늘에 이미지를 넣는것이기때문에 너무 키우면 픽셀이깨짐
그래서 장치객체의 SetRenderState함수를 사용
D3DRS_ZWRITEENABLE로 그리는 상태를 true,false로 설정가능
ZENABLE z버퍼의 값과 비교를 하겠다. default = true라서 비교해줬었음
ZWRITEENABLE 은 값을 변경하겠다.
스카이박스를 그릴때 ZWRITEENABLE를 끄면 비교는 하겠지만 값을 채우지는않음 -> 비교 대상에 넣지 않겠다.
결국 스카이박스를 제일먼저그리면 스카이박스가 그려지고 스카이박스의 깊이값과 상관없이 다른 객체들이 위에 그려짐
UI는 반대로 무조건 그려준다 ZENABLE false로
오브젝트 매니저에 객체를 넣을때 순서를 염두에 두고 넣어줘야함
이는 원하는 속성에따라서 객체를 관리하지못하는 단점이있음
해결법 : 오브젝트매니저는 그리는순서를 상관하지않고 속성별로 보관할것
그리는것은 백버퍼에 객체들을 그리는 부분에서 새로운 클래스객체를만들어서 객체들을 그리는 순서에따라 보관하겠다.
레벨 로고의 렌더는 퇴화할것 (렌더에서 디버깅적 요소를 출력하는 용도로만 사용
메인앱에다가 렌더러 객체를 만들어둘것 렌더러는 그리는순서에따라서 객체들을 보관하고있을것
메인앱의 게임인스턴스에서 렌더 레벨 함수를 호출해주자
배경부터 띄워보자
CBackground 클래스 추가
다음 엔진에 오브젝트의 부모가될 클래스를 추가해주자
CGameObject와 CGameObject Manager클래스 추가
게임오브젝트클래스는 생성자에서 장치를 인자로받는다
가상소멸자와 Free함수도 선언
NativeConstrcuct();
Tick,Late_Tick() 함수 선언
Render()함수도 선언
cpp에서 이니셜라이저 해주고
다시 백그라운드 클래스로 돌아와서 함수 선언해주자
오브젝트 매니저 클래스또한CBase를 상속받음
오브젝트매니저는 객체들을 개발자의 기준에 따라 구분하여 보관하다.
객체는 map STL을 통해 보관하자
맵의 키로 tchar를 쓰느냐 string을 쓰느냐에따라서 프레임속도가 크게 달라지기도함
map<const _tchar,list<class CGameObject>> m_Layers[] 에다가 객체들을보관하자
맵을 사용하기위해 using namspace std를 추가
list<class CGameObject*>가 너무 길기떄문에 클래스로 팩킹을 해주자
보기좋음 + 오브젝트매니저를 라이브러리화할때 템플릿타입은 라이브러리화할때 경고가 하나식뜸 이를 방지해주는 효과
맵을 배열로 선언한 이유: 레벨을 변경할때 레벨을 삭제하기전에 스테이지를 만들어야함->오브젝트 매니저에 객체가 섞이게됨
이를 방지하기 위해 각씬마다 맵 배열로 구분해서 따로쓰자
각씬의 Free에서 각씬의 해당하는 오브젝트매니저 레이어를 지어주면됨
씬갯수는 클라마다 다르기때문에
맵을 포인터형태로 멤버변수로 가지고 Reserve_Containver를 통해 맵을 동적할당해서 넣어주자
함수해서는 iNumLevel을 인자로받아 그 수만큼 맵을 동적할당 해주자