¡Ô µ¨ÆÄÀÌ °ÔÀÓ Á¦ÀÛ ¿¬Àç

 ¡å Direct3D9À» ÀÌ¿ëÇÑ 2D °ÔÀÓ ¸¸µé±â

Delphi

¼Ò½ºêó


³ª´Â °­Á °°Àº °ÍÀ» ½á¼­ ¼¼»ó¿¡ °øÇå ÇÏ°í ½ÍÀº »ý°¢Àº ¾ø´Ù.
³»°¡ ±»ÀÌ ÀÌ·± °÷¿¡ °­Á¸¦ ¿Ã¸®Áö ¾Ê¾Æµµ ÃæºÐÈ÷ ¼¼»óÀº ¹ßÀüÀûÀ¸·Î µ¹¾Æ±â ¶§¹®¿¡ '³ª ÇϳªÂë'ÇÏ´Â ¸¶À½À» °¡½¿ ¼Ó¿¡ ±íÀÌ »õ±â°í ³» ¹ä ¹ú¾î ¸Ô±â¿¡¸¸ ¸ôµÎÇÏ´Â, ±×·± Áö±ØÈ÷ ÁÖ°üÀûÀ¸·Î ¾Æ¸§´Ù¿î »îÀ» ¿µÀ§ÇÏ°í ½Í´Ù.

ÇÏÁö¸¸ ³ª´Â Áö±Ý ¿©±â¿¡ °­Á¸¦ ¿Ã¸®°í ÀÖ´Ù. ±× ÀÌÀ¯´Â ¹»±î?
±â¾ïµµ ³¯¶û ¸»¶ûÇÏ´Â ¾ÆÁÖ ¿¹Àü Direct X 3.0 ~ 6.0 ½ÃÀý¿¡ °ü·Ã °­Á¸¦ HiTel¿¡ ¿Ã¸° ÀûÀÌ ÀÖ´Ù. ±× °­Á°¡ µ¹°í µ¹¾Æ ¿©±â±îÁö ¿Ô´ÂÁö ¾Æ´Ï¸é ³»°¡ ÀÚÁøÇؼ­ ¿©±â¿¡ ¿Ã·È´ÂÁö Àß »ý°¢Àº ¾È³ªÁö¸¸ ÇÏ¿©°£ ³ªÀÇ °­Á°¡ ÀÌ »çÀÌÆ® ¾Æ·§ ±¸¼® ¾îµò°¡¿¡ ÀÖ´Ù´Â °ÍÀº È®½ÇÇÏ´Ù.

Áö±ÝÀÌ ¾î´À ½Ã´ëÀΰ¡? Direct X´Â 9.0c±îÁö ³ª¿Ô°í ±×·¡ÇÈ Ä«µå´Â 3D H/W °¡¼ÓÀ» ´ç¿¬ÇÏ´Ù´Â µíÀÌ Áö¿øÇÑ´Ù. Àΰ£ÀÌ ´Þ³ª¶óµµ °¡°í, ¸ÓÁö¾Ê¾Æ È­¼ºÀÎÀÇ Ä§°ø±îÁö ¹ÞÀ»Áöµµ ¸ð¸£´Â ÀÌ »óȲ¿¡¼­ ³ªÀÇ °­Á´ ¾ÆÁ÷µµ °í¹«½ÅÀ» ½Å°í ¸®¾îÄ«¸¦ ²ø¸ç ºñÆ÷Àå µµ·Î¿¡ ¸Ó¹°·¯ ÀÖ´Ù. ÇѸ¶µð·Î ¸»Çؼ­ 'ÂÊÆȸ°´Ù'´Â À̾߱â´Ù.

±×·¡¼­ ¸Ô°í »ç´À¶ó ¾ÆÁÖ ¹Ù»Û ¿ÍÁß¿¡µµ 'µ¨ÆÄÀÌ °ÔÀÓ Á¦ÀÛ ºÎÈï'À̶ó´Â ¹Ì¸í ¾Æ·¡ Ãʺ¸ µ¨ÇǾðÀ» Ȥ¼¼¹«¹ÎÇÏ°íÀÚ ÀÌ·± °­Á ºñ½º¹«¸®ÇÑ °ÍÀ» ¾²°Ô µÇ¾ú´Ù.
 



¢¸¢¸ ¸ñÂ÷ 

        1. ÀÌ °­ÁÂÀÇ ¸ñÀû
        2. »ç¿ëµÇ´Â Åø
        3. Direct3D9ÀÇ ½ÃÀÛ°ú ³¡
        4. DeviceÀÇ »ý¼º
        5. textureÀÇ »ý¼º
        6. texture Àбâ
        7. ºí·»µù ¿É¼Ç
        8. ±âº» primitive Ãâ·Â
        9. À̹ÌÁö Ãâ·Â
        10. È­¸é¿¡ Ãâ·Â Çϱâ

        11. ¿¹Á¦ ¼³¸í
        12. °­Á¸¦ Á¢À¸¸ç
 


1. ÀÌ °­ÁÂÀÇ ¸ñÀû

Direct3D9 (Direct3D 9.0)À» ÀÌ¿ëÇÏ¿© 2D °ÔÀÓÀ» ¸¸µå´Â °ÍÀÌ ¸ñÀûÀÌ´Ù. 3D¸¦ ¸¸µéÁö ¿Ö 2D¸¦ ¸¸µå´À³Ä°í ÇÏ¸é º°·Î ÇÒ¸»Àº ¾ø´Ù. ´ÜÁö 3D¸¦ ¸¸µé±â À§ÇÑ ÀÚ·áµéÀº ÀÌ¹Ì ¸¹ÀÌ ¸¸µé¾îÁ® ÀÖ°í È°¹ßÇÑ ½ºÅ͵𰡠µÇ°í ÀÖÀ¸¸ç °ü·Ã ¼­Àûµµ ¸¹´Ù. ±×¸®°í °³ÀÎÀûÀ¸·Î 3D °ÔÀÓÀ» ÁÁ¾ÆÇÏÁö ¾Ê´Â´Ù. ¶ÇÇÑ ³»°¡ ÇÏÁö ¾Ê´õ¶óµµ 3D °­Á¸¦ ½áÁֽǸ¸ÇÑ ½Ç·ÂÀÚµéÀÌ ¿©±â¿¡ ¸¹±â ¶§¹®ÀÌ´Ù.

°­ÁÂÀÇ ÁÖ´ë»óÀº µ¨ÆÄÀÌ °ÔÀÓ Á¦ÀÛÀÇ Ãʺ¸µéÀÌ´Ù. ´©±¸³ª Ãʺ¸ ¶§´Â Èûµé´Ù. ÀÌ °­Á¸¦ ÅëÇØ ´õ¿í ´õ Èûµç ÁÂÀýÀ» °ÞÀ» ¼ö ÀÖµµ·Ï µµ¿Í ÁÖ´Â °ÍÀÌ ³ªÀÇ ÀÓ¹«´Ù. ¸ðµÎ °°ÀÌ ÀÚ¼¼¸¦ ÃëÇغ¸ÀÚ OTL


2. »ç¿ëµÇ´Â Åø

¿©±â¿¡¼­ »ç¿ëµÈ ¼Ò½º¿Í ¹ÙÀ̳ʸ®µéÀº ¸ðµÎ Delphi 5.0 standard¿¡¼­ ÄÄÆÄÀϵǰí Å×½ºÆ® µÇ¾ú´Ù.
±× ÀÌÇÏÀÇ ¹öÀüÀ̳ª ±× ÀÌ»óÀÇ ¹öÀü¿¡¼­ÀÇ ¿Àµ¿ÀÛÀº ¸ðµÎ InpriseÀÇ Å¿À¸·Î Ã¥ÀÓÀ» Àü°¡ÇÒ »ý°¢ÀÌ´Ù.

DirectX 9.0 runtimeÀÌ ÇÊ¿äÇÏ´Ù. SDK´Â ¼³Ä¡ÇÒ ÇÊ¿ä¾ø´Ù´Â ¸»Ã³·³ µé¸®´Âµ¥, ¼³Ä¡¾ÈÇصµ ÇÁ·Î±×·¥ÀÌ Àß µ¹ ¼ö ÀÖµµ·Ï ³»°¡ Ưº°È÷ ±â¿øÇØ ÁÖ°Ú´Ù.


3. Direct3D9ÀÇ ½ÃÀÛ°ú ³¡

Á¦¸ñÀ¸·Î º¸¾Æ¼­´Â Direct3D9ÀÇ Ã³À½ºÎÅÍ ³¡±îÁö ¸ðµÎ ¾Ë·ÁÁÙ µíÀÌ À̾߱âÇÏ´Â °Í °°´Ù.

Direct3D9µµ ´Ù¸¥ DirectXÀÇ  ¿ÀºêÁ§Æ®¿Í ¸¶Âù°¡Áö·Î ÀνºÅϽº¸¦ °¡Áø´Ù. ±×¸®°í ±× ÀνºÅϽº¸¦ ¾ò±â À§Çؼ­´Â ÀÏ¹Ý ÇÔ¼ö¸¦ È£ÃâÇÏ´Â ¹æ½ÄÀ» ÃëÇϴµ¥ ±× ¼±¾ðÀº ´ÙÀ½°ú °°´Ù.

function Direct3DCreate9(SDKVersion : Cardinal) : IDirect3D9;

ÀÌ ÇÔ¼ö¸¦ ÅëÇؼ­ ¹ÞÀº ÀνºÅϽº´Â ¾ÕÀ¸·Î Direct3D9ÀÇ ±â´ÉÀ» »ç¿ëÇϴµ¥ °¡Àå ½ÃÃÊ°¡ µÇ´Â °ÍÀ¸·Î, ¾ÕÀ¸·Î ³ª¿Ã ¹«¼öÇÑ Direct3D9ÀÇ ÀÎÅÍÆäÀ̽º(Ŭ·¡½º)´Â ¸ðµÎ ÀÌ ÀνºÅϽº¸¦ ÅëÇؼ­ »ý¼ºµÇ°Å³ª ÀÌ ÀνºÅϽº¿¡¼­ »ý¼ºµÈ ÀÎÅÍÆäÀ̽º¿¡ ÀÇÇØ »ý¼ºµÈ´Ù. µû¶ó¼­ ÀÌ ÀνºÅϽº´Â Àü¿ªº¯¼ö, ±Û·Î¹ú ¸â¹öº¯¼ö µîÀ¸·Î Á¤ÀǵǾ DirectX°¡ À¯È¿ÇÑ ¹üÀ§ ³»¿¡¼­´Â Ç×»ó Á¢±Ù °¡´ÉÇϵµ·Ï ÇØ¾ß ÇÑ´Ù. (Áï, ·ÎÄà º¯¼ö µîÀ¸·Î ½ºÅÿ¡ »ý¼ºµÇ¾î¼­´Â ¾ÈµÈ´Ù)

±×·³ ÀνºÅϽº¸¦ »ý¼ºÇÏ´Â ±¸Ã¼ÀûÀÎ Äڵ带 º¸ÀÚ. (¿©±â¼­´Â Ŭ·¡½º ¸â¹ö º¯¼ö·Î ¼±¾ðµÇ¾ú´Ù.)
 

// º¯¼ö ¼±¾ð
m_pD3D: IDirect3D9;
.......

// ÀνºÅϽº¸¦ »ý¼ºÇÑ´Ù.
m_pD3D := Direct3DCreate9(D3D_SDK_VERSION);

// ÀνºÅϽº »ý¼º ¿©ºÎ¸¦ °Ë»çÇÑ´Ù.
if not assigned(m_pD3D) then
    exit;
 

¿©±â¼­ Direct3DCreate9()ÀÇ ÆĶó¹ÌÅÍ·Î D3D_SDK_VERSION°¡ µé¾î °¬´Ù. D3D_SDK_VERSION´Â Direct3D9¿¡¼­ Á¤ÀǵǴ »ó¼ö °ªÀ¸·Î, ¾ÖÇø®ÄÉÀ̼ǿ¡°Ô Á¤È®ÇÑ ¹öÀüÀ¸·Î ºôµåµÇ¾ú´Â°¡¸¦ ¾Ë·ÁÁÖ´Â ¿ªÇÒÀ» ÇÑ´Ù. µû¶ó¼­ ¹«Á¶°Ç D3D_SDK_VERSION¸¸ ³Ö´Â´Ù°í »ý°¢ÇÏ¸é °¡Àå ÆíÇÏ´Ù.

±×·³ ÀÌ·¸°Ô »ý¼ºÇÑ ÀνºÅϽº¸¦ ÇØÁ¦ÇÏ´Â Äڵ带 º¸ÀÚ.
 

m_pD3D := nil;
 

¾ÆÁÖ °£´ÜÇÏ´Ù ´ÜÁö nil¸¸ ´ëÀÔÇÏ´Â °ÍÀ¸·Î ³¡³­´Ù. C++À̶ó¸é Release()¸¦ È£ÃâÇØÁÖ¾î¾ß ÇÏ°ÚÁö¸¸ DelphiÀÇ COMÀÇ Æ¯¼º »ó, ±×³É ´ëÀÔ¸¸ ÇÏ¸é ¾Ë¾Æ¼­ ·¹ÆÛ·±½º Ä«¿îÆ®¿¡ µû¶ó µ¿ÀÛÀÌ ¼öÇàµÈ´Ù. ÀÌ ºÎºÐÀº ´ç½ÅÀÌ µ¨ÆÄÀ̸¦ Çϱ⠶§¹®¿¡ ´©¸± ¼ö Àִ Ư±ÇÀÌ´Ù.

ÀÌ¹Ì ´ç½ÅÀº 'Direct3D9ÀÇ ½ÃÀÛ°ú ³¡'À» ¾Ë°Ô µÇ¾ú´Ù.



4. DeviceÀÇ »ý¼º

Direct3D9 ÀνºÅϽºÀÇ »ý¼ºÀº ÀÇ¿Ü·Î ½Ì°Ì°Ô ³¡³Â´Ù. »ç½Ç ¾ÕÀ¸·Î ³ª¿Ã °Íµéµµ ÀÌ·± ¹æ½ÄÀ» Å©°Ô ¹þ¾î³ªÁö ¾Ê´Â´Ù.
À̹ø ¼³¸íÇÒ °ÍÀº Device´Ù. Device´Â Direct3D¿¡¼­´Â ½ÇÁ¦ ±×·¡ÇÈÀÌ Ãâ·ÂµÇ´Â ÀåÄ¡¸¦ Ç¥ÇöÇϱâ À§ÇÑ ÀÎÅÍÆäÀ̽º·Î º¼ ¼ö ÀÖ´Ù. È­¸é¿¡ Ãâ·ÂµÉ ÀåÄ¡ ÀÚü¸¦ Device·Î º¼ ¼öµµ Àִµ¥ ÀÏ´Ü ÃÖÁ¾ Ãâ·ÂÀº ¸ðµÎ ÀÌ Device¸¦ ÅëÇØ ³ª°£´Ù°í »ý°¢ÇÏ¸é µÈ´Ù.

±×·³ Device¸¦ »ý¼ºÇÏ´Â ¹æ¹ýÀ» ¾Ë¾Æ º¸ÀÚ. Device´Â ÀÌ ¾Õ¿¡¼­ »ý¼ºÇÑ Direct3D9 ÀνºÅϽº¸¦ ÅëÇؼ­¸¸ »ý¼ºÇÒ ¼ö ÀÖ´Ù. Direct3D9 ÀνºÅϽºÀÇ Å¬·¡½º¿¡´Â ½Ê¼ö°³ÀÇ ¸Þ¼­µå¸¦ °¡Áö°í Àִµ¥ ±× Áß¿¡¼­ Device¸¦ »ý¼ºÇϱâ À§ÇÑ °ÍÀÌ IDirect3D9.CreateDevice()ÀÌ¸ç ±×°ÍÀÇ Á¤ÀÇ´Â ´ÙÀ½°ú °°´Ù.
 

function IDirect3D9.CreateDevice
(
    // D3DADAPTER_DEFAULT¸¸ ³ÖÀÚ
    const Adapter : Cardinal;
    // D3DDEVTYPE_HAL¸¸ ³ÖÀÚ
    const DeviceType : TD3DDevType;
    // À©µµ¿ì ÇÚµé, Áï Form1.Handle¿¡ ÇØ´çÇÏ´Â °Í
    FocusWindow : HWND;
    // D3DCREATE_SOFTWARE_VERTEXPROCESSINGÀ» ³ÖÀÚ
    BehaviorFlags : LongWord;
    // ¾Æ·¡¿¡¼­ ¼³¸í
    var PresentationParameters : TD3DPresentParameters;
    // Device »ý¼º¿¡ ¼º°øÇßÀ¸¸é ¿©±â¿¡ °ªÀÌ µ¹¾Æ ¿Â´Ù
    out ReturnedDeviceInterface : IDirect3DDevice9
): HResult; stdcall;
 

º¹ÀâÇϱä ÇÏÁö¸¸ ¾Ë°í º¸¸é ´Ù ½¬¿î ³»¿ëµéÀÌ´Ù. ÀÚ¼¼ÇÑ ÆĶó¹ÌÅÍÀÇ ¼³¸íÀ̳ª »ç¿ë°¡´ÉÇÑ Ç÷¡±×´Â DirectX 9.0 Documentation¿¡ º¸¸é ÀÚ¼¼ÇÏ°Ô ³ª¿Â´Ù. ³Ö¾î¾ß ÇÒ ÆĶó¹ÌÅ͸¦ Á÷Á¢ ¸í½ÃÇÑ °ÍÀº ½ÃÇàÂø¿À¸¦ ÁÙÀ̱â À§ÇÑ °ÍÀÌ¸ç °í±Þ »ç¿ëÀÚ°¡ µÇ±â À§Çؼ­´Â ´Ù¸¥ ÆĶó¹ÌÅÍÀÇ ¿ëµµ¿¡ ´ëÇؼ­µµ ¼÷ÁöÇÏ°í ÀÖ¾î¾ß ÇÑ´Ù.

±×·¸´Ù¸é ÇöÀç ¼³¸íµÇÁö ¾ÊÀº ÆĶó¹ÌÅÍ´Â PresentationParametersÀÌ´Ù. ÀÌ ÆĶó¹ÌÅÍ´Â Device¸¦ »ý¼º ÇÒ ¶§ ±× ¼Ó¼ºÀ» Á¤ÀÇÇØ ÁÖ´Â °ÍÀ̶ó°í ÇÒ ¼ö ÀÖ´Ù.
 

// º¯¼ö ¼±¾ð
d3dPP      : TD3DPresentParameters;
.......

// fill D3D present parameters with zero
ZeroMemory(@d3dPP, sizeof(d3dPP));

// fill D3D present parameter's fields
d3dPP.SwapEffect       := D3DSWAPEFFECT_DISCARD;
d3dPP.BackBufferCount  := 1;
d3dPP.Flags            := D3DPRESENTFLAG_LOCKABLE_BACKBUFFER;
d3dPP.Windowed         := not isFullScreen;
d3dPP.BackBufferFormat := d3dFormat;
d3dPP.BackBufferWidth  := width;
d3dPP.BackBufferHeight := height;

ÀÚ, ÀÌ·¸°Ô¸¸ ³Ö¾îÁÖ¸é Device´Â »ý¼ºµÇ´Â °ÍÀÌ´Ù. TD3DPresentParameters´Â º¸´Â ¹Ù¿Í °°ÀÌ ¾ÆÁÖ Àǹ̰¡ ¸íÈ®ÇÏ°Ô Çʵå¸íÀÌ ºÙ¾î ÀÖÀ¸¹Ç·Î º°´Ù¸¥ ¼³¸íÀº ÇÏÁö ¾Ê°Ú´Ù. ÇÏÁö¸¸ µü µÎ °³¸¸ ¤°í ³Ñ¾î°¡ÀÚ¸é, ±× ù°°¡ Windowed¶ó´Â ÇʵåÀε¥ ÀÌ°ÍÀÌ TRUEÀ̸é À©µµ¿ì â ¸ðµå·Î »ý¼ºµÇ¸ç ÀÌ°ÍÀÌ FALSEÀ̸é Àüü È­¸é ¸ðµå·Î ½ÇÇàµÈ´Ù. (ÀÌ°ÍÀº ³ªÁß¿¡ alt-enter µîÀ» ÀÌ¿ëÇؼ­ È­¸é Ãâ·Â ¸ðµå¸¦ ÀüȯÇϵµ·Ï ¸¸µé ¶§µµ »ç¿ëµÈ´Ù.) µÑ°´Â BackBufferFormatÀε¥ Àüü È­¸é ¸ðµåÀÏ ¶§´Â ¿©±â¿¡´Ù°¡ »ç¿ëÇÒ ¹é¹öÆÛÀÇ Æ÷¸ËÀ» Á÷Á¢ ¸í½ÃÇÒ ¼ö ÀÖ´Ù. ¿©±â¿¡ µé¾î °¥ °ÍÀº µü 2°³¸¸ ¿Ü¿ì¸é µÈ´Ù. 16ºñÆ® ¸ðµå·Î ÇÒ ¶§´Â D3DFMT_R5G6B5, 32ºñÆ® ¸ðµå¸¦ ÇÒ ¶§´Â D3DFMT_X8R8G8B8ÀÌ´Ù. ¹°·Ð ÀÚ½ÅÀÌ ½º½º·Î Áß±Þ »ç¿ëÀÚ¶ó°í »ý°¢ÇϽô ºÐµéÀº IDirect3D9.CheckDeviceType() ÇÔ¼ö¸¦ ÀÌ¿ëÇؼ­ D3DFMT_X1R5G5B5, D3DFMT_A1R5G5B5, D3DFMT_R8G8B8, D3DFMT_A8R8G8B8 µîµîÀÇ °¡´É¼ºÀ» ½ÃµµÇغÁµµ µÈ´Ù.

ÀÌ·¸°Ô Device¸¦ »ý¼ºÇÏ°í ³ª¸é ±âº»ÀûÀÎ ¼Ó¼ºÀ» ¼³Á¤ÇØ¾ß ÇÑ´Ù. ÇÏÁö¸¸ ÀÌ °­Á´ 2D¸¦ ÀÌ¿ëÇÏ´Â °ÍÀ̱⠶§¹®¿¡ ±»ÀÌ ¼³Á¤ÇÏÁö ¾Ê°í µðÆúÆ® ¼Ó¼ºÀ» ½áµµ Å« ¹®Á¦´Â ¾ø´Ù (¼ÓÁö ¸»ÀÚ!). ±×·¡µµ ¿¹ÀÇ »ó ¤°í ³Ñ¾î°¡ÀÚ¸é ´ÙÀ½°ú °°´Ù.

1) View port ¼³Á¤
 

viewPort: TD3DVIEWPORT9;

viewPort.X      := 0;
viewPort.Y      := 0;
viewPort.Width  := width;
viewPort.Height := height;
viewPort.MinZ   := 0.0;
viewPort.MaxZ   := 1.0;

m_pD3DDevice.SetViewport(viewPort);
 

°£´ÜÇÏ´Ù. ÀÌÁ¦ºÎÅÍ ¸ðµç DeviceÀÇ Ãâ·ÂÀº (0, 0) - (width, height)¿¡ ±¹ÇѵȴÙ. »ç½Ç ÀüÈ­¸éÀ¸·Î Ãâ·ÂÇÏ´Â ´ëºÎºÐÀÇ 2D°ÔÀÓ¿¡¼­´Â ¼³Á¤ÇÏÁö ¾Ê°í »ç¿ëÇصµ µÇ³ª, ¸Ê Ãâ·Â ¿µ¿ªÀÌ È­¸éÀÇ ÀϺηΠÇÑÁ¤µÇ´Â °ÔÀÓÀÇ °æ¿ì¿¡´Â µû·Î clipping area¸¦ ±¸ÇöÇÒ ÇÊ¿ä°¡ ¾øÀÌ view port¸¦ Á¶ÀÛÇÏ´Â °Í¸¸À¸·Îµµ ÈǸ¢ÇÏ°Ô clippingµÈ´Ù.

2) ¾ËÆÄ ºí·»µù ¼Ó¼º ÁöÁ¤
 

// ºí·»µù ½ºÅ×ÀÌÁöÀÇ ¼Ó¼º ¼³Á¤
m_pD3DDevice.SetTextureStageState(0, D3DTSS_TEXCOORDINDEX, 0);
m_pD3DDevice.SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
m_pD3DDevice.SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
m_pD3DDevice.SetTextureStageState(0, D3DTSS_COLOROP,   D3DTOP_MODULATE);
m_pD3DDevice.SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
m_pD3DDevice.SetTextureStageState(0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE);
m_pD3DDevice.SetTextureStageState(0, D3DTSS_ALPHAOP,   D3DTOP_MODULATE);

// ÇÊÅÍ »ç¿ëÇÏÁö ¾ÊÀ½
m_pD3DDevice.SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
m_pD3DDevice.SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);

// Çȼ¿ ºí·»µù ¹æ¹ý °áÁ¤
m_pD3DDevice.SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
m_pD3DDevice.SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
m_pD3DDevice.SetRenderState(D3DRS_BLENDOP, D3DBLENDOP_ADD);
 

¸ÕÀú ºí·»µù ½ºÅ×ÀÌÁöÀÇ ¼Ó¼ºÀ» º¸ÀÚ. Direct3D´Â ÃÑ 8°³ÀÇ ºí·»µù ½ºÅ×ÀÌÁö¸¦ Áö¿øÇϳª º» »ùÇÿ¡¼­´Â 0¹ø ½ºÅ×ÀÌÁö¸¸ »ç¿ëÇϵµ·Ï ÇÑ´Ù. µû¶ó¼­ 0¹ø¿¡ ´ëÇÑ ¼³Á¤À» ÇÑ °ÍÀ̸ç color¿Í alpha¸ðµÎ texture¿Í diffuse Ä÷¯¸¦ modulateÇÏ´Â ¹æ½ÄÀ¸·Î ºí·»µù Ç϶ó°í ¼³Á¤Çß´Ù. Á» ´õ ½±°Ô ¸»Çϸé, ¾ÆÁÖ ÀϹÝÀûÀÎ ºí·»µù ¹æ½ÄÀ̶ó°í ÀÌÇØÇÏ¸é ¸Ó¸®°¡ Á» ´ú ¾ÆÇÁ´Ù.

Ãß°¡ÀûÀ¸·Î ¾Ë¾Æ µÎ¾î¾ß ÇÒ °ÍÀº, µÎ ¹ø° ½ºÅ×ÀÌÁöºÎÅÍ´Â ÀÌÀü °á°ú¿Í ´Ù½Ã ºí·»µùÇÏ´Â °æ¿ì°¡ ¸¹À¸¹Ç·Î D3DTA_CURRENT¸¦ »ç¿ëÇÒ °æ¿ì°¡ ¸¹´Ù´Â °Í°ú, D3DTOP_MODULATE ÀÌ¿Ü¿¡ D3DTOP_ADD µîÀ» »ç¿ëÇÏ¸é ´Ù¸¥ ÀÌÆåÆ®¸¦ Á¶ÇÕÇÒ ¼ö ÀÖ´Ù´Â °Í Á¤µµ¸¸ ¾Ë¾ÆµÎ¸é µÉ °Í °°´Ù.

ÇÊÅÍ´Â 3Á¾·ù ÀÌ»óÀÌ ÀÖÁö¸¸ 2D °ÔÀÓÀÇ ´À³¦À» ³»±â À§Çؼ­´Â D3DTEXF_POINT¸¦ »ç¿ëÇÏ´Â °ÍÀÌ ÁÁ´Ù. D3DTEXF_LINEAR¸¦ »ç¿ëÇØ¾ß °á°ú°¡ ´õ ÁÁÀº ºÎºÐÀÌ Àִµ¥ ±×°ÍÀº Á÷Á¢ ´«À¸·Î È®ÀÎÇغ¸¸é ½±°Ô °áÁ¤ ÇÒ ¼ö °¡ ÀÖ´Ù.

¸¶Áö¸·Àº Çȼ¿ ºí·»µù ¹æ½ÄÀ» ÁöÁ¤ÇÏ´Â °ÍÀÌ´Ù. ÆĶó¹ÌÅÍ´Â, »ç¿ëÇÒ ¼ö ÀÖ´Â H/W capability ³»¿¡¼­ ¹«±Ã¹«ÁøÇϳª À§ÀÇ ÆĶó¹ÌÅÍ°¡ °¡Àå ÀϹÝÀûÀÎ ¾ËÆÄ ºí·»µù¿¡ ºÎÇÕÇÑ´Ù°í »ý°¢ÇÏ¿© À§¿Í °ªÀÌ °ªÀ» ¼³Á¤Çß´Ù. ±× Àǹ̴Â, source pixelÀÇ alphaºñÀ²·Î destination pixel°ú ¼¯´Â °ÍÀÌ´Ù.

Âü°í·Î, ÀÌ°ÍÀÇ µðÆúÆ® °ªÀº
 

m_pD3DDevice.SetRenderState(D3DRS_SRCBLEND, D3DBLEND_ONE);
m_pD3DDevice.SetRenderState(D3DRS_DESTBLEND, D3DBLEND_ZERO);
m_pD3DDevice.SetRenderState(D3DRS_BLENDOP, D3DBLENDOP_ADD);
 

Àε¥, ÀÌ°ÍÀº sourceÀÇ ³»¿ëÀ» destination¿¡ ±×´ë·Î Ãâ·Â(º¸Åë copy¶ó ºÒ¸®´Â...)Ç϶ó´Â ÀǹÌÀÌ´Ù.

3) Ä÷¯Å° ¼Ó¼º ÁöÁ¤

Ä÷¯Å°´Â DirectDraw ¶§µµ »ç¿ëµÈ °íÀüÀûÀÎ masking ±â¹ýÀÌ´Ù. ±× ¿ø¸®´Â '¸í½ÃÇÑ °ªÀ» Á¦¿ÜÇÑ ³ª¸ÓÁö¸¦ Ãâ·ÂÇ϶ó'´Â ÀǹÌÀε¥, Direct3D¿¡¼­´Â alpha test¶ó´Â ¹æ¹ýÀ¸·Î Ä÷¯Å°ÀÇ ±â´ÉÀ» Áö¿øÇÑ´Ù. (±×³É À§ÀÇ alpha blendingÀ» ÀÌ¿ëÇصµ µÈ´Ù)

alpha test´Â alpha °ªÀÌ ¸í½ÃÇÑ Á¶°Ç°ú °°À» ¶§¸¸ source pixelÀ» Ãâ·ÂÇ϶ó´Â °ÍÀε¥, ¾Æ·¡¿Í °°ÀÌ Çϸé alpha°¡ 0ÀÎ ºÎºÐ¸¸ Åõ¸íÇÏ°Ô Ã³¸®Ç϶ó´Â Àǹ̰¡ µÈ´Ù.
 

// if alpha <> $00 then
m_pD3DDevice.SetRenderState(D3DRS_ALPHAREF, $00);
m_pD3DDevice.SetRenderState(D3DRS_ALPHAFUNC, D3DCMP_NOTEQUAL);
 

´Ù½Ã Ç®¾î º¸¸é, alpha°¡ $00ÀÌ ¾Æ´Ò ¶§(not equal) source pixelÀ» Ãâ·ÂÇ϶ó´Â Àǹ̴Ù. ÀÀ¿ëÇؼ­ °°Àº È¿°ú¸¦ ³»·Á¸é,
 

// if alpha > $00 then
m_pD3DDevice.SetRenderState(D3DRS_ALPHAREF, $00);
m_pD3DDevice.SetRenderState(D3DRS_ALPHAFUNC, D3DCMP_GREATER);
 

ÀÌ·¸°Ô ¿©·¯°¡Áö ¹æ¹ýÀ¸·Î Ç¥ÇöÀÌ °¡´ÉÇÏ´Ù. (³ª¸ÓÁö ÆĶó¹ÌÅÍ´Â SDK ¸Å´º¾óÀ» Âü°íÇϱ⠹ٶõ´Ù)

´Ü, ÀÌ ¹æ¹ýÀ» »ç¿ëÇÏ·Á¸é ÃÖÃÊÀÇ À̹ÌÁö°¡ 0ÀÇ °ªÀ» °¡Áö´Â alpha pixelÀ» Æ÷ÇÔÇÏ°í Àְųª, ƯÁ¤ÇÑ Ä÷¯ ÀÏ ¶§´Â alpha°ªÀ» 0À¸·Î ¼³Á¤Çؼ­ texture¸¦ ÀÐ¾î ¿Àµµ·Ï »ç¿ëÀÚ°¡ Á÷Á¢ ±¸ÇöÇÒ ¼öµµ ÀÖ´Ù. ÀÌ°ÍÀº ³ªÁß¿¡ ´Ù½Ã ¼³¸íÇϵµ·Ï ÇÏ°Ú´Ù.

4) ±âŸ ¼Ó¼º ÁöÁ¤

±× ÀÌ¿Ü¿¡´Â µðÆúÆ® ¼Ó¼º °ªÀ» ½áµµ ¹«¹æÇÏÁö¸¸ ¸î °¡Áö Á¤µµ´Â ÃëÇâ¿¡ µû¶ó ´Ù¸£°Ô ¼³Á¤Çصµ µÈ´Ù.
³ªÀÇ °æ¿ì¿¡´Â ¾Æ·¡ÀÇ °ÍÀ» ¼³Á¤ÇÑ´Ù.
 

m_pD3DDevice.SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);
 

Direct3D¿¡¼­ ÀϹÝÀûÀ¸·Î, ¹Ý½Ã°è¹æÇâÀ¸·Î °¨±â´Â Æú¸®°ïÀº ±× ¸éÀÌ ¹Ý´ë ¹æÇâÀ¸·Î ÇâÇÏ´Â Æú¸®°ïÀ¸·Î Ãë±ÞÇؼ­ ¿£Áø¿¡¼­ Ãâ·ÂÀ» »ý·«ÇÑ´Ù. ÇÏÁö¸¸ À§ÀÇ °ÍÀ» ¼³Á¤ÇÏ¸é ¾î¶»°Ô °¨°Ü ÀÖ´Â Æú¸®°ïÀÌ¶óµµ ±×´ë·Î Ãâ·ÂÇØ ÁØ´Ù. Áï, ¹Ý´ë·Î °¨¾Æ¼­ µÚÁýÈù ½ºÇÁ¶óÀÌÆ®µµ ±×¸± ¼ö ÀÖ´Ù. ÀÌ°ÍÀ» Àß ÀÌ¿ëÇÏ¸é ¿ÞÂÊÀ¸·Î ÇâÇÑ À̹ÌÁö¸¸ ·ÎµùÇÑ ÈÄ, ¿À¸¥ÂÊÀ¸·Î ÇâÇÑ À̹ÌÁö´Â ¿ÞÂÊÀ¸·Î ÇâÇÑ À̹ÌÁö¸¦ flip Çؼ­ »ç¿ëÇÒ ¼ö ÀÖ°Ô µÈ´Ù.

5) ±âŸ ¼Ó¼º ¾ò±â

±»ÀÌ DeviceÀÇ ¼Ó¼ºÀ» º¸À¯ÇÏ°í ÀÖÀ» ÇÊ¿ä´Â ¾øÀ¸³ª ±×·¡µµ ¼Ó¼º¿¡ ´ëÇÑ ºü¸¥ Á¢±ÙÀ» À§Çؼ­ ¹Ì¸® °ªÀ» ¹Þ¾Æ µÑ ¼öµµ ÀÖ´Ù.
 

m_d3dCaps        : TD3DCaps9;
m_d3dDisplayMode : TD3DDisplayMode;

// DeviceÀÇ capability¸¦ ¾ò´Â´Ù
m_pD3DDevice.GetDeviceCaps(m_d3dCaps);
// µð½ºÇ÷¹ÀÌÀÇ Å©±â¿Í pixel formatÀ» ¾ò´Â´Ù
m_pD3DDevice.GetDisplayMode(0, m_d3dDisplayMode);
 

ƯÈ÷ â¸ðµå·Î ÃʱâÈ­ µÇ¾úÀ» ¶§´Â ÀÌ¹Ì ¼³Á¤µÈ pixel format À§¿¡¼­ Device°¡ »ý¼ºµÇ´Âµ¥ À̶§ ¹ÙÅÁ È­¸éÀÇ pixel formatÀ» ¾ò¾î¿À´Âµ¥ À¯¿ëÇÏ°Ô ¾µ ¼ö ÀÖ´Ù.

±×·³ ÀÌ°ÍÀ¸·Î µð¹ÙÀ̽ºÀÇ »ý¼ºµµ ³¡³µ´Ù. Áö±Ý±îÁö´Â Device¸¦ »ý¼ºÇÏ°í ±× ¼Ó¼ºÀ» ÁöÁ¤Çß´Ù. ´ÙÀ½ Àå¿¡¼­´Â ±× ¼Ó¼ºÀ» »ç¿ëÇϱâ À§ÇÑ ÀÚ¿øÀ» »ý¼ºÇϵµ·Ï ÇÏ°Ú´Ù.



5. textureÀÇ »ý¼º

Texture´Â À̹ÌÁö¸¦ ¿Ã·Á ³õ±â À§ÇÑ °ø°£À¸·Î ÀÌ °­Á ³»¿¡¼­´Â 2DÀÇ À̹ÌÁö ¹öÆÛ¿Í µ¿ÀÏÇÑ °ÍÀ¸·Î ºÁµµ ¹«¹æÇÏ´Ù. ±×·¸´Ù¸é °¡Àå Áß¿äÇÑ ¼Ó¼ºÀº µü 3°¡Áö´Ù. ±×°ÍÀº ¹Ù·Î, °¡·Î Å©±â, ¼¼·Î Å©±â, pixel formatÀε¥ ÀÌ °­Á¿¡¼­´Â ÀÌ 3°¡Áö¸¦ ÆĶó¹ÌÅÍ·Î ¹Þ¾Æ¼­ texture¸¦ ¸¸µå´Â ¿¹Á¦¸¦ ¸¸µé »ý°¢ÀÌ´Ù. (½ÇÁ¦·Î ÇÊ¿äÇÑ ÆĶó¹ÌÅÍ´Â ´õ ÀÖ´Ù´Â À̾߱â´Ù.)

Texture´Â ÀÏ¹Ý À̹ÌÁö ¹öÆÛ¿Í´Â ´Þ¸® ±× Å©±â³ª ÇüÅ¿¡ ´ëÇØ Á¦¾àÀÌ ½ÉÇÑ ÆíÀÌ´Ù. ´ëÇ¥ÀûÀÎ 3°¡Áö¸¦ º¸ÀÚ¸é,
 

1> °¡·Î¿Í ¼¼·ÎÀÇ Å©±â´Â 2ÀÇ ½Â¼ö°¡ µÇ¾î¾ß ÇÑ´Ù.
2> °¡·Î¿Í ¼¼·Î Å©±â°¡ °°¾Æ¾ß ÇÑ´Ù. (±¸½Ä H/WÀÇ °æ¿ì)
3> »ý¼º °¡´ÉÇÑ ÃÖ´ë Å©±â¿¡ ´ëÇÑ Á¦¾àÀÌ ÀÖ´Ù. (±¸½Ä H/WÀÇ °æ¿ì)
 

ÀÚ, ±×·³ ÆĶó¹ÌÅÍ·Î ¹Þ¾Æ µéÀÎ width, height¿¡ ´ëÇØ DeviceÀÇ capabity¸¦ È®ÀÎÇÏ¿© ¿øÇÏ´Â Å©±â·Î Á¶Á¤À» Çغ¸ÀÚ.

realW, realH: integer; 

// ¾Æ±îµµ ÇÑ ¹ø ³ª¿Ô´ø DeviceÀÇ capability¸¦ ¾ò¾î ¿À´Â ÇÔ¼ö
m_pD3DDevice.GetDeviceCaps(ddCaps);

// TextureÀÇ Å©±â°¡ 2ÀÇ ½Â¼ö¿©¾ß ÇÑ´Ù¸é,
if (ddCaps.TextureCaps and D3DPTEXTURECAPS_POW2) > 0 then begin
    // widthº¸´Ù Å©°Å³ª °°Àº 2ÀÇ ½Â¼ö Áß¿¡¼­ °¡Àå ÀÛÀº °ªÀ» ã´Â´Ù.
    realW := 4;
    while width > realW do
        realW := realW shl 1;

    // heightº¸´Ù Å©°Å³ª °°Àº 2ÀÇ ½Â¼ö Áß¿¡¼­ °¡Àå ÀÛÀº °ªÀ» ã´Â´Ù.
    realH := 4;
    while height > realH do
        realH := realH shl 1;
end
else begin

    // ¿ø·¡ÀÇ width, height¸¦ ´ëÀÔÇÑ´Ù.
    realW := width;
    realH := height;
end;

// TextureÀÇ °¡·Î ¼¼·Îºñ°¡ Ç×»ó 1:1ÀÌ¿©¾ß ÇÑ´Ù¸é,
if (ddCaps.TextureCaps and D3DPTEXTURECAPS_SQUAREONLY) > 0 then begin
    // °¡·Î ¼¼·Î Áß¿¡¼­ Å« ÂÊÀ¸·Î ¸ÂÃá´Ù.
    if realW > realH then
        realH := realW
    else
        realW := realH
end;

ÀÌ °úÁ¤À» °ÅÄ¡¸é realW¿Í realH´Â Device°¡ ¿øÇÏ´Â Å©±â°¡ µÇ¾î ÀÖÀ» °ÍÀÌ´Ù. ±×·¸´Ù¸é ÀÌÁ¦´Â ÀÌ °ªÀ» °¡Áö°í texture¸¦ »ý¼ºÇÏ¸é µÈ´Ù.
 

m_pD3DDevice.CreateTexture(realW, realH, 0, 0, pixelFormat, D3DPOOL_MANAGED, pTexture, nil);
 
¾Ñ, ÀÌ°Ô ¹«¾ùÀΰ¡? Á¶±Ý Àü¿¡´Â 3°³ÀÇ ÆĶó¹ÌÅ͸¸ ÀÖÀ¸¸é µÈ´Ù°í Çߴµ¥ ÀÌ°ÍÀº ¾à°£ ´õ º¹ÀâÇÏ°Ô º¸ÀδÙ. ÇÏÁö¸¸ ÀÌ °­Á´ Ȥ¼¼¹«¹ÎÀ» ±âº» ¿øÄ¢À¸·Î ÇÏ°í Àֱ⠶§¹®¿¡ ÀÌ Á¤µµ´Â ±×³É ´«°¨¾Æ ÁÖ±æ ¹Ù¶õ´Ù. À̹ø¿¡µµ ±×³É ¶È°°ÀÌ »ç¿ëÇÏ¸é µÈ´Ù. ±×´ë½Å Çϳª¸¸ ¤°í ³Ñ¾î°¡¾ß ÇÒ °ÍÀÌ ÀÖ´Ù. ±×°ÍÀº ¹Ù·Î D3DPOOL_MANAGED¶ó´Â ÆĶó¹ÌÅÍÀε¥ ¾Ë°íº¸¸é ÀÌ°ÍÀÌ °¡Àå Áß¿äÇÑ textureÀÇ ¼Ó¼ºÁßÀÇ Çϳª¸¦ °áÁ¤ÇÏ´Â ¿ä¼Ò´Ù.
 

D3DPOOL_DEFAULT
    - ºñµð¿À ¸Þ¸ð¸®ÀÇ ¿µ¿ª¿¡ »ý¼ºµÈ´Ù. ºñµð¿À ¸Þ¸ð¸®°¡ ºÎÁ·ÇÏ¸é ½Ã½ºÅÛ ¸Þ¸ð¸®¿¡ »ý¼ºµÈ´Ù.
    - Lock/UnlockÀÌ ºÒ°¡´É ÇÏ´Ù.
    - IDirect3DDevice9.StretchRect()¸¦ ÅëÇØ ¼­·ÎÀÇ surface¸¦ º¹»çÇÒ ¼ö ÀÖ´Ù.
    - IDirect3DDevice9.UpdateSurface()¸¦ ÅëÇØ ¸Þ¸ð¸® surface¸¦ ÀÚ½ÅÀÇ
       surface¿¡ ¿Ã·Á ³õÀ» ¼ö ÀÖ´Ù.
    - IDirect3DDevice9.ColorFill()À» ÅëÇØ ÁöÁ¤µÈ ¿µ¿ªÀ» ÁöÁ¤µÈ »öÀ¸·Î ä¿ï ¼ö ÀÖ´Ù.

D3DPOOL_MANAGED
    - óÀ½¿¡´Â ºñµð¿À ¸Þ¸ð¸®°¡ ¾Æ´Ñ ¾îµò°¡¿¡ »ý¼ºµÈ´Ù. ±×¸®°í »ç¿ëÇÒ ¶§´Â ºñµð¿À ¸Þ¸ð¸®¿¡
       ¿Ã¶ó°£´Ù.
    - IDirect3DTexture9.PreLoad() ¸Þ¼­µå¸¦ ÅëÇØ ¹Ì¸® ºñµð¿À ¸Þ¸ð¸®¿¡ ¿Ã·Á ³õÀ» ¼öµµ
       ÀÖ´Ù.
    - Lock/UnlockÀÌ °¡´É ÇÏ´Ù. ÇÏÁö¸¸ IDirect3DDevice9.LockRect() ÇÔ¼ö¿¡¼­ ¾öû³­
       latency°¡ ¹ß»ýÇÒ ¶§°¡ ÀÖ´Ù.
    - Device lostÀÇ °æ¿ì, ½Ã½ºÅÛ¿¡ ÀÇÇØ ÀÚµ¿ º¹±¸µÈ´Ù.

3DPOOL_SYSTEMMEM
    - ½Ã½ºÅÛ ¸Þ¸ð¸® ¿µ¿ª¿¡ »ý¼ºµÈ´Ù.
    - IDirect3DDevice9.UpdateSurface()¸¦ ÅëÇØ ÀÚ½ÅÀÇ surface³»¿ëÀ» ºñµð¿À ¸Þ¸ð¸®
       surface¿¡ ¿Ã¸± ¼ö ÀÖ´Ù.

    - IDirect3DDevice9.UpdateTexture()¸¦ ÅëÇØ ÀÚ½ÅÀ» 3DPOOL_DEFAULT·Î »ý¼ºµÈ
       texture¿¡ º¹»çÇÒ ¼ö ÀÖ´Ù.
 

ÀÌ·¸µí ¼­·Î ´Ù¸¥ ¼Ó¼ºÀ» °¡Áö±â ¶§¹®¿¡ °¡Àå ÀûÀýÇÑ pool typeÀ» ¼±ÅÃÇÏ´Â °ÍÀº ¹Ù·Î ´ç½ÅÀÇ ¸òÀÌ´Ù. (¿©±â¼­´Â ÆÄÀÏ¿¡¼­ µ¥ÀÌÅ͸¦ ºÒ·¯¿Í IDirect3DDevice9.LockRect()·Î ¹öÆÛÀÇ ¸Þ¸ð¸®¸¦ ¿­°í µ¥ÀÌÅ͸¦ °¡°øÇØ¾ß Çϱ⠶§¹®¿¡ D3DPOOL_MANAGEDÀ» ¼±ÅÃÇß´Ù. ¹°·Ð D3DPOOL_DEFAULTÀÎ texture¿¡¼­µµ °°Àº °á°ú¸¦ ³¾ ¼ö ÀÖ´Ù)



6. texture Àбâ

ÀÏ´Ü texture ¹öÆÛ¸¦ ¸¸µé¾úÁö¸¸ ±× ³»¿ëÀ» ä¿ö ³Ö´Â ÀÏÀÌ ¾ÆÁ÷ ³²¾Ò´Ù. Á÷Á¢ ƯÁ¤ÇÑ Æ÷¸ËÀ¸·Î ÀÎÄÚµùµÇ¾î ÀÖ´Â ½ºÆ®¸²(ÆÄÀÏ ½ºÆ®¸² Æ÷ÇÔ)À» µðÄÚµùÇϸ鼭 ¹öÆÛ¸¦ ä¿ï ¼öµµ ÀÖ°ÚÁö¸¸ ÀÌ °­Á¿¡¼­´Â ƯÁ¤ Æ÷¸Ë¿¡ Á¾¼ÓÀûÀÌÁö ¾Ê°Ô ¹öÆÛ¸¦ ä¿ì´Â ÂÊÀ¸·Î ÇÏ·Á ÇÑ´Ù.

¸ÕÀú À̹ÌÁö ¹öÆÛ¸¦ Á¤ÀÇÇϱâ À§ÇÑ °¡Àå ±âº»ÀûÀÎ ¼Ó¼ºÀ» º¸ÀÚ¸é, À̹ÌÁö ¹öÆÛÀÇ ½ÃÀÛ ÁÖ¼Ò, Çȼ¿ ´ÜÀ§ÀÇ °¡·Î ¼¼·Î Å©±â, ´ÙÀ½ ¶óÀαîÁö ½ºÅµÇϱâ À§ÇÑ ¹ÙÀÌÆ® ¼ö, ÇÑ Çȼ¿ÀÌ Â÷ÁöÇÏ´Â ºñÆ® ¼öµîÀ» ²ÅÀ» ¼ö ÀÖ°Ú´Ù. ÀÌ·± ¼Ó¼ºµéÀº DirectDraw surface¿Íµµ Å©°Ô ´Ù¸£Áö ¾ÊÀº ¼Ó¼ºÀ̹ǷΠº°´Ù¸¥ ¼³¸íÀº ÇÊ¿äÇÏÁö ¾ÊÀ» °Í °°´Ù. ±×·³, ¹æ±Ý ¼³¸íÇÑ À̹ÌÁöÀÇ ¼Ó¼ºÀ» °¡Áö°í texture¸¦ ä¿ì´Â ÇÔ¼ö¸¦ ¼Ò°³ÇÏ·Á ÇÑ´Ù. ÀÌ ÇÔ¼ö´Â ½¬¿î ¼³¸íÀ» À§ÇØ ÃÖÀûÈ­µÇÁö´Â ¾Ê¾ÒÀ¸¹Ç·Î ½ÇÁ¦ ÃÖÁ¾ »ùÇÿ¡¼­´Â ¾Æ·¡ÀÇ ³»¿ë°ú Á» ´Ù¸¦ ¼öµµ ÀÖ´Ù. ¾Æ·¡ÀÇ »ùÇÃÀº D3DFMT_X8R8G8B8 ¶Ç´Â D3DFMT_A8R8G8B8ÀÇ ÅؽºÃÄ¿¡ ´ëÇؼ­ 32-bit ¶Ç´Â 24-bit(BGRÀÇ ¼ø¼­)ÀÇ À̹ÌÁö ¹öÆÛÀÇ ³»¿ëÀ» º¹»çÇØ ³Ö´Â °ÍÀ¸·Î ÇÑÁ¤µÇ¾î ÀÖ´Ù.
 

function AssignImage
    (
        // ´ë»óÀÌ µÇ´Â texture
        hImage: IDirect3DTexture9;
        // source À̹ÌÁö°¡ ÀÖ´Â ¹öÆÛ
        pImage: pointer;

        // source À̹ÌÁöÀÇ Å©±â
        width, height: integer;

        // source À̹ÌÁö¿¡¼­ ÇÑ Çȼ¿ÀÌ Â÷ÁöÇÏ´Â ºñÆ®¼ö
        depth: integer;

        // source À̹ÌÁö¿¡¼­ ÇÑ ¶óÀÎÀ» ±¸¼ºÇϴ ¹ÙÀÌÆ® ¼ö
        pitch: integer;
        // Ä÷¯Å°¸¦ Àû¿ëÇÒ °ÍÀΰ¡?
        useColorKey: boolean = FALSE;

        // Ä÷¯Å°¸¦ Àû¿ëÇÒ ¶§ Ä÷¯Å°ÀÇ »ö»ó °ª
        colorKey: longword = 0
    ): boolean;

var
    pSour08: Pbyte;
    pSour32: Plongword;
    pDest32: Plongword;
    lockRect: TD3DLockedRect;
    i, j: integer;
    _R, _G, _B: longword;

begin
    result := FALSE;

    // ½ÇÁ¦·Î´Â ´õ ¸¹Àº ÆĶó¹ÌÅÍ °Ë»ç°¡ ÀÌ·ç¾îÁ®¾ß ÇÑ´Ù.
    // assert() »ç¿ë °¡´É

    if not assigned(hImage) then
        exit;

    // À̹ÌÁö¸¦ º¹»çÇÒ textureÀÇ ¹öÆÛ¸¦ ¿¬´Ù.

    if hImage.LockRect(0, lockRect, nil, 0) <> D3D_OK then
        exit;

    // Ä÷¯Å°¸¦ À§ÇØ Ä÷¯ ¼ººÐ¸¸ ºÐ¸®ÇÑ´Ù.

    colorKey := colorKey and $00FFFFFF;

    case depth of
    32:

        // 32 bits sourceÀÎ °æ¿ì

        for j := 0 to pred(height) do begin
            pSour32 := Plongword(longint(pImage) + j * pitch);
            pDest32 := Plongword(longint(lockRect.Bits)
                       + j * lockRect.Pitch);
            for i := 0 to pred(width) do begin

                // Ä÷¯Å°°¡ Àû¿ëµÇ´Â °æ¿ì¿¡´Â
                // alpha component¸¦ 0À¸·Î ¸¸µç´Ù.

                if useColorKey and ((pSour32^ and $00FFFFFF)
                   = colorKey) then
                    pDest32^ := pSour32^ and $00FFFFFF
                else
                    pDest32^ := pSour32^;
                inc(pSour32);
                inc(pDest32);
            end;
        end;
    24:

        // 24 bits sourceÀÎ °æ¿ì

        for j := 0 to pred(height) do begin
            pSour08 := Pbyte(longint(pImage) + j * pitch);
            pDest32 := Plongword(longint(lockRect.Bits)
                       + j * lockRect.Pitch);
            for i := 0 to pred(width) do begin

                // B, G, RÀÇ ¼ø¼­·Î ÀúÀåµÇ¾ú´Ù°í »ý°¢ÇÑ´Ù.
                // (24 bits BMP ±¸Á¶¿Í µ¿ÀÏ)

                _B := pSour08^; inc(pSour08);
                _G := pSour08^; inc(pSour08);
                _R := pSour08^; inc(pSour08);

                 // ¿øº»¿¡ alpha componentÀÇ Á¤º¸°¡ ¾ø¾úÀ¸¹Ç·Î
                // ¿©±â¼­ °æ¿ì¿¡ ¸Â°Ô ÷°¡ÇÑ´Ù.

                if useColorKey and (((_R shl 16) or (_G shl 8) or _B)
                   = colorKey) then
                    pDest32^ := $00000000 or
                                
(_R shl 16) or (_G shl 8) or _B
                else
                    pDest32^ := $FF000000 or
                                (_R shl 16) or (_G shl 8) or _B;

                 inc(pDest32);
            end;
        end;
    end;

    // À̹ÌÁöÀÇ º¹»ç°¡ ³¡³µÀ¸¹Ç·Î textureÀÇ ¹öÆÛ¸¦ ´Ý´Â´Ù.

    hImage.UnlockRect(0);

end;
 

ÇÑ °¡Áö Á» ´õ ¼³¸íÇÏÀÚ¸é, À§ÀÇ ÇÔ¼ö¸¦È£ÃâÇϸ鼭 useColorKey¸¦ TRUE·Î ÇÏ°í colorKey¿¡ ¿øÇÏ´Â Ä÷¯ °ªÀ» ³ÖÀ¸¸é ±× Ä÷¯´Â Ç×»ó alpha°¡ 0ÀÌ µÇ¾î¼­ ÀúÀåµÈ´Ù. µû¶ó¼­ ÇöÀç alpha°¡ 0À϶§´Â Ä÷¯Å°¸¦ Àû¿ëÇÏ°Ô ¼Ó¼ºÀ» º¯°æÇßÀ¸¹Ç·Î DirectDraw¿¡¼­ source color key¸¦ ¼³Á¤ÇÑ °Í°ú °°Àº È¿°ú¸¦ ³¾ ¼ö ÀÖ´Ù. (4-3ÀÇ ³»¿ëÀ» Âü°íÇÏÀÚ)



7. ºí·»µù ¿É¼Ç

ÀÌÀüÀÇ DirectDraw¿¡ ºñÇØ Direct3D¸¦ »ç¿ëÇϸ鼭 ¾ò´Â °¡Àå Å« À̵æÀº ¹Ù·Î ºí·»µùÀÇ ÆíÀǼºÀ» µé ¼ö ÀÖ°Ú´Ù. »ç½Ç DirectDraw¿¡¼­´Â Ä÷¯Å° Á¤µµ¸¸ »ç¿ëÇÒ ¼ö ÀÖÀ»»Ó, ÀÓÀÇÀÇ °¢µµ¿¡ ´ëÇÑ È¸Àü°ú ¾ËÆÄºí·»µùÀº ½ºÆå »óÀ¸·Î¸¸ ¸í½ÃµÇ¾î ÀÖ´Â ¼Ó¼ºÀ̾ú´Ù. ÇÏÁö¸¸ ÀÌÁ¦´Â À§´ëÇÑ H/W °¡¼Ó±âÀÇ ÈûÀ» ºô¾î 2D °ÔÀÓ¿¡¼­µµ °¡°øÇÒ¸¸ÇÑ ÇýÅÃÀ» ´©¸± ¼ö ÀÖ°Ô µÇ¾ú³ª´Ï ±× ¹æ¹ýÀ» ¼Ò°³ÇÏ·Á ÇÑ´Ù.

¿¹Á¦¿¡¼­ Á¤ÀÇÇÑ ºí·»µù ¸ðµå´Â 4°³ÀÌ´Ù. ½ÇÁ¦·Î ´õ ÇÊ¿äÇÑ °ÍÀÌ ¸¹Áö¸¸ ÀÌ¹Ì ÀÚ·áµµ ¸¹À»»Ó´õ·¯ Çϳª Çϳª Á÷Á¢ Å×½ºÆ® Çغ¸¸é ´õ ¸¹Àº È¿°ú¸¦ ãÀ» ¼ö ÀÖÀ» °ÍÀÌ´Ù.
 

TBlendingMode =
    (
        // ÀÏ¹Ý º¹»ç Ãâ·Â
        bmNormal,
        // Ä÷¯Å°Ã³·³ ÀϺθ¦ Åõ¸íÇÏ°Ô Ãâ·Â
        bmTransparent,
        // Çȼ¿º° ¾ËÆÄ ºí·»µù
        bmAlpha,
        // ±×¸²ÀÚ¿ë ºí·»µù
        bmShadow
    );
 

ÀÌ·± ½ÄÀ¸·Î ºí·»µù ¸ðµå¸¦ Á¤ÀÇÇÏ°í ³ª¼­ ´ÙÀ½°ú °°ÀÌ case¹®À» ÅëÇØ ºí·»µù ¹æ½ÄÀ» Àû¿ëÇÏ¸é µÈ´Ù.
 

case blendingMode of
    bmNormal:
    begin
        // ¸ðµÎ disable
        m_pD3DDevice.SetRenderState(D3DRS_ALPHABLENDENABLE, 0);
        m_pD3DDevice.SetRenderState(D3DRS_ALPHATESTENABLE, 0);
    end;
    bmTransparent:
    begin
        // alpha test¸¸ enable
        m_pD3DDevice.SetRenderState(D3DRS_ALPHABLENDENABLE, 0);
        m_pD3DDevice.SetRenderState(D3DRS_ALPHATESTENABLE, 1);
    end;
    bmAlpha:
    begin
        // alpha blending¸¸ enable
        m_pD3DDevice.SetRenderState(D3DRS_ALPHABLENDENABLE, 1);
        m_pD3DDevice.SetRenderState(D3DRS_ALPHATESTENABLE, 0);
        m_pD3DDevice.SetRenderState(D3DRS_SRCBLEND,
                                    D3DBLEND_SRCALPHA);
        m_pD3DDevice.SetRenderState(D3DRS_DESTBLEND,
                                    D3DBLEND_INVSRCALPHA);
    end;
    bmShadow:
    begin
        // alpha blending¸¸ enableÇϵÇ
        // ºí·»µù ¿É¼Ç¿¡ ¾à°£ÀÇ º¯È­¸¦ °¡ÇÑ´Ù.
        m_pD3DDevice.SetRenderState(D3DRS_ALPHABLENDENABLE, 1);
        m_pD3DDevice.SetRenderState(D3DRS_ALPHATESTENABLE, 0);
        m_pD3DDevice.SetRenderState(D3DRS_SRCBLEND,
                                    D3DBLEND_ZERO);
        m_pD3DDevice.SetRenderState(D3DRS_DESTBLEND,
                                    D3DBLEND_INVSRCALPHA);
    end;
end;
 

ºí·»µù ¸ðµå´Â ´ÜÁö °ÔÀÓ¿¡¼­ ÆíÇÏ°Ô »ç¿ëÇϱâ À§Çؼ­ À§ÀÇ 4°¡Áö¿Í °°Àº À̸§À» ºÙ¿´À»»Ó ½ÇÁ¦·Î´Â ¹«±Ã¹«ÁøÇÑ Á¶ÇÕÀÌ ÀÖÀ¸¸ç vertex color±îÁö ÀÌ¿ëÇÏ¸é ´õ¿í ´õ ´Ù¾çÇÑ È¿°ú¸¦ ¸¸µé ¼ö ÀÖ´Ù. À§ÀÇ ¿¹Á¦´Â ÀÌ¹Ì Á¤ÀǵǾî ÀÖ´Â rendering state¸¦ Åä±Û½ÃÄÑÁÖ´Â ¿ªÇÒ¸¸À» ÇÏ´Â °ÍÀε¥ Á» ´õ ´Ù¾çÇÑ Á¶ÇÕÀº DirectX SDK ¸Å´º¾óÀ» Âü°íÇϱ⠹ٶõ´Ù.



8. ±âº» primitive Ãâ·Â

Direct3D´Â ±×·¡ÇȽº ¶óÀ̺귯¸®ÀÇ °³³äÀÌ ¾Æ´Ï±â ¶§¹®¿¡ º¹ÇÕÀûÀÎ graphics primitive´Â Á¦°øÇÏÁö ¾Ê´Â´Ù. ½ÇÁúÀûÀ¸·Î ¸ðµç primitive´Â line drawing, rectangle filling, image drawingÀ¸·Î¸¸ ¸ðµÎ ±¸ÇöµÉ ¼ö Àֱ⠶§¹®¿¡ °¡Â¡ ±Ù°£ÀÌ µÇ´Â ¸î °³ÀÇ primitive¸¸ Á¦°øÇÑ´Ù. (±×Áß¿¡ °¡Àå Áß¿äÇÑ °ÍÀº ¿ª½Ã »ï°¢Çü ·»´õ¸µÀÌ´Ù)

Primitive¿¡ ºÐ·ùÇÏ±ä °³³äÀÌ Á» ´Ù¸£Áö¸¸ ÀÏ´Ü Á¦ÀÏ ¸ÕÀú º¼ °ÍÀº IDirect3DDevice9::Clear()´Ù.
 

m_pD3DDevice.Clear(1, nil, D3DCLEAR_TARGET, color, 1.0, 1);
 

ÀÌ°ÍÀº ¹é¹öÆÛ¸¦ ÁöÁ¤ÇÑ color·Î ¼Ò°ÅÇÏ´Â °ÍÀε¥ ¹éÆÛ¹ö»Ó¸¸ ¾Æ´Ï¶ó z-buffer µîµµ °°ÀÌ ÃʱâÈ­½Ãų ¼öÀÖ´Ù. ´Ù¸¸ ÀÌ °­Á¿¡¼­´Â z-buffer¸¦ »ç¿ëÇÏÁö ¾ÊÀ¸¹Ç·Î ·»´õ¸µ Ÿ°ÙÀ̵Ǵ surface¸¸ ¼Ò°ÅÇϵµ·Ï Çß´Ù. ¿©±â¼­ ÁÖ¸ñÇØ¾ß ÇÒ °ÍÀº ù ¹ø° ÆĶó¹ÌÅÍ¿Í µÎ ¹ø° ÆĶó¹ÌÅÍ´Ù. µÎ ¹ø° ÆĶó¹ÌÅÍ´Â ¼Ò°ÅÇÒ ¿µ¿ªÀÇ ¸®½ºÆ®¸¦ ¹è¿­·Î ³ªÅ¸³½ Æ÷ÀÎÅÍ°¡ µé¾î°¡°í ù ¹ø° ÆĶó¹ÌÅÍ¿¡´Â ±× ¹è¿­ÀÇ °³¼ö¸¦ ³ÖÀ¸¸é µÈ´Ù. À§ÀÇ ¿¹¿¡¼­´Â µÎ ¹ø° ÆĶó¹ÌÅÍ°¡ nil(Ưº°ÇÑ ¿µ¿ªÀ» ÁöÁ¤ÇÏÁö ¾Ê¾ÒÀ¸¹Ç·Î Àü¿µ¿ª)À̱⠶§¹®¿¡ ù¹ø ° ÆĶó¹ÌÅÍ´Â 0À̶õ °ªÀÌ µé¾î °¬´Ù. ±×·¸´Ù¸é FillRect()¶ó´Â ÇÔ¼ö¸¦ ¸¸µé¾î º¸ÀÚ. ±×°ÍÀº IDirect3DDevice9::Clear()¸¦ ÀÌ¿ëÇؼ­ °£´ÜÇÏ°Ô ¸¸µé ¼ö ÀÖ´Ù.
 

function FillRect(color: longword; x, y, w, h: integer): boolean;
var
    rect: TRect;
begin
    rect.Left   := x;
    rect.Top    := y;
    rect.Right  := x + w;
    rect.Bottom := y + h;

    // 1°³ÀÇ »ç°¢ ¿µ¿ªÀ» ¸í½ÃÇÑ »öÀ¸·Î ä¿ìµµ·Ï ÁöÁ¤ÇÑ´Ù.
    result := (m_pD3DDevice.Clear(1, @rect, D3DCLEAR_TARGET, color,
               1.0, 0) = D3D_OK);
end;
 

±× ´ÙÀ½Àº lineÀ» ±×¾îº¸ÀÚ. (°ú¿¬ ÀÌ°ÍÀÌ °ÔÀÓÀ» ¸¸µé ¶§ ÇÊ¿äÇÑ °ÍÀÌÁö´Â Àß ¸ð¸£°Ú´Ù.)
 

function DrawLine(color: longword; x1, y1: integer; x2, y2: integer)
         : boolean;
type
    // 3DÀÇ ÁÂÇ¥¿¡ ƯÁ¤ÇÑ »öÀ» ÁöÁ¤ÇϵÇ
    // transformationÀÇ ¿µÇâÀ» ¹ÞÁö ¾Êµµ·Ï ÇÑ´Ù.

    TSimpleVertex = packed record
        x, y, z, rhw: single;
        color: longword;
    end;
    PArraySimpleVertex = ^TArraySimpleVertex;
    TArraySimpleVertex = array[0..0] of TSimpleVertex;
var
    // ¾îÂ÷ÇÇ ½ºÅÃÀÌ´Ù.
    pVertex: array[0..99] of TSimpleVertex;
    hr: HRESULT;
begin
    // (x1, y1)¿¡ ÇØ´çÇÏ´Â Á¡À» pVertex[0]¿¡ Ç¥ÇöÇÑ´Ù.
    pVertex[0].x := x1 - 0.5;
    pVertex[0].y := y1 - 0.5;
    pVertex[0].z := 0.5;
    pVertex[0].rhw := 1.0;
    pVertex[0].color := color;
    // (x2, y2)¿¡ ÇØ´çÇÏ´Â Á¡À» pVertex[1]¿¡ Ç¥ÇöÇÑ´Ù.
    pVertex[1].x := x2 - 0.5;
    pVertex[1].y := y2 - 0.5;
    pVertex[1].z := 0.5;
    pVertex[1].rhw := 1.0;
    pVertex[1].color := color;

     // ÀÌ°ÍÀº ÅؽºÃĸ¦ Àû¿ëÇÏ´Â °ÍÀÌ ¾Æ´Ï´Ù. 
    m_pD3DDevice.SetTexture(0, nil);
    // TSimpleVertex¿¡¼­ Á¤ÀÇÇß´ø ³»¿ëÀ» °¡¼Ó±â¿¡°Ô ¾Ë·ÁÁØ´Ù. 
    m_pD3DDevice.SetFVF(D3DFVF_XYZRHW or D3DFVF_DIFFUSE);
    // pVertex¿¡´Â ¼±À» ±×¸®±â À§ÇÑ Á¤º¸°¡ ÀÖÀ¸¸ç ±×¸®·Á´Â ¼±Àº 1°³
    hr := m_pD3DDevice.DrawPrimitiveUP(D3DPT_LINELIST, 1, @pVertex,
                                       sizeof(TSimpleVertex));

     result := (hr = D3D_OK);
end;
 

TSimpleVertex¶ó´Â ŸÀÔÀ» Á¤ÀÇÇߴµ¥, ÀÌ lineÀÇ ¸ñÀûÀº 2D»óÀÇ Æò¸é¿¡ ±×·Á¾ß ÇÏ°í, ÅؽºÃÄ¿Í´Â °ü°è°¡ ¾øÀ¸¹Ç·Î À§¿Í °°ÀÌ Á¤ÀǵǾú´Ù. ´«¿©°Ü ºÁ¾ß ÇÒ °ÍÀº SetTexture()¿¡¼­ nilÀ» ³ÖÀº °Í°ú DrawPrimitiveUP( D3DPT_LINELIST, 1, ....)ÀÇ ºÎºÐÀÌ´Ù. D3DPT_LINELISTÀÇ ³»¿ëÀº DirectX9 SDK¸¦ Âü°íÇϱ⠹ٶõ´Ù.

±×·¸´Ù¸é ÀÌ°ÍÀ» Á¶±Ý ´õ ÀÀ¿ëÇÑ Æú¸®°ï ±×¸®±â¸¦ º¸±â·Î ÇÏÀÚ.
 

function DrawPolygon(color: longword; points: array of TFPoint;
                     n: integer): boolean;
type
    // ¹Ý°©´Ù. ¹Ù·Î À§¿Í °°´Ù.
    TSimpleVertex = packed record
        x, y, z, rhw: single;
        color: longword;
    end;
    PArraySimpleVertex = ^TArraySimpleVertex;
    TArraySimpleVertex = array[0..0] of TSimpleVertex;
var
    i: integer;
    // pointsÀÇ °³¼ö°¡ 100°³°¡ ³ÑÀ¸¸é ³¶ÆдÙ.
    pVertex: array[0..99] of TSimpleVertex;
    hr: HRESULT;
begin
    // ³¶Æи¦ ¾È´çÇϵµ·Ï assert()¸¦ ½áº¸µçÁö
    // µ¿Àû ÇÒ´çÀ» ÇϵçÁö ¸¾´ë·Î...

    for i := 0 to pred(n) do begin
        pVertex[i].x := points[i].x;
        pVertex[i].y := points[i].y;
        pVertex[i].z := 0.5;
        pVertex[i].rhw := 1.0;
        pVertex[i].color := color;
    end;

     // À§¿Í °°´Ù. 
    m_pD3DDevice.SetTexture(0, nil);
    m_pD3DDevice.SetFVF(D3DFVF_XYZRHW or D3DFVF_DIFFUSE);
    // D3DPT_TRIANGLEFANÀº »óȲ¿¡ µû¶ó¼­ À§ÇèÇÏ´Ù.
    // ConcaveÀÎ Æú¸®°ï¿¡¼­´Â ³¶ÆÐ
    hr := m_pD3DDevice.DrawPrimitiveUP(D3DPT_TRIANGLEFAN, n-2,
                            @pVertex, sizeof(TSimpleVertex));

     result := (hr = D3D_OK);
end;
 

À­ÂÊÀÇ DrawLine()°ú Å©°Ô ´Ù¸¥ Á¡Àº ¾ø´Ù. ´ÜÁö Æú¸®°ïÀ» »ï°¢ÇüÀ¸·Î ÂÉ°³¾î¼­ D3DPT_TRIANGLEFANÀÇ Çü½ÄÀ¸·Î Ãâ·ÂÀ» ÇÑ´Ù. ÇöÀç culling mode¸¦ D3DCULL_NONE·Î ¼³Á¤ÇßÀ¸¹Ç·Î Æú¸®°ïÀÌ °¨±â´Â ¹æÇâ°ú´Â °ü°è¾øÀÌ Ãâ·ÂµÉ °ÍÀÌ´Ù. (´Ü, À§ÀÇ ¿¹Á¦´Â convexÀÎ Æú¸®°ï¿¡¼­¸¸ Àû¿ëµÈ´Ù. ConcaveÀÇ °æ¿ì¿¡´Â D3DPT_TRIANGLELIST ¶Ç´Â D3DPT_TRIANGLESTRIP¸¦ »ç¿ëÇÏ´Â ¹æ¹ýÀ¸·Î ±¸ÇöÇØ¾ß ÇÑ´Ù. ÇÏÁö¸¸ ÀÌ °­Á¿ʹ °ü°è°¡ ¾øÀ¸¹Ç·Î »ý·«)



9. À̹ÌÁö Ãâ·Â

2DÀÇ °³³äÀ» ºô¾î 'À̹ÌÁö'Ãâ·ÂÀ̶ó°í ÇÏ¿´Áö¸¸ ½ÇÁ¦´Â texture Ãâ·ÂÀÌ´Ù. ÇÏÁö¸¸ 2D °ÔÀÓÀ» ¸¸µå´Â ÀÔÀå¿¡¼­´Â ÃÖ´ëÇÑ 3DÀÇ Á¸À縦 ¼û±â´Â °ÍÀÌ ÁÁÀ¸¹Ç·Î ´ÙÀ½°ú °°Àº ÆĶó¹ÌÅÍÀÇ À̹ÌÁö Ãâ·Â ÇÔ¼ö¸¦ ¸¸µé°íÀÚ ÇÑ´Ù.
 

DrawImage
    (
        // destinationÀÇ left-top ÁÂÇ¥
        xDest, yDest: integer;
        // À̹ÌÁö ÇÚµé
        hImage: integer;
        // À̹ÌÁö »ó¿¡¼­ º¹»ç¸¦ ½ÃÀÛÇÒ left-top ÁÂÇ¥
        xSour, ySour: integer;
        // º¹»çµÉ ¿µ¿ª¿¡ ´ëÇÑ width¿Í height
        wSour, hSour: integer
    ):
 

¹º°¡ Àͼ÷ÇÏÁö ¾ÊÀº°¡? ±×·¸´Ù ¹Ù·Î ÀÌ°ÍÀº Win32 APIÀÇ BitBit()°ú °ÅÀÇ À¯»çÇÑ Çü½ÄÀÇ ÆĶó¹ÌÅÍ´Ù. ¾ÆÁ÷ Åõ¸íµµ Á¶Á¤, »ö»ó ¹à±â Á¶Á¤, ȸÀü/È®´ë/Ãà¼Ò ÁöÁ¤ÀÌ µé¾î°¡Áö ¾ÊÀº »óÅ¿¡¼­´Â ¾Æ¸¶ ÀÌ Á¤µµÀÇ ÆĶó¹ÌÅͶó¸é ÀÏ¹Ý Å¸ÀÏ Ãâ·Â ¹× ½ºÇÁ¶óÀÌÆ® Ãâ·Â¿¡ ¸ðµÎ »ç¿ëÇÒ ¼ö ÀÖÀ» °ÍÀ̶ó »ý°¢ÇÑ´Ù.

±×·³ ¸ÕÀú À̹ÌÁö Çڵ鿡 ´ëÇÑ °ÍºÎÅÍ ÇÏÀÚ. ³»°¡ Á¦¾ÈÇÏ´Â °ÍÀº ´ÙÀ½°ú °°´Ù.
 

PTextureInfo = ^TTextureInfo;
TTextureInfo = record
    // À̹ÌÁöÀÇ width
    wSize: longint;
    // À̹ÌÁöÀÇ height
    hSize: longint;
    // textureÀÇ ½ÇÁ¦ width
    wTexture: longint;
    // textureÀÇ ½ÇÁ¦ height
    hTexture: longint;
    // textureÀÇ Æ÷¸Ë
    pixelFormat: TD3DFORMAT;
    // À̹ÌÁö¸¦ ´ëÇ¥ÇÏ´Â texture ÀνºÅϽº
    pTexture: IDirect3DTexture9;
end;
 

ÀÌ·¸°Ô Á¤ÀÇµÈ TTextureInfoÀÇ Æ÷ÀÎÅÍ ÇüÅÂ, Áï PTextureInfo¸¦ integer·Î castingÇÑ °ÍÀ» ÇÚµé·Î ¾²·Á°í ÇÑ´Ù. À̹ÌÁö ¸Å´ÏÁ®°¡ ÇÚµéÀÇ ¹øÈ£¸¦ ¼±ÇüÀûÀ¸·Î ±¸ÇöÇϸ鼭 °¢°¢ÀÇ ÂüÁ¶ Æ÷ÀÎÅ͸¦ °¡Áö°í ÀÖ´Ù¸é ´õ ÁÁ°ÚÁö¸¸ ÀÌ °­Á¿¡¼­´Â ÀÌ·¸°Ô ½áµµ ¹«¸®°¡ ¾øÀ¸¹Ç·Î ±×³É Æ÷ÀÎÅÍ ÀÚü¸¦ ÇÚµé·Î »ç¿ëÇÑ´Ù. (´Ü, »ç¿ëÀÚ¿¡°Ô´Â TTextureInfo ÇüÀÇ Æ÷ÀÎÅͶó´Â °ÍÀ» ¾Ë¸± ÇÊ¿ä°¡ ¾ø´Ù)
 

type
    // texture Ãâ·ÂÀ» À§ÇÑ vertex ±¸Á¶Ã¼
    PVertex = ^TVertex;
    TVertex =
packed record
        x, y, z, rhw : single;
        tu, tv       : single;
    end;

function
TD3DDevice.DrawImage(xDest, yDest: integer;
                              hImage: integer;
                              xSour, ySour, wSour, hSour: integer)
         : boolean;
const
    // »ç°¢ÇüÀÇ À̹ÌÁö¸¦ ¸¸µé±â À§Çؼ­´Â »ï°¢Çü µÎ °³°¡ ÇÊ¿äÇϸç
    // ±× »ï°¢ÇüÀº 2°³ÀÇ ²ÀÁöÁ¡À» °øÀ¯ÇϹǷΠÇÊ¿äÇÑ vertex ¼ö´Â
    // (3 * 2) - 2 = 4

    MAX_VERTEX = 4;
var
    pTexInfo: PTextureInfo;
    x, y, w, h, tu, tv, tw, th: single;
    vertices: array[0..pred(MAX_VERTEX)] of TVertex;
begin
    result := FALSE;

    // ¸ðµç ÆĶó¹ÌÅ͸¦ ´Ù üũÇÒ ÇÊ¿ä´Â ¾ø´Ù.

    // ¸¸¾à wSour°¡ À½¼ö¶ó°Å³ª textureÀÇ Å©±âº¸´Ù Å©¸é Àç¹ÌÀÖ´Â
    // ¹ÝÀÀÀ» ³ªÅ¸³½´Ù.

    if hImage = 0 then
        exit;

    pTexInfo := PTextureInfo(hImage);
 

    // wSour¿Í hSour¸¦ 0À¸·Î ÁÖ¸é ¾Ë¾Æ¼­ Àü ¿µ¿ªÀ¸·Î ¹Ù²Ù¾î ÁØ´Ù.

    if wSour = 0 then
        wSour := pTexInfo.wSize;
    if hSour = 0 then
        hSour := pTexInfo.hSize;
 

    // 2D ÁÂÇ¥¸¦ 3DÀÇ ½Ç¼ö ÁÂÇ¥¿¡ ¸ÅÇÎÇϱâ À§Çؼ­ -0.5¸¦ ÇØÁØ´Ù.

    x := xDest - 0.5;
    y := yDest - 0.5;
    w  := wSour;
    h  := hSour;
    tu := xSour / pTexInfo.wTexture;
    tv := ySour / pTexInfo.hTexture;
    tw := wSour / pTexInfo.wTexture;
    th := hSour / pTexInfo.hTexture;
 

    // À̹ÌÁöÀÇ Áß½ÉÁ¡À» ±âÁØÀ¸·Î Ãâ·ÂÀ» ÇÒ °æ¿ì´Ù.

    if m_imageOrigin = ioCenter then begin
        x := x - w / 2;
        y := y - h / 2;
    end;
 

    // Á»ó´ÜÀÇ ²ÀÁöÁ¡À» ÁöÁ¤ÇÑ´Ù.

    vertices[0].x := x;
    vertices[0].y := y;
    vertices[0].z := 1.0;
    vertices[0].rhw := 1.0;
    vertices[0].tu := tu;
    vertices[0].tv := tv;
 

    // ¿ì»ó´ÜÀÇ ²ÀÁöÁ¡À» ÁöÁ¤ÇÑ´Ù.

    vertices[1].x := x + w;
    vertices[1].y := y;
    vertices[1].z := 1.0;
    vertices[1].rhw := 1.0;
    vertices[1].tu := tu + tw;
    vertices[1].tv := tv;
 

    // ¿ìÇÏ´ÜÀÇ ²ÀÁöÁ¡À» ÁöÁ¤ÇÑ´Ù.

    vertices[2].x := x + w;
    vertices[2].y := y + h;
    vertices[2].z := 1.0;
    vertices[2].rhw := 1.0;
    vertices[2].tu := tu + tw;
    vertices[2].tv := tv + th;
 

    // ÁÂÇÏ´ÜÀÇ ²ÀÁöÁ¡À» ÁöÁ¤ÇÑ´Ù.

    vertices[3].x := x;
    vertices[3].y := y + h;
    vertices[3].z := 1.0;
    vertices[3].rhw := 1.0;
    vertices[3].tu := tu;
    vertices[3].tv := tv + th;
 

    // À̹ø Ãâ·Â¿¡ Àû¿ëµÉ texture¸¦ ÁöÁ¤ÇÑ´Ù.

    m_pD3DDevice.SetTexture(0, pTexInfo.pTexture);

    // ÆĶó¹ÌÅÍ°¡ Á» ´Ù¸£´Ù. texture¸¦ Ãâ·ÂÇϱ⠶§¹®ÀÌ´Ù.

    m_pD3DDevice.SetFVF(D3DFVF_XYZRHW or D3DFVF_TEX1);

    // Triangle fan Çü½ÄÀ¸·Î Ãâ·ÂÇÑ´Ù.

    m_pD3DDevice.DrawPrimitiveUP(D3DPT_TRIANGLEFAN, MAX_VERTEX-2,
                                 @vertices, sizeof(TVertex));
 

    result := TRUE;
end;
 

À§¿¡¼­ triangle fan Çü½ÄÀÌ ¾Æ´Ï¶ó triangle strip Çü½ÄÀ¸·Î Ãâ·ÂÇÏ·Á Çß´Ù¸é vertices[2]¿Í vertices[3]ÀÇ ³»¿ëÀº ¼­·Î ¹Ù²î¾î¾ß ÇÑ´Ù. (±× ÀÌÀ¯´Â DirectX SDK ¸Å´º¾óÀ» µÚÁ®º¸ÀÚ)

¾Æ¸¶µµ À§ÀÇ ÇÔ¼ö¸¸ ÀÖÀ¸¸é ±âÁ¸¿¡ Ç¥ÇöÇß´ø 2D °ÔÀÓÀÇ feature¸¦ ´ëºÎºÐ ¸¸Á·ÇÏÁö ¾ÊÀ»±î ½Í±äÇÏÁö¸¸ ¿ì¸®°¡ 3D¸¦ ÀÌ¿ëÇϸ鼭 ¾òÀº ÀÌÁ¡ Áß¿¡´Â vertex color¸¦ »ç¿ëÇÒ ¼ö ÀÖ´Ù´Â °Í°ú À̹ÌÁöÀÇ È¸Àü ¶Ç´Â ½ºÄÉÀϸµÀÌ ÀÚÀ¯·Ó´Ù´Â °ÍÀÌ ÀÖ´Ù. ±×·¡¼­ ÀÌ ÇÔ¼ö¿Í´Â º°µµ·Î È®Àå ÇÔ¼ö¸¦ Çϳª ´õ ¸¸µé¾ú´Ù.
 

DrawImageEx
    (
        xDest, yDest: integer;
        hImage: integer;
        xSour, ySour: integer;
        wSour, hSour: integer;
        // alpha °ª, 0À϶§ ¿ÏÀü Åõ¸íÀÌ°í 255À϶§ ¿ÏÀü ºÒÅõ¸í
        opacity: integer = 255;
        // À̹ÌÁöÀÇ ¹à±â, <R = R * lighten / 255>ÀÇ °ø½ÄÀÌ Àû¿ë
        lighten: integer = 255;
        // ȸÀü °¢µµ, radianÀÌ ¾Æ´Ï´Ù. degree ´ÜÀ§·Î ÁöÁ¤ÇØ¾ß ÇÔ
        angle: integer = 0;
        // ȸÀü °¢µµ, radianÀÌ ¾Æ´Ï´Ù. degree ´ÜÀ§·Î ÁöÁ¤ÇØ¾ß ÇÔ
        scale: integer = 100
    );
 

DrawImage()¿¡ ºñÇØ ¸¹Àº ÆĶó¹ÌÅÍ°¡ ´Ã¾úÁö¸¸ ½ÇÁ¦ ±¸ÇöµÉ ÄÚµå´Â ±×¸® ¸¹Áö ¾Ê´Ù. ±¸Çö ÀÚüµµ ±×¸® ¾î·ÆÁö ¾Ê¾Æ¼­, °íµîÇб³ ¼öÇп¡¼­ »ï°¢ÇÔ¼ö ½Ã°£¿¡ Á¹Áö¸¸ ¾Ê¾Ò´Ù¸é ½±°Ô ÀÌÇØµÉ ºÎºÐµéÀÌ´Ù. (ȸÀüµÉ ±âÁØÀÌ À̹ÌÁöÀÇ left-topÀÎÁö centerÀÎÁö¿¡ µû¶ó¼­ ±¸ÇöÀÌ Á¶±Ý ´Þ¶óÁö´Âµ¥ À̰͸¸ Á» À¯½ÉÈ÷ º¸¸é µÈ´Ù)
 

type
    // texture Ãâ·ÂÀ» À§ÇÑ vertex ±¸Á¶Ã¼. vertex color°¡ Ãß°¡µÇ¾ú´Ù.
    PVertexTL = ^TVertexTL;
    TVertexTL =
packed record
        x, y, z, rhw : single;
        color        : longword;
        tu, tv       : single;
    end;

function
TD3DDevice.DrawImageEx
    (
        xDest, yDest: integer;
        hImage: integer;
        xSour, ySour: integer;
        wSour, hSour: integer;
        opacity: integer = 255;
        lighten: integer = 255;
        angle: integer = 0;
        scale: integer = 100
    ): boolean;
const
    MAX_VERTEX = 4;
    // ½Å°æ ¾²Áö ¸»ÀÚ. ÇÊ¿ä¾øÀ¸¸é ±×³É Áö¿ìÀÚ.
    OBLIQUE: single = 1.0;
var
    pTexInfo: PTextureInfo;
    x, y, w, h, tu, tv, tw, th: single;
    vertices: array[0..pred(MAX_VERTEX)] of TVertexTL;

    angle2: integer;
    radius: single;
begin
    result := FALSE;
 

    if hImage = 0 then
        exit;
 

    pTexInfo := PTextureInfo(hImage); 

    if wSour = 0 then
        wSour := pTexInfo.wSize;
    if hSour = 0 then
        hSour := pTexInfo.hSize;
 

    x  := xDest - 0.5;
    y  := yDest - 0.5;
    w  := wSour;
    h  := hSour;
    tu := xSour / pTexInfo.wTexture;
    tv := ySour / pTexInfo.hTexture;
    tw := wSour / pTexInfo.wTexture;
    th := hSour / pTexInfo.hTexture;
 

    // opacity¿Í lightenÀ¸·Î vertex color¸¦ ¸¸µç´Ù.
    opacity := (opacity shl 24) or
               
(lighten shl 16) or (lighten shl 8) or (lighten);
 

    // À̹ÌÁöÀÇ Áß½ÉÀ» ±âÁØÀ¸·Î ÇÒ ¶§´Â ȸÀü¿¡ »ç¿ëµÇ´Â °ø½ÄÀÌ
    // ´Ù¸£´Ù.

    case m_imageOrigin of
    ioLeftTop:
        if angle = 0 then begin
            // ¸¹ÀÌ º¸´ø °Å´Ù.
            w := w * scale / 100;
            h := h * scale / 100;
            vertices[0].x := x;
            vertices[0].y := y;
            vertices[1].x := x + w;
            vertices[1].y := y;
            vertices[2].x := x + w;
            vertices[2].y := y + h;
            vertices[3].x := x;
            vertices[3].y := y + h;
        end
        else begin
            // µåµð¾î °íµîÇб³ ¼öÁØÀÇ ¼öÇÐÀÌ ³ª¿Ô´Ù.
            w := w * scale / 100;
            h := h * scale / 100;
            radius := round(SmSqrt(w * w + h * h));
            angle2 := round(SmAtan(-h, w)*ONE_RADIAN);
 

            vertices[0].x := x;
            vertices[0].y := y;
            vertices[1].x := x + w * SmCos(angle);
            vertices[1].y := y - w * SmSin(angle) * OBLIQUE;
            vertices[2].x := x + radius * SmCos(angle+angle2);
            vertices[2].y := y - radius * SmSin(angle+angle2)
                                          * OBLIQUE;
            vertices[3].x := x + h * SmCos(angle-90);
            vertices[3].y := y - h * SmSin(angle-90) * OBLIQUE;
        end;
    ioCenter:
        if angle = 0 then begin
            // ¹¹, ¾Æ±î¶û ºñ½ÁÇÏ´Ù.
            w := w * scale / 100;
            h := h * scale / 100;
            x := x - w / 2;
            y := y - h / 2;
            vertices[0].x := x;
            vertices[0].y := y;
            vertices[1].x := x + w;
            vertices[1].y := y;
            vertices[2].x := x + w;
            vertices[2].y := y + h;
            vertices[3].x := x;
            vertices[3].y := y + h;
        end
        else begin
            // ´Ù½Ã °íµîÇб³ ¼öÁØÀÇ ¼öÇÐÀÌ ³ª¿Ô´Ù. (¶óÁö¸¸....)
            w := w / 2;
            h := h / 2;
            radius := round(SmSqrt(w * w + h * h)) * scale / 100;
 

            angle2 := round(SmAtan(h, -w)*ONE_RADIAN);
            vertices[0].x := x + SmCos(angle + angle2) * radius;
            vertices[0].y := y - SmSin(angle + angle2) * radius
                                                       * OBLIQUE;
            angle2 := round(SmAtan(h, w)*ONE_RADIAN);
            vertices[1].x := x + SmCos(angle + angle2) * radius;
            vertices[1].y := y - SmSin(angle + angle2) * radius
                                                       * OBLIQUE;
            angle2 := round(SmAtan(-h, w)*ONE_RADIAN);
            vertices[2].x := x + SmCos(angle + angle2) * radius;
            vertices[2].y := y - SmSin(angle + angle2) * radius
                                                       * OBLIQUE;
            angle2 := round(SmAtan(-h, -w)*ONE_RADIAN);
            vertices[3].x := x + SmCos(angle + angle2) * radius;
            vertices[3].y := y - SmSin(angle + angle2) * radius                                                        * OBLIQUE;
        end;
    end;
 

    // vertexÀÇ ³ª¸ÓÁö ºÎºÐÀ» ä¿î´Ù.
    vertices[0].z := 0.0;
    vertices[0].rhw := 1.0;
    vertices[0].color := opacity;
    vertices[0].tu := tu;
    vertices[0].tv := tv;
 

    vertices[1].z := 0.0;
    vertices[1].rhw := 1.0;
    vertices[1].color := opacity;
    vertices[1].tu := tu + tw;
    vertices[1].tv := tv;
 

    vertices[2].z := 0.0;
    vertices[2].rhw := 1.0;
    vertices[2].color := opacity;
    vertices[2].tu := tu + tw;
    vertices[2].tv := tv + th;
 

    vertices[3].z := 0.0;
    vertices[3].rhw := 1.0;
    vertices[3].color := opacity;
    vertices[3].tu := tu;
    vertices[3].tv := tv + th;
 

    m_pD3DDevice.SetTexture(0, pTexInfo.pTexture);
    m_pD3DDevice.SetFVF(D3DFVF_XYZRHW or D3DFVF_DIFFUSE
                        or D3DFVF_TEX1);
    m_pD3DDevice.DrawPrimitiveUP(D3DPT_TRIANGLEFAN, MAX_VERTEX-2,
                                 @vertices, sizeof(TVertexTL));
 

    result := TRUE;
end;
 

À§ÀÇ ³»¿ëÀ» ¼³¸íÇϱâ Àü¿¡ óÀ½ ³ª¿À´Â ¼öÇÐ °ü·Ã ÇÔ¼ö°¡ Àִµ¥ ±× Á¤ÀÇ´Â ¾Æ·¡¿Í °°´Ù. º°·Î ƯÀÌÇÑ °ÍÀº ¾Æ´Ï°í radian ´ÜÀ§ÀÇ ÇÔ¼ö¸¦ degree ´ÜÀ§·Î ¾µ ¼ö ÀÖµµ·Ï ÇÑ °ÍÀε¥, ÀÌ·¸°Ô »ç¿ëÇÑ °¡Àå Å« ÀÌÀ¯´Â ³ªÁß¿¡ ÀÌ ÇÔ¼öµé¸¸ µû·Î ÃÖÀûÈ­ ÇÒ ¼ö Àֱ⠶§¹®ÀÌ´Ù. ¿¹¸¦ µé¾î ÇϳªÀÇ sine Å×À̺íÀ» ÀÌ¿ëÇؼ­ °í¼ÓÀ¸·Î sine, cosine, tagent¸¦ ±¸ÇÒ ¼ö Àֱ⵵ ÇÏ°í, Á¤¼öÇüÀ¸·Î Àü°³Çؼ­ °í¼ÓÀ¸·Î square root¸¦ ±¸ÇÒ ¼ö Àֱ⠶§¹®ÀÌ´Ù. (½ÇÁ¦·Î ¿ø·¡ÀÇ ¼Ò½º´Â ÃÖÀûÈ­ µÇ¾î ÀÖÀ¸³ª ÀúÀÛ±Ç ¹®Á¦ ¶§¹®¿¡ ÀÌ °­Á¿¡¼­´Â ¾Æ·¡ÀÇ ÇÔ¼ö·Î ´ëü½ÃÄÑ ³õ¾Ò´Ù)
 
const
    ONE_RADIAN = 180 / 3.14159265358979323846;


function SmSin(degree : integer) : single;
begin
    SmSin := Sin(degree * ONE_RADIAN / 180.0);
end;
 

function SmCos(degree : integer) : single;
begin
    SmCos := Cos(degree * ONE_RADIAN / 180.0);
end;
 

function SmAtan(y, x: extended): extended;
begin
    SmAtan := ArcTan2(y, x);
end;
 

function SmSqrt(Value : single) : single;
begin
    SmSqrt := Sqrt(Value);
end;

 


10. È­¸é¿¡ Ãâ·Â Çϱâ

»ç½Ç ¿©Å±îÁö È­¸é¿¡ Á÷Á¢ Ãâ·ÂÀÌ ÀϾ´Â °ÍÀº Çϳªµµ ¾ø¾ú±â ¶§¹®¿¡ Áö·çÇßÀ»Áöµµ ¸ð¸£°Ú´Ù. ÇÏÁö¸¸ À̹ø¿¡´Â Á¤¸»·Î È­¸é¿¡ Ãâ·ÂÀÌ ÀϾ´Â ºÎºÐÀ» ´Ù·é´Ù. ÀÏ´Ü ¸ð½ÀÀº 2D °ÔÀÓÀ̶ó°í ÇÏ´õ¶óµµ ±× ½Çü´Â Direct3DÀ̱⠶§¹®¿¡ ¾Æ¸¶µµ ´ÙÀ½°ú °°Àº ¸ÞÀÎ ·çÇÁ¸¦ µ¹ °ÍÀ̶ó´Â ¿¹»óÀ» Çغ»´Ù.
 

procedure MainLoop();
begin
    // ¸ðµç °´Ã¼ÀÇ ÇൿÀ» ó¸®
    ProcessSomething();

    // ±×¸²À» ±×¸± ¼ö ÀÖ´Ù¸é
    if (g_d3D.BeginScene()) then begin
        
// ¸ðµç °´Ã¼µéÀ» È­¸é¿¡ Ãâ·Â
        ProcessDisplaying();
        // Ãâ·ÂÀÌ ³¡³µÀ½
        g_d3D.EndScene();
        // Ãâ·Â °á°ú¹°À» È­¸éÀ¸·Î º¸³¿
        g_d3DFlush();
    end;
end;
 

Á¶±Ý IDirect3DDevice9¸¦ ¾Æ½Ã´Â ºÐÀ̶ó¸é ±× °´Ã¼¿¡µµ °°Àº ±â´ÉÀ» ÇÏ´Â °ÍÀÌ ÀÖ´Ù´Â °ÍÀ» ¾Ë °ÍÀÌ´Ù. ÇÏÁö¸¸ ¿©±â¼­ ´Ù½Ã ±×°ÍÀ» ÇÑ ¹ø ´õ ·¡ÇÎÇÑ °ÍÀº  ±× ¾È¿¡¼­ »ç¿ëÀÚ°¡ ÇØÁÖ¾î¾ß ÇÒ ±âº» ÀûÀΠ󸮸¦ ºÎ°¡ÀûÀ¸·Î ´õ ÇØÁÖ±â À§ÇÑ °ÍÀÌ´Ù.

- g_d3D.BeginScene()

IDirect3DDevice9.BeginScene()À» ºÎ¸£´Â °ÍÀÌ °¡Àå Å« ¿ªÇÒÀÌ´Ù. ÇÏÁö¸¸ ±×°ÍÀÌ ¼±ÇàµÇ±â ÀÌÀü¿¡ ÀÌ¹Ì ÀÌ°ÍÀÌ ºÒ·È´ÂÁö¸¦ È®ÀÎÇØ¾ß ÇÏ°í ÇöÀç µ¿±âÈ­¿¡ ÀÇÇØ È­¸é Ãâ·ÂÀ» ½ºÅµÇØ¾ß ÇÏ´ÂÁö ÆǺ°ÇÏ´Â ºÎºÐµµ µé¾î°¡¾ß ÇÑ´Ù.

- g_d3D.EndScene()

IDirect3DDevice9.EndScene()À» ºÎ¸£´Â °ÍÀÌ °¡Àå Å« ¿ªÇÒÀÌ´Ù. ±×¸®°í BeginScene()ÀÌ ºÒ¸®±â Àü¿¡ ÀÌ°ÍÀÌ È£ÃâµÇ¾ú´ÂÁöµµ È®ÀÎÇØ¾ß Çϸç È­¸é Ãâ·ÂÀÌ ³¡³­ ½ÃÁ¡¿¡¼­ »ç¿ëÀÚ¿¡°Ô Ç¥½ÃÇϱâ À§ÇÑ µð¹ö±ë Á¤º¸(¿¹¸¦ µé¸é, Flip Per Second)¸¦ Ãâ·ÂÇϴµ¥µµ ÀÌ¿ëµÈ´Ù.

- g_d3DFlush()

IDirect3DDevice9.Present()À» ºÎ¸£´Â °ÍÀÌ °¡Àå Å« ¿ªÇÒÀÌ´Ù. ±×¸®°í D3DERR_DEVICELOST ¶Ç´Â D3DERR_DEVICENOTRESET »óÅ¿¡ ´ëÇÑ º¹±¸¸¦ ÇÏ´Â ¿ªÇÒÀ» ÇÑ´Ù.

À§¿¡¼­´Â ÀÌ·¯ Àú·¯ÇÑ °ÍÀ» Ãß°¡ÇØ¾ß ÇÑ´Ù°í ¸»ÇßÁö¸¸ ÇöÀç ¿¹Á¦¿¡¼­´Â ±×°ÍÀ» ±¸ÇöÇÏ°í ÀÖÁö´Â ¾Ê´Ù.
 

function TD3DDevice.BeginScene(): boolean;
begin
    // IDirect3DDevice9.BeginScene()ÀÌ µÎ ¹ø ºÒ¸®Áö ¾Êµµ·Ï ó¸®,
    // assert»ç¿ë
    // µ¿±âÈ­ ¶§¹®¿¡ Ãâ·ÂÇÏÁö ¸»¾ÆÇØ ÇÑ´Ù¸é FALSE¸¦ ¸®ÅÏ
    // 2D °ÔÀÓÀº view port°¡ ÇϳªÀÏ °æ¿ì°¡ ¸¹À¸¹Ç·Î
    // IDirect3DDevice9.Clear()¸¦ ¿©±â¿¡ ³Ö¾îµµ ¹«¹æ
    result := (m_pD3DDevice.BeginScene() = D3D_OK);
end;
 

function TD3DDevice.EndScene(): boolean;
begin
    // IDirect3DDevice9.BeginScene()°ú ½ÖÀÌ µÇ°í ÀÖ´ÂÁö È®ÀÎ,
    // assert»ç¿ë
    result := (m_pD3DDevice.EndScene() = D3D_OK);
    // ¸®ÅÏÇϱâ Àü¿¡ µð¹ö±ë °ü·Ã Á¤º¸¸¦ Back buffer¿¡ ±â·ÏÇÒ
    // ¼öµµ ÀÖ´Ù.
end;

function TD3DDevice.Flush(): boolean;
var
    hr: HRESULT;
begin
    // ±×µ¿¾È ±×·È´ø °ÍÀ» ½ÇÁ¦ È­¸é¿¡ ¹Ý¿µÇÑ´Ù.
    // 3¹ø° ÀÎÀÚ´Â 0À¸·Î Çصµ µÈ´Ù.
    hr := m_pD3DDevice.Present(nil, nil, m_hWindow, nil);

    if FAILED(hr) then begin
        case hr of

            // µð¹ÙÀ̽º¸¦ ¼Ò½ÇÇß°í, º¹±¸°¡ ºÒ°¡´É »óÅÂ
            D3DERR_DEVICELOST:
            begin
            end;
            // µð¹ÙÀ̽º¸¦ ¼Ò½ÇÇßÁö¸¸, º¹±¸°¡ °¡´ÉÇÑ°æ¿ì
            D3DERR_DEVICENOTRESET:
            begin
            end;
        end;
    end
;

    result := (hr = D3D_OK);
end;
 

»õ·Î ³ª¿Â IDirect3DDevice9 ¸Þ¼­µå¿¡´Â IDirect3DDevice9.BeginScene()°ú IDirect3DDevice9.EndScene()ÀÌ ÀÖ´Ù. Direct3D9ÀÇ ¸ðµç ·»´õ¸µ ÇÔ¼ö´Â BeginScene()°ú EndScene() »çÀÌ¿¡¼­ ±¸ÇöµÇ¾î¾ß ÇÑ´Ù°í »ý°¢ÇÏ¸é µÈ´Ù. ÀÌ°ÍÀº ¾ÆÁÖ Áß¿äÇÑ ºÎºÐÀ̸鼭µµ ³Ê¹«³ªµµ ´ç¿¬ÇÑ Direct3DÀÇ Æ¯Â¡ÀÌ´Ù.

TD3DDevice.Flush()¶ó°í Ç¥ÇöÇÑ Å¬·¡½º ÇÔ¼ö¿¡¼­´Â ±²ÀåÈ÷ Áß¿äÇÑ ºÎºÐÀÌ ÀÖ´Ù. ±×°ÍÀº À§ÀÇ ¼Ò½º¿¡¼­ ÁÖ¼®À¸·Î ¼³¸íÇÏ°í ÀÖ´Â D3DERR_DEVICELOST¿Í D3DERR_DEVICENOTRESET¿¡ ´ëÇÑ °ÍÀÌ´Ù. ÀÌ°ÍÀº Device lost¿¡ ´ëÇÑ °ÍÀ» ó¸®ÇÏ´Â °ÍÀ¸·Î, DirectDraw ½ÃÀýºÎÅÍ Ç×»ó ¹®Á¦°¡ µÇ¾î ¿Ô´ø °ÍÀÌ´Ù. Á¦ÇѵǾî ÀÖ´Â ºñµð¿À H/WÀÇ ÀÚ¿øÀ» ¿©·¯ ÇÁ·Î±×·¥ÀÌ °øÀ¯ÇÏ·Á´Ù º¸´Ï ÀÌ°ÍÀº ÇÊ¿ä¾Ç°ú °°ÀÌ Á¸ÀçÇØ ¿Ô´Ù. ¿¹¸¦ µé¾î, A¶ó´Â ÇÁ·Î±×·¥ÀÌ ºñµð¿À ¸Þ¸ð¸®¸¦ »ç¿ëÇÏ°í Àִµ¥ B¶ó´Â ÇÁ·Î±×·¥ÀÌ A¸¦ minimize½ÃÅ°°í ÀÚ½ÅÀÌ Ç®½ºÅ©¸°À» Â÷ÁöÇÏ´Â ½Ã³ª¸®¿À°¡ ÀÖ´Ù°í Çϸé B¿¡°Ô ºñµð¿À ÀÚ¿øÀ» ÇÒ´ç ÇØÁÖ±â À§Çؼ­ ºñÈ°¼ºÈ­µÈ AÀÇ ÀÚ¿øÀ» »°¾î¼­ B¿¡°Ô ÁÖ°Ô µÈ´Ù.

¸ÕÀú Device lost°¡ ÀϾ´Â Á¶°ÇÀ» º¸ÀÚ¸é,

1. Ç®½ºÅ©¸°À¸·Î °ÔÀÓ Áß¿¡ alt-tabÀ» ´­·¯ ¹ÙÅÁ È­¸éÀ¸·Î °¬À» ¶§
2. Ç®½ºÅ©¸°À¸·Î °ÔÀÓ Áß¿¡ ´Ù¸¥ À©µµ¿ì(´ÙÀ̾ó·Î±× µî)°¡ È°¼ºÈ­µÇ¸é¼­ Ç®½ºÅ©¸° °ÔÀÓÀÌ minimizeµÉ ¶§
3. Ç®½ºÅ©¸°À¸·Î °ÔÀÓ Áß¿¡ Windows¿¡ ÀÇÇØ °­Á¦·Î È­¸é ¸ðµå°¡ ÀüȯµÉ ¶§ (½ºÅ©¸° ¼¼À̹ö °°Àº...)
4. â¸ðµå·Î °ÔÀÓ Áß¿¡ ´Ù¸¥ °ÔÀÓÀÌ Ç®½ºÅ©¸°À¸·Î ½ÇÇàµÉ ¶§

³ªÀÇ °æÇèÀ¸·Î´Â ÀÌ Á¤µµÀÇ °æ¿ì¿¡ Device lost°¡ ¹ß»ýÇߴµ¥ ¾Æ¸¶µµ ã¾Æº¸¸é ´õ ÀÖÀ» °Í °°´Ù. ÇÏÁö¸¸ ¹ß»ý Á¶°Ç°ú´Â »ó°ü¾øÀÌ, ¿ì¸® ÂÊ¿¡¼­ ¹æ¾îÀûÀ¸·Î Device lost¿¡ ´ëÇÑ ´ëºñÃ¥À» ¸¸µé¾î ³õÀ¸¸é ¹®Á¦°¡ ¾øÀ» °ÍÀ¸·Î »ý°¢µÈ´Ù.

º¸Åë Device lost´Â ¾ðÁ¦¶óµµ IDirect3DDevice9.TestCooperativeLevel()¿¡¼­ È®ÀÎÇÒ ¼ö´Â ÀÖÁö¸¸ ÀϹÝÀûÀ¸·Î´Â IDirect3DDevice9.Present()¿¡¼­ ó¸®ÇÏ´Â °ÍÀÌ ÆíÇÏ´Ù. (ÆíÇÏ´Ù´Â °ÍÀÏ»Ó ÃÖ¼±ÀÇ ¹æ¹ýÀº ¾Æ´Ï´Ù)

±×·¸´Ù¸é D3DERR_DEVICELOST¿Í D3DERR_DEVICENOTRESETÀÇ Â÷ÀÌÁ¡Àº ¹«¾ùÀΰ¡? À̸§¿¡µµ ¾Ë ¼ö ÀÖÁö¸¸ D3DERR_DEVICELOST´Â ¿ÏÀüÈ÷ DeviceÀÇ ÀÚ¿øÀ» ÀÒ¾î¹ö¸° »óÅÂÀÌ°í D3DERR_DEVICENOTRESETÀº Device°¡ resetµÇÁö ¾ÊÀº »óÅ·Π¹Ù²î¾ú´Ù´Â °ÍÀÌ´Ù. À̸§¸¸À¸·Î ºÁµµ ÀüÀÚ°¡ ÈÄÀÚÀÇ supersetÀ̶ó´Â °ÍÀ» ¾Ë ¼ö ÀÖ´Ù.

¸ÕÀú, D3DERR_DEVICENOTRESET »óŶó¸é, ¸ÕÀú ÀϺΠtexture¸¦ ÇØÁ¦ÇؾßÇÑ´Ù. IDirect3DDevice9.CreateTexture()¿¡¼­ D3DPOOL_MANAGED·Î »ý¼ºÇÑ texture´Â ½Ã½ºÅÛ¿¡ ÀÇÇØ ÀÚµ¿ º¹±¸°¡ µÇ°í D3DPOOL_SYSTEMMEM·Î »ý¼ºÇÑ texture´Â ½Ã½ºÅÛ ¸Þ¸ð¸®±â ¶§¹®¿¡ H/W ÀÚ¿øÀÌ ¾Æ´Ï´Ù. µû¶ó¼­ D3DPOOL_DEFAULT·Î »ý¼ºÇÑ texture¸¸ ¸ðµÎ ÇØÁ¦(= nil)ÇÑ´Ù. ±×¸®°í IDirect3DDevice9.Reset()À» ÅëÇØ Device¸¦ ´Ù½Ã ¼¼ÆÃÇÏ°í D3DPOOL_DEFAULT·Î »ý¼ºÇÒ texture¸¦ ´Ù½Ã Àд´Ù. ±×¸®°í Device ÃʱâÈ­ ¶§ Çß´ø IDirect3DDevice9.SetTextureStageState() µîÀ» óÀ½ºÎÅÍ ´Ù½Ã ÇØÁØ´Ù.

¸¸¾à D3DERR_DEVICELOST¶ó¸é ¿ÀÈ÷·Á ´õ °£´ÜÇÏ´Ù. ¿ÏÀüÈ÷ Device¸¦ ÇØÁ¦ÇÏ´Â °úÁ¤À» °ÅÄ£ ÈÄ ´Ù½Ã óÀ½ºÎÅÍ ´Ù½Ã Device¸¦ »ý¼ºÇÏ¸é µÈ´Ù. ÀϹÝÀûÀÎ »óȲ¿¡¼­´Â D3DERR_DEVICELOST°¡ ´õ ¸¹ÀÌ ¹ß»ýÇϱ⠶§¹®¿¡(°ÔÀÓÇÏ´Ù°¡ alt-tabÀ¸·Î ´Ù¸¥ ÀÛ¾÷ Çϱ⠵î) D3DERR_DEVICENOTRESETÀÌ¶óµµ D3DERR_DEVICELOST¿Í °°ÀÌ Ã³¸®Çصµ »ó°ü¾ø´Ù. (ÀÌ°ÍÀº ³ªÀÇ ÁÖ°üÀûÀÎ »ý°¢À¸·Î, ´Ù¸¥ ±×·¡ÇÈ H/W¿¡¼­´Â °á°ú°¡ ´Ù¸¦ ¼öµµ ÀÖ´Ù)



11. ¿¹Á¦ ¼³¸í

¿©±â±îÁö ¿ÔÀ¸¸é ÀÌÁ¦ ÀÌ °­Áµµ ´Ù ³¡³µ´Ù. ÀüÇô ÀÚ¼¼ÇÏÁöµµ ¾Ê°í ÀüÇô ±â¼úÀûÀÎ ºÎºÐµµ ¾øÁö¸¸ ´ÙÇེ·´°Ôµµ ¿ì¸®´Â ÀÌ Á¤µµ¸¸ ¾Ë¾Æµµ 2D °ÔÀÓ Á¤µµ´Â ¸¸µé ¼ö°¡ ÀÖ´Ù. »ç½Ç 2D °ÔÀÓÀ̶ó´Â °ÍÀº ½ºÇÁ¶óÀÌÆ®¸¸ ÂïÀ» ¼ö ÀÖÀ¸¸é ´©±¸¶óµµ ¸¸µé ¼ö ÀÖ´Â °Í ¾Æ´Ï¾ú´ø°¡. ¿©±â¿¡ ÷ºÎÇÑ ¿¹Á¦ °ÔÀÓµµ ¸¶Âù°¡Áö´Ù. µý °Ç º°·Î ¾ø°í ±×³É ½ºÇÁ¶óÀÌÆ®¸¸ ¿­½ÉÈ÷ Âï¾ú´Ù. (°ÔÀÓÀÇ ¸ÞÀÎ ·çÇÁ³ª ¿ÀºêÁ§Æ® Á¤ÀÇ´Â '2D'¶ó´Â ´Ü¾î¿Í´Â »ó°ü¾øÀ¸¹Ç·Î ÀÌ °­Á¿¡¼­´Â ¾ð±ÞÇÏÁö ¾Ê´Â´Ù) ±×·¡µµ ½ºÇÁ¶óÀÌÆ®¸¸ Âï±â´Â Á» ¹¹Çؼ­ ½Ã°£À» Á» ´õ ³»¾î ¾à°£ÀÇ È¿°úµµ Áຸ°í °ÔÀӸʵµ °£´ÜÇÏ°Ô ±¸¼ºÇß´Ù. ¿ø·¡ºÎÅÍ ¹«¼ºÀÇÇÏ°í ¹«Ã¥ÀÓÇÑ °­Á¸¦ ¸ñÇ¥·Î Ç߱⠶§¹®¿¡ ±×³É ¿¹Á¦Çϳª ´Þ¶û ´øÁ® ³õ°í µµ¸Á°¡·Á ÇÏ¿´À¸³ª, ¸¶Áö¸·±îÁö Ãʺ¸ µ¨ÇǾðÀ» Ȧ¸®°íÀÚ Á» ´õ ÈûÀ» ³»¾î º¸°Ú´Ù.

¾Æ·¡ÀÇ ½ºÅ©¸°¼¦Àº Ã·ºÎµÈ ¿¹Á¦¸¦ ½ÇÇàÇÑ °á°ú·Î¼­, ÀϹÝÀûÀÎ ÄõÅͺä(isometric-view)ÀÇ 2D È­¸éÀ» º¸¿©ÁØ´Ù.



Á¶ÀÛÅ°
 

È­»ìǥŰ: 8¹æÇâ À̵¿
Ctrl Å°: Á¡ÇÁ
Esc Å°: Á¾·á 

ÀúÀ۱Ǡ

¹è°æ ±×¸²: 'º°°ú ¼Ò³à' ÆÀ

ŸÀÏ ±×¸²: ³×Åä´Ô
ij¸¯ÅÍ ±×¸²: ±èº´Ã¶´Ô

¿¹Á¦´Â °ÔÀÓÀ̶ó°í´Â ºÎ¸¦ ¼ö ÀÖÀ»¸¸Å­ ¿Ï¼ºµµ°¡ ³ôÁö°¡ ¾Ê´Ù. ´Ù¸¸ ÀÌ °­Á¿¡¼­ ¼³¸íÇß´ø ¸ðµç °ÍÀ» »ç¿ëÇؼ­ 2DÀÇ È­¸é Ãâ·ÂÀ» ±¸ÇöÇÑ °ÍÀ̶ó°í º¼ ¼ö ÀÖ´Ù. ÄÄÆÄÀÏÀÌ °¡´ÉÇϵµ·Ï ¸ðµç ¼Ò½º°¡ µé¾î°¡ ÀÖÀ¸¸ç Å×½ºÆ®´Â Delphi5¿¡¼­ Çß´Ù.

»ç½Ç °ÔÀÓ ±¸¼º ÀÚü¿¡ ´ëÇÑ ¼³¸íµµ Æ÷ÇԵǾî¾ß Çϳª ±×´ÙÁö ƯÀÌÇÑ °Íµµ ¾ø±â ¶§¹®¿¡, ÀÌ °­ÁÂÀÇ Àǹ̿¡ ¸Â´Â
3DÀÇ ¿ä¼Ò¸¦ »ç¿ëÇØ 2D¸¦ Ç¥ÇöÇÑ ºÎºÐ¸¸ Ãß°¡ÀûÀ¸·Î ¼³¸íÇÏ°Ú´Ù. 

1) ±×¸²ÀÚ È¿°ú 

Áö±Ý±îÁö ¼³¸íÇÑ °Í ÀÌ¿Ü¿¡ ÀÌ ¿¹Á¦¿¡¼­ Ưº°È÷ Çϳª ´õ ±¸ÇöÇÑ °ÍÀº ±×¸²ÀÚ È¿°úÀÌ´Ù. °ú°ÅÀÇ ÀÏ¹Ý 2D ¿£ÁøÀÇ °æ¿ì¿¡´Â ±×¸²ÀÚ È¿°ú¸¦ ±¸ÇöÇϱâ À§Çؼ­´Â Áö±Ý ±×¸²ÀÚ µ¥ÀÌÅ͸¦ Ãß°¡Çϰųª ±×¸²ÀÚ¸¦ Ãâ·ÂÇϱâ À§ÇÑ ½ºÇÁ¶óÀÌÆ® ÇÔ¼ö¸¦ Á÷Á¢ ¸¸µé¾î¾ß Çß´Ù. ÇÏÁö¸¸ ÀÌÁ¦´Â ÈûµéÁö ¾Ê°Ô °£´ÜÇÏ°Ô ±¸ÇöÇÒ ¼ö°¡ ÀÖ´Ù. ¿ø·¡ Ãâ·ÂÇÏ·Á´Â½ºÇÁ¶óÀÌÆ®¸¦ »ç°¢ÇüÀÌ ¾Æ´Ñ 45µµ ±â¿ï¾îÁø ÆòÇà»çº¯ÇüÀ¸·Î ³ªÅ¸³»¸é¼­ Åõ¸íÇÏÁö ¾ÊÀº ºÎºÐ¿¡ ´ëÇؼ­ °ËÀº»ö ¹ÝÅõ¸íÀ¸·Î ¸¸µé¾î ÁÖ¸é µÈ´Ù. 

¾Õ¿¡¼­ ¼³¸íÇÒ ¶§ ±×¸²ÀÚ È¿°ú¸¦ ÁÖ±â À§ÇÑ render state¸¦ ´ÙÀ½°ú °°ÀÌ Á¤ÀÇÇß´Ù.
 

m_pD3DDevice.SetRenderState(D3DRS_SRCBLEND, D3DBLEND_ZERO);
m_pD3DDevice.SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
 
Source¸¦ zero·Î Ãâ·ÂÇ϶ó´Â °ÍÀº R, G, B°¡ ¾î¶² »öÀÌµç °£¿¡ ¸ðµÎ °ËÀº »öÀ¸·Î ³ªÅ¸³»¾î¶ó´Â °ÍÀ̸ç, destinationÀÌ inverse source alpha¶ó´Â °ÍÀº destination¿¡¼­´Â sourceÀÇ ¾ËÆÄ °ªÀÇ ¹Ý´ë °ªÀ» °­Á¦·Î ÁöÁ¤ÇÏ°Ú´Ù´Â °ÍÀε¥ °á°úÀûÀ¸·Î source¿¡¼­ alpha °ªÀÌ 0ÀÎ ºÎºÐÀ» ³²°Ü ³õ°Ô µÈ´Ù. ÀÏ´Ü À̰͸¸ ÁöÁ¤ÇÏ°Ô µÇ¸é ½ºÇÁ¶óÀÌÆ®°¡ Ç×»ó °Ë°Ô Ãâ·ÂµÈ´Ù. (ÇÏÁö¸¸ Ä÷¯Å°´Â ¸ðµÎ Àû¿ëµÈ´Ù) ±×·¸´Ù¸é ÀÌÁ¦´Â ÀÌ·¸°Ô ¸¸µç °ËÀº»öÀÇ ½ºÇÁ¶óÀÌÆ®¸¦ ¹ÝÅõ¸íÇÏ°Ô 45µµ ±â¿ïÀÎ ÆòÇà »çº¯ÇüÀ¸·Î ¸¸µå´Â °Í¸¸ ³²¾Ò´Ù. ÀÌ°Í ¿ª½Ã ¾î·ÆÁö ¾ÊÀºµ¥, ¿©Å²¯ Á÷»ç°¢ÇüÀ¸·Î ÁöÁ¤ÇØ ¿Ô´ø 4°³ÀÇ vertex ÁÂÇ¥À» ÆòÇà»çº¯ÇüÀ¸·Î Áֱ⸸ ÇÏ¸é µÈ´Ù.
 
procedure TGameMain.PutSpriteShadow
(
    // ¿©±â¼­ÀÇ zÁÂÇ¥´Â 3D ÁÂÇ¥°¡ ¾Æ´Ï¶ó 2.5DÀÇ zÁÂÇ¥¸¦ ¸»ÇÑ´Ù.
    // Áï, Á¡ÇÁ¿¡ ´ëÇÑ zÁÂÇ¥¶ó°í º¼ ¼ö ÀÖ´Ù.
    xPos, yPos, zPos : integer;
    // texture¿¡ ´ëÇÑ ÇÚµé
    index : integer;
    // texture¿¡¼­ ¿øº»ÀÇ »ç°¢ ¿µ¿ª
    const smRect: TSmRect;
    // Åõ¸íµµ, ÁöÁ¤ÇÏÁö ¾ÊÀ¸¸é 100% (= 255)
    opacity: integer = 255
);
var
    x, y: integer;
    vertices: array[0..3] of TVertexTL;
begin
    // ÁöÁ¤ÇÑ textureÀÇ pixel ÁÂÇ¥¸¦ vertex °ªÀ¸·Î ¹Ù²ã¼­ µ¹·ÁÁØ´Ù.
    // ÀÌ ºÎºÐÀº shadow¸¦ ±¸ÇöÇÏ´Â °ÍÀ̱⠶§¹®¿¡
    // vertex color¿¡ ´ëÇÑ Åõ¸íµµ¸¦ 50% (= 128)·Î ÁöÁ¤Çß´Ù.

    InitVertexTL(index, smRect.x, smRect.y, smRect.w, smRect.h,
                 vertices, 128);

    // ½ÇÁ¦ ±×¸²ÀÚ°¡ ½ÃÀÛÇÏ´Â (x, y)¸¦ °è»ê
    x := xPos -(smRect.dx * smRect.dy div smRect.h) + zPos div 2;
    y := yPos -(smRect.dy + (smRect.h-smRect.dy) div 2) + zPos div 2;

    // ±â¿ï¾îÁø ÆòÇà»çº¯ÇüÀ¸·Î Ãâ·ÂÇϵµ·Ï vertex ÁÂÇ¥¸¦ ¼öÁ¤
    ShadowVertexTL(x, y, smRect.w, smRect.h, vertices);

    // °è»êµÈ vertex·Î Ãâ·Â
    g_d3Device.DrawTexture(index, vertices);
end;

À̹ø¿¡´Â ÀÌÀü¿¡ ¼Ò°³ÇÏÁö ¾ÊÀº ÇÔ¼ö°¡ 3°³ Á¤µµ ³ª¿Ô´Ù. ÀÌ ºÎºÐÀº ¾à°£ÀÇ Æ®¸¯À» ¿äÇÏ´Â °ÍÀ̱⠶§¹®¿¡ ÀϹÝÀûÀÎ 2DÀÇ ¹æ¹ýÀÌ ¾Æ´Ñ Direct3D9ÀÇ ¿ä¼Ò¸¦ ÀûÀûÈ÷ »ç¿ëÇØ¾ß ÇÏ´Â ºÎºÐÀ̹ǷΠ2DÀÇ ÀÔÀå¿¡¼­´Â Á» ´õ nativeÇÑ ÄÚµå·Î ÀÛ¼ºµÇ¾îÁø ºÎºÐÀÌ´Ù. InitVertexTL()°ú ShadowVertexTL()Àº ¿¹Á¦ Äڵ忡¼­ ¿ë¹ýÀ» Á÷Á¢ ÆľÇÇϱ⠹ٶó¸ç ¿©±â¼­´Â DrawTexture()¿¡ ´ëÇÑ ºÎºÐ¸¸ ¤°í ³Ñ¾î °¡·Á ÇÑ´Ù.

function
TD3DDevice.DrawTexture
(
    hImage: integer;
    const vertices: array of TVertexTL
): boolean;
var
    pTexInfo: PTextureInfo;
begin
    result := FALSE;
 

    if hImage = 0 then
        exit;
 

    // ÇÚµéÀ» ¿ø·¡ÀÇ texture ±¸Á¶Ã¼·Î ¹Ù²Ù´Â °úÁ¤
    pTexInfo := PTextureInfo(hImage);
 

    // ÀÌ¹Ì vertex buffer ¼³Á¤ÀÌ ³¡³µÀ¸¹Ç·Î ¹Ù·Î Ãâ·ÂÇÑ´Ù.
    t_SetTexture(0, pTexInfo.pTexture);
    m_pD3DDevice.SetFVF(D3DFVF_XYZRHW or D3DFVF_DIFFUSE or
                        D3DFVF_TEX1);
    m_pD3DDevice.DrawPrimitiveUP(D3DPT_TRIANGLEFAN, high(vertices)-1,
                                 @vertices, sizeof(TVertexTL));
 

    result := TRUE;
end;
 

2) ÆÄÀÏ¿¡¼­ À̹ÌÁö Àбâ

¿¹Á¦¿¡¼­´Â ÆÄÀÏ¿¡¼­ bmp¿Í jpgÀ» Àо ó¸®ÇÏ°í ÀÖ´Ù. ¾Æ¸¶µµ ½ÇÁ¦ °ÔÀÓÀ» ¸¸µç´Ù°í Çصµ ÀÌ ºÎºÐÀº ÇÊ¿äÇÒ °ÍÀÌ´Ù.

¿ø·¡ Direct3DX¿¡¼­´Â ÆÄÀÏ¿¡¼­ bmpµîÀ» Àо texture·Î ¹Ù²Ù¾î ÁÖ´Â ÇÔ¼ö¸¦ Á¦°øÇÑ´Ù. ÇÏÁö¸¸ °£´ÜÇÏ°Ô »ç¿ëÇÒ ¶§´Â ÆíÇÒÁö ¸ð¸£°ÚÀ¸³ª ³ªÁß¿¡ °ÔÀÓÀÌ ¿Ï¼ºµµ¸¦ °®Ãß¾î °¥ ¶§ÂëÀ̸é ÀÚüÀûÀÎ À̹ÌÁö Æ÷¸ËÀ» »ç¿ëÇϰųª ¿øº»ÀÇ À̹ÌÁö¿¡ Àü󸮸¦ °ÅÄ¡´Â ÀÏÀÌ ¸¹¾ÆÁú °ÍÀ̹ǷΠÀÌ·± ÇÔ¼ö´Â Á÷Á¢ Çϳª ¸¸µé¾î ÁÖ´Â °ÍÀ» ±ÇÀåÇÑ´Ù. ƯÈ÷ µ¨ÆÄÀÌ´Â ÀÌ¹Ì TBitmap Ŭ·¡½º¿Í TJPEGImage Ŭ·¡½º°¡ Áö¿øµÇ°í ÀÖÀ¸¹Ç·Î ´Ù¸¥ ¾ð¾îº¸´Ù´Â ¼Õ½±°Ô À̹ÌÁö ÆÄÀÏÀ» texture·Î ¸¸µé ¼ö ÀÖ´Ù.

¿©±â¼­´Â 2Á¾·ùÀÇ À̹ÌÁö Àбâ ÇÔ¼ö¸¦ Á¦°øÇϴµ¥, ±×³É À̹ÌÁö¸¦ Àд ÇÔ¼öÀÎ LoadD3DImage()¿Í Ä÷¯Å°¸¦ ÁöÁ¤ÇÒ ¼ö ÀÖµµ·Ï ÇÑ LoadD3DImageEx()¸¦ ¼Ò°³ÇÏ°íÀÚ ÇÑ´Ù. ±× µÎ ÇÔ¼ö´Â ´ÙÀ½°ú °°ÀÌ Á¤ÀǵǾî ÀÖ´Ù.
 

function LoadD3DImage
(
    const d3Device : TGfxDevice;
    fileName       : string
): integer;
begin
    result := LoadD3DImageSub(d3Device, fileName, FALSE);
end;

function LoadD3DImageEx
(
    const d3Device : TGfxDevice;
    fileName       : string;
    colorKey       : longword
): integer;
begin
    result := LoadD3DImageSub(d3Device, fileName, TRUE, colorKey);
end;

function LoadD3DImageSub
(
    // TGfxDevice´Â ¿©±â¼­ Á¤ÀÇÇÑ Direct3D Device¸¦ ·¡ÇÎÇÏ´Â °´Ã¼
    const d3Device : TGfxDevice;
    fileName       : string;
    useColorKey    : boolean;
    colorKey       : longword = 0
): integer;
var
    i, j         : integer;
    depth        : integer;
    ExtString    : string;
    hImage       : integer;
    bitmap       : TBitmap;
    jpgImage     : TJPEGImage;
    pDest32      : Plongword;
    temp, _R, _B : longword;
    paletteEntry : array[0..255] of longword;
    pPalette     : Plongint;

begin
    result       := 0;
    pPalette     := nil;
    depth        := 32;
 

    if not FileExists(fileName) then
        exit;
 

    bitmap := TBitmap.Create; 

    try
        ExtString := LowerCase(ExtractFileExt(fileName));

        if ExtString = '.jpg' then begin

            // È®ÀåÀÚ°¡ jpgÀÏ ¶§´Â TJPEGImage¸¦ ÅëÇØ Àд´Ù.
            jpgImage := TJPEGImage.Create();
            jpgImage.LoadFromFile(fileName);
            bitmap.Assign(jpgImage);
            jpgImage.Free;
        end
        else begin
            // È®ÀåÀÚ°¡ jpg°¡ ¾Æ´Ò ¶§´Â TBitmapÀ» ÅëÇØ Àд´Ù.
            bitmap.LoadFromFile(fileName);
        end;
 

        if useColorKey then begin

            // Ä÷¯Å°°¡ Àû¿ëµÇ´Â °æ¿ì¿¡´Â À̹ÌÁö ÀÚü¸¦ 32-bit·Î ¼³Á¤
            bitmap.PixelFormat := pf32Bit;

            colorKey := colorKey and $00FFFFFF;
            for j := 0 to pred(bitmap.Height) do begin
                pDest32 := bitmap.ScanLine[j];
                for i := 0 to pred(bitmap.Width) do begin
                    // °­ÁÂÀÇ ¾Õ ºÎºÐ¿¡ ³ª¿Ô´ø ºÎºÐ
                    if (pDest32^ and $00FFFFFF) <> colorKey then
                        pDest32^ := pDest32^ or $FF000000
                    else 
                        pDest32^ := pDest32^ and $00FFFFFF;

                    inc(pDest32);
                end;
            end;
        end
        else begin
            depth := GetPixelDepth(bitmap);

            if depth = 8 then begin
                // 8-bit À̹ÌÁö´Â ÆÈ·¹Æ® ¼³Á¤ÀÌ ÇÊ¿äÇÏ´Ù.
                GetPaletteEntries(bitmap.Palette, 0, 256,
                                  paletteEntry);
                for i := 0 to 255 do begin
                    temp := paletteEntry[i] or $FF000000;
                    _R := (temp and $000000FF) shl 16;
                    _B := (temp and $00FF0000) shr 16;
                    paletteEntry[i] := (temp and $FF00FF00) or
                                       
_R or _B;
                end;
                pPalette := @paletteEntry;
            end;
        end;
 
        // ÀÏ´Ü texture¸¦ »ý¼ºÇÑ´Ù.
        hImage := d3Device.CreateImage(bitmap.Width, bitmap.Height);

        if hImage = 0 then
            exit;

        // texture¿¡ TBitmap¿¡ ÀúÀåµÇ¾î ÀÖ´Â À̹ÌÁö¸¦ Àû¿ë½ÃŲ´Ù.
        d3Device.AssignImage(hImage, bitmap.ScanLine[0],
           bitmap.Width, bitmap.Height, depth,
           integer(bitmap.ScanLine[1]) - integer(bitmap.ScanLine[0]),
           pPalette);

    finally
        bitmap.Free;

    end;

    result := hImage;
end;
 
³ªÁß¿¡´Â ¸®¼Ò½º º¸È£¸¦ À§ÇØ À̹ÌÁö µîÀº ÀÚü Æ÷¸ËÀ̳ª ÅëÇÕ ¸®¼Ò½º ÇüÅ·Π³²°Ô µÈ´Ù. ±×¶§´Â ±×¿¡ ¸Â°Ô À§ÀÇ ¼Ò½º¸¦ ¼öÁ¤ÇÏ¸é µÈ´Ù.

3) °ÔÀÓÀÇ ¸ÞÀÎ ·çƾ°ú ±×·¡ÇÈ ÀÌ¿ÜÀÇ ¼³¸í

¾îÂ÷ÇÇ ¼Ò½º¸¦ ÷ºÎÇÑ ¿¹Á¦ÀÌ´Ï Á÷Á¢ »ìÆ캸½Ã±â ¹Ù¶õ´Ù. ³ªµµ ¼ÒÁßÇÑ ÁÖ¸»À» ÄÄÇ»ÅÍ ¾Õ¿¡¼­ ŸÀÌÇÎÇϸ鼭 º¸³»°í ½ÍÁö´Â ¾Ê´Ù.



12. °­Á¸¦ Á¢À¸¸ç

¸¶Áö¸·À¸·Î °ÔÀÓÀ» ¸¸µé±â À§Çؼ­ '2D'¶ó´Â È­¸é Ãâ·Â ÀÌ¿Ü¿¡ ÇÁ·Î±×·¡¸Ó·Î¼­ »ý°¢ÇØ¾ß ÇÒ °ÍµéÀ» ¾Ë¾Æ º¸ÀÚ.

- °ÔÀÓÀÇ ¸ÞÀÎ ·çÇÁ´Â ¾î¶² ½ÄÀ¸·Î µ¿ÀÛ½Ãų °ÍÀΰ¡?
- ¿ÀºêÁ§Æ®ÀÇ Á¤ÀÇ ¹× Çൿ ¾ç½Ä ¼³°è
- °ÔÀÓ ¸ÊÀÇ ±¸¼º°ú ·Îµù ¹æ½Ä
- ÇÑ±Û ÀÔÃâ·Â ¶Ç´Â Áö¿ªÈ­ °ü·Ã À̽´
- »ç¿îµå ¶óÀ̺귯¸® (¹è°æÀ½ ¹× È¿°úÀ½)
- ³×Æ®¿öÅ© ÇÁ·Î±×·¡¹Ö
- °ÔÀÓ ÁøÇàÀ» À§ÇÑ ½ºÅ©¸³Æ® ¿£Áø
- °ÔÀÓÀÇ ¼¼À̺긦 À§ÇÑ object serialization
- User interface ÇÁ·Î±×·¡¹Ö
- °ÔÀÓ ÆÐÄ¡¸¦ À§ÇÑ ÀÚµ¿ ¾÷µ¥ÀÌÆ® ½Ã½ºÅÛ
- ÇÁ·Î±×·¡¸ÓÀÇ ¸¶Áö¸· Èñ¿­À» À§ÇÑ easter egg »ðÀÔ
 

»ý°¢Çϴ´ë·Î Àû¾î º¸¾Ò´Âµ¥ ¾Æ¸¶µµ ºüÁø ºÎºÐÀÌ ¸¹À» °ÍÀÌ´Ù. ÀÌ·¸µí '2D °ÔÀÓ'À» ³ªÅ¸³»±â À§ÇØ È­¸é¿¡ Ãâ·ÂÇÏ´Â °ÍÀº ÀÌ·¸°Ô³ª ¸¹Àº 'ÇؾßÇÒ ÀÏ' Áß¿¡ ÇϳªÀÏ»ÓÀÌ´Ù. À§ÀÇ ³»¿ëµéÀ» Á¦´ë·Î ±¸Çö¸¸ ÇØ ³õ¾Ò´Ù¸é ±Ý¹æ ÀÚ½ÅÀÇ °ÔÀÓÀ» 3D·Îµµ ¸¸µé ¼ö ÀÖ´Ù. (ÀÚ.... ¶Ç ¼Ó°í ÀÖ´Â °ÍÀÌ´Ù) ±×¸®°í ÀÌ·¯ÇÑ '°ÔÀÓ ÇÁ·Î±×·¡¹Ö'µµ °ÔÀÓ Á¦ÀÛ Àüü¿¡¼­ º¸¸é ¶Ç ÀϺÎÀÌ°í, ÀÌ·¯ÇÔ '°ÔÀÓ Á¦ÀÛ'Àº, »ó¾÷ÀûÀ¸·Î ¼º°øÇÑ °ÔÀÓÀ» ÅëÇØ ÀÌÀÍÀ» ¾ò´Â ¹æ¹ý¿¡ ´ëÇؼ­´Â ¶Ç ÀϺκÐÀÏ»ÓÀÌ´Ù.

½½½½ ´«Ä¡ ë°ÚÁö¸¸ ÀÌ °­Á´ Áß¿äÇÑ °ÍÀ» ¸¹ÀÌ »©¸Ô°í ÀÖ´Ù. Direct3D9ÀÇ °¡Àå ±âº»ÀûÀÎ ºÎºÐÀº ¸ðµÎ ³Ñ¾î°¡°í Àִµ¥, ±×°ÍÀº ÀÌ¹Ì DirectX SDK ¸Å´º¾óÀÇ DirectX Graphics - Programming Guide - Getting Started with Direct3D ºÎºÐ¿¡¼­ ¸ðµÎ ¼³¸íÇÏ°í Àֱ⠶§¹®¿¡ Ưº°È÷ ¿©±â¼­ ŸÀÌÇÎÀÇ ¾çÀ» ´ÃÀÌ°í ½ÍÁö´Â ¾Ê¾Ò´Ù.

°­ÁÂÀÇ ³»¿ë»óÀ¸·Î º¸¸é ºÎÁ·ÇÑ ºÎºÐµµ ¸¹°í ÁÖ°üÀûÀÎ »ý°¢µµ ¸¹´Ù. ³»°¡ ±â¼úÇÑ ¸ðµç °ÍµéÀº Àý´ëÀûÀÎ °ÍÀÌ ¾Æ´Ï¸ç Àд »ç¶÷µé·Î ÇÏ¿©±Ý ÀÚ½ÅÀÌ »ý°¢ÇÏ°í ÀÖ´Â ¹æ½Ä¿¡ ´ëÇÑ Âü°í Á¤µµ¸¸ µÈ´Ù¸é ¾î´À Á¤µµ ÀÌ °­ÁÂÀÇ ¸ñÀûÀº ´Þ¼ºÇÑ °ÍÀ̶ó°í º»´Ù.

(°­Á¸¦ ¾²°í ³ª¼­ ÀüüÀûÀ¸·Î °ËÅ並 ÇÏÁö ¾Ê¾ÒÀ¸¹Ç·Î ¿ÀÅ»ÀÚ°¡ ¸¹Àº °ÍÀÌ´Ù. ÇÏÁö¸¸ ºÒÆòÇÏÁö ¾Ê´Â ´ç½ÅÀÌ ¾Æ¸§´ä´Ù) 

÷ºÎÆÄÀÏ (275K) (Delphi 5¿¡¼­ ÀÛ¼ºµÇ¾úÀ½)