⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 maplighter.cpp

📁 使用stl技术,(还没看,是听说的)
💻 CPP
字号:
/***************************************************************************
*                                                                         *
*   This program is free software; you can redistribute it and/or modify  *
*   it under the terms of the GNU Lesser General Public License as        *
*   published by the Free Software Foundation; either version 2 of the    *
*   License, or (at your option) any later version.                       *
*                                                                         *
***************************************************************************/
/**
@file 
MapLighter.cpp
@brief
Utility that pre-calculate light map.
*/
#include "MapUtil.h"
#include "MapLighter.h"
#include "MapBlurrer.h"
#include "OgrePagingLandScapeOptions.h"

#include <iostream>

namespace Ogre
{
//----------------------------------------------------------------------
MapLighter::MapLighter()
{
    reset();
}
//----------------------------------------------------------------------
MapLighter::~MapLighter()
{
   
}
//----------------------------------------------------------------------
void MapLighter::reset()
{
    mAlreadyComputed = false;
}
//----------------------------------------------------------------------
Image *MapLighter::getShadowMap(const Vector3 &sun, float amb, float diff, 
                                int Blur)
{
    if (mAlreadyComputed)
        return &mShadowMap;

    CalcMapShadow (sun);
    CalcMapLight (sun, amb, diff, Blur);
    mAlreadyComputed = true;

    return &mShadowMap;
}
//----------------------------------------------------------------------
Image *MapLighter::getLightMap(const Vector3 &sun, float amb, float diff, 
                               int Blur)
{
    if (mAlreadyComputed)
        return &mLightMap;

    CalcMapShadow (sun);
    CalcMapLight (sun, amb, diff, Blur);

    mAlreadyComputed = true;
    return &mLightMap;
}



//----------------------------------------------------------------------
void MapLighter::CalcMapShadow (const Vector3 &sun)
{
    uint  height = MapUtil::getSingleton().getMapHeight () - 1;
    uint  width = MapUtil::getSingleton().getMapWidth () - 1;
    uchar *heightMap = MapUtil::getSingleton().getHeightMapData ();

    std::cout << "Shadow Map Calc : ";

    /* Allocate space for the shadow map */
    DataChunk dc;
    dc.allocate(width * height * 1);
    memset (dc.getPtr (), 0, dc.getSize ());
    // Assign the color texture
    mShadowMap.loadRawData (dc, width, height, PF_L8);
    dc.clear();
    uchar *ShadowMap = mShadowMap.getData();

    /* Make sure the light source is normalised */
    Vector3 LightDirection = sun;

    //LightDirection.x /= PagingLandScapeOptions::getSingleton().scale.x;
    // LightDirection.y /= PagingLandScapeOptions::getSingleton().scale.y;
    //LightDirection.z /= PagingLandScapeOptions::getSingleton().scale.z;

    LightDirection.normalise ();

    if (LightDirection.y == 0.0f ) 
        // || (LightDirection.x == 0.0f && LightDirection.x == 0.0f )
    {
        /* light vector horizontal*/
        /* all in shadow */
        return;
    }

    /* For each heightmap location */ 
    uint index_pixel = 0;
    for (uint j = 0; j < height; j++) 
     { 
        DEBUG_PROGRESS_OUTPUT(".")
        for (uint i = 0; i < width; i++) 
        {
            /* If already in shadow no need to compute again ?
             what if we store precise height at which it is not shadowed ?*/
            if (ShadowMap[index_pixel] == 0)
            {
                /* a line passing starting from heightmap point 
                    and following light direction*/
                Real terrain_height = heightMap[ index_pixel ];
                    
                if (fabs(LightDirection.x) < fabs(LightDirection.z))
                { 
                    int index_z = 1;
                    float index_x = LightDirection.x / LightDirection.z;
                    float index_y = LightDirection.y / LightDirection.z;
                    if (LightDirection.z < 0) 
                    {
                        index_x = -index_x; 
                        index_y = -index_y;
                        index_z = -index_z; 
                    }
                    int z = j + index_z;
                    float x = i + index_x;
                    terrain_height += index_y;
                    uint zmap = ((uint)z);
                    uint xmap = ((uint)x);
                    while  (terrain_height >= 0.0f &&
                            xmap < width &&
                            zmap < height)
                    {        
                        if ((zmap < height) && 
                             heightMap[xmap + zmap*(width)] <= terrain_height)
                             ShadowMap[xmap + (zmap*width)] = 255; 
                    
                        x += index_x;
                        z += index_z;
                        terrain_height += index_y;

                        zmap = ((uint)z);
                        xmap = ((uint)x);
                     }
                }
                else 
                {
                    int index_x = 1;
                    float index_z = LightDirection.z / LightDirection.x;
                    float index_y = LightDirection.y / LightDirection.x;
                    if (LightDirection.x < 0) 
                    {
                        index_x = -index_x;  
                        index_y = -index_y;
                        index_z = -index_z;
                    }

                    float z = j + index_z;
                    int x = i + index_x;
                    terrain_height += index_y;
                    uint zmap = ((uint)z);
                    uint xmap = ((uint)x);
                    while (terrain_height >= 0.0f &&
                            xmap < width &&
                            zmap < height)
                    {
                        if ((zmap < height) && 
                            heightMap[xmap + zmap*(width)] <= terrain_height)
                            ShadowMap[xmap + (zmap*width)] = 255;   
                        x += index_x; 
                        z += index_z;
                        terrain_height += index_y;
                        zmap = ((uint)z);
                        xmap = ((uint)x);
                    }
                 }
            }
            index_pixel++;
        }
    }

    std::cout << "\n";
}


//----------------------------------------------------------------------
void MapLighter::CalcMapLight(const Vector3 &sun, float amb, float diff, 
                              int Blur)
    {
    Vector3 LightDirection;
    uchar *ShadowMap = mShadowMap.getData ();
    uint  height = MapUtil::getSingleton().getMapHeight () - 1;
    uint  width = MapUtil::getSingleton().getMapWidth () - 1;

    std::cout << "light Map Calc : ";

    // Create the base image
    DataChunk dc;
    dc.allocate(width * height * 1);
    memset (dc.getPtr (), 0, dc.getSize ());
    // Assign the color texture
    mLightMap.loadRawData(dc, width, height, PF_L8);
    dc.clear();

    uchar *LightMapData = mLightMap.getData();
    /* Make sure the light source is normalised */
    LightDirection = sun;  

    //LightDirection.x /= PagingLandScapeOptions::getSingleton().scale.x;
    //LightDirection.y /= PagingLandScapeOptions::getSingleton().scale.y;
    //LightDirection.z /= PagingLandScapeOptions::getSingleton().scale.z;

    LightDirection.normalise ();
    LightDirection = LightDirection * -1.0f;


    const float scaleShadow = 1.0f / 255.0f;
    uint index_pixel = 0;
    /* For each point */
    for (uint j = 0; j < height; j++) 
     {
        /* Show progress */
        DEBUG_PROGRESS_OUTPUT(".")
        for (uint i = 0; i < width; i++) 
        {
            /* Get the dot product with the light source direction */
            Vector3 normal = MapUtil::getSingleton ().getNormalAt (i, j);
            float d = LightDirection.dotProduct (normal);
            if (d < 0.0f)
                d = 0.0f;

            /* Calculate illumination model (ambient plus diffuse) */
            float s = 1.0f - scaleShadow * ShadowMap[index_pixel];
            float l = amb + s * d * diff;
            if (l < 0.0f)
                l = 0.0f;
            else 
                if (l > 1.0f)
                l = 1.0f;

            /* Save in light map */
            LightMapData[index_pixel] = (uchar)(l * 255.0f);
            index_pixel++;
        }
     }

    std::cout << "\n";
    /* Blur the light map */  
    if (Blur > 0)
    {
        MapBlurrer Blurrer;
        Blurrer.gaussianBlur(&mLightMap, Blur);
    }

}
}//namespace Ogre

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -