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();
}
Example #2
0
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();
	}
}