Code: Select all
void Mesh::organiseTangentsBuffer(VertexData *vertexData,
VertexElementSemantic targetSemantic, unsigned short index,
unsigned short sourceTexCoordSet)
{
VertexDeclaration *vDecl = vertexData->vertexDeclaration ;
VertexBufferBinding *vBind = vertexData->vertexBufferBinding ;
const VertexElement *tangentsElem = vDecl->findElementBySemantic(targetSemantic, index);
bool needsToBeCreated = false;
if (!tangentsElem)
{ // no tex coords with index 1
needsToBeCreated = true ;
}
else if (tangentsElem->getType() != VET_FLOAT3)
{
// buffer exists, but not 3D
OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS,
"Target semantic set already exists but is not 3D, therefore "
"cannot contain tangents. Pick an alternative destination semantic. ",
"Mesh::organiseTangentsBuffer");
}
HardwareVertexBufferSharedPtr newBuffer;
if (needsToBeCreated)
{
// To be most efficient with our vertex streams,
// tack the new tangents onto the same buffer as the
// source texture coord set
const VertexElement* prevTexCoordElem =
vertexData->vertexDeclaration->findElementBySemantic(
VES_TEXTURE_COORDINATES, sourceTexCoordSet);
if (!prevTexCoordElem)
{
OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND,
"Cannot locate the first texture coordinate element to "
"which to append the new tangents.",
"Mesh::orgagniseTangentsBuffer");
}
// Find the buffer associated with this element
HardwareVertexBufferSharedPtr origBuffer =
vertexData->vertexBufferBinding->getBuffer(
prevTexCoordElem->getSource());
// Now create a new buffer, which includes the previous contents
// plus extra space for the 3D coords
newBuffer = HardwareBufferManager::getSingleton().createVertexBuffer(
origBuffer->getVertexSize() + 3*sizeof(float), /////////////////////////look this 1
vertexData->vertexCount,
origBuffer->getUsage(),
origBuffer->hasShadowBuffer() );
// Add the new element
vDecl->addElement(
prevTexCoordElem->getSource(),
origBuffer->getVertexSize(),
VET_FLOAT3,
targetSemantic,
index);
// Now copy the original data across
unsigned char* pSrc = static_cast<unsigned char*>(
origBuffer->lock(HardwareBuffer::HBL_READ_ONLY));
unsigned char* pDest = static_cast<unsigned char*>(
newBuffer->lock(HardwareBuffer::HBL_DISCARD));
size_t vertSize = origBuffer->getVertexSize();
for (size_t v = 0; v < vertexData->vertexCount; ++v)
{
// Copy original vertex data////////////////////////////////////look this 2
memcpy(pDest, pSrc, vertSize);
pSrc += vertSize;
pDest += vertSize;
// Set the new part to 0 since we'll accumulate in this
memset(pDest, 0, sizeof(float)*3);
pDest += sizeof(float)*3;
}
origBuffer->unlock();
newBuffer->unlock();
// Rebind the new buffer
vBind->setBinding(prevTexCoordElem->getSource(), newBuffer);
}
}
Discussion : if do this we had two VES_TEXTURE_COORDINATES ,why not shared the Existed one ,and if origBuffer->hasShadowBuffer() == this , we have three copy.