top of page

​​Chap 11/100​Terrain with HEIGHT​​

​

What I will Learn here?:

​On this Chapter we will learn how to load a height map terrain.

​

​

​

​

​

​

​

​

​

​

​

​

​

​

​

​

​

​

​

​

​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 11

​

​​​​​​​​​​​​​​(applicationClass.cpp)​ ​​

​

​

Our Current Main Render Function : bool ApplicationClass::RenderGraphics()​

​
// Render 1 Full FRAME:
// ==================================================================================================================================
bool ApplicationClass::RenderGraphics()
// ==================================================================================================================================

{    static ID3D11DeviceContext* pContext = m_DirectX11->m_deviceContext;
   

    //----------------------------------------------------------------------------------------------------------------------
    // [1] CLEAR THE SCENE:
    //----------------------------------------------------------------------------------------------------------------------

    static float ClearColor[] = // Set color to clear the "back buffer":
    #if TUTORIAL_CHAP >= 016    //Fog
    {0.5f, 0.5f, 0.5f, 1.0f};
    #else
    {0.0f, 0.0f, 0.5f, 1.0f};   //Blue
    #endif//

    // Clear the "back buffer":
    pContext->ClearRenderTargetView(m_DirectX11->m_renderTargetView, ClearColor);

    // Clear the "depth buffer":
    pContext->ClearDepthStencilView(m_DirectX11->m_depthStencilView, D3D10_CLEAR_DEPTH, 1.0f, 0);


    //----------------------------------------------------------------------------------------------------------------------
    // [2] CONSTRUCT FRUSTRUM: Construct the frustum based on the view and projection matrix.
    //----------------------------------------------------------------------------------------------------------------------

#if TUTORIAL_CHAP >= 6
    m_Frustum.ConstructFrustum(g_SCREEN_DEPTH, g_projectionMatrix, g_viewMatrix);
#endif//


    //#############################################################################################################
    //      3D    
    //#############################################################################################################

    // 1. 3D RENDERING: SKY
    //----------------------------------------------------------------------------------------------------------------------

    #if TUTORIAL_CHAP >= 7
    RenderSky();
    #endif


    // 2. 3D Fixed Infinite Terrain / Water:
    //----------------------------------------------------------------------------------------------------------------------

    #if TUTORIAL_CHAP >= 4
    InfiniteFixedTerraniWater();
    #endif


    // 3. 3D RENDERING: Terrain
    //----------------------------------------------------------------------------------------------------------------------

#if TUTORIAL_CHAP >= 9 && defined (SCENE_TERRAIN)
    pContext->ClearDepthStencilView(m_DirectX11->m_depthStencilView, D3D10_CLEAR_DEPTH, 1.0f, 0);
    m_TerrainManager.Render(FILL_SOLID);
#endif


    //#############################################################################################################
    //      2D    
    //#############################################################################################################

#if TUTORIAL_CHAP >= 7
    m_DirectX11->TurnZBufferOff();        //Need
    m_DirectX11->TurnOnAlphaBlending(); //need
#endif


    // 2D SPRITES: MAIN MAP
    //----------------------------------------------------------------------------------------------------------------------
    //


    { //else

    // 13. SPRITE: BANNER title
    //----------------------------------------------------------------------------------------------------------------------

    pContext->RSSetState(m_DirectX11->m_rasterStateCullBack[FILL_SOLID]); // RESET
#if TUTORIAL_CHAP >= 7 && defined (SCENE_BANNER)// BANNER 2D TITLE:
    IF_NOT_RETURN_FALSE ( m_BannerSprite.RenderRotY (pContext, (g_ScreenWidth - m_BannerSprite.m_bitmapWidth)/2, 0, m_scale) );
#endif//


    // XP BAR:
    //----------------------------------------------------------------------------------------------------------------------

​
    // BAG:
    //----------------------------------------------------------------------------------------------------------------------

    }


    // 14. 2D SPRITES: 2D TEXT elements
    //----------------------------------------------------------------------------------------------------------------------

#if TUTORIAL_CHAP >= 8
    IF_NOT_RETURN_FALSE ( m_Text.Render() );
#endif//


    //----------------------------------------------------------------------------------------------------------------------
    // [6] PRINT THE 3D SCENE TO SCREEN, Swap Chain or wait from VSYNC refresh rate, if it is the case
    //----------------------------------------------------------------------------------------------------------------------

    m_DirectX11->m_swapChain->Present(g_VSYNC_ENABLED, 0);

    return true;
}
​

​

​RenderGraphics invoke RenderSky():

 

void ApplicationClass::RenderSky ()
{
static ID3D11DeviceContext* pContext = m_DirectX11->m_deviceContext;


    // 1. 3D RENDERING: SKY
    //----------------------------------------------------------------------------------------------------------------------

#if TUTORIAL_CHAP >= 7
   
    g_deviceContext->RSSetState(m_DirectX11->m_rasterStateCullBack[FILL_MODE]);
    // Generate the view matrix based on the camera's position.
    m_CameraSKY.m_rotationY = m_Camera.m_rotationY;
    m_CameraSKY.m_rotationX = m_Camera.m_rotationX;
    m_CameraSKY.Render();
    m_CameraSKY.GetViewMatrix(g_viewMatrixSKY);    // Get the world, view, projection, and ortho matrices from the camera and SKY object.

    #if defined (SCENE_CLEANSKY)
    skyModel[currentSky].render(pContext);
    #endif
#endif//


    // 1. 3D RENDERING: MOON or SUN as a Single Billboard
    //----------------------------------------------------------------------------------------------------------------------

#if TUTORIAL_CHAP >= 10 && defined (SCENE_SUN_MOON)
   
    D3DXMATRIX translateMatrix = g_identMatrix;
    translateMatrix._11 = translateMatrix._22 = translateMatrix._33 = 5 * g_skySize;
    if (currentSky == 1)
    {
        translateMatrix._41 = 0;
        translateMatrix._42 = 32*g_skySize; // Height of Moon on horizon
        translateMatrix._43 = g_SCREEN_DEPTH * g_skySize -15; // Set Moon at "North"

        D3DXMatrixRotationY(&m_MoonBill.m_world, atan2(translateMatrix._41, translateMatrix._43));
        D3DXMatrixMultiply(&m_MoonBill.m_world, &m_MoonBill.m_world, &translateMatrix);        // Finally combine the rotation and translation matrices
        m_MoonBill.render(pContext);
    } else {
        translateMatrix._41 = g_SCREEN_DEPTH/6; // Set Sun at "Este"
        translateMatrix._42 = 12; // Height of Sun on horizon
        translateMatrix._43 = 0;

        m_DirectX11->TurnOnAlphaBlending(); //need to mask Sun
        D3DXMatrixRotationY(&m_SunBill.m_world, atan2(translateMatrix._41, translateMatrix._43));
        D3DXMatrixMultiply(&m_SunBill.m_world, &m_SunBill.m_world, &translateMatrix);        // Finally combine the rotation and translation matrices
        m_SunBill.render(pContext, 0, false);
        m_DirectX11->TurnOffAlphaBlending(); //not needed any more
    }
#endif//
}

 

RenderGraphics invoke InfiniteFixedTerraniWater()​

 

void ApplicationClass::InfiniteFixedTerraniWater ()
{
static ID3D11DeviceContext* pContext = m_DirectX11->m_deviceContext;

    #if TUTORIAL_CHAP >= 7
    m_DirectX11->TurnZBufferOn();        //Z Buffer Needed to be used: To make sure that moon is allways after Terrain
    #endif


    // 2. 3D Fixed Infinite Water:
    //----------------------------------------------------------------------------------------------------------------------
#if (TUTORIAL_CHAP == 4)  && defined (SCENE_OBJMODEL)
    pContext->RSSetState(m_DirectX11->m_rasterStateCullNone[FILL_SOLID]); // RESET
    objModel.render(pContext);
#endif//
#if (TUTORIAL_CHAP == 5)  && defined (SCENE_OBJMODEL)
    pContext->RSSetState(m_DirectX11->m_rasterStateCullNone[FILL_SOLID]); // RESET
    for (float z=g_INIT_CAMZ+2; z < g_INIT_CAMZ+5; z++) {
        for (float x=g_INIT_CAMX-2; x <= g_INIT_CAMX+2; x++) {
            objModel.m_world._41 = 4*x;
            objModel.m_world._42 = 0;
            objModel.m_world._43 = 4*z;
            objModel.render(pContext);
        }
    }
#endif//
#if TUTORIAL_CHAP >= 6 && TUTORIAL_CHAP <= 8 && defined (SCENE_OBJMODEL)
    pContext->RSSetState(m_DirectX11->m_rasterStateCullNone[FILL_SOLID]); // RESET
    #define GROUND_PATCH_SIZE 4
    #define N_PATCHEs 6
    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 = 0;
            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//

#if TUTORIAL_CHAP >= 9 && defined (SCENE_OBJMODEL) //Note: CH7 become world sand
    g_deviceContext->RSSetState(m_DirectX11->m_rasterStateCullFront[FILL_MODE]);
    #define GROUND_PATCH_SIZE 12
    #define N_PATCHEs 10

    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 = -0.5f;   // Height of our water!
            objModel.m_world._43 = (float)GROUND_PATCH_SIZE*z;
            #if TUTORIAL_CHAP >= 6
            if (m_Frustum.CheckSphere(objModel.m_world._41, 0, objModel.m_world._43, GROUND_PATCH_SIZE) ) //Because its faster than squar
            #endif
            {
                objModel.render(pContext);
            }
        }
    }
#endif//
}

 

​

​(terrainClass.cpp)​ ​​- The relevant changes here is LoadHeightMap(char* filename, float xPos, float zPos)

​The Function responsible for load BMP and transform it into a verttex array.

​

​​

​Project Code:

​

http://woma.no-ip.org/woma/WoMA_PartII_Chap11.zip

 

​What's next?

On next tutorial we will see how to add a light source to our terrain

bottom of page