📄 mapsplatter.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
MapSplatter.cpp
@brief
Utility that pre-calculate splating by
pre-calculating coverage map, A Color Map and a Base Map.
*/
#include "MapUtil.h"
#include "MapSplatter.h"
#include "OgrePagingLandScapeOptions.h"
#include <iostream>
namespace Ogre
{
//----------------------------------------------------------------------
MapSplatter::MapSplatter()
{
reset();
}
//----------------------------------------------------------------------
MapSplatter::~MapSplatter()
{
}
//----------------------------------------------------------------------
Image *MapSplatter::getBaseMap()
{
CalcMapSplats ();
mAlreadyComputed = true;
return &BaseMap;
}
//----------------------------------------------------------------------
Image *MapSplatter::getCoverageMap()
{
CalcMapSplats ();
return &CoverageMap;
}
//----------------------------------------------------------------------
Image *MapSplatter::getColorMap()
{
CalcMapSplats ();
return &ColorMap;
}
//----------------------------------------------------------------------
Image *MapSplatter::getAlphaMap(uint i)
{
CalcMapSplats ();
return &destAlphaMap[i];
}
//----------------------------------------------------------------------
Image *MapSplatter::getRGBMap(uint i)
{
CalcMapSplats ();
return &destRGBMap[i];
}
//----------------------------------------------------------------------
void MapSplatter::reset()
{
mAlreadyComputed = false;
}
//----------------------------------------------------------------------
void MapSplatter::CalcMapSplats()
{
if (mAlreadyComputed)
return;
matColor[0] = PagingLandScapeOptions::getSingleton().matColor[0];
matColor[1] = PagingLandScapeOptions::getSingleton().matColor[1];
matColor[2] = PagingLandScapeOptions::getSingleton().matColor[2];
matColor[3] = PagingLandScapeOptions::getSingleton().matColor[3];
mScale = PagingLandScapeOptions::getSingleton().scale;
matHeight[0] = PagingLandScapeOptions::getSingleton().matHeight[0];
matHeight[1] = PagingLandScapeOptions::getSingleton().matHeight[1];
mHeight = MapUtil::getSingleton().getMapHeight ();
mWidth = MapUtil::getSingleton().getMapWidth ();
std::cout << "Loading Splats Maps \n";
//snow = 0
MapUtil::getSingleton().load(PagingLandScapeOptions::getSingleton().Splat_Filename_0,
&SplatMap[0]);
//sand = 1
MapUtil::getSingleton().load(PagingLandScapeOptions::getSingleton().Splat_Filename_1,
&SplatMap[1]);
//grass = 2
MapUtil::getSingleton().load(PagingLandScapeOptions::getSingleton().Splat_Filename_2,
&SplatMap[2]);
//rock = 3
MapUtil::getSingleton().load(PagingLandScapeOptions::getSingleton().Splat_Filename_3,
&SplatMap[3]);
bool b_Base = PagingLandScapeOptions::getSingleton().BaseMap ||
PagingLandScapeOptions::getSingleton().LitColorMapGenerate;
bool b_RGB = PagingLandScapeOptions::getSingleton().RGBMaps;
bool b_Color = PagingLandScapeOptions::getSingleton().ColorMapGenerate ||
PagingLandScapeOptions::getSingleton().LitColorMapGenerate;
bool b_Alpha = PagingLandScapeOptions::getSingleton().AlphaMaps ||
PagingLandScapeOptions::getSingleton().AlphaSplatLightMaps ||
PagingLandScapeOptions::getSingleton().AlphaSplatRGBAMaps;
bool b_Coverage = PagingLandScapeOptions::getSingleton().CoverageMap;
DataChunk dc;
uint size4;
uint size3;
uint size1;
size1 = mWidth * mHeight;
size3 = size1 + size1 + size1;
size4 = size3 + size1;
uchar *BaseData;
uchar *ColorData;
uchar *CoverageData;
uchar *destAlphaMapData0;
uchar *destAlphaMapData1;
uchar *destAlphaMapData2;
uchar *destAlphaMapData3;
uchar *destRGBMapData0;
uchar *destRGBMapData1;
uchar *destRGBMapData2;
uchar *destRGBMapData3;
uint p2width = mWidth - 1;
uint p2height = mHeight - 1;
if (b_Base)
{
std::cout << "Base ";
// Create the base image
dc.allocate(size4);
BaseMap.loadRawData(dc, p2width, p2height, PF_A8R8G8B8);
dc.clear();
BaseData = BaseMap.getData();
}
if (b_Color)
{
std::cout << "Color ";
// Create the color texture
dc.allocate(size3);
ColorMap.loadRawData(dc, p2width, p2height, PF_R8G8B8);
dc.clear();
ColorData = ColorMap.getData();
}
if (b_Coverage)
{
std::cout << "Coverage ";
dc.allocate(size4);
CoverageMap.loadRawData(dc, p2width, p2height, PF_A8R8G8B8);
dc.clear();
CoverageData = CoverageMap.getData();
}
if (b_Alpha)
{
std::cout << "Alpha ";
// alpha maps used as coverage
//without having to decompose it in real-time
dc.allocate(size1);
memset(dc.getPtr (), 0, size1);
// create transparent Alpha images
// loadRawData does allocate and memcpy data, so no need
// to reallocate a new pointer using DC
destAlphaMap[0].loadRawData(dc, p2width, p2height, PF_A8);
destAlphaMap[1].loadRawData(dc, p2width, p2height, PF_A8);
destAlphaMap[2].loadRawData(dc, p2width, p2height, PF_A8);
destAlphaMap[3].loadRawData(dc, p2width, p2height, PF_A8);
dc.clear();
destAlphaMapData0 = destAlphaMap[0].getData ();
destAlphaMapData1 = destAlphaMap[1].getData ();
destAlphaMapData2 = destAlphaMap[2].getData ();
destAlphaMapData3 = destAlphaMap[3].getData ();
}
if (b_RGB)
{
std::cout << "RGB ";
// rgb maps used as coverage
// without having to decompose it in real-time
// actually they are gray images...
dc.allocate(size3);
// create back rgb images
// loadRawData does allocate and memcpy data, so no need
// to reallocate a new pointer using DC
destRGBMap[0].loadRawData(dc, p2width, p2height, PF_R8G8B8);
destRGBMap[1].loadRawData(dc, p2width, p2height, PF_R8G8B8);
destRGBMap[2].loadRawData(dc, p2width, p2height, PF_R8G8B8);
destRGBMap[3].loadRawData(dc, p2width, p2height, PF_R8G8B8);
dc.clear();
destRGBMapData0 = destRGBMap[0].getData ();
destRGBMapData1 = destRGBMap[1].getData ();
destRGBMapData2 = destRGBMap[2].getData ();
destRGBMapData3 = destRGBMap[3].getData ();
}
// each splatting texture can have different
// height, width and pixel size
uchar *SplatMapData0 = SplatMap[0].getData();
uchar *SplatMapData1 = SplatMap[1].getData();
uchar *SplatMapData2 = SplatMap[2].getData();
uchar *SplatMapData3 = SplatMap[3].getData();
uint SplatMapWidth0 = (uint) SplatMap[0].getWidth ();
uint SplatMapWidth1 = (uint) SplatMap[1].getWidth ();
uint SplatMapWidth2 = (uint) SplatMap[2].getWidth ();
uint SplatMapWidth3 = (uint) SplatMap[3].getWidth ();
uint SplatMapHeight0 = (uint) SplatMap[0].getHeight ();
uint SplatMapHeight1 = (uint) SplatMap[1].getHeight ();
uint SplatMapHeight2 = (uint) SplatMap[2].getHeight ();
uint SplatMapHeight3 = (uint) SplatMap[3].getHeight ();
uint SplatMapbpp0 = (uint) SplatMap[0].getNumElemBytes (SplatMap[0].getFormat ());
uint SplatMapbpp1 = (uint) SplatMap[1].getNumElemBytes (SplatMap[1].getFormat ());
uint SplatMapbpp2 = (uint) SplatMap[2].getNumElemBytes (SplatMap[2].getFormat ());
uint SplatMapbpp3 = (uint) SplatMap[3].getNumElemBytes (SplatMap[3].getFormat ());
bool bSplatMap0NotUsed, bSplatMap1NotUsed, bSplatMap2NotUsed, bSplatMap3NotUsed;
bSplatMap0NotUsed = bSplatMap1NotUsed = bSplatMap2NotUsed = bSplatMap3NotUsed = true;
uint SplatMap_index_pixel0 = 0;
uint SplatMap_index_pixel1 = 0;
uint SplatMap_index_pixel2 = 0;
uint SplatMap_index_pixel3 = 0;
uint index_1pixel = 0;
uint index_3pixel = 0;
uint index_4pixel = 0;
// This texture will be used as a base color for the terrain,
// it will fake the splat for distant renderables.
std::cout << "Map Calc : ";
uint j = 0;
while (j < p2height)
{
DEBUG_PROGRESS_OUTPUT(".")
uint i = 0;
while (i < p2width)
{
ColourValue color;
Real alpha0, alpha1, alpha2, alpha3;
// calculate value using height and slope
BuildPoint( color, i, j, alpha0, alpha1, alpha2, alpha3);
uchar inv_alpha = uchar (( 1.0 - ( alpha0 + alpha1 + alpha2 + alpha3 ) ) * 255.0f);
if (b_Base)
{
BaseData[index_4pixel + 0] = uchar (color.r * 255.0f); //Red
BaseData[index_4pixel + 1] = uchar (color.g * 255.0f); //Green
BaseData[index_4pixel + 2] = uchar (color.b * 255.0f); //Blue
BaseData[index_4pixel + 3] = inv_alpha; // Alpha (Opaque)
}
// MUST SAVE A BASE WITHOUT ALPHA !!!!!!!!
if (b_Color)
{
//Red
ColorData[index_3pixel] = uchar (color.r * inv_alpha +
SplatMapData0[SplatMap_index_pixel0] * alpha0 +
SplatMapData1[SplatMap_index_pixel1] * alpha1 +
SplatMapData2[SplatMap_index_pixel2] * alpha2 +
SplatMapData3[SplatMap_index_pixel3] * alpha3);
//Green
ColorData[index_3pixel + 1] = uchar (color.g * inv_alpha +
SplatMapData0[SplatMap_index_pixel0 + 1] * alpha0 +
SplatMapData1[SplatMap_index_pixel1 + 1] * alpha1 +
SplatMapData2[SplatMap_index_pixel2 + 1] * alpha2 +
SplatMapData3[SplatMap_index_pixel3 + 1] * alpha3);
//Blue
ColorData[index_3pixel + 2] = uchar (color.b * inv_alpha +
SplatMapData0[SplatMap_index_pixel0 + 2] * alpha0 +
SplatMapData1[SplatMap_index_pixel1 + 2] * alpha1 +
SplatMapData2[SplatMap_index_pixel2 + 2] * alpha2 +
SplatMapData3[SplatMap_index_pixel3 + 2] * alpha3);
}
// Generate the alpha map 1
if (bSplatMap0NotUsed && alpha0 - 0.05f > 0)
bSplatMap0NotUsed = false;
// Generate the alpha map 2
if (bSplatMap1NotUsed && alpha1 - 0.05f > 0)
bSplatMap1NotUsed = false;
// Generate the alpha map 3
if (bSplatMap2NotUsed && alpha2 - 0.05f > 0)
bSplatMap2NotUsed = false;
// Generate the alpha map 4
if (bSplatMap3NotUsed && alpha3 - 0.05f > 0 )
bSplatMap3NotUsed = false;
uchar splat1 = uchar (alpha0*255.0f);
uchar splat2 = uchar (alpha1*255.0f);
uchar splat3 = uchar (alpha2*255.0f);
uchar splat4 = uchar (alpha3*255.0f);
if (b_Coverage)
{
CoverageData[index_4pixel] = splat1;// stored as Red
CoverageData[index_4pixel + 1] = splat2;// stored as Green
CoverageData[index_4pixel + 2] = splat3;// stored as Blue
CoverageData[index_4pixel + 3] = splat4;// stored as Alpha
}
if (b_Alpha)
{
destAlphaMapData0[index_1pixel] = splat1;
destAlphaMapData1[index_1pixel] = splat2;
destAlphaMapData2[index_1pixel] = splat3;
destAlphaMapData3[index_1pixel] = splat4;
}
if (b_RGB)
{
destRGBMapData0[index_3pixel] = splat1;
destRGBMapData0[index_3pixel + 1] = splat1;
destRGBMapData0[index_3pixel + 2] = splat1;
destRGBMapData1[index_3pixel] = splat2;
destRGBMapData1[index_3pixel + 1] = splat2;
destRGBMapData1[index_3pixel + 2] = splat2;
destRGBMapData2[index_3pixel] = splat3;
destRGBMapData2[index_3pixel + 1] = splat3;
destRGBMapData2[index_3pixel + 2] = splat3;
destRGBMapData3[index_3pixel] = splat4;
destRGBMapData3[index_3pixel + 1] = splat4;
destRGBMapData3[index_3pixel + 2] = splat4;
}
index_4pixel += 4;
index_3pixel += 3;
index_1pixel += 1;
// don't move it a the end
// it will false following computation
// of position in splats maps
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -