Which member variable can view the Vertex data of Submesh

Problems building or running the engine, queries about how to use features etc.
Post Reply
alexwang
Gnoblar
Posts: 21
Joined: Thu Nov 04, 2021 10:17 am

Which member variable can view the Vertex data of Submesh

Post by alexwang »

Ogre Version: :1.12.12:
Operating System: :linux, ubunutu:
Render System: :GL:

I'm tring to change vertexData in the rendering loop. The original mesh is a rectangle which include 4 point (position, normal,texcoord). In the rendering loop, I debuging the Submesh, I wanna get the data in the variable.

Code: Select all

SubMesh* tmpSubMesh = mesh->getSubMesh(0);
tmpSubMesh->vertexData->vertexCount = 3;	//change rectangle to triangle
VertexBufferBinding* tmpVertexBufferBinding = tmpSubMesh ->vertexData->vertexBufferBinding;
//vertexBuffer
HardwareVertexbufferSharedPtr tmpVertexBuffer = tmpVertexBufferBingding->getBindings().begin()->second;
tmpVertexBuffer->writeData(....);
//indexBuffer
HardwareIndexBufferSharedPtr tmpIndexBuffer = tmpSubMesh->indexData->indexBuffer;
tmpIndexBuffer ->writeData(.....);
the result didn't show the new triangle. It seems only update indexBuffer (half of the rectangle). I wanna monitor tmpSubMesh->vertexData to confirm wheather triangle data has updated. But huge data structures dissuade me. I wanna know which struct include new vertex data.
Bady
Halfling
Posts: 52
Joined: Sun Mar 16, 2014 1:47 am
x 3

Re: Which member variable can view the Vertex data of Submesh

Post by Bady »

For raycast reasons I use this algorithm to retrieve the submesh vertex data(and literally anything else) maybe this will help you:

Code: Select all

void GetMeshInformation(const Ogre::Entity* entity, size_t& vertex_count, Ogre::Vector3*& vertices, vector<Ogre::Vector2>& uvs,
	size_t& index_count, unsigned long*& indices, const Ogre::Vector3& position, const Ogre::Quaternion& orient, const Ogre::Vector3& scale)
{
	bool added_shared = false;
	size_t current_offset = 0;
	size_t shared_offset = 0;
	size_t next_offset = 0;
	size_t index_offset = 0;
	vertex_count = index_count = 0;

	Ogre::MeshPtr mesh = entity->getMesh();


	bool useSoftwareBlendingVertices = entity->hasSkeleton();

	if (useSoftwareBlendingVertices)
		const_cast<Ogre::Entity*>(entity)->_updateAnimation();

	// Calculate how many vertices and indices we're going to need
	for (unsigned short i = 0, size = mesh->getNumSubMeshes(); i < size; ++i)
	{
		Ogre::SubMesh* submesh = mesh->getSubMesh(i);

		// We only need to add the shared vertices once
		if (submesh->useSharedVertices)
		{
			if (!added_shared) {
				vertex_count += mesh->sharedVertexData->vertexCount;
				added_shared = true;
			}
		}
		else
		{
			vertex_count += submesh->vertexData->vertexCount;
		}

		// Add the indices
		index_count += submesh->indexData->indexCount;
	}


	// Allocate space for the vertices and indices
	
	vertices = new Ogre::Vector3[vertex_count];
	indices = new unsigned long[index_count];

	added_shared = false;

	// Run through the submeshes again, adding the data into the arrays
	for (unsigned short i = 0, size = mesh->getNumSubMeshes(); i < size; ++i)
	{
		Ogre::SubMesh* submesh = mesh->getSubMesh(i);





		//----------------------------------------------------------------
		// GET VERTEXDATA
		//----------------------------------------------------------------

		//Ogre::VertexData* vertex_data = submesh->useSharedVertices ? mesh->sharedVertexData : submesh->vertexData;
		Ogre::VertexData* vertex_data;

		//When there is animation:
		if (useSoftwareBlendingVertices)
			vertex_data = submesh->useSharedVertices ? entity->_getSkelAnimVertexData() : entity->getSubEntity(i)->_getSkelAnimVertexData();
		else
			vertex_data = submesh->useSharedVertices ? mesh->sharedVertexData : submesh->vertexData;


		if ((!submesh->useSharedVertices) || (submesh->useSharedVertices && !added_shared))
		{
			if (submesh->useSharedVertices) {
				added_shared = true;
				shared_offset = current_offset;
			}

			const Ogre::VertexElement* posElem = vertex_data->vertexDeclaration->findElementBySemantic(Ogre::VES_POSITION);

			Ogre::HardwareVertexBufferSharedPtr vbuf = vertex_data->vertexBufferBinding->getBuffer(posElem->getSource());

			unsigned char* vertex = static_cast<unsigned char*>(vbuf->lock(Ogre::HardwareBuffer::HBL_READ_ONLY));

			// There is _no_ baseVertexPointerToElement() which takes an Ogre::Real or a double
			//  as second argument. So make it float, to avoid trouble when Ogre::Real will
			//  be comiled/typedefed as double:
			//      Ogre::Real* pReal;
			float* pReal = 0;
			//int vbusfsize=vbuf->getVertexSize();
			for (size_t j = 0; j < vertex_data->vertexCount; ++j, vertex += vbuf->getVertexSize())
			{
				posElem->baseVertexPointerToElement(vertex, &pReal);
				Ogre::Vector3 pt(pReal[0], pReal[1], pReal[2]);
				vertices[current_offset + j] = (orient * (pt * scale)) + position;

				Ogre::Vector2 ptuv(pReal[6], pReal[7]);
				uvs.push_back(ptuv);
			}

			vbuf->unlock();
			next_offset += vertex_data->vertexCount;
		}


		Ogre::IndexData* index_data = submesh->indexData;
		size_t numTris = index_data->indexCount / 3;
		Ogre::HardwareIndexBufferSharedPtr ibuf = index_data->indexBuffer;

		bool use32bitindexes = (ibuf->getType() == Ogre::HardwareIndexBuffer::IT_32BIT);

		unsigned long*  pLong = static_cast<unsigned long*>(ibuf->lock(Ogre::HardwareBuffer::HBL_READ_ONLY));
		unsigned short* pShort = reinterpret_cast<unsigned short*>(pLong);


		size_t offset = (submesh->useSharedVertices) ? shared_offset : current_offset;
		size_t index_start = index_data->indexStart;
		size_t last_index = numTris * 3 + index_start;

		if (use32bitindexes) {
			for (size_t k = index_start; k < last_index; ++k)
				indices[index_offset++] = pLong[k] + static_cast<unsigned long>(offset);
		}
		else {
			for (size_t k = index_start; k < last_index; ++k)
				indices[index_offset++] =
				static_cast<unsigned long>(pShort[k]) +
				static_cast<unsigned long>(offset);
		}

		ibuf->unlock();
		current_offset = next_offset;
	}
}
The last sceneblender
alexwang
Gnoblar
Posts: 21
Joined: Thu Nov 04, 2021 10:17 am

Re: Which member variable can view the Vertex data of Submesh

Post by alexwang »

In my project, the indexbuffer (HardwareIndexBufferSharedPtr) updated successfully, but VertexBuffer didn't show as expected.

Code: Select all

tmpVertexBuffer->writeData(0, tmpVertexBuffer->getSizeInBytes(), &vertices[0], true);
tmpIndexBuffer->writeData(0, tmpIndexBuffer->getSizeInBytes(), &faces[0], true);
vertices and faces are 'vector' objects.
rpgplayerrobin
Gnoll
Posts: 619
Joined: Wed Mar 18, 2009 3:03 am
x 353

Re: Which member variable can view the Vertex data of Submesh

Post by rpgplayerrobin »

There is not much we can do without a complete code that reproduces the problem you are facing. Otherwise everyone here can just guess what the problem is.
So either you give us a complete code that shows the issue, or check my other solution below.

Isn't this kind of the same post as viewtopic.php?f=2&t=96531?

If you see my answer there, you will be able to understand exactly how to alter the data of a custom mesh, with the same kind of system that you have.
Just basically study the code. Since your code is not working, you can try the class in your project to see how it works, then you can alter your own code after you see what is wrong with your code compared to mine.

With simple functions that also existed in Ogre::ManualObject it is extremely simple to change the object in my code.
alexwang
Gnoblar
Posts: 21
Joined: Thu Nov 04, 2021 10:17 am

Re: Which member variable can view the Vertex data of Submesh

Post by alexwang »

thank you for your answer, my solution is based on your CManual_Object class, maybe there is something important i missed, I'll check it out. :wink: :wink:
Post Reply