From 0f705eaca580da7bf11bc773529b9fc54c9d2b28 Mon Sep 17 00:00:00 2001 From: Jacob Essex Date: Fri, 2 Mar 2012 21:03:53 +0000 Subject: [PATCH] Removed the option of not splitting terrain as it was slower and adding to code complexity. The only real reason for keeping it, which was that it made debugging some texture issues easier is now gone. --- apps/openmw/mwrender/terrain.cpp | 183 +++++++++++-------------------- apps/openmw/mwrender/terrain.hpp | 25 +---- 2 files changed, 69 insertions(+), 139 deletions(-) diff --git a/apps/openmw/mwrender/terrain.cpp b/apps/openmw/mwrender/terrain.cpp index 39aeb6437..113a4a831 100644 --- a/apps/openmw/mwrender/terrain.cpp +++ b/apps/openmw/mwrender/terrain.cpp @@ -31,9 +31,9 @@ namespace MWRender static_cast(activeProfile); mTerrainGlobals->setMaxPixelError(8); - mTerrainGlobals->setLayerBlendMapSize(SPLIT_TERRAIN ? 32 : 1024); - mTerrainGlobals->setLightMapSize(SPLIT_TERRAIN ? 256 : 1024); - mTerrainGlobals->setCompositeMapSize(SPLIT_TERRAIN ? 256 : 1024); + mTerrainGlobals->setLayerBlendMapSize(32); + mTerrainGlobals->setLightMapSize(256); + mTerrainGlobals->setCompositeMapSize(256); mTerrainGlobals->setDefaultGlobalColourMapSize(256); //10 (default) didn't seem to be quite enough @@ -52,29 +52,21 @@ namespace MWRender matProfile->setReceiveDynamicShadowsEnabled(false); matProfile->setGlobalColourMapEnabled(true); - mLandSize = ESM::Land::LAND_SIZE; - mRealSize = ESM::Land::REAL_SIZE; - if ( SPLIT_TERRAIN ) - { - mLandSize = (mLandSize - 1)/2 + 1; - mRealSize /= 2; - } - mTerrainGroup = OGRE_NEW Ogre::TerrainGroup(mgr, Ogre::Terrain::ALIGN_X_Z, mLandSize, - mRealSize); + mWorldSize); - mTerrainGroup->setOrigin(Ogre::Vector3(mRealSize/2, + mTerrainGroup->setOrigin(Ogre::Vector3(mWorldSize/2, 0, - -mRealSize/2)); + -mWorldSize/2)); Ogre::Terrain::ImportData& importSettings = mTerrainGroup->getDefaultImportSettings(); importSettings.inputBias = 0; importSettings.terrainSize = mLandSize; - importSettings.worldSize = mRealSize; + importSettings.worldSize = mWorldSize; importSettings.minBatchSize = 9; importSettings.maxBatchSize = mLandSize; @@ -111,109 +103,72 @@ namespace MWRender const int cellY = store->cell->getGridY(); - if ( SPLIT_TERRAIN ) + //split the cell terrain into four segments + const int numTextures = ESM::Land::LAND_TEXTURE_SIZE/2; + + for ( int x = 0; x < 2; x++ ) { - //split the cell terrain into four segments - const int numTextures = ESM::Land::LAND_TEXTURE_SIZE/2; - - for ( int x = 0; x < 2; x++ ) + for ( int y = 0; y < 2; y++ ) { - for ( int y = 0; y < 2; y++ ) + Ogre::Terrain::ImportData terrainData = + mTerrainGroup->getDefaultImportSettings(); + + 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); + + //copy the height data row by row + for ( int terrainCopyY = 0; terrainCopyY < mLandSize; terrainCopyY++ ) { - Ogre::Terrain::ImportData terrainData = - mTerrainGroup->getDefaultImportSettings(); + //the offset of the current segment + const size_t yOffset = y * (mLandSize-1) * ESM::Land::LAND_SIZE + + //offset of the row + terrainCopyY * ESM::Land::LAND_SIZE; + const size_t xOffset = x * (mLandSize-1); - const int terrainX = cellX * 2 + x; - const int terrainY = cellY * 2 + y; + memcpy(&terrainData.inputFloat[terrainCopyY*mLandSize], + &store->land[1][1]->landData->heights[yOffset + xOffset], + mLandSize*sizeof(float)); + } - //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); + std::map indexes; + initTerrainTextures(&terrainData, store, + x * numTextures, y * numTextures, + numTextures, indexes); - //copy the height data row by row - for ( int terrainCopyY = 0; terrainCopyY < mLandSize; terrainCopyY++ ) + if (mTerrainGroup->getTerrain(cellX, cellY) == NULL) + { + mTerrainGroup->defineTerrain(terrainX, terrainY, &terrainData); + + mTerrainGroup->loadTerrain(terrainX, terrainY, true); + + Ogre::Terrain* terrain = mTerrainGroup->getTerrain(terrainX, terrainY); + initTerrainBlendMaps(terrain, store, + x * numTextures, y * numTextures, + numTextures, + indexes); + + if ( store->land[1][1]->landData->usingColours ) { - //the offset of the current segment - const size_t yOffset = y * (mLandSize-1) * ESM::Land::LAND_SIZE + - //offset of the row - terrainCopyY * ESM::Land::LAND_SIZE; - const size_t xOffset = x * (mLandSize-1); + Ogre::TexturePtr vertex = getVertexColours(store, + x*(mLandSize-1), + y*(mLandSize-1), + mLandSize); - memcpy(&terrainData.inputFloat[terrainCopyY*mLandSize], - &store->land[1][1]->landData->heights[yOffset + xOffset], - mLandSize*sizeof(float)); - } - - std::map indexes; - initTerrainTextures(&terrainData, store, - x * numTextures, y * numTextures, - numTextures, indexes); - - if (mTerrainGroup->getTerrain(cellX, cellY) == NULL) - { - mTerrainGroup->defineTerrain(terrainX, terrainY, &terrainData); - - mTerrainGroup->loadTerrain(terrainX, terrainY, true); - - Ogre::Terrain* terrain = mTerrainGroup->getTerrain(terrainX, terrainY); - initTerrainBlendMaps(terrain, store, - x * numTextures, y * numTextures, - numTextures, - indexes); - - if ( store->land[1][1]->landData->usingColours ) - { - 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() ); - } + 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() ); } } } } - else - { - Ogre::Terrain::ImportData terrainData = - mTerrainGroup->getDefaultImportSettings(); - - //one cell is one terrain segment - terrainData.inputFloat = OGRE_ALLOC_T(float, - mLandSize*mLandSize, - Ogre::MEMCATEGORY_GEOMETRY); - - memcpy(&terrainData.inputFloat[0], - &store->land[1][1]->landData->heights[0], - mLandSize*mLandSize*sizeof(float)); - - std::map indexes; - initTerrainTextures(&terrainData, store, 0, 0, - ESM::Land::LAND_TEXTURE_SIZE, indexes); - - mTerrainGroup->defineTerrain(cellX, cellY, &terrainData); - - mTerrainGroup->loadTerrain(cellX, cellY, true); - Ogre::Terrain* terrain = mTerrainGroup->getTerrain(cellX, cellY); - - initTerrainBlendMaps(terrain, store, 0, 0, - ESM::Land::LAND_TEXTURE_SIZE, - indexes); - - if ( store->land[1][1]->landData->usingColours ) - { - 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() ); - } - } mTerrainGroup->freeTemporaryResources(); } @@ -222,22 +177,14 @@ namespace MWRender void TerrainManager::cellRemoved(MWWorld::Ptr::CellStore *store) { - if ( SPLIT_TERRAIN ) + for ( int x = 0; x < 2; x++ ) { - for ( int x = 0; x < 2; x++ ) + for ( int y = 0; y < 2; y++ ) { - for ( int y = 0; y < 2; y++ ) - { - mTerrainGroup->unloadTerrain(store->cell->getGridX() * 2 + x, - store->cell->getGridY() * 2 + y); - } + mTerrainGroup->unloadTerrain(store->cell->getGridX() * 2 + x, + store->cell->getGridY() * 2 + y); } } - else - { - mTerrainGroup->unloadTerrain(store->cell->getGridX(), - store->cell->getGridY()); - } } //---------------------------------------------------------------------------------------------- diff --git a/apps/openmw/mwrender/terrain.hpp b/apps/openmw/mwrender/terrain.hpp index c298b7fc1..eba437a2d 100644 --- a/apps/openmw/mwrender/terrain.hpp +++ b/apps/openmw/mwrender/terrain.hpp @@ -17,14 +17,8 @@ namespace MWRender{ /** * Implements the Morrowind terrain using the Ogre Terrain Component * - * This currently has two options as to how the terrain is rendered, one - * is that one cell is rendered as one Ogre::Terrain and the other that - * it is rendered as 4 Ogre::Terrain segments - * - * Splitting it up into segments has the following advantages - * * Seems to be faster - * * Terrain can now be culled more aggressivly using view frustram culling - * * We don't hit splat limits as much + * Each terrain cell is split into four blocks as this leads to an increase + * in performance and means we don't hit splat limits quite as much */ class TerrainManager{ public: @@ -40,26 +34,15 @@ namespace MWRender{ Ogre::TerrainGlobalOptions* mTerrainGlobals; Ogre::TerrainGroup* mTerrainGroup; - /** - * Should each cell be split into a further four Ogre::Terrain objects - * - * This has the advantage that it is possible to cull more terrain and - * we are more likly to be able to be able to fit all the required splats - * in (Ogre's default material generator only works with about 6 textures) - */ - static const bool SPLIT_TERRAIN = true; - /** * The length in verticies of a single terrain block. - * This takes into account the SPLIT_TERRAIN option */ - int mLandSize; + static const int mLandSize = (ESM::Land::LAND_SIZE - 1)/2 + 1; /** * The length in game units of a single terrain block. - * This takes into account the SPLIT_TERRAIN option */ - int mRealSize; + static const int mWorldSize = ESM::Land::REAL_SIZE/2; /** * Setups up the list of textures for part of a cell, using indexes as