DX9을 이용한 3D Game 프로그래밍 입문 - Part.3 Direct3D 응용 9장

김주현·2021년 11월 7일
0

9장 글꼴

9.1 ID3DXFont

ID3DXFont : D3DX 라이브러리가 제공하는 Direct3D 애플리케이션에서 텍스트를 그리는 데 사용할 수 있는 인터페이스,내부적으로 GDI를 이용하기 때문에 약간의 성능 저하가 따르지만,GDI의 도움으로 복잡한 글꼴이나 포맷팅을 이용할 수 있다.

9.1.1 ID3DXFont 만들기

D3DXCreateFontIndirect 함수를 이용해 ID3DXFont 인터페이스를 만들 수 있다.

HRESULT D3DXCreateFontIndirect (
LPDIRECT3DDEVICE9 pDevice // 글꼴과 연결된 장치

CONST LOGFONT* pLogFont, // 글꼴을 나태는 LOGFONT 구조체

LPD3DXFONT* ppFont   //만들어진 글꼴을 리턴한다.

);

다음 코드는 이 함수의 이용 방법을 보여준다.

LOGFONT lf;
ZeroMemory(&lf,sizeof(LOGFONT));
lf.lfHeight = 25; // 논리적 단위
lf.lfWitdth = 12; // 논리적 단위
lf.lfWeight = 500; // 굵기의 단위, 범위 0(얇음) ~ 1000(두꺼움)
lf.lfItalic = false;
lf.lfUnderline = false;
lf.lfStrikeOut = false;
lf.lfCharSet = DEFAULT_CHARSET;
strcpy(lf.lfFaceName, "Times New Roman"); // 글꼴 스타일

ID3DXFont* font = 0;
D3DXCreateFontIndirect(Device, &lf,&font);

만들고자 하는 글꼴의 특성을 지정하는 LOGFONT 구조체를 먼저 채워야 한다는 것을 기억하자.

-NOTE-
D3DXCreateFont 함수를 이용해 ID3DXFont로의 포인터를 얻는 방법도 있다.

9.1.2 텍스트 그리기
ID3DXFont 인터페이스로의 포인터를 얻은 다음에는 ID3DXFont::DrawText 메서드를 호출하여 간단하게 텍스트를 그려낼 수 있다.

INT ID3DXFont::DrawText(
LPCSTR pString, //그리고자하는 문자열을 가리키는 포인터
INT Count, // 문자열 내에 포함된 문자의 수. 문자열이 null로 끝나는 경우에는 -1을 지정할 수 있다.
LPRECT pRect, // 텍스트가 그려질 화면 상의 영역을 정의하는 RECT 구조체를 가리키는 포인터
DWORD Format, // 텍스트 포맷을 지정하는 선택적 플래그;
D3DCOLOR Color // 텍스트 컬러
);

Font->DrawText(
"Hello World" //그리고자 하는 문자열
-1, //null로 끝나는 문자열
&rect // 텍스트가 그려질 사각형
DT_TOP | DT_LEFT // 사각형의 왼쪽 상단에 그린다.
0xff000000) // 검은색
);

9.1.3 초당 렌더링 프레임 계산하기

FPS를 계산하는 방법을 살펴보자.

먼저 세 개의 전연 변수를 만든다

DWORD FrameCnt //렌더링된 프레임 수
float TimeElapsed // 현재까지 경과된 시간
float FPS // 초당 렌더링 프레임 수

매 초마다 FPS를 계산하여 비교적 정확한 평균을 얻는다. 부가적으로 매 초당 일정한 FPS를 유지하여 변경된 값을 다시 계산할 동안 충분한 시간을 제공한다.

각각의 프레임은 FrameCnt를 증가시키며 TimeElapsed에 마지막 프레임부터 현재까지 걸린 시간을 더한다.

FrameCnt++;
TomeElapsec += timeDelta;
여기에서 timeDelta는 각 프레임 당 걸린 시간이 된다.

1초가 흐른 뒤에는 다음과 같은 식을 이용해 FPS를 계산한다.

FPS = (float) FrameCnt / TimeElapsed;

이제 FrameCnt와 TimeElapsed를 초기화하고 다음 1초를 위한 FPS계산한다.

void CalcFPS(float timeDelta)
{
FrameCnt++;
TimeElapsed += timeDelta;

if(TimeElapsed >= 1.0f)
{
	FPS = (float)FrameCnt / TimeElapsed;
    
    TimeElapsed = 0.0f;
    FrameCnt = 0;
    
}

}

9.2 CD3DFont

DX SDK는 DXSDK 루트 디렉토리의 \Samples\C++\Common 폴더에 매우 유용한 유틸리티 코드를 제공한다.

CD3font : D3D와 텍스처를 입힌 삼각형을 이용해 텍스트를 렌더링,
GDI가 아닌 D3D를 이용하므로 ID3DXFont에 비해 훨씬 빠른 속도를 가짐 But ID3DXFont의 복잡한 글꼴과 포맷팅은 지원하지 못한다.
간단한 텍스트를 빠른속도로 그려내고자할때 유용

9.2.1 CD3Dfont 구성하기

CD3DFont 인스턴스를 만들기 위해서는 일반적인 C++ 객체와 마찬가지로 이를 인스턴스화하면 된다. 다음은 CD3DFont의 생성자 프로토 타입이다.

CD3DFont(
const TCHAR* strFontName, //글꼴의 이름을 지정하는 null로끝나는 문자열
DWORD dwHeight, // 글꼴의 높이
DWORD dwFlags=0L // 선택적 생성 플래그들
);

CD3DFont 객체를 인스턴스화한 다음에는 다음의 메서드들을 순서대로 호출하여 글꼴을 초기화해야 한다.

Font = new CD3DFont("Times New Roman",16, 0); //인스턴스화
Font->InitDeviceObjects(Device);
Font->ResotrDeviceObjects();

9.2.2 텍스트 그리기

CD3DFont 객체를 구성하고 초기화하였다면 텍스트를 그릴 준비가 완료된 것이다. 텍스트를 그리는 데는 DrawText메서드가 이용된다.

HRESULT CD3DFont::DrawText(
FLOAT x, //텍스트 그리기를 시작할 화면의 X축 좌표
FLOAT y, //텍스트 그리기를 시작할 화면의 y축 좌표
DWORD dwColor, //텍스트의 컬러
const TCHAR* strText, //그리고자 하는 문자열의 포인터
DWORD dwFlags=0L // 선택적 렌더링 플래그들;
);

9.2.3 정리

CD3DFont 객체를 삭제하기 전에 다음의 코드 조각에서 보여주는 것과 같은 약간의 정리 루틴을 호출해야 한다.

Font->InvalidateDeviceObjects();
Font->DeleteDeviceObjects();
delete Font;

);

9.3 D3DXCreateText

텍스트의 3D 메쉬를 만드는 데 이용된다.

HRESULT D3DXCreateText(
LPCIRECT3DDEVICE9 pDevice, -메쉬와 연결될 장치
HDC hDC, - 메쉬를 생성하는 데 이용될 글꼴 정보를 포함하는 장치 컨텍스트로의 핸들
LPCTSTR pText, - 메쉬로 만들 텍스트를 포함하는 null로 끝나는 문자열
FLOAT Deviation,-트루타입 글꼴 외각선에서의 최대 편차. 이 값은 0이거나 보다 커야 한다. 이 값이 0일 때 편차는 원본 글꼴의 한 디자인 단위와 같게 된다.
FLOAT Extrusion - 음의 z축 방향으로 잰 글꼴의 깊이
LPD3DXMESH ppMesh, - 만들어진 메쉬를 리턴한다.
LPD3DXBUFFER
ppAdjacency,- 만들어진 메쉬의 근접 정보를 리턴한다.필요치 않을 경우 null을 지정한다.
LPGLYPHMETRICSFLOAT pGlyphMetrics-장식 거리 데이터를 포함하는 LPGLYPHMETERICSFLOAT 구조체 배열의 포인터.장식 거리 데이터에 상관하지 않는 경우에는 이를 0으로 지정한다.
);
이 함수는 실행이 성공한 경우 D3D_OK를 리턴한다.

마지막으로 메쉬의 DrawSubset 메서드를 호출하여 간단히 3D 텍스트 메쉬를 렌더링할 수 있다.

9.4 요약

*복잡한 글꼴이나 포맷팅 지원이 필요한 경우에는 ID3DXFont 인터페이스를 이용해 텍스트를 렌더링한다. 이 인터페이스는 내부적으로 GDI를 이용하므로 약간의 성능 저하가 있다.

*간단한 텍스트를 빠르게 그리기 위해서는 CD3DFont 클래스를 이용한다. 이 클래스는 Direct3D와 텍스처를 입힌 삼각형을 이용하므로 ID3DXFont 보다 훨씬 빠르게 동작한다.

*텍스트 문자열의 3D 메쉬를 만들고자 한다면 D3DXCreateText를 이용한다.

0개의 댓글

관련 채용 정보