Multiple hardware buffers

Problems building or running the engine, queries about how to use features etc.
Post Reply
User avatar
sjcomp
Gnome
Posts: 315
Joined: Sat Apr 23, 2005 2:35 pm
Location: Dover, NH
Contact:

Multiple hardware buffers

Post by sjcomp »

I am trying to use separate hardware buffers for my mesh and I have a problem with the second buffer containing uv coordinates. I used forum threads: http://www.ogre3d.org/phpBB2/viewtopic.php?t=2893 and
http://www.ogre3d.org/phpBB2/viewtopic.php?t=4371
as my starting point.
The problem is that texture is not displayed correctly. The texture is multiplied multiple times accross the triangle, while it should be stretched. Any suggestions about what I am doing wrong? Thanks a lot.
The code is as follows:

Code: Select all

		Ogre::MeshPtr mesh = Ogre::MeshManager::getSingleton().createManual("Mesh",Ogre::ResourceGroupManager::getSingleton().getWorldResourceGroupName());
		Ogre::SubMesh * sub = mesh->createSubMesh();
		sub->operationType = Ogre::RenderOperation::OT_TRIANGLE_LIST;
		sub->useSharedVertices = false;

		const unsigned int num_verts = 3;
		const unsigned int size_vert = 6;
		const unsigned int uv_size_vert = 2;
		const unsigned int total_verts_size = num_verts * size_vert;
		const unsigned int uv_total_verts_size = num_verts * uv_size_vert;

		Ogre::Real verts[total_verts_size] =
		{
			-100.0, -100.0, 0.0,  0.0, 0.0, 1.0,
			100.0, -100.0, 0.0,  0.0, 0.0, 1.0,
			0.0, 100.0, 0.0,  0.0, 0.0, 1.0,
		};
		Ogre::Real uv_verts[uv_total_verts_size] =
		{
			0.0, 0.0,
			1.0, 0.0,
			0.0, 1.0
		};
	    bool vertexShadowBuffer = true;
		Ogre::HardwareVertexBufferSharedPtr vbuf;
		vbuf = Ogre::HardwareBufferManager::getSingleton().createVertexBuffer
			(size_vert*sizeof(Ogre::Real),
			num_verts,
			Ogre::HardwareBuffer::HBU_STATIC_WRITE_ONLY,vertexShadowBuffer);

		Ogre::HardwareVertexBufferSharedPtr uv_vbuf = 
			Ogre::HardwareBufferManager::getSingleton().createVertexBuffer
				(uv_size_vert*sizeof(Ogre::Real),
				num_verts,
				Ogre::HardwareBuffer::HBU_STATIC_WRITE_ONLY,
				vertexShadowBuffer);

		Ogre::HardwareBuffer::Usage indexBufferUsage = Ogre::HardwareBuffer::HBU_STATIC_WRITE_ONLY;
	    
		Ogre::HardwareIndexBufferSharedPtr ibuf;
	    
		sub->indexData->indexCount = num_verts;
		sub->indexData->indexStart = 0;
		sub->indexData->indexBuffer = Ogre::HardwareBufferManager::getSingleton().
			createIndexBuffer(Ogre::HardwareIndexBuffer::IT_32BIT,
				sub->indexData->indexCount, indexBufferUsage);
		ibuf = sub->indexData->indexBuffer;
	    
		Ogre::Real *pReal = (Ogre::Real*) vbuf->lock(Ogre::HardwareBuffer::HBL_DISCARD);
		unsigned int* pIndexes = static_cast<unsigned int*>	(ibuf->lock(Ogre::HardwareBuffer::HBL_DISCARD) );

		for (int i = 0; i < total_verts_size; ++i)
		{
			*pReal++ = verts[i];
		}

		pReal = (Ogre::Real*)uv_vbuf->lock(Ogre::HardwareBuffer::HBL_DISCARD);
		// writing to a vbuf from uv_verts array
		for (int i = 0; i < uv_total_verts_size ; ++i)
		{
			*pReal++ = uv_verts[i];
		}

		*pIndexes++ = 0;
		*pIndexes++ = 1;
		*pIndexes++ = 2;

		ibuf->unlock();
		vbuf->unlock();
		uv_vbuf->unlock();

		sub->vertexData = new Ogre::VertexData();
		sub->vertexData->vertexStart = 0;
		sub->vertexData->vertexCount = num_verts;

		Ogre::VertexBufferBinding* bind = sub->vertexData->vertexBufferBinding;
		bind->setBinding(0, vbuf);
		bind->setBinding(1, vbuf);
	    
		size_t offset = 0;
		Ogre::VertexDeclaration* decl = sub->vertexData->vertexDeclaration;
		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);
		decl->addElement(1, 0, Ogre::VET_FLOAT2, Ogre::VES_TEXTURE_COORDINATES, 0);

		mesh->_setBounds(Ogre::AxisAlignedBox(-100.0, -100.0, -100.0, 100.0, 100.0, 100.0)); 
		mesh->load();
		return mesh;

Regards, Alexander. http://sjcomp.com
genva
OGRE Retired Team Member
OGRE Retired Team Member
Posts: 1603
Joined: Wed Oct 20, 2004 7:54 am
Location: Beijing, China
x 1

Re: Multiple hardware buffers

Post by genva »

sjcomp wrote:

Code: Select all

		bind->setBinding(0, vbuf);
		bind->setBinding(1, vbuf);
Should be

Code: Select all

		bind->setBinding(0, vbuf);
		bind->setBinding(1, uv_vbuf);
Another suggestion: Hardware vertext buffer floating-point value type is float, not Real. Just avoid potential issue when compile Ogre in double-precision mode, in this case Real is typedef'ed to double.
User avatar
sjcomp
Gnome
Posts: 315
Joined: Sat Apr 23, 2005 2:35 pm
Location: Dover, NH
Contact:

Re: Multiple hardware buffers

Post by sjcomp »

genva wrote:

Code: Select all

bind->setBinding(1, uv_vbuf);
Thanks genva. Shame on me for such a miss.
Another suggestion: Hardware vertext buffer floating-point value type is float, not Real.
Does it mean that I should use float as in the following lines?

Code: Select all

float uv_verts[2] ={0.0f, 0.0f}; 
pFloat = (float*)uv_vbuf->lock(Ogre::HardwareBuffer::HBL_DISCARD);
instead of:

Code: Select all

Real uv_verts[2] ={0.0, 0.0}; 
pReal = (Real*)uv_vbuf->lock(Ogre::HardwareBuffer::HBL_DISCARD);
Example in wiki and all I have seen in forums were using Ogre::Real (wiki example). How can I make sure that I do not have dependancy on the compilation options of the Ogre?
Thanks a lot!
Regards, Alexander. http://sjcomp.com
genva
OGRE Retired Team Member
OGRE Retired Team Member
Posts: 1603
Joined: Wed Oct 20, 2004 7:54 am
Location: Beijing, China
x 1

Post by genva »

Yes, use float access hardware vertex buffer float-point value always. The wiki is kinda out-of-date.
User avatar
sjcomp
Gnome
Posts: 315
Joined: Sat Apr 23, 2005 2:35 pm
Location: Dover, NH
Contact:

Post by sjcomp »

Thanks a lot, genva!
Regards, Alexander. http://sjcomp.com
Post Reply