WinAPI 16 SceneManager

CJB_ny·2022년 9월 1일
0

WinAPI

목록 보기
16/79
post-thumbnail

Rectangle

지금 살짝 이해가 안되었던 부분이 뭐냐하면은

여기서 지금 화면 clear하는 부분인데 왜 사각형을 그리는데 화면을 clear하냐?

Rectangle함수 자체가 1픽셀로 사각형 그리는데 안은 흰색으로 채우기 때문이다.

흰색으로 채운다음에 _memDC로 사각형 가운데다가 그리는 것임.

약간 꼼수? 같은 느낌이다.


CCore 구조

먼저 각 매니저의 update함수 호출하고

CSceneManager update함수 호출한다. -> 여기서 키 입력을 받을 것이다.

이후 67에서 화면을 clear해준다음

rendering 해줄 것이다. 근데 update한 부분을 그리기 위해서는 그릴 목적지가 필요하기 때문에

CSceneManager의 render함수가 HDC를 받아주어야 목적지를 알아서 해당 목적지에 DC로 그림을 그릴 것이다. 이렇게 비트맵을 가르키는 목적지 DC(_memDC)를 넘겨준다.

이후 BitBlt함수로 복사를 하는 구조이다.

current Scene

현재씬은 StartScene이다. 현재씬을 update하고 현재씬을 render해주어야한다.

sceneDC는 CCore에서부터 계속 전달받은 녀석이다.

CScene 상속 구조 ❗❗❗

  • virtaul

  • RTTI

  • 추상 클래스


https://velog.io/@starkshn/%EB%8B%A4%ED%98%95%EC%84%B1-1-2#%EA%B0%80%EC%83%81%ED%95%A8%EC%88%98-%EC%A3%BC%EC%86%8C%ED%85%8C%EC%9D%B4%EB%B8%94%EC%9D%84-%EC%B1%84%EC%9A%B0%EB%8A%94-%EC%A3%BC%EC%B2%B4%EB%8A%94-%EB%88%84%EA%B5%AC%EC%9D%B8%EA%B0%80


현재 모든 씬들은 다 CScene을 상속을 받는다. 우리는 각자의 씬들이 스스로의 초기화 함수를 가지고 싶어한다.

그런데 지금 우리는 지금 모든 씬들을 부모 포인터로 가르킬 것이다

그런데 자식의 init이라는 함수를 각자 알아서 잘 찾기를 원한다면

virtual 함수 사용해야 하고 부모의 init은 그냥 인터페이스만 전달하는 용도로 사용하고 싶다면? => '순수 가상 함수'가 나와야한다.

그렇게되면 CScene 클래스는 '추상 클래스'로 간주되며 추상 클래스는 직접적으로 객체를 가질 수 없게 된다❗❗

(이유는 추상 클래스라서 인터페이스를 구현을 해야하는데 구현을 할려면 자식이여야 하기 때문)

virtaul 반환형 함수이름() abstract; || virtaul 반환형 함수이름() = 0;
왼쪽이 C++11 || C++

물려 받는 자식은 virtual 무조건 적는것은 아니고 가독성과 명확성을 위해서 꼭붙이자.

final, override모르겠으면 좆잡고 반성 복습하자...

protect 좋나 ❓

원래는 private이라 자식에서 접근이 불가능 해서 protected로 바꾸어 주었다.

그런데 이게 좋은 방법일까???

정답이 있는 것은 아닌데 어소는 선호하지 않는단다.

protected사용해서 멤버들을 접근할 수 있게 하면은 나중에 '디버깅'할 때 힘들다.

그런데 이렇게 철저하게 비공개 처리하고 오로지 함수를 통해서만 접근을 할 수 있게 한다면 더 좋지 않을까?

이렇게 AddObject라는 함수를 만들어주고 기존의 _objects는 private으로 막는다.

이렇게하면 에러 났을 경우 진입통로가 여기로 다 몰리기 때문에

에러를 찾기가 쉽다.

여기다가 구현을 해주자.

함수 호출비용 ❗❗❗

이렇게 하면 함수 호출 비용이 들지 않느냐?

현재 CScene클래스가 뭐냐?

지금 헤더에다가 '구현' 해놓았다.

클래스를 헤더에 구현해놓으면 inline처리가 되어서 '호출'해도 해당 스택해서 해결한다.

지금 inline으로 하였을 때까 훨씬 더 이득이다.


inline ❓❓❓ ❗❗❗

https://velog.io/@starkshn/CPP%EC%96%B4%EC%86%8C68list-iterator-inline#inline

컴파일러에게 우리가 구현한 함수에 대해서 최적화를 시켜달라.

함수를 호출을 한다는 것은 해당 함수를 호출한 쪽 파일?에다가 계속 적어내는 것이다.

많이 호출하면 할 수록 해당 함수를 계속해서 적어 낼 것이다.

클래스를 헤더에 구현해 놓는 경우, inline처리를 하겠다라는 것인데

inline처리를 하게되면, 호출한쪽에다가 계속 적어내서 사용하는게 아니라, 아예 해당 함수를 호출하는쪽 파일? 에다가 '추가'를 해버린다.

기능을 그대로 복붙하는 식임.

=> 함수의 '호출비용'을 막겠다 ❗❗


그래서 AddObject와 같은 짧고 자주 호출되는 함수의 경우에는 inline처리를 해서 함수호출비용을 최소화 하는것이 좋은 방법이다.

ㅇㅋ>> => ㅇㅋ.

벡터안에 들어간 애들 삭제(상속) ❗

_objects안에 들어간 녀석들은 누가 없애주는게 맞을까?

이게 상속을 사용한 '목적'과 이어진다.

목적 : 코드를 '재사용'하기 위하여.

만약, 상속받아간 자식에서 _objects라는 벡터에 들어있는 데이터들을 삭제하게 한다면은

자식클래스마다 이것을 소멸자 에다가 다 구현을 해야한다...

그래서 당연히 '부모' 소멸자에서 하는것이 맞다.

그래서 이중 반복 돌면서 i번째 벡터의

j번쨰 물체를 delete한다.

소멸자 생성자 ❗❗

는 컴파일러가 알아서 해제를 해준다.

그래서 멤버 벡터인 _objects의 32가지의 '통' 자체는 CScene의 소멸자에서 구현을 해놓지 않아도 알아서 소멸을 시켜주는 것이고

_objects 라는 벡터안에 들어있는 데이터들은 동적할당해서 밀어 준 것이기 때문에

이중 반복문으로 개별적인 오브젝트들을 해제를 해준 것이다.

벡터 메모리 구조 ❗❗❗

포인터를 데이터로 가지는 vector의 메모리 구조를 알아보자

현재 push_back으로

이렇게 밀어 넣었을 경우

players< Player* > 라는 vector는 이렇게 뜬다.

현재 0x64 운영체제라 포인터의 크기는 8바이트 이다.

players[0]의 크기는 8바이트 주소는 0x000000A8DB35F5F0 이것인데

다음 주소가 0x000000A8DB35F610 이다.

0x000000A8DB35F5F0에서 64비트를 더하면 0x000000A8DB35F610가 나온다.

지금 열이 두줄이다. 16진수 두자리당 1비트 이다.

(근데 이거 지금 2열당 몇바이트 인지 모르겟다...)

아무튼 이안에 이제 힙에서 할당받은 주소가 각각들어간다.

players[1] 의 시작주소 메모리 이다.

실제 players의 1번째 인덱스에 있는 데이터들의 주소인데

메모리를 까보면 실제 그 주소들이 다 담겨져있다.

해당 주소를 타고 가보면

이렇게 부모 클래스의 _hp = 100, _attack = 2값과

자식 클래스의 _hp = 100, _attack = 10이 들어간 것을 볼 수 있다.

접근할 때는 다차원 배열처럼 _objects[][] 이런식으로 접근을 한다.

구조

Core에서

이런 매니저들 싹다 초기화 해주고

Core에서는 DT값 계산을 하고

(원레는 메세지 기반 방식이였는데 지금 비동기 식으로 처리를 progress엣더 한다)

여기서 처음에 TimeManager에서 DT값 계산을 하고

Key체크 하고

SceneManager에서 현재 씬을 돌려준다.

SceneManager->update에서

이까지 들어와서 _objects마다 싹다 돌면서 각 오브젝트가 스스로 update호출하게 만든다.

이 _objects의 update가 하는 일은 Core에서 KeyManager에서 키를 눌렸을때 키의 상태값을 바탕으로

CObject->update에서 이렇게 누른 키가 무엇인지 판별을 해서 움직인다.

그러면 지금 오브젝트가 움직인 상태임. 어디? => 비트맵에.

그래서 해당 프레임에 모든 작업들이 끝났으면 이제

이까지가 한 프레임작업 끝난 것이다.

지금 현재 기준으로 화면 한번 날리고

_memDC에다가 현재 장면 싹다 render하게 CSceneManager->render ()에다가 _memDC전달해준다.

이거 타고타고 가보면 최종적으로

이까지 온 다음에 Rectangle함수 호출해서 이동한 방향만큼 그린다!

이까지 비트맵에 다 그렸다면 이제

BitBlt호출하여 비트맵에 그려진거 현재 윈도우 화면에 송출 될 수 있게 픽셀 하나하나를 싹다 복사받는다.

이게 초당 800~900반복하는 작업을 보고 있는 것이다.

profile
https://cjbworld.tistory.com/ <- 이사중

0개의 댓글