game programming - egloospds9.egloos.com/pds/200804/25/79/gp12.pdf · 2008. 4. 24. · game...

15
ecl.incheon.ac.kr Game Programming Drawing Text Prof. 박종승 Dept. of CSE, Univ. of Incheon [email protected] http://ecl.incheon.ac.kr/

Upload: others

Post on 26-Jan-2021

2 views

Category:

Documents


0 download

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)