Home  
  Home Lecture Link BBS Blame  



¢Â3D °ÔÀÓ Á¦ÀÛ Auxiliary¢Â

 

±³À°±â°ü¿¡¼­ 3D ±âÃÊ °úÁ¤ ¼ö¾÷ÀÌ ³¡³ª°í 2~3ÁÖ Á¤µµ ½Ã°£À» µÎ¾î °ÔÀÓ Á¦ÀÛ ½Ç½ÀÀ» ÁøÇàÇÕ´Ï´Ù. 3D ±âÃÊ °úÁ¤¸¸À¸·Îµµ °ÔÀÓ Á¦ÀÛÀÌ °¡´ÉÇÏÁö¸¸ ÀǿܷΠÀÛÀº ºÎºÐµé¿¡¼­ ½Ã°£À» ¸¹ÀÌ »©¾Ñ±â°Å³ª ¶Ç´Â ÄÚµå ¸î ÁÙ ´õ ³ÖÀ¸¸é °ÔÀÓ ºÐÀ§±â°¡ È® ´Þ¶óÁö´Â ÀϵéÀÌ Á¾Á¾ ÀÖ½À´Ï´Ù. ÀÌ ÀåÀº 3D ±âÃÊ °úÁ¤À» ¹è¿ì°í °ÔÀÓ Á¦ÀÛÀ» ½ÃÀÛÇÏ´Â ºÐµé¿¡°Ô Ưº°ÇÑ ÁÖÁ¦µéÀ» ¸ð¾Æ¼­ µµ¿òÀÌ µÉ¸¸ÇÑ ³»¿ëÀ» ¸ð¾Ò½À´Ï´Ù. 3DÀÇ Àü¹ÝÀûÀÎ ³»¿ëÀÌ ¾Æ´Ñ Áö¿ªÀûÀÎ ³»¿ëÀÌ ¸¹¾Æ ÀÌ ÀåÀº ³Ñ¾î°¡µµ »ó°ü¾ø½À´Ï´Ù.

 

 

3.1 Æ÷±×(Fog)

D3D´Â 3DÀÇ Çö½Ç°¨(Reality)¸¦ ³ôÀ̱â À§Çؼ­ Anti-aliasing, ¹üÇÁ ¸ÅÇÎ(Bump Mapping), ¹Ý»ç³ª ±¼Àý¿¡ ´ëÇÑ È¯°æ ¸ÅÇÎ(Environment Mapping), ½ºÅÙ½Ç, ¹öÅØ½º ºí·»µù(Vertex Blending), Æ÷±×(Fog) µîÀ» Áö¿øÇÕ´Ï´Ù. ÀÌ Áß¿¡¼­ Æ÷±×´Â ÄÄÇ»ÅÍ ±×·¡ÇȽº¿¡¼­ Çö½ÇÀÇ ¾È°³ È¿°ú¸¦ Ç¥ÇöÇÑ °ÍÀÔ´Ï´Ù. Æ÷±×¸¦ Àû¿ëÇϸé 3D Àå¸éÀ» ±¸¼ºÇÏ´Â °¡»ó Ä«¸Þ¶ó¿¡¼­ ¸Ö¸® ÀÖ´Â ¿ÀºêÁ§Æ®´Â Æ÷±×ÀÇ »ö»ó¿¡ °¡±õ°Ô ¸¸µé°í °¡±î¿ï¼ö·Ï ¹°Ã¼¸¦ ¼±¸íÇÏ°Ô º¸ÀÌ°Ô ÇÕ´Ï´Ù. ¶ÇÇÑ Æ÷±×¸¦ »ç¿ëÇÏ¸é ¸Ö¸® ÀÖ´Â ¹°Ã¼´Â µð¹ÙÀ̽º°¡ 'Àû´çÈ÷' ±×¸®°Ô µÇ¾î ·»´õ¸µ ¼Óµµ°¡ Çâ»óµÇ¸ç º¼·ý üÀûÀÇ Far Æò¸é°úÀÇ °Å¸® °ªº¸´Ù ÀÛÀ» ¶§ ¿ÀºêÁ§Æ®°¡ °©ÀÚ±â Æ¢¾î³ª¿À´Â Çö»óµµ ¸·À» ¼ö ÀÖ½À´Ï´Ù.

 

D3D´Â Àå¸é¿¡ Æ÷±×¸¦ Àû¿ëÇÏ´Â Á¤Á¡ Æ÷±×, Çȼ¿ Æ÷±× µÎ °¡Áö ¹æ¹ýÀÌ ÀÖ½À´Ï´Ù. ÀÌµé Æ÷±×´Â ´ÙÀ½°ú °°Àº ¼±Çü °è»ê °ø½ÄÀ¸·Î Æú¸®°ï¿¡ Àû¿ëµË´Ï´Ù.

 

ÃÖÁ¾ Æú¸®°ï »ö»ó C = f * Æú¸®°ï »ö»ó + (1 - f)* Æ÷±× »ö»ó

 

f´Â Æ÷±× °è¼ö(Fog Factor)·Î °Å¸®ÀÇ Á¤µµ¿¡ µû¶ó °è»êÇϴµ¥ ´ÙÀ½°ú °°ÀÌ ¼±Çü Æ÷±×(Linear Fog)¿Í Áö¼ö Æ÷±×(Exponential Fog)·Î ºÐ·ù µË´Ï´Ù.

 

 (¼±ÇüÆ÷±×: D3DFOG_LINEAR)

(Áö¼ö Æ÷±×: D3DFOG_EXP)

(Áö¼ö Æ÷±×: D3DFOG_EXP)

<Æ÷±× °ø½Ä°ú ±×·¡ÇÁ>

 

°ø½ÄÀÇ d´Â Ä«¸Þ¶ó¿¡¼­ Á¤Á¡±îÁö °Å¸®À̰í e´Â ÀÚ¿¬ ´ë¼ö(exponential)ÀÔ´Ï´Ù. start´Â ¼±ÇüÆ÷±×°¡ Àû¿ëµÇ´Â ½ÃÀÛ °Å¸®, end´Â Æ÷±×ÀÇ È¿°ú°¡ ´õ ÀÌ»ó Áõ°¡ÇÏÁö ¾Ê´Â ÃÖ´ë °Å¸®ÀÔ´Ï´Ù.

±×·¡ÇÁ¸¦ º¸¸é ¼±Çü Æ÷±×´Â ÀüüÀûÀ¸·Î ¼±ÇüÀûÀ¸·Î º¯È­ÇÏ´Â ¹Ý¸é¿¡ exp Æ÷±×´Â ±Þ°ÝÈ÷ º¯È­Çß´Ù°¡ õõÈ÷ º¯È­Çϰí exp2 Æ÷±×´Â õõÈ÷ º¯È­ÇÏ´Ù°¡ ±Þ°ÝÈ÷ º¯ÇÏ´Â °ÍÀ» ¾Ë ¼ö ÀÖ½À´Ï´Ù.

 

  

<Linear, Exp, Exp2>

 

¼±Çü Æ÷±×´Â end °ª ÀÌÈÄ¿¡´Â Æ÷±×»ö»óÀÌ 100%Àû¿ëÀÌ µÇ¾î ¿ÞÂÊó·³ £Àº Æ÷±× »ö»óÀÇ ¶ì¸¦ ¸¸µé±âµµ ÇÕ´Ï´Ù.

 

D3DÀÇ Æ÷±×´Â ´ÙÀ½ ±×¸²Ã³·³ ¿µ¿ª ±â¹Ý(Range-based)¸¦ ¼³Á¤Çϰųª ¶Ç´Â ÇØÁ¦(Plane-based) ÇÒ ¼ö ÀÖ½À´Ï´Ù.

 

<¿µ¿ª ±â¹Ý(Range-based) Æ÷±× ¼³Á¤, ¹Ì ÁöÁ¤>

 

<¿µ¿ª ±â¹Ý ¼³Á¤ÀÌ ¾ÈµÈ Æ÷±×¿¡¼­ÀÇ ¿ÀºêÁ§Æ®>

 

¿µ¿ª ±â¹ÝÀ¸·Î Çϸé Ä«¸Þ¶óÀÇ È¸Àü¿¡µµ Æ÷±×°¡ ÀÚ¿¬½º·´°Ô Àû¿ëÀÌ µË´Ï´Ù. ±×·¯³ª ¿µ¿ª ±â¹ÝÀ» ºñȰ¼ºÈ­ Çϸé Ä«¸Þ¶ó¿ÍÀÇ °Å¸®°¡ ¾Æ´Ñ z °ªÀ» °¡Áö°í Æ÷±×°è¼ö¸¦ °è»êÇϱ⠶§¹®¿¡ Ä«¸Þ¶óÀÇ È¸Àü¿¡ ´ëÇØ¼­ Æ÷±× Àû¿ëÀÌ µÉ ¼öµµ ÀÖ°í ¾ÈµÉ ¼öµµ ÀÖ½À´Ï´Ù.

 

Á¤Á¡ Æ÷±×´Â Á¤Á¡ º¯È¯°ú Á¶¸íÀ» Àû¿ëÇÒ ¶§ Æ÷±× ¶ÇÇÑ Àû¿ëÀÌ µÇ°í, Çȼ¿ Æ÷±×´Â Çϵå¿þ¾î¿¡ µû¶ó¼­ ¹Ì¸® °è»ê µÈ ÂüÁ¶ Å×À̺íÀ» ÅëÇØ¼­ Çȼ¿ÀÇ ±íÀÌ °ª¿¡ µû¶ó Æ÷±×°¡ Àû¿ëÀÌ µË´Ï´Ù. ÀÌ·± ÀÌÀ¯·Î Çȼ¿ Æ÷±×¸¦ Å×ÀÌºí Æ÷±×¶ó Çϱ⵵ Çϸç Çȼ¿ Æ÷±×´Â ¿µ¿ª ±â¹Ý ¼³Á¤ÀÌ Á¦´ë·Î ¾ÈµË´Ï´Ù.

Â÷À̰¡ Ŭ °Í °°Áö¸¸ Á¤Á¡ Æ÷±×¿Í Çȼ¿ Æ÷±×´Â Àß º¸Áö ¾ÊÀ¸¸é Àå¸éÀÇ °á°ú¿¡¼­´Â °ÅÀÇ Â÷À̰¡ ¾ø½À´Ï´Ù.

 

Æ÷±×ÀÇ ±âº»ÀûÀÎ ³»¿ëÀ» ´Ù »ìÆì º¸¾Ò°í ´ÙÀ½À¸·Î À̸¦ ±¸Çö ÇÏ´Â ¹æ¹ýÀÔ´Ï´Ù. ¸ÕÀú ´ÙÀ½°ú °°Àº ÇÔ¼ö¸¦ ÁغñÇÏ´Â °ÍÀÌ ÁÁ½À´Ï´Ù.

 

inline DWORD FtoDW(float& p) { return *((DWORD*)&p); }

 

À̰ÍÀº D3DÀÇ »óÅ °ª ¼³Á¤Àº °ÅÀÇ DWORDÇüÀ¸·Î µÇ¾î ÀÖ½À´Ï´Ù. ±×·±µ¥ Æ÷±×´Â FLOATÇüÀ» »ç¿ëÇϰí À־ ´Ü¼øÈ÷ ÀڷḦ º¹»çÇÏ°Ô µÇ¸é Á¦´ë·Î 󸮰¡ ¾ÈµÇ¾î DWORDÇüÀ¸·Î ÀڷḦ ij½ºÆÃ ÇØ¾ß¸¸ ÇÕ´Ï´Ù. À§¿Í °°Àº ÇÔ¼ö¸¦ »ç¿ëÇϸé ÀÚ·áÀÇ À¯½Ç ¾øÀÌ ¿Ã¹Ù·Î ³Ñ±æ ¼ö ÀÖ½À´Ï´Ù.

 

´ÙÀ½À¸·Î ´ÙÀ½°ú °°ÀÌ Æ÷±×ÀÇ »ö»ó, ½ÃÀÛ, ³¡, ¹Ðµµ(Density)¿¡ ´ëÇÑ º¯¼ö¸¦ ÁغñÇÕ´Ï´Ù.

 

DWORD   dFog    = D3DXCOLOR(0.2f, 1.f, 0.7f, 1.0f);

float   fStart  = 300.0f;

float   fEnd    = 700.0f;

float   fDens   = 0.0015f;

 

°ÔÀÓ¿¡¼­´Â ÁÖ·Î ¼±Çü Æ÷±×(Linear Fog)¸¦ »ç¿ëÇϰí À־ EXP¿¡¼­ »ç¿ëµÇ´Â ¹Ðµµ(Density) º¯¼ö´Â °ÅÀÇ ¼³Á¤ ¾È ÇÕ´Ï´Ù.

µð¹ÙÀ̽ºÀÇ »óÅ ¼³Á¤ ÇÔ¼ö RenderState()¸¦ ÀÌ¿ëÇØ¼­ Æ÷±×¸¦ Ȱ¼ºÈ­ÇÕ´Ï´Ù.

 

m_pDev->SetRenderState(D3DRS_FOGENABLE, TRUE);

 

Á¤Á¡ Æ÷±×ÀÌ¸é ´ÙÀ½°ú °°ÀÌ Çȼ¿ ±â¹Ý Æ÷±×¸¦ ¸·°í Á¤Á¡ Æ÷±×¿¡ Linear, Exp, Exp2Áß Çϳª¸¦ ¼³Á¤ÇÕ´Ï´Ù.

 

m_pDev->SetRenderState(D3DRS_FOGTABLEMODE, D3DFOG_NONE);

m_pDev->SetRenderState(D3DRS_FOGVERTEXMODE, D3DFOG_"LINEAR", "EXP", or"EXP2");

 

Çȼ¿ Æ÷±×¸é Á¤Á¡ Æ÷±×¸¦ ¸·°í Çȼ¿ Æ÷±× ¼³Á¤À» ÇÕ´Ï´Ù.

 

m_pDev->SetRenderState(D3DRS_FOGVERTEXMODE, D3DFOG_NONE);

m_pDev->SetRenderState(D3DRS_FOGTABLEMODE, D3DFOG_"LINEAR", "EXP", or"EXP2");

 

¸¶Áö¸·À¸·Î Æ÷±× º¯¼öµé°ú ¿µ¿ª ±â¹Ý Ȱ¼ºÈ­¸¦ ¼³Á¤ÇÕ´Ï´Ù.

 

m_pDev->SetRenderState(D3DRS_RANGEFOGENABLE, "TRUE"? "FALSE");

m_pDev->SetRenderState(D3DRS_FOGCOLOR,            "Æ÷±× »ö»ó");

m_pDev->SetRenderState(D3DRS_FOGSTART,       *((DWORD*)(&fStart)));

m_pDev->SetRenderState(D3DRS_FOGEND,       FtoDW(fEnd));

m_pDev->SetRenderState(D3DRS_FOGDENSITY,     FtoDW(fDens));

 

Àüü ÄÚµå´Â daux01_fog.zip ÀÇ CMain::Render() ÇÔ¼ö¸¦ Âü°í Çϱ⠹ٶø´Ï´Ù.

 

 

3.2 ÆùÆ®(Font)

3.2.1 ID3DXFont

ID3DXFont´Â ¾ÆÁÖ ½±°Ô »ç¿ëÇÒ ¼ö ÀÖ´Â ÆùÆ® Ãâ·Â¿ë È®Àå À¯Æ¿¸®Æ¼ÀÔ´Ï´Ù. ÀϹÝÀûÀ¸·Î À©µµ¿ìÀÇ ÆùÆ®¸¦ ±âº»À¸·Î ¸¹ÀÌ »ç¿ëÇÕ´Ï´Ù. ±×·±µ¥ ¶§·Î´Â °ÔÀÓ¿¡ ¸Â´Â ÆùÆ®¸¦ µû·Î ¸¸µé¾î »ç¿ëÇÒ ¶§µµ ÀÖ½À´Ï´Ù. ÀÌ·± °æ¿ì À©µµ¿ì Æú´õ¿¡ ÆùÆ®¸¦ µî·ÏÇØ »ç¿ëÇØ¾ß ÇÏÁö¸¸ °£´ÜÈ÷ Platform SDK ÇÔ¼ö¸¦ »ç¿ëÇØ¼­ ÇÁ·Î±×·¥ ³»ºÎ¿¡¼­¸¸ »ç¿ëÇÒ ¼ö ÀÖ´Â ¹æ¹ýÀÌ ÀÖ½À´Ï´Ù.

 

AddFontResourceEx()/RemoveFontResourceEx() ÇÔ¼ö´Â ÆùÆ®¸¦ ÇÁ·Î±×·¥ ³»ºÎ¿¡¼­ »ç¿ëÇϰí ÇØÁ¦ ÇÒ ¶§ »ç¿ëÇÏ´Â ÇÔ¼öÀÔ´Ï´Ù. ÀÌ ÇÔ¼ö´Â Windows 2000 À̻󿡼­¸¸ Áö¿øÀÌ µË´Ï´Ù. µû¶ó¼­ "windows.h" Æ÷ÇÔÇÒ ¶§ ¸ÅÅ©·Î·Î »óÀ§¹öÀüÀÓÀ» Ç¥½ÃÇØ¾ß ÇÕ´Ï´Ù.

ÀÌ ÇÔ¼öµéÀ» »ç¿ëÇØ¼­ ID3DXFont°´Ã¼ »ý¼º°ú ÇØÁ¦´Â ´ÙÀ½°ú °°ÀÌ ¿ä¾àÇÒ ¼ö ÀÖ½À´Ï´Ù.

 

#define _WIN32_WINNT   0x0500

#include <windows.h>

 

// ÆùÆ® µî·Ï

hr = AddFontResourceEx("font/08SeoulNamsanB.ttf", FR_NOT_ENUM, NULL);

hr = AddFontResourceEx("font/08SeoulHangangM.ttf", FR_NOT_ENUM, NULL);

¡¦

// ID3DXFont °´Ã¼ »ý¼º

hr = D3DXCreateFont(¡¦, "08¼­¿ï³²»êü B", &m_pDXFont1);

¡¦

// ÆùÆ® ÇØÁ¦

RemoveFontResourceEx("font/08SeoulNamsanB.ttf", FR_NOT_ENUM, NULL);

RemoveFontResourceEx("font/08SeoulHangangM.ttf", FR_NOT_ENUM, NULL);

 

< AddFontResourceEx() ÇÔ¼ö·Î ÇÁ·Î±×·¥ ³»ºÎ¿¡¼­¸¸ »ç¿ë: daux02_font1_dx2d.zip>

 

 

3.2.2 3D ¹®ÀÚ¿­

D3D´Â È®Àå À¯Æ¿¸®Æ¼·Î 3D ÆùÆ®µµ Áö¿øÇÕ´Ï´Ù. D3DXCreateText() ÇÔ¼ö¸¦ »ç¿ëÇϸé 3D·Î ¹®ÀÚ¿­À» ¸¸µé ¼ö ÀÖ½À´Ï´Ù. ±×·¯³ª ÀÌ ÇÔ¼ö´Â ÇÑ±Û ¹®ÀÚ¿­À» Ãâ·ÂÇÒ ¶§´Â À¯´ÏÄÚµå(Unicode)¸¦ »ç¿ëÇϰųª ´ÙÀ½°ú °°ÀÌ MultiByteToWideChar() ÇÔ¼ö¸¦ »ç¿ëÇØ¼­ ¹®ÀÚ¿­À» À¯´ÏÄÚµå·Î ¸¸µé¾î¾ß Ãâ·ÂÀÌ µË´Ï´Ù.

D3DXCreateText() ÇÔ¼ö´Â ¶ÇÇÑ À©µµ¿ì DC(Device Context)¸¦ Àμö·Î ¹Þ°í ÀÖ¾î ¹®ÀÚ¿­ Ãâ·ÂÀ» À§ÇØ API ¹æ½ÄÀ¸·Î CreateFont() ÇÔ¼ö ¶Ç´Â CreateFontIndirect() ÇÔ¼ö·Î ¼­Ã¼¿¡ ´ëÇÑ FONT °´Ã¼¸¦ ¸¸µç ´ÙÀ½, DC¿¡ ¿¬°áÇÑ ÈÄ¿¡ D3DXCreateText()¸¦ È£ÃâÇØ¾ß ÇÔÀ» ÀǹÌÇÕ´Ï´Ù.

´ÙÀ½ ÄÚµå´Â 3D ¹®ÀÚ¿­À» Ãâ·ÂÇÏ´Â ¿¹ÀÔ´Ï´Ù.

 

// 3D ¹®ÀÚ¿­ Ãâ·Â °´Ã¼

LPD3DXMESH     m_pMshStr;

¡¦

// DC »ý¼º

HDC hdc = CreateCompatibleDC( NULL );

HFONT hFontNew = NULL;

HFONT hFontOld = NULL;

 

LOGFONT hfont={0};

hfont.lfHeight      = 32;

¡¦

_tcscpy(hfont.lfFaceName, _T("08¼­¿ï³²»êü B"));

 

hFontNew = CreateFontIndirect(&hfont);

hFontOld = (HFONT)SelectObject(hdc, hFontNew);

 

 

char    sSrc[256] = "¾È³çÇϼ¼¿ä  Hello world !!! \0";

WCHAR sDst[256]={0};

 

// ¸ÖƼ ¹ÙÀÌÆ®¸¦ À¯´ÏÄÚµå·Î º¯°æ

LcStr_AnsiToUnicode(sDst, sSrc, strlen(sSrc)+1);

 

// 3D ¹®ÀÚ¿­À» »ý¼º

D3DXCreateTextW(m_pDev, hdc, sDst, 200.f, 3.f, &m_pMshStr, 0, 0);

 

SelectObject(hdc, hFontOld);

DeleteObject( hFontNew);

 

// DC ÇØÁ¦

DeleteDC( hdc );

 

LcStr_AnsiToUnicode() ÇÔ¼ö´Â À¯´ÏÄÚµå·Î ¹®ÀÚ¿­À» ¹Ù²Ù¾îÁÖ´Â »ç¿ëÀÚ Á¤ÀÇ ÇÔ¼ö ÀÔ´Ï´Ù.

 

<3D ¹®ÀÚ¿­ Ãâ·Â: daux02_font2_dx3d.zip>

 

 

3.2.3 ÈÄ¸é ¹öÆÛ(Back Buffer) Ãâ·Â

ID3DXFont´Â »ç¿ëÀÌ Æí¸®ÇÕ´Ï´Ù. ±×·¯³ª ¹®ÀÚ¿­ÀÌ ¸¹¾ÆÁö¸é ·»´õ¸µ ¼Óµµ°¡ »ó´çÈ÷ ´À·ÁÁý´Ï´Ù. ¸¸¾à ¹®ÀÚ¿­ÀÌ È­¸é °¡µæÇصµ ÃÖ´ë ¼Óµµ¸¦ ¿øÇÑ´Ù¸é ÈÄ¸é ¹öÆÛ¿¡ Á÷Á¢ Ãâ·ÂÇÏ´Â ¹æ¹ýÀÌ ÀÖ½À´Ï´Ù.

D3D9Àº ¾ËÆÄ°¡ ¾ø´Â ºÒÅõ¸í ¼­Çǽº(Surface), D3DFMT_R5G6B5, D3DFMT_X1R5G5B5, D3DFMT_R8G8B8, D3DFMT_X8R8G8B8 Çü½ÄÀ¸·Î ¸¸µç ¼­Çǽº¿¡ ´ëÇØ¼­ DC¸¦ °¡Á®¿Ã ¼ö ÀÖ°Ô Çß½À´Ï´Ù.  D3DPRESENT_ PARAMETERS ±¸Á¶Ã¼ º¯¼ö BackBufferFormat¸¦ X8R8G8B8 ¶Ç´Â D3DFMT_R5G6B5·Î ÁöÁ¤Çϰí Flags º¯¼ö ¶ÇÇÑ D3DPRESENTFLAG_LOCKABLE_BACKBUFFER À¸·Î ÁöÁ¤À» ÇØ¾ß¸¸ ÈÄ¸é ¹öÆÛ¿¡¼­ DC¸¦ °¡Á®¿Ã ¼ö ÀÖ½À´Ï´Ù.

 

m_d3dpp. BackBufferFormat = D3DFMT_X8R8G8B8;

m_d3dpp.MultiSampleType         = D3DMULTISAMPLE_NONE;

m_d3dpp.Flags = D3DPRESENTFLAG_LOCKABLE_BACKBUFFER;

 

ÈÄ¸é ¹öÆÛÀÇ DC´Â ¾Æ¹« ¶§³ª »ç¿ëÇÒ ¼ö ÀÖ´Â °ÍÀÌ ¾Æ´Ï¶ó ´ÙÀ½°ú °°ÀÌ BeginScene()/EndScene() ¹Û¿¡¼­¸¸ »ç¿ëÇØ¾ß ÇÕ´Ï´Ù.

 

m_pd3dDevice->BeginScene();

¡¦

m_pd3dDevice->EndScene();

 

LPDIRECT3DSURFACE9     pBackBuffer = NULL;

m_pd3dDevice->GetBackBuffer( 0, 0, D3DBACKBUFFER_TYPE_MONO, &pBackBuffer );

if(pBackBuffer)

{

        HDC hDC = NULL;

        pBackBuffer->GetDC(&hDC);

        if(hDC)

        {

               HFONT   hFontOld = NULL;

               hFontOld = (HFONT)SelectObject(hDC, m_hFont);

               ¡¦

               TextOut(hDC, 10, 200, "Ãâ·Â ¹®ÀÚ¿­", strlen("Ãâ·Â ¹®ÀÚ¿­"));

               SelectObject(hDC, hFontOld);

               DeleteDC( hDC );

               pBackBuffer->ReleaseDC(hDC);

        }

        pBackBuffer->Release();

 

< ÈÄ¸é ¹öÆÛ DC¿¡ ¹®ÀÚ¿­ Ãâ·Â: daux02_font3_backbuffer.zip>

 

»ó´çÈ÷ ºü¸£°Ô µ¿ÀÛÇÏÁö¸¸ ¹®Á¦´Â Flags º¯¼ö¸¦ D3DPRESENTFLAG_LOCKABLE_BACKBUFFER À¸·Î ¼³Á¤Çϸé Anti-AliasingÀÌ Áö¿øÀÌ ¾ÈµË´Ï´Ù. ¶ÇÇÑ BeginScene()/EndScene() ¹Û¿¡¼­ ó¸®ÇØ¾ß ÇϹǷΠ¹®ÀÚ¿­ Ãâ·ÂÀ» À§Çؼ­ Àüü ½Ã½ºÅÛ ÀÚü¸¦ ¹Ù²Ù¾î¾ß ÇÏ´Â ¹®Á¦µµ ÀÖ½À´Ï´Ù. ÀÌ ¸ðµç °ÍÀ» °¨¼öÇØµµ °¡Àå Å« ¹®Á¦´Â Èĸé¹öÆÛ¿¡ Á÷Á¢ Ãâ·ÂÀÌ µÇ¾î °ÔÀÓ ¾È ¿©·¯ ÆË¾÷ âÀÇ Overlap¿¡¼­ ¸ðµç ¹®ÀÚ°¡ ¾ÕÀ¸·Î º¸ÀÌ´Â ¹®Á¦¸¦ Á¦¾îÇϱⰡ ¾î·Æ½À´Ï´Ù.

 

 

3.2.4 ÅØ½ºÃ³¸¦ ÀÌ¿ëÇÑ Ãâ·Â

ID3DXFont´Â ¹®ÀÚ¿­ÀÌ ¸¹¾ÆÁö¸é ³»ºÎ ¹öÆÛ¸¦ °»½ÅÇϴ Ƚ¼öµµ Áõ°¡ÇØ ·»´õ¸µÀÌ ´À·ÁÁö´Â °ÍÀÔ´Ï´Ù. ¾Õ¼­ ºÒÅõ¸íÇÑ ¼­Çǽº¿¡ ´ëÇØ¼­ D3D9´Â DC¸¦ °¡Á®¿Í »ç¿ëÇÒ ¼ö ÀÖ´Ù°í Çß½À´Ï´Ù. À̰ÍÀ» Àß ÀÌ¿ëÇϸé ÀÚÁÖ °»½ÅÀÌ ¾È µÇ´Â ¹®ÀÚ¿­À» ÅØ½ºÃ³¿¡ Ãâ·ÂÇØ °¡Áö°í ÀÖ´Ù¸é ·»´õ¸µÀÇ ¼Óµµ´Â ºÐ¸íÈ÷ Áõ°¡ÇÒ °ÍÀÔ´Ï´Ù.

ÅØ½ºÃ³¿¡ ¹®ÀÚ¿­À» Ãâ·ÂÇϱâ À§ÇØ ´ÙÀ½°ú °°ÀÌ FONT °´Ã¼, ÅØ½ºÃ³, ¼­Çǽº¸¦ ÁغñÇÕ´Ï´Ù.

 

HFONT                  m_hFont;

LPDIRECT3DTEXTURE9     m_pTex;

LPDIRECT3DSURFACE9     m_pSfc;

 

´ÙÀ½À¸·Î ÆùÆ® °´Ã¼¸¦ ¸¸µé°í ÅØ½ºÃ³´Â D3DFMT_X8R8G8B8 Çü½ÄÀ¸·Î ¸¸µì´Ï´Ù. ÅØ½ºÃ³ °´Ã¼¸¦ ¸¸µç ÈÄ¿¡ ¼­Çǽº¸¦ ÅØ½ºÃ³¿¡¼­ °¡Á® ¿É´Ï´Ù. ÀÌ ºÎºÐÀº daux02_font4_tex.zipÀÇ CMain::Init()¿¡ ±¸ÇöµÇ¾î ÀÖ½À´Ï´Ù.

 

// 1. ÆùÆ® °´Ã¼ »ý¼º

LOGFONT logf={0};

logf.lfHeight = 32;

¡¦

_tcscpy(logf.lfFaceName, _T("±Ã¼­"));

m_hFont = CreateFontIndirect(&logf);

 

// 2. ÅØ½ºÃ³ »ý¼º

hr = D3DXCreateTexture(¡¦, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &m_pTex);

 

// 3. ¼­Çǽº °¡Á®¿È

m_pTex->GetSurfaceLevel(0, &m_pSfc);

 

ÅØ½ºÃ³¸¦ »ý¼ºÇÒ ¶§ ¹Ó(Mip) ·¹º§À» 1·Î Çϰí, À©µµ¿ì Àüȯ¿¡µµ ¹®Á¦ ¾øµµ·Ï ¸Þ¸ð¸® Ç®À» MANAGED·Î ¼³Á¤ÇÏ´Â °ÍÀÌ ÁÁ½À´Ï´Ù. ÀÌÁ¦ ¼­Çǽº¿¡¼­ DC¸¦ ¾ò°í ¹®ÀÚ¿­À» Ãâ·ÂÇÏ¸é µË´Ï´Ù. ´ÙÀ½ ÄÚµå´Â daux02_font4_tex.zipÀÇ CMain::FrameMove() ÇÔ¼ö¿¡ ±¸ÇöµÇ¾î ÀÖ½À´Ï´Ù.

 

// ÅØ½ºÃ³ ¼­ÇǽºÀÇ DC¿¡ ¹®ÀÚ¿­ Ãâ·Â

if(m_pSfc)

{

        HDC hDC = NULL;

        m_pSfc->GetDC(&hDC);

        if(hDC)

        {

               TCHAR sMsg[256] = "";

               sprintf( sMsg, "ÅØ½ºÃ³ DC¿¡ ¹®ÀÚ¿­ Ãâ·ÂÀÔ´Ï´Ù");

               HFONT hFontOld = (HFONT)SelectObject(hDC, m_hFont);

               SetBkMode(hDC, TRANSPARENT);

               SetTextColor(hDC, RGB(255, 0, 255));

               TextOut(hDC, 50, 50, sMsg, strlen(sMsg));

¡¦

               SelectObject(hDC, hFontOld);

               DeleteDC( hDC );

               m_pSfc->ReleaseDC(hDC);

        }

}

 

< ¼­ÇǽºÀÇ DC¿¡ ¹®ÀÚ Ãâ·Â: daux02_font4_tex.zip>

 

 

3.2.5 ÅØ½ºÃ³ Ãâ·Â¿¡ ´ëÇÑ ÆùÆ® Ŭ·¡½º

ÀÌÁ¦ ÅØ½ºÃ³¿¡ Ãâ·ÂÀÌ µÈ´Ù´Â °ÍÀ» ¾Ë¾Ò½À´Ï´Ù. ³²Àº °ÍÀº ÀÌ ³»¿ëÀ» ID3DXFontó·³ »ç¿ëÇÏ±â Æí¸®ÇÏ°Ô Å¬·¡½º·Î ¸¸µå´Â ÀÏÀÔ´Ï´Ù. daux02_lnfont_2d.zipÀÇ CLnFont2D Ŭ·¡½º´Â ÅØ½ºÃ³¿¡ ¹®ÀÚ¿­À» Ãâ·ÂÇϴ Ŭ·¡½º ÀÔ´Ï´Ù.

CLnFont2D Ŭ·¡½ºÀÇ ¼±¾ð¿¡ º¸¸é ¹®ÀÚ¿­À» Æ÷ÇÔÇÏ´Â ÅØ½ºÃ³´Â ´ÙÀ½°ú °°ÀÌ ¼±¾ðµÇ¾î ÀÖ½À´Ï´Ù.

 

LPDIRECT3DTEXTURE9     m_pTxD; // Output Texture

 

º¸Åë ¹®ÀÚ¿­ ÀÌ¿ÜÀÇ °ø°£Àº ÀüºÎ Åõ¸íÇÏ°Ô ÇØ¾ß ÇÕ´Ï´Ù. ±×·±µ¥ ¼­Çǽº¿¡¼­ DC¸¦ °¡Á®¿Ã ¼ö ÀÖ´Â °ÍÀº ºÒÅõ¸í ÅØ½ºÃ³ ¹Û¿¡ ¾ø½À´Ï´Ù. ¹®ÀÚ¿­ÀÇ ¹è°æÀ» Åõ¸íÇÏ°Ô ¸¸µé±â À§Çؼ­ ¸ÕÀú Àӽ÷ΠºÒÅõ¸í ÅØ½ºÃ³¸¦ ¸¸µé°í ÀÌ ºÒÅõ¸í ÅØ½ºÃ³ÀÇ DC¿¡ ¹®ÀÚ¿­À» Ãâ·ÂÇÕ´Ï´Ù. ´ÙÀ½À¸·Î ¾ËÆÄ°¡ ÀÖ´Â Ãâ·Â¿ë ÅØ½ºÃ³¸¦ ¸¸µé¾î¼­ ºÒÅõ¸í ÅØ½ºÃ³ ÀüºÎ¸¦ º¹»çÇÕ´Ï´Ù.

CLnFont2D::SetTexture() ÇÔ¼ö´Â ¹Ù·Î ÀÌ·± ÀÏÀ» ó¸®ÇÕ´Ï´Ù. ÀÌ ÇÔ¼öÀÇ Äڵ带 ¼³¸íÇÏ¸é ¸ÕÀú ´ÙÀ½°ú °°ÀÌ ºÒÅõ¸í ÅØ½ºÃ³, ÀÌ ºÒÅõ¸í ÅØ½ºÃ³¿¡ ´ëÇÑ ¼­Çǽº, Ãâ·Â¿ë ÅØ½ºÃ³¿¡ ´ëÇÑ ¼­Çǽº¸¦ ÁغñÇÕ´Ï´Ù.

 

LPDIRECT3DTEXTURE9     pTxS    = NULL;        // ºÒÅõ¸í ÅØ½ºÃ³

LPDIRECT3DSURFACE9     pSfTxtS = NULL;        // ºÒÅõ¸í ÅØ½ºÃ³ÀÇ ¼­Çǽº

LPDIRECT3DSURFACE9     pSfTxtD = NULL;        // Ãâ·Â¿ë ÅØ½ºÃ³ m_pTxDÀÇ ¼­Çǽº

 

´ÙÀ½À¸·Î ºÒÅõ¸í ÅØ½ºÃ³¸¦ ¹®ÀÚ¿­ÀÇ Æø°ú ³ôÀ̸¸Å­ ÅØ½ºÃ³¸¦ ¸¸µé°í ¼­Çǽº¸¦ °¡Á®¿É´Ï´Ù.

¹®ÀÚ¿­ ³ôÀÌ¿Í ÆøÀº CLnFont2D::SetString(TCHAR* sStr) ÇÔ¼ö¿¡¼­ GetTextExtentPoint32() ÇÔ¼ö¿Í GetTextMetrics() ÇÔ¼ö¸¦ ÅëÇØ¼­ °è»êÇÕ´Ï´Ù.

 

D3DXCreateTexture(¡¦, D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &pTxS);     // ºÒÅõ¸í Texture »ý¼º

pTxS->GetSurfaceLevel(0, &pSfTxtS);

 

ÀÌ ºÒÅõ¸í ÅØ½ºÃ³ÀÇ DC ¸¦ ¾ò°í ¹®ÀÚ¿­À» ¾¹´Ï´Ù.

 

pSfTxtS->GetDC(&hDC);

TextOut(hDC, ¡¦, m_sStr, m_iLen);

 

¸¶Áö¸· ´Ü°è¿¡¼­ ¾ËÆÄ°¡ ÀÖ´Â Ãâ·Â¿ë ÅØ½ºÃ³¸¦ ´Ù½Ã »ý¼ºÇÏ°í ºÒÅõ¸í ÅØ½ºÃ³¿¡¼­ ¾ËÆÄ°¡ ÀÖ´Â Ãâ·Â¿ë ÅØ½ºÃ³·Î D3DXLoadSurfaceFromSurface() ÇÔ¼ö¸¦ ÀÌ¿ëÇØ¼­ ÀüºÎ º¹»ç¸¦ ÇÕ´Ï´Ù. ÀÌ ¶§ ¿ÏÀü ºÒÅõ¸í °ËÁ¤»ö(0xFF000000)À» Åõ¸í °ªÀ¸·Î ¼³Á¤ÇÕ´Ï´Ù.

 

D3DXCreateTexture(¡¦, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &m_pTxD); // ¹ÝÅõ¸í ÅØ½ºÃ³ »ý¼º

¡¦

m_pTxD->GetSurfaceLevel(0, &pSfTxtD);

D3DXLoadSurfaceFromSurface( pSfTxtD, ¡¦, pSfTxtS, D3DX_DEFAULT, 0xFF000000);

 

0xFF000000 »ö»ó °ªÀ» Åõ¸í Ű·Î ¸¸µé¾î¼­ ÇϳªÀÇ »ö»ó(0xFF000000)À» »ç¿ëÇÒ ¼ö ¾øÁö¸¸ ÀüüÀûÀ¸·Î ÅØ½ºÃ³¸¦ ÀÌ¿ëÇϰí À־ ¹®ÀÚ¿­ÀÌ ÀÚÁÖ ¹Ù²îÁö ¾Ê´Â ÇÑ ´Ù¸¥ ¾î¶² ¹æ¹ýº¸´Ù ·»´õ¸µ ¼Óµµ°¡ ¿ì¼öÇÏ´Ù°í ÇÒ ¼ö ÀÖ½À´Ï´Ù. ¶ÇÇÑ ÀÚÁÖ º¯ÇÏ´Â ¹®ÀÚ¿­À» µû·Î °ü¸®Çؼ­ ÀÌ¿¡ ÀÇÇÑ ·»´õ¸µ ¼Óµµ ÀúÇϸ¦ ¸·À» ¼ö ÀÖ½À´Ï´Ù. ¿¹¸¦ µé¸é äÆÃ°ú °°Àº ÀÚÁÖ ¹®ÀÚ¿­ÀÌ °»½ÅµÇ°í È­¸é ½ºÅ©·ÑÀÌ ÇÊ¿äÇÑ ¹®ÀÚ¿­¿¡ ´ëÇØ¼­ °¢ ¹®ÀÚ¿­ ¶óÀÎ º°·Î ÅØ½ºÃ³¸¦ ¸¸µé¾î¼­ ¹®ÀÚ¿­À» Ãâ·ÂÇØ °ü¸®ÇÏ¸é ¹®ÀÚ¿­¿¡ ÀÇÇÑ ¼Óµµ ÀúÇϸ¦ ¸·À» ¼ö ÀÖ½À´Ï´Ù.

¿Ü°û¼± ÃßÃâ ¾Ë°í¸®Áò ¾øÀÌ 9¹øÀ» DC¿¡ ½á¼­ °£´ÜÇÏ°Ô ¹®ÀÚ¿­¿¡ Å׵θ®¸¦ ¸¸µé ¼öµµ ÀÖ½À´Ï´Ù. ±×¸®°í ÀÌ·± ¹æ½ÄÀ» Direct3DMobile¿¡ Àû¿ëÀ» Çϸé Çѱ۰ú °°Àº 2Byte ¹®ÀÚ¿­À» ½±°Ô Ãâ·ÂÇÒ ¼ö ÀÖ½À´Ï´Ù.

´ÙÀ½ ±×¸²Àº ÅØ½ºÃ³¿¡ ¹®ÀÚ¿­À» Ãâ·ÂÇØ¼­ ¸¸µç ¿¹Á¦ ÀÔ´Ï´Ù.

 

 

<ÅØ½ºÃ³¿¡ ¹®ÀÚ¿­ Ãâ·Â Ŭ·¡½º: daux02_lnfont_2d.zip, daux02_lnfont_3d.zip>

 

DXSDK 2003 summer ¹öÀü±îÁö ¿¹Á¦ Áß¿¡ CD3DFont Ŭ·¡½º°¡ ÀÖ¾ú½À´Ï´Ù. ÀÌ Å¬·¡½º´Â ¾Æ½ºÅ° (ASCII) Äڵ忡 ´ëÇØ¼­¸¸ Ãâ·ÂÇϰí ÀÖ½À´Ï´Ù. ±×·±µ¥ Àç¹ÌÀÖ´Â °ÍÀº ¾Æ½ºÅ° ¹®ÀÚ¿­ Áß¿¡¼­ Ư¼ö ¹®ÀÚ¸¦ Á¦¿ÜÇÏ°í ¾Æ½ºÅ° ¹øÈ£ 32(space) ~ 126±îÁö ¹®ÀÚµéÀ» ÅØ½ºÃ³¿¡ ¹Ì¸® ¸¸µé¾î ³õ°í, ¹®ÀÚ¿­Ãâ·ÂÀ» ¿äûÇϸé È­¸é À§Ä¡¿¡ ÇÑ ±ÛÀÚ¾¿ Ãâ·ÂÀ» ÇÕ´Ï´Ù. ÀÌ ¹æ¹ýÀº OpenGL¿¡¼­µµ ºñ½ÁÇÏ°Ô ÀÌ¿ëÇÏ´Â ¹æ¹ýÀÌ´Ï ³ªÁß¿¡ ½Ã°£ÀÌ ÀÖÀ¸¸é µé¿©´Ù º¸±â ¹Ù¶ø´Ï´Ù.

 

 

3.3 FPS (Frames Per Second)

2D °ÔÀÓ ÇÁ·Î±×·¡¹Ö¿¡¼­ Frame °è»êÀ» ¹è¿ü½À´Ï´Ù. ÇÁ·¹ÀÓ °è»êÀº Æò±ÕÀ» ÀÌ¿ë 1ÃÊ µ¿¾È È­¸é¿¡ ·»´õ¸µ Çϴ Ƚ¼ö¸¦ °è»ê ÇÕ´Ï´Ù. µû¶ó¼­ °¡Àå Á¤È®ÇÑ ½Ã°£À» »ç¿ëÇØ¾ß ÇÁ·¹ÀÓµµ Á¤È®È÷ °è»ê µÉ ¼ö ÀÖ½À´Ï´Ù.

À©µµ¿ì ½Ã½ºÅÛÀº ½Ã°£ ÃøÁ¤À» À§ÇØ GetTickCount()¿Í timeGetTime() ÇÔ¼ö°¡ Á¸Àç ÇÕ´Ï´Ù. ±×·±µ¥ ¸¸¾à À©µµ¿ì ½Ã½ºÅÛÀ» »ç¿ëÇÏÁö ¾Ê´Â ¸ð¹ßÀÏ ½Ã½ºÅÛ °°Àº °æ¿ì¿¡´Â C-Library¸¦ »ç¿ëÇÒ ¼ö ¹Û¿¡ ¾ø´Â °æ¿ìµµ ÀÖ½À´Ï´Ù. ÀÌ ¶§ timeGetTime() ´ë½Å clock() ÇÔ¼ö¸¦ »ç¿ëÇÕ´Ï´Ù.

clock()ÇÔ¼ö´Â ´ë·« 1/CLOCKS_PER_SEC Á¤µµÀÇ Á¤È®µµ¸¦ °¡Áö¸ç À©µµ¿ì ½Ã½ºÅÛ ½Ã°£ º¸´Ù Á¤È®µµ´Â ¸¹ÀÌ ¶³¾îÁö´Â ÆíÀÌÁö¸¸ C ¾ð¾î°¡ Áö¿øµÇ´Â ¾î¶² Ç÷§Æû¿¡¼­µµ »ç¿ëÇÒ ¼ö ÀÖ°í ÇÁ·¹ÀÓÀÌ ³ôÁö ¾ÊÀº °æ¿ì¿¡´Â ´ë¾ÈÀ¸·Î »ç¿ëÇÒ ¼ö ÀÖ½À´Ï´Ù.

 

´ÙÀ½Àº clock()ÇÔ¼ö¸¦ »ç¿ëÇØ¼­ ÇÁ·¹ÀÓÀÇ Æò±ÕÀ» °è»êÇÏ´Â ÄÚµå ÀÔ´Ï´Ù.

 

FLOAT UseClock()

{

        static DOUBLE  fFps = 0.;

        static INT     iCnt = 0;

        static clock_t dBgn = clock();

        clock_t dCur = clock();

        ++iCnt;

 

        if(iCnt>=MaxCount)

        {

               fFps = DOUBLE(dCur - dBgn);

               fFps = iCnt*1000./fFps;

               iCnt = 0;

               dBgn = dCur;

        }

        return (FLOAT)fFps;

}

 

°°Àº Äڵ忡 ½Ã°£ È£Ãâ ÇÔ¼ö¸¦ À©µµ¿ìÀÇ timeGetTime(), ¶Ç´Â GetTickCount()¸¦ clock() ÇÔ¼ö ÀÚ¸®¿¡ ¹Ù²Ù¾î ³õÀ¸¸é À©µµ¿ì ½Ã½ºÅÛ¿¡¼­ Àß µ¿ÀÛÇÏ´Â ÇÁ·¹ÀÓ °è»ê ÇÔ¼ö°¡ µË´Ï´Ù.

 

FLOAT UseTimeGetTime()

{

        static DOUBLE  fFps = 0.;

        static INT     iCnt = 0;

        static DWORD   dBgn = timeGetTime();

        DWORD   dCur = timeGetTime();  // GetTickCount()

        ++iCnt;

 

        if(iCnt>=MaxCount)

        {

               fFps = DOUBLE(dCur-dBgn);

               fFps = iCnt*1000./fFps;

               iCnt = 0;

               dBgn = dCur;

        }

        return (FLOAT)fFps;

}

 

¸¸¾à Intel CPU¸¦ ´ë»óÀ¸·Î ÇÑ´Ù¸é ´ÙÀ½ÀÇ GetIntelPrecisionTime() ÇÔ¼ö¿Í °°ÀÌ Inline Assembly¸¦ ÀÌ¿ëÇØ¼­ 1/1,000,000 ÃÊ ´ÜÀ§ÀÇ °íÇØ»óµµ(High-Resolution) ½Ã°£À» ÃøÁ¤ÇÒ ¼ö ÀÖ½À´Ï´Ù. ÀÌ ÇÔ¼ö´Â clock() ¶Ç´Â GetTickCount() °ú ºñ½ÁÇÑ µ¿ÀÛÀ» À§ÇØ ÀÛ¼º µÇ¾ú½À´Ï´Ù. ½Ã°£ÀÇ Á¤¹Ðµµ¸¦ À§ÇØ double ÇüÀ» »ç¿ëÇϰí ÀÖÀ½À» ÁÖÀÇÇϱ⠹ٶø´Ï´Ù.

 

DOUBLE GetIntelPrecisionTime()

{

        #define cpuid __asm __emit 0fh __asm __emit 0a2h

        #define rdtsc __asm __emit 0fh __asm __emit 031h

 

        static LARGE_INTEGER   Freq ={0};

        static BOOL            bEnable = 1;

        LARGE_INTEGER          dCur ={0};

        DOUBLE                 dTime =0;

 

        if(0 == bEnable)

               return -1;

 

        if(0 == Freq.QuadPart)

        {

               bEnable = QueryPerformanceFrequency(&Freq);

               if(0 == bEnable)

                       return -1;

        }

 

        __asm

        {

               cpuid

               rdtsc

               mov dCur.LowPart, eax

               mov dCur.HighPart, edx

        }

 

        dTime = DOUBLE(dCur.QuadPart)/DOUBLE(Freq.QuadPart);

        dTime *=1000.;

        return  dTime;

}

 

ÀÌÀüÀÇ ÇÁ·¹ÀÓ °è»ê¿¡¼­ clock(), ¶Ç´Â timeGetTime()À» GetIntelPrecisionTime () ÇÔ¼ö·Î ¹Ù²Ù¸é ÀÎÅÚ Ä¨ÀÇ °íÇØ»óµµ ŸÀ̸Ӹ¦ ÀÌ¿ëÇÑ ÇÁ·¹ÀÓ °è»ê ÇÔ¼ö°¡ µË´Ï´Ù.

 

FLOAT UseTimeGetPrecisionTime()

{

        static DOUBLE  fFps = 0.;

        static INT     iCnt = 0;

        static DOUBLE  dBgn = GetIntelPrecisionTime();

        DOUBLE  dCur = GetIntelPrecisionTime();

        ++iCnt;

 

        if(iCnt>=MaxCount)

        {

               fFps = dCur-dBgn;

               fFps = iCnt*1000./fFps;

               iCnt = 0;

               dBgn = dCur;

        }

        return (FLOAT)fFps;

}

 

À©µµ¿ì ½Ã½ºÅÛ¿¡¼­´Â °íÇØ»óµµ ŸÀ̸Ӹ¦ À§ÇÑ QueryPerformanceCounter()¿Í QueryPerformance-Frequency() ÇÔ¼ö°¡ ÀÖ½À´Ï´Ù. ¸¸¾à CPU¿¡¼­ °íÇØ»óµµ ŸÀ̸Ӹ¦ Áö¿øÀÌ µÇ¸é ÀÌ µÑÀÇ ÇÔ¼ö¸¦ »ç¿ëÇÏ´Â °ÍÀÌ ÁÁ½À´Ï´Ù.

¸ÕÀú QueryPerformanceFrequency() ÇÔ¼ö¸¦ °¡Áö°í Áøµ¿¼ö¸¦ °¡Á® ¿É´Ï´Ù. ¸¸¾à °¡Á®¿À±â°¡ ½ÇÆÐÇϸé 0À» ¹ÝȯÇÕ´Ï´Ù. ´ÙÀ½À¸·Î QueryPerformanceCounter() ÇÔ¼ö¸¦ »ç¿ëÇØ¼­ ¼öÇàÇÑ Counter¸¦ ¾ò¾î ¿É´Ï´Ù. ÀÌ °ªÀ» ¾Õ¿¡¼­ ±¸ÇÑ Áøµ¿¼ö·Î ³ª´©¸é ÇÁ·¹ÀÓÀÌ µË´Ï´Ù. ´ÙÀ½ ÇÔ¼ö´Â ÀÌ µÎ ÇÔ¼ö¸¦ »ç¿ëÇØ¼­ ÇÁ·¹ÀÓÀ» °è»êÇÏ´Â ÄÚµå ÀÔ´Ï´Ù.

 

FLOAT UsePerformanceCounter()

{

        static DOUBLE          fFps = 0.;

        static INT             iCnt = 0;

        static LARGE_INTEGER   Freq = {0};

        static LARGE_INTEGER   dBgn = {0};

        static BOOL            bEnable=1;

        LARGE_INTEGER  dCur = {0};

 

        if(0 == bEnable)

               return -1.f;           // Çϵå¿þ¾î Áö¿øÀÌ ¾ÈµÊ

 

        if(0 == Freq.QuadPart)        // ÃÖÃÊ ÇÔ¼ö È£Ãâ ½Ã

        {

               bEnable = QueryPerformanceFrequency( &Freq);

               if(0 == bEnable)

                       return -1.f;

 

               QueryPerformanceCounter(&dBgn);

        }

 

        QueryPerformanceCounter(&dCur);

        ++iCnt;

 

        if(iCnt>=MaxCount)

        {

               DOUBLE fElapsedTime =

 DOUBLE(dCur.QuadPart - dBgn.QuadPart)/ DOUBLE(Freq.QuadPart);

 

               fFps = iCnt/fElapsedTime;

               iCnt = 0;

               dBgn = dCur;

        }

        return (FLOAT)fFps;

}

 

QueryPerformanceCounter() ¿¡¼­ ¾òÀº °ªÀ» QueryPerformanceFrequency() ÇÔ¼ö¿¡¼­ ¾òÀº Áøµ¿¼ö·Î ³ª´©¸é ½Ã°£ÀÌ µÇ¾î timeGetTime()À» ´ë½ÅÇÒ ¼ö ÀÖ½À´Ï´Ù. ÀÌ ¶§ ÁÖÀÇÇÒ °ÍÀº °íÇØ»óµµ ŸÀÌ¸Ó´Â ÇØ»óµµ°¡ 1/1,000,000 ÃÊ ÀÔ´Ï´Ù. timeGetTime()Àº 1/1,000 ÃÊ ´ÜÀ§À̹ǷΠÀÌ µÑÀ» ¸ÂÃß·Á¸é °íÇØ»óµµ ŸÀ̸Ӻκп¡ 1000.0À» °öÇØ¾ß ¼­·Î°¡ µ¿ÀÏÇÑ ½Ã°£À» ¸¸µé¾î ÁÝ´Ï´Ù.

 

DOUBLE TimeGetPrecisionTime()

{

        static LARGE_INTEGER   Freq ={0};

        static BOOL            bEnable = 1;

        LARGE_INTEGER  dCur ={0};

        DOUBLE         dTime =0;

 

        if(0 == bEnable)

               return -1;

 

        if(0 == Freq.QuadPart)

        {

               bEnable = QueryPerformanceFrequency(&Freq);

 

               if(0 == bEnable)

                       return -1;

        }

 

        QueryPerformanceCounter(&dCur);

        dTime = DOUBLE(dCur.QuadPart)/DOUBLE(Freq.QuadPart);

        dTime *=1000.;

        return  dTime;

}

 

´ÙÀ½ ±×¸²Àº À̵é ÇÔ¼ö¸¦ ÀÌ¿ëÇØ¼­ ÇÁ·¹ÀÓ°ú ½Ã°£À» °è»êÇÑ °á°ú ÀÔ´Ï´Ù.

 

 

<30 ÇÁ·¹ÀÓ Æò±Õ, 4 ÇÁ·¹ÀÓ Æò±Õ: daux03_frame.zip>

 

ÇÁ·¹ÀÓÀ» °è»êÇϴµ¥ ´ë·« 30À» Æò±Õ Ƚ¼ö·Î ¼³Á¤ÇÑ °æ¿ì¿¡´Â ¿ÞÂÊó·³ °íÇØ»óµµ ¶Ç´Â ÀúÇØ»óµµ ŸÀ̸Ӹ¦ »ç¿ëÇØµµ °ÅÀÇ Â÷À̰¡ ¾ø½À´Ï´Ù. ±×·±µ¥ Ƚ¼ö¸¦ ÁÙÀ̸é ÇØ»óµµ°¡ ³·Àº clock(), timeGetTime() ÇÔ¼ö´Â °è»êÀÌ ¾û¸ÁÀÌ µË´Ï´Ù. µû¶ó¼­ ¾ÆÁÖ ºü¸¥ ½Ã½ºÅÛÀ» ´ë»óÀ¸·Î °ÔÀÓÀ» ¸¸µé °æ¿ì¿¡´Â °íÇØ»óµµ ŸÀ̸Ӹ¦ ÀÌ¿ëÇÏ´Â °ÍÀÌ À¯¸®ÇÒ °Í °°Áö¸¸ ²À ±×·¸Áöµµ ¾ÊÀº °ÍÀÌ ½ÇÁ¦·Î °ÔÀÓÀÇ ·»´õ¸µ ¼Óµµ´Â ÇÁ·Î±×·¡¸ÓµéÀÌ 15~60 »çÀÌ¿¡ ¸ÂÃß´Â °æÇâÀÌ ÀÖ½À´Ï´Ù. °ÔÀÓÀÌ 1000 ÇÁ·¹ÀÓ ÀÌ»ó ¾È µÇ´Â °æ¿ì¿¡´Â ¿©ÀüÈ÷ timeGetTime()°ú °°Àº ÇÔ¼ö·Î ÇÁ·¹ÀÓ °è»êÀ» ÇØµµ ÃæºÐÇÕ´Ï´Ù.

 

 

3.4 ÇÑ±Û IME

ÇÑ±Û ¹®ÀÚ¿­Àº ID3DXFont µîÀ» ÀÌ¿ëÇØ Ãâ·ÂÇÒ ¼ö ÀÖ¾ú½À´Ï´Ù. ±×·±µ¥ ÇÑ±Û ÀÔ·ÂÀº ¾î¶»°Ô ó¸®ÇÒ±î¿ä? ¿µ¾î´Â ¾Æ½ºÅ° ÄÚµå·Î GetAsyncKeyState() ÇÔ¼ö µîÀ» ÀÌ¿ëÇØ Áï½Ã 󸮰¡ °¡´ÉÇÏÁö¸¸ ÇѱÛÀÇ °æ¿ì ±ÛÀÚ¸¦ Á¶ÇÕÇØ¾ß ÇÕ´Ï´Ù.

À©µµ¿ì ½Ã½ºÅÛÀº ÀԷ±⠶Ǵ ÀÔ·Â ¹æ½Ä ÆíÁý±â¶ó´Â IME(Input Method Editor) ½Ã½ºÅÛÀ» ÀÌ¿ëÇØ¼­ ¾Æ½ºÅ° ÄÚµå ÀÌ¿ÜÀÇ ¹®ÀÚµéÀ» Á¶ÇÕÇϸç, IME¸¦ »ç¿ëÇϱâ À§Çؼ­´Â À©µµ¿ìÀÇ ¸Þ½ÃÁö ½Ã½ºÅÛÀ» ÀÌ¿ëÇØ¾ß ÇÕ´Ï´Ù.

 

¼ø¼ö Çѱ۸¸ Ãâ·ÂÇÏ´Â °æ¿ì¿¡ À©µµ¿ì ¸Þ½ÃÁö WM_IME_STARTCOMPOSITION, WM_IME_COMPOSITION, WM_CHAR ¼¼ °¡Áö¸¸ »ç¿ëÇÕ´Ï´Ù. WM_IME_STARTCOMPOSITION ¸Þ½ÃÁö´Â ÇÑ±Û ÀÔ·ÂÀ» ¸· ½ÃÀÛÇÒ ¶§, WM_IME_COMPOSITION´Â ±ÛÀÚ¸¦ Á¶ÇÕ ÁßÀÏ ¶§, WM_CHAR´Â ÇÑ±Û Á¶ÇÕ À̿ܿ¡ ¾Æ½ºÅ° Äڵ尡 ÀÔ·ÂµÉ ¶§ 󸮸¦ ÇÕ´Ï´Ù.

 

¸Þ½ÃÁö ÇÁ·Î½ÃÀú(Message Procedure) ÇÔ¼ö¿¡¼­ ¸ÕÀú ´ÙÀ½°ú °°ÀÌ WM_IME_STARTCOMPOSITION¿¡¼­ Á¶ÇÕÀÌ ½ÃÀÛ µÆÀ½À» ÀÎÁö ÇÕ´Ï´Ù. Äڵ忡¼­´Â ¾Æ¹« Àϵµ ¾È Çϰí Àִµ¥ ÇÊ¿äÇÏ´Ù¸é ¹º°¡¸¦ ³Ö¾îÁÖ´Â °Íµµ ÁÁ½À´Ï´Ù.

 

LRESULT CLcHangul::MsgProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam )

¡¦

        INT     len = 0;

        HIMC    hIMC= 0;

        WPARAM  wLo = LOWORD(wParam);

 

if(WM_IME_STARTCOMPOSITION == uMsg)

        return TRUE;

 

´ÙÀ½À¸·Î ±ÛÀÚ¸¦ Á¶ÇÕ ÁßÀÎ WM_IME_COMPOSITION ¸Þ½ÃÁö ó¸® ÀÔ´Ï´Ù. ±ÛÀÚ°¡ Á¶ÇÕ Áß ¶Ç´Â Á¶ÇÕÀÌ ¿Ï·á µÇ¸é ÀÌ ¸Þ½ÃÁö·Î ¿É´Ï´Ù. ¸ÕÀú IME ÇÚµéÀ» ImmGetContext()ÇÔ¼ö¸¦ ÅëÇØ¼­ °¡Á®¿É´Ï´Ù. ¹°·Ð ´Ù »ç¿ëÇßÀ¸¸é ImmReleaseContext() ÇÔ¼ö·Î ÀÚ¿øÀ» ¹Ý³³ ÇØ¾ß ÇÕ´Ï´Ù.

 

else if(WM_IME_COMPOSITION == uMsg)           // ±Û¾¾ Á¶ÇÕ Áß

¡¦

        hIMC = ImmGetContext(hWnd);           // Get IME Handle

 

¼ø¼­»óÀ¸·Î ±ÛÀÚÀÇ Á¶ÇÕ ÁßÀÎ °ÍÀ» ¸ÕÀú ó¸® ÇÏÁö ¾Ê°í Á¶ÇÕÀÌ ¿Ï·áµÈ °ÍÀ» ¸ÕÀú ó¸®ÇÕ´Ï´Ù. ¿Ï·á¿¡ ´ëÇÑ ÆÇ´ÜÀº LPARAM °ªÀ» GCS_RESULTSTR °ªÀ¸·Î ºñÆ® ¿¬»êÀ» ÅëÇØ¼­ ÆÇº°ÇÕ´Ï´Ù. ¿Ï·áµÈ ¹®ÀÚ¿­Àº ImmGetCompositionString() ÇÔ¼ö¸¦ µÎ ¹ø »ç¿ëÇØ¼­ ¾ò´Âµ¥ ¸ÕÀú IME ÇÚµé°ú GCS_RESULTSTR Àμö ¸¸À» ³Ö¾î¼­ ¹®ÀÚ¿­ÀÇ ±æÀ̸¦ ¾ò¾î ¿À°í ´ÙÀ½À¸·Î ÀÌ ±æÀÌ¿Í ¹öÆÛ¸¦ ¿¬°áÇØ¼­ ¹öÆÛ¸¦ ÅëÇØ¼­ ¹®ÀÚ¿­À» °¡Á® ¿É´Ï´Ù.

 

if (lParam & GCS_RESULTSTR)

¡¦

        len = ImmGetCompositionString(hIMC, GCS_RESULTSTR, NULL, 0); // Á¶ÇÕÀÌ ¿Ï·áµÈ ±æÀÌ

 

        if( 0 < len)

        {

               ImmGetCompositionString(hIMC, GCS_RESULTSTR, "¿Ï¼ºµÈ ¹®ÀÚ¿­ ¹öÆÛ", len);

¡¦

 

Á¶ÇÕ ÁßÀÎ ¹®ÀÚ¿­µµ È­¸é¿¡ Ãâ·ÂÀ» ÇØ¾ß ÇÕ´Ï´Ù. LPARAM °ª¿¡ GCS_COMPSTR °ªÀ¸·Î ºñÆ® ¿¬»êÀ» Çϸé Á¶ÇÕ ÁßÀÎÁö ¾Ë ¼ö ÀÖ½À´Ï´Ù. ¾ÕÀÇ ¿Ï·áµÈ ¹®ÀÚ¿­À» ¾òµíÀÌ ImmGetCompositionString() ÇÔ¼ö¸¦ µÎ ¹ø »ç¿ëÇØ¼­ Á¶ÇÕ ÁßÀÎ ¹®ÀÚ¿­À» ¾ò¾î ¿É´Ï´Ù. ÀÌ ¶§´Â GCS_RESULTSTR ´ë½Å GCS_COMPSTR °ªÀ» »ç¿ëÇØ¾ß ÇÕ´Ï´Ù.

±ÛÀÚ¸¦ ¹é ½ºÆäÀ̽º(Back Space) Ű·Î Áö¿ö¼­ Á¶ÇÕ ÁßÀÎ ±æÀ̸¦ 0À¸·Î ¸¸µé ¶§°¡ ÀÖ½À´Ï´Ù. ÀÌ °æ¿ì¿¡´Â Á¶ÇÕÁßÀÎ ¹öÆÛ¸¦ ¸»²ûÈ÷ ºñ¿ì´Â °ÍÀÌ ÁÁ½À´Ï´Ù.

 

else if (lParam & GCS_COMPSTR)

¡¦

        len = ImmGetCompositionString(hIMC, GCS_COMPSTR, NULL, 0); // Á¶ÇÕÁßÀÎ ±æÀÌ

              

               if(0==len)             // Á¶ÇÕ Áß¿¡ Back space°¡ ¿Â °æ¿ì

                       EraseWord();

               else

                       ImmGetCompositionString(hIMC, GCS_COMPSTR, m_sWrd, len);

 

ÇÑ±Û ÀÔ·ÂÀ» ´Ù ó¸® ÇßÀ¸¸é IME ÇÚµéÀ» ¹ÝȯÇÕ´Ï´Ù.

 

ImmReleaseContext(hWnd, hIMC);

 

Çѱ۰ú °°ÀÌ ¿µ¹®µµ Ãâ·ÂÇØ¾ß ÇϹǷΠIME ÀÛµ¿ÀÌ ¾Æ´Ò ¶§ ¾Æ½ºÅ° ¹®Àڵ鿡 ´ëÇØ¼­ WM_CHAR ¸Þ½ÃÁö¿¡¼­ ó¸®ÇÕ´Ï´Ù.

 

else if(WM_CHAR == uMsg)

¡¦

        if(wParam>=32 && wParam<127)

               m_sStr[strlen(m_sStr)] = wParam;

 

¾Æ½ºÅ° ¹®ÀÚµµ 0~31 ¹ø±îÁö´Â Åë½Å, Á¦¾î¿¡ °ü·ÃµÈ ¹®ÀÚÀÔ´Ï´Ù. À̵éÀº È­¸é¿¡ Ãâ·ÂÇÒ Çʿ䰡 ¾øÀ¸¹Ç·Î 32~126 »çÀÌÀÇ ¹®ÀÚ¸¸ Ãâ·ÂÇÏ°Ô ÇÕ´Ï´Ù.

 

<IME ÇѱÛ: daux04_IME_hangul.zip>

 

¿¹Á¦ daux04_IME_hangul.zipÀº IME¸¦ »ç¿ëÇØ¼­ ÇѱÛÀ» Ãâ·ÂÇÏ´Â ¿¹Á¦ ÀÔ´Ï´Ù. ÇѱÛÀ» ÀÔ·ÂÇÏ°í ¿£ÅÍ Å°¸¦ ´©¸£¸é À©µµ¿ì ŸÀÌÆ²¿¡ ÇØ´ç ¹®ÀÚ¿­À» Ãâ·ÂÇØ ÁÝ´Ï´Ù. ´Ù½Ã ÇÑ±Û ÀÔ·ÂÀ» »ç¿ëÇÏ·Á¸é ¿£ÅÍ Å°¸¦ ÇÑ ¹ø ´õ ´©¸£¸é µË´Ï´Ù.

 

 

3.5 Texture

3.5.1 ¹Ó¸Ê »ç¿ë ºñ±³

ÅØ½ºÃ³¸¦ ÆÄÀÏ¿¡¼­ ÀÐ¾î ¿À´Â ÇÔ¼ö´Â D3DXCreateTextureFromFileEx() ÇÔ¼ö¿Í D3DXCreateTexture-FromFile() ÇÔ¼ö¸¦ °¡Àå ¸¹ÀÌ »ç¿ëÇϰí ÀÖ½À´Ï´Ù. ¾Õ¼­ 2D °ÔÀÓ °­ÀÇ¿¡¼­ 2D °ÔÀÓÀÇ ÅØ½ºÃ³´Â D3DXCreateTextureFromFileEx() ÇÔ¼ö¸¦ »ç¿ëÇÑ´Ù°í Çß½À´Ï´Ù.

µµ¿ò¸»À» º¸¸é D3DXCreateTextureFromFile() ÇÔ¼ö´Â D3DXCreateTextureFromFileEx(pDevice, pSrcFile, D3DX_DEFAULT, D3DX_DEFAULT, D3DX_DEFAULT, 0, D3DFMT_UNKNOWN, D3DPOOL_MANAGED, D3DX_DEFAULT, D3DX_DEFAULT, 0, NULL, NULL, ppTexture)¿Í °°´Ù°í µÇ¾î ÀÖ½À´Ï´Ù.

 

ÅØ½ºÃ³ÀÇ ÇÊÅ͸µ¿¡¼­ ¿ì¸®´Â ¹Ó¸ÊÀ» ¹è¿ü½À´Ï´Ù. ¹Ó¸ÊÀº Anti-AliasingÀ» À§ÇØ ¿øº» ÅØ½ºÃ³¸¦ 2ÀÇ ½Â¼ö·Î ÇÏÀ§ ÅØ½ºÃ³ÀÇ Å©±â´Â 1/4¾¿ ÁÙ¿© ³ª°¡¸é¼­ ¸¸µç´Ù°í Çß½À´Ï´Ù. ¿øº» ÅØ½ºÃ³¿Í ÇÏÀ§ ÅØ½ºÃ³·Î ÀÎÇØ ´Ã¾î³­ ¸Þ¸ð¸®´Â µîºñ ¼ö¿­ÀÌ µÇ¾î ´ë·« ´ÙÀ½°ú °°ÀÌ °è»êÀÌ µË´Ï´Ù.

 

  ~ 1.33

 

 

ÀÌ °è»êÀº ¾à 33 %ÀÇ ¸Þ¸ð¸® Áõ°¡¸¦ º¸À̰í ÀÖ½À´Ï´Ù. ½ÇÁ¦·Îµµ ºñ½ÁÇÑ °á°ú°¡ µÇ´ÂÁö »ìÆì º¾½Ã´Ù.

daux05_texture1_mipmap.zip ´Â ¹Ó¸Ê°ú ¹Ó¸Ê ·¹º§À» 1·Î ÇÒ ¶§¿¡ »ç¿ëÇÏ´Â ¸Þ¸ð¸®¸¦ ºñ±³ Çϰí ÀÖ½À´Ï´Ù. ¸Þ¸ð¸® ºñ±³¸¦ À§Çؼ­ MEMORYSTATUS ŸÀÔÀÇ Àü¿ª º¯¼ö¸¦ ¼³Á¤Çϰí ÅØ½ºÃ³¸¦ »ý¼ºÇϱâ Àü¿¡ ÀÌ Àü¿ª º¯¼ö¿¡ ½Ã½ºÅÛÀÇ »ç¿ë ¸Þ¸ð¸®¸¦ GlobalMemoryStatus() ÇÔ¼ö¸¦ ÀÌ¿ëÇØ¼­ ±â·ÏÇÕ´Ï´Ù.

 

MEMORYSTATUS   g_MmSt;        // Àü¿ª º¯¼ö

¡¦

GlobalMemoryStatus(&g_MmSt);

 

´ë·« 100 Á¤µµ D3DXCreateTextureFromFileEx(), D3DXCreateTextureFromFile() ÇÔ¼ö·Î °°Àº ÆÄÀÏÀ» È£ÃâÇØ¼­ ÀÌ µÑÀÇ ¸Þ¸ð¸® »ç¿ëÀ» ºñ±³ÇØ º¸¸é ¹Ó¸Ê ·¹º§À» Ç®¾î ³õÀ¸¸é ¾à 30%Á¤µµ Áõ°¡ Çϰí ÀÖÀ½À» º¼ ¼ö ÀÖ½À´Ï´Ù.

3D´Â ¹Ó¸ÊÀÌ ÇÊ¿äÇÏÁö¸¸ 2D´Â ¹Ó¸ÊÀÌ ÀüÇô Çʿ䰡 ¾ø½À´Ï´Ù. µû¶ó¼­ ¹Ó¸Ê ·¹º§À» Á¶Á¤ÇÒ ¼ö ÀÖ´Â D3DXCreateTextureFromFileEx() ÇÔ¼ö¸¦ »ç¿ëÇϸé D3DXCreateTextureFrom-File() ÇÔ¼ö¸¦ »ç¿ëÇÒ ¶§º¸´Ù ¸Þ¸ð¸®¸¦ 30% Á¤µµ Àý¾àÇÒ ¼ö ÀÖ°Ô µË´Ï´Ù.

 

 

3.5.2 ÅØ½ºÃ³ ÆÄÀÏ Merge

ÆÄÀÏÀÇ º¸È£¸¦ À§ÇØ ¸ÓÁö(Merge: ÇÕº´)ÇÒ Çʿ䵵 ÀÖ½À´Ï´Ù. °£´ÜÇÑ ¸ÓÁö ¹æ¹ýÀº Àüü ÅØ½ºÃ³ÀÇ ¼ýÀÚ¸¦ ÆÄÀÏ¿¡ ±â·ÏÇÏ°í ¼øÂ÷ÀûÀ¸·Î ÆÄÀÏÀÇ À̸§, Å©±â, ½ÃÀÛ Æ÷ÀÎÅÍ, Á¾·á Æ÷ÀÎÅÍ ÅØ½ºÃ³ µ¥ÀÌÅ͸¦ ¹Ýº¹Çؼ­ ±â·ÏÇÕ´Ï´Ù.

 

<¿©·¯ °¡Áö ¸ÓÁö ¹æ¹ý>

 

Á» ´õ Çâ»óµÈ ±â¼úÀº ÆÄÀÏÀÇ À̸§, Å©±â, ½ÃÀÛÆ÷ÀÎÅÍ, Á¾·á Æ÷ÀÎÅÍ Á¤º¸¸¦ ¸ÕÀú ±â·ÏÇÑ ÈÄ¿¡ ÅØ½ºÃ³ÀÇ ÆÄÀÏÀ» Çì´õ¿¡ ±â·ÏµÈ ¼ø¼­´ë·Î ¸ÓÁö ÇÕ´Ï´Ù. ¾Æ´Ï¸é ÅØ½ºÃ³ ÆÄÀÏÀ» ¸ÕÀú ¸ÓÁö ÇÑ ÈÄ¿¡ ¸¶Áö¸·¿¡ ÆÄÀÏ Á¤º¸¸¦ ±â·ÏÇÏ´Â ¹æ¹ýµµ ÀÖ½À´Ï´Ù.

¾î¶² ¹æ½ÄÀ¸·Î ¸ÓÁö¸¦ ÇÏµç ´Ù½Ã ÀÌ ÆÄÀϵéÀ» Ç®¾î¼­ ÅØ½ºÃ³¸¦ »ý¼ºÇØ¾ß ÇÕ´Ï´Ù. ±×·±µ¥ ÅØ½ºÃ³¸¦ Àӽà Æú´õ¿¡ Ç®¾î¼­ D3DXCreateTextureFromFile(0 ÇÔ¼ö µîÀ¸·Î ÅØ½ºÃ³¸¦ »ý¼ºÇÏ°Ô µÇ¸é ÇÏµå µð½ºÅ©¸¦ »ç¿ëÇÏ°Ô µÇ¾î ÆÄÀÏÀÌ ¸¹Àº °æ¿ì ·Îµù¿¡ ½Ã°£ÀÌ ¸¹ÀÌ µì´Ï´Ù.

 

D3D´Â ÆÄÀÏ À̿ܿ¡ ¸Þ¸ð¸®, ¸®¼Ò½º¿¡¼­ ÅØ½ºÃ³¸¦ »ý¼ºÇÏ´Â ÇÔ¼ö°¡ ÀÖ½À´Ï´Ù.

D3DXCreateTextureFromFileInMemoryEx(),D3DXCreateTextureFromFileInMemory() ÇÔ¼ö´Â ¸Þ¸ð¸®¿¡¼­ ÅØ½ºÃ³¸¦ »ý¼ºÇϸç, D3DXCreateTextureFromResourceEx(),D3DXCreateTextureFromResource() ÇÔ¼ö´Â ÇÁ·Î±×·¥ÀÇ ¸®¼Ò½º¿¡¼­ ÅØ½ºÃ³¸¦ »ý¼ºÇÕ´Ï´Ù.

daux05_texture2_merge_file.zipÀº ¸ÓÁö¸¦ ÇÑ ÈÄ¿¡ 3DXCreateTextureFromFileInMemoryEx() ÇÔ¼ö·Î ¸Þ¸ð¸®¿¡¼­ ÅØ½ºÃ³¸¦ »ý¼ºÇÏ´Â ¿¹Á¦ ÀÔ´Ï´Ù.

 

¸ÓÁö¸¦ À§Çؼ­ °¢ ÆÄÀÏ¿¡ ´ëÇÑ Á¤º¸¸¦ ±â·ÏÇÒ ¼ö ÀÖµµ·Ï ´ÙÀ½°ú °°ÀÌ ÆÄÀÏ À̸§, Å©±â, ½ÃÀÛ Æ÷ÀÎÅÍ, ³¡ Æ÷ÀÎÅ͸¦ ÀúÀåÇÒ ¼ö Àִ Ŭ·¡½º°¡ ÇÊ¿äÇÕ´Ï´Ù.

 

struct MrgTx

{

        char    sFile[256];            // File Name

        int     iSize;                 // File Size

        int     iBgn;                  // Starting point

        int     iEnd;                  // End point

};

 

typedef std::vector<MrgTx* >  lsTx;

 

¸ÓÁö¸¦ ½ÇÇàÇÏ¸é ÆÄÀÏÀÇ Á¤º¸¸¦ ¸ÕÀú ¸ðÀ¸°í ±× ´ÙÀ½À¸·Î ÇϳªÀÇ ÆÄÀÏ¿¡ ±â·ÏÀ» ÇÕ´Ï´Ù. ¿©±â¼­´Â ¾ÕÀÇ ¸ÓÁö ¹æ¹ý ±×¸² Áß¿¡ °¡¿îµ¥ ºÎºÐ ±×¸²Ã³·³ ÆÄÀÏÀÇ °³¼ö, ÆÄÀÏÀÇ Á¤º¸, ÆÄÀÏ ³»¿ëÀ» ±â·ÏÇϰڽÀ´Ï´Ù. CMain::MergeFile() ÇÔ¼ö°¡ ´ÙÀ½°ú °°ÀÌ À̸¦ ±¸ÇöÇϰí ÀÖ½À´Ï´Ù.

 

¸ÕÀú ÆÄÀÏÀÇ Á¤º¸¸¦ Àоî¿Í ¸ÓÁö Á¤º¸¸¦ °¡Áö°í ÀÖ´Â º¤ÅÍ¿¡ ³Ö½À´Ï´Ù.

 

void CMain::MergeFile()

¡¦

lsTx    vTx;

 

// 1. Merge File Information

vTx.push_back(new MrgTx("Texture/seatosky1.jpg"));

vTx.push_back(new MrgTx("Texture/seatosky2.jpg",     vTx[vTx.size()-1]));

¡¦

 

´ÙÀ½À¸·Î ¸ÓÁö ÆÄÀÏÀ» »ý¼ºÇÏ°í ÆÄÀÏÀÇ °³¼ö¸¦ ±â·ÏÇÑ ´ÙÀ½º¤ÅÍ¿¡ ÀúÀåµÇ¾î ÀÖ´Â ÆÄÀϵéÀÇ Á¤º¸¸¦ ±â·ÏÇÕ´Ï´Ù.

 

int     iN=vTx.size();

BYTE*   pSrc;

FILE* fpDst = fopen("Texture/Merge.mrg", "wb");

¡¦

// 2. Write File Counter

fwrite(&iN, 1, sizeof(iN), fpDst);

 

// 3. Write File Information

for(i=0; i<iN; ++i)

{

        MrgTx* pTxF = vTx[i];

        fwrite(pTxF->sFile,    1, sizeof(pTxF->sFile), fpDst);

¡¦

}

 

´ÙÀ½À¸·Î ÆÄÀÏÀ» Åë°·Î Àоî¿Í¼­ ¸ÓÁö ÆÄÀÏ¿¡ ±â·ÏÇÕ´Ï´Ù.

 

// 5. Write File Data

for(i=0; i<iN; ++i)

{

        MrgTx* pTxF = vTx[i];

        fpSrc = fopen(pTxF->sFile, "rb");

        pSrc = new BYTE[pTxF->iSize];

        fread(pSrc, 1, pTxF->iSize, fpSrc);

        fclose(fpSrc);

 

        fwrite(pSrc, 1, pTxF->iSize, fpDst);

¡¦

}

 

ÀÌ·¸°Ô ¸ÓÁö ÆÄÀÏÀ» ¸¸µé¾úÀ¸¸é À̰ÍÀ» ´Ù½Ã Ç®¾î¼­ È®ÀÎÇØ ºÁ¾ß ÇÕ´Ï´Ù. CMain::GetFileData() ÇÔ¼ö´Â new ¿¬»êÀÚ·Î Àӽà ¹öÆÛ¸¦ ¸¸µé°í ¸ÓÁö ÆÄÀÏ¿¡¼­ ÆÄÀÏ µ¥ÀÌÅ͸¦ Àоî¿À´Â ¿ªÇÒÀ» ÇÕ´Ï´Ù.

 

BYTE* CMain::GetFileData(int idx, int* iSize)

¡¦

FILE* fp = fopen("Texture/Merge.mrg", "rb");

 

// 3. Read File Information

for(i=0; i<iN; ++i)

{

        MrgTx* pTxF = new MrgTx;

        vTx.push_back(pTxF);

        pTxF    = vTx[i];

        fread(pTxF->sFile,     1, sizeof(pTxF->sFile), fp);

        fread(&pTxF->iSize,    1, sizeof(pTxF->iSize), fp);

¡¦

}

 

MrgTx* pTxF = vTx[idx];

 

// 4. Move File Point

fseek(fp, pTxF->iBgn, SEEK_SET);

¡¦

// 6. Read File Data

pBuf = new BYTE[pTxF->iSize];

fread(pBuf, 1, pTxF->iSize, fp);

fclose(fp);

¡¦

return pBuf;

 

 

CMain::GetFileData() ÇÔ¼ö·Î ÀÐÀº ÆÄÀÏÀÇ µ¥ÀÌÅÍ¿¡¼­ D3DXCreateTextureFromFileInMemoryEx()ÇÔ¼ö·Î ÅØ½ºÃ³¸¦ »ý¼ºÇÕ´Ï´Ù. ÀÌ ¿¹´Â CMain::FrameMove()¿¡ ±¸ÇöµÇ¾î ÀÖ½À´Ï´Ù.

 

HRESULT CMain::FrameMove()

¡¦

int     iIdx = rand()%10;

INT     iSize=0;

BYTE*   pSrc = GetFileData(iIdx, &iSize);

¡¦     

D3DXCreateTextureFromFileInMemoryEx(¡¦);

¡¦

 

Àüü ÄÚµå´Â daux05_texture2_merge_file.zip¸¦ Âü°í Çϱ⠹ٶø´Ï´Ù.

 

< ÇÕº´ÇÑ ÆÄÀÏ¿¡¼­ ÅØ½ºÃ³ »ý¼º: daux05_texture2_merge_file.zip>

 

 

3.5.3 Private Data

Private Data´Â ´Ü¾î ¶æ ±×´ë·Î ³»ºÎÀûÀÎ µ¥ÀÌÅÍ·Î D3D¿¡¼­ IDirect3DResource9, IDirect3DBaseTexture9, IDirect3DCubeTexture9, IDirect3DTexture9, IDirect3DVolumeTexture9, IDirect3DIndexBuffer9, IDirect3DVertexBuffer9 µîÀÇ ÀÚ¿ø¿¡ ¾î¶² ¸ñÀûÀ» À§ÇØ º¸Á¶ÀûÀ¸·Î ÇÒ´çÇÑ ÀÚ¿øÀ» ÀúÀåÇÏ´Â °ø°£ÀÔ´Ï´Ù.

¿¹¸¦ µé¾î D3D´Â ÅØ½ºÃ³¸¦ 2ÀÇ ½Â¼ö·Î ¸¸µé¾î ¹ö¸³´Ï´Ù. 2ÀÇ ½Â¼ö°¡ ¾Æ´Ñ ÅØ½ºÃ³´Â ¿øº» Á¤º¸¸¦ ¾î¶² ½ÄÀ¸·ÎµçÁö ÀúÀåÀ» ÇØ¾ß¸¸ ·»´õ¸µ¿¡¼­ Á¤È® À̹ÌÁö ¿µ¿ªÀ» Ç¥½ÃÇÒ ¼ö ÀÖ½À´Ï´Ù. ±×·±µ¥ ¸¸¾à ¿øº» Á¤º¸¸¦ ³Ñ±æ ¼ö ¾ø´Â »óȲÀÌ ÀÖ´Ù¸é ¾î¶»°Ô ÇÒ±î¿ä?

¹°·Ð ¿øº» À̹ÌÁö Á¤º¸¸¦ ¹ÞÀ» ¼ö ÀÖµµ·Ï ½Ã½ºÅÛÀ» ¼öÁ¤ÇØ¾ß ÇÏ´Â °ÍÀÌ °¡Àå Çö¸íÇÑ ¹æ¹ýÀÔ´Ï´Ù. ÀÌ ¸¶ Àúµµ ¾ÈµÉ ¶§´Â Private Data¸¦ »ç¿ëÇÕ´Ï´Ù.

 

´ÙÀ½°ú °°ÀÌ ÅØ½ºÃ³¸¦ »ý¼ºÇÏ°í ¿øº» À̹ÌÁöÀÇ Á¤º¸¸¦ new ¿¬»êÀÚ·Î µ¿Àû ÇÒ´çÇÑ ´ÙÀ½¿¡ ÇØ´ç ÅØ½ºÃ³¿¡ SetPrivateData() ÇÔ¼ö·Î ¿¬°áÇÕ´Ï´Ù.

 

 

GUID IID_ILcTexInfo ={0x85c31227, 0x3de5, 0x4f00, 0x9b

, 0x3a, 0xf1, 0x1a, 0xc3, 0x8c, 0x18, 0xb5};

 

INT LcUtil_TextureLoad(¡¦, LPDIRECT3DTEXTURE9* pTx, TCHAR* sFile,¡¦)

¡¦

D3DXIMAGE_INFO* pImg = new D3DXIMAGE_INFO;

¡¦

D3DXCreateTextureFromFileEx(pDev, sFile, ¡¦, pImg, NULL, pTx);

(*pTx)->SetPrivateData( IID_ILcTexInfo, &pImg, sizeof(pImg), 0);

¡¦

 

ÀÌ·¸°Ô ¿¬°áÇÏ°í ³ª¼­ ´ÙÀ½°ú °°ÀÌ GetPrivateData() ÇÔ¼ö¸¦ ÅëÇØ¼­ À̹ÌÁö Á¤º¸¸¦ °¡Á®¿Í »ç¿ëÇÕ´Ï´Ù.

 

HRESULT CMain::Render()

¡¦

DWORD          dSize= 0;

DWORD          dData= 0;

D3DXIMAGE_INFO* pData;

m_pTex1->GetPrivateData(IID_ILcTexInfo, &dData, &dSize);

 

pData = (D3DXIMAGE_INFO*)dData;

RECT    rc1={0,0, pData->Width, pData->Height};

 

m_pd3dSprite->Draw(m_pTex1, &rc1, ¡¦);

¡¦

 

ÀÌ·¸°Ô µ¿Àû ÇÒ´çÀ¸·Î ¸¸µç Private Data´Â ÇÁ·Î±×·¥ ÇØÁ¦ÇÒ ¶§ °°ÀÌ ¼Ò¸ê½ÃÄÑ¾ß ÇÏ´Â °ÍÀº ´ç¿¬ÇÕ´Ï´Ù. ¶ÇÇÑ FreePrivateData() ÇÔ¼ö¸¦ È£ÃâÇØ¼­ Private Data »ç¿ëÀ» ÇØÁ¦ÇÕ´Ï´Ù.

 

HRESULT CMain::Destroy()

¡¦

DWORD          dData= 0;

D3DXIMAGE_INFO* pData;

 

m_pTex1->GetPrivateData( IID_ILcTexInfo, &dData, &dSize);

m_pTex1->FreePrivateData(IID_ILcTexInfo);

pData = (D3DXIMAGE_INFO*)dData;

delete pData;

 

Àüü ÄÚµå´Â daux05_texture3_privatedata.zip ÆÄÀÏÀ» Âü°í Çϱ⠹ٶø´Ï´Ù.

 

<Private Data: daux05_texture3_privatedata.zip>

 

SetPrivateData() ÇÔ¼ö¸¦ È£ÃâÇÒ ¶§ ù ¹øÂ° Àμö´Â ±¸ÀÌµå ¹øÈ£(Guid Number) ¶ó´Â °ªÀ¸·Î À©µµ¿ì ½Ã½ºÅÛ¿¡¼­ ¸¸µç À¯ÀÏ °ªÀ» º¸ÀåÇÏ´Â ¼öÀÔ´Ï´Ù. Visual Studio´Â ±¸ÀÌµå ¹øÈ£¸¦ »ý¼ºÇÏ´Â ÇÁ·Î±×·¥ÀÌ GuidGen.exe ¶Ç´Â uuidGen.exe °¡ ÀÖ½À´Ï´Ù. 2005 ¹öÀüÀÇ GuidGen.exe¸¦ ã¾Æ¼­ ½ÇÇàÇÏ¸é ´ÙÀ½ À©µµ¿ì°¡ ½ÇÇàÀÌ µÇ¸ç Copy ¹öưÀ» ´­·¯ ±¸ÀÌµå ¹øÈ£¸¦ º¹»ç ÇÕ´Ï´Ù. New GUID ¹öưÀ» ´©¸¦ ¶§¸¶´Ù Àü¼¼°è¿¡¼­ Çϳª ¹Û¿¡ ¾ø´Â ¹øÈ£¸¦ ¸¸µé¾î ³À´Ï´Ù.

 

<GuidGen.exe>

 

ÀÌ ¹øÈ£¸¦ º¹»ç ÇØ¼­ ´ÙÀ½°ú °°ÀÌ GUID ±¸Á¶Ã¼¿¡ ä¿ö¼­ SetPrivateData(), GetPrivateData() ÇÔ¼ö È£ÃâÀÇ Àμö·Î »ç¿ëÇÕ´Ï´Ù.

 

GUID IID_ILcTexInfo ={0x85c31227, 0x3de5, 0x4f00

, 0x9b, 0x3a, 0xf1, 0x1a, 0xc3, 0x8c, 0x18, 0xb5};

 

 

3.5.4 Targa ¿Í PNG

D3D´Â DXSDK¿¡¼­ À̹ÌÁö¸¦ ºÒ·¯¿À´Â ÇÔ¼ö°¡ Áö¿øÀÌ ÀÖ¾î À̹ÌÁö¸¦ ÀÐ°í ¾²´Â ÀϵéÀ» °í¹Î ¾È ÇØµµ µË´Ï´Ù. ±×·±µ¥ ¸¸¾à D3D·Î ¸ð¹ÙÀÏ µîÀÇ ±â±â¿¡ À̽ÄÇϱâ À§ÇÑ Emulator¸¦ ¸¸µç´Ù°í ÇÑ´Ù¸é ÀÌ ±â±âÀÇ È¯°æ¿¡ ¸Â´Â À̹ÌÁö Çü½ÄÀ¸·Î ÄÚµùÀ» ÇØ¾ß ÇÕ´Ï´Ù.

¿©·¯ À̹ÌÁö Æ÷¸Ë Áß¿¡¼­ °¡Àå ¸¹ÀÌ »ç¿ëÇÏ´Â Æ÷¸ËÀº Targa Çü½ÄÀÔ´Ï´Ù. Targa ÆÄÀÏÀº ÀÐ°í ¾²±â°¡ Æí¸®Çؼ­ ´ëºÎºÐÀÇ °ÔÀÓ ÇÁ·Î±×·¡¹Ö Ã¥¿¡ ¼Ò°³°¡ µÇ¾î ÀÖ½À´Ï´Ù. D3D¸¦ °øºÎÇÏ´Â ¿©·¯ºÐµµ Targa ÆÄÀÏ ¸¸Å­Àº DXSDK ÇÔ¼ö¸¦ »ç¿ëÇÏÁö ¾Ê°í ÀÐ°í ¾²´Â ¹ýÀ» ³ªÁß¿¡¶óµµ ¿¬½ÀÇϱ⠹ٶø´Ï´Ù.

 

daux05_texture4_ToTarga.zip ÆÄÀÏÀº PNG ÆÄÀÏÀ» D3D ÇÔ¼ö·Î ÀÐÀº ÈÄ¿¡ ¼­ÇǽºÀÇ Çȼ¿À» ¾ò¾î¿Í Targa·Î ÀúÀåÇÏ´Â ¿¹Á¦ ÀÔ´Ï´Ù. TargaÀÇ ÀÐ°í ¾²´Â ¹æ¹ýÀº °ÅÀÇ ÀÏÁ¤ÇÕ´Ï´Ù. µû¶ó¼­ ¼Ò½º Äڵ常 º¸´õ¶óµµ ´©±¸³ª ½±°Ô ÀÌÇØ ÇÒ ¼ö ÀÖ½À´Ï´Ù. ±×·¡¼­ Targa¿¡ ´ëÇÑ ÀÚ¼¼ÇÑ ¼³¸íÀº »ý·«Çϰí ÁÖÀÇÁ¡ Á¤µµ¸¸ º¸°Ú½À´Ï´Ù.

 

Targa ÆÄÀÏÀ» Àд ¹æ¹ýÀº °íÁ¤ÀÌ µÇ¾î À־ ¾î¶² Äڵ带 ¾ò´õ¶óµµ °ÅÀÇ °°Àº ¹æ½ÄÀ¸·Î ±¸¼ºµÇ¾î ÀÖ½À´Ï´Ù. ±×·±µ¥ ÁÖÀÇÇÒ Á¡Àº Çȼ¿À» ÀÐ¾î ¿À°í ³ª¼­ ÀÌ Çȼ¿ÀÌ 24ºñÆ® À̸é 32 ºñÆ®·Î ¹Ù²Ù¾î »ç¿ëÇÏ´Â °ÍÀÌ ÁÁ½À´Ï´Ù.

´ÙÀ½ ÄÚµåÀÇ for ¹®¿¡¼­ ÀÌ·¯ÇÑ ÀÏÀ» ó¸®Çϰí ÀÖ½À´Ï´Ù.

 

INT LoadTGAFile()

¡¦

fp = fopen(filename, "rb");

¡¦

// read bit depth

fread(&ImgBit, sizeof(BYTE), 1, fp);

¡¦

// colormode -> 3 = BGR, 4 = BGRA

colorMode = ImgBit / 8;

 

// bgr ->bgra

if(3 == colorMode)

{

        BYTE* pPixel4  = new BYTE[ImgWidth * ImgHeight * 4];

 

        for (INT i = 0; i < imageSize/3; ++i)

        {

               INT idx1 =  i*3;

               INT idx2 =  i*4;

 

               pPixel4[idx2+0] = pPixel[idx1 + 0];

               pPixel4[idx2+1] = pPixel[idx1 + 1];

               pPixel4[idx2+2] = pPixel[idx1 + 2];

               pPixel4[idx2+3] = 0xFF;

        }

¡¦

 

D3D´Â »ö»ó 32 ºñÆ®ÀÇ ¼ø¼­°¡ ³·Àº ¹ÙÀÌÆ®ºÎÅÍ B->G->R->A ¼øÀ¸·Î µÇ¾î ÀÖ½À´Ï´Ù. ¸¸¾à »ö»óÀÇ ¼ø¼­°¡ A->R->G->B·Î ±¸¼ºµÇ¾î ÀÖ´Â ½Ã½ºÅÛ¿¡¼­´Â ¾ÕÀÇ ÄÚµå for ¹®¿¡¼­ ÀÌ ¼ø¼­¸¦ ¹Ù²Ù¾î ÁÖ¸é µË´Ï´Ù.

 

pPixel4[idx2+3] = pPixel[idx1 + 0];

pPixel4[idx2+2] = pPixel[idx1 + 1];

pPixel4[idx2+1] = pPixel[idx1 + 2];

pPixel4[idx2+0] = pPixel[idx1 + 2] ¶Ç´Â 0xFF;

 

ÀÌ·¸°Ô Çȼ¿ÀÇ ¼ø¼­¸¦ ¹Ù²Ù´Â ÀÏÀº ´Ù¸¥ Ç÷§Æû¿¡ À̽ÄÇÒ ¶§ ¶Ç´Â ÆÄÀÏ Çü½ÄÀÌ ´Ù¸¥ °æ¿ì¿¡ Á¾Á¾ ¹ß»ýÇÕ´Ï´Ù. ´ÙÀ½ÀÇ ¿¹´Â DXSDK ÇÔ¼ö·Î »ý¼ºÇÑ ÅØ½ºÃ³¸¦ Targa°¡ Çü½ÄÀ¸·Î ÀúÀåÇÏ´Â ÇÔ¼ö ÀÔ´Ï´Ù. Çȼ¿À» ÆÄÀÏ¿¡ ÀúÀåÇÒ ¶§ Targa ÆÄÀÏÀº for ¹® ¾È¿¡¼­ ARGB Çü½ÄÀ» BGRA·Î ¹Ù²Ù°í ÀÖÀ½À» º¼ ¼ö ÀÖ½À´Ï´Ù.

 

INT SaveTGAFile(¡¦)

¡¦

// ARGB -> BGRA

BYTE *b, *g, *r, *a;

 

for(int j=0; j<imageHeight; ++j)

{

        for(int i=0; i<imageWidth; ++i)

        {

               BYTE* pData = pPixel + (  (imageHeight-1-j)*RealWidth + i)*4;

 

               a = pData + 3;

               r = pData + 2;

               g = pData + 1;

               b = pData + 0;

¡¦

               fwrite(b, sizeof(BYTE), 1, fp);

               fwrite(g, sizeof(BYTE), 1, fp);

               fwrite(r, sizeof(BYTE), 1, fp);

               fwrite(a, sizeof(BYTE), 1, fp);

        }

}

 

daux05_texture4_ToTarga.zip ÀÇ ¾ÐÃàÀ» Ç®¸é ´ÙÀ½ ±×¸²ÀÇ ¿ÞÂÊó·³ PNG ÆÄÀÏÀ» ºÒ·¯¿Í¼­ Targa·Î ÀúÀåÇÑ ÇÁ·Î±×·¥ Mck.exe°¡ ÀÖ½À´Ï´Ù. PNG ÆÄÀÏÀÇ ¾ÐÃà¿¡ ´ëÇÑ ¾Ë°í¸®Áò°ú ÄÚµå´Â °ø°³µÇ¾î ÀÖ½À´Ï´Ù. ¿À¸¥ÂÊ ±×¸²Àº http://zlib.net/ »çÀÌÆ®¿¡¼­ PNG ÆÄÀÏÀÇ ÀÔÃâ·Â Äڵ带 ¾ò¾î¿Í ¶óÀ̺귯¸®¸¦ ¸¸µé¾î DC¿¡ Àû¿ë½ÃŲ È­¸éÀÔ´Ï´Ù. wn_56_ReadPng Æú´õ¿¡ Çì´õ, ¶óÀ̺귯¸®, ½ÇÇà ÆÄÀÏ McApi.exe°¡ ÀÖ½À´Ï´Ù.

 

 

< Targa ÆÄÀÏ ÀúÀå°ú PNG ·Îµå: daux05_texture4_ToTarga.zip>

 

 

3.6 Anti-Aliasing

AliasingÀº °íÇØ»óµµ µ¥ÀÌÅͰ¡ ÀúÇØ»óµµ µ¥ÀÌÅÍ·Î »ùÇøµ µÇ´Â °ÍÀ» AliasingÀ̶ó Çß½À´Ï´Ù. ÀÌ ¹®Á¦¸¦ ÇØ°áÇÏ´Â Anti-AliasingÁß¿¡¼­ ¼öÆÛ »ùÇøµ ¶Ç´Â ¸ÖƼ »ùÇøµ 󸮸¦ °£´ÜÈ÷ ¹è¿ü½À´Ï´Ù.

Çϵå¿þ¾î°¡ ¾ó¸¶¸¸Å­ÀÇ ¸ÖƼ »ùÇøµ ŸÀÔÀ» Áö¿øÇÏ´ÂÁö ¾Ë¾Æº¸·Á¸é ´ÙÀ½°ú °°ÀÌ ÃÖ´ë °ªºÎÅÍ ¼º°øÇÒ ¶§±îÁö °Ë»çÇÏ¸é µË´Ï´Ù.

 

DWORD dQualityLevels;

for(int nType=D3DMULTISAMPLE_16_SAMPLES; nType>=0; --nType)

{

        if(SUCCEEDED(m_pD3D->CheckDeviceMultiSampleType(D3DADAPTER_DEFAULT

                              , D3DDEVTYPE_HAL

                              , m_d3dpp.BackBufferFormat

                              , TRUE

                               , (D3DMULTISAMPLE_TYPE)nType

                              , &dQualityLevels)))

        {

               m_d3dpp.MultiSampleType = (D3DMULTISAMPLE_TYPE)nType;

               m_d3dpp.MultiSampleQuality = dQualityLevels-1;

               break;

        }

}

 

ÀÌ·¸°Ô ãÀº ÈÄ¿¡ µð¹ÙÀ̽º¸¦ »ý¼ºÇÏ¸é µÇ¸ç ÀÚµ¿À¸·Î Anti-aliasingÀÌ Àû¿ëÀÌ µË´Ï´Ù. È­¸éÀÇ Àüȯ¿¡¼­ µð¹ÙÀ̽º´Â ¸®¼ÂÀÌ µÇ¹Ç·Î ´ÙÀ½°ú °°ÀÌ Anti-aliasingÀ» Ȱ¼ºÈ­ ½ÃÄÑ¾ß ÇÕ´Ï´Ù.

 

m_pd3dDevice->SetRenderState (D3DRS_MULTISAMPLEANTIALIAS, TRUE);

m_pd3dDevice->SetRenderState (D3DRS_ANTIALIASEDLINEENABLE, TRUE);

 

Àüü ÄÚµå´Â daux06_antialias1.zipÀ» Âü°í Çϱ⠹ٶø´Ï´Ù. ´ÙÀ½ ±×¸²Àº Anti-aliasing¿¡ ´ëÇÑ ¿¹Á¦ ÀÔ´Ï´Ù. F2, F3 ۸¦ ´©¸£¸é Anti-aliasingÀÇ ºñȰ¼ºÈ­/Ȱ¼ºÈ­¸¦ ¼³Á¤ ÇÒ ¼ö ÀÖ½À´Ï´Ù. ¿À¸¥ÂÊ ±×¸²À» º¸¸é Anti-aliasingÀ» Ȱ¼ºÈ­ ÇÏ¸é ·»´õ¸µ ¼Óµµ°¡ °¨¼ÒµÈ °ÍÀ» º¼ ¼ö ÀÖ½À´Ï´Ù.

 

 

<Anti-aliasing: daux06_antialias1.zip, daux06_antialias2.zip>

 

 

3.7 ID3DXMesh ¿Í X-file

3.7.1 ID3DXMesh

Tutorial ¿¹Á¦¿Í ÁÖÀüÀÚ, ¿øÅë µî È®Àå À¯Æ¿¸®Æ¼¸¦ ÅëÇØ¼­ ID3DXMeshÀÇ »ç¿ëÀ» ¹è¿ü½À´Ï´Ù. ID3DXMesh´Â Àå¸éÀÇ ¿¬Ãâ¿¡ ÇÊ¿äÇÑ ±âº»ÀûÀÎ Á¤Á¡ ¹öÆÛ¿Í À妽º ¹öÆÛ¸¦ °¡Áö°í ÀÖ°í, ·»´õ¸µ ¼Óµµ¸¦ ¿Ã¸®±â À§Çؼ­ »ï°¢ÇüÀÇ À妽º¸¦ ±×·ì(Group)À¸·Î ¹­¾î ³õÀº ¼Ó¼º ¹öÆÛ¸¦ °¡Áö°í ÀÖ½À´Ï´Ù.

 

º¸Åë ÇϳªÀÇ »ï°¢Çü¿¡ ÀçÁú(Material) ¶Ç´Â ÅØ½ºÃ³(°°Àº ´Ü°è(stage)ÀÏ °æ¿ì)´Â 1°³ ¹Û¿¡ ¼³Á¤ÀÌ ºÒ°¡´ÉÇÕ´Ï´Ù. ¸¸¾à ÇϳªÀÇ ·»´õ¸µ ¿ÀºêÁ§Æ®¿¡ ÀçÁúÀÌ ¿©·¯ °³ÀÇ °æ¿ì¶ó¸é °¢ Á¤Á¡À» ÀçÁú¿¡ ¸Â°Ô ºÐ·ùÇØ¾ß ÇÕ´Ï´Ù. ÀÌ·¸°Ô µÇ¸é ÀçÁú¸¸ ´Ù¸¥ °°Àº »ï°¢ÇüÀÌ¶óµµ º¹»ç¸¦ ÇØ¾ß ÇÕ´Ï´Ù.

¼Ó¼º ¹öÆÛ´Â ÀçÁúÀÌ ¿©·¯ °³ÀÎ °æ¿ì¿¡ Á¤Á¡ ¹öÆÛ¸¦ °¢°¢ ºÐ¸®ÇÏÁö ¾Ê°í, °¢ ÀçÁú¿¡ µû¸¥ »ï°¢ÇüÀÇ À妽º¸¦ ¸ð¾Æ ³õÀº ÀÚ·á ±¸Á¶ÀÔ´Ï´Ù. ¼Ó¼º ¹öÆÛ¸¦ »ç¿ëÇϸé Á¤Á¡ ¹öÆÛ¿Í À妽º ¹öÆÛ¸¦ ±×´ë·Î À¯ÁöÇϸ鼭 ¼­·Î ´Ù¸¥ ÀçÁú ¶Ç´Â ÅØ½ºÃ³¸¦ Àû¿ëÇÒ ¼ö ÀÖ½À´Ï´Ù.

 

<¼Ó¼º Å×À̺í, ¼Ó¼º ¹öÆÛ, À妽º ¹öÆÛ, Á¤Á¡ ¹öÆÛ>

 

ID3DXMesh °´Ã¼¸¦ ·»´õ¸µ ÇÒ ¶§ DrawSubset() ÇÔ¼ö¸¦ È£ÃâÇÑ ÀûÀÌ ÀÖ½À´Ï´Ù. DrawSubset() ÇÔ¼öÀÇ Àμö¿¡ Àü´ÞÇÏ´Â À妽º°¡ ¼Ó¼º Å×ÀÌºí¿¡ ±â·ÏµÈ À妽º ÀÔ´Ï´Ù. ¼Ó¼º Å×ÀÌºí¿¡´Â ¾ÆÀ̵ð, Face ½ÃÀÛ À妽º, Face °³¼ö, Á¤Á¡ÀÇ ½ÃÀÛ À妽º Á¤Á¡ÀÇ °³¼ö°¡ ±â·ÏµÇ¾î ÀÖ½À´Ï´Ù.

À妽º ¹öÆÛ¸¦ ¸¸µé ¶§ WORD ¶Ç´Â DWORDÇüÀÇ ÀÚ·á ±¸Á¶¸¦ ±×´ë·Î »ç¿ëÇÏÁö ¾Ê°í ´ÙÀ½°ú °°Àº ±¸Á¶Ã¼¸¦ »ç¿ëÇÑ´Ù¸é Face À妽º¿Í ÀÌ ±¸Á¶Ã¼ÀÇ À妽º¸¦ µ¿ÀÏÇÏ°Ô ¸ÂÃâ ¼ö ÀÖ½À´Ï´Ù.

 

struct VtxIdx

{

        WORD a;    WORD b;    WORD c;

};

 

»ï°¢ÇüÀÇ ¸é(Face)¸¦ ±¸¼ºÇÏ´Â ±¸Á¶Ã¼°¡ ¾ø´Ù¸é ¿©·¯ºÐÀº ÇÁ·Î±×·¥À» ÀÛ¼ºÇÒ ¶§ °è»êÀ» Àß ÇØ¾ß ÇÕ´Ï´Ù.

 

¿¬½ÀÀ» À§ÇØ ÅØ½ºÃ³°¡ ¸ÅÇÎ µÈ 6 ¸éü ID3DXMesh °´Ã¼·Î ·»´õ¸µ ÇØº¾½Ã´Ù. ¸ÕÀú ´ÙÀ½ °°Àº ID3DXMesh °´Ã¼¸¦ ¼±¾ðÇÕ´Ï´Ù. ±×¸®°í 6¸é¿¡ ´ëÇØ¼­ 6ÀåÀÇ ÅØ½ºÃ³¸¦ ¸ÅÇÎ ÇÏ´Â °ÍÀ¸·Î ÇϰڽÀ´Ï´Ù.

 

ID3DXMesh*             m_pMsh;

INT                    m_nMtl;

LPDIRECT3DTEXTURE9     m_pTex[6];

 

´ÙÀ½ ´Ü°è¿¡¼­ FaceÀÇ °³¼ö, Á¤Á¡ °³¼ö, FVF µîÀ» D3DXCreateMeshFVF() ÇÔ¼öÀÇ Àμö·Î Àü´ÞÇÏ°í ¸Þ½¬ °´Ã¼¸¦ »ý¼ºÇÕ´Ï´Ù.

 

D3DXCreateMeshFVF("Á¤Á¡ÀÇ °³¼ö", "FaceÀÇ °³¼ö", ¡¦, FVF, ¡¦, &m_pMsh);

 

ÀÌ ÇÔ¼ö´Â ¸Þ½¬ °´Ã¼ÀÇ Á¤Á¡°ú À妽ºÀÇ °ø°£À» ¸¸µì´Ï´Ù. ´ÙÀ½À¸·Î Lock()/Unlock() ÇÔ¼ö·Î Á¤Á¡ ¶Ç´Â À妽ºÀÇ µ¥ÀÌÅ͸¦ º¯°æÇÕ´Ï´Ù.

 

VtxUV1 pVtxS[24];

pVtxS[ 0] = VtxUV1(-6.F, -6.F, -6.F0.f, 0.f);

pVtxS[ 1] = VtxUV1(-6.F6.F, -6.F0.f, 1.f);

¡¦

 

VtxIdx pIdxS[12];

pIdxS[ 0] = VtxIdx012);

pIdxS[ 1] = VtxIdx023);

 

// Á¤Á¡, À妽º º¹»ç

VtxUV1* pVtx = NULL;

m_pMsh->LockVertexBuffer(0, (void**)&pVtx);

        memcpy(pVtx, pVtxS, sizeof(VtxUV1) * 24);

m_pMsh->UnlockVertexBuffer();

 

VtxIdx* pIdx = NULL;

m_pMsh->LockIndexBuffer(0, (void**)&pIdx);

        memcpy(pIdx, pIdxS, sizeof(VtxIdx) * 12);

m_pMsh->UnlockIndexBuffer();

 

Á¤Á¡°ú À妽º ¼³Á¤ ¸¸À¸·Îµµ ·»´õ¸µÀº °¡´ÉÇÕ´Ï´Ù. ¸ÅÇÎ ¿©·¯ °³¶ó¸é ´ÙÀ½°ú °°ÀÌ ¼Ó¼º ¹öÆÛÀÇ ³»¿ëÀ» °»½ÅÇÕ´Ï´Ù.

 

DWORD* attBuf = NULL;

m_pMsh->LockAttributeBuffer(0, &attBuf);

attBuf[ 0] = 0;

attBuf[ 1] = 1;

¡¦

m_pMsh->UnlockAttributeBuffer();

 

¾Õ¼­ À妽º ¹öÆÛ¸¦ ±¸¼ºÇÒ ¶§ VtxIdx¿Í °°Àº ±¸Á¶Ã¼¸¦ »ç¿ëÇÏ´Â °ÍÀÌ ÁÁ´Ù°í Çß½À´Ï´Ù. »ï°¢Çü¿¡ ´ëÇØ¼­ ¼Ó¼º ¹öÆÛ¿¡ ±â·ÏÇÏ´Â À妽º´Â VtxIdx À妽º¿Í °°½À´Ï´Ù.

 

¸¶Áö¸· ´Ü°è¿¡¼­ ¼Ó¼º ¹öÆÛ¿¡ ÀúÀåµÈ »ï°¢ÇüÀÇ À妽º¿¡ ¸ÂÃß¾î ·»´õ¸µ ¼Óµµ¸¦ À§ÇØ ÃÖÀûÈ­¸¦ ÇÕ´Ï´Ù. ÀÌ ´Ü°è´Â ¼±Åà »çÇ×ÀÌ¸ç ¸¸¾à »ç¿ëÀÚ°¡ ¼Ó¼º ¹öÆÛ¸¦ Àß ±¸¼º Çß´Ù¸é ÇÒ ÇÊ¿ä´Â ¾ø½À´Ï´Ù.

 

DWORD* pAdjacencyBuf = new DWORD[12 * 3];

 

m_pMsh->GenerateAdjacency(0.f, pAdjacencyBuf);

m_pMsh->OptimizeInplace(

        D3DXMESHOPT_ATTRSORT | D3DXMESHOPT_COMPACT | D3DXMESHOPT_VERTEXCACHE

        , pAdjacencyBuf, 0, 0, 0);

 

delete [] pAdjacencyBuf;

 

OptimizeInplace() ÇÔ¼öÀÇ ÃÖÀûÈ­ ¿É¼ÇÀº ´ÙÀ½°ú °°½À´Ï´Ù.

D3DXMESHOPT_COMPACT: »ç¿ëÇÏÁö ¾Ê´Â Á¤Á¡°ú À妽º¸¦ Áö¿ì°í Àç ±¸¼º ÇÕ´Ï´Ù.

D3DXMESHOPT_ATTRSORT: ¼Ó¼º ¹öÆÛÀÇ ³»¿ëÀ» Âü°íÇØ¼­ Face(»ï°¢Çü) Á¤·Ä ÇÕ´Ï´Ù.

D3DXMESHOPT_VERTEXCACHE: Face¸¦ À籸¼ºÇؼ­ ¹öÅØ½º ij½Ã¿¡ ´ëÇÑ ÀûÁß·üÀ» ³ôÀÔ´Ï´Ù.

D3DXMESHOPT_STRIPREORDER: °¡´ÉÇÑ ÇÑ Ä¿´Ù¶õ ½ºÆ®¸³À¸·Î ±¸¼ºÇϵµ·Ï À妽º¸¦ Àç ±¸¼ºÇÕ´Ï´Ù.

D3DXMESHOPT_IGNOREVERTS: ¹öÅØ½º Á¤º¸´Â ¹«½ÃÇϰí À妽º Á¤º¸¸¸ ÃÖÀûÈ­ ÇÕ´Ï´Ù

D3DXMESHOPT_DONOTSPLIT: ¼Ó¼ºÀÇ Á¤·Ä Áß¿¡¼­ ¼Ó¼º ±×·ì »çÀÌ¿¡ °øÀ¯µÇ°í ÀÖ´Â Á¤Á¡µéÀº ºÐÇÒ ¾È ÇÕ´Ï´Ù.

D3DXMESHOPT_DEVICEINDEPENDENT´Â Á¤Á¡ ij½ÃÀÇ »çÀÌÁî¿¡ ¿µÇâÀ» ÁÖ¸ç Çϵå¿þ¾î¿¡¼­ ¹®Á¦ ¹ß»ýÀ» ¾ø¾Ö±â À§ÇØ µðÆúÆ® Á¤Á¡ ij½Ã »çÀÌÁî°¡ ÁöÁ¤µË´Ï´Ù.

 

¼Ó¼º Å×À̺íÀÇ ³»¿ëÀ» ¾Ë±â À§Çؼ­ GetAttributeTable() ÇÔ¼ö¸¦ »ç¿ëÇÕ´Ï´Ù. ÀÌ ÇÔ¼ö¸¦ »ç¿ëÇÏ·Á¸é ¸ÕÀú ´ÙÀ½°ú °°ÀÌ ¸ÕÀú Å×ÀÌºí ¼ö¸¦ °¡Á®¿À°í Å×ÀÌºí ³»¿ëÀ» ±â·ÏÇÒ ¹öÆÛ¸¦ µ¿ÀûÀ¸·Î ¸¸µç ´ÙÀ½ ÀÌ ¹öÆÛ¿Í Å×ÀÌºí ¼ö¸¦ Àμö·Î GetAttributeTable() ÇÔ¼ö¸¦ È£ÃâÇÏ¸é ³»¿ëÀ» °¡Á®¿Ã ¼ö ÀÖ½À´Ï´Ù.

 

DWORD   nNumSubset=0;

hr= m_pMsh->GetAttributeTable(0, &nNumSubset);

D3DXATTRIBUTERANGE* attTable= new D3DXATTRIBUTERANGE[nNumSubset];

hr= m_pMsh->GetAttributeTable(attTable, &nNumSubset);

delete [] attTable;

 

m_nMtl = nNumSubset;

 

Àüü ³»¿ëÀº daux07_mesh01.zipÀ» Âü°í Çϱ⠹ٶø´Ï´Ù.

 

 

<»ç¿ëÀÚ Á¤ÀÇ¿¡ ÀÇÇÑ ID3DXMesh: daux07_mesh01.zip>

 

ID3DXMesh¸¦ ÀÌ¿ëÇØ¼­ Àå¸éÀ» ¿¬ÃâÇÏÁö ¾Ê°í ¸Þ½¬ µ¥ÀÌÅ͸¦ º¹»çÇØ¼­ »ç¿ëÇÒ °æ¿ìµµ ÀÖ½À´Ï´Ù. ÀÌ ¶§ ¸Þ½¬ °´Ã¼ ³»ºÎÀÇ µ¥ÀÌÅ͸¦ °¡Á®¿À±â À§Çؼ­ ÃÖ¼ÒÇÑ ´ÙÀ½°ú °°Àº Áö¿À¸ÞÆ®¸® ±¸Á¶Ã¼¿Í ¸â¹ö º¯¼ö¸¦ °¡Áö°í ÀÖ¾î¾ß ÇÕ´Ï´Ù.

Áö¿À¸ÞÆ®¸®(Geometry) ±¸Á¶Ã¼´Â ID3DXMesh °´Ã¼ÀÇ Subset°ú 1:1 °ü°èÀÔ´Ï´Ù. ·»´õ¸µ¿¡ ÇÊ¿äÇÑ Face ¼ýÀÚ¿Í, Face ¸®½ºÆ®°¡ ÇÊ¿äÇÕ´Ï´Ù.

 

 

struct McGeo                  // Geometry

{

        UINT    nFce;          // Face ¼ýÀÚ

        UINT    nVtx;          // Á¤Á¡ ¼ýÀÚ

        VtxIdx* pIdx;          // Face ¸®½ºÆ®

};

 

Áö¿À¸ÞÆ®¸®¸¦ °¡Áö°í ÀÖÀ» Ŭ·¡½ºÀÇ ¸â¹ö º¯¼ö´Â Áö¿À¸ÞÆ®¸®ÀÇ ¼ýÀÚ¿Í µ¥ÀÌÅ͸¦ °¡Á®¾ß Çϰí, ID3DXMesh °´Ã¼¿¡¼­ Á¤Á¡ ¹öÆÛ¸¦ º¹»çÇØ¿Í¾ß ÇϹǷΠÁ¤Á¡ÀÇ ¼ö, Á¤Á¡ ÇϳªÀÇ Å©±â, FVF, Á¤Á¡ ¹öÆÛ¸¦ ÀÖ¾î¾ß ÇÕ´Ï´Ù.

 

INT            m_nGeo;        // Áö¿À¸ÞÆ®¸® ¼ö

McGeo*         m_pGeo;        // Áö¿À¸ÞÆ®¸®

UINT           m_nVtx;        // Á¤Á¡ÀÇ °³¼ö

UINT           m_dVtx;        // Á¤Á¡ ÇϳªÀÇ Å©±â

DWORD          m_dFVF;        // FVF

void*          m_pVtx;        // Á¤Á¡ ¹öÆÛ

 

ID3DXMesh °´Ã¼¿¡¼­ µ¥ÀÌÅ͸¦ ²¨³»¿À´Â ¹æ¹ýÀº ´ÙÀ½°ú °°ÀÌ ¸ÕÀú Á¤Á¡ÀÇ ¼ö, À妽º(Face)ÀÇ ¼ö¸¦ ¾ò¾î ¿É´Ï´Ù.

 

ID3DXMesh* pMeshSrc = "ID3DXMesh °´Ã¼ »ý¼º ÇÔ¼ö";

¡¦

INT     nVtxS= pMeshSrc->GetNumVertices();

INT     nFceS= pMeshSrc->GetNumFaces();

 

·»´õ¸µ¿¡ ÇÊ¿äÇÑ Á¤Á¡ ÇϳªÀÇ Å©±â, FVF, Á¤Á¡ ¹öÆÛ¸¦ »ý¼ºÇÕ´Ï´Ù. Á¤Á¡ÀÇ Æ÷¸ËÀº ¾ËÁö ¸øÇϱ⠶§¹®¿¡ malloc() ÇÔ¼ö µîÀ¸·Î ¸Þ¸ð¸®¸¸ È®º¸ÇÕ´Ï´Ù.

 

m_nVtx  = nVtxS;

m_dVtx  = (UINT)pMeshSrc->GetNumBytesPerVertex();

m_dFVF  = pMeshSrc->GetFVF();

m_pVtx  = malloc(m_nVtx * m_dVtx);

 

ID3DXMesh °´Ã¼¿¡¼­ Á¤Á¡À» º¹»çÇÕ´Ï´Ù.

 

VtxUV1* pVtxS=NULL;

pMeshSrc->LockVertexBuffer(0, (void**)&pVtxS);

        memcpy(m_pVtx, pVtxS, sizeof(VtxUV1) * nVtxS);

pMeshSrc->UnlockVertexBuffer();

 

À妽º´Â Áö¿À¸ÞÆ®¸®¿¡ ±â·ÏµÉ °ÍÀÔ´Ï´Ù. µû¶ó¼­ ID3DXMesh¿¡ ÀÖ´Â À妽º´Â Àӽà ¹öÆÛ¸¦ ¸¸µé°í ¿©±â¿¡ º¹»çÇÕ´Ï´Ù.

 

VtxIdx* pFce = new VtxIdx[nFceS];

 

VtxIdx* pIdxS=NULL;

pMeshSrc->LockIndexBuffer(0, (void**)&pIdxS);

        memcpy(pFce, pIdxS, sizeof(VtxIdx) * nFceS);

pMeshSrc->UnlockIndexBuffer();

 

Áö¿À¸ÞÆ®¸® °´Ã¼ÀÇ ³»¿ëÀ» ¼³Á¤Çϱâ À§Çؼ­ ¼Ó¼º Å×À̺íÀÇ °³¼ö¿Í ³»¿ëÀ» °¡Á®¿É´Ï´Ù. ¼Ó¼º Å×À̺íÀÇ ¼ýÀÚ´Â Áö¿À¸ÞÆ®¸®ÀÇ ¼ýÀÚ¿Í µ¿ÀÏÇÏ°Ô Çϰí ÀÌ °³¼ö¸¸Å­ Áö¿À¸ÞÆ®¸®¸¦ ¸¸µì´Ï´Ù.

 

DWORD   nNumSubset=0;

hr= pMeshSrc->GetAttributeTable(0, &nNumSubset);

 

// Geometry ¼ýÀÚ¸¦ ¼³Á¤ÇÑ´Ù.

m_nGeo = nNumSubset;

m_pGeo = new McGeo[m_nGeo];

 

D3DXATTRIBUTERANGE* attTable = new D3DXATTRIBUTERANGE[nNumSubset];

hr= pMeshSrc->GetAttributeTable(attTable, &nNumSubset);

 

¼Ó¼º Å×À̺íÀÇ ³»¿ëÀ» °¡Áö°í Áö¿À¸ÞÆ®¸®ÀÇ À妽º(Face)¸¦ ±¸¼ºÇÕ´Ï´Ù.

 

for(i=0; i<m_nGeo; ++i)

{

        McGeo* pGeo = &m_pGeo[i];

        pGeo->nFce     = attTable[i].FaceCount;

        pGeo->nVtx     = attTable[i].VertexCount;

        pGeo->nFceB    = attTable[i].FaceStart;

 

        // GeometryÀÇ À妽º ¹öÆÛ »ý¼º

        pGeo->pIdx     = new VtxIdx[pGeo->nFce];

 

        // Index Buffer º¹»ç

        VtxIdx* pIdxDst = pFce + pGeo->nFceB;

        memcpy(pGeo->pIdx, pIdxDst, sizeof(VtxIdx) * pGeo->nFce);

}

 

Àå¸éÀ» ±¸¼ºÇÒ Á¤Á¡ ¹öÆÛ, Áö¿À¸ÞÆ®¸®ÀÇ ³»¿ëÀ» ´Ù ä¿ü½À´Ï´Ù. ID3DXMesh°´Ã¼¿Í Àӽ÷Π»ç¿ëÇÑ À妽º ¹öÆÛ, ¼Ó¼ºÅ×À̺íÀº ÇØÁ¦ÇÕ´Ï´Ù. ·»´õ¸µÀº ´ÙÀ½°ú °°ÀÌ Á¤Á¡ ¹öÆÛ¿Í Áö¿À¸ÞÆ®¸®ÀÇ Á¤º¸¸¦ ÀÌ¿ëÇÕ´Ï´Ù.

 

for(i = 0; i < m_nGeo; i++)

{

        McGeo* pGeo = &m_pGeo[i];

        m_pDev->SetTexture( 0, m_pTex[i] );

        m_pDev->SetFVF(m_dFVF);

        m_pDev->DrawIndexedPrimitiveUP(D3DPT_TRIANGLELIST, 0, m_nVtx

, pGeo->nFce, pGeo->pIdx, D3DFMT_INDEX16, m_pVtx, m_dVtx);

}

 

Àüü ÄÚµå´Â daux07_mesh02.zipÀ» Âü°íÇϱ⠹ٶø´Ï´Ù.

 

 

<ID3DXMesh °´Ã¼ÀÇ ³»¿ëÀ» º¹»çÇÑ Áö¿À¸ÞÆ®¸®·Î ·»´õ¸µ: daux07_mesh02.zip>

 

DXSDK´Â ¿¬¼ÓµÈ Á¤Á¡ µ¥ÀÌÅÍ¿¡ ´ëÇØ¼­ Ãæµ¹¿¡ ´ëÇÑ °æ°è»óÀÚ(Bounding Box)¿Í °æ°è ±¸(Bounding Sphere)¸¦ ±¸ÇØÁÖ´Â ÇÔ¼ö°¡ ÀÖ½À´Ï´Ù. ¸¸¾à ID3DXMesh °´Ã¼¿¡ ´ëÇÑ Bounding Box, Sphere´Â ´ÙÀ½°ú °°ÀÌ ÇÕ´Ï´Ù.

 

D3DXVECTOR3* pVtx=NULL;

D3DXVECTOR3 vcMax; D3DXVECTOR3 vcMin; D3DXVECTOR3 vcCenter; FLOAT fRadius;

 

DWORD nVtx     = m_pMsh->GetNumVertices();

DWORD dFVF     = m_pMsh->GetFVF();

DWORD dStride  = D3DXGetFVFVertexSize(dFVF);

 

pMesh->LockVertexBuffer(D3DLOCK_READONLY, (void**)&pVtx);

D3DXComputeBoundingBox((D3DXVECTOR3*)pVtx, nVtx, dStride, &vcMin, &vcMax);

D3DXComputeBoundingSphere((D3DXVECTOR3*)pVtx, nVtx, dStride, &vcCenter, &fRadius);

pMesh->UnlockVertexBuffer();

 

 

3.7.2 X-file

3D ±âÃÊ Tutorial¿¡¼­ È£¶ûÀÌ X-fileÀ» ¿ì¸®´Â È­¸é¿¡ ¿Ã·Á º¸¾Ò½À´Ï´Ù. X-file Àå¸é¿¡ ´ëÇÑ ·»´õ¸µ ¿ÀºêÁ§Æ®ÀÇ Á¤º¸¸¦ °¡Áö°í ÀÖ´Â X-file¿¡ ´ëÇÑ ÇØ¼®Àº DXSDK¿¡¼­ Áö¿ø µÇ¾î º°µµÀÇ ³ë·ÂÀÌ ÇÊ¿ä ¾ø½À´Ï´Ù. ´Ù·ç±â°¡ ½¬¿ö¼­ °ÔÀÓ °³¹ß ±â°£ Áß¿¡ Å×½ºÆ® ÆÄÀÏ·Î °¡Àå ¸¹ÀÌ »ç¿ëµÇ´Â Æ÷¸ËÀÔ´Ï´Ù. °ÔÀÓ È¸»ç´Â ¿ÀºêÁ§Æ®¿¡ ´ëÇÑ ÀÚü Æ÷¸ËÀÌ ÀÖ½À´Ï´Ù. ±×·±µ¥ ÀÌ Æ÷¸ËÀ» °³¹ßÇÏ´Â ´Ü°è¿¡¼­ Á¦´ë·Î ÀÛµ¿ÇÏ´ÂÁö ºñ±³¸¦ Çϱâ À§Çؼ­ X-fileÀ» °¡Àå ¸¹ÀÌ »ç¿ëÇÕ´Ï´Ù. °ÔÀÓ ÇÁ·Î±×·¡¹ÖÀ» óÀ½ ¹è¿ì´Â »ç¶÷µéµµ °ÔÀÓ ¿ÀºêÁ§Æ®¸¦ X-file·Î ¸¹ÀÌ °¡Á®°©´Ï´Ù. µû¶ó¼­ X-file¿¡ ´ëÇÑ Å¬·¡½º¸¦ ¸¸µé¾î ³õ´Â °ÍÀº ÇÊ ¼ö ÀÔ´Ï´Ù.

 

Ŭ·¡½º¸¦ ¸¸µé±â À§ÇØ ÇÊ¿äÇÑ ÀڷᱸÁ¶¸¦ ¸ðÀ¸´Ï ´ÙÀ½°ú °°ÀÌ ¸Þ½¬, ÀçÁú, ÅØ½ºÃ³ °´Ã¼·Î ¸ð¾ÆÁý´Ï´Ù.

 

class CMcXFile

        LPDIRECT3DDEVICE9      m_pDev;

        char                   m_sFile[MAX_PATH];

        ID3DXMesh*             m_pMsh;

        D3DMATERIAL9*          m_pMtl;

        LPDIRECT3DTEXTURE9*    m_pTex;

        INT                    m_nMtl;

 

ÆÄÀÏ¿¡¼­ D3DXLoadMeshFromX() ÇÔ¼ö·Î ¸Þ½¬¸¦ Àоî¿À´Â °ÍÀº È£¶ûÀ̸¦ ¿Ã·Á º¸¾ÒÀ¸¸é ÀÌ¹Ì ¾Ë°í ÀÖ´Â ³»¿ëÀÔ´Ï´Ù.

 

ID3DXBuffer* AdjBuf = NULL;

ID3DXBuffer* MtlBuf = NULL;

hr = D3DXLoadMeshFromX(sFile, D3DXMESH_SYSTEMMEM, m_pDev

                       , &AdjBuf, &MtlBuf, 0, &nMtl, &m_pMsh);

 

´ÙÀ½À¸·Î ID3DXMesh¿¡¼­ ¹è¿î »ï°¢ÇüÀÇ ÀÎÁ¢ Á¤º¸¸¦ ÀÌ¿ëÇÑ ÃÖÀûÈ­¸¦ ÁøÇàÇÕ´Ï´Ù.

 

DWORD dOpt  = D3DXMESHOPT_ATTRSORT | D3DXMESHOPT_COMPACT | D3DXMESHOPT_VERTEXCACHE;

DWORD* pAdj = (DWORD*)AdjBuf->GetBufferPointer();

hr = m_pMsh->OptimizeInplace(dOpt, pAdj, 0, 0, 0);

 

DXSDKÀÇ ID3DXBuffer ÀÎÅÍÆäÀ̽º´Â ÀڷḦ ¿¬¼ÓÀûÀÎ ¸Þ¸ð¸® °ø°£¿¡ ÀúÀåÇϱâ À§Çؼ­ ¹ü¿ëÀûÀ¸·Î ¸¸µç ÀÚ·á ±¸Á¶ÀÔ´Ï´Ù. ID3DXBuffer ÀÎÅÍÆäÀ̽º´Â ÀÚ·á ÀÚü¸¦ °¡Á®¿À´Â GetBufferPointer()¿Í ÀúÀåµÈ ÀÚ·áÀÇ Å©±â(Byte)¸¦ °¡Á®¿À´Â GetBufferSize() ÇÔ¼ö°¡ ÀÖ½À´Ï´Ù.

GetBufferPointer() ÇÔ¼ö·Î ÀÚ·áÀÇ ½ÃÀÛ ÁÖ¼Ò¸¦ °¡Á®¿Í¼­ ÇÊ¿äÇÑ °æ¿ì¿¡ ij½ºÆÃÇØ¼­ »ç¿ëÇÕ´Ï´Ù. ID3DXBuffer °´Ã¼ÀÇ Release() ÇÔ¼ö¸¦ È£ÃâÇϸé ID3DXBuffer °´Ã¼ ³»ºÎ¿¡ ÀúÀåµÈ ÀÚ·áµéµµ °°ÀÌ ¼Ò¸êÇÕ´Ï´Ù. ÀÌ °´Ã¼´Â ÀÌÈÄ ½¦ÀÌ´õ¿¡¼­ ¿¡·¯ µîÀÇ ¸Þ½ÃÁö¸¦ ¹Ýȯ ¹ÞÀ» ¶§µµ »ç¿ëµË´Ï´Ù.

D3DXCreateBuffer() ¶ó´Â ÇÔ¼ö¸¦ »ç¿ëÇØ¼­ Á÷Á¢ ¿¬¼ÓµÈ ¸Þ¸ð¸®¸¦ È®º¸ÇÒ ¼ö ÀÖ½À´Ï´Ù.

 

»ï°¢Çü ÃÖÀûÈ­°¡ ³¡³ª¸é ÀçÁú°ú ÅØ½ºÃ³¸¦ »ý¼ºÇϰí ÀçÁú ¸ÕÀú º¹»ç ÇÕ´Ï´Ù.

 

// ÀçÁú°ú ÅØ½ºÃ³ »ý¼º

m_pMtl = new D3DMATERIAL9[m_nMtl];

m_pTex = new LPDIRECT3DTEXTURE9[m_nMtl];

 

// ÅØ½ºÃ³ Æ÷ÀÎÅÍ ÃʱâÈ­

memset(m_pTex, 0, sizeof(LPDIRECT3DTEXTURE9) *m_nMtl);

 

// ÀçÁú µ¥ÀÌÅÍ °¡Á®¿È

D3DXMATERIAL* pMtl = (D3DXMATERIAL*)MtlBuf->GetBufferPointer();

 

// ÀçÁú º¹»ç.

for(i=0; i<m_nMtl; ++i)

        memcpy(&(m_pMtl[i]), &(pMtl[i].MatD3D), sizeof(D3DMATERIAL9));

 

ÅØ½ºÃ³´Â Á¶±Ý ÁÖÀÇÇØ¾ß ÇÕ´Ï´Ù. X-file ³»ºÎ¿¡ ÀúÀåµÈ À̹ÌÁö °æ·Î¿Í ½ÇÁ¦ À̹ÌÁöÀÇ À§Ä¡°¡ ´Ù¸¦ ¼ö ÀÖ½À´Ï´Ù. °¡Àå ÁÁÀº ¹æ¹ýÀº ÇØ´ç X-file¿¡ ÅØ½ºÃ³¸¦ °°ÀÌ ³õ°Å³ª ¾Æ´Ï¸é X-fileÀÌ ÀÖ´Â Æú´õÀÇ Æ¯Á¤À̸§ÀÌ ÀÖ´Â ÇÏÀ§ Æú´õ¿¡ ÅØ½ºÃ³¸¦ °¡Áö°í ÀÖÀ¸¸é ÄÚµùÀÇ Àϰü¼ºÀÌ »ý±é´Ï´Ù.

¿©±â¼­´Â °°Àº °æ·Î¿¡ ÀÖ´Ù°í »ý°¢ÇÏ°í ´ÙÀ½°ú °°ÀÌ _splitpath() ÇÔ¼ö¿Í _makepath() ÇÔ¼ö·Î À̹ÌÁö °æ·Î¸¦ Á¶Á¤Çؼ­ ÅØ½ºÃ³°¡ »ý¼ºµÉ ¼ö°Ô ÀÖ°Ô ÇÕ´Ï´Ù.

 

char    sParentPath[MAX_PATH]={0}; char       dir[_MAX_DIR]={0};

_splitpath( sFile, NULL, dir, NULL, NULL);

_makepath(sParentPath, NULL, dir, NULL, NULL);

 

// ÅØ½ºÃ³ »ý¼º        

for(i=0; i<m_nMtl; ++i)

{

        char sTexFile[MAX_PATH]={0};

char fname[_MAX_FNAME]={0};

char ext[_MAX_EXT]={0};

        char* sTexSrc = pMtl[i].pTextureFilename;

 

        if(NULL == sTexSrc || strlen(sTexSrc)<3)

               continue;

 

        _splitpath( sTexSrc, NULL, NULL, fname, ext);

        _makepath(sTexFile, NULL, sParentPath, fname, ext);

 

        IDirect3DTexture9* pTx = NULL;

        D3DXCreateTextureFromFile(m_pDev, sTexFile, &pTx);

        m_pTex[i] = pTx;

 

Àüü ÄÚµå´Â daux07_xfile01.zipÀ» Âü°íÇϰí CMcScene::Create() ÇÔ¼öÀÇ ÁÖ¼®À» ¹Ù²Ù¾îº¸¸é ´ÙÀ½°ú °°Àº Dwarf¿Í °Ç¹°À» º¼ ¼ö ÀÖ½À´Ï´Ù.

 

 

<x-file: daux07_xfile01.zip>

 

daux07_xfile01.zipÀÇ Dwarf¸¦ ½ÇÇàÇÏ¸é °Ç¹°º¸´Ù »ó´çÈ÷ ÀÛ°Ô ³ª¿É´Ï´Ù. ¿ùµå Çà·ÄÀ» ¹Ù²Ù¾î¼­ ¹Ù²Ù¸é Å©°Ô Ãâ·ÂÇÒ ¼ö ÀÖÀ» °ÍÀÔ´Ï´Ù.

ÀÌ·¸°Ô X-fileÀÇ Å¬·¡½º ÀÛ¾÷Àº ³¡ÀÌ ³ª º¸ÀÔ´Ï´Ù. ±×·±µ¥ ¿©±â¼­ Àá±ñ »ý°¢ÇغÁ¾ß ÇÒ °ÍÀÌ ÀÖ½À´Ï´Ù. ¸¸¾à °°Àº ¸ðµ¨ÀÇ Dwarf¸¦ ¿©·¯ °³ Ãâ·ÂÇÏ°Ô µÈ´Ù¸é ¸Å ¹ø ÆÄÀÏ¿¡¼­ Àоî¿Í¾ß ÇÒ±î¿ä?

¸Å¹ø ÆÄÀÏ¿¡¼­ ºÒ·¯¿Í »ý¼ºÇÏ¸é º¸Á¶ ±â¾ï ÀåÄ¡¸¦ Á¢±ÙÇÏ´Â °ÍÀ̹ǷΠ·»´õ¸µ ¼ÓµµÀÇ ÀúÇÏ´Â ºÒÀ» º¸µí »·ÇÕ´Ï´Ù. ±×·¸´Ù¸é ÇϳªÀÇ ¸ðµ¨À» °¡Áö°í º¹Á¦Çؼ­ »ç¿ëÇÏ´Â ¹æ¹ýÀ» »ý°¢ÇÒ ¼ö ÀÖ½À´Ï´Ù.

 

¸Þ½¬ÀÇ ±âÇÏ Á¤º¸¸¦ º¹»çÇÏ´Â CloneMeshFVF() ÇÔ¼ö¸¦ ÅëÇØ¼­ Á¤Á¡°ú À妽º µîÀ» º¹»ç Çϰí ÅØ½ºÃ³´Â º¯ÇÏ´Â ÀÏÀÌ ¾øÀ¸¹Ç·Î ¿øº»¿¡¼­ ÂüÁ¶Çϵµ·Ï ÇÏ¸é µÉ °Í °°½À´Ï´Ù. ±×·±µ¥ ÀÌ ¹æ¹ýµµ ´õ »ý°¢ÇØ ºÁ¾ß ÇÕ´Ï´Ù. ÆÄƼŬ°ú °°ÀÌ Á¤Á¡ÀÇ À§Ä¡¸¦ ÆÄÀÌÇÁ¶óÀο¡ ¿Ã¸®±â Àü¿¡ ¹Ù²Ù¾î¾ß ÇÏ´Â °ÍÀº ±âÇÏ Á¤º¸¸¦ ¹Ýµå½Ã º¹»ç¸¦ ÇØ¾ß ÇÏÁö¸¸ ·»´õ¸µ ÆÄÀÌÇÁ¶óÀÎÀÇ ¿ùµå Çà·Ä¸¸ ¹Ù²Ù¾îµµ µÇ´Â ¿ÀºêÁ§Æ®´Â º¹»ç°¡ ¾Æ´Ñ ¿øº»À» ÂüÁ¶ÇÏ´Â ¹æ¹ýÀ¸·Î ¿ÀºêÁ§Æ®¸¦ ±¸¼ºÇØ¾ß ÇÕ´Ï´Ù.

 

 ÀÌ·± ÁÁÀº ¾ÆÀ̵ð¾î°¡ À־ ¸·»ó ÄÚµå·Î Ç¥Çö ÇÏ´Â °ÍÀÌ ¾î·Á¿ï ¼öµµ ÀÖ½À´Ï´Ù. ÀÌ·² ¶§ ¹«Á¶°Ç ÀÌÀüÀÇ Äڵ带 ´Ù ¹Ù²ÙÁö ¸»°í Àß ±¸¼ºµÇ¾î ÀÖ´Ù¸é »õ·Î¿î Ŭ·¡½º¸¦ Ãß°¡Çؼ­ °ü°è¸¦ ¸¸µé¾î °¡´Â °ÍÀÌ ´õ ÁÁ½À´Ï´Ù.

 

±×¸²Ã³·³ IMcXFile¸¦ ¼ø¼ö °¡»óÇÔ¼öµé·Î ±¸¼ºµÈ ÀÎÅÍÆäÀ̽º¸¦ Çϳª¸¦ ¸¸µé°í CMcXFile Ŭ·¡½º´Â À̸¦ »ó¼ÓÇÕ´Ï´Ù. ±×¸®°í ·»´õ¸µ ¿ÀºêÁ§Æ®ÀÎ CMcXFileIns Ŭ·¡½º´Â IMcXFile Ŭ·¡½º¸¦ »ó¼Ó ¹Þ°í CMcXFile Ŭ·¡½º¸¦ Æ÷ÇÔÇÕ´Ï´Ù.

¿©±â¼­ ¿øÄ¢À» Çϳª ¸¸µé¸é CMcXFileÀº ·»´õ¸µÀÌ °¡´ÉÇØµµ ±× ¿ªÇÒÀ» ÇÏÁö ¾Ê°í ¿ÀÁ÷ CMcXFileIns Ŭ·¡½º¸¸ Àå¸éÀ» ·»´õ¸µ ÇÏ°Ô Çϸé CMcXFileÀÇ ÀνºÅϽº´Â ¸Þ¸ð¸® º¹Á¦¿ëÀ¸·Î¸¸ »ç¿ëÇÏ°Ô µË´Ï´Ù.

 

<X-file °´Ã¼¸¦ Ç¥ÇöÇϱâ À§ÇÑ Å¬·¡½º ±¸Á¶>

 

À̰ÍÀ» ÄÚµå·Î ±¸ÇöÇØ º¸¸é ¸ÕÀú IMcXFileÀÇ ÀÎÅÍÆäÀ̽º¸¦ ´ÙÀ½°ú °°ÀÌ ¸¸µì´Ï´Ù.

 

#define interface struct

 

interface IMcXFile

{

        virtual INT    Create(¡¦, char* sFileName=NULL, void* pOriginal=NULL)=0;

        virtual void   Destroy()=0;

        virtual INT    FrameMove()=0;

        virtual void   Render()=0;

 

        virtual IMcXFile* GetOrigin()=0;

        virtual void   SetWorldMatrix(const D3DXMATRIX*)=0;

        virtual D3DXMATRIX* GetWorldMatrix()=0;

};

 

Create(), Destroy(), FrameMove(), Render()ÇÔ¼ö´Â °´Ã¼ÀÇ »ý¼º, ¼Ò¸ê, µ¥ÀÌÅÍ °»½Å, ·»´õ¸µ¿¡ ´ëÇÑ ÇÔ¼ö ÀÔ´Ï´Ù. GetOrigin() ÇÔ¼ö´Â X-fileÀÇ ³»¿ëÀ» °®°í ÀÖ´Â CMcXFileÀÇ °´Ã¼¸¦ ¹ÝȯÇÏ´Â ÇÔ¼ö ÀÔ´Ï´Ù. °¢ ·»´õ¸µ ¿ÀºêÁ§Æ®´Â ¿ùµå Çà·ÄÀÌ ÀÖ¾î¾ß ÇϹǷΠ¿ùµå Çà·ÄÀ» ¼³Á¤Çϰųª °¡Á®¿Ã ¼ö ÀÖ´Â ÇÔ¼ö¸¦ ÁغñÇÕ´Ï´Ù.

 

°´Ã¼ÀÇ »ý¼ºÀº ´ÙÀ½°ú °°Àº ÇÔ¼ö·Î Ŭ·¡½ºÀÇ ÀνºÅϽº¸¦ ¸¸µì´Ï´Ù.

 

INT McXCreate_Xfile(IMcXFile** pOut, LPDIRECT3DDEVICE9 pDev, char* sFile, void* pOriginal)

{

        IMcXFile*      pObj= NULL;

 

        if(sFile)

               pObj = new CMcXFile;

        else if(pOriginal)

               pObj = new CMcXFileIns;

        else{   *pOut = NULLreturn -1;     }

 

        if(FAILED(pObj->Create(pDev, sFile, pOriginal)))

        {

               delete pObj;   return -1;

        }

 

        *pOut = pObj;

        return 0;

}

 

ÀÌ ÇÔ¼ö´Â ÇØ´ç ÀνºÅϽº¸¦ ¾î´À Ŭ·¡½º¿¡¼­ ¸¸µéÁö °áÁ¤ÇÕ´Ï´Ù. ¸¸¾à ÆÄÀÏ À̸§ÀÌ ÁÖ¾îÁö¸é CMcXFile Ŭ·¡½ºÀÇ °´Ã¼¸¦ ¸¸µé°í ÆÄÀÏ À̸§ ´ë½Å CMcXFile °´Ã¼¿¡ ´ëÇÑ Original Æ÷ÀÎÅͰ¡ ÁÖ¾îÁö¸é º¹Á¦¿¡ ´ëÇÑ ¿ä±¸·Î ¹Þ¾Æ µé¿© CMcXFileIns Ŭ·¡½ºÀÇ °´Ã¼¸¦ ¸¸µì´Ï´Ù.

CMcXFile Ŭ·¡½º´Â ´ÙÀ½°ú °°ÀÌ IMcXFile ÀÎÅÍÆäÀ̽º¸¦ »ó¼Ó ¹Þ°í º¹Á¦¿¡ ÇÊ¿äÇÑ Á¤º¸¸¦ Àü´Þ ÇÒ ¼ö ÀÖµµ·Ï ¸î °³ÀÇ ¸Þ¼Òµå¸¦ Ãß°¡Çß½À´Ï´Ù.

 

class CMcXFile : public IMcXFile

¡¦

public:

        ID3DXMesh*             GetMesh()      {       return m_pMsh; }

        D3DMATERIAL9*          GetMaterial()  {       return m_pMtl; }

        LPDIRECT3DTEXTURE9*    GetTexture()   {       return m_pTex; }

        INT                    GetNumMaterial(){      return m_nMtl; }

 

·»´õ¸µ ¿ªÇÒÀ» ÇÏ°Ô µÉ CMcXFileIns´Â ¿øº» CMcXFile Ŭ·¡½ºÀÇ °´Ã¼¿Í Àå¸é ±¸¼º¿¡ ÇÊ¿äÇÑ ¿ùµå Çà·ÄÀ» ¸â¹ö·Î ±¸¼ºÇÕ´Ï´Ù. ¶ÇÇÑ ¿ÜºÎ¿¡¼­ ¿ùµé Çà·ÄÀ» ¼³Á¤Çϰųª °¡Á®¿Ã ¼ö ÀÖ´Â ¸â¹ö ÇÔ¼ö¸¦ ±¸ÇöÇÕ´Ï´Ù.

 

class CMcXFileIns : public IMcXFile

¡¦

        CMcXFile*      m_pOrg;        // Original X-file Instance

        D3DXMATRIX     m_mtWld;

 

public:

        virtual IMcXFile* GetOrigin()         {       return m_pOrg;         }

        virtual void   SetWorldMatrix(const D3DXMATRIX* v){  m_mtWld = *v;  }

        virtual D3DXMATRIX* GetWorldMatrix()  {       return &m_mtWld;       }

 

³²Àº °ÍÀº CMcXFileIns Ŭ·¡½º¿¡¼­ ·»´õ¸µ¿¡ ÇÊ¿äÇÑ µ¥ÀÌÅÍ ÃʱâÈ­ ÀÔ´Ï´Ù. CMcXFileIns:: Create() ÇÔ¼ö¸¦ º¸¸é ´ÙÀ½°ú °°ÀÌ °£´ÜÇÏ°Ô Ã³¸®Çϰí ÀÖÀ½À» º¼ ¼ö ÀÖ½À´Ï´Ù.

 

INT CMcXFileIns::Create(¡¦, void* pOriginal)

¡¦

        m_pOrg = (CMcXFile*)pOriginal;

        m_pMsh = m_pOrg->GetMesh();

        m_pMtl  = m_pOrg->GetMaterial();

        m_pTex  = m_pOrg->GetTexture();

        m_nMtl  = m_pOrg->GetNumMaterial();

 

¸Þ½¬, ÀçÁú, ÅØ½ºÃ³¿¡ ´ëÇÑ ÁÖ¼Ò¸¦ °¡Áú ÇÊ¿ä´Â ¾øÁö¸¸ ·»´õ¸µ ÇÔ¼ö¿¡¼­ ¸Å¹ø ¿øº»¿¡¼­ È£ÃâÇÏ´Â ºÎ´ãÀ» ´ú±â À§Çؼ­ÀÔ´Ï´Ù.

 

ÀÌ Å¬·¡½ºÀÇ Render()ÇÔ¼ö´Â ´ÙÀ½°ú °°ÀÌ ¿ùµå Çà·ÄÀ» ¼³Á¤ÇÏ°í ¿øº»ÀÇ ¸Þ½¬, ÀçÁú µîÀÇ ÁÖ¼Ò¸¦ ÀúÀåÇÑ Æ÷ÀÎÅÍ·Î ·»´õ¸µ ÇÕ´Ï´Ù.

 

void CMcXFileIns::Render()

¡¦

        m_pDev->SetTransform(D3DTS_WORLD, &m_mtWld);

 

        for(i=0; i<m_nMtl; ++i)

        {

               m_pDev->SetMaterial( &m_pMtl[i] );

               m_pDev->SetTexture( 0, m_pTex[i] );

               m_pMsh->DrawSubset( i );

        }

 

        static D3DXMATRIX mtI(1,0,0,00,1,0,00,0,1,00,0,0,1);

        m_pDev->SetTransform(D3DTS_WORLD, &mtI);

 

¸¶Áö¸·À¸·Î Å×½ºÆ®°¡ ³²¾Ò½À´Ï´Ù. daux07_xfile02.zipÀÇ CMcScene Ŭ·¡½º ¼±¾ðÀ» º¸¸é ´ÙÀ½°ú °°ÀÌ ¿øº»°ú ¿øº»ÀÇ µ¥ÀÌÅ͸¦ ÂüÁ¶ÇÏ´Â 3°³ÀÇ ·»´õ¸µ ¿ÀºêÁ§Æ® ÀνºÅϽº¸¦ º¼ ¼ö ÀÖ½À´Ï´Ù.

 

class CMcScene

¡¦

        IMcXFile*      m_pXOrg;

        IMcXFile*      m_pXClone1;

        IMcXFile*      m_pXClone2;

        IMcXFile*      m_pXClone3;

 

3°³ÀÇ ·»´õ¸µ ¿ÀºêÁ§Æ®µéÀº CMcScene::Create() ÇÔ¼ö¿¡¼­ ´ÙÀ½°ú °°ÀÌ ¿øº»À» ¸ÕÀú »ý¼ºÇÑ ´ÙÀ½ ÀÌ ÀνºÅϽº¸¦ ÀÌ¿ëÇØ¼­ »ý¼ºÇÕ´Ï´Ù.

 

INT CMcScene::Create(LPDIRECT3DDEVICE9 pDev)

¡¦

        hr = McXCreate_Xfile(&m_pXOrg, m_pDev, "xfile/dwarf/dwarf.x");

 

        hr = McXCreate_Xfile(&m_pXClone1, m_pDev, NULL, m_pXOrg);

        hr = McXCreate_Xfile(&m_pXClone2, m_pDev, NULL, m_pXOrg);

        hr = McXCreate_Xfile(&m_pXClone3, m_pDev, NULL, m_pXOrg);

 

¿ùµå Çà·Ä °»½Å°ú ·»´õ¸µÀº CMcScene::FrameMove() ÇÔ¼ö¿Í CMcScene::Render() ÇÔ¼ö¿¡¼­ ±¸ÇöµÇ¾î ÀÖÀ¸´Ï Âü°í Çϱ⠹ٶø´Ï´Ù.

daux07_xfile02.zip¸¦ ½ÇÇàÇÏ¸é ´ÙÀ½°ú °°ÀÌ Dwarf 3°³°¡ ÀÖ´Â È­¸éÀ» º¼ ¼ö ÀÖ½À´Ï´Ù.

 

<X-file Ŭ·¡½º¿¡ ´ëÇÑ Ãß»óÈ­: daux07_xfile02.zip>

 

 

3.8 X-file Animation

3.8.1 Skinning Animation ±âÃÊ

Á¤ÀûÀÎ ¸ðµ¨ÀÇ DXSDKÀÇ Sample Æú´õ¿¡ SkinnedMesh ¿¹Á¦°¡ ÀÖ½À´Ï´Ù. ÀÌ ¿¹Á¦´Â ¾Ö´Ï¸ÞÀÌ¼Ç Á¤º¸°¡ Æ÷ÇԵǾî ÀÖ´Â X-fileÀ» È­¸é¿¡ Ãâ·ÂÇØ ÁÝ´Ï´Ù.

 

<DXSDK Skinning ¿¹Á¦>

 

3D °ÔÀÓ¿¡¼­ ¾Ö´Ï¸ÞÀ̼ÇÀ̶ó´Â °ÍÀº °£´ÜÇÏ°Ô ½Ã°£¿¡ ´ëÇÑ Á¤Á¡ÀÇ À̵¿À̶ó ÇÒ ¼ö ÀÖ°Ú½À´Ï´Ù. ÀÌ Á¤Á¡À» À̵¿ ½ÃŰ´Â ¹æ¹ýÀº ½Ã°£¿¡ ´ëÇØ¼­ ¿ÀºêÁ§Æ®ÀÇ ¸ðµç À§Ä¡¸¦ ÀúÀåÇÑ µ¥ÀÌÅÍ¿¡¼­ °¡Á®¿À´Â ¹æ¹ýÀÌ ÀÖ½À´Ï´Ù. ÀÌ ¹æ¹ýÀº °¡Àå ºü¸£°í Á¤È®ÇÑ ¾Ö´Ï¸ÞÀ̼ÇÀ» ¸¸µé¾î ³»Áö¸¸ ¹®Á¦´Â Á¤Á¡ÀÇ ¼ýÀÚ¿Í ¾Ö´Ï¸ÞÀ̼ÇÀÇ ½Ã°£¿¡ °ö¿¡ ¸Þ¸ð¸®¸¦ ¾öû³ª°Ô ÇÊ¿ä·Î ÇÕ´Ï´Ù.

ÀÌÀÇ °³¼± Ã¥À¸·Î ¸¹ÀÌ ¼±ÅÃÇÏ´Â °ÍÀÌ ÀÚ·á ±¸Á¶ Áß ³ª¹« ±¸Á¶(tree structure)ó·³ ¿ÀºêÁ§Æ®¸¦ ±¸¼ºÇϰí ÀÖ´Â °³º°ÀûÀÎ Geometry¸¦ ºÎ¸ð¿Í Àڽİ£ÀÇ °ü°è·Î ¼³Á¤Çϰí, ½Ã°£¿¡ ´ëÇÑ º¯È­¸¦ °¢ GeometryÀÇ Çà·Ä·Î ÀúÀåÇØ¼­ ÇØ´ç ½Ã°£¿¡ ºÎ¸ðÀÇ Çà·ÄÀ» ÀÚ½ÅÀÇ Áö¿ª Çà·Ä¿¡ °öÇØ ¾Ö´Ï¸ÞÀ̼ÇÀ» ÇÏ´Â ¹æ¹ýÀÌ ÀÖ½À´Ï´Ù. ÀÌ ¹æ¹ýÀ» »ç¿ëÇÏ¸é ½Ã°£ÀÌ ´Ã¾î³ªµµ ¾Ö´Ï¸ÞÀÌ¼Ç Á¤º¸ÀÇ Çà·Ä ¸¸ Ä¿Áú »Ó Á¤Á¡ÀÇ °³¼ö¿Í´Â ¹«°üÇÏ°Ô µÇ¾î È¿À²ÀûÀÎ ÇÁ·Î±×·¥ÀÌ µÇ°í ÇöÀç ´ëºÎºÐÀÇ °ÔÀÓÀº ÀÌ ¹æ¹ýÀ» ä¿ëÇϰí ÀÖ½À´Ï´Ù

3D¿¡¼­ ÇϳªÀÇ Çà·ÄÀ» ÇϳªÀÇ ¿ÀºêÁ§Æ®¿¡ °¡ÇÏ¸é ¿ÀºêÁ§Æ®¸¦ ±¸¼ºÇÏ´Â Á¤Á¡ »çÀÌÀÇ °ü°è ƯÈ÷, °Å¸®ÀÇ ºñÀ²Àº ÀÌÀü°ú º¯ÇÔÀÌ ¾ø½À´Ï´Ù. ÀÌ·¸°Ô ÀÌÀüÀÇ Æ¯¼ºÀÌ À¯ÁöµÇ´Â ¾Ö´Ï¸ÞÀ̼ÇÀ» µüµüÇÑ ¾Ö´Ï¸ÞÀ̼Ç(Rigid body: °­Ã¼)¶ó ºÎ¸£´Â °­Ã¼ ¾Ö´Ï¸ÞÀ̼ÇÀÔ´Ï´Ù. °­Ã¼¶ó´Â °ÍÀº ¼øÀüÈ÷ ¹°¸®Çп¡¼­ ¿Â ¿ë¾î·Î ¾î¶² ¿ÜºÎÀÇ ÈûÀ» °¡Çصµ ±× ¼ºÁúÀÌ º¯ÇÏÁö ¾Ê´Â ½Ç ¼¼°è´Â Á¸ÀçÇÏÁö ¾Ê´Â °¡»óÀÇ ¹°Ã¼ÀÔ´Ï´Ù. °­Ã¼ ¾Ö´Ï¸ÞÀ̼ÇÀ» È­¸é¿¡ Ç¥ÇöÇÏ¸é µ¿ÀÛÀÌ ·Îº¿Ã³·³ µüµüÇÕ´Ï´Ù.

 

Mechatronics¸¦ ¹è°æÀ¸·Î °ÔÀÓÀ» ¸¸µç´Ù¸é °­Ã¼ ¾Ö´Ï¸ÞÀÌ¼Ç ¸¸À¸·Îµµ ÃæºÐÇÕ´Ï´Ù. ±×·±µ¥ ÀÌ °­Ã¼ ¾Ö´Ï¸ÞÀ̼ÇÀ» »ç¶÷À̳ª µ¿¹°À» ÁÖ¿ä ¼ÒÀç·Î ÇÏ´Â °ÔÀÓ¿¡ Àû¿ëÇÏ¸é ÆÈ°ú °°Àº °üÀý ºÎÀ§¿¡¼­ ÇǺΰ¡ ´Ù¸¥ ÇǺθ¦ ÆÄ°í µé°Å³ª ¹ú¾îÁö´Â Çö»óÀÌ ¸¸µé¾îÁ® ÀÚ¿¬½º·¯¿òÀÌ ¸¹ÀÌ °¨¼ÒµË´Ï´Ù.

ƯÈ÷ °ÝÅõ °ÔÀÓó·³ ij¸¯ÅͰ¡ È­¸é °¡µæ ä¿ì´Â »óȲÀ̶ó¸é °­Ã¼ ¾Ö´Ï¸ÞÀ̼ÇÀº Á¶±Ý ºÎÁ·ÇÕ´Ï´Ù. °ú°Å¿¡´Â ÀÌ·± ¹®Á¦¸¦ ÆÈÀ̳ª ´Ù¸®¿¡ º¸È£´ë ¶Ç´Â °©¿ÊÀ» µ¡¾º¿ö¼­ ÇØ°áÀ» ÇßÀ¸¸ç Áö±Ýµµ ¸¹ÀÌ »ç¿ëÇÏ´Â ¸ÚÁø ¹æ¹ýÀÔ´Ï´Ù. ÃÖ±Ù¿¡´Â Skinning À̶ó´Â ¹æ½ÄÀÌ µµÀÔµÇ¾î °üÀý ºÎÀ§ÀÇ ºÎ ÀÚ¿¬½º·¯¿î ¸ð½ÀÀ» ¾ø¾Ý½À´Ï´Ù. ÀÌ·Î ÀÎÇØ °ÔÀÓ Ä³¸¯ÅÍÀÇ À°°¨ÀûÀÌ°í ¾ß¼ºÀûÀÎ ¸ð½ÀÀ» ³ªÅ¸³»±â À§ÇØ °ÉÄ¡´Â ¿Ê°¨ÀÇ ¾çÀÌ ¸¹ÀÌ ÁÙ¾ú½À´Ï´Ù.

 

<°­Ã¼ ¾Ö´Ï¸ÞÀ̼ǰú Skinning ¾Ö´Ï¸ÞÀ̼Ç>

 

Skinning ¾Ö´Ï¸ÞÀÌ¼Ç ±¸ÇöÀº ÀǿܷΠ°£´ÜÇÕ´Ï´Ù. Á¤Á¡À» ±¸¼ºÇÏ´Â Geometry Áß¿¡¼­ °üÀý ºÎÀ§¿¡ ÇØ´çÇÏ´Â Á¡µéÀº ÇØ´ç GeometryÀÇ Çà·Ä»Ó¸¸ ¾Æ´Ï¶ó ÀÎÁ¢ÇÑ GeometryÀÇ Çà·Äµµ °°ÀÌ Àû¿ëÇÏ´Â °ÍÀÔ´Ï´Ù.

±×¸²¿¡¼­ °­Ã¼ ¾Ö´Ï¸ÞÀ̼ÇÀÇ Á¤Á¡ p´Â Geometry AÀÇ Çà·Ä¿¡¸¸ ¿µÇâÀ» ¹ÞÁö¸¸ Skinning ¾Ö´Ï¸ÞÀ̼ÇÀÇ Á¤Á¡ p´Â Geometry BÀÇ Çà·Ä¿¡µµ ¿µÇâÀ» ¹Þ½À´Ï´Ù. Á¤Á¡¿¡ ¿µÇâÀ» ÁÖ´Â Á¤µµ¸¦ ºñÁß(Weight)·Î ¼³Á¤Çؼ­ ¼ö½ÄÀ¸·Î Ç¥Çö ÇÏ¸é ´ÙÀ½°ú °°½À´Ï´Ù.

 

Á¤Á¡ pÀÇ º¯È¯ = (p * Geometry A Çà·Ä) * Geometry AÀÇ ºñÁß

 + (p * Geometry B Çà·Ä) * Geometry BÀÇ ºñÁß

 

´Ü¼øÇÏ°Ô 2°³ÀÇ Çà·Ä ¸¸ °üÀýºÎÀ§ÀÇ Á¤Á¡¿¡ Àû¿ëÇÏ¸é ¹ú¾îÁö°Å³ª °ãÄ¡´Â ¹®Á¦´Â ÇØ°áÀÌ µÇÁö¸¸ ºÎµå·¯¿î °î¸éÀ» ¸¸µé±â°¡ ¾î·Æ½À´Ï´Ù. À̸¦ À§ÇØ ¿©·¯ °³ÀÇ Çà·ÄÀ» ÀûÁ¤¿¡ Àû¿ëÀ» ÇÕ´Ï´Ù.

 

Á¤Á¡ pÀÇ º¯È¯ = (p * Geometry A Çà·Ä) * Geometry AÀÇ ºñÁß

 + (p * Geometry B Çà·Ä) * Geometry BÀÇ ºñÁß + ¡¦

+ (p * Geometry M Çà·Ä) * Geometry MÀÇ ºñÁß

 

¼öÇÐ ±âÈ£¸¦ »ç¿ëÇØ¼­ Ç¥ÇöÇÏ¸é ¿µÇâÀ» ÁÖ´Â Çà·ÄÀ» , ºñÁßÀ» ¶ó ÇÏ¸é º¯È¯ ÈÄÀÇ Á¤Á¡ À§Ä¡ ´Â ´ÙÀ½°ú °°ÀÌ Ç¥Çö µË´Ï´Ù.

 

 

°ýÈ£ ¾ÈÀÇ Á¡ Àº ¥Ò¹ÛÀ¸·Î »©³»¿Ã ¼ö ÀÖÀ¸¹Ç·Î ¼ö½ÄÀ» Á¤¸®Çϸé

 

 , 

 

ÀÌ µË´Ï´Ù. ¿ìÃøÀÇ ½ÄÀº ÀÌÀüÀÇ ½Äó·³ °¢ Çà·Ä¸¶´Ù Á¤Á¡À» º¯È¯ ½ÃŰ´Â °ÍÀÌ ¾Æ´Ï¶ó °¢ Çà·Ä¿¡ ´ëÇØ¼­  °è»êÀ» ¸ÕÀúÇϰí À̵éÀ» ´õÇÑ ÀüºÎ ´õÇÑ ´ÙÀ½¿¡ Á¤Á¡ÀÇ º¯È¯À» ¼öÇàÇϱ⠶§¹®¿¡ ó¸® ¼Óµµ¿¡ À̵æÀÔ´Ï´Ù. ±×¸®°í ¸ðµç ºñÁßÀÇ ÇÕÀ» 1·Î À¯ÁöÇÕ´Ï´Ù. ¸¸¾à 1º¸´Ù Å©°Å³ª ÀÛÀ¸¸é Á¤Á¡ÀÇ À§Ä¡¿¡ Å©±â º¯È¯ÀÌ Àû¿ëµÈ °Í°ú °°Àº »óȲÀ» ¸¸µì´Ï´Ù. Á¤Á¡¿¡ ÇϳªÀÇ ºñÁ߸¸ ÀÖ°í °ªÀÌ 1À̶ó¸é ÀÌ ¾Ö´Ï¸ÞÀ̼ÇÀº °­Ã¼ ¾Ö´Ï¸ÞÀ̼ǰú °°½À´Ï´Ù. µû¶ó¼­ °­Ã¼ ¾Ö´Ï¸ÞÀ̼ÇÀº Skinning ¾Ö´Ï¸ÞÀ̼ÇÀÇ ºÎºÐ ÁýÇÕÀ̶ó ÇÒ ¼ö ÀÖ½À´Ï´Ù.

ÀÌ·¸°Ô °£´ÜÇÑ ¼ö½Ä Á¶Â÷µµ Çϵå¿þ¾î¿¡¼­ Áö¿øµÇ±â ½ÃÀÛÇÑ °ÍÀº ÃÖ±ÙÀÇ ÀÏÀÔ´Ï´Ù.

 

°íÁ¤ ±â´É ÆÄÀÌÇÁ¶óÀο¡¼­ D3D´Â ÇϳªÀÇ Á¤Á¡¿¡ ÃÖ´ë 4°³±îÁö ¿µÇâÀ» ÁÖ´Â Çà·ÄÀ» ¼³Á¤ ÇÒ ¼ö ÀÖ°í ÃÖ´ë 255°³±îÁö ¿µÇâÀ» ÁÖ´Â Çà·ÄµéÀ» ¸¸µé ¼ö ÀÖ½À´Ï´Ù. (½¦ÀÌ´õ¸¦ »ç¿ëÇϸé ÀÌ Á¦ÇÑÀº °ÅÀÇ ¾ø½À´Ï´Ù.) ÇÏÁö¸¸ Çϵå¿þ¾î´Â D3D ¶æ´ë·Î Á¤Á¡¿¡ 4°³ÀÇ Çà·ÄÀ» ¿¬°áÇÒ ¼ö ÀÖÁö¸¸ ¿µÇâÀ» ÁÙ ¼ö ÀÖ´Â Çà·ÄµéÀÇ ÃÑ ¼ö°¡ 255°³°¡ ¾ÈµÉ ¼ö ÀÖ½À´Ï´Ù.

 

±×·¡¼­ ¸ÕÀú ÇÁ·Î±×·¥À» Àû¿ëÇϱâ Àü¿¡ Çϵå¿þ¾î¿¡¼­ Áö¿øµÇ´Â Çà·ÄÀÇ ÃÖ´ë ¼ýÀÚ¸¦ ´ÙÀ½°ú °°ÀÌ È®ÀÎ ÇÕ´Ï´Ù.

 

D3DCAPS9 d3dCaps;

m_pDev->GetDeviceCaps( &d3dCaps );

m_nMaxMatrixSize = d3dCaps.MaxVertexBlendMatrixIndex;

 

°£´ÜÇÑ Skinning ¿¹Á¦·Î "űرâ ÈÖ³¯¸®¸ç" ¸¦ ¸¸µé¾î º¾½Ã´Ù. ¸ÕÀú ´ÙÀ½°ú °°ÀÌ È­¸é¿¡ űر⸦ Çϳª Ãâ·ÂÇÕ´Ï´Ù.

 

 

<űرâ Á¤Á¡>

 

űرⰡ ¹Ù¶÷¿¡ Á¦´ë·Î ÆÞ·°À̵µ·Ï Á¤Á¡ ¹öÆÛ¸¦ ±×¸²ÀÇ ¿ÞÂÊó·³ »ï°¢ÇüÀ» 40°³ Á¤µµ »ý¼ºÇÕ´Ï´Ù.

¿ì¸®ÀÇ ¸ñÇ¥´Â ¿ÞÂÊ¿¡ Ç¥½ÃµÈ »ï°¢ÇüÀ» ¿òÁ÷ÀÌ´Â °ÍÀ¸·Î Á¤Á¡ ¸¶´Ù Çà·ÄÀ» °¢°¢ µû·Î ¼³Á¤ÇÒ °ÍÀÔ´Ï´Ù. ¿À¸¥ÂÊ È­¸é°ú °°Àº Á¤Á¡À» Ãâ·ÂÇϱâ À§Çؼ­ °¡Áö´Â ±¸Á¶Ã¼´Â ´ÙÀ½°ú °°À» °ÍÀÔ´Ï´Ù.

 

struct VtxUV1

{

        D3DXVECTOR3    p;

        FLOAT          u, v;

        enumFVF = (D3DFVF_XYZ |D3DFVF_TEX1),      };

};

ÀÌ ±¸Á¶Ã¼¸¦ °³·®Çؼ­ Çà·ÄÀÇ À妽º¿Í ºñÁßÀ» ¼³Á¤ÇÕ´Ï´Ù. ¿¹¸¦ µé¾î Á¤Á¡ Çϳª¿¡ ¿µÇâÀ» ÁÖ´Â Çà·ÄÀ» µÎ °³·Î ¼³Á¤ÇÑ´Ù¸é Á¤Á¡ ±¸Á¶Ã¼´Â ´ÙÀ½°ú °°ÀÌ ¸¸µé¾î¾ß ÇÕ´Ï´Ù.

 

struct VtxUV1

{

        D3DXVECTOR3    p;

 

        FLOAT           g;      // ºñÁß(Weight)

        BYTE            m[4];   // Çà·ÄÀÇ À妽º

¡¦

        enumFVF = (D3DFVF_XYZB2 | D3DFVF_LASTBETA_UBYTE4 | ¡¦),  };

};

 

±¸Á¶Ã¼¸¦ º¸¸é ºñÁßÀº floatÇü 1°³·Î ¼³Á¤µÇ¾î ÀÖ½À´Ï´Ù. À̰ÍÀº Çϳª¸¦ ¼³Á¤ÇÏ¸é ³ª¸ÓÁö Çϳª´Â ÆÄÀÌÇÁ¶óÀο¡¼­ 1.0f - g °ªÀ¸·Î ÀÚµ¿ °è»ê µË´Ï´Ù. Çà·ÄÀÇ À妽º´Â m º¯¼ö¿¡ ÀúÀåÇÕ´Ï´Ù.

FVF¿¡¼­ XYZ µÚ¿¡ B2°¡ ºÙ¾ú½À´Ï´Ù. À̰ÍÀº Blending À妽ºÀÇ °³¼ö°¡ 2¸¦ ÀǹÌÇϸç Çà·ÄÀÇ À妽º 4¹ÙÀÌÆ® m¸¦ ÇÏÀ§ ¹ÙÀÌÆ®ºÎÅÍ index0, index 1 µÎ °³ÀÇ À妽º »ç¿ëÀ» ¶æÇÕ´Ï´Ù.

D3DFVF_LASTBETA_UBYTE4´Â ¾ÕÀÇ ±¸Á¶Ã¼Ã³·³ ºñÁß°ú À妽º¸¦ µ¿½Ã¿¡ °¡Áö°í ÀÖÀ» ¶§ ¸¶Áö¸· °ªÀ» unsigned byte 4°³¸¦ À妽º·Î »ç¿ëÇÔÀ» ÀǹÌÇÕ´Ï´Ù. °ÅÀÇ ÀÌ Æ÷¸ËÀ» »ç¿ëÇϱ⠶§¹®¿¡ ¹öÅØ½º¿¡ Çà·ÄÀ» ¿©·¯ °³ ¼³Á¤ÇÒ ¶§´Â ÀÌ Ç÷¡±×´Â °íÁ¤À̶ó »ý°¢ÇÏ´Â °ÍÀÌ ÁÁ½À´Ï´Ù.

ÀÌ·¸°Ô Á¤Á¡¿¡ Çà·ÄÀÇ À妽º¸¦ Àû¿ëÇØ¼­ SkinningÀ» ±¸ÇöÇϱ⠶§¹®¿¡ (Matrix) Indexed ¹æ½Ä ¶Ç´Â Matrix Palette ¹æ½ÄÀÇ Á¤Á¡ ºí·»µù(Blending) À̶ó ºÎ¸¨´Ï´Ù.

 

¾ÆÁ÷ Àͼ÷ÇÏÁö ¾ÊÀ¸´Ï ºñ½ÁÇÑ ¿¹¸¦ Çϳª ´õ ¸¸µé¾îº¾½Ã´Ù. Á¤Á¡¿¡ ¿µÇâÀ» ÁÖ´Â Çà·ÄÀÌ 3°³ÀÎ Á¤Á¡ ±¸Á¶Ã¼¿Í FVF´Â ±¸¼ºÇÒ±î¿ä?

 

struct VtxUV1

{

        D3DXVECTOR3    p;

 

        D3DXVECTOR2    g;      // ºñÁß(Weight)

        DWORD           m;      // Çà·ÄÀÇ À妽º

        ¡¦

        enumFVF = (D3DFVF_XYZB3 | D3DFVF_LASTBETA_UBYTE4 | ¡¦),  };

};

 

´Ù½Ã űر⠹®Á¦·Î µ¹¾Æ°¡¼­ Çà·ÄÀ» 4°³ ¼³Á¤À» ÇÒ ¼ö ÀÖ°í, ÅØ½ºÃ³ÀÇ ÁÂÇ¥°¡ Àû¿ëµÇ´Â ±¸Á¶Ã¼´Â ´ÙÀ½°ú °°À» °ÍÀÔ´Ï´Ù.

 

struct VtxBlend

{

        D3DXVECTOR3    p;             // Á¤Á¡ÀÇ º¯È¯µÈ ÁÂÇ¥

 

        FLOAT          g[3];          // blend weight

        BYTE           m[4];          // Index

 

        FLOAT          u, v;          // UV

¡¦

        enumFVF = (D3DFVF_XYZB4 | D3DFVF_LASTBETA_UBYTE4 | D3DFVF_TEX1), };

};

 

ÀÌ ±¸Á¶Ã¼¸¦ ¹Þ¾ÆµéÀÌ´Â ÆÄÀÌÇÁ¶óÀÎÀº Çà·ÄÀ» ´ÙÀ½°ú °°ÀÌ °è»êÀ» ÇÑ ´ÙÀ½ Á¤Á¡ÀÇ À§Ä¡¸¦ º¯È¯ÇÕ´Ï´Ù.

 

 

´ÙÀ½À¸·Î űرâÀÇ Á¤Á¡¿¡ ¿µÇâÀ» ÁÖ´Â Çà·Ä ¹è¿­ÀÇ Å©±â¸¦ D3D°¡ Áö¿øÇÏ´Â ÃÖ´ë °ªÀ¸·Î ¼³Á¤ÇÕ´Ï´Ù.

 

D3DXMATRIX     m_mtWld[256];

 

´ÙÀ½À¸·Î Á¤Á¡ µ¥ÀÌÅ͸¦ ¸¸µé ¶§ ºñÁß°ú Çà·Ä À妽º¸¦ ¿¬°áÇÕ´Ï´Ù. Áö±ÝÀº Á¤Á¡¿¡ ¼øÂ÷ÀûÀ¸·Î Çà·ÄÀ» Àû¿ëÇϰí ÀÖÁö¸¸ ÀÌ·± ¹æ¹ýÀº Ưº°ÇÑ °æ¿ìÀÔ´Ï´Ù.

 

for(¡¦)

¡¦

        m_pVtx[2*i + 0].g[0] = 1.0F;          // ºñÁß

        m_pVtx[2*i + 0].m[0] = i;             // Çà·Ä À妽º

 

        m_pVtx[2*i + 1].g[0] = 1.0F;          // ºñÁß

        m_pVtx[2*i + 1].m[0] = i;             // Çà·Ä Àε¥½º

 

¸Å ÇÁ·¹ÀÓ ¸¶´Ù Çà·ÄÀ» °»½ÅÇÕ´Ï´Ù.

 

FLOAT   fAngle = GetTickCount() * 0.4f;

for(i=0; i<256; ++i)

{

        float fTheta = fAngle + i * (360.f/15);

        m_mtWld[i]._41 = cosf( D3DXToRadian(fTheta) ) * 1.5f;

        m_mtWld[i]._42 = sinf( D3DXToRadian(fTheta) ) * 4.0f;

}

 

·»´õ¸µ¸¸ ³²¾Ò½À´Ï´Ù. ¸ÕÀú ÇÁ·Î±×·¥ ½ÃÀÛÇÒ ¶§ Çϵå¿þ¾î¿¡¼­ Áö¿øµÇ´Â Çà·ÄÀÇ ÃÖ´ë ¼ýÀÚ¸¦ °¡Áö°í Áö±ÝÀÇ Çà·ÄÀÇ °³¼ö°¡ À̺¸´Ù Ŭ °æ¿ì¿¡´Â ´ÙÀ½°ú °°ÀÌ ¼ÒÇÁÆ®¿þ¾î ¹öÅØ½º ÇÁ·Î¼¼½ÌÀ» È£ÃâÇÕ´Ï´Ù.

 

if(m_nMaxMatrixSize<128)

        m_pDev->SetSoftwareVertexProcessing(TRUE);

 

SetSoftwareVertexProcessing() ÇÔ¼ö´Â MIXED_VERTEX_PROCESSING¿¡¸¸ Àû¿ëÀÌ µË´Ï´Ù. µû¶ó¼­ MIXED·Î µð¹ÙÀ̽º¸¦ »ý¼ºÇϰųª ¾Æ´Ï¸é SOFTWARE_VERTEX_PROCESSINGÀ¸·Î µð¹ÙÀ̽º¸¦ ¸¸µé¾î¾ß ÇÕ´Ï´Ù. ´ÙÀ½¿¡ º¸¿©ÁÙ ¿¹Á¦´Â MIXED·Î µð¹ÙÀ̽º¸¦ ¸¸µé¾ú½À´Ï´Ù.

´ÙÀ½À¸·Î À妽º¿¡ ÀÇÇÑ ¹öÅØ½º ºí·»µùÀ» Ȱ¼ºÈ­ÇÕ´Ï´Ù.

 

m_pDev->SetRenderState(D3DRS_INDEXEDVERTEXBLENDENABLE, TRUE );

 

¶ÇÇÑ ¹öÅØ½º ºí·»µùÀÇ ºñÁß¿¡ ´ëÇÑ ÃÖ´ë À妽º¸¦ ÁöÁ¤ÇÕ´Ï´Ù. ±¸Á¶Ã¼¿¡¼­ Çà·Ä¿¡ ´ëÇØ¼­ 4°³ÀÇ À妽º¸¦ ÁöÁ¤Çϰí ÀÖÀ¸¹Ç·Î 0,1,2,3¿¡¼­ 3ÀÇ °ªÀ» ¼±ÅÃÇØ ´ÙÀ½°ú °°ÀÌ µð¹ÙÀ̽º¿¡ Àû¿ëÇÕ´Ï´Ù.

 

m_pDev->SetRenderState(D3DRS_VERTEXBLEND, D3DVBF_3WEIGHTS );

 

Çà·Ä ¹è¿­À» µð¹ÙÀ̽º¿¡ ¼³Á¤ÇÏ°í ¿ÀºêÁ§Æ®¸¦ ·»´õ¸µ ÇÕ´Ï´Ù.

 

for(i=0; i<256; ++i)

        m_pDev->SetTransform( D3DTS_WORLDMATRIX(i), &m_mtWld[i] );

¡¦

m_pDev->DrawPrimitiveUP(D3DPT_TRIANGLESTRIP, 40, m_pVtx, sizeof(VtxBlend));

 

µð¹ÙÀ̽º¸¦ ¿ø»óÅ·ΠµÇµ¹·Á ³õ½À´Ï´Ù.

 

m_pDev->SetRenderState( D3DRS_INDEXEDVERTEXBLENDENABLE, FALSE);

m_pDev->SetRenderState( D3DRS_VERTEXBLEND, D3DVBF_DISABLE  );

m_pDev->SetSoftwareVertexProcessing(FALSE);

 

// µð¹ÙÀ̽ºÀÇ Çà·Ä ÃʱâÈ­

static D3DXMATRIX mtIdentity( 1,0,0,00,1,0,00,0,1,00,0,0,1);

for(i=0; i<256; ++i)

        m_pDev->SetTransform( D3DTS_WORLDMATRIX(i), &mtIdentity);

 

Àüü ÄÚµå´Â daux08_skinning01.zipÀ» Âü°íÇϽʽÿÀ. À̸¦ ½ÇÇàÇÏ¸é ´ÙÀ½°ú °°Àº È­¸éÀ» ¾òÀ» ¼ö ÀÖ½À´Ï´Ù.

 

<Skinning űر⠿¹Á¦: daux08_skinning01.zip>

 

 

3.8.2 Modified SkinnedMesh

DXSDK SampleÀÇ SkinnedMesh´Â X-fileÀÇ Á¤º¸¸¦ ¹Þ¾Æ¼­ SkinningÀ¸·Î ¾Ö´Ï¸ÞÀ̼ÇÀ» ±¸ÇöÇÑ ¿¹Á¦ÀÔ´Ï´Ù.

¿¹Á¦´Â ÆÄÀÏ¿¡¼­ ¾Ö´Ï¸ÞÀÌ¼Ç Á¤º¸¸¦ ¸¸µå´Â CAllocateHierarchy Ŭ·¡½º, Àå¸éÀÇ ·»´õ¸µ¿¡ ÇÊ¿äÇÑ ¸Þ½¬, ÅØ½ºÃ³, ÀçÁú, Çà·Ä µîÀ» °¡Áø D3DXMESHCONTAINER Ŭ·¡½º, ¸Þ½¬ ÄÁÅ×À̳ʵéÀ» ¸ð¾Æ¼­ ÇϳªÀÇ ³ª¹« ±¸Á¶(Tree Structure)¸¦ ¸¸µå´Â D3DXFRAME ¼¼ ºÎºÐÀ¸·Î ±¸¼ºµÇ¾î ÀÖ°í, Skinning¿¡ ´ëÇÑ ¾Ö´Ï¸ÞÀ̼ÇÀ» Non-Index, Indexed, Á¤Á¡ ½¦ÀÌ´õ(Vertex Shader), °í ¼öÁØ ½¦ÀÌ´õ(HLSL) ÃÑ 4°³ÀÇ ¹æ½Ä Áß¿¡¼­ Çϳª¸¦ ¼±ÅÃÇØ¼­ Àû¿ëÇØ º¼ ¼ö ÀÖ½À´Ï´Ù.

 

 

<SkinnedMesh ¿¹Á¦ÀÇ ¼öÁ¤µÈ ÀÚ·á ±¸Á¶>

 

Non-Index´Â ±âº»ÀûÀ¸·Î Indexed ¹æ½ÄÀ¸·Î ¾Ö´Ï¸ÞÀ̼ÇÀ» ±¸ÇöÇÏÁö¸¸ Á¤Á¡¿¡ ¼³Á¤µÈ Çà·ÄÀÇ À妽º°¡ Çϵå¿þ¾î¿¡¼­ Áö¿øµÇ´Â ÃÖ´ë Å©±â¸¦ ³Ñ¾î¼­´Â °æ¿ì¿¡ ¼ÒÇÁÆ®¿þ¾î(CPU)·Î Á¤Á¡ÀÇ Ã³¸®Çϵµ·Ï Äڵ尡 ±¸¼ºµÇ¾î ÀÖ½À´Ï´Ù. ¾Õ¼­ űر⠿¹Á¦¿¡¼­ ÀÌ·± ¹æ¹ýÀ» À§Çؼ­ µð¹ÙÀ̽ºÀÇ SetSoftware-VertexProcessing() ÇÔ¼ö¸¦ È£ÃâÇÑ ÀûÀÌ ÀÖ½À´Ï´Ù. À̰ÍÀÌ Áö¿øµÇ·Á¸é MIXED·Î µð¹ÙÀ̽º¸¦ »ý¼ºÇØ¾ß ÇÑ´Ù°í Çß°í, ÀÌ ¶§¹®¿¡ SkinnedMesh ¿¹Á¦µµ MIXED·Î µð¹ÙÀ̽º¸¦ ¸¸µé¾úÀ½À» º¼ ¼ö ÀÖ½À´Ï´Ù.

 

ÀÌ ¿¹Á¦¸¦ ±×´ë·Î »ç¿ëÇϱâ´Â ¹«Ã´ ¾î·Æ½À´Ï´Ù. ±×·¡¼­ Äڵ带 °ÔÀÓ¿¡ Àû¿ëÇÒ ¼ö ÀÖµµ·Ï Àç¹èÄ¡ ÇØ¾ß ÇÕ´Ï´Ù. daux08_skinning02.zip´Â ÀÌ ¿¹Á¦¸¦ °ÔÀÓ ÇÁ·Î±×·¥¿¡ Àû¿ëÇÒ ¼ö ÀÖµµ·Ï ¼öÁ¤ÇÑ ¿¹ÀÔ´Ï´Ù.

Äڵ带 Àç¹èÄ¡ Çϸ鼭 Shader ºÎºÐÀº °ú°¨È÷ »ý·«Çϰí, Indexed ¹æ½Äµµ Non-Index¿¡ Æ÷ÇԵǾî ÀÖÀ¸¹Ç·Î ÀÌ ºÎºÐµµ Á¦°ÅÇß½À´Ï´Ù. ÀÌÀüÀÇ X-fileÀ» Ŭ·¡½º·Î ¸¸µé ¶§Ã³·³ ±¸Á¶´Â °ÅÀÇ ±×´ë·Î µÎ°í(º¯¼ö À̸§°ú ÇÔ¼ö À̸§Àº ÀϺΠ¹Ù²Ù¾ú½À´Ï´Ù.) ¸î °³ÀÇ ÀÎÅÍÆäÀ̽º¿Í Ŭ·¡½º¸¦ Ãß°¡ÇÏ¿© ¾ÕÀÇ ±×¸²°ú °°Àº ±¸Á¶·Î º¯°æÇؼ­ ¸¸µç ¿¹°¡ daux08_skinning02.zipÀÔ´Ï´Ù.

 

ILcMdlÀº X-fileÀÇ Skinning¿¡ ´ëÇÑ ÃÖ»óÀ§ Ŭ·¡½º·Î ÀÎÅÍÆäÀ̽º ¿ªÇÒÀ» ÇÕ´Ï´Ù. À̸¦ »ó¼Ó¹ÞÀº CLcXSkin Ŭ·¡½º´Â ¾Ö´Ï¸ÞÀ̼ǿ¡ ÇÊ¿äÇÑ ½Ã°£°ú °´Ã¼¿¡ ´ëÇÑ ¿ùµå Çà·ÄÀÇ ¸â¹ö º¯¼ö¸¦ °¡Áö°í ÀÖ°í À̵éÀ» ¼³Á¤Çϰųª ÂüÁ¶ÇÒ ¼ö ÀÖ´Â ¸â¹ö ÇÔ¼ö¸¦ ´ÙÀ½°ú °°ÀÌ °¡Áö°í ÀÖ½À´Ï´Ù.

 

class CLcXSkin : public ILcMdl

¡¦

        D3DXMATRIX     m_mtWorld      ;       // °´Ã¼ÀÇ ¿ùµå Çà·Ä

        DOUBLE         m_dTimeCur     ;       // °´Ã¼ÀÇ ½Ã°£

¡¦

        virtual INT    SetAttrib(char* sCmd, void* pVal);

        virtual INT    GetAttrib(char* sCmd, void* pVal);

        virtual INT    SetPosition(FLOAT* float3);

        virtual INT    GetPosition(FLOAT* float3);

 

¼Ó¼ºÀÌ ¸¹¾Æ Áö¸é ÀÌ¿¡ ´ëÇÑ ÇÔ¼öµµ Áõ°¡ÇÒ ¼ö ÀÖ¾î Äڵ尡 ¾û¸ÁÀÌ µÇ±â ½±½À´Ï´Ù. °£´ÜÇÑ µ¥ÀÌÅÍ¿¡ ´ëÇÑ ¼³Á¤°ú ÂüÁ¶´Â ÇϳªÀÇ ÇÔ¼ö¿¡¼­ ´ÙÀ½°ú °°ÀÌ Ã³¸®ÇÏ´Â °ÍÀÌ Àüü ±¸Á¶¸¦ Àß °¡Áö°í °¥ ¼ö ÀÖ´Â ºñ°áÀÔ´Ï´Ù.

 

INT CLcXSkin::SetAttrib(char* sCmd, void* pVal)

{

        if(0 ==_stricmp(sCmd, "World Matrix"))

        {

               m_mtWorld =*((D3DXMATRIX*)pVal);

               return 0;

        }

        else if(0 ==_stricmp(sCmd, "Elapsed Time"))

        {

               FLOAT fTime =*((FLOAT*)pVal);

               m_dTimeCur += fTime;

               return 0;

        }

¡¦

}

 

INT CLcXSkin::GetAttrib(char* sCmd, void* pVal)

{

        if(0 ==_stricmp(sCmd, "World Matrix"))

        {

               *((D3DXMATRIX*)pVal) = m_mtWorld;

               return 0;

        }

        else if(0 ==_stricmp(sCmd, "Current Time"))

        {

               *((DOUBLE*)pVal) = m_dTimeCur;

               return 0;

        }

¡¦

}

 

³»ºÎ¿¡¼­ if ~ elseÀÇ Áõ°¡´Â ¾î¿ ¼ö ¾øÁö¸¸ ¹Û¿¡¼­ º¸´Â Ŭ·¡½ºÀÇ ¿ÜÇüÀû ±¸Á¶´Â °£°áÇÕ´Ï´Ù.

 

¸Þ½¬, ¾Ö´Ï¸ÞÀÌ¼Ç Á¤º¸, ³ª¹« ±¸Á¶(Tree Structure)¸¦ ±¸¼ºÇÏ´Â CLcXSkinSrc Ŭ·¡½º´Â ´ÙÀ½°ú °°ÀÌ ¾Ö´Ï¸ÞÀÌ¼Ç Á¦¾î¿¡ ´ëÇÑ °´Ã¼¿Í Çà·ÄÀÇ ¹è¿­À» °¡Áö°í ÀÖ½À´Ï´Ù.

 

class CLcXSkinSrc : public CLcXSkin

¡¦

        SFrame*                       m_pFrameRoot   ;       // Root

        LPD3DXANIMATIONCONTROLLER     m_pAC          ;       // Animation Controller

        UINT                          m_NumBoneMatricesMax;  // Çà·Ä À妽ºÀÇ ¼ö

        D3DXMATRIX*                   m_pBoneMatrices        ;       // Çà·ÄÀÇ ¹è¿­

¡¦

        virtual INT    Create();

        void            UpdateFrameMatrices();

        void            DrawFrame();

        void            RenderNonIndexed();

 

CLcXSkinSrc::Create() ÇÔ¼ö´Â D3DXLoadMeshHierarchyFromX() ÇÔ¼ö¸¦ ÀÌ¿ëÇØ¼­ ¸Þ½¬¿Í °èÃþ ±¸Á¶(hierarchy)¸¦ °¡Á®¿É´Ï´Ù. ÀÌ ÇÔ¼ö´Â »ç¿ëÀÚ°¡ ID3DXAllocateHierarchy »ó¼Ó ¹Þ´Â Ŭ·¡½º¸¦ Á¤ÀÇÇÑ ÀڷḦ Àμö·Î ¹Þ½À´Ï´Ù. »ç¿ëÀÚ´Â ´ÙÀ½ÀÇ ¼¼ ÇÔ¼ö¿¡ ´ëÇØ¼­ ¹Ýµå½Ã ±¸ÇöÇØ¾ß ÇÕ´Ï´Ù.

 

class CLcXSkinAlloc: public ID3DXAllocateHierarchy

¡¦

public:

        virtual HRESULT CreateFrame();

        virtual HRESULT CreateMeshContainer();      

        virtual HRESULT DestroyFrame();

        virtual HRESULT DestroyMeshContainer();

 

À̵é ÇÔ¼ö´Â D3DXLoadMeshHierarchyFromX() ÇÔ¼ö¿¡¼­ È£ÃâµÇ¸ç ´ÙÀ½°ú °°Àº ¿ªÇÒÀ» ÇÕ´Ï´Ù.

 

CreateFrame(): FrameÀ» ¸Þ¸ð¸®¿¡ »ý¼ºÇÒ ¶§ È£ÃâÇÕ´Ï´Ù.

CreateMeshContainer(): ¸Þ½¬ ÄÁÅ×À̳ʸ¦ ¸Þ¸ð¸®¿¡ »ý¼ºÇÒ ¶§ È£ÃâÇÕ´Ï´Ù.

DestroyFrame(): »ý¼ºÇÑ FrameÀ» ÇØÁ¦ÇÒ ¶§ È£ÃâÇÕ´Ï´Ù.

DestoryMeshContainer(): »ý¼ºÇÑ ¸Þ½¬ ÄÁÅ×À̳ʸ¦ ÇØÁ¦ÇÒ ¶§ È£ÃâÇÕ´Ï´Ù.

 

Äڵ带 ¿Å±â¸é¼­ Mesh Container ±¸Á¶¸¦ »ó¼Ó¿¡¼­ µ¶¸³µÈ Ŭ·¡½º·Î ¹Ù²Ù¾ú½À´Ï´Ù. ÀÌ Mesh Container´Â  Àå¸éÀ» ¸¸µå´Â °´Ã¼·Î ¸Þ½¬, º¯È¯¿¡ ÇÊ¿äÇÑ Çà·ÄÀÇ Æ÷ÀÎÅÍ, ÀçÁú(Material), Texture µîÀ» Æ÷ÇÔÇϰí ÀÖ½À´Ï´Ù.

 

struct SMeshContainer //: D3DXMESHCONTAINER

¡¦

        D3DXMESHDATA            MeshData;

        LPD3DXMATERIAL          pMaterials;

        DWORD                   NumMaterials;

        LPDIRECT3DTEXTURE9*    ppTextures;       // array of textures

        // Skin Mesh info            

        DWORD                NumAttributeGroups;

        DWORD                NumInfl;         // ÄÁÅ×À̳ʿ¡ ¿µÇâÀ» ÁÖ´Â Çà·ÄÀÇ ¼ö

        LPD3DXBUFFER         pBoneCombinationBuf;

        D3DXMATRIX**         m_pBoneMatrix;

 

Frame °´Ã¼´Â °èÃþÀûÀÎ ³ª¹«(Tree) ±¸Á¶¸¦ Çü¼ºÇÏ´Â °´Ã¼·Î ³ëµå(Node)ÀÇ Æ÷ÀÎÅ͵é°ú ÇÔ²² Àå¸é°ú ¾Ö´Ï¸ÞÀ̼ÇÀ» ±¸¼ºÇϱâ À§ÇÑ º¯È¯ Çà·Ä, ¸Þ½¬ Æ÷ÀÎÅÍ µîÀ» Æ÷ÇÔ ÇÑ °´Ã¼ÀÔ´Ï´Ù. Root ³ëµåºÎÅÍ ³Êºñ ¿ì¼± Ž»ö(breadth-first search: BFS)À¸·Î Çà·ÄÀ» °»½ÅÇϰí, Mesh Container Æ÷ÀÎÅ͸¦ ÀÌ¿ëÇØ¼­ ·»´õ¸µÀ» ¼öÇà ÇÕ´Ï´Ù.

 

struct SFrame  //: public D3DXFRAME

¡¦

        D3DXMATRIX             tmMatrix;      // Áö¿ª ÁÂÇ¥°èÀÇ Çà·Ä

        SMeshContainer*                pmcMesh;       // ·»´õ¸µ¿¡ ´ëÇÑ ¸Þ½¬ ÄÁÅ×À̳Ê

 

        SFrame*                pFrameSibling; // ÀÌ¿ô ÇüÁ¦ ³ëµå

        SFrame*                pFrameFirstChild;// ù ¹øÂ° ÀÚ½Ä ³ëµå

        D3DXMATRIX             tmWorld;       // ¿ùµå Çà·Ä = tmMatrix * ºÎ¸ð Çà·Ä

        SFrame *FindFrame(char *szFrame);

 

CLcXSkinSrc::UpdateFrameMatrices() ÇÔ¼ö¸¦ º¸¸é Frame °´Ã¼ÀÇ ¿ùµå Çà·ÄÀ» ÀÚ½ÅÀÇ Áö¿ª Çà·Ä°ú ºÎ¸ðÀÇ ¿ùµå Çà·Ä °öÀ¸·Î ¸¸µé°í ÀÖ°í ÇüÁ¦ ³ëµå¿Í ÀÚ½Ä ³ëµå¿¡ ´ëÇØ¼­ BFS·Î ³ëµå¸¦ ã¾Æ°¡ µ¥ÀÌÅ͸¦ °»½ÅÇϰí ÀÖÀ½À» º¼ ¼ö ÀÖ½À´Ï´Ù.

 

if (pParentMatrix != NULL)

                D3DXMatrixMultiply(&pFrame->tmWorld, &pFrame->tmMatrix, pParentMatrix);

else

                pFrame->tmWorld = pFrame->tmMatrix;

 

if (pFrame->pFrameSibling != NULL)

                UpdateFrameMatrices(pFrame->pFrameSibling, pParentMatrix);

 

if (pFrame->pFrameFirstChild != NULL)

                UpdateFrameMatrices(pFrame->pFrameFirstChild, &pFrame->tmWorld);

 

·»´õ¸µµµ CLcXSkinSrc::DrawFrame()ÇÔ¼ö¸¦ º¸¸é BFS·Î ÁøÇàÇϰí ÀÖ½À´Ï´Ù.

 

pMeshContainer = pFrame->pmcMesh;

while (pMeshContainer != NULL)

{

                DrawMeshContainer(pMeshContainer, pFrame);

                pMeshContainer = pMeshContainer->pNextMeshContainer;

}

 

if (pFrame->pFrameSibling != NULL)

                DrawFrame(pFrame->pFrameSibling);

 

if (pFrame->pFrameFirstChild != NULL)

                DrawFrame(pFrame->pFrameFirstChild);

 

ÇÁ·Î±×·¥¿¡¼­ ·»´õ¸µ°ú ¾Ö´Ï¸ÞÀÌ¼Ç Á¤º¸¸¦ °¡Áö°í ÀÖ´Â CDXSkinSrc Ŭ·¡½ºÀÇ ÀνºÅϽº¸¦ ÂüÁ¶Çؼ­ Àå¸éÀ» ±¸¼ºÇÏ´Â CDXSkinInst Ŭ·¡½º´Â ´ÙÀ½°ú °°Àº °£´ÜÇÑ ±¸Á¶·Î ±¸¼ºÀÌ µË´Ï´Ù.

 

class CLcXSkinIns : public CLcXSkin

¡¦

        CLcXSkinSrc*                  m_pOrg;        // Original Pointer

        LPD3DXANIMATIONCONTROLLER     m_pAC;         // Animation Controller

        SFrame*                       m_pFrameRoot;  // Root Frame

¡¦

        virtual INT    Create(void* =0, void* =0, void* =0, void* =0);

        virtual void   Destroy();

        virtual INT    FrameMove();

        virtual void   Render();

 

Root FrameÀº ¸Å¹ø Original¿¡¼­ °¡Á®¿À´Â ¹ø°Å·Î¿òÀ» ¾ø¾Ö±â À§ÇØ ¸¸µç º¯¼ö ÀÔ´Ï´Ù. INT CLcXSkinIns::Create() ÇÔ¼ö¸¦ º¸¸é Animation Controller¸¦ º¹Á¦ÇÏ°í »ç¿ëÀÇ Æí¸®¸¦ À§ÇØ Original·ÎºÎÅÍ ÇÊ¿äÇÑ Á¤º¸¸¦ ¾ò½À´Ï´Ù.

 

INT CLcXSkinIns::Create(¡¦)

¡¦

        m_pOrg = (CLcXSkinSrc*)p3;

        m_pFrameRoot = (SFrame*)m_pOrg->GetRootFrame();

 

        LPD3DXANIMATIONCONTROLLER     pAC =

(LPD3DXANIMATIONCONTROLLER)m_pOrg->GetAnimationController();

 

        UINT MaxNumAnimationOutputs   = pAC->GetMaxNumAnimationOutputs();

        UINT MaxNumAnimationSets      = pAC->GetMaxNumAnimationSets();

        UINT MaxNumTracks             = pAC->GetMaxNumTracks();

        UINT MaxNumEvents             = pAC->GetMaxNumEvents();

 

        pAC->CloneAnimationController( MaxNumAnimationOutputs

                                      , MaxNumAnimationSets

                                      , MaxNumTracks

                                      , MaxNumEvents

                                      , &m_pAC);

 

·»´õ¸µÀº Animation ColtrollerÀÇ AdvanceTime () ÇÔ¼ö¿¡ Àüü Àå¸éÀ» 1 ÇÁ·¹ÀÓ ·»´õ¸µ Çϴµ¥ ¼Ò¸ðµÈ ½Ã°£À» Àμö·Î Àü´ÞÇϸ鼭 ½ÃÀÛÇÕ´Ï´Ù. ¸¸¾à ÇÑ Àå¸é¿¡ µé¾ú´ø ½Ã°£ ´ë½Å ÃÑ ½Ã°£À» »ç¿ëÇÑ´Ù¸é ´ÙÀ½°ú °°ÀÌ TrackÀÇ À§Ä¡¸¦ 0À¸·Î ¼³Á¤ÇØ¾ß ÇÕ´Ï´Ù. ´ÙÀ½À¸·Î OriginalÀÇ UpdateFrame-Matrices() ÇÔ¼ö¿Í DrawFrame() ÇÔ¼ö¸¦ ¼øÂ÷ÀûÀ¸·Î È£ÃâÇØ¼­ Àå¸éÀ» ±×¸³´Ï´Ù.

 

void CLcXSkinIns::Render()

¡¦

m_pAC->SetTrackPosition(0, 0);

m_pAC->AdvanceTime(m_dTimeCur, NULL);

m_pOrg->UpdateFrameMatrices(m_pFrameRoot, &m_mtWorld);

m_pOrg->DrawFrame(m_pFrameRoot);

 

CMain Ŭ·¡½º¿¡´Â ILcMdl¿¡ ´ëÇÑ Original °´Ã¼ 1°³¿Í À̸¦ ÂüÁ¶Çؼ­ ¸¸µé 3°³ÀÇ ILcMdl °´Ã¼¸¦ ¼±¾ðÇϰí CMain::Init() ÇÔ¼ö¿¡¼­ ÀÖ½À´Ï´Ù. LcMdl_Create()ÇÔ¼ö¿¡ ÆÄÀÏ À̸§À¸·Î OriginalÀ» ¸¸µé°í OriginalÀ» Àμö·Î Àü´ÞÇØ¼­ ³ª¸ÓÁö 3°³ÀÇ °´Ã¼¸¦ ¸¸µé°í ÀÖÀ½À» º¼ ¼ö ÀÖ½À´Ï´Ù.

 

LcMdl_Create(NULL, &m_pDXMeshOrg, m_pd3dDevice, m_strMeshFilename);

LcMdl_Create(NULL, &m_pDxMeshIns1, m_pd3dDevice, NULL, m_pDXMeshOrg);

LcMdl_Create(NULL, &m_pDxMeshIns2, m_pd3dDevice, NULL, m_pDXMeshOrg);

LcMdl_Create(NULL, &m_pDxMeshIns3, m_pd3dDevice, NULL, m_pDXMeshOrg);

 

LcMdl_Create() ÇÔ¼ö´Â ¾Ö´Ï¸ÞÀ̼ÇÀÌ ¾ø´Â X-file¿Í ºñ½ÁÇÏ°Ô ÆÄÀÏÀ̸§ÀÌ ÀÖÀ¸¸é ¿øº» °´Ã¼¸¦ ¸¸µé°í ¿øº» °´Ã¼ÀÇ ÁÖ¼Ò°¡ ¿À¸é À̸¦ ÂüÁ¶ÇÏ´Â °´Ã¼¸¦ ¸¸µì´Ï´Ù.

 

INT LcMdl_Create(char* sCmd , ILcMdl** pData // Output Data

                , void* p1            // Device

                , void* p2            // File Name

                , void* p3            // Source Model

                , void* p4 )

{

        ILcMdl* pObj = NULL;

        *pData = NULL;

        if( NULL != p2)               pObj = new CLcXSkinSrc;

        else if(NULL != p3)    pObj = new CLcXSkinIns;

        else                   return -1;

 

        if(FAILED(pObj->Create(p1, p2, p3, p4)))

        {

               delete pObj;   return -1;

        }

 

        *pData = pObj;

        return 0;

}

 

ÀÌ daux08_skinning02.zip¸¦ ½ÇÇàÇÏ¸é ´ÙÀ½°ú °°ÀÌ ¼­·Î ´Ù¸¥ ½Ã°£¿¡ ¾Ö´Ï¸ÞÀ̼ÇÀ» ÇÏ´Â 3°³ÀÇ °´Ã¼¸¦ º¼ ¼ö ÀÖ½À´Ï´Ù.

 

 

<Modified SkinnedMesh: daux08_skinning02.zip>

 

Äڵ带 ÀüȯÇϸ鼭 °¡Àå ¾î·Á¿ü´ø °ÍÀº µ¥ÀÌÅÍÀÇ °»½Å°ú ·»´õ¸µÀÌ ºÐ¸®°¡ ¾ÈµÇ¾î ÀÖ´Â Á¡°ú ¾Ö´Ï¸ÞÀÌ¼Ç ¼³Á¤ÀÌ ½±Áö°¡ ¾Ê´Ù´Â °ÍÀÔ´Ï´Ù. Animation SetÀÌ ¿©·¯ °³ ÀÖÀ» °æ¿ì 0¹ø SetÀ¸·Î µÎ¸é ´Ù¸¥ °´Ã¼¿¡ ¿µÇâÀ» ÁÖ¾î ÇÒ ¼ö ¾øÀÌ ¸¶Áö¸· SetÀ¸·Î ¾Ö´Ï¸ÞÀ̼ÇÀ» °áÁ¤ÇØ¾ß Çß½À´Ï´Ù.

if(m_nAniMax)

        m_pAC->SetTrackAnimationSet(0, m_vAS[m_nAniMax - 1]);

 

¿Ïº®ÇÏÁö´Â ¾ÊÁö¸¸ Á¦´ë·Î µÈ ¶óÀ̺귯¸®¸¦ ¾ò±â Àü±îÁö ¾µ¸¸ÇÏ´Ù°í »ý°¢µÇ¸ç, ƯÈ÷ ¾Ö´Ï¸ÞÀ̼ÇÀ» óÀ½ Á¢ÇÏ´Â ºÐµé¿¡°Ô µµ¿òÀÌ µÇ¸®¶ó »ý°¢µË´Ï´Ù.

 

 

3.9 2D Sprite

3.9.1 RHW Sprite

3D ±âÃÊ¿Í °ÔÀÓ ÇÁ·Î±×·¥¿¡ ÇÊ¿äÇÑ ¾Ö´Ï¸ÞÀ̼DZîÁöÀÇ Áö½Ä¸¸À¸·Îµµ 3D °ÔÀÓÀ» ¾ó¸¶µçÁö ¸¸µé ¼ö ÀÖ½À´Ï´Ù. ±×·±µ¥ ´ëºÎºÐ 3D¸¦ ¹è¿ö³õ°íµµ ¹«¾ùÀ» ÇØ¾ß ÇÒÁö ¸·¸·ÇÒ ¶§°¡ ¸¹ÀÌ ÀÖ½À´Ï´Ù. ÀÌ·² ¶§ ±ÇÇÏ°í ½ÍÀº °ÍÀÌ ID3DXSprite¸¦ 3D·Î ¸¸µé¾î º¸´Â °ÍÀÔ´Ï´Ù. 3D °ÔÀÓ¿¡¼­ È­¸éÀÇ UI(User Interface)¸¦ ±¸¼ºÇÒ ¶§ 2D Sprite¸¦ »ç¿ëÇϰí ID3DXSprite¸¦ ´ëºÎºÐ »ç¿ëÇÕ´Ï´Ù. ±×·±µ¥ ID3DXSprite¶ó´Â °ÍÀÌ D3D ¶Ç´Â D3DX ¹öÀü ¸¶´Ù ¾à°£ÀÇ Â÷À̰¡ ÀÖ½À´Ï´Ù. ¸¸¾à 3D·Î 2D Sprite¸¦ ±¸ÇöÇØ ³õÀ¸¸é D3D ¹öÀü¿¡µµ ¿µÇâÀ» ¹ÞÁö ¾Ê°í ¿Ïº®ÇÏ°Ô 3D·Î 2D¸¦ ±¸Çö Çϴµ¥ Àǹ̰¡ ÀÖ½À´Ï´Ù.

 

3D´Â Á¤Á¡ÀÌ ÀÖ¾î¾ß Àå¸éÀ» ¿¬ÃâÇÒ ¼ö ÀÖÀ¸¸ç µû¶ó¼­ 2Dµµ Á¤Á¡ÀÌ ÀÖ¾î¾ß ÇÕ´Ï´Ù. ÆÄÀÌÇÁ¶óÀÎÀÇ º¯È¯ °úÁ¤À» °ÅÄ¡Áö ¾Ê´Â °¡Àå ÀûÇÕÇÑ ÇüÅ´ RHW(Reciprocal of Homogeneous W) ÇüÅ·ΠÁ¤Á¡À» ±¸¼ºÇÏ´Â °ÍÀÔ´Ï´Ù. ÇÁ·Î±×·¥ÀÇ ÀÎÅÍÆäÀ̽º´Â D3D¿Í À¯»çÇÏ°Ô ±¸¼ºÇÏ´Â °ÍÀÌ Áö±Ý±îÁö ¸¸µç ÇÁ·Î±×·¥°ú ȣȯ¼ºÀ» À¯Áö¿¡ µµ¿òÀÌ µË´Ï´Ù. ÀÌ·± ¾ÆÀ̵ð¾î¸¦ Á¾ÇÕÇØ¼­ ÇÁ·Î±×·¥À» ÀÛ¼ºÇØ º¾½Ã´Ù.

 

¸ÕÀú 2D SpriteÀÇ ÀÎÅÍÆäÀ̽º¿Í Sprite °´Ã¼¸¦ »ý¼ºÇÏ´Â ÇÔ¼ö ÀÔ´Ï´Ù.

 

interface ILcSprite           // 2D Sprite Interface

{

        virtual ~ILcSprite(){};

        virtual INT    Draw(void* pTx0, const RECT* pRcDrw=NULL

, const FLOAT* pvcPos=NULL, DWORD Color=0xFFFFFFFF)=0;

};

 

INT LcxCreateSprite(ILcSprite** pOut, void* pd3dDevice);

 

Sprite °´Ã¼¸¦ »ý¼ºÇÏ´Â LcxCreateSprite() ÇÔ¼ö¿¡¼­ °´Ã¼¿¡ ´ëÇÑ ¹ÝȯÀ» ÀμöÀÇ ¾ÕÂÊ¿¡ ³Ö¾ú½À´Ï´Ù.

CLcSprite Ŭ·¡½º´Â ILcSprite¸¦ »ó¼Ó¹Þ¾Æ¼­ ½ÇÁ¦·Î Draw() ÇÔ¼ö¸¦ ó¸®Çϴ Ŭ·¡½ºÀÔ´Ï´Ù.

 

class CLcSprite : public ILcSprite

¡¦

        LPDIRECT3DDEVICE9      m_pDev;

        LPDIRECT3DSTATEBLOCK9  m_pStCur;      // Current State Block

        LPDIRECT3DSTATEBLOCK9  m_pStSpt;      // Sprite State Block

¡¦

        INT            Create(LPDIRECT3DDEVICE9 pDev);

        virtual INT    Draw(¡¦);

 

Sprite °´Ã¼¿¡ ÀÇÇØ µð¹ÙÀ̽ºÀÇ »óÅ °ªÀÌ º¯ÇÏÁö ¾Êµµ·Ï »óŸ¦ ÀúÀåÇϱâ À§Çؼ­ D3DÀÇ State Block °´Ã¼¸¦ °¡Áö°í ÀÖ½À´Ï´Ù.

ÀÌ State Block °´Ã¼ »ý¼ºÀº D3D µð¹ÙÀ̽ºÀÇ BeginStateBlock()ÇÔ¼ö È£ÃâÀ» Çϸ鼭 ÀúÀåÇÒ »óŸ¦ ¼³Á¤ÇÏ°í ¸¶Áö¸·¿¡ EndStateBlock() ÇÔ¼ö¿¡¼­ °´Ã¼¸¦ »ý¼ºÇÕ´Ï´Ù.

 

m_pDev->BeginStateBlock();

m_pDev->SetRenderState( D3DRS_FOGENABLE,     FALSE );

m_pDev->SetRenderState( D3DRS_LIGHTING,              FALSE );

¡¦

m_pDev->EndStateBlock(&m_pStSpt);

 

»óÅ ¼³Á¤ÀÌ ±æ¾îÁú ¶§ À¯¿ëÇÕ´Ï´Ù. ÀÌ State Blockµµ ÇØÁ¦ÇÒ ¶§´Â Release() ÇÔ¼ö¸¦ ÀÌ¿ëÇÕ´Ï´Ù.

 

Draw() ÇÔ¼ö´Â ¿øº» À̹ÌÁöÀÇ Å©±â¿Í È­¸é¿¡ ±×¸®°Ô µÉ À̹ÌÁö ¿µ¿ª, È­¸é ÁÂÇ¥, »ö»óÀ» ÀÌ¿ëÇØ¼­ 4°³ÀÇ Á¤Á¡À» ¿Ï¼ºÇϰí Ãâ·ÂÇÏ´Â °ÍÀÔ´Ï´Ù. ÅØ½ºÃ³ ¼­Çǽº¿¡¼­ ³Êºñ¿Í ³ôÀ̸¦ °¡Á®¿Ã ¼ö ÀÖ°í ÀÌ¿Í ÇÔ²² È­¸é¿¡ Ãâ·ÂÇÒ À̹ÌÁöÀÇ ¿µ¿ªÀ» ÀÌ¿ëÇØ¼­ ÅØ½ºÃ³ÀÇ UVÁÂÇ¥¸¦ °è»êÇÕ´Ï´Ù.

 

INT CLcSprite::Draw(¡¦, const RECT* pRcImg, const RECT* pRcDrw, const FLOAT* pvcPos, ¡¦)

¡¦

// ¼­ÇǽºÀÇ Width, Height¸¦ °¡Á®¿Â´Ù.

        D3DSURFACE_DESC dsc;

        pTex0->GetLevelDesc(0, &dsc);

        FLOAT fImgW = FLOAT(dsc.Width);              // Width of Surface

        FLOAT fImgH = FLOAT(dsc.Height);      // Height of Surface

 

        // Draw Region Width, Height

        if(pRcDrw)

        {

               fDrwL = FLOAT(pRcDrw->left);

               fDrwT = FLOAT(pRcDrw->top);

               fDrwW = FLOAT(pRcDrw->right - pRcDrw->left);

               fDrwH = FLOAT(pRcDrw->bottom- pRcDrw->top );

        }

        // Setup UV

        uv0.x = (fDrwL +     0)/fImgW;

        uv1.x = (fDrwL + fDrwW)/fImgW;

        uv0.y = (fDrwT +     0)/fImgH;

        uv1.y = (fDrwT + fDrwH)/fImgH;

 

// Setup Vertices

        struct TVtxRHWUV1

        {

               FLOAT   p[4];

                DWORD   d;

                FLOAT   u, v;

        } pVtx[4] =

        {

               {pos.x +     0, pos.y +     001,  dColor,   uv0.x,  uv0.y},

               {pos.x + fDrwW, pos.y +     001,  dColor,   uv1.x,  uv0.y},

               {pos.x + fDrwW, pos.y + fDrwH,  01,  dColor,   uv1.x,  uv1.y},

               {pos.x +     0, pos.y + fDrwH,  01,  dColor,   uv0.x,  uv1.y},

        };

 

        // Rendering 2D

        m_pStCur->Capture();

        m_pStSpt->Apply();

        m_pDev->SetTexture(0, pTex0);

        m_pDev->SetFVF(D3DFVF_XYZRHW|D3DFVF_DIFFUSE|D3DFVF_TEX1);

        m_pDev->DrawPrimitiveUP( D3DPT_TRIANGLEFAN, 2, pVtx, sizeof(TVtxRHWUV1) );

        m_pDev->SetTexture(0, NULL);

        m_pStCur->Apply();

 

½ºÇÁ¶óÀÌÆ® °´Ã¼´Â ¸Å¹ø Á¤Á¡À» ¼³Á¤ÇØ¾ß ÇϹǷΠUser Memory Pointer¸¦ »ç¿ëÇÏ´Â °ÍÀÌ Æí¸®ÇÕ´Ï´Ù.

Àüü ÄÚµå´Â daux09_2d_sprite01.zip Âü°í Çϰí À̸¦ ½ÇÇàÇÏ¸é ´ÙÀ½°ú °°ÀÌ ID3DXSprite °´Ã¼¿Í ºñ±³ÇÑ È­¸éÀÌ Ãâ·ÂµË´Ï´Ù.

 

<RHW Sprite: daux09_2d_sprite01.zip>

 

±×¸²ÀÇ ÀÛÀº ÀÔÀÚÀÇ ºÓÀº »ö µ¿±×¶ó¹Ì¸¦ º¸¸é UV°¡ ¾È ¸Â´Â °ÍÀÌ º¸ÀÔ´Ï´Ù. À̰ÍÀº ÅØ½ºÃ³¸¦ ¸¸µé ¶§ ÇÊÅ͸µÀÌ ¼³Á¤µÇ¾ú±â ¶§¹®ÀÔ´Ï´Ù. ¶ÇÇÑ ºÒÅõ¸í ÅØ½ºÃ³¿¡ ´ëÇÑ Ä®¶ó Ű(Color Key)°¡ ¼³Á¤ÀÌ ¾È µÇ¾î À־ °ËÁ¤»ö ¹è°æ »ö»óÀÌ ±×´ë·Î Ãâ·ÂµÇ°í ÀÖÀ½À» º¼ ¼ö ÀÖ½À´Ï´Ù. ÀÌ·± ¹®Á¦µéÀ» »ý°¢ÇßÀ» ¶§ Áö±Ý±îÁö Àß »ç¿ëÇϰí ÀÖ¾ú´ø IDirect3DTexture9 °´Ã¼ ÁÖ¼Ò¿Í D3DXIMAGE_INFO ±¸Á¶Ã¼ º¯¼ö¸¦ Wrapping ÇØ¼­ »ç¿ëÇÒ ¼ö ÀÖ´Â ÀÎÅÍÆäÀ̽º°¡ ÇÊ¿äÇÏ°Ô µË´Ï´Ù.

 

´ÙÀ½°ú °°ÀÌ °£´ÜÇÑ ±¸Á¶Ã¼·Î ¸¸µé¾î¼­ »ç¿ëÇÒ ¼ö ÀÖ½À´Ï´Ù.

 

struct LcTexture

{

        D3DXIMAGE_INFO         pInf;

        LPDIRECT3DTEXTURE9     pTex;

};

 

ÇÑ ¹ø ÇØ ³õÀ¸¸é °è¼Ó ¾µ ¼ö ÀÖÀ¸´Ï ÀÌ¿ÕÀÌ¸é ´ÙÀ½°ú °°ÀÌ ÀÛ¼ºÇÏ´Â °ÍÀÌ ÁÁ½À´Ï´Ù. ¸ÕÀú ÀÎÅÍÆäÀ̽º¿Í »ý¼º ÇÔ¼ö¸¦ ÀÌÀüÀÇ Sprite¿Í ºñ½ÁÇÏ°Ô ¸¸µì´Ï´Ù. ILcTexture »ý¼º ÇÔ¼ö¿¡´Â ÇÊÅ͸µ, Ä®¶ó ۸¦ Àü´ÞÇÒ ¼ö ÀÖ´Â Àμö¸¦ Ãß°¡ÇÕ´Ï´Ù.

 

interface ILcTexture

{

        virtual ~ILcTexture(){};

 

        virtual void*   GetTexture()=0;        // LPDIRECT3DTEXTURE9

        virtual INT     GetImgW()=0;   // Image Width

        virtual INT     GetImgH()=0;   // Image Height

        virtual INT     GetImgD()=0;   // Image Depth

};

 

INT LcxCreateTextureFromFile(ILcTexture** pOut, void* pd3dDevice

, char* sFile, DWORD dFilter=-1, DWORD dColor=0x00FFFFFF);

 

ÀÎÅÍÆäÀ̽º ILcTexture¸¦ ±¸ÇöÇÒ Å¬·¡½º CLcTexture¸¦ ´ÙÀ½°ú °°ÀÌ ÀÛ¼ºÇÕ´Ï´Ù.

 

class CLcTexture : public ILcTexture

¡¦

        LPDIRECT3DTEXTURE9     m_pTex;

        D3DXIMAGE_INFO         m_pInf;

¡¦

        INT     Create(LPDIRECT3DDEVICE9 pDev, char* sFile

, DWORD dFilter=-1, DWORD dColorKey=0x00FFFFFF);

 

 

CLcTexture::Create() ÇÔ¼ö´Â D3DXCreateTextureFromFileEx() ÇÔ¼ö¸¦ ÀÌ¿ëÇØ¼­ ÅØ½ºÃ³¿Í ¿øº» À̹ÌÁö Á¤º¸¸¦ ÀúÀåÇÕ´Ï´Ù. ÇÊÅͰ¡ -1À̸é MipLevels¸¦ ÃÖ´ë·Î ¼³Á¤ÇÏ°í ±×·¸Áö ¾ÊÀº °æ¿ì¿¡´Â 1·Î ¼³Á¤Çؼ­ 2Dȯ°æ¿¡¼­ »ç¿ëµÇÁö ¾Ê´Â Sub Texture¸¦ ¾È ¸¸µì´Ï´Ù.

 

INT CLcTexture::Create(¡¦)

¡¦

        UINT MipLevels = (dFilter==-1? -1 : 1);

        D3DXCreateTextureFromFileEx(pDev, sFile

                              , D3DX_DEFAULT, D3DX_DEFAULT

, MipLevels, 0

                              , D3DFMT_UNKNOWN, D3DPOOL_MANAGED

, dFilter, dFilter

, dColorKey, &m_pInf, NULL, &m_pTex);

 

 

daux09_2d_sprite02.zip¸¦ ½ÇÇà ÇÏ¸é ´ÙÀ½°ú °°ÀÌ Lc, DX ¸ðµÎ ¿øÇÏ´Â ´ë·Î Ãâ·ÂÇϰí ÀÖ½À´Ï´Ù.

 

<RHW Sprite: daux09_2d_sprite02.zip>

 

 

3.9.2 ȸÀü º¯È¯

2D ȸÀüÀ» °áÁ¤ÇÏ´Â °ÍÀÌ ½¬¿ì¸é¼­µµ ¾î·Æ½À´Ï´Ù. ±×°ÍÀº SpriteÀÇ È°¿ë¿¡ µû¶ó ´Þ¶óÁý´Ï´Ù. ¸¸¾à ºôº¸µå È¿°ú(Billboard Effect)°ú °°Àº 3D¿¡¼­ 2Â÷¿ø Æò¸éÀ» À§ÇÑ °ÍÀ̶ó¸é SpriteÀÇ È¸ÀüÀº 3D º¯È¯ °úÁ¤°ú µ¿ÀÏÇØ¾ß ÇÕ´Ï´Ù. ±×·¸Áö ¾Ê°í È­¸é¿¡¸¸ ¸ÂÃá´Ù¸é 2Â÷¿ø ȸÀü¸¸ °í·ÁÇÏ¸é µË´Ï´Ù. ¿©±â¼­´Â È­¸éÀ» ±âÁØÀ¸·Î ȸÀüÀ» Àû¿ëÇϰڽÀ´Ï´Ù.

 

ȸÀü °¢µµ(Radian)¸¦ ¥è·Î Çϸé ȸÀü Àü ÁÂÇ¥¸¦ (x, y)¶ó Çϰí ȸÀü ÈÄ ÁÂÇ¥¸¦ (x', y') À§Ä¡ º¯È¯Àº ´ÙÀ½°ú °°ÀÌ µË´Ï´Ù.

 

x' = x * cos¥è - y * sin¥è

y' = x * sin¥è + y * cos¥è

<¿À¸¥¼Õ ÁÂÇ¥°è>

x' =  x * cos¥è + y * sin¥è

y' = -x * sin¥è + y * cos¥è

<¿Þ¼Õ ÁÂÇ¥°è>

 

¸¸¾à ȸÀü Á᫐ ÃàÀÌ ÀÖ´Ù¸é À§Ä¡¸¦ ÀÌ Áß½ÉÃุŭ À̵¿ÇÏ°í ³ª¼­ ȸÀüÀ» Àû¿ëÇÑ ´ÙÀ½ ´Ù½Ã ¿ø·¡ÀÇ À§Ä¡·Î ¿Í¾ß ÇÕ´Ï´Ù.

 

¥Äx = x- rot x, ¥Äy = x- rot y

 

¥Äx' = ¥Äx * cos¥è - ¥Äy * sin¥è

¥Äy' = ¥Äx * sin¥è + ¥Äy * cos¥è

 

x' = ¥Äx' + rot x

y' = ¥Äy' + rot y

¶Ç´Â (x' y') = rot(x, y) + (¥Äx', ¥Äy')

 

daux09_2d_sprite03.zip ÀÇ CLcSprite::Draw()´Â ÀÌ·¯ÇÑ È¸ÀüÀ» Àû¿ëÇÑ ÇÔ¼ö·Î ÄÚµåÀÇ Áß°£¿¡ ȸÀü Á᫐ ÃàÀÌ ÁÖ¾îÁö¸é À̸¦ ±¸ÇöÇϰí ÀÖ½À´Ï´Ù. ȸÀüÀº ¹Ý ½Ã°è¹æÇâÀ¸·Î ȸÀüÇϵµ·Ï Çϱâ À§Çؼ­ ¿Þ¼Õ ÁÂÇ¥°è °ø½ÄÀ» Àû¿ëÇß½À´Ï´Ù.

 

if(pvcRot)

{

        D3DXVECTOR2 vcR = D3DXVECTOR2(pvcRot[0], pvcRot[1]);

        D3DXVECTOR2 d(0,0);

        FLOAT   fCos = cosf(fTheta);

        FLOAT   fSin = sinf(fTheta);

 

        for(INT i=0; i<4; ++i)

        {

               D3DXVECTOR2 vcT = pos[i] - vcR;

               d.x = vcT.x * fCos + vcT.y * fSin;

               d.y =-vcT.x * fSin + vcT.y * fCos;

 

               pos[i] = vcR + d;

        }

}

 

°¢µµ´Â D3D´Â Radian [0, 2¥ð]À» »ç¿ëÇϳª Degree [0, 360] °¡ ¸¹ÀÌ »ç¿ëµÇ¹Ç·Î ÀÔ·Â °ªÀº Degree·Î ÇÏ°í ³»ºÎ¿¡¼­ RadianÀ¸·Î ó¸®Çϵµ·Ï ÇÕ´Ï´Ù.

´ÙÀ½ ±×¸²Àº daux09_2d_sprite03.zip ½ÇÇà °á°úÀÔ´Ï´Ù.

 

<ȸÀüÀÌ Àû¿ëµÈ 2D  Sprite: daux09_2d_sprite03.zip>

 

 

3.9.3 Å©±â º¯È¯

Å©±â º¯È¯µµ ȸÀüó·³ È­¸é ±âÁØÀ¸·Î ÀÛ¼ºÇÕ´Ï´Ù. ¸¸¾à Å©±â¿¡ À½¼ö°¡ ¿À¸é Á¿ì, ¶Ç´Â »óÇϸ¦ ¹Ý´ë·Î µÚ ¤¾î ÁÝ´Ï´Ù. ¹ÝÀüÀÌ ÀÖÀ¸¸é »ï°¢ÇüÀ» ±×¸®´Â Á¤Á¡ÀÇ ¼ø¼­°¡ CW¿¡¼­ CCW·Î ¹Ù²ò´Ï´Ù. µû¶ó¼­ Culling Mode¸¦ NoneÀ¸·Î ÇÏ´Â °ÍÀÌ ÁÁ½À´Ï´Ù.

 

m_pDev->SetRenderState( D3DRS_CULLMODE, D3DCULL_NONE);

 

ID3DXSprite´Â Å©±â º¯È¯ °ªÀ» À½¼ö·Î ¼³Á¤Çϸé À§Ä¡¸¦ º¸Á¤ÇØ¾ß ÇÕ´Ï´Ù. À̰ÍÀº ºÒÆíÇϹǷΠ¹ÝÀüÀÌ À־ ½ÃÀÛ À§Ä¡¸¦ º¯µ¿½ÃŰÁö ¾Êµµ·Ï Äڵ忡¼­ Á¤Á¡ÀÇ À§Ä¡¿¡ ´ëÇÑ °è»êÀ» ´ÙÀ½°ú °°ÀÌ ÀÛ¼ºÇÕ´Ï´Ù.

 

FLOAT   fSclX = pvcScl[0];     FLOAT   fSclY = pvcScl[1];

 

if(fSclX<0)

¡¦

        pos[1].x = pos[0].x;

        pos[2].x = pos[1].x;

        pos[0].x = pos[1].x - fDrwW * fSclX;

        pos[3].x = pos[0].x;

¡¦

if(fSclY<0)

¡¦

        pos[3].y = pos[0].y;

        pos[2].y = pos[3].y;

        pos[0].y = pos[3].y - fDrwH * fSclY;

        pos[1].y = pos[0].y;

 

Àüü ÄÚµå´Â daux09_2d_sprite04.zipÀ» Âü°í Çϱâ¹Ù¶ø´Ï´Ù.

 

<Å©±â º¯È¯: daux09_2d_sprite04.zip>

 

 

3.9.4 ¾ËÆÄ ¸Ê(Alpha Map)

Sprite¿¡ ±â´ÉÀ» ³Ö±â ½ÃÀÛÇϸé Çѵµ ³¡µµ ¾øÀ» Á¤µµ·Î ¹«±Ã¹«Áø ÇÕ´Ï´Ù. ±×·¡µµ ÇѰ¡Áö ³Ö°í ½ÍÀº °ÍÀÌ ÀÖ´Ù¸é ¾ËÆÄ ¸ÊÀ» ³Ö´Â °ÍÀÔ´Ï´Ù. ÀÌ ±â´ÉÀº ´ÙÀ½°ú °°ÀÌ ¿øº» À̹ÌÁö¿¡¼­ ƯÁ¤ÇÑ ºÎºÐÀ» À߶󳻰ųª ¾Æ´Ï¸é ¹ÝÅõ¸íÀ» ó¸®ÇÏ´Â °ÍÀÔ´Ï´Ù.

 

<2D Sprite ¾ËÆÄ ¸Ê¿¡ ÀÇÇÑ Æ¯Á¤ ¿µ¿ªÀÇ Ãâ·Â>

 

À̰ÍÀº 3DÀÇ ´ÙÁß ÅØ½ºÃ³(Multi-Texturing)À» Àû¿ëÇÏ¸é ¾ÆÁÖ ½±°Ô ÇØ°áÀÌ µË´Ï´Ù. ´ÙÀ½°ú °°ÀÌ ´ÙÁß ÅØ½ºÃ³ ó¸® ´Ü°è 1¿¡¼­´Â ´Ü°è 0ÀÇ °á°ú °ªÀ» Current·Î ÀúÀåÇÏ°í »ö»óÀº ±×´ë·Î Ãâ·ÂÇÕ´Ï´Ù.

 

m_pDev->SetTextureStageState( 1, D3DTSS_COLORARG1, D3DTA_CURRENT );

m_pDev->SetTextureStageState( 1, D3DTSS_COLOROP,   D3DTOP_SELECTARG1);

 

¾ËÆÄ¸¸ Current°ª°ú °ö¼ÀÀ» Çϰí Ãâ·ÂÇÕ´Ï´Ù.

 

m_pDev->SetTextureStageState( 1, D3DTSS_ALPHAARG1, D3DTA_CURRENT );

m_pDev->SetTextureStageState( 1, D3DTSS_ALPHAARG2, D3DTA_TEXTURE );

m_pDev->SetTextureStageState( 1, D3DTSS_ALPHAOP,   D3DTOP_SELECTARG2);

 

ÅØ½ºÃ³ ÁÂÇ¥´Â ´Ü°è 0¿¡¼­ »ç¿ëÇÑ ÁÂÇ¥¸¦ ±×´ë·Î »ç¿ëÇÕ´Ï´Ù. ÀÌ ºÎºÐÀº ÀÌ ÈÄ SpriteÀÇ ±â´É º¸°­¿¡¼­ ÇÊ¿äÇÏ´Ù¸é ¼öÁ¤ÇÏ¸é µË´Ï´Ù.

 

m_pDev->SetTextureStageState(1, D3DTSS_TEXCOORDINDEX, 0);

 

¹°·Ð Draw() ÇÔ¼öµµ ¼öÁ¤ÇØ¾ß ÇÕ´Ï´Ù. ÀÌÀüÀÇ Draw() ÇÔ¼ö¿Í ±¸ºÐÇϱâ À§Çؼ­ »õ·Î¿î DrawEx() ÇÔ¼ö¸¦ ¸¸µå´Â °ÍÀÌ ÁÁ½À´Ï´Ù. ±×¸®°í ÀÌÀü Draw()ÇÔ¼ö´Â DrawEx()¸¦ È£ÃâÇØ¼­ »ç¿ëÇϵµ·Ï ÇÕ´Ï´Ù.

 

INT CLcSprite::Draw(¡¦)

{

        return DrawEx(pTx0, NULL, ¡¦);

}

 

daux09_2d_sprite05.zip´Â ¾ËÆÄ ¸ÊÀ» Àû¿ëÇÑ Sprite ¿¹Á¦ÀÔ´Ï´Ù. ½ÇÇàÇÏ¸é ´ÙÀ½°ú °°Àº È­¸éÀ» º¼ ¼ö ÀÖ½À´Ï´Ù.

 

<¾ËÆÄ ¸ÊÀÌ ÀÖ´Â 2D Sprite: daux09_2d_sprite05.zip>

 

 







Creative Commons License