protected override void UpdateTextureGeometry()
{
if ( material != null && isInitialized )
{
int numLayers = material.GetTechnique( 0 ).GetPass( 0 ).TextureUnitStageCount;
VertexDeclaration decl = renderOperation.vertexData.vertexDeclaration;
// if the required layers is less than the current amount of tex coord buffers, remove
// the extraneous buffers
if ( numTexCoordsInBuffer > numLayers )
{
for ( int i = numTexCoordsInBuffer; i > numLayers; --i )
{
decl.RemoveElement( VertexElementSemantic.TexCoords, i );
}
}
else if ( numTexCoordsInBuffer < numLayers )
{
// we need to add more buffers
int offset = VertexElement.GetTypeSize( VertexElementType.Float2 ) * numTexCoordsInBuffer;
for ( int i = numTexCoordsInBuffer; i < numLayers; ++i )
{
decl.AddElement( TEXTURE_COORDS, offset, VertexElementType.Float2, VertexElementSemantic.TexCoords, i );
offset += VertexElement.GetTypeSize( VertexElementType.Float2 );
} // for
} // if
// if the number of layers changed at all, we'll need to reallocate buffer
if ( numTexCoordsInBuffer != numLayers )
{
HardwareVertexBuffer newBuffer =
HardwareBufferManager.Instance.CreateVertexBuffer( decl.Clone( TEXTURE_COORDS ), renderOperation.vertexData.vertexCount, BufferUsage.StaticWriteOnly );
// Bind buffer, note this will unbind the old one and destroy the buffer it had
renderOperation.vertexData.vertexBufferBinding.SetBinding( TEXTURE_COORDS, newBuffer );
// record the current number of tex layers now
numTexCoordsInBuffer = numLayers;
} // if
if ( numTexCoordsInBuffer != 0 )
{
// get the tex coord buffer
HardwareVertexBuffer buffer = renderOperation.vertexData.vertexBufferBinding.GetBuffer( TEXTURE_COORDS );
IntPtr data = buffer.Lock( BufferLocking.Discard );
unsafe
{
float* texPtr = (float*)data.ToPointer();
int texIndex = 0;
int uvSize = VertexElement.GetTypeSize( VertexElementType.Float2 ) / sizeof( float );
int vertexSize = decl.GetVertexSize( TEXTURE_COORDS ) / sizeof( float );
for ( int i = 0; i < numLayers; i++ )
{
// Calc upper tex coords
float upperX = bottomRight.x * tileX[ i ];
float upperY = bottomRight.y * tileY[ i ];
/*
0-----2
| /|
| / |
|/ |
1-----3
*/
// Find start offset for this set
texIndex = ( i * uvSize );
texPtr[ texIndex ] = topLeft.x;
texPtr[ texIndex + 1 ] = topLeft.y;
texIndex += vertexSize; // jump by 1 vertex stride
texPtr[ texIndex ] = topLeft.x;
texPtr[ texIndex + 1 ] = upperY;
texIndex += vertexSize;
texPtr[ texIndex ] = upperX;
texPtr[ texIndex + 1 ] = topLeft.y;
texIndex += vertexSize;
texPtr[ texIndex ] = upperX;
texPtr[ texIndex + 1 ] = upperY;
} // for
} // unsafev
// unlock the buffer
buffer.Unlock();
}
} // if material != null
}