From 1d0ae9c8d122ea168b9515bb696a74e6d8c9aa05 Mon Sep 17 00:00:00 2001 From: Jacob Essex Date: Wed, 29 Feb 2012 23:05:22 +0000 Subject: [PATCH 1/4] Start of a basic implementation of fake vertex colours --- apps/openmw/mwrender/terrain.cpp | 146 ++++++++++++++++++++++++++++--- apps/openmw/mwrender/terrain.hpp | 26 +++++- components/esm/loadland.cpp | 5 +- components/esm/loadland.hpp | 2 + 4 files changed, 167 insertions(+), 12 deletions(-) diff --git a/apps/openmw/mwrender/terrain.cpp b/apps/openmw/mwrender/terrain.cpp index 710a3ad05e..89c362c4cd 100644 --- a/apps/openmw/mwrender/terrain.cpp +++ b/apps/openmw/mwrender/terrain.cpp @@ -2,6 +2,8 @@ #include #include +#include + #include "terrain.hpp" #include "components/esm/loadland.hpp" @@ -104,6 +106,9 @@ namespace MWRender const int terrainX = cellX * 2 + x; const int terrainY = cellY * 2 + y; + //it makes far more sense to reallocate the memory here, + //and let Ogre deal with it due to the issues with deleting + //it at the wrong time if using threads (Which Ogre::Terrain does) terrainData.inputFloat = OGRE_ALLOC_T(float, mLandSize*mLandSize, Ogre::MEMCATEGORY_GEOMETRY); @@ -122,10 +127,16 @@ namespace MWRender mLandSize*sizeof(float)); } + //this should really be 33*33 + Ogre::uchar* vertexColourAlpha = OGRE_ALLOC_T(Ogre::uchar, + mLandSize*mLandSize, + Ogre::MEMCATEGORY_GENERAL); + std::map indexes; initTerrainTextures(&terrainData, store, x * numTextures, y * numTextures, - numTextures, indexes); + numTextures, vertexColourAlpha, + indexes); assert( mTerrainGroup->getTerrain(cellX, cellY) == NULL && "The terrain for this cell already existed" ); @@ -133,9 +144,20 @@ namespace MWRender mTerrainGroup->loadTerrain(terrainX, terrainY, true); 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, x * numTextures, y * numTextures, - numTextures, indexes); + numTextures, + vertexColourBlendMap.getData(), + indexes); } } @@ -154,16 +176,30 @@ namespace MWRender &store->land[1][1]->landData->heights[0], mLandSize*mLandSize*sizeof(float)); + Ogre::uchar* vertexColourAlpha = OGRE_ALLOC_T(Ogre::uchar, + mLandSize*mLandSize, + Ogre::MEMCATEGORY_GENERAL); + std::map indexes; initTerrainTextures(&terrainData, store, 0, 0, - ESM::Land::LAND_TEXTURE_SIZE, indexes); + ESM::Land::LAND_TEXTURE_SIZE, vertexColourAlpha, indexes); mTerrainGroup->defineTerrain(cellX, cellY, &terrainData); mTerrainGroup->loadTerrain(cellX, cellY, true); 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, - ESM::Land::LAND_TEXTURE_SIZE, indexes); + ESM::Land::LAND_TEXTURE_SIZE, + vertexColourBlendMap.getData(), indexes); } mTerrainGroup->freeTemporaryResources(); @@ -196,6 +232,7 @@ namespace MWRender void TerrainManager::initTerrainTextures(Ogre::Terrain::ImportData* terrainData, MWWorld::Ptr::CellStore* store, int fromX, int fromY, int size, + Ogre::uchar* vertexColourAlpha, std::map& indexes) { assert(store != NULL && "store must be a valid pointer"); @@ -227,7 +264,7 @@ namespace MWRender { //NB: All vtex ids are +1 compared to the ltex ids assert((int)ltexIndex >= 0 && - store->landTextures->ltex.size() > (size_t)ltexIndex - 1 && + (int)store->landTextures->ltex.size() >= (int)ltexIndex - 1 && "LAND.VTEX must be within the bounds of the LTEX array"); std::string texture; @@ -262,6 +299,17 @@ namespace MWRender } } } + + //add the vertex colour overlay + //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()); } //---------------------------------------------------------------------------------------------- @@ -269,6 +317,7 @@ namespace MWRender void TerrainManager::initTerrainBlendMaps(Ogre::Terrain* terrain, MWWorld::Ptr::CellStore* store, int fromX, int fromY, int size, + Ogre::uchar* vertexColourAlpha, const std::map& indexes) { assert(store != NULL && "store must be a valid pointer"); @@ -294,6 +343,15 @@ namespace MWRender ->getBlendPointer(); memset(pBlend, 0, sizeof(float) * blendSize * blendSize); } + //except the overlay, which we will just splat over the top + { + //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 for ( int texY = fromY - 1; texY < fromY + size + 1; texY++ ) @@ -354,10 +412,9 @@ namespace MWRender } } - //update the maps - for ( iter = indexes.begin(); iter != indexes.end(); ++iter ) + for ( int i = 1; i < terrain->getLayerCount(); i++ ) { - Ogre::TerrainLayerBlendMap* blend = terrain->getLayerBlendMap(iter->second); + Ogre::TerrainLayerBlendMap* blend = terrain->getLayerBlendMap(i); blend->dirty(); blend->update(); } @@ -424,8 +481,7 @@ namespace MWRender 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); } @@ -451,4 +507,74 @@ namespace MWRender return tex; } + //---------------------------------------------------------------------------------------------- + + Ogre::TexturePtr TerrainManager::getVertexColours(MWWorld::Ptr::CellStore* store, + Ogre::uchar* alpha, + int fromX, int fromY, int size) + { + Ogre::TextureManager* const texMgr = Ogre::TextureManager::getSingletonPtr(); + const char* const colours = store->land[1][1]->landData->colours; + + const std::string colourTextureName = "VtexColours_" + + boost::lexical_cast(store->cell->getGridX()) + + "_" + + boost::lexical_cast(store->cell->getGridY()) + + "_" + + boost::lexical_cast(fromX) + + "_" + + boost::lexical_cast(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(pixelBox.data); + + for ( int y = 0; y < size; y++ ) + { + for ( int x = 0; x < size; x++ ) + { + const size_t colourOffset = (y+fromY)*3*65 + (x+fromX)*3; + + assert( colourOffset >= 0 && colourOffset < 65*65*3 && + "Colour offset is out of the expected bounds of record" ); + + const unsigned char r = colours[colourOffset + 0]; + const unsigned char g = colours[colourOffset + 1]; + const unsigned char b = colours[colourOffset + 2]; + + //as is the case elsewhere we need to flip the y + const size_t imageOffset = (size - 1 - y)*size*4 + x*4; + pDest[imageOffset + 0] = b; + pDest[imageOffset + 1] = g; + pDest[imageOffset + 2] = r; + 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(); + + return tex; + } + } diff --git a/apps/openmw/mwrender/terrain.hpp b/apps/openmw/mwrender/terrain.hpp index 548d00eab3..a201fdb614 100644 --- a/apps/openmw/mwrender/terrain.hpp +++ b/apps/openmw/mwrender/terrain.hpp @@ -74,12 +74,16 @@ namespace MWRender{ * @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 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 * can be used by initTerrainBlendMaps */ void initTerrainTextures(Ogre::Terrain::ImportData* terrainData, MWWorld::Ptr::CellStore* store, int fromX, int fromY, int size, + Ogre::uchar* vertexColourAlpha, std::map& indexes); /** @@ -90,11 +94,16 @@ namespace MWRender{ * @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 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 */ void initTerrainBlendMaps(Ogre::Terrain* terrain, MWWorld::Ptr::CellStore* store, int fromX, int fromY, int size, + Ogre::uchar* vertexColourAlpha, const std::map& indexes); /** @@ -118,7 +127,22 @@ namespace MWRender{ * @param fileName the name of the *diffuse* texture */ Ogre::TexturePtr getNormalDisp(const std::string& fileName); - + + /** + * Due to the fact that Ogre terrain doesn't support vertex colours + * we have to generate them manually + * + * @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 fromY the *vertex* index in the current cell to start making the texture from + * @param size the size (number of vertexes) to get + */ + Ogre::TexturePtr getVertexColours(MWWorld::Ptr::CellStore* store, + Ogre::uchar* alpha, + int fromX, int fromY, int size); }; } diff --git a/components/esm/loadland.cpp b/components/esm/loadland.cpp index 1d670036e3..3bca8692b7 100644 --- a/components/esm/loadland.cpp +++ b/components/esm/loadland.cpp @@ -93,7 +93,10 @@ void Land::loadData(ESMReader &esm) } if (esm.isNextSub("VCLR")) { - esm.skipHSubSize(12675); + landData->usingColours = true; + esm.getHExact(&landData->colours, 3*LAND_NUM_VERTS); + }else{ + landData->usingColours = false; } //TODO fix magic numbers uint16_t vtex[512]; diff --git a/components/esm/loadland.hpp b/components/esm/loadland.hpp index 4219f3eb63..eeb198e905 100644 --- a/components/esm/loadland.hpp +++ b/components/esm/loadland.hpp @@ -58,6 +58,8 @@ struct Land float heights[LAND_NUM_VERTS]; //float normals[LAND_NUM_VERTS * 3]; uint16_t textures[LAND_NUM_TEXTURES]; + + bool usingColours; char colours[3 * LAND_NUM_VERTS]; }; From 69243486960bb9b4ab8bed03d591dcbf04a0f085 Mon Sep 17 00:00:00 2001 From: Jacob Essex Date: Wed, 29 Feb 2012 23:33:54 +0000 Subject: [PATCH 2/4] Fixed some texture splatting issues with loading empty terrain cells --- apps/openmw/mwrender/terrain.cpp | 3 +-- components/esm/loadland.cpp | 2 ++ 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/apps/openmw/mwrender/terrain.cpp b/apps/openmw/mwrender/terrain.cpp index 89c362c4cd..0e6fdff01e 100644 --- a/apps/openmw/mwrender/terrain.cpp +++ b/apps/openmw/mwrender/terrain.cpp @@ -263,8 +263,7 @@ namespace MWRender if ( it == indexes.end() ) { //NB: All vtex ids are +1 compared to the ltex ids - assert((int)ltexIndex >= 0 && - (int)store->landTextures->ltex.size() >= (int)ltexIndex - 1 && + assert( (int)store->landTextures->ltex.size() >= (int)ltexIndex - 1 && "LAND.VTEX must be within the bounds of the LTEX array"); std::string texture; diff --git a/components/esm/loadland.cpp b/components/esm/loadland.cpp index 3bca8692b7..4fe6279d32 100644 --- a/components/esm/loadland.cpp +++ b/components/esm/loadland.cpp @@ -111,6 +111,8 @@ void Land::loadData(ESMReader &esm) } else { + landData->usingColours = false; + memset(&landData->textures, 0, 512 * sizeof(uint16_t)); for (int i = 0; i < LAND_NUM_VERTS; i++) { landData->heights[i] = -256.0f * HEIGHT_SCALE; From 611f336d0731bdff53203c6aa93fa5b9af087522 Mon Sep 17 00:00:00 2001 From: Jacob Essex Date: Wed, 29 Feb 2012 23:38:21 +0000 Subject: [PATCH 3/4] Now doesn't attempt to use fake vertex colours with cells that don't have vertex colours --- apps/openmw/mwrender/terrain.cpp | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/apps/openmw/mwrender/terrain.cpp b/apps/openmw/mwrender/terrain.cpp index 0e6fdff01e..59f2f2082f 100644 --- a/apps/openmw/mwrender/terrain.cpp +++ b/apps/openmw/mwrender/terrain.cpp @@ -300,15 +300,18 @@ namespace MWRender } //add the vertex colour overlay - //TODO sort the *4 bit - Ogre::TexturePtr vclr = getVertexColours(store, vertexColourAlpha, fromX*4, fromY*4, mLandSize); - Ogre::TexturePtr normDisp = getNormalDisp("DOES_NOT_EXIST"); + 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()); + 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()); + } } //---------------------------------------------------------------------------------------------- @@ -343,6 +346,7 @@ namespace MWRender 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) From 8dd6e75ae1437f9db6db52e0d9fab5498f78624b Mon Sep 17 00:00:00 2001 From: Jacob Essex Date: Fri, 2 Mar 2012 11:56:51 +0000 Subject: [PATCH 4/4] Vertex colours now uses the Ogre::Terrain colour map --- apps/openmw/mwrender/terrain.cpp | 134 +++++++------------------------ apps/openmw/mwrender/terrain.hpp | 17 +--- 2 files changed, 34 insertions(+), 117 deletions(-) diff --git a/apps/openmw/mwrender/terrain.cpp b/apps/openmw/mwrender/terrain.cpp index 59f2f2082f..2d433d52f5 100644 --- a/apps/openmw/mwrender/terrain.cpp +++ b/apps/openmw/mwrender/terrain.cpp @@ -2,8 +2,6 @@ #include #include -#include - #include "terrain.hpp" #include "components/esm/loadland.hpp" @@ -127,38 +125,29 @@ namespace MWRender mLandSize*sizeof(float)); } - //this should really be 33*33 - Ogre::uchar* vertexColourAlpha = OGRE_ALLOC_T(Ogre::uchar, - mLandSize*mLandSize, - Ogre::MEMCATEGORY_GENERAL); - std::map indexes; initTerrainTextures(&terrainData, store, x * numTextures, y * numTextures, - numTextures, vertexColourAlpha, - indexes); + numTextures, indexes); assert( mTerrainGroup->getTerrain(cellX, cellY) == NULL && "The terrain for this cell already existed" ); mTerrainGroup->defineTerrain(terrainX, terrainY, &terrainData); mTerrainGroup->loadTerrain(terrainX, terrainY, true); + 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, x * numTextures, y * numTextures, numTextures, - vertexColourBlendMap.getData(), 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], mLandSize*mLandSize*sizeof(float)); - Ogre::uchar* vertexColourAlpha = OGRE_ALLOC_T(Ogre::uchar, - mLandSize*mLandSize, - Ogre::MEMCATEGORY_GENERAL); - std::map indexes; initTerrainTextures(&terrainData, store, 0, 0, - ESM::Land::LAND_TEXTURE_SIZE, vertexColourAlpha, indexes); + ESM::Land::LAND_TEXTURE_SIZE, indexes); mTerrainGroup->defineTerrain(cellX, cellY, &terrainData); mTerrainGroup->loadTerrain(cellX, cellY, true); 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, 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(); @@ -232,7 +216,6 @@ namespace MWRender void TerrainManager::initTerrainTextures(Ogre::Terrain::ImportData* terrainData, MWWorld::Ptr::CellStore* store, int fromX, int fromY, int size, - Ogre::uchar* vertexColourAlpha, std::map& indexes) { 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, MWWorld::Ptr::CellStore* store, int fromX, int fromY, int size, - Ogre::uchar* vertexColourAlpha, const std::map& indexes) { assert(store != NULL && "store must be a valid pointer"); @@ -345,16 +313,6 @@ namespace MWRender ->getBlendPointer(); 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 for ( int texY = fromY - 1; texY < fromY + size + 1; texY++ ) @@ -484,7 +442,8 @@ namespace MWRender 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); } @@ -512,38 +471,14 @@ namespace MWRender //---------------------------------------------------------------------------------------------- - Ogre::TexturePtr TerrainManager::getVertexColours(MWWorld::Ptr::CellStore* store, - Ogre::uchar* alpha, + Ogre::Image TerrainManager::getVertexColours(MWWorld::Ptr::CellStore* store, int fromX, int fromY, int size) { - Ogre::TextureManager* const texMgr = Ogre::TextureManager::getSingletonPtr(); const char* const colours = store->land[1][1]->landData->colours; - const std::string colourTextureName = "VtexColours_" + - boost::lexical_cast(store->cell->getGridX()) + - "_" + - boost::lexical_cast(store->cell->getGridY()) + - "_" + - boost::lexical_cast(fromX) + - "_" + - boost::lexical_cast(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(pixelBox.data); + Ogre::uchar* imgData = OGRE_ALLOC_T(Ogre::uchar, + size*size*sizeof(Ogre::uchar)*3, + Ogre::MEMCATEGORY_GENERAL); for ( int y = 0; y < size; y++ ) { @@ -559,25 +494,18 @@ namespace MWRender const unsigned char b = colours[colourOffset + 2]; //as is the case elsewhere we need to flip the y - const size_t imageOffset = (size - 1 - y)*size*4 + x*4; - pDest[imageOffset + 0] = b; - pDest[imageOffset + 1] = g; - pDest[imageOffset + 2] = r; - 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; - } + const size_t imageOffset = (size - 1 - y)*size*3 + x*3; + imgData[imageOffset + 0] = r; + imgData[imageOffset + 1] = g; + imgData[imageOffset + 2] = b; } } - pixelBuffer->unlock(); + Ogre::Image img; + img.loadDynamicImage(imgData, size, size, 1, Ogre::PF_R8G8B8, true); - return tex; + return img; } } diff --git a/apps/openmw/mwrender/terrain.hpp b/apps/openmw/mwrender/terrain.hpp index a201fdb614..232c1d103d 100644 --- a/apps/openmw/mwrender/terrain.hpp +++ b/apps/openmw/mwrender/terrain.hpp @@ -74,16 +74,12 @@ namespace MWRender{ * @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 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 * can be used by initTerrainBlendMaps */ void initTerrainTextures(Ogre::Terrain::ImportData* terrainData, MWWorld::Ptr::CellStore* store, int fromX, int fromY, int size, - Ogre::uchar* vertexColourAlpha, std::map& indexes); /** @@ -94,16 +90,11 @@ namespace MWRender{ * @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 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 */ void initTerrainBlendMaps(Ogre::Terrain* terrain, MWWorld::Ptr::CellStore* store, int fromX, int fromY, int size, - Ogre::uchar* vertexColourAlpha, const std::map& indexes); /** @@ -133,15 +124,13 @@ namespace MWRender{ * we have to generate them manually * * @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 fromY the *vertex* index in the current cell to start making the texture from * @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::uchar* alpha, + Ogre::Image getVertexColours(MWWorld::Ptr::CellStore* store, int fromX, int fromY, int size); };