mirror of
https://gitlab.com/OpenMW/openmw.git
synced 2025-09-28 22:51:05 -04:00
Vertex colours now uses the Ogre::Terrain colour map
This commit is contained in:
parent
611f336d07
commit
8dd6e75ae1
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user