Jump to content

  • Log In with Google      Sign In   
  • Create Account

Terrain not displaying correctly in xna 4.0 game


Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

  • You cannot reply to this topic
3 replies to this topic

#1 lougv22   Members   -  Reputation: 226

Like
0Likes
Like

Posted 27 March 2012 - 07:19 PM

I am working on a simple Third-Person Shooter game in XNA 4.0 and I am currently having troubles getting the terrain to display correctly on the screen. Here is what it looks like now:

Posted Image

You can see it, but it definitely looks wrong. I am not sure what the problem is so I'll show some of my code related to the terrain, hopefully someone here can figure it out. First off, the terrain is initialized in my LevelCreator class like so:

private static GameLevel CreateAlienPlanetLevel(Game game)
{
		    ContentManager Content = game.Content;
		    GameLevel gameLevel = new GameLevel();

		    // Camera and lights
		    AddCameras(game, ref gameLevel);
		    gameLevel.LightManager = new LightManager();
		    gameLevel.LightManager.AmbientLightColor = new Vector3(0.1f, 0.1f, 0.1f);
		    gameLevel.LightManager.Add("MainLight", new PointLight(new Vector3(10000, 10000, 10000), new Vector3(0.2f, 0.2f, 0.2f)));
		    gameLevel.LightManager.Add("CameraLight", new PointLight(Vector3.Zero, Vector3.One));
 
		    game.Services.AddService(typeof(CameraManager), gameLevel.CameraManager);
		    game.Services.AddService(typeof(LightManager), gameLevel.LightManager);
 
		    // Terrain
		    gameLevel.Terrain = new Terrain(game);
		    gameLevel.Terrain.Initialize();
		    gameLevel.Terrain.Load(game.Content, "Terrain1", 8.0f, 1.0f);
 
		    // Terrain material
		    TerrainMaterial terrainMaterial = new TerrainMaterial();
		    terrainMaterial.LightMaterial = new LightMaterial(new Vector3(0.8f), new Vector3(0.3f), 32.0f);
		    terrainMaterial.DiffuseTexture1 = GetTextureMaterial(game, "Terrain1", new Vector2(40, 40));
		    terrainMaterial.DiffuseTexture2 = GetTextureMaterial(game, "Terrain2", new Vector2(25, 25));
		    terrainMaterial.DiffuseTexture3 = GetTextureMaterial(game, "Terrain3", new Vector2(15, 15));
		    terrainMaterial.DiffuseTexture4 = GetTextureMaterial(game, "Terrain4", Vector2.One);
		    terrainMaterial.AlphaMapTexture = GetTextureMaterial(game, "AlphaMap", Vector2.One);
		    terrainMaterial.NormalMapTexture = GetTextureMaterial(game, "Rockbump", new Vector2(128, 128));
		    gameLevel.Terrain.Material = terrainMaterial;
		    game.Services.AddService(typeof(Terrain), gameLevel.Terrain);

The Load method in my Terrain class looks like this:

public void Load(ContentManager content, string heightMapFileName, float blockScale, float heightScale)
{
		   if (!_isInitialized)
			    Initialize();
 
		    // Load the height map file
		    Texture2D heightMapTexture = content.Load<Texture2D>(heightMapFileName);
		    int heightMapSize = heightMapTexture.Width * heightMapTexture.Height;
		    _heightMap = new Color[heightMapSize];
			 heightMapTexture.GetData<Color>(_heightMap);
 
		    this._vertexCountX = heightMapTexture.Width;
		    this._vertexCountZ = heightMapTexture.Height;
		    this._blockScale = blockScale;
		    this._heightScale = heightScale;
 
		    // Load vertex declaration once
		    this._vertexDeclaration = new VertexDeclaration(VertexPositionNormalTangentBinormalTexture.VertexElements);
 
		    // Generate the terrain's mesh
		    GenerateTerrainMesh();
		    _transformation = new Transformation();
 
		    // Load effect
		    _effect = new TerrainEffect(Game.Content.Load<Effect>(TerrainEffect.EFFECT_FILENAME));
		    _terrainMaterial = new TerrainMaterial();
}

One of the methods I am not quite sure about is GenerateTerrainMesh, also in class Terrain. The reason I am not sure about it is because I ported the original code for it from XNA 3.0 to 4.0 and I know there are some differences there in the VertexBuffer and IndexBuffer class. Here it is:

private void GenerateTerrainMesh()
{
		    _numVertices = _vertexCountX * _vertexCountZ;
		    _numTriangles = (_vertexCountX - 1) * (_vertexCountZ - 1) * 2;
 
		    // Generate the terrain indices first
		    int[] indices = GenerateTerrainIndices();

		    // Next generate the terrain's vertices
		    VertexPositionNormalTangentBinormalTexture[] vertices = GenerateTerrainVertices(indices);
 
		    // Create a vertex buffer to hold all the vertices
		    _vertexBuffer = new VertexBuffer(GraphicsDevice, _vertexDeclaration, _numVertices, BufferUsage.WriteOnly);
		    _vertexBuffer.SetData<VertexPositionNormalTangentBinormalTexture>(vertices);
 
		    _indexBuffer = new IndexBuffer(GraphicsDevice, IndexElementSize.ThirtyTwoBits, _numTriangles * 3 * sizeof(int),
										    BufferUsage.WriteOnly);
		    _indexBuffer.SetData<int>(indices);
}

Another method I am not sure about, for the same reason as above, is Draw:

public override void Draw(GameTime gameTime)
{
		    // Configure TerrainEffect
		    SetEffectMaterial();
 
		    // Set mesh vertex and index buffer
		    GraphicsDevice.SetVertexBuffers(_vertexBuffer);
		    GraphicsDevice.Indices = _indexBuffer;
 
		    // Loop through all effect passes
		    foreach (EffectPass pass in _effect.CurrentTechniquePasses)
		    {
			    pass.Apply();
			    // Draw the mesh
			    GraphicsDevice.DrawIndexedPrimitives(PrimitiveType.TriangleList, 0, 0, _numVertices, 0, _numTriangles);
		    }
}

And finally, here is how all the files for the terrain are organized in my Content folder:

Posted Image

So any ideas why it wouldn't display correctly?

Sponsor:

#2 Darg   Members   -  Reputation: 209

Like
0Likes
Like

Posted 28 March 2012 - 05:36 PM

It looks like your camera might be underneath the terrain?
Portfolio & Blog:http://scgamedev.tumblr.com/

#3 lougv22   Members   -  Reputation: 226

Like
0Likes
Like

Posted 01 April 2012 - 11:48 AM

It looks like your camera might be underneath the terrain?


I am not sure that's the problem. I played around with my camera but that didn't seem to fix the issue. Also, I was playing around with the Transformation (translate, rotate, scale) attributes of the Terrain by adding the following line:

// Terrain
2			 gameLevel.Terrain = new Terrain(game);
3			 gameLevel.Terrain.Initialize();
4			 gameLevel.Terrain.Load(game.Content, "Terrain1", 8.0f, 1.0f);
5 
6			 // Terrain material
7			 TerrainMaterial terrainMaterial = new TerrainMaterial();
8			 terrainMaterial.LightMaterial = new LightMaterial(new Vector3(0.8f), new Vector3(0.3f), 32.0f);
9			 terrainMaterial.DiffuseTexture1 = GetTextureMaterial(game, "Terrain1", new Vector2(40, 40));
10			 terrainMaterial.DiffuseTexture2 = GetTextureMaterial(game, "Terrain2", new Vector2(25, 25));
11			 terrainMaterial.DiffuseTexture3 = GetTextureMaterial(game, "Terrain3", new Vector2(15, 15));
12			 terrainMaterial.DiffuseTexture4 = GetTextureMaterial(game, "Terrain4", Vector2.One);
13			 terrainMaterial.AlphaMapTexture = GetTextureMaterial(game, "AlphaMap", Vector2.One);
14			 terrainMaterial.NormalMapTexture = GetTextureMaterial(game, "Rockbump", new Vector2(128, 128));
15			 gameLevel.Terrain.Material = terrainMaterial;
16			 gameLevel.Terrain.Transformation = new GameBase.Transformation(new Vector3(0, -2600, 0), new Vector3(0, 200, 0), new Vector3(10, 10, 10));
17			 game.Services.AddService(typeof(Terrain), gameLevel.Terrain);


Line #16 is the new one. The first Vector3 in the Transformation constructor is the Translate attribute, second one is Rotate, and last one is Scale. Here are 3 screenshots with 3 different values of the Y Rotate attribute, 120, -120, and 200:

Posted Image

Posted Image

Posted Image

And finally, this is what the game should look like if everything works correctly (this is a screenshot from a YouTube video somebody posted):

Posted Image

#4 jameszhao00   Members   -  Reputation: 271

Like
0Likes
Like

Posted 01 April 2012 - 01:28 PM

One problem that I spotted as I skimmed your code.


_numVertices = _vertexCountX * _vertexCountZ;

_vertexCountX = width map texture width
_vertexCountX = height map texture width

Pretend width/height is 1. Then _vertexCountX should be 4, not 1.

Try creating a 2x2 height map and getting that to work properly. It's a lot easier to debug.




Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.



PARTNERS