Chad Vernon
  • Home
  • Reel/Resume
  • Work
  • Resources
  • About
  • Contact
sideBar

Search

Categories

  • CG
  • cvxporter
  • Maya
    • API
    • Plug-ins
  • Personal

Archives

  • May 2012
  • March 2012
  • September 2011
  • June 2011
  • March 2011
  • December 2010
  • November 2010
  • September 2010
  • August 2010
  • July 2010
  • May 2010
  • April 2010
  • March 2010
  • December 2009
  • October 2009
  • September 2009
  • August 2009
  • July 2009
  • June 2009
  • May 2009
  • April 2009
  • March 2009
  • February 2009
  • January 2009
  • December 2008
  • November 2008
  • October 2008
  • September 2008
  • August 2008
  • July 2008
  • June 2008
  • May 2008
  • April 2008
  • March 2008
  • February 2008
  • January 2008
  • December 2007
  • November 2007
  • October 2007
  • September 2007
  • August 2007

Rss

  • Main Entries RSS
  • Comments RSS
Home » Resources » Managed DirectX 2.0 » Dynamic Buffers

Dynamic Buffers

  CU_MDX_DynamicBuffer.zip (64.3 KiB, 2,100 hits)


  CUnitFramework.zip (101.1 KiB, 16,693 hits)

Extract the C-Unit Framework
inside the project (not solution) directory.

In the Vertex and Index Buffers tutorial, we worked with static buffers. We didn’t alter the vertex data once we put it in the buffer. Dynamic vertex buffers allow us to alter data in a vertex buffer, which lets objects deform and change shape. When we use dynamic buffers, we can change the contents of the buffer each frame. Some uses for dynamic buffers include particle engines and skinned meshes. Both of which have geometry that is constantly moving within itself.

Static buffers are filled up once and then sent off to be rendered. Dynamic buffers, on the other hand, are filled up, rendered, filled up again with updated geometry, rendered, and so on. This tutorial shows you how to use a dynamic vertex buffer to create_ a basic particle effect. Each frame we will fill up the buffer with particles that are moved slightly from their previous positions.

/// <summary>Initialize application-specific resources, states here.</summary>
/// <returns>True on success, false on failure</returns>
private bool Initialize()
{
// Initialize positions and random speeds
m_positions = new Vector3[1000];
m_speeds = new Vector3[m_positions.Length];
Random random = new Random( 1000 );
for ( int i = 0; i < m_positions.Length; i++ )
{
float x = (float)random.Next( -500, 500 ) / 50.0f;
float y = (float)random.Next( -500, 500 ) / 50.0f;
m_speeds[i] = new Vector3( x, y, 0 );
m_positions[i] = new Vector3( 0.0f, 0.0f, 0.0f );

}

return true;

}

First, we’ll create_ two Vector3 arrays to store each particles’ position and velocity vector. The speeds are all randomly generated. We need to keep track of each particles’ position and speed in order to update_ the particles every frame.

/// <summary>
/// This event will be fired immediately after the Direct3D device has been
/// reset, which will happen after a lost device scenario, a window resize, and a
/// fullscreen toggle. This is the best location to create_ Pool.Default resources
/// since these resources need to be reloaded whenever the device is reset. Resources
/// created here should be released in the OnLostDevice callback.
/// </summary>
/// <param name=”device”>The Direct3D device</param>
public override void OnResetDevice( Device device )
{

// Clip…

// Create the buffer
m_vb = new VertexBuffer( device, m_positions.Length * PositionColored.StrideSize, Usage.Dynamic | Usage.WriteOnly, PositionColored.Format, Pool.Default, null );

// Set render states
device.RenderState.Lighting = false;
device.RenderState.FillMode = m_framework.FillMode;
device.RenderState.PointSize = 3.0f;

}

Second, we create_ the vertex buffer. Dynamic vertex buffers cannot be made in the Pool.Managed memory pool, therefore, we’ll create_ in in the Pool.Default memory pool. Since it is in the Default memory pool, we create_ it in the OnResetDevice method. To create_ a dynamic buffer, we have to specify the Usage.Dynamic usage flag.

We can control the size of each particle by setting the PointSize property of the render state.

/// <summary>Updates a frame prior to rendering.</summary>
/// <param name=”device”>The Direct3D device</param>
/// <param name=”elapsedTime”>Time elapsed since last frame</param>
public override void OnUpdateFrame( Device device, float elapsedTime )
{
// Create the new vertices
PositionColored[] verts = new PositionColored[m_positions.Length];
for ( int i = 0; i < m_positions.Length; i++ )
{
m_positions[i] += m_speeds[i] * elapsedTime;
// Constrain points
if ( m_positions[i].X < -7.0f || m_positions[i].X > 7.0f ||
m_positions[i].Y < -5.0f || m_positions[i].Y > 5.0f )
{
m_positions[i].X = 0.0f;
m_positions[i].Y = 0.0f;

}
// Form colors based on distance from origin
// Lots of parabola shift and squeeze math going on.
double distanceFromOrigin = Vector3.Length( m_positions[i] );
int red = -(int)( distanceFromOrigin * distanceFromOrigin * 15 ) + 255;
red = Math.Max( 0, red );
red = Math.Min( 255, red );
int green = -(int)( ( distanceFromOrigin – 5 ) * ( distanceFromOrigin – 5 ) * 15 ) + 255;
green = Math.Max( 0, green );
green = Math.Min( 255, green );
int blue = -(int)( ( distanceFromOrigin – 8 ) * ( distanceFromOrigin – 8 ) * 15 ) + 255;
blue = Math.Max( 0, blue );
blue = Math.Min( 255, blue );
Color color = Color.FromArgb( red, green, blue );
verts[i] = new PositionColored( m_positions[i].X, m_positions[i].Y, m_positions[i].Z, color.ToArgb() );

}
// Fill up the buffer with the new vertices
GraphicsBuffer<PositionColored> buffer = m_vb.Lock<PositionColored>( 0, 0, LockFlags.Discard );
buffer.Write( verts );
m_vb.Unlock();
buffer.Dispose();

}

This is the heart of dynamic buffers: updating it’s contents. Each frame, we update_ the particles’ position with the corresponding velocity vector. To create_ the illusion of particles being emitted, we reset the position of a particle to the origin whenever the particle goes outside of the bounding rectangle. The color is calculated based on the distance of the particle from the origin. The exact numbers took some tweeking until I got the effect that I wanted. Basically, I used the parabola equation y = x^2 for each color component. Using our clever math skills, we know we can shift a parabola with y = (x-shift)^2, and we can squeeze a parabola with y = (squeeze)x^2. Color components must have a value between 0 and 255 so we can use the Min and Max methods to constrain the value to this range. Once all the positions and color values are set, we can insert_ the vertex data into the vertex buffer.

/// <summary>Renders the current frame.</summary>
/// <param name=”device”>The Direct3D device</param>
/// <param name=”elapsedTime”>Time elapsed since last frame</param>
public override void OnRenderFrame( Device device, float elapsedTime )
{
device.Clear( ClearFlags.Target | ClearFlags.ZBuffer, Color.Black, 1.0f, 0 );
device.BeginScene();

// Clip…

// Render buffers
device.SetStreamSource( 0, m_vb, 0, PositionColored.StrideSize );
device.VertexFormat = PositionColored.Format;
device.DrawPrimitives( PrimitiveType.PointList, 0, m_positions.Length );

// Clip…

device.EndScene();
device.Present();

}

Since we want to render a series of points, we’ll use the PointList primitive type.

Dynamic buffers can be used to render geometry very quickly. Both my GUI system and BitmapFont system use dynamic buffers to render their contents and as a result, they perform quite fast.

No Responses to “Dynamic Buffers”

Subscribes to this topic Comment RSS or TrackBack URL

Leave A Reply

Allowed tag : <blockquote>, <p>, <code>, <em>, <small>, <ul>, <li>, <ol>, <a href=>..

 Username

 Email Address

 Website

Sticky: Always double check your comment before posting Please Note: Comment Moderation Maybe Active So There Is No Need To Resubmit Your Comments
Home » Resources » Managed DirectX 2.0 » Dynamic Buffers

© 2011 Chad Vernon