Jump to content
  • Advertisement
Sign in to follow this  
lougv22

Terrain not displaying correctly in xna 4.0 game

This topic is 2276 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

[color=#4A4A4A]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:

[color=#4A4A4A]XNA_TPS_Terrain_0.png

[color=#4A4A4A]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);


[color=#4A4A4A]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();
}


[color=#4A4A4A]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);
}


[color=#4A4A4A]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);
}
}


[color=#4A4A4A]And finally, here is how all the files for the terrain are organized in my Content folder:

[color=#4A4A4A]XNA_TPS_Terrain_Content_0.png

[color=#4A4A4A]So any ideas why it wouldn't display correctly?

Share this post


Link to post
Share on other sites
Advertisement

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. [color=#4A4A4A]Also, I was playing around with the Transformation (translate, rotate, scale) attributes of the Terrain by adding the following line:

[color=#4A4A4A]
// 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);


[color=#4A4A4A]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:

[color=#4A4A4A]XNA_TPS_Terrain_1.png

[color=#4A4A4A]XNA_TPS_Terrain_2.png

[color=#4A4A4A]XNA_TPS_Terrain_3.png

[color=#4A4A4A]And finally, this is what the game should look like if everything works correctly (this is a screenshot from a YouTube video somebody posted):

[color=#4A4A4A]XNA_TPSFinal.png

Share this post


Link to post
Share on other sites
One problem that I spotted as I skimmed your code.


[color=#000000]_numVertices [color=#666600]=[color=#000000] _vertexCountX [color=#666600]*[color=#000000] _vertexCountZ[color=#666600];

[color=#666600]_vertexCountX = width map texture width
[color=#666600]_vertexCountX = height map texture width

[color=#666600]Pretend width/height is 1. Then _vertexCountX should be 4, not 1.

[color=#666600]Try creating a 2x2 height map and getting that to work properly. It's a lot easier to debug.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

Participate in the game development conversation and more when you create an account on GameDev.net!

Sign me up!