Ogre::Terrain - Simple Material Generator for .material

A place for users of OGRE to discuss ideas and experiences of utilitising OGRE in their games / demos / applications.

Ogre::Terrain - Simple Material Generator for .material

Postby Nauk » Sun Sep 09, 2012 5:53 pm

Hello everyone, since the question keeps coming up, with the Ogre::Terrain documentation still being really thin and it took me quite some hours to figure out how it works too I thought I'd share my findings back:

Short Version:
Code: Select all
This sample shows how to use your old fashioned Ogre material with Ogre::Terrain.

The sample consists of a very basic and simple TerrainMaterialGenerator that appends the global terrain normalmap to the chosen Ogre material and a simple CG 2.x singlepass 9 texture splatting shader with dynamic lighting, 3 splattmaps, global lightmap and global colourmap support.

More or less typical ArtifexTerra / ETM terrain data. I tried to find how to get a multipass material to work, but I didn't manage or find a solution to avoid the skirts flashing through in a very disturbing way. So if anyone knows how to do that it would be great if you could share your knowledge :). The shader works with common JPG and PNG textures, so no DDS required. And of course you don't need the provided shaders, any single pass material works.

There is still a small glitch with the dynamic lighting, in certain light angles the tiles seem to have slightly different lighting, if anyone has a clue how to fix it... would be great :)
Edit: *apparently there is something wrong with the tangent calculation, working on a fix.

You can download the whole sample with textures etc as zip here: https://sourceforge.net/projects/artifexterra3d/files/

Image

Usage:
Code: Select all
// Init custom materialgenerator
TerrainMaterialGeneratorPtr terrainMaterialGenerator;

// Set Ogre Material  with the name "TerrainMaterial" in constructor
TerrainMaterial *terrainMaterial = OGRE_NEW TerrainMaterial("TerrainMaterial");         
terrainMaterialGenerator.bind( terrainMaterial ); 
               
terrainGlobals->setDefaultMaterialGenerator( terrainMaterialGenerator );
Note: this needs to be done before your load your terrain.

Change Terrain material:
Code: Select all
terrainMaterial->setMaterialByName("MyOtherMaterialName");


TerrainMaterial.h v1.0:
Code: Select all
#ifndef TERRAINMATERIAL_H
#define TERRAINMATERIAL_H

// V1.0

#include "Ogre.h"
#include "OgreTerrain.h"
#include "OgreTerrainMaterialGenerator.h"

    class TerrainMaterial : public Ogre::TerrainMaterialGenerator
    {
    public:
      
      TerrainMaterial(Ogre::String materialName, bool addNormalmap=true, bool cloneMaterial=true);
      
      void setMaterialByName(const Ogre::String materialName);
      void addNormalMapOnGenerate(bool set) { mAddNormalMap=set; };
      void cloneMaterialOnGenerate(bool set) { mCloneMaterial=set; };

      Ogre::String getMaterialName() { return mMaterialName; };
       
        class Profile : public Ogre::TerrainMaterialGenerator::Profile
        {
        public:
            Profile(Ogre::TerrainMaterialGenerator* parent, const Ogre::String& name, const Ogre::String& desc);
            ~Profile();

            bool isVertexCompressionSupported() const { return false; }

            Ogre::MaterialPtr generate(const Ogre::Terrain* terrain);

            Ogre::MaterialPtr generateForCompositeMap(const Ogre::Terrain* terrain);

            Ogre::uint8 getMaxLayers(const Ogre::Terrain* terrain) const;

            void updateParams(const Ogre::MaterialPtr& mat, const Ogre::Terrain* terrain);

            void updateParamsForCompositeMap(const Ogre::MaterialPtr& mat, const Ogre::Terrain* terrain);

            void requestOptions(Ogre::Terrain* terrain);       

        };
    protected:         
      Ogre::String mMaterialName;
      bool mCloneMaterial;
      bool mAddNormalMap;
    };
   
#endif



TerrainMaterial.cpp v1.0:
Code: Select all
#include "TerrainMaterial.h"

   TerrainMaterial::TerrainMaterial(Ogre::String materialName, bool addNormalmap, bool cloneMaterial)
      : mMaterialName(materialName), mAddNormalMap(addNormalmap), mCloneMaterial(cloneMaterial)
    {
        mProfiles.push_back(OGRE_NEW Profile(this, "OgreMaterial", "Profile for rendering Ogre standard material"));
        setActiveProfile("OgreMaterial");
    }
   
    void TerrainMaterial::setMaterialByName(const Ogre::String materialName) {
      mMaterialName = materialName;
      _markChanged();
    };

    // -----------------------------------------------------------------------------------------------------------------------

    TerrainMaterial::Profile::Profile(Ogre::TerrainMaterialGenerator* parent, const Ogre::String& name, const Ogre::String& desc)
        : Ogre::TerrainMaterialGenerator::Profile(parent, name, desc)       
    {
    };

    TerrainMaterial::Profile::~Profile()
    {
    };

    Ogre::MaterialPtr TerrainMaterial::Profile::generate(const Ogre::Terrain* terrain)
    {
      const Ogre::String& matName = terrain->getMaterialName();       

      Ogre::MaterialPtr mat = Ogre::MaterialManager::getSingleton().getByName(matName);
      if (!mat.isNull())
         Ogre::MaterialManager::getSingleton().remove(matName);

      TerrainMaterial* parent = (TerrainMaterial*)getParent();

      // Set Ogre material
      mat = Ogre::MaterialManager::getSingleton().getByName(parent->mMaterialName);

      // Clone material
      if(parent->mCloneMaterial) {
         mat = mat->clone(matName);
         parent->mMaterialName = matName;
      }
      
      // Add normalmap
      if(parent->mAddNormalMap) {
         // Get default pass
         Ogre::Pass *p = mat->getTechnique(0)->getPass(0);      

         // Add terrain's global normalmap to renderpass so the fragment program can find it.
         Ogre::TextureUnitState *tu = p->createTextureUnitState(matName+"/nm");

         Ogre::TexturePtr nmtx = terrain->getTerrainNormalMap();
         tu->_setTexturePtr(nmtx);   
      }
      
      return mat;
    };
   
    Ogre::MaterialPtr TerrainMaterial::Profile::generateForCompositeMap(const Ogre::Terrain* terrain)
    {
      return terrain->_getCompositeMapMaterial();
    };

    Ogre::uint8 TerrainMaterial::Profile::getMaxLayers(const Ogre::Terrain* terrain) const
    {
        return 0;
    };

    void TerrainMaterial::Profile::updateParams(const Ogre::MaterialPtr& mat, const Ogre::Terrain* terrain)
    {
    };

    void TerrainMaterial::Profile::updateParamsForCompositeMap(const Ogre::MaterialPtr& mat, const Ogre::Terrain* terrain)
    {
    };

    void TerrainMaterial::Profile::requestOptions(Ogre::Terrain* terrain)
    {
        terrain->_setMorphRequired(false);
        terrain->_setNormalMapRequired(true); // enable global normal map
        terrain->_setLightMapRequired(false);
        terrain->_setCompositeMapRequired(false);
    };



Note: The following material files are optional samples and you don't really need them.
CG 2_x Vertex Shader terrain_vp.cg:
Code: Select all
    void terrain_vp(
       float4 position : POSITION,
       float2 uv      : TEXCOORD0,
       float delta     : BLENDWEIGHT,

       out float4 oPosition : POSITION,
       out float2 oUv       : TEXCOORD0,
       out float4 oColor    : COLOR,
      
       uniform float4 ambient,
       uniform float4x4 worldViewProj,
       uniform float morphFactor
       )
    {
       position.y = position.y + (delta.x * morphFactor);
       oPosition = mul(worldViewProj, position);
       oUv = uv;
       oColor = ambient;
    }


CG 2_x Fragment Shader terrain_fp.cg:
Code: Select all
float4 expand(float4 v)
{
   return v * 2 - 1;
}

void terrain_fp
(
  float2 iTexCoord0 : TEXCOORD0,
  float4 iPosition : TEXCOORD1,
  float iAmbient    : COLOR,
 
  uniform float4 lightDiffuse,
  uniform float4 lightSpecular,
  uniform float exponent,
  uniform float4 lightPosition,
  uniform float3 eyePosition,
  uniform float4 attenuation,
 
  out float4 oColor : COLOR,
 
  uniform sampler2D covMap1,
  uniform sampler2D covMap2,
  uniform sampler2D covMap3,
  uniform sampler2D splat1,
  uniform sampler2D splat2,
  uniform sampler2D splat3,
  uniform sampler2D splat4,
  uniform sampler2D splat5,
  uniform sampler2D splat6,
  uniform sampler2D splat7,
  uniform sampler2D splat8,
  uniform sampler2D splat9,
  uniform sampler2D colourMap,
  uniform sampler2D lightMap,
   
  /* global normalmap is added by the TerrainMaterialGenerator to TerrainMaterial
   since Ogre::Terrain doesn't have vertex normals */   
  uniform sampler2D normalMap,
 
  uniform float splatScaleX,
  uniform float splatScaleZ
)
{
   float3 cov1 = tex2D(covMap1, iTexCoord0).rgb;
   float3 cov2 = tex2D(covMap2, iTexCoord0).rgb;
   float3 cov3 = tex2D(covMap3, iTexCoord0).rgb;

   // save TexCoord for Global Textures
   float2 globalTexCoord = iTexCoord0;

   iTexCoord0.x *= splatScaleX;
   iTexCoord0.y *= splatScaleZ;

   // calculate Splatting
   oColor = tex2D(splat1, iTexCoord0) * cov1.x
           + tex2D(splat2, iTexCoord0) * cov1.y
           + tex2D(splat3, iTexCoord0) * cov1.z
           + tex2D(splat4, iTexCoord0) * cov2.x
           + tex2D(splat5, iTexCoord0) * cov2.y
           + tex2D(splat6, iTexCoord0) * cov2.z
         + tex2D(splat7, iTexCoord0) * cov3.x
         + tex2D(splat8, iTexCoord0) * cov3.y
         + tex2D(splat9, iTexCoord0) * cov3.z;   
   // add global Colourmap      
   oColor *= tex2D(colourMap, globalTexCoord);      
   // add global Lightmap
   oColor *= tex2D(lightMap, globalTexCoord); //*tex2D(lightMap, globalTexCoord);   
   
   // lighting
   float3 normal = expand(tex2D(normalMap, globalTexCoord)).rgb;   
   normal = normalize(normal);

   float3 lightDir = lightPosition.xyz - (iPosition.xyz * lightPosition.w);
   lightDir = normalize(lightDir);
   
   float distance = length(lightDir);
   float lumination = 1 / (attenuation.y + attenuation.z * distance + attenuation.w * distance * distance);

   lumination = min(lumination, 1.0);

   float3 eyeDir = normalize(eyePosition - iPosition.xyz);
   eyeDir = normalize(eyeDir);

   float3 halfAngle = normalize(lightDir + eyeDir);

   float NdotL = dot(lightDir, normal);
   float NdotH = dot(halfAngle, normal);
   float4 Lit = lit(NdotL, NdotH, exponent);

   // add lighting to color
   oColor *= iAmbient + lumination * (lightDiffuse * Lit.y + lightSpecular * Lit.z * Lit.y);   
}


Program File terrain.program:
Code: Select all
vertex_program Terrain/Programs/TerrainVP cg
{
   source TerrainVP.cg
   entry_point terrain_vp
   profiles vs_2_x arbvp1

   default_params
   {
      param_named_auto morphFactor custom 77
      param_named_auto worldViewProj worldviewproj_matrix
      param_named_auto ambient ambient_light_colour
   }
}
fragment_program Terrain/Programs/TerrainFP cg
{
   source TerrainFP.cg
   entry_point terrain_fp
   profiles ps_2_x arbfp1
   default_params
   {
      param_named_auto lightDiffuse light_diffuse_colour 0
      param_named_auto lightSpecular light_specular_colour 0
      
      param_named_auto lightPosition light_position_object_space 0
      param_named_auto eyePosition camera_position_object_space
      
      param_named_auto attenuation light_attenuation 0
   }
}


Material file terrain.material:
Code: Select all
material TerrainMaterial 
{

  technique
  {
    // requires PS 2.x
      
    pass
    {
      vertex_program_ref Terrain/Programs/TerrainVP
      {
      }
     
      fragment_program_ref Terrain/Programs/TerrainFP
      {      
      param_named exponent float 63
                param_named splatScaleX float 96
      param_named splatScaleZ float 96
      }
     
      texture_unit 0
      {
         // first coverage map
         texture ETcoverage.0.png
      }
      texture_unit 1
      {
         // second coverage map
         texture ETcoverage.1.png
      }
      texture_unit 2
      {
         // third coverage map
         texture ETcoverage.2.png
      }

      // splatting textures
      texture_unit 3
      {
         texture splatting0.png
      }
      texture_unit 4
      {
         texture splatting1.png
      }
      texture_unit
      {
         texture splatting2.png
      }
      texture_unit
      {
         texture splatting3.png
      }
      texture_unit
      {
         texture splatting4.png
      }
      texture_unit
      {
         texture splatting5.png
      }
      texture_unit
      {
         texture splatting6.png
      }
      texture_unit
      {
         texture splatting7.png
      }
      texture_unit
      {
         texture splatting8.png
      }   

      texture_unit
      {
         texture artifexterra3d_colourmap.png
      }
      
      texture_unit
      {
         texture ETlightmap.png
      }
    } // pass
   
} // technique

}




Going to set a wiki page up with it when I find the time. Hope this is of use for some of you. Feedback, critics and improvment are most welcome. :)
//Nauk
Last edited by Nauk on Tue Sep 25, 2012 11:57 pm, edited 9 times in total.

For this message the author Nauk has received 4 kudos
User avatar
Nauk
Gnoll
 
Posts: 647
Kudos: 25
Joined: 11 May 2006
Location: Bavaria

Re: Ogre::Terrain - Simple Material Generator for .material

Postby Chapiscado » Mon Sep 17, 2012 5:37 am

Congratulations! This help was very useful to me!
One question: do you know how to change the texture or material at runtime?
I tried using the SetMaterialByName and upgrade the ground but could not ...

thank you
Chapiscado
Gnoblar
 
Posts: 3
Kudos: 0
Joined: 10 Jan 2012

Re: Ogre::Terrain - Simple Material Generator for .material

Postby Nauk » Mon Sep 17, 2012 6:26 pm

Chapiscado wrote:Congratulations! This help was very useful to me!
One question: do you know how to change the texture or material at runtime?
I tried using the SetMaterialByName and upgrade the ground but could not ...

thank you


Thank you, glad it was of help :)

I tried using the SetMaterialByName and upgrade the ground but could not ...
You need to call generate again, after you set the material name to a new material.

Code: Select all
terrainMaterial->setMaterialByName("test");
terrainMaterial->generate(mTerrainGroup->getTerrain(0,0));


*Edit:* going to change that in the next version, so setMaterialByName does that automatically.
User avatar
Nauk
Gnoll
 
Posts: 647
Kudos: 25
Joined: 11 May 2006
Location: Bavaria

Re: Ogre::Terrain - Simple Material Generator for .material

Postby Chapiscado » Wed Sep 19, 2012 6:04 pm

It is Necessary to call some method to update?
I tried using this code and this has not changed anything.
What I'm really wanting to get to the the texture is applied field, modify it and update it at runtime. Got it?
Thank you for your attention
Chapiscado
Gnoblar
 
Posts: 3
Kudos: 0
Joined: 10 Jan 2012

Re: Ogre::Terrain - Simple Material Generator for .material

Postby Nauk » Thu Sep 20, 2012 12:49 pm

Chapiscado wrote:It is Necessary to call some method to update?

Jap :)

Chapiscado wrote:What I'm really wanting to get to the the texture is applied field, modify it and update it at runtime.

You can see halfway how to do that in the TerrainMaterial.cpp where the normalmap is added. Iterate through the texture unit states (textures)
of the material pass and use Ogre::TextureUnitState::setTexture on the texture you want to change should do the trick.
User avatar
Nauk
Gnoll
 
Posts: 647
Kudos: 25
Joined: 11 May 2006
Location: Bavaria

Re: Ogre::Terrain - Simple Material Generator for .material

Postby Nauk » Mon Sep 24, 2012 11:41 am

I tried using the SetMaterialByName and upgrade the ground but could not ...
You need to call generate again, after you set the material name to a new material.

Code: Select all
terrainMaterial->setMaterialByName("test");
terrainMaterial->generate(mTerrainGroup->getTerrain(0,0));



Actually I just found out that does not work always, when I tested that I did it short after the terrain was loaded where it still worked while later on during execution it didn't, sorry for the confusion. Correct would be:
Code: Select all
terrainMaterial->setMaterialByName("test");
terrainMaterial->_markChanged();
User avatar
Nauk
Gnoll
 
Posts: 647
Kudos: 25
Joined: 11 May 2006
Location: Bavaria

Re: Ogre::Terrain - Simple Material Generator for .material

Postby Nauk » Tue Sep 25, 2012 3:02 pm

Update:
- setMaterialByName() now calls _markChanged() so that's all you need to change the material.
- 2 new constructor parameters which let you decide wether the normalmap is added to your material or not and if you want the material cloned so you can get Ogre::Terrain autonaming for it.
User avatar
Nauk
Gnoll
 
Posts: 647
Kudos: 25
Joined: 11 May 2006
Location: Bavaria

Re: Ogre::Terrain - Simple Material Generator for .material

Postby Arkiruthis » Wed Oct 10, 2012 11:11 am

Many thanks for this! Particularly useful as I have a custom terrain shader that I want to use with the Ogre Terrain.

Something that's confusing me though is how you access the Terrain's normal map?

In the FP:
Code: Select all
  /* global normalmap is added by the TerrainMaterialGenerator to TerrainMaterial
   since Ogre::Terrain doesn't have vertex normals */   
  uniform sampler2D normalMap,


In your example (in the FP), if I just pass "tex2d(normalMap, UV).rgb" to the fragment shader to see the normals, I get this:
Image

This doesn't look like a generated mesh normal map? Looks like "ETcoverage.0.png"?

In the custom TerrainMaterial::Profile::generate(const Ogre::Terrain* terrain):
Code: Select all
      // Add terrain's global normalmap to renderpass so the fragment program can find it.
      Ogre::TextureUnitState *tu = p->createTextureUnitState(matName+"/nm");
   
      // LOGGING LINE ADDED BY ME
      Ogre::LogManager::getSingletonPtr()->logMessage(matName+"/mn");

      Ogre::TexturePtr nmtx = terrain->getTerrainNormalMap();
        tu->_setTexturePtr(nmtx);


The log calls this material:
11:06:33: OgreTerrain/2309288290/mn

I need to access the terrain normal map in my custom shader but I'm still confused about where and how it's being accessed? I've probably missed something obvious.
Arkiruthis
Gremlin
 
Posts: 177
Kudos: 11
Joined: 24 Dec 2010

Re: Ogre::Terrain - Simple Material Generator for .material

Postby Arkiruthis » Wed Oct 10, 2012 11:27 am

Ah! After I removed all the other texture units, it appeared... I guess my GFX card has a tex unit limit lower than the shader was set for.

Image

Question: The custom material seems to be be applying a form of fog though (visible in that screenshot)? I'm not sure where this is happening in the code?
Arkiruthis
Gremlin
 
Posts: 177
Kudos: 11
Joined: 24 Dec 2010

Re: Ogre::Terrain - Simple Material Generator for .material

Postby Nauk » Thu Oct 11, 2012 9:25 am

Arkiruthis wrote:In the custom TerrainMaterial::Profile::generate(const Ogre::Terrain* terrain):
Code: Select all
      // Add terrain's global normalmap to renderpass so the fragment program can find it.
      Ogre::TextureUnitState *tu = p->createTextureUnitState(matName+"/nm");
   
      // LOGGING LINE ADDED BY ME
      Ogre::LogManager::getSingletonPtr()->logMessage(matName+"/mn");

      Ogre::TexturePtr nmtx = terrain->getTerrainNormalMap();
        tu->_setTexturePtr(nmtx);


The log calls this material:
11:06:33: OgreTerrain/2309288290/mn

I need to access the terrain normal map in my custom shader but I'm still confused about where and how it's being accessed? I've probably missed something obvious.

The normal map is generated by Ogre::Terrain and yes that is the part where I retrieve and add it.

Arkiruthis wrote:Ah! After I removed all the other texture units, it appeared... I guess my GFX card has a tex unit limit lower than the shader was set for.

Image

Question: The custom material seems to be be applying a form of fog though (visible in that screenshot)? I'm not sure where this is happening in the code?

There is a fog setup in the sampleapp, just remove it, it is one line. Note I havent updated the zip archive yet, so the code I pasted here is the latest. And it seems your card is limited to shader model 2_0 which has I think only 2 texture registers, shader model 2_x has 16. So if you want to use more than 12 textures you would have to do multipass which leaves you with another problem: The terrain skirts are flashing which I still have not found a solution for.
User avatar
Nauk
Gnoll
 
Posts: 647
Kudos: 25
Joined: 11 May 2006
Location: Bavaria


Re: Ogre::Terrain - Simple Material Generator for .material

Postby Arkiruthis » Thu Oct 11, 2012 11:04 am

Nauk wrote:There is a fog setup in the sampleapp, just remove it, it is one line.

Ah yep, thanks, found it.

Nauk wrote:And it seems your card is limited to shader model 2_0 which has I think only 2 texture registers, shader model 2_x has 16. So if you want to use more than 12 textures you would have to do multipass which leaves you with another problem: The terrain skirts are flashing which I still have not found a solution for.


No worries, 16 is more than enough for my needs. Shader about 80% ported to OgreTerrain. :D
Image

I take it that if I want to have tangents in my shader, I can only do that in the fragment shader? (i.e. cross product of normalMap value to X-UNIT or Z-UNIT binomial)?

There's no way to offload any of these calculations to the vertex shader?
Arkiruthis
Gremlin
 
Posts: 177
Kudos: 11
Joined: 24 Dec 2010

Re: Ogre::Terrain - Simple Material Generator for .material

Postby Nauk » Thu Oct 11, 2012 6:44 pm

Wow, nice screenshot :) Not that I know, that is one of the drawbacks with not having the normals on the geometry and storing them in an image instead. 2_0 / 2_x vertex shaders cannot do texture lookups, aka tex2D(). I have no clue how to do it otherwise and I couldn't find something on the net. Well if you find something, let me know because I certainly would like to have that rather in the vertex shader too. And yeah you calculate it from the normal. There are severals ways to do it what I have seen:
Code: Select all
float3 tangent = float3(1,0,0);
float3 binormal = cross(normal, tangent);


Code: Select all
float3 tangent  = float3(abs(normal.y) + abs(normal.z), abs(normal.x), 0); 


Code: Select all
float3 tangent;

float3 c1 = cross(normal, float3(0.0, 0.0, 1.0));
float3 c2 = cross(normal, float3(0.0, 1.0, 0.0));

if( length(c1) > length(c2) ) {
   tangent = c1;
} else {
   tangent = c2;
}

Not sure which one is actually the better more acurate one, I am still at the very beginning when it comes to 3D math, and fighting with lighting problems in the terrain shader at the moment, which I believe are rooted in the tangent calculation.
User avatar
Nauk
Gnoll
 
Posts: 647
Kudos: 25
Joined: 11 May 2006
Location: Bavaria

Re: Ogre::Terrain - Simple Material Generator for .material

Postby Nauk » Thu Oct 11, 2012 7:05 pm

I made a little QT testbed there to toy around with light and tangent settings. You can clearly see there is different lighting on the tiles, which I think might be tangent related? Lighting works fine for the per pixel lighting shader without texture normalmapping tho.
Image
User avatar
Nauk
Gnoll
 
Posts: 647
Kudos: 25
Joined: 11 May 2006
Location: Bavaria

Re: Ogre::Terrain - Simple Material Generator for .material

Postby raven_3rdwing » Tue Nov 27, 2012 10:45 pm

hi,
is it possible to send parameters to the shader from the C++ ogre side ? like setCustomParameter
thanks in advance .
raven_3rdwing
Gnoblar
 
Posts: 5
Kudos: 0
Joined: 28 Aug 2011
Location: France


Re: Ogre::Terrain - Simple Material Generator for .material

Postby raven_3rdwing » Wed Nov 28, 2012 1:35 pm


hi
thanks , i will try this evening
best regards
raven_3rdwing
Gnoblar
 
Posts: 5
Kudos: 0
Joined: 28 Aug 2011
Location: France

Re: Ogre::Terrain - Simple Material Generator for .material

Postby raven_3rdwing » Thu Nov 29, 2012 11:33 am

it works ! :D 1000 x thanks!!!!
raven_3rdwing
Gnoblar
 
Posts: 5
Kudos: 0
Joined: 28 Aug 2011
Location: France


Re: Ogre::Terrain - Simple Material Generator for .material

Postby Evorlde » Thu Aug 06, 2015 7:44 pm

Hi,

Sorry for this "ressurection of topic", but i need help on your tutorial.
I use your MaterialGenerator system and i want to know how can i do a setMaterialByName just on one terrain.

Actually when i do a setMaterialByName, it works but it reloads all my terrains present in my terrain group. I want to apply the modification just on one terrain.

Tank,
Evorlde
Gnoblar
 
Posts: 8
Kudos: 1
Joined: 25 Mar 2014


Return to Using OGRE in practice

Who is online

Users browsing this forum: No registered users and 5 guests