Vertex colours now uses the Ogre::Terrain colour map

This commit is contained in:
Jacob Essex 2012-03-02 11:56:51 +00:00
parent 611f336d07
commit 8dd6e75ae1
2 changed files with 34 additions and 117 deletions

View File

@ -2,8 +2,6 @@
#include <OgreTerrainGroup.h> #include <OgreTerrainGroup.h>
#include <OgreTerrainMaterialGeneratorA.h> #include <OgreTerrainMaterialGeneratorA.h>
#include <boost/lexical_cast.hpp>
#include "terrain.hpp" #include "terrain.hpp"
#include "components/esm/loadland.hpp" #include "components/esm/loadland.hpp"
@ -127,38 +125,29 @@ namespace MWRender
mLandSize*sizeof(float)); mLandSize*sizeof(float));
} }
//this should really be 33*33
Ogre::uchar* vertexColourAlpha = OGRE_ALLOC_T(Ogre::uchar,
mLandSize*mLandSize,
Ogre::MEMCATEGORY_GENERAL);
std::map<uint16_t, int> indexes; std::map<uint16_t, int> indexes;
initTerrainTextures(&terrainData, store, initTerrainTextures(&terrainData, store,
x * numTextures, y * numTextures, x * numTextures, y * numTextures,
numTextures, vertexColourAlpha, numTextures, indexes);
indexes);
assert( mTerrainGroup->getTerrain(cellX, cellY) == NULL && assert( mTerrainGroup->getTerrain(cellX, cellY) == NULL &&
"The terrain for this cell already existed" ); "The terrain for this cell already existed" );
mTerrainGroup->defineTerrain(terrainX, terrainY, &terrainData); mTerrainGroup->defineTerrain(terrainX, terrainY, &terrainData);
mTerrainGroup->loadTerrain(terrainX, terrainY, true); mTerrainGroup->loadTerrain(terrainX, terrainY, true);
Ogre::Terrain* terrain = mTerrainGroup->getTerrain(terrainX, terrainY); Ogre::Terrain* terrain = mTerrainGroup->getTerrain(terrainX, terrainY);
Ogre::Image vertexColourBlendMap = Ogre::Image();
vertexColourBlendMap.loadDynamicImage(vertexColourAlpha,
mLandSize, mLandSize, 1,
Ogre::PF_A8, true)
.resize(mTerrainGlobals->getLayerBlendMapSize(),
mTerrainGlobals->getLayerBlendMapSize(),
Ogre::Image::FILTER_BOX);
initTerrainBlendMaps(terrain, store, initTerrainBlendMaps(terrain, store,
x * numTextures, y * numTextures, x * numTextures, y * numTextures,
numTextures, numTextures,
vertexColourBlendMap.getData(),
indexes); indexes);
if ( store->land[1][1]->landData->usingColours )
{
Ogre::Image vertex = getVertexColours(store, x*32, y*32, mLandSize);
terrain->setGlobalColourMapEnabled(true);
terrain->getGlobalColourMap()->loadImage(vertex);
}
} }
} }
} }
@ -176,30 +165,25 @@ namespace MWRender
&store->land[1][1]->landData->heights[0], &store->land[1][1]->landData->heights[0],
mLandSize*mLandSize*sizeof(float)); mLandSize*mLandSize*sizeof(float));
Ogre::uchar* vertexColourAlpha = OGRE_ALLOC_T(Ogre::uchar,
mLandSize*mLandSize,
Ogre::MEMCATEGORY_GENERAL);
std::map<uint16_t, int> indexes; std::map<uint16_t, int> indexes;
initTerrainTextures(&terrainData, store, 0, 0, initTerrainTextures(&terrainData, store, 0, 0,
ESM::Land::LAND_TEXTURE_SIZE, vertexColourAlpha, indexes); ESM::Land::LAND_TEXTURE_SIZE, indexes);
mTerrainGroup->defineTerrain(cellX, cellY, &terrainData); mTerrainGroup->defineTerrain(cellX, cellY, &terrainData);
mTerrainGroup->loadTerrain(cellX, cellY, true); mTerrainGroup->loadTerrain(cellX, cellY, true);
Ogre::Terrain* terrain = mTerrainGroup->getTerrain(cellX, cellY); Ogre::Terrain* terrain = mTerrainGroup->getTerrain(cellX, cellY);
Ogre::Image vertexColourBlendMap = Ogre::Image();
vertexColourBlendMap.loadDynamicImage(vertexColourAlpha,
mLandSize, mLandSize, 1,
Ogre::PF_A8, true)
.resize(mTerrainGlobals->getLayerBlendMapSize(),
mTerrainGlobals->getLayerBlendMapSize(),
Ogre::Image::FILTER_BOX);
initTerrainBlendMaps(terrain, store, 0, 0, initTerrainBlendMaps(terrain, store, 0, 0,
ESM::Land::LAND_TEXTURE_SIZE, ESM::Land::LAND_TEXTURE_SIZE,
vertexColourBlendMap.getData(), indexes); indexes);
if ( store->land[1][1]->landData->usingColours )
{
Ogre::Image vertex = getVertexColours(store, 0, 0, mLandSize);
terrain->setGlobalColourMapEnabled(true);
terrain->getGlobalColourMap()->loadImage(vertex);
}
} }
mTerrainGroup->freeTemporaryResources(); mTerrainGroup->freeTemporaryResources();
@ -232,7 +216,6 @@ namespace MWRender
void TerrainManager::initTerrainTextures(Ogre::Terrain::ImportData* terrainData, void TerrainManager::initTerrainTextures(Ogre::Terrain::ImportData* terrainData,
MWWorld::Ptr::CellStore* store, MWWorld::Ptr::CellStore* store,
int fromX, int fromY, int size, int fromX, int fromY, int size,
Ogre::uchar* vertexColourAlpha,
std::map<uint16_t, int>& indexes) std::map<uint16_t, int>& indexes)
{ {
assert(store != NULL && "store must be a valid pointer"); assert(store != NULL && "store must be a valid pointer");
@ -298,20 +281,6 @@ namespace MWRender
} }
} }
} }
//add the vertex colour overlay
if ( store->land[1][1]->landData->usingColours )
{
//TODO sort the *4 bit
Ogre::TexturePtr vclr = getVertexColours(store, vertexColourAlpha, fromX*4, fromY*4, mLandSize);
Ogre::TexturePtr normDisp = getNormalDisp("DOES_NOT_EXIST");
const size_t position = terrainData->layerList.size();
terrainData->layerList.push_back(Ogre::Terrain::LayerInstance());
terrainData->layerList[position].worldSize = mRealSize;
terrainData->layerList[position].textureNames.push_back(vclr->getName());
terrainData->layerList[position].textureNames.push_back(normDisp->getName());
}
} }
//---------------------------------------------------------------------------------------------- //----------------------------------------------------------------------------------------------
@ -319,7 +288,6 @@ namespace MWRender
void TerrainManager::initTerrainBlendMaps(Ogre::Terrain* terrain, void TerrainManager::initTerrainBlendMaps(Ogre::Terrain* terrain,
MWWorld::Ptr::CellStore* store, MWWorld::Ptr::CellStore* store,
int fromX, int fromY, int size, int fromX, int fromY, int size,
Ogre::uchar* vertexColourAlpha,
const std::map<uint16_t, int>& indexes) const std::map<uint16_t, int>& indexes)
{ {
assert(store != NULL && "store must be a valid pointer"); assert(store != NULL && "store must be a valid pointer");
@ -345,16 +313,6 @@ namespace MWRender
->getBlendPointer(); ->getBlendPointer();
memset(pBlend, 0, sizeof(float) * blendSize * blendSize); memset(pBlend, 0, sizeof(float) * blendSize * blendSize);
} }
//except the overlay, which we will just splat over the top
if ( store->land[1][1]->landData->usingColours )
{
//the overlay is always the last texture layer
float* pBlend = terrain->getLayerBlendMap(terrain->getLayerCount() - 1)
->getBlendPointer();
for ( int i = 0; i < blendSize * blendSize; i++ ){
*pBlend++ = (*vertexColourAlpha++)/255.0f;
}
}
//covert the ltex data into a set of blend maps //covert the ltex data into a set of blend maps
for ( int texY = fromY - 1; texY < fromY + size + 1; texY++ ) for ( int texY = fromY - 1; texY < fromY + size + 1; texY++ )
@ -484,7 +442,8 @@ namespace MWRender
return texMgr->getByName(normalTextureName); return texMgr->getByName(normalTextureName);
} }
const std::string textureName = "default_terrain_normal"; if ( !texMgr->getByName(textureName).isNull() ) const std::string textureName = "default_terrain_normal";
if ( !texMgr->getByName(textureName).isNull() )
{ {
return texMgr->getByName(textureName); return texMgr->getByName(textureName);
} }
@ -512,38 +471,14 @@ namespace MWRender
//---------------------------------------------------------------------------------------------- //----------------------------------------------------------------------------------------------
Ogre::TexturePtr TerrainManager::getVertexColours(MWWorld::Ptr::CellStore* store, Ogre::Image TerrainManager::getVertexColours(MWWorld::Ptr::CellStore* store,
Ogre::uchar* alpha,
int fromX, int fromY, int size) int fromX, int fromY, int size)
{ {
Ogre::TextureManager* const texMgr = Ogre::TextureManager::getSingletonPtr();
const char* const colours = store->land[1][1]->landData->colours; const char* const colours = store->land[1][1]->landData->colours;
const std::string colourTextureName = "VtexColours_" + Ogre::uchar* imgData = OGRE_ALLOC_T(Ogre::uchar,
boost::lexical_cast<std::string>(store->cell->getGridX()) + size*size*sizeof(Ogre::uchar)*3,
"_" + Ogre::MEMCATEGORY_GENERAL);
boost::lexical_cast<std::string>(store->cell->getGridY()) +
"_" +
boost::lexical_cast<std::string>(fromX) +
"_" +
boost::lexical_cast<std::string>(fromY);
Ogre::TexturePtr tex = texMgr->getByName(colourTextureName);
if ( !tex.isNull() )
{
return tex;
}
tex = texMgr->createManual(colourTextureName,
Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME,
Ogre::TEX_TYPE_2D, size, size, 0, Ogre::PF_BYTE_BGRA);
Ogre::HardwarePixelBufferSharedPtr pixelBuffer = tex->getBuffer();
pixelBuffer->lock(Ogre::HardwareBuffer::HBL_NORMAL);
const Ogre::PixelBox& pixelBox = pixelBuffer->getCurrentLock();
Ogre::uint8* pDest = static_cast<Ogre::uint8*>(pixelBox.data);
for ( int y = 0; y < size; y++ ) for ( int y = 0; y < size; y++ )
{ {
@ -559,25 +494,18 @@ namespace MWRender
const unsigned char b = colours[colourOffset + 2]; const unsigned char b = colours[colourOffset + 2];
//as is the case elsewhere we need to flip the y //as is the case elsewhere we need to flip the y
const size_t imageOffset = (size - 1 - y)*size*4 + x*4; const size_t imageOffset = (size - 1 - y)*size*3 + x*3;
pDest[imageOffset + 0] = b; imgData[imageOffset + 0] = r;
pDest[imageOffset + 1] = g; imgData[imageOffset + 1] = g;
pDest[imageOffset + 2] = r; imgData[imageOffset + 2] = b;
pDest[imageOffset + 3] = 255; //Alpha, TODO this needs to be removed
const size_t alphaOffset = (size - 1 - y)*size + x;
if ( r == 255 && g == 255 && b == 255 ){
alpha[alphaOffset] = 0;
}else{
alpha[alphaOffset] = 128;
}
} }
} }
pixelBuffer->unlock(); Ogre::Image img;
img.loadDynamicImage(imgData, size, size, 1, Ogre::PF_R8G8B8, true);
return tex; return img;
} }
} }

View File

@ -74,16 +74,12 @@ namespace MWRender{
* @param fromX the ltex index in the current cell to start making the texture from * @param fromX the ltex index in the current cell to start making the texture from
* @param fromY the ltex index in the current cell to start making the texture from * @param fromY the ltex index in the current cell to start making the texture from
* @param size the size (number of splats) to get * @param size the size (number of splats) to get
* @param vertexColourAlpha this should be an empty array containing the number of
* vertexes in this terrain segment. It is filled with the
* alpha values for the vertex colours
* @param indexes a mapping of ltex index to the terrain texture layer that * @param indexes a mapping of ltex index to the terrain texture layer that
* can be used by initTerrainBlendMaps * can be used by initTerrainBlendMaps
*/ */
void initTerrainTextures(Ogre::Terrain::ImportData* terrainData, void initTerrainTextures(Ogre::Terrain::ImportData* terrainData,
MWWorld::Ptr::CellStore* store, MWWorld::Ptr::CellStore* store,
int fromX, int fromY, int size, int fromX, int fromY, int size,
Ogre::uchar* vertexColourAlpha,
std::map<uint16_t, int>& indexes); std::map<uint16_t, int>& indexes);
/** /**
@ -94,16 +90,11 @@ namespace MWRender{
* @param fromX the ltex index in the current cell to start making the texture from * @param fromX the ltex index in the current cell to start making the texture from
* @param fromY the ltex index in the current cell to start making the texture from * @param fromY the ltex index in the current cell to start making the texture from
* @param size the size (number of splats) to get * @param size the size (number of splats) to get
* @param vertexColourAlpha this should be an array containing the alpha values
* for the vertex colours. NOTE: This should be the
* size of a splat map, which is NOT the same size
* as retured from initTerrainTextures.
* @param indexes the mapping of ltex to blend map produced by initTerrainTextures * @param indexes the mapping of ltex to blend map produced by initTerrainTextures
*/ */
void initTerrainBlendMaps(Ogre::Terrain* terrain, void initTerrainBlendMaps(Ogre::Terrain* terrain,
MWWorld::Ptr::CellStore* store, MWWorld::Ptr::CellStore* store,
int fromX, int fromY, int size, int fromX, int fromY, int size,
Ogre::uchar* vertexColourAlpha,
const std::map<uint16_t, int>& indexes); const std::map<uint16_t, int>& indexes);
/** /**
@ -133,15 +124,13 @@ namespace MWRender{
* we have to generate them manually * we have to generate them manually
* *
* @param store the cell store for the given terrain cell * @param store the cell store for the given terrain cell
* @param vertexColourAlpha this should be an empty array containing the number of
* vertexes in this terrain segment. It is filled with the
* alpha values for the vertex colours
* @param fromX the *vertex* index in the current cell to start making texture from * @param fromX the *vertex* index in the current cell to start making texture from
* @param fromY the *vertex* index in the current cell to start making the texture from * @param fromY the *vertex* index in the current cell to start making the texture from
* @param size the size (number of vertexes) to get * @param size the size (number of vertexes) to get
*
* @TODO FIXME the return of this function possibly copies the image data
*/ */
Ogre::TexturePtr getVertexColours(MWWorld::Ptr::CellStore* store, Ogre::Image getVertexColours(MWWorld::Ptr::CellStore* store,
Ogre::uchar* alpha,
int fromX, int fromY, int size); int fromX, int fromY, int size);
}; };