I've some strange behavior when using dynamic buffers to display quad's. I follow the usual steps: Create dynamic buffers, lock, fill, unlock, draw, but the quads I was drawing was flickering madly.
After going over all of my code I ended up in the buffer locking. I used the following to lock:
mVertexBuffer.Lock(offset * mStride, lf)
This seemed fine, but then I saw in the SlimDX code that I could also pass a size along to Lock. So I changed the code to
mVertexBuffer.Lock(offset * mStride, count * mStride, lf)
and suddenly all the flickering stopped, and the quad's was rendered perfectly.
In SlimDX Lock is as follows:
DataStream^ VertexBuffer::Lock( int offset, int size, LockFlags flags )
{
void* lockedPtr;
HRESULT hr = VbPointer->Lock( offset, size, &lockedPtr, (DWORD) flags );
GraphicsException::CheckHResult( hr );
int lockedSize = size == 0 ? SizeInBytes : size;
bool readOnly = (flags & LockFlags::ReadOnly) == LockFlags::ReadOnly;
DataStream^ stream = gcnew DataStream( lockedPtr, lockedSize, true, !readOnly );
return stream;
}
DataStream^ VertexBuffer::Lock( int offset, LockFlags flags )
{
return Lock( offset, 0, flags );
}
but after looking in the DX documenation I found the following under IDirect3DVertexBuffer9::Lock:
Quote:
OffsetToLock
[in] Offset into the vertex data to lock, in bytes. To lock the entire vertex buffer, specify 0 for both parameters, SizeToLock and OffsetToLock.
SizeToLock
[in] Size of the vertex data to lock, in bytes. To lock the entire vertex buffer, specify 0 for both parameters, SizeToLock and OffsetToLock.
It seems having OffsetToLock != 0 and SizeToLock == 0 will give an incorrect behavior.
To correct this I think Lock in SlimDX should be changed to something like:
DataStream^ VertexBuffer::Lock( int offset, int size, LockFlags flags )
{
int lockedSize = size == 0 ? SizeInBytes - offset : size;
void* lockedPtr;
HRESULT hr = VbPointer->Lock( offset, lockedSize, &lockedPtr, (DWORD) flags );
GraphicsException::CheckHResult( hr );
bool readOnly = (flags & LockFlags::ReadOnly) == LockFlags::ReadOnly;
DataStream^ stream = gcnew DataStream( lockedPtr, lockedSize, true, !readOnly );
return stream;
}
and equivalent for IndexBuffer.