private void CreateBuffers()
{
/* Alloc positions ( 1 or 4 verts per billboard, 3 components )
colours ( 1 x RGBA per vertex )
indices ( 6 per billboard ( 2 tris ) if not point rendering )
tex. coords ( 2D coords, 1 or 4 per billboard )
*/
// LogManager.Instance.Write(string.Format("BillBoardSet.CreateBuffers entered; vertexData {0}, indexData {1}, mainBuffer {2}",
// vertexData == null ? "null" : vertexData.ToString(),
// indexData == null ? "null" : indexData.ToString(),
// mainBuffer == null ? "null" : mainBuffer.ToString()));
// Warn if user requested an invalid setup
// Do it here so it only appears once
if ( this.pointRendering && this.billboardType != BillboardType.Point )
{
LogManager.Instance.Write(
"Warning: BillboardSet {0} has point rendering enabled but is using a type " +
"other than BillboardType.Point, this may not give you the results you " +
"expect.",
this.name );
}
this.vertexData = new VertexData();
if ( this.pointRendering )
{
this.vertexData.vertexCount = this.poolSize;
}
else
{
this.vertexData.vertexCount = this.poolSize * 4;
}
this.vertexData.vertexStart = 0;
// Vertex declaration
VertexDeclaration decl = this.vertexData.vertexDeclaration;
VertexBufferBinding binding = this.vertexData.vertexBufferBinding;
int offset = 0;
decl.AddElement( 0, offset, VertexElementType.Float3, VertexElementSemantic.Position );
offset += VertexElement.GetTypeSize( VertexElementType.Float3 );
decl.AddElement( 0, offset, VertexElementType.Color, VertexElementSemantic.Diffuse );
offset += VertexElement.GetTypeSize( VertexElementType.Color );
// Texture coords irrelevant when enabled point rendering (generated
// in point sprite mode, and unused in standard point mode)
if ( !this.pointRendering )
{
decl.AddElement( 0, offset, VertexElementType.Float2, VertexElementSemantic.TexCoords, 0 );
}
this.mainBuffer =
HardwareBufferManager.Instance.CreateVertexBuffer( decl.Clone( 0 ), this.vertexData.vertexCount, BufferUsage.DynamicWriteOnlyDiscardable );
// bind position and diffuses
binding.SetBinding( 0, this.mainBuffer );
if ( !this.pointRendering )
{
this.indexData = new IndexData();
// calc index buffer size
this.indexData.indexStart = 0;
this.indexData.indexCount = this.poolSize * 6;
// create the index buffer
this.indexData.indexBuffer =
HardwareBufferManager.Instance.CreateIndexBuffer(
IndexType.Size16,
this.indexData.indexCount,
BufferUsage.StaticWriteOnly );
/* Create indexes (will be the same every frame)
Using indexes because it means 1/3 less vertex transforms (4 instead of 6)
Billboard layout relative to camera:
0-----1
| /|
| / |
|/ |
2-----3
*/
// lock the index buffer
IntPtr idxPtr = this.indexData.indexBuffer.Lock( BufferLocking.Discard );
unsafe
{
ushort* pIdx = (ushort*)idxPtr.ToPointer();
for ( int idx, idxOffset, bboard = 0; bboard < this.poolSize; ++bboard )
{
// Do indexes
idx = bboard * 6;
idxOffset = bboard * 4;
pIdx[ idx ] = (ushort)idxOffset; // + 0;, for clarity
pIdx[ idx + 1 ] = (ushort)( idxOffset + 2 );
pIdx[ idx + 2 ] = (ushort)( idxOffset + 1 );
pIdx[ idx + 3 ] = (ushort)( idxOffset + 1 );
pIdx[ idx + 4 ] = (ushort)( idxOffset + 2 );
pIdx[ idx + 5 ] = (ushort)( idxOffset + 3 );
} // for
} // unsafe
// unlock the buffers
this.indexData.indexBuffer.Unlock();
}
this.buffersCreated = true;
}