Need Help with Index Buffer

Started by
5 comments, last by mozie 19 years, 3 months ago
I am trying to load a file I exported from 3D Studio. The file I exported contains 16 objects. To export I dumped all vertices to file in one long shot. Then for each object I dumped it's faces out to file. I am loading this info into DirectX. All vertices into one large VB and all face info into 16 different index buffers. When I run the program I see nothing. The model is centered at origin. It's extents are 1000+- in X and Y axes and 15+- on Z axis. I have a camera pointed at origin located 3500 units up (the z axis) so I should be looking straight down at the mesh. I've also -3500 units for the camera thinking it was a backfacing issue. Code to fill the vertex buffer

device.VertexFormat = CustomVertex.PositionColored.Format;
CustomVertex.PositionColored[] verts = new CustomVertex.PositionColored
                                       [_Vertexes.Count];
int i;
for(i=0; i<_Vertexes.Count; i++)
{
	verts.Position = new Vector3(((Vertex)_Vertexes).GetVertexX(),
                           ((Vertex)_Vertexes).GetVertexY(),
                           ((Vertex)_Vertexes).GetVertexZ());
	verts.Color = System.Drawing.Color.Aqua.ToArgb();
}
			
VertexBuffer vb = new VertexBuffer(typeof(CustomVertex.PositionColored), _Vertexes.Count, device, Usage.Dynamic | Usage.WriteOnly, CustomVertex.PositionColored.Format, Pool.Default);
vb.SetData(verts, 0, LockFlags.None);
device.SetStreamSource(0,vb, 0);

Code to fill and render Index Buffers

short[] indices;
int i;
indices = new short[_IndexArray.Count];
for(i=0; i<indices.Length; i++)
{
     indices = (short)_IndexArray;
}
IndexBuffer ib = new IndexBuffer(typeof(short), indices.Length, device, Usage.WriteOnly, Pool.Default);
device.Indices = ib;
device.DrawIndexedPrimitives(PrimitiveType.TriangleList,0, 0, 10521, 0,indices.Length/3);

Code to setup camera and other matrices

device.Transform.Projection = Matrix.PerspectiveFovLH((float)Math.PI/4, this.Width/this.Height, 1.0f, 10000.0f);
device.Transform.View = Matrix.LookAtLH(new Vector3(0,0, distance), new Vector3(0,0,0), new Vector3(0,1,0));
device.RenderState.Lighting = false;
device.Transform.World = Matrix.RotationZ(angle / (float)Math.PI);
device.RenderState.FillMode = FillMode.WireFrame;
angle += 0.1f;

distance is my z (it starts at 3500 and I can move it up or down with the keyboard) angle is simply used to rotate the camera around the z axis a little each frame. The mesh file contains 10521 vertices. The part of the mesh I want to render with the Index Buffer contains 3309 indices so 1103 faces to render out of a total of 18410 faces. However, nothing is showing up. Thanks for having a look, Webby
Advertisement
I've changed my code around a bit. Here's how it works now.
1) Mesh is initialized. This creates the vertex buffer one time. Then it creates all of the index buffers. I keep track of number of objects, faces, verts, etc at all steps.
2) The render loop now simply sets the StreamSource to my vb, then calls render on all of the IndexBuffer holding objects like this:
device.Indices = _ib;
device.DrawIndexedPrimitives(PrimitiveType.TriangleList,0, 0, 10521, _level5StartIndex, _numLevel5Indices/3);

During this call _numLevel5Indices = 3309 as expected. 10521 is still the total number of vertices.

My next step is to arrange the vertex buffer such that I can use the baseVertex parameter to DrawIndexedPrimitives instead of simply passing in the 10521 every time. However, still, nothing is showing up on the screen.

The code is pretty much like it was in the previous post so I won't relist it. The only things different are that I an initializing the buffers only once.

Thanks for any help,
Webby
I don't know C#, VB.Net, or whatever that is, however it doesn't appear that you're copying data into the index buffers, ever.

You shouldn't be constantly making new index buffers every time you render either. Make one at init, fill it in, then just keep using it. Right now I'd imagine the .NET garbage collection is working overtime to stop the CPU and GPU memory leaks you're throwing about... assuming it catches them at all. I've heard D3D has many unmanaged areas, and perhaps setting the index buffer passes the object to an unmanaged area, and .NET can no longer track if it's unused or not.
Guess I need to post new code after all :)

Initialization code for DirectX
public void Init(System.Windows.Forms.Control window){	_window = window;	//Set our presentation parameters	_presentParams = new Microsoft.DirectX.Direct3D.PresentParameters();	_presentParams.Windowed = true;	_presentParams.SwapEffect = SwapEffect.Discard;	_presentParams.AutoDepthStencilFormat = DepthFormat.D16;	_presentParams.EnableAutoDepthStencil = true;	//Create our device	_device = new Microsoft.DirectX.Direct3D.Device(0,                       DeviceType.Hardware, window,                       CreateFlags.HardwareVertexProcessing, _presentParams);}


//Setup vertex and Index buffers once
public void SetupVertexAndIndexBuffers(Device device){	//Set up the vertex buffer only once.				CustomVertex.PositionColored[] verts = new CustomVertex.PositionColored                                               [_terrainVertexes.Count];	int i;	for(i=0; i<_terrainVertexes.Count; i++)	{		verts.Position = new Vector3(((TerrainVertex)_terrainVertexes).GetVertexX(),((TerrainVertex)_terrainVertexes).GetVertexY(),((TerrainVertex)_terrainVertexes).GetVertexZ());		verts.Color = System.Drawing.Color.Aqua.ToArgb();	}				_vb = new VertexBuffer(typeof(CustomVertex.PositionColored),               _terrainVertexes.Count, device, Usage.WriteOnly,               CustomVertex.PositionColored.Format, Pool.Managed);	_vb.SetData(verts, 0, LockFlags.None);	SetupIndexBuffers(device);}public void SetupIndexBuffers(Device device){	int indicesNeeded = CalculateNumberOfIndices(); //Returns 3309	GetAllIndicesGrouped(indicesNeeded); //Initializes a private _indices array of shorts to the size indicesNeeded. Then loops through the required indices and copies them into the _indices array.					_ib = new IndexBuffer(typeof(short), _indices.Length, device,               Usage.WriteOnly, Pool.Default); //At this point indices.Length                                                 is 3309	_ib.SetData(_indices, 0, LockFlags.None);		//Free up this memory because we are done with it.	_indices = new short[0];}


Rendering code
device.VertexFormat = CustomVertex.PositionColored.Format;device.SetStreamSource(0, _vb, 0);device.Indices = _ib;device.DrawIndexedPrimitives(PrimitiveType.TriangleList,0, 0, 10521,                              _level5StartIndex, _numLevel5Indices/3); //Draw 1103 faces


Webby
Well, I've gotten it to render. Turns out my worlds matrix was off.
I needed Transform.World = Matrix.Translation(-1000,0,0); just to get something into view.

Now I've run into a different problem. I've exported a simple mesh from 3D Studio. It's a quad object converted to editable mesh. It contains 72 faces and 49 vertices.

I've checked and rechecked that all 72 faces get exported and loaded as well as all 49 of the vertices.

If I render a triangle list using DrawIndexedPrimitive like this
device.DrawIndexedPrimitives(PrimitiveType.TriangleList, 0, 0, 49, 0, 72);
I get part of the mesh correctly and parts of it are wayyyy off as shown below in the link below
Clicky

All z values of this mesh are 0.0 if that matters (not sure why it would).

Any ideas?
Thanks,
Webby
Turns out I had an index error. I was reading my buffer from 1 to x instead of 0 to x-1.

There are still issues but I have successfully gotten the mesh loaded and looking normal!!!

Webby
Quote:Original post by WebsiteWill
Turns out I had an index error. I was reading my buffer from 1 to x instead of 0 to x-1.
Webby


I hate when I miss something like that! Its fun trying to find a bug in the main content of the code, just to find it in the for() statement.

This topic is closed to new replies.

Advertisement