//--------------------------------------------------------------------- void TangentSpaceCalc::extendBuffers(VertexSplits& vertexSplits) { if (!vertexSplits.empty()) { // ok, need to increase the vertex buffer size, and alter some indexes // vertex buffers first VertexBufferBinding* newBindings = HardwareBufferManager::getSingleton().createVertexBufferBinding(); const VertexBufferBinding::VertexBufferBindingMap& bindmap = mVData->vertexBufferBinding->getBindings(); for (VertexBufferBinding::VertexBufferBindingMap::const_iterator i = bindmap.begin(); i != bindmap.end(); ++i) { HardwareVertexBufferSharedPtr srcbuf = i->second; // Derive vertex count from buffer not vertex data, in case using // the vertexStart option in vertex data size_t newVertexCount = srcbuf->getNumVertices() + vertexSplits.size(); // Create new buffer & bind HardwareVertexBufferSharedPtr newBuf = HardwareBufferManager::getSingleton().createVertexBuffer( srcbuf->getVertexSize(), newVertexCount, srcbuf->getUsage(), srcbuf->hasShadowBuffer()); newBindings->setBinding(i->first, newBuf); // Copy existing contents (again, entire buffer, not just elements referenced) newBuf->copyData(*(srcbuf.get()), 0, 0, srcbuf->getNumVertices() * srcbuf->getVertexSize(), true); // Split vertices, read / write from new buffer char* pBase = static_cast<char*>(newBuf->lock(HardwareBuffer::HBL_NORMAL)); for (VertexSplits::iterator spliti = vertexSplits.begin(); spliti != vertexSplits.end(); ++spliti) { const char* pSrcBase = pBase + spliti->first * newBuf->getVertexSize(); char* pDstBase = pBase + spliti->second * newBuf->getVertexSize(); memcpy(pDstBase, pSrcBase, newBuf->getVertexSize()); } newBuf->unlock(); } // Update vertex data // Increase vertex count according to num splits mVData->vertexCount += vertexSplits.size(); // Flip bindings over to new buffers (old buffers released) HardwareBufferManager::getSingleton().destroyVertexBufferBinding(mVData->vertexBufferBinding); mVData->vertexBufferBinding = newBindings; // If vertex size requires 32bit index buffer if (mVData->vertexCount > 65536) { for (size_t i = 0; i < mIDataList.size(); ++i) { // check index size IndexData* idata = mIDataList[i]; HardwareIndexBufferSharedPtr srcbuf = idata->indexBuffer; if (srcbuf->getType() == HardwareIndexBuffer::IT_16BIT) { size_t indexCount = srcbuf->getNumIndexes(); // convert index buffer to 32bit. HardwareIndexBufferSharedPtr newBuf = HardwareBufferManager::getSingleton().createIndexBuffer( HardwareIndexBuffer::IT_32BIT, indexCount, srcbuf->getUsage(), srcbuf->hasShadowBuffer()); uint16* pSrcBase = static_cast<uint16*>(srcbuf->lock(HardwareBuffer::HBL_NORMAL)); uint32* pBase = static_cast<uint32*>(newBuf->lock(HardwareBuffer::HBL_NORMAL)); size_t j = 0; while (j < indexCount) { *pBase++ = *pSrcBase++; ++j; } srcbuf->unlock(); newBuf->unlock(); // assign new index buffer. idata->indexBuffer = newBuf; } } } } }