game programming - egloospds9.egloos.com/pds/200804/25/79/gp12.pdf · 2008. 4. 24. · game...
TRANSCRIPT
-
ecl.incheon.ac.kr
Game ProgrammingDrawing Text
Prof. 박종승Dept. of CSE, Univ. of [email protected]://ecl.incheon.ac.kr/
-
Game Programming - Spring 2005 Univ. of Incheon, CSE
2
Fonts• ID3DXFont• CD3DFont• D3DXCreateText• Summary
-
Game Programming - Spring 2005 Univ. of Incheon, CSE
3
ID3DXFont• 글꼴출력방법
– ID3DXFont: 내부적으로 GDI를이용; 복잡한글꼴과포맷팅을지원함– CD3DFont: GDI가아닌 Direct3D를이용; 매우빠름; 간단한텍스트출력에적합
• ID3DXFont 만들기
• D3DXFONT_DESC
HRESULT WINAPI D3DXCreateFontIndirect(LPDIRECT3DDEVICE9 pDevice, //deviceCONST D3DXFONT_DESC *pDesc, //font attributesLPD3DXFONT *ppFont //created ID3DXFont interface
);
typedef struct D3DXFONT_DESC {INT Height; //폰트 문자의 높이 (in logical units)UINT Width; //폰트 문자의 너비 (in logical units)UINT Weight; //font의 Weight(boldness); [0(light)..1000(bold)]UINT MipLevels; //mip level의 수;
/* 0 또는 D3DX_DEFAULT이면완전한mipmap chain이생성됨; *//* 1이면 texture space가동일하게 screen space로매핑됨 */
BOOL Italic; // true이면 italic font가 됨BYTE CharSet; //character setBYTE OutputPrecision; //output이 요청한 사양과 얼마나
// 부합되어야 하는지를 명시함BYTE Quality; //output qualityBYTE PitchAndFamily; //pitch and family of the fontTCHAR FaceName[LF_FACESIZE]; //typeface name of the font (32문자이내)
/* empty string일경우다른 attribute들에의해선정된첫 font를사용함 */} D3DXFONT_DESC;
-
Game Programming - Spring 2005 Univ. of Incheon, CSE
4
ID3DXFont• D3DXCreateFontIndirect 이용방법예 1
• D3DXCreateFontIndirect 이용방법예 2
D3DXFONT_DESC fontDesc; ZeroMemory(&fontDesc, sizeof(D3DXFONT_DESC)); fontDesc.Height = 25; fontDesc.Width = 12; fontDesc.Weight = 500; fontDesc.MipLevels = D3DX_DEFAULT; fontDesc.Italic = false; fontDesc.CharSet = DEFAULT_CHARSET; fontDesc.OutputPrecision = 0; fontDesc.Quality = 0; fontDesc.PitchAndFamily = 0; strcpy(fontDesc.FaceName, "Times New Roman");if(FAILED(D3DXCreateFontIndirect(Device, &fontDesc, &MyFont))){::MessageBox(0, "D3DXCreateFontIndirect() - FAILED", 0, 0); ::PostQuitMessage(0);
}
ID3DXFont *font = 0; D3DXFONT_DESC df; ZeroMemory(&df, sizeof(D3DXFONT_DESC)); df.Height = 22; df.Width = 10;df.Weight = 400;df.Italic = false; df.CharSet = DEFAULT_CHARSET; df.Quality = 0; df.PitchAndFamily = 0; strcpy(df.FaceName, "Times New Roman");if (FAILED(D3DXCreateFontIndirect(device, &df, &font))){ ::MessageBox(0, "D3DXCreateFontIndirectA() - FAILED", 0, 0); ::PostQuitMessage(0); }
-
Game Programming - Spring 2005 Univ. of Incheon, CSE
5
ID3DXFont - Text Drawing• DrawText
– Windows GDI의 DrawText와유사함– BeginScene과 EndScene내에서사용되어야함
• 예외: text block의크기를계산하기위한경우 (DT_CALCRECT)– text를 clip하여 rectangle 외부에는표시되지않도록함 (예외: DT_NOCLIP이지정된경우)
– text block은여러라인을가질수있다고가정함 (예외: DT_SINGLELINE)
INT DrawText(LPD3DXSPRITE pSprite, //string을가지는 ID3DXSprite object;
//NULL일경우 Direct3D가자신의 sprite object로렌더링함;//DrawText가여러번호출되는경우에는효율성을위해서명시하는것이좋음.
LPCTSTR pString, //draw할 string;//Count가 -1이면 string이반드시 null로종료되어야함.
INT Count, //string의문자의수;//-1인경우 string이 null로끝난다고가정하고문자수를자동계산함.
LPRECT pRect,//text가 들어갈 사각형을 표시하는 RECT 구조체; DWORD Format, //formatting 방법; DT_XXX (DT_CENTER등); API 참조할것D3DCOLOR Color //text color
);
-
Game Programming - Spring 2005 Univ. of Incheon, CSE
6
ID3DXFont - Text Drawing• DrawText의사용예 1
• DrawText의사용예 2
• DrawText의사용예 3
RECT rect = {0,0, 600, 400}; MyFont->DrawText(0, "Hello World", -1, &rect, DT_CENTER|DT_VCENTER, 0xffffffff);
std::stringstream FPSStr; FPSStr DrawText(NULL,“Hello World”, //string to draw-1, //null terminating string&rect, //rectangle to draw the string inDT_TOP|DT_LEFT, //draw in top-left corner of rect0xff000000); //black
-
Game Programming - Spring 2005 Univ. of Incheon, CSE
7
ID3DXFont 예제 (1/2)#include "d3dUtility.h"ID3DXFont* Font = 0;DWORD FrameCnt = 0; //The number of frames that have occurred.float TimeElapsed = 0; //The time that has elapsed so far.float FPS = 0; //The frames rendered per second.char FPSString[9];bool Setup(){D3DXFONT_DESC fontDesc;ZeroMemory(&fontDesc, sizeof(D3DXFONT_DESC));fontDesc.Height = 25; fontDesc.Width = 12; fontDesc.Weight = 500;fontDesc.MipLevels = D3DX_DEFAULT; fontDesc.Italic = false;fontDesc.CharSet = DEFAULT_CHARSET;fontDesc.OutputPrecision = 0; fontDesc.Quality = 0;fontDesc.PitchAndFamily = 0;strcpy(fontDesc.FaceName, "Times New Roman"); // font styleif(FAILED(D3DXCreateFontIndirect(Device, &fontDesc, &Font))) {
::MessageBox(0, "D3DXCreateFontIndirect() - FAILED", 0, 0);::PostQuitMessage(0);
}return true;
}void Cleanup(){d3d::Release(Font);
}
-
Game Programming - Spring 2005 Univ. of Incheon, CSE
8
ID3DXFont 예제 (2/2)bool Display(float timeDelta){if( Device ){
FrameCnt++;TimeElapsed += timeDelta;if(TimeElapsed >= 1.0f){
FPS = (float)FrameCnt / TimeElapsed;sprintf(FPSString, "%f", FPS);FPSString[8] = '\0'; // mark end of stringTimeElapsed = 0.0f;FrameCnt = 0;
}Device->Clear(0, 0,
D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 1.0f, 0);Device->BeginScene();RECT rect = {0, 0, Width, Height};Font->DrawText(NULL,
FPSString, -1, // size of string or -1 indicates null terminating string&rect, // rectangle text is to be formatted to in windows coordsDT_TOP | DT_LEFT, // draw in the top left corner of the viewport0xff000000); // black text
Device->EndScene();Device->Present(0, 0, 0, 0);
}return true;
}
-
Game Programming - Spring 2005 Univ. of Incheon, CSE
9
CD3DFont• CD3DFont class
– DXSDK\Samples\C++\Common
– textured triangle을이용해 text를 rendering함– GDI를사용하지않음; 매우빠르나글꼴과포맷팅이단순함– CD3DFont class의사용을위해서는 Common의다음소스를추가해야함
• d3dfont.h/cpp, d3dutil.h/cpp, dxutil.h/cpp
• CD3DFont구성하기
• CD3DFont객체생성후글꼴을초기화
CD3DFont(const TCHAR* strFontName, //font name, null terminating stringDWORD dwHeight, //font heightDWORD dwFlags=0L); //0, D3DFONT_BOLD/ITALIC/ZENABLE
Font = new CD3DFont(“Times New Roman”, 16, 0); //instance화Font->InitDeviceObjects(Device);Font->RestoreDeviceObjects();
-
Game Programming - Spring 2005 Univ. of Incheon, CSE
10
CD3DFont• Text Drawing
– 예:
• Finish: CD3DFont객체를삭제하기전에마무리
HRESULT CD3DFont::DrawText(FLOAT x, FLOAT y, //text drawing을 시작할 화면의 x/y-축 좌표DWORD dwColor, //text colorconst TCHAR* strText, //draw할 stringDWORD dwFlags=0L); //flags: 0,D3DFONT_CENTERED/TWOSIDED/FILTERED
Font->DrawText(20, 20, 0xff000000, “Hello, World”);
Font->InvalidateDevideObjects();Font->DeleteDeviceObjects();delete Font;
-
Game Programming - Spring 2005 Univ. of Incheon, CSE
11
CD3DFont 예제 (1/2)#include "d3dUtility.h"#include "d3dfont.h"
CD3DFont* Font = 0;DWORD FrameCnt = 0;float TimeElapsed = 0;float FPS = 0;char FPSString[9];
bool Setup(){// Create a font object and initialize it.Font = new CD3DFont("Times New Roman", 16, 0);Font->InitDeviceObjects( Device );Font->RestoreDeviceObjects();return true;
}void Cleanup(){if( Font ) {
Font->InvalidateDeviceObjects();Font->DeleteDeviceObjects();d3d::Delete(Font);
}}
-
Game Programming - Spring 2005 Univ. of Incheon, CSE
12
CD3DFont 예제 (2/2)bool Display(float timeDelta){if( Device ) {
// Update: Compute the frames per second.FrameCnt++;TimeElapsed += timeDelta;if(TimeElapsed >= 1.0f) {
FPS = (float)FrameCnt / TimeElapsed; sprintf(FPSString, "%f", FPS);FPSString[8] = '\0'; // mark end of stringTimeElapsed = 0.0f;FrameCnt = 0;
}// RenderDevice->Clear(0, 0,
D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 1.0f, 0);Device->BeginScene();if( Font )
Font->DrawText(20, 20, 0xff000000, FPSString); Device->EndScene();Device->Present(0, 0, 0, 0);
}return true;
}
-
Game Programming - Spring 2005 Univ. of Incheon, CSE
13
Text Mesh 만들기 - D3DXCreateText• Text로부터mesh를만들고이를렌더링함
– Windows API: HDC(device context)를얻고(CreateCompatibleDC), HFONT를생성(LOGFONT,CreateFontIndirect),
– D3DXCreateText를호출하여mesh 생성• D3DXCreateText
HRESULT WINAPI D3DXCreateText(LPDIRECT3DDEVICE9 pDevice, //deviceHDC hDC, //device context; 선택된 font는 꼭 TrueType font여야 함.LPCTSTR pText, //생성할 textFLOAT Deviation, //max chordal deviation from TTF outlines
//0이상의 값. 0이면 원본 글꼴의 한 디자인 단위와 같게됨.FLOAT Extrusion, //-z축 방향으로 잰 글꼴의 깊이LPD3DXMESH *ppMesh, //만들어진 meshLPD3DXBUFFER *ppAdjacency, //만들어진 mesh의 adjacency 정보;
//필요하지 않으면 NULL로 지정.LPGLYPHMETRICSFLOAT pGlyphMetrics //glyph metric data.
//string의 문자수만큼의 glyph들이 있음. 필요하지 않으면 NULL로 지정.);
-
Game Programming - Spring 2005 Univ. of Incheon, CSE
14
Text Mesh 만들기예 (1/2)ID3DXMesh* Text = 0;bool Setup(){// Get a handle to a device context.HDC hdc = CreateCompatibleDC( 0 );HFONT hFont; HFONT hFontOld;// Describe the font we want.LOGFONT lf;ZeroMemory(&lf, sizeof(LOGFONT));lf.lfHeight = 25; lf.lfWidth = 12;lf.lfEscapement = 0; lf.lfOrientation = 0; lf.lfWeight = 500; lf.lfItalic = false; lf.lfUnderline = false; lf.lfStrikeOut = false; lf.lfCharSet = DEFAULT_CHARSET;lf.lfOutPrecision = 0; lf.lfClipPrecision = 0; lf.lfQuality = 0; lf.lfPitchAndFamily = 0; strcpy(lf.lfFaceName, "Times New Roman");// Create the font and select it with the device context.hFont = CreateFontIndirect(&lf);hFontOld = (HFONT)SelectObject(hdc, hFont);// Create the text mesh based on the selected font in the HDC.D3DXCreateText(Device, hdc, "Direct3D", 0.001f,0.4f, &Text, 0,0);// Restore the old font and free the acquired HDC.SelectObject(hdc, hFontOld);DeleteObject( hFont );DeleteDC( hdc );// Lights…// Set camera…// Set projection matrix…return true;
}
-
Game Programming - Spring 2005 Univ. of Incheon, CSE
15
Text Mesh 만들기예 (2/2)bool Display(float timeDelta){if( Device ) {
// Update: Spin the 3D text.D3DXMATRIX yRot, T;static float y = 0.0f;D3DXMatrixRotationY(&yRot, y);y += timeDelta;if( y >= 6.28f )
y = 0.0f;D3DXMatrixTranslation(&T, -1.6f, 0.0f, 0.0f);T = T * yRot;Device->SetTransform(D3DTS_WORLD, &T);// RenderDevice->Clear(0, 0,
D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);Device->BeginScene();Device->SetMaterial(&d3d::WHITE_MTRL);Text->DrawSubset(0);Device->EndScene();Device->Present(0, 0, 0, 0);
}return true;
}
Game ProgrammingDrawing TextFontsID3DXFontID3DXFontID3DXFont - Text DrawingID3DXFont - Text DrawingID3DXFont 예제 (1/2)ID3DXFont 예제 (2/2)CD3DFontCD3DFontCD3DFont 예제 (1/2)CD3DFont 예제 (2/2)Text Mesh 만들기 - D3DXCreateTextText Mesh 만들기 예 (1/2)Text Mesh 만들기 예 (2/2)