History: Mogre Basic Tutorial 3b
Preview of version: 7
Terrain
The New Terrain Component
Since Ogre 1.7 there is a new component for Terrain. It will replace the old Terrain SceneManager in Ogre 1.8. So far the problem was that in Mogre 1.7 this new component is not yet included. But now maintainer mstoyke created an alpha version. To use it you need a version of Mogre that is compiled from the branch "TerrainAndPaging" (for example the binaries user Cygon provided here).
Introduction
The project we will make in this tutorial consists of two main components: TerrainGroup and Terrain. There are also TerrainGlobalOptions, but they are used as a supplementary component. You can imagine TerrainGroup as a moderate zone like a glade, meadow or play-field. TerrainGroup can aggregate a bunch of Terrain pieces inside. This subdivision is used for LOD rendering, which is based on the camera's distance to each of the Terrains. In turn, Terrains consist of tiles with some material strained over them. We will use a single TerrainGroup without paging; Terrain systems using paging will be described in Intermediate tutorials.
Before we render the Terrain, we must set up all the necessary parameters of the Ogre Terrain System.
Global variables
Because the code to set up the terrain is plit up into multiple methods we need three global options:
TerrainGlobalOptions mTerrainGlobals; TerrainGroup mTerrainGroup; bool mTerrainImported;
Dealing with the camera
First, let's modify our Camera object for our terrain. Put this code in the CreateScene() function:
protected override void CreateScene() { // setting up the camera mCamera.Position = new Vector3(1683, 50, 2116); mCamera.LookAt(new Vector3(1963, 50, 1660)); mCamera.NearClipDistance = 0.1f; mCamera.FarClipDistance = 50000; if (mRoot.RenderSystem.Capabilities.HasCapability(Capabilities.RSC_INFINITE_FAR_PLANE)) mCamera.FarClipDistance = 0;
What it does, besides setting the position and orientation of the camera, is adjust the near and far clip distances. A terrain is often fairly big, and we want our camera to be able to see far into the distance. If the RenderSystem supports it, make it infinite.
Setting up directional and ambient light
The Terrain component uses a directional light to compute the terrain lightmap, so let's put a directional light into our scene (in the CreateScene() method):
// setting up the light Vector3 lightDir = new Vector3(0.55f, -0.3f, 0.75f); lightDir.Normalise(); Light light = mSceneMgr.CreateLight("tstLight"); light.Type = Light.LightTypes.LT_DIRECTIONAL; light.Direction = lightDir; light.DiffuseColour = ColourValue.White; light.SpecularColour = new ColourValue(0.4f, 0.4f, 0.4f); mSceneMgr.AmbientLight = new ColourValue(0.2f, 0.2f, 0.2f);
We also set some ambient light to smooth out the lighting.
Configuring our terrain
First, we create a new set of global terrain options. For this task TerrainGlobalOptions class is used. It is an options class which just stores default options for all terrains we will create and provides a Properties. There are also local options to each TerrainGroup called DefaultImportSettings, which you will see later.
mTerrainGlobals = new TerrainGlobalOptions();
Then we construct our TerrainGroup object - a helper class to manage a grid of terrains but it does not do any paging (which is done by the paging component you can see in Intermediate tutorials soon).
mTerrainGroup = new TerrainGroup(mSceneMgr, Terrain.Alignment.ALIGN_X_Z, 513, 12000.0f); mTerrainGroup.SetFilenameConvention("BasicTutorialTerrain3", "dat"); mTerrainGroup.Origin = Vector3.ZERO;
The TerrainGroup class constructor takes our SceneManager instance, Terrain alignment option, terrain size and terrain world size as parameters. Then we tell the TerrainGroup what name we would like it to use when saving our terrain, using the SetFilenameConvention function. And lastly we set the origin of the terrain group.
Now it's time to configure our terrain:
ConfigureTerrainDefaults(light);
We'll deal with the configureTerrainDefaults function later. Notice that we're passing our directional light to the function. And then we define our terrains and instruct the TerrainGroup to load them all: