Controlling How Buffers Are Locked

Last, we need to talk about the flags you can use when locking the buffer. The only valid flags when locking a vertex buffer are

  • LockFlags.None

  • LockFlags.Discard

  • LockFlags.NoOverwrite

  • LockFlags.NoDirtyUpdate

  • LockFlags.NoSystemLock

  • LockFlags.ReadOnly

Obviously, when using no lock flags, the default locking mechanism is used. However, if you want more control over your locking, the other flags can be used for a variety of options.

The "Discard" flag can only be used on dynamic buffers. For Vertex and Index buffers, the entire buffer will be discarded, and a new chunk of memory will be returned to you in case there is anything else still accessing the old memory. This flag is useful if you are filling a vertex buffer dynamically. Once the vertex buffer has been filled completely, you lock with discard. It is often used in combination with the next flag.

The "NoOverwrite" flag (which is also only valid on dynamic buffers) tells Direct3D that you will not overwrite any data in the vertex or index buffer. Using the flag will allow the call to return immediately, and continue to use the buffer. If you do not use this flag, the lock call will not return until any rendering is currently finished. Since you may not overwrite any of the data currently in this buffer, it is only useful for appending vertices to a buffer.

A common use of these two flags comes from a large buffer you are filling dynamically. As you keep adding new data into your buffer, you continue to use the NoOverwrite flag until the buffer is full. At that time, your next lock will use the Discard flag to flush the buffer and start over. We can look at Listing 8.1, an excerpt of code from the Point Sprites sample that ships with the DirectX SDK.

Listing 8.1 Portion of PointSprites Example
 if (++numParticlesToRender == flush) {     // Done filling this chunk of the vertex buffer.  Lets unlock and     // draw this portion so we can begin filling the next chunk.     vertexBuffer.Unlock();     dev.DrawPrimitives(PrimitiveType.PointList, baseParticle,                 numParticlesToRender);     // Lock the next chunk of the vertex buffer.  If we are at the     // end of the vertex buffer, LockFlags.Discard the vertex buffer and start     // at the beginning.  Otherwise, specify LockFlags.NoOverWrite, so we can     // continue filling the VB while the previous chunk is drawing.     baseParticle += flush;     if (baseParticle >= discard)         baseParticle = 0;     vertices = (PointVertex[])vertexBuffer.Lock(baseParticle *          DXHelp.GetTypeSize(typeof(PointVertex)), typeof(PointVertex),         (baseParticle != 0) ? LockFlags.NoOverwrite : LockFlags.Discard,         flush);     count = 0;     numParticlesToRender = 0; } 

In this excerpt, we detect whether or not it's time to "flush" our data (a call to DrawPrimitives). If it is, we unlock our buffer and render. Then we detect whether or not we are at the end of our buffer (baseParticle >= discard), and finally lock our buffer once more. We start locking at the end of the buffer, passing in the NoOverwrite flag, unless baseParticle is zero, in which case we lock at the beginning of the buffer, and use the Discard flag. This allows us to continue to add new point sprites to our scene until our buffer is full, at which time we discard our old buffer and start using a new one.

With the two "complex" flags out of the way, we can discuss the remaining flags now. The easiest of these is the "ReadOnly" flag, which as its name implies tells Direct3D that you will not write to the buffer. When dealing with the lock overloads that return arrays, this also has the benefit of not copying the data you've updated when you finally call Unlock.

The NoDirtyUpdate flag prevents any change in the "dirty" status of the resource. Without this flag, locking a resource will automatically add a dirty region to that resource.

The last of the flags probably won't be used all that often. Normally, when you lock a resource in video memory, a systemwide critical section is reserved, not allowing any display mode changes while the lock is in effect. Using the NoSystemLock flag disables this feature. This is only useful for lock operations you expect to take quite some time, and only if you still need speedy system speed. Using this flag often isn't recommended.

Naturally, after you've called lock, you must tell Direct3D that you're done with the lock at some time. The unlock method is used for this. There are no parameters for this function, and unlock must be called every time you call lock. Rendering will fail if there are any unlocked buffers.



Managed DirectX 9 Graphics and Game Programming, Kick Start
Managed DirectX 9 Kick Start: Graphics and Game Programming
ISBN: B003D7JUW6
EAN: N/A
Year: 2002
Pages: 180
Authors: Tom Miller

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net