void processIndexData(IndexData* indexData) { if (!mFlipVertexWinding) { // Nothing to do. return; } if (indexData->indexCount % 3 != 0) { printf("Index number is not a multiple of 3, no vertex winding flipping possible. Skipped."); return; } //print("Flipping index order for vertex winding flipping.", V_HIGH); Ogre::HardwareIndexBufferSharedPtr buffer = indexData->indexBuffer; unsigned char* data = static_cast<unsigned char*>(buffer->lock(Ogre::HardwareBuffer::HBL_READ_ONLY)); if(buffer->getType() == Ogre::HardwareIndexBuffer::IT_16BIT) { // 16 bit //print("using 16bit indices", V_HIGH); for (size_t i = 0; i < indexData->indexCount; i+=3) { Ogre::uint16 * i0 = (Ogre::uint16*)(data+0 * buffer->getIndexSize()); Ogre::uint16* i2 = (Ogre::uint16*)(data+2 * buffer->getIndexSize()); // flip Ogre::uint16 tmp = *i0; *i0 = *i2; *i2 = tmp; data += 3 * buffer->getIndexSize(); } } else { // 32 bit //print("using 32bit indices", V_HIGH); for (size_t i = 0; i < indexData->indexCount; i+=3) { Ogre::uint32* i0 = (Ogre::uint32*)(data+0 * buffer->getIndexSize()); Ogre::uint32* i2 = (Ogre::uint32*)(data+2 * buffer->getIndexSize()); // flip Ogre::uint32 tmp = *i0; *i0 = *i2; *i2 = tmp; data += 3 * buffer->getIndexSize(); } } buffer->unlock(); }
void ChunkBase::generateMesh() { if (!mIsModified) return; generateVertices(); if (isEmpty) { return; } uint32_t numVertices, numIndices; if (mNumVertices > DefaultFaces * 4) { // more vertices than the default buffer can hold -> allocate new one; if (mVertexBufferCreated) { removeMesh(); } numVertices = mNumVertices; numIndices = mNumIndices; } else { numVertices = DefaultFaces * 4; numIndices = DefaultFaces * 6; } if (!mVertexBufferCreated) { mMeshPtr = Ogre::MeshManager::getSingleton().createManual(mChunkName, "Game"); Ogre::SubMesh* sub = mMeshPtr->createSubMesh(); /// Create vertex data structure for 8 vertices shared between submeshes mMeshPtr->sharedVertexData = new Ogre::VertexData(); mMeshPtr->sharedVertexData->vertexCount = mNumVertices; /// Create declaration (memory format) of vertex data Ogre::VertexDeclaration* decl = mMeshPtr->sharedVertexData->vertexDeclaration; size_t offset = 0; // 1st buffer decl->addElement(0, offset, Ogre::VET_FLOAT3, Ogre::VES_POSITION); offset += Ogre::VertexElement::getTypeSize(Ogre::VET_FLOAT3); decl->addElement(0, offset, Ogre::VET_FLOAT3, Ogre::VES_NORMAL); offset += Ogre::VertexElement::getTypeSize(Ogre::VET_FLOAT3); decl->addElement(0, offset, Ogre::VET_FLOAT2, Ogre::VES_TEXTURE_COORDINATES); offset += Ogre::VertexElement::getTypeSize(Ogre::VET_FLOAT2); /// Allocate vertex buffer of the requested number of vertices (vertexCount) and bytes per vertex (offset) Ogre::HardwareVertexBufferSharedPtr vbuf = Ogre::HardwareBufferManager::getSingleton(). createVertexBuffer(offset, numVertices, Ogre::HardwareBuffer::HBU_DYNAMIC_WRITE_ONLY_DISCARDABLE); /// Upload the vertex data to the card vbuf->writeData(0, (decl->getVertexSize(0) * mNumVertices), mVertices, true); /// Set vertex buffer binding so buffer 0 is bound to our vertex buffer Ogre::VertexBufferBinding* bind = mMeshPtr->sharedVertexData->vertexBufferBinding; bind->setBinding(0, vbuf); /// Allocate index buffer of the requested number of vertices (ibufCount) Ogre::HardwareIndexBufferSharedPtr ibuf = Ogre::HardwareBufferManager::getSingleton(). createIndexBuffer(Ogre::HardwareIndexBuffer::IT_16BIT, numIndices, Ogre::HardwareBuffer::HBU_DYNAMIC_WRITE_ONLY_DISCARDABLE); /// Upload the index data to the card ibuf->writeData(0, (ibuf->getIndexSize() * mNumIndices), mIndices, true); /// Set parameters of the submesh sub->indexData->indexBuffer = ibuf; sub->indexData->indexCount = mNumIndices; /// Set bounding information (for culling) mMeshPtr->_setBounds(Ogre::AxisAlignedBox(0, 0, 0, Ogre::Real(ChunkSizeX), Ogre::Real(mHighestCube), Ogre::Real(ChunkSizeZ))); mMeshPtr->_setBoundingSphereRadius((Ogre::Real) std::sqrt((float) (2 * 16 * 16 + 128 * 128))); /// Notify -Mesh object that it has been loaded mMeshPtr->load(); mVertexBufferCreated = true; } else { Ogre::VertexDeclaration* decl = mMeshPtr->sharedVertexData->vertexDeclaration; mMeshPtr->sharedVertexData->vertexCount = mNumVertices; Ogre::SubMesh* sub = mMeshPtr->getSubMesh(0); sub->indexData->indexCount = mNumIndices; /// Upload the new vertex data to the card Ogre::HardwareVertexBufferSharedPtr vbuf = mMeshPtr->sharedVertexData->vertexBufferBinding->getBuffer(0); vbuf->writeData(0, (decl->getVertexSize(0) * mNumVertices), mVertices, true); /// Upload the index data to the card Ogre::HardwareIndexBufferSharedPtr ibuf = sub->indexData->indexBuffer; ibuf->writeData(0, (ibuf->getIndexSize() * mNumIndices), mIndices, true); mMeshPtr->_setBounds(Ogre::AxisAlignedBox(0, 0, 0, Ogre::Real(ChunkSizeX), Ogre::Real(mHighestCube), Ogre::Real(ChunkSizeZ))); mMeshPtr->load(); } }