I'm using XNA 4.0 in C# (.net framework 4.0) (windows xp sp3, so directx9)
Loading a .png as a height-map and creating terrain from that data. basically following tutorial at reimers.net
(.png is < 256x256 -- not very large, not too many points in the buffers)
Anyway, I get the terrain data created, that works fine. (as in the tutorial) I create an array if indices and vertices which can be used with GraphicsDevice.DrawUserIndexPrimitive() -- but this must send the data from cpu to gpu each frame, so there is a relatively small data size limit.
So now I'm trying to use VertextBuffer and IndexBuffer, so the data can be stored on the gpu.
The problem: When I draw it as wireframe, my fps drops WAY down...like 2-4 fps.
The weird thing: When I was first rendering terrain, and sending the data from cpu to gpu, wireframe worked at 60fps just like FillMode = Solid. However, now that I'm using VertexBuffer and IndexBuffer, wireframe goes 2-4 fps I'm not sure why. It's not really a problem yet, because I plan to render the terrain solid ofc..but I'm curious as to why it's so much slower. The vertex/index buffers are on the gpu, so why is wireframe rendering taking so much longer? I even tried messing with Cullmode = none/clock/counter , which helped some, but still less fps than when sending the data each frame. Which doesn't make sense.
Here the terrain section of my Draw() method.
Code:
..
_wireFrame = new RasterizerState();
_wireFrame.CullMode = CullMode.None ; // tried CW And CCW: performance gain! but still < 40fps
_wireFrame.FillMode = FillMode.WireFrame;
..
..
public void Draw()
{
..
..
//Draw terrain
_gameEngine.GraphicsDevice.RasterizerState = _wireFrame; // _noCulling;
_gameEngine.GraphicsDevice.Indices = _terrain.IndexBuffer;
_gameEngine.GraphicsDevice.SetVertexBuffer(_terrain.VertexBuffer);
_drawEffects.Parameters["xView"].SetValue(ViewMatrix);
_drawEffects.Parameters["xProjection"].SetValue(Projecti********);
_drawEffects.Parameters["xWorld"].SetValue(_terrain.WorldMatrix);
foreach (EffectPass pass in _drawEffects.CurrentTechnique.Passes)
{
pass.Apply();
//_gameEngine.GraphicsDevice.DrawUserIndexedPrimitives(PrimitiveType.TriangleList,_terrain._vertices, 0, _terrain._vertices.Length, _terrain._indices, 0, _terrain._indices.Length / 3, VertexPositionColor.VertexDeclaration);
_gameEngine.GraphicsDevice.DrawIndexedPrimitives(PrimitiveType.TriangleList, 0, 0, _terrain.VerticesCount, 0, _terrain.IndicesCount / 3);
}
(the commented line under pass.Apply() was my first method of drawing terrain. Now i store the data on gpu via vertex/index buffers.
So, why the drop in speed?
Any comments appreciated.
edit:
figured out the problem (well, not really)
Basically WireFrame goes really slow if you have too many points on screen.
Solid doesn't have this problem.
So: Apparently when the terrain is rendered SOLID, cullmode doesn't matter. Setting it to None will still leave FPS at 60+ even if all the points are currently on screen.
When you render it in WireFrame, cullmode matters and fps CRAWLS if you have too many points on screen.
Just kind of took my by surprise, but I guess it should make sense.
Since I'm not planning (yet?) on using wireframe for anything, it's not really a problem: a 512x512 image worth of points will show at 60+ fps, as long as it's Solid. I'll be doing stress tests soon.
.
.
A Bunch of screenshots below
(pretty cheesy, but cool at how many looks you can get with only modifying a few lines of code)
.
few different effects by only changing a couple lines of code
and when you scale up the map coordinates (the two constants in my code that were = 1)
you get semi-real world sized terrain. At the cost of a 256x256 picture. Pretty cool.
Since I just got a few random heightmaps from google, it doesn't look "like a level", but you can see the potential.
.
.
Next: I guess I should make some type of terrain editor, but the math behind line-of-sight and figuring out which poly the cursor would be on scares me a little. So for now I'm just going manually make a few heightmaps and work on loading them together and how to swap them in and out of memory as you move. And adding textures of course (and lod(?!)) so the ground looks better. And before that, actually keeping the player on the terrain and semi-realistic climb/slide physics. I know there are dozens of ways to do this, and it all depends on the type of game you're making. I'm going for semi-open world like most mmorpg's have where you can travel most of the world without a loading screen. If anyone wants to do something similar, or has advice, or questions, reply plz.
moved to C# Programming Section due to lack of activity here
mod please erase?