Sign in to follow this  

Having issues with offsets

This topic is 4340 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

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[i] += (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.

Share this post


Link to post
Share on other sites
(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:

024
135
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.

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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]

Share this post


Link to post
Share on other sites
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?).

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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

Share this post


Link to post
Share on other sites

This topic is 4340 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.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this