History: How to use different texture layers for different terrains in a terrain group
Source of version: 2
Copy to clipboard
A TerrainGroup is a container that holds multiple Terrain instances. Each instance of a Terrain can have its own texture layers. The following is the createScene() method that has been modified from the BasicTutorial3. It simply creates a TerrainGroup with 2 terrains and gives each terrain it's own texture layer. The two terrains it creates are flat terrains with no height map, just the different textures. The code is just a simple example to illustrate how to use different terrain textures.
{CODE(wrap="1", colors="c++")}
void BasicTutorial3::createScene(void)
{
mCamera->setPosition(Ogre::Vector3(0, 50, 0));
mCamera->lookAt(Ogre::Vector3(512, 0, 512));
mCamera->setNearClipDistance(0.1);
mCamera->setFarClipDistance(50000);
if (mRoot->getRenderSystem()->getCapabilities()->hasCapability(Ogre::RSC_INFINITE_FAR_PLANE))
{
mCamera->setFarClipDistance(0); // enable infinite far clip distance if we can
}
// Play with startup Texture Filtering options
// Note: Pressing T on runtime will discarde those settings
// Ogre::MaterialManager::getSingleton().setDefaultTextureFiltering(Ogre::TFO_ANISOTROPIC);
// Ogre::MaterialManager::getSingleton().setDefaultAnisotropy(7);
Ogre::Vector3 lightdir(0.55, -0.3, 0.75);
lightdir.normalise();
Ogre::Light* light = mSceneMgr->createLight("tstLight");
light->setType(Ogre::Light::LT_DIRECTIONAL);
light->setDirection(lightdir);
light->setDiffuseColour(Ogre::ColourValue::White);
light->setSpecularColour(Ogre::ColourValue(0.4, 0.4, 0.4));
mSceneMgr->setAmbientLight(Ogre::ColourValue(0.2, 0.2, 0.2));
int terrainResolution = 513; // the number of verticies on each side of a terrain, must be 2^n+1
float terrainWorldUnits = 1200.0;
mTerrainGlobals = OGRE_NEW Ogre::TerrainGlobalOptions();
mTerrainGroup = OGRE_NEW Ogre::TerrainGroup( mSceneMgr, // the scene manager that will handle the terrains
Ogre::Terrain::ALIGN_X_Z, // align the terrain along the X-Z plane
terrainResolution, // the number of vertices along the edge of the terrains
terrainWorldUnits); // The size of the terrain in world units
mTerrainGroup->setFilenameConvention(Ogre::String("BasicTutorial3Terrain"), Ogre::String("dat"));
mTerrainGroup->setOrigin(Ogre::Vector3::ZERO);
//=========================================================
// Configure terrain defults.
//=========================================================
mTerrainGlobals->setMaxPixelError(8); // When moving far away from the terrain, the terrain will be approximated with
// a lower vertex count. The higher the maxPixelError, the less vertices will be
// used when approximating (??)
mTerrainGlobals->setCompositeMapDistance(500); // How far away from the terrain do we have to be before the terrain texture
// gets approximated as one big texture. (??)
//Important to set these so that the terrain knows what to use for derived (non-realtime) data
mTerrainGlobals->setLightMapDirection(light->getDerivedDirection());
mTerrainGlobals->setCompositeMapAmbient(mSceneMgr->getAmbientLight());
mTerrainGlobals->setCompositeMapDiffuse(light->getDiffuseColour());
// Create default import settings for all terrains created in the group. We can change these later for each individual
// terrain we add. We will do this later.
Ogre::Terrain::ImportData& defaultimp = mTerrainGroup->getDefaultImportSettings();
defaultimp.terrainSize = terrainResolution; // The number of vertices along the edge of the terrains
defaultimp.worldSize = 1200.0f; //The size of the terrain in world space units. Terrains would be 1200m x 1200m in dimensions
defaultimp.inputScale = 15.0; //When loading height map data from an image, the height will be multiplied by this factor
// we are not loading a height field. Our terrain is goign to be flat for now.
defaultimp.minBatchSize = 33; // I don't know what this means
defaultimp.maxBatchSize = 129; //
//defaultimp.inputBias = 0.1; // I don't know what this does. (??)
defaultimp.layerList.resize(3);
defaultimp.layerList[0].worldSize = 100; // The number of times you want the texture to repeat.
defaultimp.layerList[0].textureNames.push_back("dirt_grayrocky_diffusespecular.dds");
defaultimp.layerList[0].textureNames.push_back("dirt_grayrocky_normalheight.dds");
defaultimp.layerList[1].worldSize = 1; // The number of times you want the texture to repeat.
defaultimp.layerList[1].textureNames.push_back("grass_green-01_diffusespecular.dds");
defaultimp.layerList[1].textureNames.push_back("grass_green-01_normalheight.dds");
defaultimp.layerList[2].worldSize = 30; // The number of times you want the texture to repeat.
defaultimp.layerList[2].textureNames.push_back("growth_weirdfungus-03_diffusespecular.dds");
defaultimp.layerList[2].textureNames.push_back("growth_weirdfungus-03_normalheight.dds");
//==========================================================
//==========================================================
// Define the two terrains in the group we are going to use.
// These won't be loaded until we call the loadAllTerrains(true) function below
mTerrainGroup->defineTerrain(0,0,0.0f); // define a flat terrain of height 0 at the (0,0) location in the terrain group
mTerrainGroup->defineTerrain(0,1,0.0f); // define a flat terrain of height 0 at the (0,1) location in the terrain group.
//==========================================================
// sync load since we want everything in place when we start
mTerrainGroup->loadAllTerrains(true);
// how many layers terrain(0,1) has...it should be 3 because we set the default number of layers to be 3 previously.
int terrain01_layer_count = mTerrainGroup->getTerrain(0,1)->getLayerCount();
// Now switch the first two texture layers for terrain(0,1) just so we can see the difference when rendered
mTerrainGroup->getTerrain(0,1)->setLayerWorldSize(0,100);
mTerrainGroup->getTerrain(0,1)->setLayerTextureName(0,0,"grass_green-01_diffusespecular.dds"); // Set the first layer to be a grass layer instead of rock
mTerrainGroup->getTerrain(0,1)->setLayerTextureName(0,1,"grass_green-01_normalheight.dds");
mTerrainGroup->getTerrain(0,1)->setLayerTextureName(1,0,"dirt_grayrocky_diffusespecular.dds"); // Set the second layer to be a rock layer instead of grass
mTerrainGroup->getTerrain(0,1)->setLayerTextureName(1,1,"dirt_grayrocky_normalheight.dds");
mTerrainGroup->freeTemporaryResources(); //I dont konw what temporary resources are (??)
// Generate FOG. For some reason the fog is only appearing on the grass terrain, not the rock terrain.
Ogre::ColourValue fadeColour(0.9, 0.9, 0.9);
mWindow->getViewport(0)->setBackgroundColour(fadeColour);
mSceneMgr->setFog(Ogre::FOG_LINEAR, fadeColour, 0.0, 10, 2000.0);
// Create a sky
Ogre::Plane plane2;
plane2.d = 100;
plane2.normal = Ogre::Vector3::NEGATIVE_UNIT_Y;
//mSceneMgr->setSkyDome(true, "Examples/CloudySky", 5, 8, 500);
mSceneMgr->setSkyPlane(true, plane2, "Examples/CloudySky", 500, 20, true, 0.5, 150, 150);
}
{CODE}