How to use LockFlags.Discard and LockFlags.NoOverWrite?

Hi,

I'm trying to mix the usage of Discard and NoOverWrite to batch my vertexbuffer updates.
I start out by locking chunks of the buffer with NoOverWrite and then release the lock and render with DrawIndexedPrimitives when the chunk is full. When I reach the end of the buffer it's locked once with Discard from the beginning and then back to NoOverWrite.
The weird thing is that it only draws the first vertices up to chunksize?.
The exact same method works well for pointsprites though.

Thanx for any help.

[539 byte] By [stenis] at [2007-12-25]
# 1
i think you should paste some code to make it clear. are you sure you setup corrent offset? correct indices? What does the dxdebug say?
fatkas at 2007-10-8 > top of Msdn Tech,Game Technologies: DirectX, XNA, XACT, etc.,Game Technologies: DirectX 101...
# 2
Hi again,

Sorry for the minimum info I gave - didn't have my source available when I was at work...
Anyway here it is:


Initialization:

BufferSize = 10000;
BatchSize = 100;
_baseQuad = 0;
_vertices = new VertexBuffer(
typeof(CustomVertex.TransformedColoredTextured),
BufferSize * 4,
_device,
Usage.Dynamic | Usage.WriteOnly,
CustomVertex.TransformedColoredTextured.Format,
Pool.Default
);
_indices = new IndexBuffer(
_device,
sizeof(ushort) * BufferSize * 6,
Usage.WriteOnly,
Pool.Default,
true
);
// fill index buffer with indices (same set repeated as we only render quads)
using(GraphicsStream indexStream = _indices.Lock(0, 0, LockFlags.None))
{
for(int i = 0; i < BufferSize * 4; i+=4)
{
ushort[] indices = {
(ushort)(i + 0),
(ushort)(i + 1),
(ushort)(i + 2),
(ushort)(i + 0),
(ushort)(i + 2),
(ushort)(i + 3)
};
indexStream.Write(indices);
}
_indices.Unlock();
}

Beginning of batch:

// set buffers on the device
_device.VertexFormat = CustomVertex.TransformedColoredTextured.Format;
_device.SetStreamSource(0, _vertices, 0, VertexSize);
_device.Indices = _indices;

// set texture and alpha blending
_device.SetTexture(0, texture);
_device.RenderState.SourceBlend = Blend.SourceAlpha;
_device.RenderState.DestinationBlend = Blend.InvSourceAlpha;
_device.RenderState.AlphaBlendEnable = true;

// get new lock for vertices
_vertexStream = _vertices.Lock(
_baseQuad * CustomVertex.TransformedColoredTextured.StrideSize * 4,
BatchSize * CustomVertex.TransformedColoredTextured.StrideSize * 4,
_baseQuad == 0 ? LockFlags.Discard : LockFlags.NoOverwrite
);

_quadsToRender = 0;


Adding a quad (array of four CustomVertex.TransformedColoredTextured):

// check if batch is full
if(_quadsToRender == BatchSize)
{
// unlock buffer
_vertices.Unlock();

// render
_device.DrawIndexedPrimitives(
PrimitiveType.TriangleList,
_baseQuad * 4,
0,
_quadsToRender * 4,
_baseQuad * 6,
_quadsToRender * 2
);

// reset number of quads to render
_quadsToRender = 0;

// skip to next chunk
_baseQuad += BatchSize;

// check if buffer size is exceeded
if(_baseQuad >= BufferSize)
_baseQuad = 0;

// get new lock for vertices
_vertexStream = _vertices.Lock(
_baseQuad * CustomVertex.TransformedColoredTextured.StrideSize * 4,
BatchSize * CustomVertex.TransformedColoredTextured.StrideSize * 4,
_baseQuad == 0 ? LockFlags.Discard : LockFlags.NoOverwrite
);
}

// write quad-vertices
_vertexStream.Write(quad);

// increase number of quads to render
_quadsToRender++;


When batch ends final UnLock and DrawIndexedPrimitives calls are made to flush the last of the buffer.
I haven't been able to run dxdebug yet, but I'll give it a try.
Also - I run on DirectX 9.0c.

On a side note - I think I got somewhat more fps out of the above routine when I use the Lock override which returns an array - is that normal? Shouldn't the GraphicsStream be the fastest way to write to the vertexbuffer?

Thanx again for any help.

stenis at 2007-10-8 > top of Msdn Tech,Game Technologies: DirectX, XNA, XACT, etc.,Game Technologies: DirectX 101...
# 3
Ok, now I'm feeling stupid.
I got it to work after switching the parameters of the DrawIndexedPrimitives call.
I thought you should give the offset to draw from as the baseVertex parameter and
but it turned out that when using the minVertexIndex instead it worked.

Thanx anyway - and happy coding! :)

stenis at 2007-10-8 > top of Msdn Tech,Game Technologies: DirectX, XNA, XACT, etc.,Game Technologies: DirectX 101...