|
|
|
|
|
|
Additional info
|
|
|
|
|
Latest Forum posts
|
|
|
|
|
Ads
|
|
|
|
|
|
|
|
|
|
|
|

BMPÆÄÀÏ·Î ¸¸µé¾îÁø height map °¡Á®¿À±â |
Reimer¾¾°¡ height mapÀ» ¼Ò°³ÇÏ°í °¡Àå ¸¹ÀÌ ¹ÞÀ» Áú¹®Àº RAWÆÄÀÏ ´ë½Å ÀϹÝÀûÀ¸·Î ¾²ÀÌ´Â BMPÆÄÀÏÀ» height map À̹ÌÁö·Î »ç¿ëÇÒ ¼ö ¾ø´Â°¡ ÇÏ´Â °Í ÀÔ´Ï´Ù. ¾Æ¹«·¡µµ BMPÆÄÀÏÀº RAWÆÄÀÏ¿¡ ºñÇØ Windows ±×¸²ÆÇÀ̳ª À̹ÌÁö ÆíÁý ÇÁ·Î±×·¥µé·Î ½±°Ô ´Ù·ê ¼ö ÀÖÀ¸´Ï±î¿ä. ÀÏ´ÜÀº, Reimer¾¾°¡ BMPÆÄÀÏ ´ë½Å RAWÆÄÀÏÀ» »ç¿ëÇÑ ÀÌÀ¯¸¦ ¾Æ´Â °ÍºÎÅÍ ½ÃÀÛÇØ º¾½Ã´Ù.
RAWÆÄÀÏÀº ¼ø¼öÇÑ(plain) dataÀÇ ÁýÇÕÀÔ´Ï´Ù. dataÀ̿ܿ¡ ¾î¶°ÇÑ Á¤º¸µµ Æ÷ÇÔÇÏÁö ¾Ê´Â ´Ü¼øÇÑ ±¸Á¶À̱⠶§¹®¿¡ ÆÄÀϳ»ÀÇ byteÀüºÎ°¡ data·Î¸¸ ±¸¼ºµÇ¾î ÀÖ½À´Ï´Ù. µû¶ó¼ headerµîÀ» Àüó¸® ÇØÁÙ ÇÊ¿ä ¾øÀÌ Ã³À½ºÎÅÍ ³¡±îÁö byte´ÜÀ§·Î Àоî¿À¸é µÇ¹Ç·Î ¸Å¿ì °£ÆíÇÕ´Ï´Ù.
BMPÆÄÀÏÀº ¾ÖÃÊ¿¡ À̹ÌÁö¿ëÀ¸·Î ¸¸µé¾îÁø ÆÄÀÏ Æ÷¸ËÀÔ´Ï´Ù. µû¶ó¼ À̹ÌÁö 󸮿¡ ÇÊ¿äÇÑ ¸¹Àº ºÎ°¡ÀûÀÎ Á¤º¸¸¦ ´ã°í ÀÖ½À´Ï´Ù. Æ÷ÇԵǴ Á¤º¸¿¡´Â ÆÄÀÏ Å©±â, °¡·Î ¼¼·Î Å©±â µîÀÌ ÀÖ½À´Ï´Ù. ÀÌ·¸°Ô ºÎ°¡ÀûÀ¸·Î Æ÷ÇԵǾî ÀÖ´Â Á¤º¸µéÀº BMPÆÄÀϷκÎÅÍ ÇÊ¿äÇÑ data¸¸À» °¡Á®¿À±â¸¦ RAWº¸´Ù ¾à°£ ¾î·Æ°Ô ÇÕ´Ï´Ù. ¿ì¸®°¡ ÇÒ ÀÏÀº BMPÆÄÀÏ¿¡¼ ÇÊ¿ä ¾ø´Â data´Â ³»¹ö·ÁµÎ°í ÇÊ¿äÇÑ data¸¸À» ÇØ´ç ¿µ¿ª¿¡¼ °¡Á®¿À´Â °ÍÀÔ´Ï´Ù. À̸¦ À§ÇØ °£´ÜÇÏ°Ô BMPÆÄÀÏ Æ÷¸ËÀ» ¼³¸íÇÏ°Ô µÉ ÅÙµ¥, BMPÆÄÀÏ Æ÷¸Ë¿¡ °ü½ÉÀÌ ¾ø´Ù¸é ÀÌ ºÎºÐÀº ¶Ù¾î³Ñ¾îµµ »ó°ü ¾ø½À´Ï´Ù.
BMPÆÄÀÏÀº header°¡ °¡¿ë(actual) pixel data ¾Õ¿¡ À§Ä¡ÇÕ´Ï´Ù. ¹°·Ð headerµµ byte data·Î ±¸¼ºµÇ¾î ÀÖ½À´Ï´Ù. ¿¹¸¦ µé¾î BMPÆÄÀÏÀ» ¸Þ¸ðÀåÀ¸·Î ¿¾îº¸¸é °¡Àå óÀ½ µÎ ¹®ÀÚ´Â ¹Ýµå½Ã ¡®BM¡¯ÀÔ´Ï´Ù. BMPÆÄÀÏÀ» hex editor¿¡¼ ¿¾îº¸¸é °¡Àå óÀ½ µÎ byte´Â ¡®BM¡¯ÀÇ hex°ªÀÎ 66 77ÀÔ´Ï´Ù. µû¶ó¼ ReadByteÇÔ¼ö·Î ù ¹øÂ° byte¸¦ Àоî¿À¸é 66ÀÌ return µÉ °Í ÀÔ´Ï´Ù. ¶Ç ±× ´ÙÀ½ È£Ãâ¿¡´Â ¹°·Ð 77ÀÌ returnµÇ°ÚÁö¿ä. ÇÏÁö¸¸ ÀÌ hex°ªµéÀÌ ascii·Î ´ëÀÀµÈ´Ù°í ÇØ¼ ¹Ýµå½Ã Àǹ̰¡ ÀÖ´Â data´Â ¾Æ´Õ´Ï´Ù. ´ÜÁö BMPÆÄÀÏ Æ÷¸ËÀÌ °¡Àå óÀ½ 2 byte´Â 66 77·Î Çϵµ·Ï Á¤ÀÇÇϰí ÀÖ´Â °Í»ÓÀÔ´Ï´Ù. ´ÙÀ½Àº BMPÆÄÀÏ Æ÷¸ËÀÌ Á¤ÀÇÇϰí ÀÖ´Â headerÀÇ ±¸Á¶ÀÔ´Ï´Ù.
header¿¡¼ ¿ì¸®¿¡°Ô Àǹ̸¦ °¡Áö´Â data´Â °¡·Î(width), ¼¼·Î(height)¿Í À¯È¿ pixel dataÀÇ ½ÃÀÛÁ¡(offset)ÀÔ´Ï´Ù. »ç½Ç Windows ±×¸²ÆÇµîÀÇ ÀϹÝÀûÀÎ ±×·¡ÇÈ ÆíÁý ÇÁ·Î±×·¥Àº BMPÆÄÀÏÀ» ÀúÀåÇÒ ¶§ À¯È¿ pixel data¸¦ header ¹Ù·Î ´ÙÀ½¿¡ À§Ä¡½ÃŰ¹Ç·Î º¸Åë data ½ÃÀÛÁ¡Àº 54°¡ µË´Ï´Ù. ±×·¯³ª ¸¸ÀÏÀÇ °æ¿ì¸¦ »ý°¢Çؼ ¹Ýµå½Ã ½ÃÀÛÁ¡À» header¿¡¼ ÀÐ¾î¼ Ã³¸®ÇØÁÖµµ·Ï ÇսôÙ.
BMPÆÄÀÏÀº À¯È¿ pixel data°¡ 1 pixel´ç 3 byte·Î ±¸¼ºµÇ¾î ÀÖ½À´Ï´Ù. Áï 3 byte°¡ 1 pixelÀ» ÀǹÌÇÕ´Ï´Ù. 3 byteÀÇ °ªÀº °¢°¢ red, green, blue (RGB value)¸¦ ÀǹÌÇÕ´Ï´Ù. ¿ì¸®°¡ heightmap¿¡¼ ³ôÀ̰ªÀ¸·Î »ç¿ëÇÏ´Â °ªÀº °¢ pixelÀÇ black ~ white»çÀÌ 255´Ü°è grayscale °ªÀ̱⠶§¹®¿¡ ÀÌ RGB»ö»ó°ªÀ» grayscale·Î ¹Ù²Ù¾î »ç¿ëÇØ¾ß ÇÕ´Ï´Ù. ¹Ù²Ù´Â ¹æ¹ýÀº °£´ÜÇÏ°Ô red, green, blue ¼¼ »ö»ó°ªÀ» ¸ðµÎ ´õÇÑ ÈÄ 2ÀÇ 3½Â, Áï 8·Î ³ª´©¾î ÁÖ¸é grayscale°ªÀÌ µË´Ï´Ù.
ÀÌÁ¦ »õ Windows Game ÇÁ·ÎÁ§Æ®¸¦ »ý¼ºÇϰí ÀÌÀü tutorial¿¡¼ ÇÊ¿äÇÑ ÆÄÀϵéÀ» º¹»çÇØ ¿É½Ã´Ù.
°¡Àå ¸ÕÀú ÇÒ ÀÏÀº ´ç¿¬È÷ BMPÆÄÀϷκÎÅÍ height°ªÀ» Àоî¿À´Â °Í ÀÔ´Ï´Ù. header¿¡¼ ÇÊ¿äÇÑ Á¤º¸¸¦ ÀÐ°í ±× Á¤º¸¿¡ µû¶ó À¯È¿ pixel data¸¦ ÀÐ¾î¼ grayscale·Î º¯È¯ÇØ¾ß ÇÕ´Ï´Ù. ´ÙÀ½ BMPÆÄÀÏÀ» »ç¿ëÇϰڽÀ´Ï´Ù. ¹°·Ð Á÷Á¢ ¸¸µé¾î¼ »ç¿ëÇØµµ »ó°ü¾ø½À´Ï´Ù.
BMPÆÄÀÏÀ» ÇÁ·ÎÁ§Æ® Æú´õ¿¡ À§Ä¡½Ã۰í ÇØ´ç ÆÄÀÏÀ» Àбâ À§ÇØ LoadHeightDataÇÔ¼öÀÇ ³»¿ëÀ» ´ÙÀ½°ú °°ÀÌ ¼öÁ¤ ÇսôÙ.
private void LoadHeightData() { FileStream fs = new FileStream("../../../heightmap.bmp", FileMode.Open, FileAccess.Read); BinaryReader br = new BinaryReader(fs); int offset; br.BaseStream.Seek(10, SeekOrigin.Current); offset = (int)br.ReadUInt32(); br.BaseStream.Seek(4, SeekOrigin.Current); WIDTH = (int)br.ReadUInt32(); HEIGHT = (int)br.ReadUInt32(); br.BaseStream.Seek(offset - 26, SeekOrigin.Current); heightdata = new int[WIDTH, HEIGHT]; for (int y = 0; y < HEIGHT; y++) { for (int x = 0; x < WIDTH; x++) { int height = ((int)(br.ReadByte()) + (int)(br.ReadByte()) + (int)(br.ReadByte())) / 8; heightdata[WIDTH - 1 - x, HEIGHT - 1 - y] = height; } } br.Close(); }
¸ÕÀú, ÀÐÀ» ÆÄÀÏ °æ·Î¸¦ ´Ù¿î¹ÞÀº BMPÆÄÀÏÀÇ °æ·Î·Î ¹Ù²Ù¾î ÁÝ´Ï´Ù.
FileStream fs = new FileStream("../../../heightmap.bmp", FileMode.Open, FileAccess.Read); BinaryReader br = new BinaryReader(fs);
´ÙÀ½À¸·Î À¯È¿ pixel dataÀÇ ½ÃÀÛ À§Ä¡¸¦ ÀúÀåÇØ µÑ °ø°£ÀÌ ÇÊ¿äÇϹǷΠoffsetÀ̶ó´Â Áö¿ª º¯¼ö¸¦ ¼±¾ðÇß½À´Ï´Ù.
int offset;
±×¸®°í ÆÄÀÏ Æ÷ÀÎÅ͸¦ headerÀÇ À¯È¿ pixel data ½ÃÀÛ À§Ä¡¸¦ ÁöÁ¤ÇÏ´Â À§Ä¡(seek 10)·Î ¿Å±â°í ReadUInt32ÇÔ¼ö·Î 4byte¸¦ Àоî offset¿¡ ÀúÀå½Ãŵ´Ï´Ù. (±×¸²¿¡¼´Â 11-14ÀÌÁö¸¸ ÆÄÀÏ Æ÷ÀÎÅÍ´Â 0¹øºÎÅÍ ½ÃÀÛÇϹǷΠ»ç½Ç 10-13ÀÔ´Ï´Ù. ´Ù¸¥ À§Ä¡µéµµ ¸¶Âù°¡Áö ÀÔ´Ï´Ù.)
br.BaseStream.Seek(10, SeekOrigin.Current); offset = (int)br.ReadUInt32();
´ÙÀ½À¸·Î À̹ÌÁöÀÇ °¡·Î Å©±â¿Í ¼¼·Î Å©±â¸¦ ¿¬¼ÓÀ¸·Î Àоî¿À±â À§ÇØ ÆÄÀÏ Æ÷ÀÎÅ͸¦ Ãß°¡·Î 4¸¸Å ¿òÁ÷¿© °¡·Î Å©±â¸¦ ÁöÁ¤ÇÏ´Â À§Ä¡(seek 14)¿¡ À§Ä¡½Ãŵ´Ï´Ù. ReadUInt32ÇÔ¼ö¸¦ 2¹ø È£ÃâÇÏ¿© 4byte¾¿ °¡·Î Å©±â¿Í ¼¼·Î Å©±â Àü¿ª º¯¼ö¿¡ °¢°¢ ÀúÀå½Ãŵ´Ï´Ù.
br.BaseStream.Seek(4, SeekOrigin.Current); WIDTH = (int)br.ReadUInt32(); HEIGHT = (int)br.ReadUInt32();
offset º¯¼ö¿¡ ÀúÀåµÈ À¯È¿ pixel data ½ÃÀÛ À§Ä¡·Î ÆÄÀÏ Æ÷ÀÎÅ͸¦ À̵¿½Ã۰í À̹ÌÁöÀÇ °¡·Î Å©±â¿Í ¼¼·Î Å©±â¸¸Å ¹è¿À» ¼±¾ðÇÕ´Ï´Ù. ±×¸®°í ÇØ´ç pixelÀÇ RGB»ö»ó°ªÀ» grayscale·Î normalize ½ÃŲ ÈÄ ¹è¿ÀÇ ÇØ´ç À§Ä¡¿¡ ÀúÀåÇÕ´Ï´Ù.
br.BaseStream.Seek(offset - 26, SeekOrigin.Current); heightdata = new int[WIDTH, HEIGHT]; for (int y = 0; y < HEIGHT; y++) { for (int x = 0; x < WIDTH; x++) { int height = ((int)(br.ReadByte()) + (int)(br.ReadByte()) + (int)(br.ReadByte())) / 8; heightdata[WIDTH - 1 - x, HEIGHT - 1 - y] = height; } }
ÀÌÁ¦ ¸ðµç vertex°¡ ÁغñµÇ¾ú½À´Ï´Ù¸¸, heightmap À̹ÌÁöÀÇ °¡·Î, ¼¼·Î Å©±â°¡ ÀÌÀüº¸´Ù ÈξÀ Ä¿Á³±â ¶§¹®¿¡ ±âÁ¸ Ä«¸Þ¶óÀÇ À§Ä¡¿¡¼´Â ÀüºÎ º¸ÀÌÁö ¾Ê½À´Ï´Ù. ¸Ö¸®¼ Àüü¸¦ ¹Ù¶óº¼ ¼ö ÀÖµµ·Ï SetupCameraÇÔ¼ö¿¡¼ Ä«¸Þ¶óÀÇ À§Ä¡¸¦ ¿Å±â°í Ä«¸Þ¶ó°¡ º¼ ¼ö ÀÖ´Â ÃÖ´ë °Å¸®µµ ´Ã·ÁÁÖµµ·Ï ÇսôÙ.
Matrix viewMatrix = Matrix.CreateLookAt(new Vector3(80.0f, 0.0f, 160.0f), new Vector3(-20.0f, 0.0f, 0.0f), new Vector3(0.0f, 0.0f, 1.0f)); Matrix projectionMatrix = Matrix.CreatePerspectiveFieldOfView(MathHelper.PiOver4, Window.ClientBounds.Width / Window.ClientBounds.Height, 1.0f, 250.0f);
ÀÌÁ¦ µð¹ö±×(F5)۸¦ ´·¯ ±× °á°ú¸¦ È®ÀÎÇØº¾½Ã´Ù.
- Website design & XNA + DirectX code : Riemer Grootjans - ©2003 - 2008 Riemer Grootjans
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2007 - 2008 MVP Award DirectX - XNA
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Support this site -- any amount is welcome !
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|