WWolves Den

DirectX 11 · 약 3분

렌더 타깃 수명: 매 프레임 재생성하지 않고 오류에서 복구하기

BeginDraw·EndDraw와 자원 생성·폐기를 분리하고, 리사이즈와 렌더 타깃 재생성이 필요한 상황을 다룹니다.

Wolfgadeok · 업데이트

만드는 일과 사용하는 일은 빈도가 다르다

그리기 전에 호출하는 자원 준비 함수는 렌더 타깃이 이미 있는지 확인하고 필요한 경우에만 생성하도록 만들 수 있습니다. 함수 이름을 CreateDeviceResources로 정하더라도 매 호출마다 새 객체를 만들어야 한다는 뜻은 아닙니다. 호출 빈도와 실제 생성 빈도를 구분해야 불필요한 최적화를 하거나 반대로 실제 재생성 비용을 놓치는 일을 피할 수 있습니다.

Direct2D에는 특정 장치나 렌더 타깃과 연결된 자원과 그렇지 않은 자원이 있습니다. 브러시와 비트맵 같은 의존 자원은 자신이 만들어진 환경과 함께 관리합니다. 타깃을 버리면서 관련 브러시를 계속 사용하면 자원 도메인이 맞지 않는 문제가 생길 수 있습니다. 단순히 포인터가 null이 아니라는 것과 지금 타깃에서 유효하다는 것은 다릅니다.

EndDraw는 결과 확인 지점이기도 하다

BeginDraw와 EndDraw는 그리기 작업의 범위를 구성합니다. 내부에서 작업을 모아 처리할 수 있기 때문에 개별 그리기 호출에서 즉시 오류가 보이지 않고 EndDraw에서 보고될 수 있습니다. 반환값을 버리지 말고 성공 여부와 복구 가능한 상태를 확인합니다. 이 개념을 모든 렌더 타깃에서 ‘백 버퍼를 앞 버퍼로 교체하는 한 함수’라고 일반화하면 안 됩니다.

D2DERR_RECREATE_TARGET이면 해당 타깃과 의존 자원을 해제하고 다음 유효한 그리기 때 다시 만들도록 설계할 수 있습니다. 다른 오류까지 전부 같은 이유라고 취급하면 실제 버그를 숨깁니다. 실패 코드를 기록하고 반복될 때 무한 재생성만 하지 않는 정책이 필요합니다. 아래는 구조를 표현한 의사 코드입니다.

예제 · text

그리기 요청:
    창의 그릴 크기가 유효한지 확인
    렌더 타깃과 의존 자원이 없으면 생성
    생성 실패면 오류 기록 후 이번 그리기 중단
    BeginDraw
    배경과 오브젝트 그리기
    result = EndDraw
    result가 재생성 요구면:
        의존 브러시와 비트맵 해제
        렌더 타깃 해제
    그 외 실패면:
        오류 코드와 현재 상태 기록

크기 변경과 복원도 정상 경로로 취급하기

사용자가 창 크기를 바꾸면 타깃 크기도 맞춰야 합니다. 최소화되어 폭이나 높이가 0이 된 상황은 정상적인 사용자 행동이므로 유효하지 않은 크기로 계속 자원을 만들지 않습니다. 크기 변경 함수도 실패할 수 있으므로 결과를 확인하고 필요할 때 자원을 재구성합니다. 위치·체력 같은 게임 상태는 그래픽 자원을 다시 만들었다고 함께 초기화하지 않습니다.

실습을 마쳤다면 창 크기를 여러 번 바꾸고 최소화·복원, 화면 배율 변경 후에도 사각형과 격자가 나타나는지 봅니다. 생성·해제 횟수를 로그로 세면 매 프레임 재생성하는 실수를 찾기 좋습니다. 버퍼링은 깜박임을 줄이는 중요한 렌더링 설계이지만, CPU의 게임 상태 복사본과 화면용 버퍼를 같은 의미로 섞어 설명하지 않습니다.

참고 자료

예제는 학습용이며, 모든 환경에서 실행 검증된 완성 프로젝트는 아닙니다. 적용 전 사용 중인 버전과 프로젝트 환경에서 동작을 확인하세요.