top of page

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:

​WoMA_Chap9.zip

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...

bottom of page