void GeomUtils::createQuad(VertexData*& vertexData) { assert(vertexData); vertexData->vertexCount = 4; vertexData->vertexStart = 0; VertexDeclaration* vertexDecl = vertexData->vertexDeclaration; VertexBufferBinding* bind = vertexData->vertexBufferBinding; vertexDecl->addElement(0, 0, VET_FLOAT3, VES_POSITION); HardwareVertexBufferSharedPtr vbuf = HardwareBufferManager::getSingleton().createVertexBuffer( vertexDecl->getVertexSize(0), vertexData->vertexCount, HardwareBuffer::HBU_STATIC_WRITE_ONLY); // Bind buffer bind->setBinding(0, vbuf); // Upload data float data[]={ -1,1,-1, // corner 1 -1,-1,-1, // corner 2 1,1,-1, // corner 3 1,-1,-1}; // corner 4 vbuf->writeData(0, sizeof(data), data, true); }
void WireBoundingBox::_initWireBoundingBox() { mRenderOp.vertexData = OGRE_NEW VertexData(); mRenderOp.indexData = 0; mRenderOp.vertexData->vertexCount = 24; mRenderOp.vertexData->vertexStart = 0; mRenderOp.operationType = RenderOperation::OT_LINE_LIST; mRenderOp.useIndexes = false; mRenderOp.useGlobalInstancingVertexBufferIsAvailable = false; VertexDeclaration* decl = mRenderOp.vertexData->vertexDeclaration; VertexBufferBinding* bind = mRenderOp.vertexData->vertexBufferBinding; decl->addElement(POSITION_BINDING, 0, VET_FLOAT3, VES_POSITION); HardwareVertexBufferSharedPtr vbuf = HardwareBufferManager::getSingleton().createVertexBuffer( decl->getVertexSize(POSITION_BINDING), mRenderOp.vertexData->vertexCount, HardwareBuffer::HBU_STATIC_WRITE_ONLY); // Bind buffer bind->setBinding(POSITION_BINDING, vbuf); // set basic white material this->setMaterial("BaseWhiteNoLighting"); }
//--------------------------------------------------------------------- void TextAreaOverlayElement::_restoreManualHardwareResources() { if(!mInitialised) return; // 6 verts per char since we're doing tri lists without indexes // Allocate space for positions & texture coords // Note - mRenderOp.vertexData->vertexCount will be less than allocatedVertexCount size_t allocatedVertexCount = mAllocSize * 6; VertexDeclaration* decl = mRenderOp.vertexData->vertexDeclaration; VertexBufferBinding* bind = mRenderOp.vertexData->vertexBufferBinding; // Create dynamic since text tends to change a lot // positions & texcoords HardwareVertexBufferSharedPtr vbuf = HardwareBufferManager::getSingleton(). createVertexBuffer( decl->getVertexSize(POS_TEX_BINDING), allocatedVertexCount, HardwareBuffer::HBU_DYNAMIC_WRITE_ONLY); bind->setBinding(POS_TEX_BINDING, vbuf); // colours vbuf = HardwareBufferManager::getSingleton(). createVertexBuffer( decl->getVertexSize(COLOUR_BINDING), allocatedVertexCount, HardwareBuffer::HBU_DYNAMIC_WRITE_ONLY); bind->setBinding(COLOUR_BINDING, vbuf); // Buffers are restored, but with trash within mGeomPositionsOutOfDate = true; mGeomUVsOutOfDate = true; mColoursChanged = true; }
void Line3D::drawLines(void) { if(mDrawn) return; else mDrawn = true; // Initialization stuff mRenderOp.indexData = 0; mRenderOp.vertexData->vertexCount = mPoints.size(); mRenderOp.vertexData->vertexStart = 0; mRenderOp.operationType = RenderOperation::OT_LINE_LIST; // OT_LINE_LIST, OT_LINE_STRIP mRenderOp.useIndexes = false; VertexDeclaration *decl = mRenderOp.vertexData->vertexDeclaration; VertexBufferBinding *bind = mRenderOp.vertexData->vertexBufferBinding; decl->addElement(POSITION_BINDING, 0, VET_FLOAT3, VES_POSITION); HardwareVertexBufferSharedPtr vbuf = HardwareBufferManager::getSingleton().createVertexBuffer( decl->getVertexSize(POSITION_BINDING), mRenderOp.vertexData->vertexCount, HardwareBuffer::HBU_STATIC_WRITE_ONLY); bind->setBinding(POSITION_BINDING, vbuf); // Drawing stuff int size = mPoints.size(); Vector3 vaabMin = mPoints[0]; Vector3 vaabMax = mPoints[0]; Real *prPos = static_cast<Real*>(vbuf->lock(HardwareBuffer::HBL_DISCARD)); for(int i = 0; i < size; i++) { *prPos++ = mPoints[i].x; *prPos++ = mPoints[i].y; *prPos++ = mPoints[i].z; if(mPoints[i].x < vaabMin.x) vaabMin.x = mPoints[i].x; if(mPoints[i].y < vaabMin.y) vaabMin.y = mPoints[i].y; if(mPoints[i].z < vaabMin.z) vaabMin.z = mPoints[i].z; if(mPoints[i].x > vaabMax.x) vaabMax.x = mPoints[i].x; if(mPoints[i].y > vaabMax.y) vaabMax.y = mPoints[i].y; if(mPoints[i].z > vaabMax.z) vaabMax.z = mPoints[i].z; } vbuf->unlock(); mBox.setExtents(vaabMin, vaabMax); }
//--------------------------------------------------------------------- void TextAreaOverlayElement::_releaseManualHardwareResources() { if(!mInitialised) return; VertexBufferBinding* bind = mRenderOp.vertexData->vertexBufferBinding; bind->unsetBinding(POS_TEX_BINDING); bind->unsetBinding(COLOUR_BINDING); }
void GeomUtils::createCone(Ogre::VertexData*& vertexData, Ogre::IndexData*& indexData, float radius , float height, int nVerticesInBase) { assert(vertexData && indexData); // define the vertex format VertexDeclaration* vertexDecl = vertexData->vertexDeclaration; // positions vertexDecl->addElement(0, 0, VET_FLOAT3, VES_POSITION); // allocate the vertex buffer vertexData->vertexCount = nVerticesInBase + 1; HardwareVertexBufferSharedPtr vBuf = HardwareBufferManager::getSingleton().createVertexBuffer(vertexDecl->getVertexSize(0), vertexData->vertexCount, HardwareBuffer::HBU_STATIC_WRITE_ONLY, false); VertexBufferBinding* binding = vertexData->vertexBufferBinding; binding->setBinding(0, vBuf); float* pVertex = static_cast<float*>(vBuf->lock(HardwareBuffer::HBL_DISCARD)); // allocate index buffer - cone and base indexData->indexCount = (3 * nVerticesInBase) + (3 * (nVerticesInBase - 2)); indexData->indexBuffer = HardwareBufferManager::getSingleton().createIndexBuffer(HardwareIndexBuffer::IT_16BIT, indexData->indexCount, HardwareBuffer::HBU_STATIC_WRITE_ONLY, false); HardwareIndexBufferSharedPtr iBuf = indexData->indexBuffer; unsigned short* pIndices = static_cast<unsigned short*>(iBuf->lock(HardwareBuffer::HBL_DISCARD)); //Positions : cone head and base for (int i=0; i<3; i++) *pVertex++ = 0.0f; //Base : float fDeltaBaseAngle = (2 * Math::PI) / nVerticesInBase; for (int i=0; i<nVerticesInBase; i++) { float angle = i * fDeltaBaseAngle; *pVertex++ = radius * cosf(angle); *pVertex++ = height; *pVertex++ = radius * sinf(angle); } //Indices : //Cone head to vertices for (int i=0; i<nVerticesInBase; i++) { *pIndices++ = 0; *pIndices++ = (i%nVerticesInBase) + 1; *pIndices++ = ((i+1)%nVerticesInBase) + 1; } //Cone base for (int i=0; i<nVerticesInBase-2; i++) { *pIndices++ = 1; *pIndices++ = i + 3; *pIndices++ = i + 2; } // Unlock vBuf->unlock(); iBuf->unlock(); }
//--------------------------------------------------------------------- void PrefabFactory::createPlane(Mesh* mesh) { SubMesh* sub = mesh->createSubMesh(); float vertices[32] = { -100, -100, 0, // pos 0,0,1, // normal 0,1, // texcoord 100, -100, 0, 0,0,1, 1,1, 100, 100, 0, 0,0,1, 1,0, -100, 100, 0 , 0,0,1, 0,0 }; mesh->sharedVertexData = OGRE_NEW VertexData(); mesh->sharedVertexData->vertexCount = 4; VertexDeclaration* decl = mesh->sharedVertexData->vertexDeclaration; VertexBufferBinding* bind = mesh->sharedVertexData->vertexBufferBinding; size_t offset = 0; decl->addElement(0, offset, VET_FLOAT3, VES_POSITION); offset += VertexElement::getTypeSize(VET_FLOAT3); decl->addElement(0, offset, VET_FLOAT3, VES_NORMAL); offset += VertexElement::getTypeSize(VET_FLOAT3); decl->addElement(0, offset, VET_FLOAT2, VES_TEXTURE_COORDINATES, 0); offset += VertexElement::getTypeSize(VET_FLOAT2); HardwareVertexBufferSharedPtr vbuf = HardwareBufferManager::getSingleton().createVertexBuffer( offset, 4, HardwareBuffer::HBU_STATIC_WRITE_ONLY); bind->setBinding(0, vbuf); vbuf->writeData(0, vbuf->getSizeInBytes(), vertices, true); sub->useSharedVertices = true; HardwareIndexBufferSharedPtr ibuf = HardwareBufferManager::getSingleton(). createIndexBuffer( HardwareIndexBuffer::IT_16BIT, 6, HardwareBuffer::HBU_STATIC_WRITE_ONLY); unsigned short faces[6] = {0,1,2, 0,2,3 }; sub->indexData->indexBuffer = ibuf; sub->indexData->indexCount = 6; sub->indexData->indexStart =0; ibuf->writeData(0, ibuf->getSizeInBytes(), faces, true); mesh->_setBounds(AxisAlignedBox(-100,-100,0,100,100,0), true); mesh->_setBoundingSphereRadius(Math::Sqrt(100*100+100*100)); }
//--------------------------------------------------------------------- void BorderPanelOverlayElement::_releaseManualHardwareResources() { if(!mInitialised) return; VertexBufferBinding* bind = mRenderOp2.vertexData->vertexBufferBinding; bind->unsetBinding(POSITION_BINDING); bind->unsetBinding(TEXCOORD_BINDING); mRenderOp2.indexData->indexBuffer.setNull(); PanelOverlayElement::_releaseManualHardwareResources(); }
//--------------------------------------------------------------------- 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; } }
//----------------------------------------------------------------------------- void TempBlendedBufferInfo::extractFrom(const VertexData* sourceData) { // Release old buffer copies first if (!destPositionBuffer.isNull()) { destPositionBuffer->getManager()->releaseVertexBufferCopy(destPositionBuffer); assert(destPositionBuffer.isNull()); } if (!destNormalBuffer.isNull()) { destNormalBuffer->getManager()->releaseVertexBufferCopy(destNormalBuffer); assert(destNormalBuffer.isNull()); } VertexDeclaration* decl = sourceData->vertexDeclaration; VertexBufferBinding* bind = sourceData->vertexBufferBinding; const VertexElement *posElem = decl->findElementBySemantic(VES_POSITION); const VertexElement *normElem = decl->findElementBySemantic(VES_NORMAL); assert(posElem && "Positions are required"); posBindIndex = posElem->getSource(); srcPositionBuffer = bind->getBuffer(posBindIndex); if (!normElem) { posNormalShareBuffer = false; srcNormalBuffer.setNull(); } else { normBindIndex = normElem->getSource(); if (normBindIndex == posBindIndex) { posNormalShareBuffer = true; srcNormalBuffer.setNull(); } else { posNormalShareBuffer = false; srcNormalBuffer = bind->getBuffer(normBindIndex); } } }
DebugRectangle2D::DebugRectangle2D() : SimpleRenderable () { #ifdef PLSM2_EIHORT mUseIdentityProjection = true; mUseIdentityView = true; #endif mRenderOp.indexData = new IndexData(); mRenderOp.vertexData = new VertexData(); mRenderOp.operationType = RenderOperation::OT_LINE_LIST; mRenderOp.indexData->indexCount = 8; mRenderOp.vertexData->vertexCount = 4; mRenderOp.vertexData->vertexStart = 0; mRenderOp.useIndexes = true; VertexDeclaration* decl = mRenderOp.vertexData->vertexDeclaration; VertexBufferBinding* bind = mRenderOp.vertexData->vertexBufferBinding; decl->addElement(POSITION_BINDING, 0, VET_FLOAT3, VES_POSITION); const size_t offset = VertexElement::getTypeSize(VET_FLOAT3); decl->addElement (POSITION_BINDING, offset, VET_COLOUR, VES_DIFFUSE); mRenderOp.indexData->indexBuffer = HardwareBufferManager::getSingleton().createIndexBuffer( HardwareIndexBuffer::IT_16BIT, mRenderOp.indexData->indexCount, HardwareBuffer::HBU_STATIC_WRITE_ONLY); HardwareVertexBufferSharedPtr vbuf = HardwareBufferManager::getSingleton().createVertexBuffer( decl->getVertexSize(POSITION_BINDING), mRenderOp.vertexData->vertexCount, HardwareBuffer::HBU_STATIC_WRITE_ONLY); // Bind buffer bind->setBinding(POSITION_BINDING, vbuf); SimpleRenderable::setBoundingBox(AxisAlignedBox(-1000 * Vector3::UNIT_SCALE, 1000 * Vector3::UNIT_SCALE)); SimpleRenderable::setRenderQueueGroup (RENDER_QUEUE_OVERLAY); // set basic white material SimpleRenderable::setMaterial("BaseWhiteNoLighting"); }
void EffectBillboardChain::_createBuffer(void) { if (mRenderOp.vertexData) { delete mRenderOp.vertexData; mRenderOp.vertexData = NULL; } mRenderOp.vertexData = new VertexData(); mRenderOp.indexData = NULL; mRenderOp.vertexData->vertexCount = mCurrentNbChainElements * 2; mRenderOp.vertexData->vertexStart = 0; mRenderOp.operationType = RenderOperation::OT_TRIANGLE_STRIP; mRenderOp.useIndexes = false; VertexDeclaration* decl = mRenderOp.vertexData->vertexDeclaration; VertexBufferBinding* bind = mRenderOp.vertexData->vertexBufferBinding; // Add a description for the buffer of the positions of the vertices size_t offset = 0; decl->addElement(0, offset, VET_FLOAT3, VES_POSITION); offset += VertexElement::getTypeSize(VET_FLOAT3); decl->addElement(0, offset, VET_COLOUR, VES_DIFFUSE); offset += VertexElement::getTypeSize(VET_COLOUR); decl->addElement(0, offset, VET_FLOAT2, VES_TEXTURE_COORDINATES); offset += VertexElement::getTypeSize(VET_FLOAT2); // Create the buffer HardwareVertexBufferSharedPtr pVertexBuffer = HardwareBufferManager::getSingleton().createVertexBuffer( decl->getVertexSize(0), mCurrentNbChainElements * 2, HardwareBuffer::HBU_STATIC_WRITE_ONLY); // Bind the buffer bind->setBinding(0, pVertexBuffer); }
//--------------------------------------------------------------------- void PanelOverlayElement::_releaseManualHardwareResources() { if(!mInitialised) return; VertexBufferBinding* bind = mRenderOp.vertexData->vertexBufferBinding; bind->unsetBinding(POSITION_BINDING); // Remove all texcoord element declarations if(mNumTexCoordsInBuffer > 0) { bind->unsetBinding(TEXCOORD_BINDING); VertexDeclaration* decl = mRenderOp.vertexData->vertexDeclaration; for(size_t i = mNumTexCoordsInBuffer; i > 0; --i) { decl->removeElement(VES_TEXTURE_COORDINATES, static_cast<unsigned short>(i - 1)); } mNumTexCoordsInBuffer = 0; } }
void TextAreaOverlayElement::checkMemoryAllocation( size_t numChars ) { if( mAllocSize < numChars) { // Create and bind new buffers // Note that old buffers will be deleted automatically through reference counting // 6 verts per char since we're doing tri lists without indexes // Allocate space for positions & texture coords VertexDeclaration* decl = mRenderOp.vertexData->vertexDeclaration; VertexBufferBinding* bind = mRenderOp.vertexData->vertexBufferBinding; mRenderOp.vertexData->vertexCount = numChars * 6; // Create dynamic since text tends to change a lot // positions & texcoords HardwareVertexBufferSharedPtr vbuf = HardwareBufferManager::getSingleton(). createVertexBuffer( decl->getVertexSize(POS_TEX_BINDING), mRenderOp.vertexData->vertexCount, HardwareBuffer::HBU_DYNAMIC_WRITE_ONLY); bind->setBinding(POS_TEX_BINDING, vbuf); // colours vbuf = HardwareBufferManager::getSingleton(). createVertexBuffer( decl->getVertexSize(COLOUR_BINDING), mRenderOp.vertexData->vertexCount, HardwareBuffer::HBU_DYNAMIC_WRITE_ONLY); bind->setBinding(COLOUR_BINDING, vbuf); mAllocSize = numChars; mColoursChanged = true; // force colour buffer regeneration } }
//--------------------------------------------------------------------- void PrefabFactory::createCube(Mesh* mesh) { SubMesh* sub = mesh->createSubMesh(); const int NUM_VERTICES = 4 * 6; // 4 vertices per side * 6 sides const int NUM_ENTRIES_PER_VERTEX = 8; const int NUM_VERTEX_ENTRIES = NUM_VERTICES * NUM_ENTRIES_PER_VERTEX; const int NUM_INDICES = 3 * 2 * 6; // 3 indices per face * 2 faces per side * 6 sides const Real CUBE_SIZE = 100.0f; const Real CUBE_HALF_SIZE = CUBE_SIZE / 2.0f; // Create 4 vertices per side instead of 6 that are shared for the whole cube. // The reason for this is with only 6 vertices the normals will look bad // since each vertex can "point" in a different direction depending on the face it is included in. float vertices[NUM_VERTEX_ENTRIES] = { // front side -CUBE_HALF_SIZE, -CUBE_HALF_SIZE, CUBE_HALF_SIZE, // pos 0,0,1, // normal 0,1, // texcoord CUBE_HALF_SIZE, -CUBE_HALF_SIZE, CUBE_HALF_SIZE, 0,0,1, 1,1, CUBE_HALF_SIZE, CUBE_HALF_SIZE, CUBE_HALF_SIZE, 0,0,1, 1,0, -CUBE_HALF_SIZE, CUBE_HALF_SIZE, CUBE_HALF_SIZE , 0,0,1, 0,0, // back side CUBE_HALF_SIZE, -CUBE_HALF_SIZE, -CUBE_HALF_SIZE, 0,0,-1, 0,1, -CUBE_HALF_SIZE, -CUBE_HALF_SIZE, -CUBE_HALF_SIZE, 0,0,-1, 1,1, -CUBE_HALF_SIZE, CUBE_HALF_SIZE, -CUBE_HALF_SIZE, 0,0,-1, 1,0, CUBE_HALF_SIZE, CUBE_HALF_SIZE, -CUBE_HALF_SIZE, 0,0,-1, 0,0, // left side -CUBE_HALF_SIZE, -CUBE_HALF_SIZE, -CUBE_HALF_SIZE, -1,0,0, 0,1, -CUBE_HALF_SIZE, -CUBE_HALF_SIZE, CUBE_HALF_SIZE, -1,0,0, 1,1, -CUBE_HALF_SIZE, CUBE_HALF_SIZE, CUBE_HALF_SIZE, -1,0,0, 1,0, -CUBE_HALF_SIZE, CUBE_HALF_SIZE, -CUBE_HALF_SIZE, -1,0,0, 0,0, // right side CUBE_HALF_SIZE, -CUBE_HALF_SIZE, CUBE_HALF_SIZE, 1,0,0, 0,1, CUBE_HALF_SIZE, -CUBE_HALF_SIZE, -CUBE_HALF_SIZE, 1,0,0, 1,1, CUBE_HALF_SIZE, CUBE_HALF_SIZE, -CUBE_HALF_SIZE, 1,0,0, 1,0, CUBE_HALF_SIZE, CUBE_HALF_SIZE, CUBE_HALF_SIZE, 1,0,0, 0,0, // up side -CUBE_HALF_SIZE, CUBE_HALF_SIZE, CUBE_HALF_SIZE, 0,1,0, 0,1, CUBE_HALF_SIZE, CUBE_HALF_SIZE, CUBE_HALF_SIZE, 0,1,0, 1,1, CUBE_HALF_SIZE, CUBE_HALF_SIZE, -CUBE_HALF_SIZE, 0,1,0, 1,0, -CUBE_HALF_SIZE, CUBE_HALF_SIZE, -CUBE_HALF_SIZE, 0,1,0, 0,0, // down side -CUBE_HALF_SIZE, -CUBE_HALF_SIZE, -CUBE_HALF_SIZE, 0,-1,0, 0,1, CUBE_HALF_SIZE, -CUBE_HALF_SIZE, -CUBE_HALF_SIZE, 0,-1,0, 1,1, CUBE_HALF_SIZE, -CUBE_HALF_SIZE, CUBE_HALF_SIZE, 0,-1,0, 1,0, -CUBE_HALF_SIZE, -CUBE_HALF_SIZE, CUBE_HALF_SIZE, 0,-1,0, 0,0 }; mesh->sharedVertexData = OGRE_NEW VertexData(); mesh->sharedVertexData->vertexCount = NUM_VERTICES; VertexDeclaration* decl = mesh->sharedVertexData->vertexDeclaration; VertexBufferBinding* bind = mesh->sharedVertexData->vertexBufferBinding; size_t offset = 0; decl->addElement(0, offset, VET_FLOAT3, VES_POSITION); offset += VertexElement::getTypeSize(VET_FLOAT3); decl->addElement(0, offset, VET_FLOAT3, VES_NORMAL); offset += VertexElement::getTypeSize(VET_FLOAT3); decl->addElement(0, offset, VET_FLOAT2, VES_TEXTURE_COORDINATES, 0); offset += VertexElement::getTypeSize(VET_FLOAT2); HardwareVertexBufferSharedPtr vbuf = HardwareBufferManager::getSingleton().createVertexBuffer( offset, NUM_VERTICES, HardwareBuffer::HBU_STATIC_WRITE_ONLY); bind->setBinding(0, vbuf); vbuf->writeData(0, vbuf->getSizeInBytes(), vertices, true); sub->useSharedVertices = true; HardwareIndexBufferSharedPtr ibuf = HardwareBufferManager::getSingleton(). createIndexBuffer( HardwareIndexBuffer::IT_16BIT, NUM_INDICES, HardwareBuffer::HBU_STATIC_WRITE_ONLY); unsigned short faces[NUM_INDICES] = { // front 0,1,2, 0,2,3, // back 4,5,6, 4,6,7, // left 8,9,10, 8,10,11, // right 12,13,14, 12,14,15, // up 16,17,18, 16,18,19, // down 20,21,22, 20,22,23 }; sub->indexData->indexBuffer = ibuf; sub->indexData->indexCount = NUM_INDICES; sub->indexData->indexStart = 0; ibuf->writeData(0, ibuf->getSizeInBytes(), faces, true); mesh->_setBounds(AxisAlignedBox(-CUBE_HALF_SIZE, -CUBE_HALF_SIZE, -CUBE_HALF_SIZE, CUBE_HALF_SIZE, CUBE_HALF_SIZE, CUBE_HALF_SIZE), true); mesh->_setBoundingSphereRadius(CUBE_HALF_SIZE); }
void Rectangle2D::_initRectangle2D(bool includeTextureCoords, Ogre::HardwareBuffer::Usage vBufUsage) { // use identity projection and view matrices mUseIdentityProjection = true; mUseIdentityView = true; mRenderOp.vertexData = OGRE_NEW VertexData(); mRenderOp.indexData = 0; mRenderOp.vertexData->vertexCount = 4; mRenderOp.vertexData->vertexStart = 0; mRenderOp.operationType = RenderOperation::OT_TRIANGLE_STRIP; mRenderOp.useIndexes = false; mRenderOp.useGlobalInstancingVertexBufferIsAvailable = false; VertexDeclaration* decl = mRenderOp.vertexData->vertexDeclaration; VertexBufferBinding* bind = mRenderOp.vertexData->vertexBufferBinding; decl->addElement(POSITION_BINDING, 0, VET_FLOAT3, VES_POSITION); HardwareVertexBufferSharedPtr vbuf = HardwareBufferManager::getSingleton().createVertexBuffer( decl->getVertexSize(POSITION_BINDING), mRenderOp.vertexData->vertexCount, vBufUsage); // Bind buffer bind->setBinding(POSITION_BINDING, vbuf); decl->addElement(NORMAL_BINDING, 0, VET_FLOAT3, VES_NORMAL); vbuf = HardwareBufferManager::getSingleton().createVertexBuffer( decl->getVertexSize(NORMAL_BINDING), mRenderOp.vertexData->vertexCount, vBufUsage); bind->setBinding(NORMAL_BINDING, vbuf); float *pNorm = static_cast<float*>(vbuf->lock(HardwareBuffer::HBL_DISCARD)); *pNorm++ = 0.0f; *pNorm++ = 0.0f; *pNorm++ = 1.0f; *pNorm++ = 0.0f; *pNorm++ = 0.0f; *pNorm++ = 1.0f; *pNorm++ = 0.0f; *pNorm++ = 0.0f; *pNorm++ = 1.0f; *pNorm++ = 0.0f; *pNorm++ = 0.0f; *pNorm++ = 1.0f; vbuf->unlock(); if (includeTextureCoords) { decl->addElement(TEXCOORD_BINDING, 0, VET_FLOAT2, VES_TEXTURE_COORDINATES); HardwareVertexBufferSharedPtr tvbuf = HardwareBufferManager::getSingleton().createVertexBuffer( decl->getVertexSize(TEXCOORD_BINDING), mRenderOp.vertexData->vertexCount, vBufUsage); // Bind buffer bind->setBinding(TEXCOORD_BINDING, tvbuf); // Set up basic tex coordinates setDefaultUVs(); } // set basic white material this->setMaterial("BaseWhiteNoLighting"); }
WaterMesh::WaterMesh(const String& inMeshName, Real planeSize, int inComplexity) { int x,y,b; // I prefer to initialize for() variables inside it, but VC doesn't like it ;( this->meshName = inMeshName ; this->complexity = inComplexity ; numFaces = 2 * complexity * complexity; numVertices = (complexity + 1) * (complexity + 1) ; lastTimeStamp = 0 ; lastAnimationTimeStamp = 0; lastFrameTime = 0 ; // initialize algorithm parameters PARAM_C = 0.3f ; // ripple speed PARAM_D = 0.4f ; // distance PARAM_U = 0.05f ; // viscosity PARAM_T = 0.13f ; // time useFakeNormals = false ; // allocate space for normal calculation vNormals = new Vector3[numVertices]; // create mesh and submesh mesh = MeshManager::getSingleton().createManual(meshName, ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); subMesh = mesh->createSubMesh(); subMesh->useSharedVertices=false; // Vertex buffers subMesh->vertexData = new VertexData(); subMesh->vertexData->vertexStart = 0; subMesh->vertexData->vertexCount = numVertices; VertexDeclaration* vdecl = subMesh->vertexData->vertexDeclaration; VertexBufferBinding* vbind = subMesh->vertexData->vertexBufferBinding; vdecl->addElement(0, 0, VET_FLOAT3, VES_POSITION); vdecl->addElement(1, 0, VET_FLOAT3, VES_NORMAL); vdecl->addElement(2, 0, VET_FLOAT2, VES_TEXTURE_COORDINATES); // Prepare buffer for positions - todo: first attempt, slow posVertexBuffer = HardwareBufferManager::getSingleton().createVertexBuffer( 3*sizeof(float), numVertices, HardwareBuffer::HBU_DYNAMIC_WRITE_ONLY_DISCARDABLE); vbind->setBinding(0, posVertexBuffer); // Prepare buffer for normals - write only normVertexBuffer = HardwareBufferManager::getSingleton().createVertexBuffer( 3*sizeof(float), numVertices, HardwareBuffer::HBU_DYNAMIC_WRITE_ONLY_DISCARDABLE); vbind->setBinding(1, normVertexBuffer); // Prepare texture coords buffer - static one // todo: optimize to write directly into buffer float *texcoordsBufData = new float[numVertices*2]; for(y=0;y<=complexity;y++) { for(x=0;x<=complexity;x++) { texcoordsBufData[2*(y*(complexity+1)+x)+0] = (float)x / complexity ; texcoordsBufData[2*(y*(complexity+1)+x)+1] = 1.0f - ((float)y / (complexity)) ; } } texcoordsVertexBuffer = HardwareBufferManager::getSingleton().createVertexBuffer( 2*sizeof(float), numVertices, HardwareBuffer::HBU_STATIC_WRITE_ONLY); texcoordsVertexBuffer->writeData(0, texcoordsVertexBuffer->getSizeInBytes(), texcoordsBufData, true); // true? delete [] texcoordsBufData; vbind->setBinding(2, texcoordsVertexBuffer); // Prepare buffer for indices indexBuffer = HardwareBufferManager::getSingleton().createIndexBuffer( HardwareIndexBuffer::IT_16BIT, 3*numFaces, HardwareBuffer::HBU_STATIC, true); unsigned short *faceVertexIndices = (unsigned short*) indexBuffer->lock(0, numFaces*3*2, HardwareBuffer::HBL_DISCARD); for(y=0 ; y<complexity ; y++) { for(x=0 ; x<complexity ; x++) { unsigned short *twoface = faceVertexIndices + (y*complexity+x)*2*3; int p0 = y*(complexity+1) + x ; int p1 = y*(complexity+1) + x + 1 ; int p2 = (y+1)*(complexity+1) + x ; int p3 = (y+1)*(complexity+1) + x + 1 ; twoface[0]=p2; //first tri twoface[1]=p1; twoface[2]=p0; twoface[3]=p2; //second tri twoface[4]=p3; twoface[5]=p1; } } indexBuffer->unlock(); // Set index buffer for this submesh subMesh->indexData->indexBuffer = indexBuffer; subMesh->indexData->indexStart = 0; subMesh->indexData->indexCount = 3*numFaces; /* prepare vertex positions * note - we use 3 vertex buffers, since algorighm uses two last phases * to calculate the next one */ for(b=0;b<3;b++) { vertexBuffers[b] = new float[numVertices * 3] ; for(y=0;y<=complexity;y++) { for(x=0;x<=complexity;x++) { int numPoint = y*(complexity+1) + x ; float* vertex = vertexBuffers[b] + 3*numPoint ; vertex[0]=(float)(x) / (float)(complexity) * (float) planeSize ; vertex[1]= 0 ; // rand() % 30 ; vertex[2]=(float)(y) / (float)(complexity) * (float) planeSize ; } } } AxisAlignedBox meshBounds(0,0,0, planeSize,0, planeSize); mesh->_setBounds(meshBounds); currentBuffNumber = 0 ; posVertexBuffer->writeData(0, posVertexBuffer->getSizeInBytes(), // size vertexBuffers[currentBuffNumber], // source true); // discard? mesh->load(); mesh->touch(); }
void MovableText::_setupGeometry() { assert(mpFont); assert(!mpMaterial.isNull()); unsigned int vertexCount = 0; //count letters to determine how many vertices are needed std::string::iterator i = mCaption.begin(); std::string::iterator iend = mCaption.end(); for ( ; i != iend; ++i ) { if ((*i != ' ') && (*i != '\n')) { vertexCount += 6; } } if (mRenderOp.vertexData) { delete mRenderOp.vertexData; mRenderOp.vertexData = NULL; mUpdateColors = true; } if (mCaption.empty()) { return; } if (!mRenderOp.vertexData) mRenderOp.vertexData = new VertexData(); mRenderOp.indexData = 0; mRenderOp.vertexData->vertexStart = 0; mRenderOp.vertexData->vertexCount = vertexCount; mRenderOp.operationType = RenderOperation::OT_TRIANGLE_LIST; mRenderOp.useIndexes = false; VertexDeclaration *decl = mRenderOp.vertexData->vertexDeclaration; VertexBufferBinding *bind = mRenderOp.vertexData->vertexBufferBinding; size_t offset = 0; // create/bind positions/tex.ccord. buffer if (!decl->findElementBySemantic(VES_POSITION)) decl->addElement(POS_TEX_BINDING, offset, VET_FLOAT3, VES_POSITION); offset += VertexElement::getTypeSize(VET_FLOAT3); if (!decl->findElementBySemantic(VES_TEXTURE_COORDINATES)) decl->addElement(POS_TEX_BINDING, offset, Ogre::VET_FLOAT2, Ogre::VES_TEXTURE_COORDINATES, 0); HardwareVertexBufferSharedPtr ptbuf = HardwareBufferManager::getSingleton().createVertexBuffer( decl->getVertexSize(POS_TEX_BINDING), mRenderOp.vertexData->vertexCount, HardwareBuffer::HBU_DYNAMIC_WRITE_ONLY); bind->setBinding(POS_TEX_BINDING, ptbuf); // Colours - store these in a separate buffer because they change less often if (!decl->findElementBySemantic(VES_DIFFUSE)) decl->addElement(COLOUR_BINDING, 0, VET_COLOUR, VES_DIFFUSE); HardwareVertexBufferSharedPtr cbuf = HardwareBufferManager::getSingleton().createVertexBuffer( decl->getVertexSize(COLOUR_BINDING), mRenderOp.vertexData->vertexCount, HardwareBuffer::HBU_DYNAMIC_WRITE_ONLY); bind->setBinding(COLOUR_BINDING, cbuf); float *pPCBuff = static_cast<float*> (ptbuf->lock(HardwareBuffer::HBL_DISCARD)); Real spaceWidth = mSpaceWidth; // Derive space width from a capital A if (spaceWidth == 0) spaceWidth = mpFont->getGlyphAspectRatio('A') * mCharHeight * 2.0; float total_height = mCharHeight; float total_width = 0.0f; float current_width = 0.0f; i = mCaption.begin(); iend = mCaption.end(); for ( ; i != iend; ++i ) { if (*i == '\n') { total_height += mCharHeight + 0.01; if ( current_width > total_width ) { total_width = current_width; current_width = 0.0; } } else { current_width += mpFont->getGlyphAspectRatio(*i) * mCharHeight * 2.0; } } if ( current_width > total_width ) { total_width = current_width; } float top = 0.0f; switch (mVerticalAlignment) { case MovableText::V_ABOVE: top = total_height * 2; break; case MovableText::V_CENTER: top = 0.5 * total_height * 2; break; case MovableText::V_BELOW: top = 0.0f; break; } float starting_left = 0.0f; switch (mHorizontalAlignment) { case MovableText::H_LEFT: starting_left = 0.0f; break; case MovableText::H_CENTER: starting_left = -total_width / 2.0f; break; } float left = starting_left; bool newLine = true; Real len = 0.0f; // for calculation of AABB Ogre::Vector3 min(9999999.0f), max(-9999999.0f), currPos(0.0f); Ogre::Real maxSquaredRadius = -99999999.0f; float largestWidth = 0.0f; for (i = mCaption.begin(); i != iend; ++i) { if (newLine) { len = 0.0f; for (String::iterator j = i; j != iend && *j != '\n'; j++) { if (*j == ' ') len += spaceWidth; else len += mpFont->getGlyphAspectRatio(*j) * mCharHeight * 2.0; } newLine = false; } if (*i == '\n') { left = starting_left; top -= mCharHeight * 2.0; newLine = true; continue; } if (*i == ' ') { // Just leave a gap, no tris left += spaceWidth; continue; } Real horiz_height = mpFont->getGlyphAspectRatio(*i); Real u1, u2, v1, v2; Ogre::Font::UVRect utmp; utmp = mpFont->getGlyphTexCoords(*i); u1 = utmp.left; u2 = utmp.right; v1 = utmp.top; v2 = utmp.bottom; // each vert is (x, y, z, u, v) //------------------------------------------------------------------------------------- // First tri // // Upper left currPos = Ogre::Vector3(left, top, 0.0); *pPCBuff++ = currPos.x; *pPCBuff++ = currPos.y; *pPCBuff++ = currPos.z; *pPCBuff++ = u1; *pPCBuff++ = v1; // Deal with bounds min.makeFloor(currPos); max.makeCeil(currPos); maxSquaredRadius = std::max(maxSquaredRadius, currPos.squaredLength()); top -= mCharHeight * 2.0; // Bottom left currPos = Ogre::Vector3(left, top, 0.0); *pPCBuff++ = currPos.x; *pPCBuff++ = currPos.y; *pPCBuff++ = currPos.z; *pPCBuff++ = u1; *pPCBuff++ = v2; // Deal with bounds min.makeFloor(currPos); max.makeCeil(currPos); maxSquaredRadius = std::max(maxSquaredRadius, currPos.squaredLength()); top += mCharHeight * 2.0; left += horiz_height * mCharHeight * 2.0; // Top right currPos = Ogre::Vector3(left, top, 0.0); *pPCBuff++ = currPos.x; *pPCBuff++ = currPos.y; *pPCBuff++ = currPos.z; *pPCBuff++ = u2; *pPCBuff++ = v1; //------------------------------------------------------------------------------------- // Deal with bounds min.makeFloor(currPos); max.makeCeil(currPos); maxSquaredRadius = std::max(maxSquaredRadius, currPos.squaredLength()); //------------------------------------------------------------------------------------- // Second tri // // Top right (again) currPos = Ogre::Vector3(left, top, 0.0); *pPCBuff++ = currPos.x; *pPCBuff++ = currPos.y; *pPCBuff++ = currPos.z; *pPCBuff++ = u2; *pPCBuff++ = v1; min.makeFloor(currPos); max.makeCeil(currPos); maxSquaredRadius = std::max(maxSquaredRadius, currPos.squaredLength()); top -= mCharHeight * 2.0; left -= horiz_height * mCharHeight * 2.0; // Bottom left (again) currPos = Ogre::Vector3(left, top, 0.0); *pPCBuff++ = currPos.x; *pPCBuff++ = currPos.y; *pPCBuff++ = currPos.z; *pPCBuff++ = u1; *pPCBuff++ = v2; min.makeFloor(currPos); max.makeCeil(currPos); maxSquaredRadius = std::max(maxSquaredRadius, currPos.squaredLength()); left += horiz_height * mCharHeight * 2.0; // Bottom right currPos = Ogre::Vector3(left, top, 0.0); *pPCBuff++ = currPos.x; *pPCBuff++ = currPos.y; *pPCBuff++ = currPos.z; *pPCBuff++ = u2; *pPCBuff++ = v2; //------------------------------------------------------------------------------------- min.makeFloor(currPos); max.makeCeil(currPos); maxSquaredRadius = std::max(maxSquaredRadius, currPos.squaredLength()); // Go back up with top top += mCharHeight * 2.0; float currentWidth = (left + 1) / 2 - 0; if (currentWidth > largestWidth) largestWidth = currentWidth; } // Unlock vertex buffer ptbuf->unlock(); // update AABB/Sphere radius mAABB = Ogre::AxisAlignedBox(min, max); mRadius = Ogre::Math::Sqrt(maxSquaredRadius); if (mUpdateColors) this->_updateColors(); mNeedUpdate = false; }
void MovableText::_setupGeometry() { assert(mpFont); assert(!mpMaterial.isNull()); unsigned int vertexCount = static_cast<unsigned int>(mCaption.size() * 6); if (mRenderOp.vertexData) { // Removed this test as it causes problems when replacing a caption // of the same size: replacing "Hello" with "hello" // as well as when changing the text alignment //if (mRenderOp.vertexData->vertexCount != vertexCount) { delete mRenderOp.vertexData; mRenderOp.vertexData = NULL; mUpdateColors = true; } } if (!mRenderOp.vertexData) mRenderOp.vertexData = new VertexData(); mRenderOp.indexData = 0; mRenderOp.vertexData->vertexStart = 0; mRenderOp.vertexData->vertexCount = vertexCount; mRenderOp.operationType = RenderOperation::OT_TRIANGLE_LIST; mRenderOp.useIndexes = false; VertexDeclaration *decl = mRenderOp.vertexData->vertexDeclaration; VertexBufferBinding *bind = mRenderOp.vertexData->vertexBufferBinding; size_t offset = 0; // create/bind positions/tex.ccord. buffer if (!decl->findElementBySemantic(VES_POSITION)) decl->addElement(POS_TEX_BINDING, offset, VET_FLOAT3, VES_POSITION); offset += VertexElement::getTypeSize(VET_FLOAT3); if (!decl->findElementBySemantic(VES_TEXTURE_COORDINATES)) decl->addElement(POS_TEX_BINDING, offset, Ogre::VET_FLOAT2, Ogre::VES_TEXTURE_COORDINATES, 0); HardwareVertexBufferSharedPtr ptbuf = HardwareBufferManager::getSingleton().createVertexBuffer(decl->getVertexSize(POS_TEX_BINDING), mRenderOp.vertexData->vertexCount, HardwareBuffer::HBU_DYNAMIC_WRITE_ONLY); bind->setBinding(POS_TEX_BINDING, ptbuf); // Colours - store these in a separate buffer because they change less often if (!decl->findElementBySemantic(VES_DIFFUSE)) decl->addElement(COLOUR_BINDING, 0, VET_COLOUR, VES_DIFFUSE); HardwareVertexBufferSharedPtr cbuf = HardwareBufferManager::getSingleton().createVertexBuffer(decl->getVertexSize(COLOUR_BINDING), mRenderOp.vertexData->vertexCount, HardwareBuffer::HBU_DYNAMIC_WRITE_ONLY); bind->setBinding(COLOUR_BINDING, cbuf); size_t charlen = mCaption.size(); float *pPCBuff = static_cast<float*>(ptbuf->lock(HardwareBuffer::HBL_DISCARD)); float largestWidth = 0; float left = 0 * 2.0 - 1.0; float top = -((0 * 2.0) - 1.0); Real spaceWidth = mSpaceWidth; // Derive space width from a capital A if (spaceWidth == 0) spaceWidth = mpFont->getGlyphAspectRatio('A') * mCharHeight * 2.0; // for calculation of AABB Ogre::Vector3 min, max, currPos; Ogre::Real maxSquaredRadius; bool first = true; // Use iterator String::iterator i, iend; iend = mCaption.end(); bool newLine = true; Real len = 0.0f; Real verticalOffset = 0; switch (mVerticalAlignment) { case MovableText::V_ABOVE: verticalOffset = mCharHeight; break; case MovableText::V_CENTER: verticalOffset = 0.5*mCharHeight; break; case MovableText::V_BELOW: verticalOffset = 0; break; } // Raise the first line of the caption top += verticalOffset; for (i = mCaption.begin(); i != iend; ++i) { if (*i == '\n') top += verticalOffset * 2.0; } for (i = mCaption.begin(); i != iend; ++i) { if (newLine) { len = 0.0f; for (String::iterator j = i; j != iend && *j != '\n'; j++) { if (*j == ' ') len += spaceWidth; else len += mpFont->getGlyphAspectRatio((unsigned char)*j) * mCharHeight * 2.0; } newLine = false; } if (*i == '\n') { left = 0 * 2.0 - 1.0; top -= mCharHeight * 2.0; newLine = true; // Bugfix by Wladimir Lukutin - thanks :) // Also reduce tri count mRenderOp.vertexData->vertexCount -= 6; // Bugfix end. continue; } if (*i == ' ') { // Just leave a gap, no tris left += spaceWidth; // Also reduce tri count mRenderOp.vertexData->vertexCount -= 6; continue; } Real horiz_height = mpFont->getGlyphAspectRatio((unsigned char)*i); Real u1, u2, v1, v2; Ogre::Font::UVRect utmp; utmp = mpFont->getGlyphTexCoords((unsigned char)*i); u1 = utmp.left; u2 = utmp.right; v1 = utmp.top; v2 = utmp.bottom; // each vert is (x, y, z, u, v) //------------------------------------------------------------------------------------- // First tri // // Upper left if(mHorizontalAlignment == MovableText::H_LEFT) *pPCBuff++ = left; else *pPCBuff++ = left - (len / 2); *pPCBuff++ = top; *pPCBuff++ = -1.0; *pPCBuff++ = u1; *pPCBuff++ = v1; // Deal with bounds if(mHorizontalAlignment == MovableText::H_LEFT) currPos = Ogre::Vector3(left, top, -1.0); else currPos = Ogre::Vector3(left - (len / 2), top, -1.0); if (first) { min = max = currPos; maxSquaredRadius = currPos.squaredLength(); first = false; } else { min.makeFloor(currPos); max.makeCeil(currPos); maxSquaredRadius = std::max(maxSquaredRadius, currPos.squaredLength()); } top -= mCharHeight * 2.0; // Bottom left if(mHorizontalAlignment == MovableText::H_LEFT) *pPCBuff++ = left; else *pPCBuff++ = left - (len / 2); *pPCBuff++ = top; *pPCBuff++ = -1.0; *pPCBuff++ = u1; *pPCBuff++ = v2; // Deal with bounds if(mHorizontalAlignment == MovableText::H_LEFT) currPos = Ogre::Vector3(left, top, -1.0); else currPos = Ogre::Vector3(left - (len / 2), top, -1.0); min.makeFloor(currPos); max.makeCeil(currPos); maxSquaredRadius = std::max(maxSquaredRadius, currPos.squaredLength()); top += mCharHeight * 2.0; left += horiz_height * mCharHeight * 2.0; // Top right if(mHorizontalAlignment == MovableText::H_LEFT) *pPCBuff++ = left; else *pPCBuff++ = left - (len / 2); *pPCBuff++ = top; *pPCBuff++ = -1.0; *pPCBuff++ = u2; *pPCBuff++ = v1; //------------------------------------------------------------------------------------- // Deal with bounds if(mHorizontalAlignment == MovableText::H_LEFT) currPos = Ogre::Vector3(left, top, -1.0); else currPos = Ogre::Vector3(left - (len / 2), top, -1.0); min.makeFloor(currPos); max.makeCeil(currPos); maxSquaredRadius = std::max(maxSquaredRadius, currPos.squaredLength()); //------------------------------------------------------------------------------------- // Second tri // // Top right (again) if(mHorizontalAlignment == MovableText::H_LEFT) *pPCBuff++ = left; else *pPCBuff++ = left - (len / 2); *pPCBuff++ = top; *pPCBuff++ = -1.0; *pPCBuff++ = u2; *pPCBuff++ = v1; currPos = Ogre::Vector3(left, top, -1.0); min.makeFloor(currPos); max.makeCeil(currPos); maxSquaredRadius = std::max(maxSquaredRadius, currPos.squaredLength()); top -= mCharHeight * 2.0; left -= horiz_height * mCharHeight * 2.0; // Bottom left (again) if(mHorizontalAlignment == MovableText::H_LEFT) *pPCBuff++ = left; else *pPCBuff++ = left - (len / 2); *pPCBuff++ = top; *pPCBuff++ = -1.0; *pPCBuff++ = u1; *pPCBuff++ = v2; currPos = Ogre::Vector3(left, top, -1.0); min.makeFloor(currPos); max.makeCeil(currPos); maxSquaredRadius = std::max(maxSquaredRadius, currPos.squaredLength()); left += horiz_height * mCharHeight * 2.0; // Bottom right if(mHorizontalAlignment == MovableText::H_LEFT) *pPCBuff++ = left; else *pPCBuff++ = left - (len / 2); *pPCBuff++ = top; *pPCBuff++ = -1.0; *pPCBuff++ = u2; *pPCBuff++ = v2; //------------------------------------------------------------------------------------- currPos = Ogre::Vector3(left, top, -1.0); min.makeFloor(currPos); max.makeCeil(currPos); maxSquaredRadius = std::max(maxSquaredRadius, currPos.squaredLength()); // Go back up with top top += mCharHeight * 2.0; float currentWidth = (left + 1)/2 - 0; if (currentWidth > largestWidth) largestWidth = currentWidth; } // Unlock vertex buffer ptbuf->unlock(); // update AABB/Sphere radius mAABB = Ogre::AxisAlignedBox(min, max); mRadius = Ogre::Math::Sqrt(maxSquaredRadius); if (mUpdateColors) this->_updateColors(); mNeedUpdate = false; }
void VolumeRenderable::initialise() { // Create geometry size_t nvertices = mSlices*4; // n+1 planes size_t elemsize = 3*3; size_t dsize = elemsize*nvertices; size_t x; Ogre::IndexData *idata = new Ogre::IndexData(); Ogre::VertexData *vdata = new Ogre::VertexData(); // Create structures float *vertices = new float[dsize]; float coords[4][2] = { {0.0f, 0.0f}, {0.0f, 1.0f}, {1.0f, 0.0f}, {1.0f, 1.0f} }; for(x=0; x<mSlices; x++) { for(size_t y=0; y<4; y++) { float xcoord = coords[y][0]-0.5; float ycoord = coords[y][1]-0.5; float zcoord = -((float)x/(float)(mSlices-1) - 0.5f); // 1.0f .. a/(a+1) // coordinate vertices[x*4*elemsize+y*elemsize+0] = xcoord*(mSize/2.0f); vertices[x*4*elemsize+y*elemsize+1] = ycoord*(mSize/2.0f); vertices[x*4*elemsize+y*elemsize+2] = zcoord*(mSize/2.0f); // normal vertices[x*4*elemsize+y*elemsize+3] = 0.0f; vertices[x*4*elemsize+y*elemsize+4] = 0.0f; vertices[x*4*elemsize+y*elemsize+5] = 1.0f; // tex vertices[x*4*elemsize+y*elemsize+6] = xcoord*sqrtf(3.0f); vertices[x*4*elemsize+y*elemsize+7] = ycoord*sqrtf(3.0f); vertices[x*4*elemsize+y*elemsize+8] = zcoord*sqrtf(3.0f); } } unsigned short *faces = new unsigned short[mSlices*6]; for(x=0; x<mSlices; x++) { faces[x*6+0] = x*4+0; faces[x*6+1] = x*4+1; faces[x*6+2] = x*4+2; faces[x*6+3] = x*4+1; faces[x*6+4] = x*4+2; faces[x*6+5] = x*4+3; } // Setup buffers vdata->vertexStart = 0; vdata->vertexCount = nvertices; VertexDeclaration* decl = vdata->vertexDeclaration; VertexBufferBinding* bind = vdata->vertexBufferBinding; size_t offset = 0; decl->addElement(0, offset, VET_FLOAT3, VES_POSITION); offset += VertexElement::getTypeSize(VET_FLOAT3); decl->addElement(0, offset, VET_FLOAT3, VES_NORMAL); offset += VertexElement::getTypeSize(VET_FLOAT3); decl->addElement(0, offset, VET_FLOAT3, VES_TEXTURE_COORDINATES); offset += VertexElement::getTypeSize(VET_FLOAT3); HardwareVertexBufferSharedPtr vbuf = HardwareBufferManager::getSingleton().createVertexBuffer( offset, nvertices, HardwareBuffer::HBU_STATIC_WRITE_ONLY); bind->setBinding(0, vbuf); vbuf->writeData(0, vbuf->getSizeInBytes(), vertices, true); HardwareIndexBufferSharedPtr ibuf = HardwareBufferManager::getSingleton(). createIndexBuffer( HardwareIndexBuffer::IT_16BIT, mSlices*6, HardwareBuffer::HBU_STATIC_WRITE_ONLY); idata->indexBuffer = ibuf; idata->indexCount = mSlices*6; idata->indexStart = 0; ibuf->writeData(0, ibuf->getSizeInBytes(), faces, true); // Delete temporary buffers delete [] vertices; delete [] faces; // Now make the render operation mRenderOp.operationType = Ogre::RenderOperation::OT_TRIANGLE_LIST; mRenderOp.indexData = idata; mRenderOp.vertexData = vdata; mRenderOp.useIndexes = true; // Create a brand new private material MaterialPtr material = MaterialManager::getSingleton().create(mTexture, "VolumeRenderable", false, 0); // Manual, loader // Remove pre-created technique from defaults material->removeAllTechniques(); // Create a techinique and a pass and a texture unit Technique * technique = material->createTechnique(); Pass * pass = technique->createPass(); TextureUnitState * textureUnit = pass->createTextureUnitState(); // Set pass parameters pass->setSceneBlending(SBT_TRANSPARENT_ALPHA); pass->setDepthWriteEnabled(false); pass->setCullingMode(CULL_NONE); pass->setLightingEnabled(false); // Set texture unit parameters textureUnit->setTextureAddressingMode(TextureUnitState::TAM_CLAMP); textureUnit->setTextureName(mTexture, TEX_TYPE_3D); textureUnit->setTextureFiltering(TFO_TRILINEAR); mUnit = textureUnit; m_pMaterial = material; }
void OgreMesh::syncFromOgreMesh(Ogre::Entity *entity,Ogre::SubMesh*subMesh) { const Ogre::Vector3 &position = entity->getParentNode()->_getDerivedPosition(); const Ogre::Quaternion &orient = entity->getParentNode()->_getDerivedOrientation(); const Ogre::Vector3 &scale = entity->getParentNode()->_getDerivedScale(); VertexData *vertexData = subMesh->vertexData; if (vertexData) { VertexDeclaration *vertexDecl = vertexData->vertexDeclaration; // find the element for position const VertexElement *element = vertexDecl->findElementBySemantic(Ogre::VES_POSITION); // find and lock the buffer containing position information VertexBufferBinding *bufferBinding = vertexData->vertexBufferBinding; HardwareVertexBuffer *buffer = bufferBinding->getBuffer(element->getSource()).get(); unsigned char *pVert = static_cast<unsigned char*>(buffer->lock(HardwareBuffer::HBL_READ_ONLY)); std::vector<Ogre::Vector3> lvertices; for (size_t vert = 0; vert < vertexData->vertexCount; vert++) { Real *vertex = 0; Real x, y, z; element->baseVertexPointerToElement(pVert, &vertex); x = *vertex++; y = *vertex++; z = *vertex++; Ogre::Vector3 vec(x, y, z); vec = (orient * (vec * scale)) + position; lvertices.push_back(vec); pVert += buffer->getVertexSize(); } buffer->unlock(); // find and lock buffer containg vertex indices IndexData * indexData = subMesh->indexData; HardwareIndexBuffer *indexBuffer = indexData->indexBuffer.get(); void *pIndex = static_cast<unsigned char *>(indexBuffer->lock(HardwareBuffer::HBL_READ_ONLY)); if (indexBuffer->getType() == HardwareIndexBuffer::IT_16BIT) { for (size_t index = indexData->indexStart; index < indexData->indexCount; ) { uint16 *uint16Buffer = (uint16 *) pIndex; uint16 v1 = uint16Buffer[index++]; uint16 v2 = uint16Buffer[index++]; uint16 v3 = uint16Buffer[index++]; mTriangles.push_back(Triangle(lvertices[v1], lvertices[v2], lvertices[v3])); } } else if (indexBuffer->getType() == HardwareIndexBuffer::IT_32BIT) { for (size_t index = indexData->indexStart; index < indexData->indexCount; ) { uint32 *uint16Buffer = (uint32 *) pIndex; uint32 v1 = uint16Buffer[index++]; uint32 v2 = uint16Buffer[index++]; uint32 v3 = uint16Buffer[index++]; mTriangles.push_back(Triangle(lvertices[v1], lvertices[v2], lvertices[v3])); } } else { assert(0); } indexBuffer->unlock(); } }
//--------------------------------------------------------------------- void PrefabFactory::createSphere(Mesh* mesh) { // sphere creation code taken from the DeferredShading sample, originally from the wiki SubMesh *pSphereVertex = mesh->createSubMesh(); const int NUM_SEGMENTS = 16; const int NUM_RINGS = 16; const Real SPHERE_RADIUS = 50.0; mesh->sharedVertexData = OGRE_NEW VertexData(); VertexData* vertexData = mesh->sharedVertexData; // define the vertex format VertexDeclaration* vertexDecl = vertexData->vertexDeclaration; size_t currOffset = 0; // positions vertexDecl->addElement(0, currOffset, VET_FLOAT3, VES_POSITION); currOffset += VertexElement::getTypeSize(VET_FLOAT3); // normals vertexDecl->addElement(0, currOffset, VET_FLOAT3, VES_NORMAL); currOffset += VertexElement::getTypeSize(VET_FLOAT3); // two dimensional texture coordinates vertexDecl->addElement(0, currOffset, VET_FLOAT2, VES_TEXTURE_COORDINATES, 0); // allocate the vertex buffer vertexData->vertexCount = (NUM_RINGS + 1) * (NUM_SEGMENTS+1); HardwareVertexBufferSharedPtr vBuf = HardwareBufferManager::getSingleton().createVertexBuffer(vertexDecl->getVertexSize(0), vertexData->vertexCount, HardwareBuffer::HBU_STATIC_WRITE_ONLY, false); VertexBufferBinding* binding = vertexData->vertexBufferBinding; binding->setBinding(0, vBuf); float* pVertex = static_cast<float*>(vBuf->lock(HardwareBuffer::HBL_DISCARD)); // allocate index buffer pSphereVertex->indexData->indexCount = 6 * NUM_RINGS * (NUM_SEGMENTS + 1); pSphereVertex->indexData->indexBuffer = HardwareBufferManager::getSingleton().createIndexBuffer(HardwareIndexBuffer::IT_16BIT, pSphereVertex->indexData->indexCount, HardwareBuffer::HBU_STATIC_WRITE_ONLY, false); HardwareIndexBufferSharedPtr iBuf = pSphereVertex->indexData->indexBuffer; unsigned short* pIndices = static_cast<unsigned short*>(iBuf->lock(HardwareBuffer::HBL_DISCARD)); float fDeltaRingAngle = (Math::PI / NUM_RINGS); float fDeltaSegAngle = (2 * Math::PI / NUM_SEGMENTS); unsigned short wVerticeIndex = 0 ; // Generate the group of rings for the sphere for( int ring = 0; ring <= NUM_RINGS; ring++ ) { float r0 = SPHERE_RADIUS * sinf (ring * fDeltaRingAngle); float y0 = SPHERE_RADIUS * cosf (ring * fDeltaRingAngle); // Generate the group of segments for the current ring for(int seg = 0; seg <= NUM_SEGMENTS; seg++) { float x0 = r0 * sinf(seg * fDeltaSegAngle); float z0 = r0 * cosf(seg * fDeltaSegAngle); // Add one vertex to the strip which makes up the sphere *pVertex++ = x0; *pVertex++ = y0; *pVertex++ = z0; Vector3 vNormal = Vector3(x0, y0, z0).normalisedCopy(); *pVertex++ = vNormal.x; *pVertex++ = vNormal.y; *pVertex++ = vNormal.z; *pVertex++ = (float) seg / (float) NUM_SEGMENTS; *pVertex++ = (float) ring / (float) NUM_RINGS; if (ring != NUM_RINGS) { // each vertex (except the last) has six indicies pointing to it *pIndices++ = wVerticeIndex + NUM_SEGMENTS + 1; *pIndices++ = wVerticeIndex; *pIndices++ = wVerticeIndex + NUM_SEGMENTS; *pIndices++ = wVerticeIndex + NUM_SEGMENTS + 1; *pIndices++ = wVerticeIndex + 1; *pIndices++ = wVerticeIndex; wVerticeIndex ++; } }; // end for seg } // end for ring // Unlock vBuf->unlock(); iBuf->unlock(); // Generate face list pSphereVertex->useSharedVertices = true; // the original code was missing this line: mesh->_setBounds( AxisAlignedBox( Vector3(-SPHERE_RADIUS, -SPHERE_RADIUS, -SPHERE_RADIUS), Vector3(SPHERE_RADIUS, SPHERE_RADIUS, SPHERE_RADIUS) ), false ); mesh->_setBoundingSphereRadius(SPHERE_RADIUS); }
//--------------------------------------------------------------------- void TangentSpaceCalc::populateVertexArray(unsigned short sourceTexCoordSet) { // Just pull data out into more friendly structures VertexDeclaration *dcl = mVData->vertexDeclaration; VertexBufferBinding *bind = mVData->vertexBufferBinding; // Get the incoming UV element const VertexElement* uvElem = dcl->findElementBySemantic( VES_TEXTURE_COORDINATES, sourceTexCoordSet); if (!uvElem || uvElem->getType() != VET_FLOAT2) { OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "No 2D texture coordinates with selected index, cannot calculate tangents.", "TangentSpaceCalc::build"); } HardwareVertexBufferSharedPtr uvBuf, posBuf, normBuf; unsigned char *pUvBase, *pPosBase, *pNormBase; size_t uvInc, posInc, normInc; uvBuf = bind->getBuffer(uvElem->getSource()); pUvBase = static_cast<unsigned char*>( uvBuf->lock(HardwareBuffer::HBL_READ_ONLY)); uvInc = uvBuf->getVertexSize(); // offset for vertex start pUvBase += mVData->vertexStart * uvInc; // find position const VertexElement *posElem = dcl->findElementBySemantic(VES_POSITION); if (posElem->getSource() == uvElem->getSource()) { pPosBase = pUvBase; posInc = uvInc; } else { // A different buffer posBuf = bind->getBuffer(posElem->getSource()); pPosBase = static_cast<unsigned char*>( posBuf->lock(HardwareBuffer::HBL_READ_ONLY)); posInc = posBuf->getVertexSize(); // offset for vertex start pPosBase += mVData->vertexStart * posInc; } // find a normal buffer const VertexElement *normElem = dcl->findElementBySemantic(VES_NORMAL); if (!normElem) OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, "No vertex normals found", "TangentSpaceCalc::build"); if (normElem->getSource() == uvElem->getSource()) { pNormBase = pUvBase; normInc = uvInc; } else if (normElem->getSource() == posElem->getSource()) { // normals are in the same buffer as position // this condition arises when an animated(skeleton) mesh is not built with // an edge list buffer ie no shadows being used. pNormBase = pPosBase; normInc = posInc; } else { // A different buffer normBuf = bind->getBuffer(normElem->getSource()); pNormBase = static_cast<unsigned char*>( normBuf->lock(HardwareBuffer::HBL_READ_ONLY)); normInc = normBuf->getVertexSize(); // offset for vertex start pNormBase += mVData->vertexStart * normInc; } // Preinitialise vertex info mVertexArray.clear(); mVertexArray.resize(mVData->vertexCount); float* pFloat; VertexInfo* vInfo = &(mVertexArray[0]); for (size_t v = 0; v < mVData->vertexCount; ++v, ++vInfo) { posElem->baseVertexPointerToElement(pPosBase, &pFloat); vInfo->pos.x = *pFloat++; vInfo->pos.y = *pFloat++; vInfo->pos.z = *pFloat++; pPosBase += posInc; normElem->baseVertexPointerToElement(pNormBase, &pFloat); vInfo->norm.x = *pFloat++; vInfo->norm.y = *pFloat++; vInfo->norm.z = *pFloat++; pNormBase += normInc; uvElem->baseVertexPointerToElement(pUvBase, &pFloat); vInfo->uv.x = *pFloat++; vInfo->uv.y = *pFloat++; pUvBase += uvInc; } // unlock buffers uvBuf->unlock(); if (!posBuf.isNull()) { posBuf->unlock(); } if (!normBuf.isNull()) { normBuf->unlock(); } }
void _prepareMesh() { int i,lvl ; mesh = MeshManager::getSingleton().createManual(name, ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME) ; subMesh = mesh->createSubMesh(); subMesh->useSharedVertices=false; int numVertices = 4 ; if (first) { // first Circle, create some static common data first = false ; // static buffer for position and normals posnormVertexBuffer = HardwareBufferManager::getSingleton().createVertexBuffer( 6*sizeof(float), // size of one vertex data 4, // number of vertices HardwareBuffer::HBU_STATIC_WRITE_ONLY, // usage false); // no shadow buffer float *posnormBufData = (float*) posnormVertexBuffer-> lock(HardwareBuffer::HBL_DISCARD); for(i=0;i<numVertices;i++) { posnormBufData[6*i+0]=((Real)(i%2)-0.5f)*CIRCLE_SIZE; // pos X posnormBufData[6*i+1]=0; // pos Y posnormBufData[6*i+2]=((Real)(i/2)-0.5f)*CIRCLE_SIZE; // pos Z posnormBufData[6*i+3]=0 ; // normal X posnormBufData[6*i+4]=1 ; // normal Y posnormBufData[6*i+5]=0 ; // normal Z } posnormVertexBuffer->unlock(); // static buffers for 16 sets of texture coordinates texcoordsVertexBuffers = new HardwareVertexBufferSharedPtr[16]; for(lvl=0;lvl<16;lvl++) { texcoordsVertexBuffers[lvl] = HardwareBufferManager::getSingleton().createVertexBuffer( 2*sizeof(float), // size of one vertex data numVertices, // number of vertices HardwareBuffer::HBU_STATIC_WRITE_ONLY, // usage false); // no shadow buffer float *texcoordsBufData = (float*) texcoordsVertexBuffers[lvl]-> lock(HardwareBuffer::HBL_DISCARD); float x0 = (Real)(lvl % 4) * 0.25 ; float y0 = (Real)(lvl / 4) * 0.25 ; y0 = 0.75-y0 ; // upside down for(i=0;i<4;i++) { texcoordsBufData[i*2 + 0]= x0 + 0.25 * (Real)(i%2) ; texcoordsBufData[i*2 + 1]= y0 + 0.25 * (Real)(i/2) ; } texcoordsVertexBuffers[lvl]->unlock(); } // Index buffer for 2 faces unsigned short faces[6] = {2,1,0, 2,3,1}; indexBuffer = HardwareBufferManager::getSingleton().createIndexBuffer( HardwareIndexBuffer::IT_16BIT, 6, HardwareBuffer::HBU_STATIC_WRITE_ONLY); indexBuffer->writeData(0, indexBuffer->getSizeInBytes(), faces, true); // true? } // Initialize vertex data subMesh->vertexData = new VertexData(); subMesh->vertexData->vertexStart = 0; subMesh->vertexData->vertexCount = 4; // first, set vertex buffer bindings VertexBufferBinding *vbind = subMesh->vertexData->vertexBufferBinding ; vbind->setBinding(0, posnormVertexBuffer); vbind->setBinding(1, texcoordsVertexBuffers[0]); // now, set vertex buffer declaration VertexDeclaration *vdecl = subMesh->vertexData->vertexDeclaration ; vdecl->addElement(0, 0, VET_FLOAT3, VES_POSITION); vdecl->addElement(0, 3*sizeof(float), VET_FLOAT3, VES_NORMAL); vdecl->addElement(1, 0, VET_FLOAT2, VES_TEXTURE_COORDINATES); // Initialize index data subMesh->indexData->indexBuffer = indexBuffer; subMesh->indexData->indexStart = 0; subMesh->indexData->indexCount = 6; // set mesh bounds AxisAlignedBox circleBounds(-CIRCLE_SIZE/2.0f, 0, -CIRCLE_SIZE/2.0f, CIRCLE_SIZE/2.0f, 0, CIRCLE_SIZE/2.0f); mesh->_setBounds(circleBounds); mesh->load(); mesh->touch(); }
FlexMesh::FlexMesh( Ogre::String const & name, RoR::GfxActor* gfx_actor, int n1, int n2, int nstart, int nrays, Ogre::String const & face_material_name, Ogre::String const & band_material_name, bool rimmed, float rim_ratio ) : m_is_rimmed(rimmed) , m_num_rays(nrays) , m_gfx_actor(gfx_actor) { // Create the mesh via the MeshManager m_mesh = MeshManager::getSingleton().createManual(name, gfx_actor->GetResourceGroup()); // Create submeshes m_submesh_wheelface = m_mesh->createSubMesh(); m_submesh_tiretread = m_mesh->createSubMesh(); //materials m_submesh_wheelface->setMaterialName(face_material_name); m_submesh_tiretread->setMaterialName(band_material_name); // Define the vertices size_t vertex_count = 4*nrays+2; // each ray needs 4 verts (2 for sidewalls and 2 for band). The axis needs an extra 2. if (m_is_rimmed) // For truckfile sections "[mesh]wheels2". { vertex_count+=2*nrays; // 1 extra vertex for each sidewall. } m_vertices = new FlexMeshVertex[vertex_count]; m_vertex_nodes=(int*)malloc(vertex_count*sizeof(int)); //define node ids m_vertex_nodes[0]=n1; m_vertex_nodes[1]=n2; int i; for (i=0; i<nrays; i++) { //face m_vertex_nodes[2+i*2]=nstart+i*2; m_vertex_nodes[2+i*2+1]=nstart+i*2+1; if (m_is_rimmed) { //band m_vertex_nodes[2+2*nrays+i*2] = nstart+2*nrays+i*2; m_vertex_nodes[2+2*nrays+i*2+1] = nstart+2*nrays+i*2+1; //face2 (outer) m_vertex_nodes[2+4*nrays+i*2] = nstart+2*nrays+i*2; m_vertex_nodes[2+4*nrays+i*2+1] = nstart+2*nrays+i*2+1; } else { //band m_vertex_nodes[2+2*nrays+i*2] = nstart+i*2; m_vertex_nodes[2+2*nrays+i*2+1] = nstart+i*2+1; } } //textures coordinates m_vertices[0].texcoord=Vector2(0.5, 0.5); // Axis vertices - texcoord is middle of the wheelface texture. m_vertices[1].texcoord=Vector2(0.5, 0.5); const bool odd_num_rays = (nrays % 2 == 0); for (i=0; i<nrays; i++) { //band int band_vert = 2+2*nrays+i*2; if (i % 2 == 0) // Even index { if (odd_num_rays && ((i+1) == nrays)) { // Finalize a wheel with odd number of rays like 'bombinette.load' in 'miniredmars' map. m_vertices[band_vert].texcoord=Vector2(0.5, 0.0); // Stretch the texture over 2 quads instead of 1... ugly, but best we can do here m_vertices[band_vert+1].texcoord=Vector2(0.5, 1.0); } else { m_vertices[band_vert].texcoord=Vector2(0.0, 0.0); m_vertices[band_vert+1].texcoord=Vector2(0.0, 1.0); } } else // Odd index { m_vertices[band_vert].texcoord=Vector2(1.0, 0.0); m_vertices[band_vert+1].texcoord=Vector2(1.0, 1.0); } //face if (m_is_rimmed) { m_vertices[2+i*2].texcoord=Vector2(0.5+0.5*rim_ratio*sin((float)i*2.0*3.14159/nrays), 0.5+0.5*rim_ratio*cos((float)i*2.0*3.14159/nrays)); m_vertices[2+i*2+1].texcoord=m_vertices[2+i*2].texcoord; m_vertices[2+4*nrays+i*2].texcoord=Vector2(0.5+0.5*sin(((float)i+0.5)*2.0*3.14159/nrays), 0.5+0.5*cos(((float)i+0.5)*2.0*3.14159/nrays)); m_vertices[2+4*nrays+i*2+1].texcoord=m_vertices[2+4*nrays+i*2].texcoord; } else { m_vertices[2+i*2].texcoord=Vector2(0.5+0.5*sin(i*2.0*3.14159/nrays), 0.5+0.5*cos(i*2.0*3.14159/nrays)); m_vertices[2+i*2+1].texcoord=m_vertices[2+i*2].texcoord; } } // Define triangles // The values in this table refer to vertices in the above table size_t tiretread_num_indices = 3*2*nrays; size_t wheelface_num_indices = 3*2*nrays; if (m_is_rimmed) wheelface_num_indices=wheelface_num_indices*3; m_wheelface_indices=(unsigned short*)malloc(wheelface_num_indices*sizeof(unsigned short)); m_tiretread_indices=(unsigned short*)malloc(tiretread_num_indices*sizeof(unsigned short)); for (i=0; i<nrays; i++) { //wheel sides m_wheelface_indices[3*(i*2)]=0; m_wheelface_indices[3*(i*2)+1]=2+i*2; m_wheelface_indices[3*(i*2)+2]=2+((i+1)%nrays)*2; m_wheelface_indices[3*(i*2+1)]=1; m_wheelface_indices[3*(i*2+1)+2]=2+i*2+1; m_wheelface_indices[3*(i*2+1)+1]=2+((i+1)%nrays)*2+1; if (m_is_rimmed) { m_wheelface_indices[3*(i*4+0+2*nrays)]=2+i*2; m_wheelface_indices[3*(i*4+0+2*nrays)+1]=2+4*nrays+i*2; m_wheelface_indices[3*(i*4+0+2*nrays)+2]=2+((i+1)%nrays)*2; m_wheelface_indices[3*(i*4+1+2*nrays)]=2+4*nrays+i*2; m_wheelface_indices[3*(i*4+1+2*nrays)+1]=2+4*nrays+((i+1)%nrays)*2; m_wheelface_indices[3*(i*4+1+2*nrays)+2]=2+((i+1)%nrays)*2; m_wheelface_indices[3*(i*4+2+2*nrays)]=2+i*2+1; m_wheelface_indices[3*(i*4+2+2*nrays)+2]=2+4*nrays+i*2+1; m_wheelface_indices[3*(i*4+2+2*nrays)+1]=2+((i+1)%nrays)*2+1; m_wheelface_indices[3*(i*4+3+2*nrays)]=2+4*nrays+i*2+1; m_wheelface_indices[3*(i*4+3+2*nrays)+2]=2+4*nrays+((i+1)%nrays)*2+1; m_wheelface_indices[3*(i*4+3+2*nrays)+1]=2+((i+1)%nrays)*2+1; } //wheel band m_tiretread_indices[3*(i*2)]=2+2*nrays+i*2; m_tiretread_indices[3*(i*2)+1]=2+2*nrays+i*2+1; m_tiretread_indices[3*(i*2)+2]=2+2*nrays+((i+1)%nrays)*2; m_tiretread_indices[3*(i*2+1)]=2+2*nrays+((i+1)%nrays)*2; m_tiretread_indices[3*(i*2+1)+2]=2+2*nrays+((i+1)%nrays)*2+1; m_tiretread_indices[3*(i*2+1)+1]=2+2*nrays+i*2+1; } //update coords updateVertices(); // Create vertex data structure for 8 vertices shared between submeshes m_mesh->sharedVertexData = new VertexData(); m_mesh->sharedVertexData->vertexCount = vertex_count; // Create declaration (memory format) of vertex data m_vertex_format = m_mesh->sharedVertexData->vertexDeclaration; size_t offset = 0; m_vertex_format->addElement(0, offset, VET_FLOAT3, VES_POSITION); offset += VertexElement::getTypeSize(VET_FLOAT3); m_vertex_format->addElement(0, offset, VET_FLOAT3, VES_NORMAL); offset += VertexElement::getTypeSize(VET_FLOAT3); // m_vertex_format->addElement(0, offset, VET_FLOAT3, VES_DIFFUSE); // offset += VertexElement::getTypeSize(VET_FLOAT3); m_vertex_format->addElement(0, offset, VET_FLOAT2, VES_TEXTURE_COORDINATES, 0); offset += VertexElement::getTypeSize(VET_FLOAT2); // Allocate vertex buffer of the requested number of vertices (vertexCount) // and bytes per vertex (offset) m_hw_vbuf = HardwareBufferManager::getSingleton().createVertexBuffer( offset, m_mesh->sharedVertexData->vertexCount, HardwareBuffer::HBU_DYNAMIC_WRITE_ONLY_DISCARDABLE); // Upload the vertex data to the card m_hw_vbuf->writeData(0, m_hw_vbuf->getSizeInBytes(), m_vertices, true); // Set vertex buffer binding so buffer 0 is bound to our vertex buffer VertexBufferBinding* bind = m_mesh->sharedVertexData->vertexBufferBinding; bind->setBinding(0, m_hw_vbuf); //for the sideface // Allocate index buffer of the requested number of vertices (ibufCount) HardwareIndexBufferSharedPtr faceibuf = HardwareBufferManager::getSingleton(). createIndexBuffer( HardwareIndexBuffer::IT_16BIT, wheelface_num_indices, HardwareBuffer::HBU_STATIC_WRITE_ONLY); // Upload the index data to the card faceibuf->writeData(0, faceibuf->getSizeInBytes(), m_wheelface_indices, true); // Set parameters of the submesh m_submesh_wheelface->useSharedVertices = true; m_submesh_wheelface->indexData->indexBuffer = faceibuf; m_submesh_wheelface->indexData->indexCount = wheelface_num_indices; m_submesh_wheelface->indexData->indexStart = 0; //for the band // Allocate index buffer of the requested number of vertices (ibufCount) HardwareIndexBufferSharedPtr bandibuf = HardwareBufferManager::getSingleton(). createIndexBuffer( HardwareIndexBuffer::IT_16BIT, tiretread_num_indices, HardwareBuffer::HBU_STATIC_WRITE_ONLY); // Upload the index data to the card bandibuf->writeData(0, bandibuf->getSizeInBytes(), m_tiretread_indices, true); // Set parameters of the submesh m_submesh_tiretread->useSharedVertices = true; m_submesh_tiretread->indexData->indexBuffer = bandibuf; m_submesh_tiretread->indexData->indexCount = tiretread_num_indices; m_submesh_tiretread->indexData->indexStart = 0; // Set bounding information (for culling) m_mesh->_setBounds(AxisAlignedBox(-1,-1,0,1,1,0), true); m_mesh->load(); }
void createSphere(const std::string& strName, const float r, const int nRings = 16, const int nSegments = 16) { MeshPtr pSphere = MeshManager::getSingleton().createManual(strName, ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); SubMesh *pSphereVertex = pSphere->createSubMesh(); pSphere->sharedVertexData = new VertexData(); VertexData* vertexData = pSphere->sharedVertexData; // define the vertex format VertexDeclaration* vertexDecl = vertexData->vertexDeclaration; size_t currOffset = 0; // positions vertexDecl->addElement(0, currOffset, VET_FLOAT3, VES_POSITION); currOffset += VertexElement::getTypeSize(VET_FLOAT3); // normals vertexDecl->addElement(0, currOffset, VET_FLOAT3, VES_NORMAL); currOffset += VertexElement::getTypeSize(VET_FLOAT3); // two dimensional texture coordinates vertexDecl->addElement(0, currOffset, VET_FLOAT2, VES_TEXTURE_COORDINATES, 0); currOffset += VertexElement::getTypeSize(VET_FLOAT2); // allocate the vertex buffer vertexData->vertexCount = (nRings + 1) * (nSegments + 1); HardwareVertexBufferSharedPtr vBuf = HardwareBufferManager::getSingleton().createVertexBuffer(vertexDecl->getVertexSize(0), vertexData->vertexCount, HardwareBuffer::HBU_STATIC_WRITE_ONLY, false); VertexBufferBinding* binding = vertexData->vertexBufferBinding; binding->setBinding(0, vBuf); float* pVertex = static_cast<float*>(vBuf->lock(HardwareBuffer::HBL_DISCARD)); // allocate index buffer pSphereVertex->indexData->indexCount = 6 * nRings * (nSegments + 1); pSphereVertex->indexData->indexBuffer = HardwareBufferManager::getSingleton().createIndexBuffer(HardwareIndexBuffer::IT_16BIT, pSphereVertex->indexData->indexCount, HardwareBuffer::HBU_STATIC_WRITE_ONLY, false); HardwareIndexBufferSharedPtr iBuf = pSphereVertex->indexData->indexBuffer; unsigned short* pIndices = static_cast<unsigned short*>(iBuf->lock(HardwareBuffer::HBL_DISCARD)); float fDeltaRingAngle = (Math::PI / nRings); float fDeltaSegAngle = (2 * Math::PI / nSegments); unsigned short wVerticeIndex = 0; // Generate the group of rings for the sphere for (int ring = 0; ring <= nRings; ring++) { float r0 = r * sinf(ring * fDeltaRingAngle); float y0 = r * cosf(ring * fDeltaRingAngle); // Generate the group of segments for the current ring for (int seg = 0; seg <= nSegments; seg++) { float x0 = r0 * sinf(seg * fDeltaSegAngle); float z0 = r0 * cosf(seg * fDeltaSegAngle); // Add one vertex to the strip which makes up the sphere *pVertex++ = x0; *pVertex++ = y0; *pVertex++ = z0; Vector3 vNormal = Vector3(x0, y0, z0).normalisedCopy(); *pVertex++ = vNormal.x; *pVertex++ = vNormal.y; *pVertex++ = vNormal.z; *pVertex++ = (float)seg / (float)nSegments; *pVertex++ = (float)ring / (float)nRings; if (ring != nRings) { // each vertex (except the last) has six indices pointing to it *pIndices++ = wVerticeIndex + nSegments + 1; *pIndices++ = wVerticeIndex; *pIndices++ = wVerticeIndex + nSegments; *pIndices++ = wVerticeIndex + nSegments + 1; *pIndices++ = wVerticeIndex + 1; *pIndices++ = wVerticeIndex; wVerticeIndex++; } }; // end for seg } // end for ring // Unlock vBuf->unlock(); iBuf->unlock(); // Generate face list pSphereVertex->useSharedVertices = true; // the original code was missing this line: pSphere->_setBounds(AxisAlignedBox(Vector3(-r, -r, -r), Vector3(r, r, r)), false); pSphere->_setBoundingSphereRadius(r); // this line makes clear the mesh is loaded (avoids memory leaks) pSphere->load(); }
//--------------------------------------------------------------------- void TangentSpaceCalc::insertTangents(Result& res, VertexElementSemantic targetSemantic, unsigned short sourceTexCoordSet, unsigned short index) { // Make a new tangents semantic or find an existing one VertexDeclaration *vDecl = mVData->vertexDeclaration ; VertexBufferBinding *vBind = mVData->vertexBufferBinding ; const VertexElement *tangentsElem = vDecl->findElementBySemantic(targetSemantic, index); bool needsToBeCreated = false; VertexElementType tangentsType = mStoreParityInW ? VET_FLOAT4 : VET_FLOAT3; if (!tangentsElem) { // no tex coords with index 1 needsToBeCreated = true ; } else if (tangentsElem->getType() != tangentsType) { // buffer exists, but not 3D OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "Target semantic set already exists but is not of the right size, therefore " "cannot contain tangents. You should delete this existing entry first. ", "TangentSpaceCalc::insertTangents"); } HardwareVertexBufferSharedPtr targetBuffer, origBuffer; unsigned char* pSrc = NULL; 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 = mVData->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 origBuffer = mVData->vertexBufferBinding->getBuffer( prevTexCoordElem->getSource()); // Now create a new buffer, which includes the previous contents // plus extra space for the 3D coords targetBuffer = HardwareBufferManager::getSingleton().createVertexBuffer( origBuffer->getVertexSize() + VertexElement::getTypeSize(tangentsType), origBuffer->getNumVertices(), origBuffer->getUsage(), origBuffer->hasShadowBuffer() ); // Add the new element tangentsElem = &(vDecl->addElement( prevTexCoordElem->getSource(), origBuffer->getVertexSize(), tangentsType, targetSemantic, index)); // Set up the source pointer pSrc = static_cast<unsigned char*>( origBuffer->lock(HardwareBuffer::HBL_READ_ONLY)); // Rebind the new buffer vBind->setBinding(prevTexCoordElem->getSource(), targetBuffer); } else { // space already there origBuffer = mVData->vertexBufferBinding->getBuffer( tangentsElem->getSource()); targetBuffer = origBuffer; } unsigned char* pDest = static_cast<unsigned char*>( targetBuffer->lock(HardwareBuffer::HBL_DISCARD)); size_t origVertSize = origBuffer->getVertexSize(); size_t newVertSize = targetBuffer->getVertexSize(); for (size_t v = 0; v < origBuffer->getNumVertices(); ++v) { if (needsToBeCreated) { // Copy original vertex data as well memcpy(pDest, pSrc, origVertSize); pSrc += origVertSize; } // Write in the tangent float* pTangent; tangentsElem->baseVertexPointerToElement(pDest, &pTangent); VertexInfo& vertInfo = mVertexArray[v]; *pTangent++ = vertInfo.tangent.x; *pTangent++ = vertInfo.tangent.y; *pTangent++ = vertInfo.tangent.z; if (mStoreParityInW) *pTangent++ = (float)vertInfo.parity; // Next target vertex pDest += newVertSize; } targetBuffer->unlock(); if (needsToBeCreated) { origBuffer->unlock(); } }
FlexMeshWheel::FlexMeshWheel( Ogre::String const & name, node_t *nds, int axis_node_1_index, int axis_node_2_index, int nstart, int nrays, Ogre::String const & mesh_name, Ogre::String const & material_name,//char* texband, float rimradius, bool rimreverse, MaterialFunctionMapper *material_function_mapper, // *mfm Skin *used_skin, // *usedSkin, MaterialReplacer *material_replacer // *mr ) : id0(axis_node_1_index) , id1(axis_node_2_index) , idstart(nstart) , mr(material_replacer) , nbrays(nrays) , nodes(nds) , revrim(rimreverse) , rim_radius(rimradius) { //the rim object std::stringstream rim_name; rim_name << "rim-" << name; rimEnt = gEnv->sceneManager->createEntity(rim_name.str(), mesh_name); MaterialFunctionMapper::replaceSimpleMeshMaterials(rimEnt, ColourValue(0, 0.5, 0.8)); if (material_function_mapper != nullptr) { material_function_mapper->replaceMeshMaterials(rimEnt); } if (material_replacer != nullptr) { material_replacer->replaceMeshMaterials(rimEnt); } if (used_skin != nullptr) { used_skin->replaceMeshMaterials(rimEnt); } rnode=gEnv->sceneManager->getRootSceneNode()->createChildSceneNode(); rnode->attachObject(rimEnt); /// Create the mesh via the MeshManager msh = MeshManager::getSingleton().createManual(name, ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME,new ResourceBuffer()); /// Create submeshes sub = msh->createSubMesh(); //materials sub->setMaterialName(material_name); /// Define the vertices nVertices = 6*(nrays+1); vbufCount = (2*3+2)*nVertices; vertices=(float*)malloc(vbufCount*sizeof(float)); //shadow shadownorvertices=(float*)malloc(nVertices*(3+2)*sizeof(float)); shadowposvertices=(float*)malloc(nVertices*3*2*sizeof(float)); int i; //textures coordinates for (i=0; i<nrays+1; i++) { covertices[i*6 ].texcoord=Vector2((float)i/(float)nrays, 0.00f); covertices[i*6+1 ].texcoord=Vector2((float)i/(float)nrays, 0.23f); covertices[i*6+2 ].texcoord=Vector2((float)i/(float)nrays, 0.27f); covertices[i*6+3 ].texcoord=Vector2((float)i/(float)nrays, 0.73f); covertices[i*6+4 ].texcoord=Vector2((float)i/(float)nrays, 0.77f); covertices[i*6+5 ].texcoord=Vector2((float)i/(float)nrays, 1.00f); } /// Define triangles /// The values in this table refer to vertices in the above table ibufCount = 3*10*nrays; faces=(unsigned short*)malloc(ibufCount*sizeof(unsigned short)); for (i=0; i<nrays; i++) { faces[3*(i*10 )]=i*6; faces[3*(i*10 )+1]=i*6+1; faces[3*(i*10 )+2]=(i+1)*6; faces[3*(i*10+1)]=i*6+1; faces[3*(i*10+1)+1]=(i+1)*6+1; faces[3*(i*10+1)+2]=(i+1)*6; faces[3*(i*10+2)]=i*6+1; faces[3*(i*10+2)+1]=i*6+2; faces[3*(i*10+2)+2]=(i+1)*6+1; faces[3*(i*10+3)]=i*6+2; faces[3*(i*10+3)+1]=(i+1)*6+2; faces[3*(i*10+3)+2]=(i+1)*6+1; faces[3*(i*10+4)]=i*6+2; faces[3*(i*10+4)+1]=i*6+3; faces[3*(i*10+4)+2]=(i+1)*6+2; faces[3*(i*10+5)]=i*6+3; faces[3*(i*10+5)+1]=(i+1)*6+3; faces[3*(i*10+5)+2]=(i+1)*6+2; faces[3*(i*10+6)]=i*6+3; faces[3*(i*10+6)+1]=i*6+4; faces[3*(i*10+6)+2]=(i+1)*6+3; faces[3*(i*10+7)]=i*6+4; faces[3*(i*10+7)+1]=(i+1)*6+4; faces[3*(i*10+7)+2]=(i+1)*6+3; faces[3*(i*10+8)]=i*6+4; faces[3*(i*10+8)+1]=i*6+5; faces[3*(i*10+8)+2]=(i+1)*6+4; faces[3*(i*10+9)]=i*6+5; faces[3*(i*10+9)+1]=(i+1)*6+5; faces[3*(i*10+9)+2]=(i+1)*6+4; } normy=1.0; //update coords updateVertices(); //compute normy; normy=((covertices[0].vertex-covertices[1].vertex).crossProduct(covertices[1].vertex-covertices[6+1].vertex)).length(); //recompute for normals updateVertices(); /// Create vertex data structure for 8 vertices shared between submeshes msh->sharedVertexData = new VertexData(); msh->sharedVertexData->vertexCount = nVertices; /// Create declaration (memory format) of vertex data decl = msh->sharedVertexData->vertexDeclaration; size_t offset = 0; decl->addElement(0, offset, VET_FLOAT3, VES_POSITION); offset += VertexElement::getTypeSize(VET_FLOAT3); decl->addElement(0, offset, VET_FLOAT3, VES_NORMAL); offset += VertexElement::getTypeSize(VET_FLOAT3); // decl->addElement(0, offset, VET_FLOAT3, VES_DIFFUSE); // offset += VertexElement::getTypeSize(VET_FLOAT3); decl->addElement(0, offset, VET_FLOAT2, VES_TEXTURE_COORDINATES, 0); offset += VertexElement::getTypeSize(VET_FLOAT2); /// Allocate vertex buffer of the requested number of vertices (vertexCount) /// and bytes per vertex (offset) vbuf = HardwareBufferManager::getSingleton().createVertexBuffer( offset, msh->sharedVertexData->vertexCount, HardwareBuffer::HBU_DYNAMIC_WRITE_ONLY_DISCARDABLE); /// Upload the vertex data to the card vbuf->writeData(0, vbuf->getSizeInBytes(), vertices, true); /// Set vertex buffer binding so buffer 0 is bound to our vertex buffer VertexBufferBinding* bind = msh->sharedVertexData->vertexBufferBinding; bind->setBinding(0, vbuf); //for the face /// Allocate index buffer of the requested number of vertices (ibufCount) HardwareIndexBufferSharedPtr ibuf = HardwareBufferManager::getSingleton(). createIndexBuffer( HardwareIndexBuffer::IT_16BIT, ibufCount, HardwareBuffer::HBU_STATIC_WRITE_ONLY); /// Upload the index data to the card ibuf->writeData(0, ibuf->getSizeInBytes(), faces, true); /// Set parameters of the submesh sub->useSharedVertices = true; sub->indexData->indexBuffer = ibuf; sub->indexData->indexCount = ibufCount; sub->indexData->indexStart = 0; /// Set bounding information (for culling) msh->_setBounds(AxisAlignedBox(-1,-1,0,1,1,0), true); //msh->_setBoundingSphereRadius(Math::Sqrt(1*1+1*1)); /// Notify Mesh object that it has been loaded //msh->buildTangentVectors(); /*unsigned short src, dest; if (!msh->suggestTangentVectorBuildParams(src, dest)) { msh->buildTangentVectors(src, dest); } */ msh->load(); //msh->touch(); // msh->load(); //msh->buildEdgeList(); }
void ThingRenderable::initialise() { // Fill array with randomly oriented quads Vector3 ax, ay, az; Quaternion q; things.clear(); orbits.clear(); for(size_t x=0; x<mCount; x++) { ax = Vector3(Math::SymmetricRandom(), Math::SymmetricRandom(), Math::SymmetricRandom()); ay = Vector3(Math::SymmetricRandom(), Math::SymmetricRandom(), Math::SymmetricRandom()); az = ax.crossProduct(ay); ay = az.crossProduct(ax); ax.normalise(); ay.normalise(); az.normalise(); q.FromAxes(ax, ay, az); //std::cerr << ax.dotProduct(ay) << " " << ay.dotProduct(az) << " " << az.dotProduct(ax) << std::endl; things.push_back(q); ax = Vector3(Math::SymmetricRandom(), Math::SymmetricRandom(), Math::SymmetricRandom()); ay = Vector3(Math::SymmetricRandom(), Math::SymmetricRandom(), Math::SymmetricRandom()); az = ax.crossProduct(ay); ay = az.crossProduct(ax); ax.normalise(); ay.normalise(); az.normalise(); q.FromAxes(ax, ay, az); orbits.push_back(q); } // Create buffers size_t nvertices = mCount*4; // n+1 planes //size_t elemsize = 2*3; // position, normal //size_t dsize = elemsize*nvertices; Ogre::IndexData *idata = new Ogre::IndexData(); Ogre::VertexData *vdata = new Ogre::VertexData(); // Quads unsigned short *faces = new unsigned short[mCount*6]; for(uint16 x=0; x<uint16(mCount); x++) { faces[x*6+0] = x*4+0; faces[x*6+1] = x*4+1; faces[x*6+2] = x*4+2; faces[x*6+3] = x*4+0; faces[x*6+4] = x*4+2; faces[x*6+5] = x*4+3; } // Setup buffers vdata->vertexStart = 0; vdata->vertexCount = nvertices; VertexDeclaration* decl = vdata->vertexDeclaration; VertexBufferBinding* bind = vdata->vertexBufferBinding; size_t offset = 0; decl->addElement(0, offset, VET_FLOAT3, VES_POSITION); offset += VertexElement::getTypeSize(VET_FLOAT3); vbuf = HardwareBufferManager::getSingleton().createVertexBuffer( offset, nvertices, HardwareBuffer::HBU_DYNAMIC_WRITE_ONLY); bind->setBinding(0, vbuf); //vbuf->writeData(0, vbuf->getSizeInBytes(), vertices, true); HardwareIndexBufferSharedPtr ibuf = HardwareBufferManager::getSingleton(). createIndexBuffer( HardwareIndexBuffer::IT_16BIT, mCount*6, HardwareBuffer::HBU_STATIC_WRITE_ONLY); idata->indexBuffer = ibuf; idata->indexCount = mCount*6; idata->indexStart = 0; ibuf->writeData(0, ibuf->getSizeInBytes(), faces, true); // Delete temporary buffers delete [] faces; // Now make the render operation mRenderOp.operationType = Ogre::RenderOperation::OT_TRIANGLE_LIST; mRenderOp.indexData = idata; mRenderOp.vertexData = vdata; mRenderOp.useIndexes = true; }
//--------------------------------------------------------------------- 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; } } } } }