From 2bea4c47242420b8d0b5db4661745a410186a727 Mon Sep 17 00:00:00 2001 From: scrawl Date: Fri, 2 Mar 2012 15:29:12 +0100 Subject: [PATCH] fixed the global colour map, apparently Ogre::Terrain was corrupting it somehow, now we are just bypassing Ogre::Terrain for the colour map and passing it directly to the material, which makes more sense performance-wise anyway --- apps/openmw/mwrender/terrain.cpp | 68 +++++++++++++++++------- apps/openmw/mwrender/terrain.hpp | 4 +- apps/openmw/mwrender/terrainmaterial.cpp | 10 ++-- 3 files changed, 55 insertions(+), 27 deletions(-) diff --git a/apps/openmw/mwrender/terrain.cpp b/apps/openmw/mwrender/terrain.cpp index 4dd03c0970..8d82cb2967 100644 --- a/apps/openmw/mwrender/terrain.cpp +++ b/apps/openmw/mwrender/terrain.cpp @@ -6,6 +6,8 @@ #include "components/esm/loadland.hpp" +#include + using namespace Ogre; namespace MWRender @@ -48,6 +50,7 @@ namespace MWRender matProfile->setLayerNormalMappingEnabled(false); matProfile->setLayerParallaxMappingEnabled(false); matProfile->setReceiveDynamicShadowsEnabled(false); + matProfile->setGlobalColourMapEnabled(true); mLandSize = ESM::Land::LAND_SIZE; mRealSize = ESM::Land::REAL_SIZE; @@ -163,9 +166,12 @@ namespace MWRender if ( store->land[1][1]->landData->usingColours ) { - Ogre::Image vertex = getVertexColours(store, x*32, y*32, mLandSize); - terrain->setGlobalColourMapEnabled(true); - terrain->getGlobalColourMap()->loadImage(vertex); + Ogre::TexturePtr vertex = getVertexColours(store, x*32, y*32, mLandSize); + + MaterialPtr mat = terrain->_getMaterial(); + mat->getTechnique(0)->getPass(0)->getTextureUnitState(1)->setTextureName( vertex->getName() ); + mat = terrain->_getCompositeMapMaterial(); + mat->getTechnique(0)->getPass(0)->getTextureUnitState(1)->setTextureName( vertex->getName() ); } } } @@ -200,9 +206,12 @@ namespace MWRender if ( store->land[1][1]->landData->usingColours ) { - Ogre::Image vertex = getVertexColours(store, 0, 0, mLandSize); - terrain->setGlobalColourMapEnabled(true); - terrain->getGlobalColourMap()->loadImage(vertex); + Ogre::TexturePtr vertex = getVertexColours(store, 0, 0, mLandSize); + + MaterialPtr mat = terrain->_getMaterial(); + mat->getTechnique(0)->getPass(0)->getTextureUnitState(1)->setTextureName( vertex->getName() ); + mat = terrain->_getCompositeMapMaterial(); + mat->getTechnique(0)->getPass(0)->getTextureUnitState(1)->setTextureName( vertex->getName() ); } } @@ -495,14 +504,37 @@ namespace MWRender //---------------------------------------------------------------------------------------------- - Ogre::Image TerrainManager::getVertexColours(MWWorld::Ptr::CellStore* store, - int fromX, int fromY, int size) + Ogre::TexturePtr 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; - Ogre::uchar* imgData = OGRE_ALLOC_T(Ogre::uchar, - size*size*sizeof(Ogre::uchar)*3, - Ogre::MEMCATEGORY_GENERAL); + 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_DISCARD); + const Ogre::PixelBox& pixelBox = pixelBuffer->getCurrentLock(); + + Ogre::uint8* pDest = static_cast(pixelBox.data); for ( int y = 0; y < size; y++ ) { @@ -518,18 +550,16 @@ 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*3 + x*3; - imgData[imageOffset + 0] = r; - imgData[imageOffset + 1] = g; - imgData[imageOffset + 2] = b; - + const size_t imageOffset = (size - 1 - y)*size*4 + x*4; + pDest[imageOffset + 0] = b; + pDest[imageOffset + 1] = g; + pDest[imageOffset + 2] = r; } } - Ogre::Image img; - img.loadDynamicImage(imgData, size, size, 1, Ogre::PF_R8G8B8, true); + pixelBuffer->unlock(); - return img; + return tex; } } diff --git a/apps/openmw/mwrender/terrain.hpp b/apps/openmw/mwrender/terrain.hpp index 923f4fc2bf..a0a48fb37f 100644 --- a/apps/openmw/mwrender/terrain.hpp +++ b/apps/openmw/mwrender/terrain.hpp @@ -130,10 +130,8 @@ namespace MWRender{ * @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::Image getVertexColours(MWWorld::Ptr::CellStore* store, + Ogre::TexturePtr getVertexColours(MWWorld::Ptr::CellStore* store, int fromX, int fromY, int size); }; diff --git a/apps/openmw/mwrender/terrainmaterial.cpp b/apps/openmw/mwrender/terrainmaterial.cpp index 9121da793b..0edc23a71b 100644 --- a/apps/openmw/mwrender/terrainmaterial.cpp +++ b/apps/openmw/mwrender/terrainmaterial.cpp @@ -203,7 +203,7 @@ namespace Ogre // normalmap --freeTextureUnits; // colourmap - if (terrain->getGlobalColourMapEnabled()) + //if (terrain->getGlobalColourMapEnabled()) --freeTextureUnits; if (isShadowingEnabled(HIGH_LOD, terrain)) { @@ -359,9 +359,9 @@ namespace Ogre tu->setTextureAddressingMode(TextureUnitState::TAM_CLAMP); // global colour map - if (terrain->getGlobalColourMapEnabled() && isGlobalColourMapEnabled()) + //if (terrain->getGlobalColourMapEnabled() && isGlobalColourMapEnabled()) { - tu = pass->createTextureUnitState(terrain->getGlobalColourMap()->getName()); + tu = pass->createTextureUnitState(""); tu->setTextureAddressingMode(TextureUnitState::TAM_CLAMP); } @@ -1004,7 +1004,7 @@ namespace Ogre "uniform sampler2D globalNormal : register(s" << currentSamplerIdx++ << ")\n"; - if (terrain->getGlobalColourMapEnabled() && prof->isGlobalColourMapEnabled()) + //if (terrain->getGlobalColourMapEnabled() && prof->isGlobalColourMapEnabled()) { outStream << ", uniform sampler2D globalColourMap : register(s" << currentSamplerIdx++ << ")\n"; @@ -1299,7 +1299,7 @@ namespace Ogre } else { - if (terrain->getGlobalColourMapEnabled() && prof->isGlobalColourMapEnabled()) + //if (terrain->getGlobalColourMapEnabled() && prof->isGlobalColourMapEnabled()) { // sample colour map and apply to diffuse outStream << " diffuse *= tex2D(globalColourMap, uv).rgb;\n";