This is a guide for exporting a terrain made in PnP TerrainCreator to Ogre 1.7.
We are using demoterrain, and due to the limit of 6 image layers per terrain page in Ogre, we are going to retexture it, using the following 4 textures:
gras.jpg | slope: 0 - 50 | height: 35 - 20000
moos1.jpg | slope: 35 - 90 | height: 0 - 35
moos2.jpg | slope: 50 - 90
schlamm_getrocknet2.jpg | slope: 0 - 35 | height: 0 - 35
Use power of four textures!
The nVidia texture tool needs them to be of that size, eg 512.
Setup the texture plugin using the above automated texturing parameters, and retexture the terrain.
You should see something like this:
Attachment:
pnptc_terrain.jpg [ 59.29 KiB | Viewed 99 times ]
(Sorry about the lack of light)
The limit of 6 layers is when using a global light map and a normal map, and then diffuse/specular, normal/height maps for the layer textures.
A SM2 card has a limit of 16 texture units in one pass.
It is possible to write your own multi-pass material generator, though. Making it possible to use more textures.
Now we are going to export it to Ogre.
First, we need to export the heightmap.
Right-click on the terrain page and select the RAW heightmap export plugin, using the following settings:
Attachment:
heightmapExport.jpg [ 13.64 KiB | Viewed 2365 times ]
This should give a full scale RAW heightmap file.
Next, we need to export the splatting maps.
Choose the alphamap export plugin, and use the following settings:
Attachment:
alphamapExport.jpg [ 19.46 KiB | Viewed 2363 times ]
Would probably be a good idea to check
power of two.
Should leave you with the following textures:
gras_00000_00000_000.PNG
moos1_00000_00000_000.PNG
moos2_00000_00000_000.PNG
schlamm_getrocknet2_00000_00000_000.PNG
Now, we need to turn the four diffuse textures into what the default Ogre terrain material generator expects:
diffuse_specular and normal_height.
Here's one way to generate those textures:
1) Get ShaderMap CL from
http://www.shadermap.renderingsystems.com/2) Create a bat file with the following contents:
Code:
CD "C:\Program Files\ShaderMap CL 1.2.2"
START /WAIT shadermap.exe cdiff "<texture_directory>\<texture_name>" -disp (60,100,12,xy) -norm (100,200,xy,0) -spec (100,-50,52,xy) -v
Replace the directory and texture name with what you want to generate maps for.
3) Generate the maps by running the bat script, once for each texture.
4) Use the following code to combine the images:
Code:
Ogre::Image combined;
combined.loadTwoImagesAsRGBA("moos1.jpg", "moos1_SPEC.bmp",
Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, Ogre::PF_BYTE_RGBA);
combined.save("moos1_diffusespecular.png");
combined.loadTwoImagesAsRGBA("moos1_NORM.tga", "moos1_DISP.bmp",
Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, Ogre::PF_BYTE_RGBA);
combined.save("moos1_normalheight.png");
You need to have the 16 source texture somewhere in declared resource location, so just put a directory called terraintex in 'media' and add a line to resources.cfg so that Ogre picks it up, ie '../media/terraintex'
5) Get the nVidida texture tools (DDS Utilities) and convert the output textures to dds.
Place the generated png's in the ddsutilities directory, open up a console and run this:
Code:
nvdxt.exe -all -dxt3
6) Done.

Of course, you can replace step 4 with whatever method you have to load a greyscale map into the alphachannel, using Photoshop or the Gimp or any other tool.
Now we have a heightmap, a set of 8 textures and 4 alphamap textures.
And we are ready to load that into Ogre.
Code:
// a light for the ligthmap
Ogre::Vector3 lightdir(0, -0.3, 0.75);
lightdir.normalise();
Ogre::Light* l = sceneMgr->createLight("tstLight");
l->setType(Ogre::Light::LT_DIRECTIONAL);
l->setDirection(lightdir);
l->setDiffuseColour(Ogre::ColourValue(1.0, 1.0, 1.0));
l->setSpecularColour(Ogre::ColourValue(0.4, 0.4, 0.4));
sceneMgr->setAmbientLight(Ogre::ColourValue(0.6, 0.6, 0.6));
// global terrain options
Ogre::TerrainGlobalOptions::setMaxPixelError(1); // set to 1 if using 1 unit/1 metre (ie pagesize of 1024)
Ogre::TerrainGlobalOptions::setCompositeMapDistance(2000);
Ogre::TerrainGlobalOptions::setLightMapDirection(lightdir);
Ogre::TerrainGlobalOptions::setCompositeMapAmbient(sceneMgr->getAmbientLight());
Ogre::TerrainGlobalOptions::setCompositeMapDiffuse(l->getDiffuseColour());
// create new instance of Ogre::Terrain
mTerrain = OGRE_NEW Ogre::Terrain(sceneMgr);
// load the heightmap from the RAW file
Ogre::DataStreamPtr stream = Ogre::ResourceGroupManager::getSingleton().openResource("demoraw.raw", "General" );
size_t size = stream.get()->size();
if(size != 1025 * 1025 * 4)
{
OGRE_EXCEPT( Ogre::Exception::ERR_INTERNAL_ERROR, "Size of stream does not match terrainsize!", "TerrainPage" );
}
float* buffer = OGRE_ALLOC_T(float, size, Ogre::MEMCATEGORY_GENERAL);
stream->read(buffer, size);
// import settings
Ogre::Terrain::ImportData imp;
imp.terrainSize = 1025;
imp.worldSize = 1024;
imp.inputFloat = buffer;
imp.minBatchSize = 33;
imp.maxBatchSize = 65;
// textures
imp.layerList.resize(4);
imp.layerList[0].textureNames.push_back("gras_diffusespecular.dds");
imp.layerList[0].textureNames.push_back("gras_normalheight.dds");
imp.layerList[0].worldSize = 30;
imp.layerList[1].textureNames.push_back("moos1_diffusespecular.dds");
imp.layerList[1].textureNames.push_back("moos1_normalheight.dds");
imp.layerList[1].worldSize = 30;
imp.layerList[2].textureNames.push_back("schlamm_getrocknet2_diffusespecular.dds");
imp.layerList[2].textureNames.push_back("schlamm_getrocknet2_normalheight.dds");
imp.layerList[2].worldSize = 30;
imp.layerList[3].textureNames.push_back("moos2_diffusespecular.dds");
imp.layerList[3].textureNames.push_back("moos2_normalheight.dds");
imp.layerList[3].worldSize = 20;
mTerrain->prepare(imp);
mTerrain->load();
// blend maps (alphamaps)
Ogre::String blendImages[4];
blendImages[0] = "gras_00000_00000_000.PNG";
blendImages[1] = "moos1_00000_00000_000.PNG";
blendImages[2] = "schlamm_getrocknet2_00000_00000_000.PNG";
blendImages[3] = "moos2_00000_00000_000.PNG";
// load those blendmaps into the layers
for(int j = 1;j < mTerrain->getLayerCount();j++)
{
Ogre::TerrainLayerBlendMap *blendmap = mTerrain->getLayerBlendMap(j);
Ogre::Image img;
img.load(blendImages[j],"General");
int blendmapsize = mTerrain->getLayerBlendMapSize();
if(img.getWidth() != blendmapsize)
img.resize(blendmapsize, blendmapsize);
float *ptr = blendmap->getBlendPointer();
Ogre::uint8 *data = static_cast<Ogre::uint8*>(img.getPixelBox().data);
for(int bp = 0;bp < blendmapsize * blendmapsize;bp++)
ptr[bp] = static_cast<float>(data[bp]) / 255.0f;
blendmap->dirty();
blendmap->update();
}
// clean up
mTerrain->freeTemporaryResources();
// adjust the position of the terrain (Ogre uses the centre of the terrain as 0,0,0
mTerrain->setPosition(Ogre::Vector3(512,0,512));
So, all we need is to compile and run our terrain application, and this is what we see:
Attachment:
screenshot01222010_152120213.jpg [ 105.03 KiB | Viewed 118 times ]