- Fade 코드 수정.
// CCamera.h
...
struct tCamEffectInfo
{
CAM_EFFECT eEffect;
float fDuration;
float fTimeAcc;
};
class CCamera
{
SINGLETON(CCamera)
private:
...
CTexture* m_pVeilTex; // 화면을 덮는 베일 텍스쳐.
//CAM_EFFECT m_eEffect; // 카메라 효과.
//float m_fEffectDuration; // 효과 지속 시간.
//float m_fEffectTimeAcc; // 효과 시간 누적.
queue<tCamEffectInfo> m_qEffectInfo;
public:
...
inline void FadeIn(float duration)
{
assert(duration > 0.f);
tCamEffectInfo effectInfo = {};
effectInfo.eEffect = CAM_EFFECT::FADE_IN;
effectInfo.fDuration = duration;
effectInfo.fTimeAcc = 0.f;
m_qEffectInfo.push(effectInfo);
}
inline void FadeOut(float duration)
{
assert(duration > 0.f);
tCamEffectInfo effectInfo = {};
effectInfo.eEffect = CAM_EFFECT::FADE_OUT;
effectInfo.fDuration = duration;
effectInfo.fTimeAcc = 0.f;
m_qEffectInfo.push(effectInfo);
}
...
기존 멤버 변수들을 구조체 tCamEffectInfo 에 묶고, 이걸 queue 자료구조에 보관.
Event Manager 에서 했던 것처럼 매 프레임마다 해당 queue 에 쌓인 effect 요청들을 처리해주면 됨.
// CCamera.cpp
...
void CCamera::render(HDC hDC)
{
if (m_qEffectInfo.empty())
return;
tCamEffectInfo& effectInfo = m_qEffectInfo.front();
effectInfo.fTimeAcc += DELTATIMEF;
if (effectInfo.fTimeAcc > effectInfo.fDuration)
effectInfo.fTimeAcc = effectInfo.fDuration;
float alphaRatio = effectInfo.fTimeAcc / effectInfo.fDuration;
BLENDFUNCTION func = {};
func.BlendOp = AC_SRC_OVER;
func.BlendFlags = 0;
func.AlphaFormat = 0;
switch (effectInfo.eEffect)
{
case CAM_EFFECT::NONE:
break;
case CAM_EFFECT::FADE_IN:
alphaRatio = 1.f - alphaRatio;
break;
case CAM_EFFECT::FADE_OUT:
case CAM_EFFECT::END:
default:
break;
}
func.SourceConstantAlpha = static_cast<BYTE>(255.f * alphaRatio);
AlphaBlend(hDC, 0, 0,
m_pVeilTex->GetWidth(), m_pVeilTex->GetHeight(),
m_pVeilTex->GetDC(), 0, 0,
m_pVeilTex->GetWidth(), m_pVeilTex->GetHeight(),
func);
if(effectInfo.fTimeAcc >= effectInfo.fDuration)
{
m_qEffectInfo.pop();
}
}
- 렌더링 최적화.
강의에서는 각 타일들을 인덱스 순서대로 좌표상에 배치되도록 구현했기 때문에, 카메라 시야 범위에서 보이는 타일들을 계산해서
해당되는 타일들만 render 함수를 호출할 수 있도록 별도의 render_tile 함수를 구현했음.
나는 일단 모든 오브젝트들에 카메라 밖인지 검사하는 함수를 추가해서 간단하게 렌더링 최적화를 적용함.
// CScene.cpp
...
void CScene::render(HDC hDC)
{
for (UINT i = 0; i < (UINT)GROUP_TYPE::END; ++i)
{
vector<CObject*>::iterator iter = m_arrObj[i].begin();
for (; iter != m_arrObj[i].end();)
{
...
if (obj->is_in_camera_view())
{
obj->render(hDC);
}
++iter;
}
}
}
Scene 의 render 함수에서 모든 오브젝트 그룹에서 카메라 밖인지 체크하고 render 호출.
// CObject.h
class CObject
{
...
public:
...
virtual void render(HDC hDC);
// 오브젝트가 화면 밖에 있을 때 렌더링을 건너뛰기 위한 함수.
virtual bool is_in_camera_view() const { return true; }
...
Object 클래스에 virtual 함수로 선언해주고, Tile 클래스에서 override 해준다.
// CTile.cpp
...
bool CTile::is_in_camera_view() const
{
POINT resolution = CCore::GetInstance()->GetResolution();
Vector2 pos = CCamera::GetInstance()->WorldToScreen(GetPos());
Vector2 size = GetSize();
if (pos.x + size.x < 0.f || pos.x > static_cast<float>(resolution.x)
|| pos.y + size.y < 0.f || pos.y > static_cast<float>(resolution.y))
{
return false;
}
return true;
}


실행해보면, fps 차이가 나긴 한다. 다만 현재 타일 사이즈를 너무 작게 하는 바람에, 화면에 그려지는 게 그냥 많기는 함.
타일들은 아무래도 타일맵이라는 클래스를 새로 만든 뒤, 타일맵 객체에서 한번에 그려주는 방식으로 만들어주는 것이 좋을 듯?
'Win32 api' 카테고리의 다른 글
| Win32 api 강의 63화. (0) | 2025.10.01 |
|---|---|
| Win32 api 강의 62화. (0) | 2025.09.30 |
| Win32 api 강의 57 - 58화. (0) | 2025.09.29 |
| Win32 api 강의 55 - 56화. (0) | 2025.09.29 |
| Win32 api 강의 54화. (0) | 2025.09.27 |