Having issues with offsets

Started by
8 comments, last by circlesoft 18 years, 2 months ago
So, I was originally developing this on a GF2 MX and it was working ok. Today I moved back to my X800, and things are messed up. I've nailed down the problem pretty much. Basically, each of my terrain patches has an offset into where in its VB it is located. If I use this offset for BaseVertexIndex in the DIP call, or as the offset for SetStreamSource (multiplied by vertex size), it works. If I add the offset directly to the indices, it only works for the case where offset = 0. That is, these two code blocks work fine:
foreach( Terrain.Patch p in terrain.VisPatches )
{
	buf = terrain.IndexBuffers[0].Lock<ushort>( 0, 0, LockFlags.Discard );
	buf.Write( p.Indices );
	terrain.IndexBuffers[0].Unlock();

	m_Driver.Device.Indices = terrain.IndexBuffers[0];
	m_Driver.Device.SetStreamSource( 0, terrain.VertexBuffers[p.VbIndex], 0, 12 );
	m_Driver.Device.DrawIndexedPrimitives( PrimitiveType.TriangleList, p.VbOffset,
		0, 65 * 65, 0, Terrain.ComputePrimCount( p.LoD ) );
}

foreach( Terrain.Patch p in terrain.VisPatches )
{
	buf = terrain.IndexBuffers[0].Lock<ushort>( 0, 0, LockFlags.Discard );
	buf.Write( p.Indices );
	terrain.IndexBuffers[0].Unlock();

	m_Driver.Device.Indices = terrain.IndexBuffers[0];
	m_Driver.Device.SetStreamSource( 0, terrain.VertexBuffers[p.VbIndex], p.VbOffset * 12, 12 );
	m_Driver.Device.DrawIndexedPrimitives( PrimitiveType.TriangleList, 0,
		0, 65 * 65, 0, Terrain.ComputePrimCount( p.LoD ) );
}

But this code does not:
foreach( Terrain.Patch p in terrain.VisPatches )
{
	for( int i = 0; i < p.Indices.Length; ++i )
		p.Indices += (ushort) p.VbOffset;
	buf = terrain.IndexBuffers[0].Lock<ushort>( 0, 0, LockFlags.Discard );
	buf.Write( p.Indices );
	terrain.IndexBuffers[0].Unlock();

	m_Driver.Device.Indices = terrain.IndexBuffers[0];
	m_Driver.Device.SetStreamSource( 0, terrain.VertexBuffers[p.VbIndex], 0, 12 );
	m_Driver.Device.DrawIndexedPrimitives( PrimitiveType.TriangleList, 0,
		0, 65 * 65, 0, Terrain.ComputePrimCount( p.LoD ) );
}

Everything I know tells me the behavior of the last should be identical to the first two...but it isn't. Additionally, for the last one I'm seeing some "weird" stuff on screen which is evidence of something messed up going on. I know for a fact that the indices are not being overflowed in that addition, and I don't understand what the problem could be.
SlimDX | Ventspace Blog | Twitter | Diverse teams make better games. I am currently hiring capable C++ engine developers in Baltimore, MD.
Advertisement
(saw your problem in the channel, figured I'd give my two cents, although given the trouble I had with simple IB stuff recently, I'm not sure that this post isn't even worth that [smile])

If you have a rectangular strip that's arranged like this:
024135
Then your IB will be as follows, for example:
021 123 243 345
which links the verts together.

However, if you add, say, 1 to those indices, you'll get:
132 234 354 456 (let's assume we have a 6th vert laying around somewhere).

As you can see, even though the vert groupings are the same to make the triangle, they ended up flipping the direction of the cycle (went from CW to CCW). If it did something like that for a relatively simple VB/IB relationship, I can only imagine the havoc it would wreak on a more complex setup where, for example, the verts aren't laid out in a fairly sequential fashion. Not to mention what would happen if a 6th vert didn't even exist in the VB!

What exactly was your logic behind doing this? Perhaps that in and of itself was flawed.

Disclaimer: I'm not hugely familiar with DIP's offset, so I'm mainly going off of the logic of SetStreamSource.
Even if that were the case (and it isn't, this is built far more carefully than that), I see no reason why the behavior of all three snippets about should be anything other than completely identical. I do not understand what the last one changes.

Indeed, if you open up the docs, go to the DIP page, and click "Scenario 4" , or alternately click here and slide down to scenario 4:
Quote:BaseVertexIndex is a value that's effectively added to every VB Index stored in the index buffer.
Which means that changing BaseVertexIndex (which I do in the first code fragment) should be the same as adding it to the indices (which I do in the third code fragment). But it isn't, and I can't for the life of me figure out why not.
SlimDX | Ventspace Blog | Twitter | Diverse teams make better games. I am currently hiring capable C++ engine developers in Baltimore, MD.
Hi,

In my apps so far, I've used indices of type Short, not UShort, which proved to work out well. Is it possible that in the process of actually modifying the indices, the signed/unsigned issue arrises?

Hope this helps.
Sirob Yes.» - status: Work-O-Rama.
When changing your indices, your MinIndex argument to DrawIndexedPrimitive will change. Since you're just adding a constant, NumVertices doesn't change. ATI cards are picky about these being accurate.

basically the card does this:

while(more)
index = ib[firstIndex++]
assert(index >= minindex)
assert(index < minindex+numvertices)
vertexptr = &vb[(index+basevertexindex)*stride+setstreamsourceoffset]
Man, I love you so much; first the cache hinting post, and now this. It's unfortunate I can't rate you any higher, but Cypher was kind enough to help out.
SlimDX | Ventspace Blog | Twitter | Diverse teams make better games. I am currently hiring capable C++ engine developers in Baltimore, MD.
Quote:Original post by Promit
Man, I love you so much; first the cache hinting post, and now this. It's unfortunate I can't rate you any higher, but Cypher was kind enough to help out.

It is worth noting that ntnet has stated this long ago and it was added to the Forum FAQ (under: "How does DrawIndexedPrimitive work? What do the various parameters mean?" - it needs to be updated to include the SetStreamSourceOffset bit, though. You listening, Jack?).

Well the problem was two-fold. First, I had forgotten about the MinIndex parameter entirely. Second, the NV card wasn't sensitive to the problem, while the ATI was.
SlimDX | Ventspace Blog | Twitter | Diverse teams make better games. I am currently hiring capable C++ engine developers in Baltimore, MD.
Quote:Original post by Muhammad Haggag
it needs to be updated to include the SetStreamSourceOffset bit, though. You listening, Jack?

* looks up *

[looksaround] me? someone want something?


I'll add it to my "work in progress" FAQ [smile]

Cheers,
Jack

<hr align="left" width="25%" />
Jack Hoxley <small>[</small><small> Forum FAQ | Revised FAQ | MVP Profile | Developer Journal ]</small>

Quote:Original post by Promit
Second, the NV card wasn't sensitive to the problem, while the ATI was.

[bawling] *cries at nvidia hardware ignoring Draw*() specs*
Dustin Franklin ( circlesoft :: KBase :: Mystic GD :: ApolloNL )

This topic is closed to new replies.

Advertisement