​​Chap 9/100: A Flat Heightmap Terrain​
​
What I will Learn here?:
​On this Chapter we will know better the game area of level 1, this area is a square of 256 x 256, this ​almost flat terrain because of borders is automatic generated using code only, without a BMP (Height Map Terrain)
On this engine the Unity it's equal to one meter.
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​​​Note:
Try move you self and discover the margins of our flat world.
​​
​Let's check our current main source tree, except the LIBs:
​
Added source on White:
​
​│ Applicationclass.cpp
│ Applicationclass.h
│ counter.h
│ main.cpp
│ main.h
│
├───camera
│ cameraClass.cpp
│ cameraClass.h
│ frustumClass.cpp
│ frustumClass.h
│ positionClass.cpp
│ positionClass.h
│
├───game
│ playerClass.cpp
│ playerClass.h​
│​
├───graphics
│ spriteClass.cpp
│ spriteClass.h​
│ textClass.cpp
│ textClass.h
│ textFontClass.cpp
│ textFontClass.h
│
├───input
│ inputClass.cpp
│ inputClass.h
│
├───loader
│ objModelV2Class.cpp
│ objModelV2Class.h
│
├───shader
│ shaderClass.cpp
│ shaderClass.h
│
├───system
│ dx11Class.cpp
│ dx11class.h
│ SystemClass.cpp
│ SystemClass.h
│ xml_loader.cpp
│ xml_loader.h
│
└───terrain
terrainClass.cpp
terrainClass.h
terrainManagerClass.cpp
terrainManagerClass.h​
​
​
​​(main.h) ​
- Set for Chapter 9
​
​​​​​​​​​(terrainClass.cpp​)​​ - ​This class will be responsible to load and render all the terrain types on Part II of this Tutorial.
​ // ------------------------------------------------------------------------------------------------------------
// Create the structure to hold the height map data.
if (m_terrainType < TERRAIN_WITH_HEIGHT) {
m_heightMap_9 = NEW HeightMapType_9[m_terrainWidth * m_terrainHeight];
if(!m_heightMap_9)return false;
// Initialize the position in the image data buffer.
UINT k=0;
// Read the image data into the height map.
for(UINT j=0; j<m_terrainHeight; j++)
{
for(UINT i=0; i<m_terrainWidth; i++)
{
UINT index = (m_terrainWidth * j) + i; //m_terrainHeight?? or m_terrainWidth
m_heightMap_9[index].x = (float)i + xPos; //-m_terrainWidth/2; //:Center MAP 0,0: -m_terrainWidth/2
m_heightMap_9[index].y = -1.5f; // Height of terrain Margins
m_heightMap_9[index].z = (float)j + zPos; //-m_terrainHeight/2; //:Center MAP 0,0: -m_terrainHeight/2
k+=3;
}
}
}
​
​​​​​​​(terrainManagerClass.cpp​)​ - ​The Terrain Manager is a proxy between Application and the detail type of a specific terrain handled in terrainClass.
​
Loading a terrain Type:
​​
UINT terrainId=0;
// "terrainType" terrainId, TerrainIndexMap, scale, X,Z,Y
if (!LoadTerrain (terrainType, terrainId, 0, 5.0f, 0,0, -1)) // This "-1" is the height of the flat terrain
{MyMessageBox(L"Could not initialize the Terrain Map"); return false;}
​
Rendering our terrains, in this case we only have one Terrain:
​​
g_DirectX11->TurnZBufferOn();
for (UINT i=0; i<N_TERRAINS; i++)
{
{
IF_NOT_RETURN_FALSE ( RenderTerrain(i, fill_mode, !true) );
}
}
​​
​​​​​(applicationClass.cpp)​ - CHANGES
​
​Here we initialize our Terrain Manager Class:
​​
// [12] TERRAIN
//-----------------------------------------------------------------------------------------
#if TUTORIAL_CHAP >= 9 && defined (SCENE_TERRAIN)
if(!m_TerrainManager.Initialize ())
{MyMessageBox(L"Could not initialize the Terrain Object"); return false;}
#endif//
​
​
The swap is implemented here every 5 seconds, later on we can address it to the real time using 24h:
​
#if TUTORIAL_CHAP >= 7 && defined (SCENE_DYNAMICSKY)
static DWORD m_skyTime = timeGetTime(); // Absolute Time (Not Frame Time!)
if(timeGetTime() >= (m_skyTime + 5000)) // 1 Second = 1000 ms
{
m_skyTime = timeGetTime();
currentSky = (currentSky == 0) ? 1:0; // Action Here!
}
#endif//
​
The rendering of the new fixed water fround and terrain:
​​
// 2. 3D Fixed Water Ground:
//----------------------------------------------------------------------------------------------------------------------
g_deviceContext->RSSetState(m_DirectX11->m_rasterStateCullFront[FILL_MODE]);
#define GROUND_PATCH_SIZE 12
#define N_PATCHEs 5
#if (TUTORIAL_CHAP >= 4) && defined (SCENE_OBJMODEL) //Note: CH7 become world sand
for (int z=(int)m_Camera.m_positionZ/GROUND_PATCH_SIZE -N_PATCHEs; z < m_Camera.m_positionZ/GROUND_PATCH_SIZE +N_PATCHEs; z++)
{
for (int x=(int)m_Camera.m_positionX/GROUND_PATCH_SIZE -N_PATCHEs; x <= m_Camera.m_positionX/GROUND_PATCH_SIZE +N_PATCHEs; x++)
{
objModel.m_world._41 = (float)GROUND_PATCH_SIZE*x;
objModel.m_world._42 = -1.55f; // Height of our water!
objModel.m_world._43 = (float)GROUND_PATCH_SIZE*z;
if (m_Frustum.CheckSphere(objModel.m_world._41, 0, objModel.m_world._43, GROUND_PATCH_SIZE) ) //Because its faster than squar
{
objModel.render(pContext);
}
}
}
#endif//
// 3. 3D RENDERING: Terrain
//----------------------------------------------------------------------------------------------------------------------
#if TUTORIAL_CHAP >= 9 && defined (SCENE_TERRAIN)
m_TerrainManager.Render(FILL_SOLID);
#endif
​To navigate on source code:
User: public
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​Project Code:
​
​
​
​
​What's next?
​We will explorer how to render the Moon and the Sun as Billboard.
This will allow us, later on to move them in the sky...