void GPUBillboardSet::createVertexDataForVertexShaderOnly(const std::vector<PhotoSynth::Vertex>& vertices)
{
	// Setup render operation
	mRenderOp.operationType = Ogre::RenderOperation::OT_TRIANGLE_LIST; 
	mRenderOp.vertexData = OGRE_NEW Ogre::VertexData();
	mRenderOp.vertexData->vertexCount = vertices.size() * 4; 
	mRenderOp.vertexData->vertexStart = 0; 
	mRenderOp.useIndexes = true; 
	mRenderOp.indexData = OGRE_NEW Ogre::IndexData();
	mRenderOp.indexData->indexCount = vertices.size() * 6;
	mRenderOp.indexData->indexStart = 0;

	// Vertex format declaration
	unsigned short sourceBufferIdx = 0;
	Ogre::VertexDeclaration* decl = mRenderOp.vertexData->vertexDeclaration;
    size_t currOffset = 0;
	decl->addElement(sourceBufferIdx, currOffset, Ogre::VET_FLOAT3, Ogre::VES_POSITION);
	currOffset += Ogre::VertexElement::getTypeSize(Ogre::VET_FLOAT3);
	decl->addElement(sourceBufferIdx, currOffset, Ogre::VET_COLOUR, Ogre::VES_DIFFUSE);
	currOffset += Ogre::VertexElement::getTypeSize(Ogre::VET_COLOUR);
	decl->addElement(sourceBufferIdx, currOffset, Ogre::VET_FLOAT2, Ogre::VES_TEXTURE_COORDINATES, 0);
	currOffset += Ogre::VertexElement::getTypeSize(Ogre::VET_FLOAT2);

	// Create vertex buffer
    Ogre::HardwareVertexBufferSharedPtr vbuf = Ogre::HardwareBufferManager::getSingleton().createVertexBuffer(
		decl->getVertexSize(sourceBufferIdx),
        mRenderOp.vertexData->vertexCount,
        Ogre::HardwareBuffer::HBU_STATIC_WRITE_ONLY);

    // Bind vertex buffer
    Ogre::VertexBufferBinding* bind = mRenderOp.vertexData->vertexBufferBinding;
	bind->setBinding(sourceBufferIdx, vbuf);

	// Fill vertex buffer (see http://www.ogre3d.org/docs/manual/manual_59.html#SEC287)
	Ogre::RenderSystem* renderSystem = Ogre::Root::getSingletonPtr()->getRenderSystem();
	unsigned char* pVert = static_cast<unsigned char*>(vbuf->lock(Ogre::HardwareBuffer::HBL_DISCARD));
	Ogre::Real* pReal;
	Ogre::RGBA* pRGBA;
	Ogre::VertexDeclaration::VertexElementList elems = decl->findElementsBySource(sourceBufferIdx);
	Ogre::VertexDeclaration::VertexElementList::iterator itr;

	const Ogre::Vector2 uvs[4] = {	Ogre::Vector2( -1.f, 1.f ),
									Ogre::Vector2( -1.f, -1.f ),
									Ogre::Vector2( 1.f, -1.f ),
									Ogre::Vector2( 1.f, 1.f ) };
	for (unsigned int i=0; i<vertices.size(); ++i )
	{
		const PhotoSynth::Vertex& vertex = vertices[i];
		for ( unsigned int j=0; j<4; j++ )
		{
			for (itr=elems.begin(); itr!=elems.end(); ++itr)
			{
				Ogre::VertexElement& elem = *itr;
				if (elem.getSemantic() == Ogre::VES_POSITION)
				{
					elem.baseVertexPointerToElement(pVert, &pReal);
					*pReal = vertex.position.x; *pReal++;
					*pReal = vertex.position.y; *pReal++;
					*pReal = vertex.position.z; *pReal++;
				}
				else if (elem.getSemantic() == Ogre::VES_DIFFUSE)
				{
					elem.baseVertexPointerToElement(pVert, &pRGBA);
					renderSystem->convertColourValue(vertex.color, pRGBA);
				}
				else if (elem.getSemantic() == Ogre::VES_TEXTURE_COORDINATES && elem.getIndex() == 0)
				{
					elem.baseVertexPointerToElement(pVert, &pReal);
					*pReal = uvs[j].x; *pReal++;
					*pReal = uvs[j].y; *pReal++;
				}
			}
			// Go to next vertex 
			pVert += vbuf->getVertexSize();
		}
	}
	vbuf->unlock();

	// Create index buffer
	if (mRenderOp.indexData->indexCount>=65536)
	{
		Ogre::HardwareIndexBufferSharedPtr ibuf = Ogre::HardwareBufferManager::getSingleton().createIndexBuffer( 
			Ogre::HardwareIndexBuffer::IT_32BIT, 
			mRenderOp.indexData->indexCount, 
			Ogre::HardwareBuffer::HBU_STATIC_WRITE_ONLY, false);

		mRenderOp.indexData->indexBuffer = ibuf;
		Ogre::uint32* indices = static_cast<Ogre::uint32*>(ibuf->lock( Ogre::HardwareBuffer::HBL_DISCARD));

		Ogre::uint32 indexFirstVertex = 0;
		const Ogre::uint32 inds[6] = {	0, 1, 2, 3, 0, 2 };
		for (unsigned int i=0; i<vertices.size(); ++i)
		{
			for (unsigned int j=0; j<6; ++j)
			{
				*indices = indexFirstVertex + inds[j];
				indices++;
			}
			indexFirstVertex +=4;
		}
		ibuf->unlock();
	}
	else
	{
		Ogre::HardwareIndexBufferSharedPtr ibuf = Ogre::HardwareBufferManager::getSingleton().createIndexBuffer(
			Ogre::HardwareIndexBuffer::IT_16BIT, 
			mRenderOp.indexData->indexCount, 
			Ogre::HardwareBuffer::HBU_STATIC_WRITE_ONLY, false);

		mRenderOp.indexData->indexBuffer = ibuf;
		Ogre::uint16* indices = static_cast<Ogre::uint16*>( ibuf->lock( Ogre::HardwareBuffer::HBL_DISCARD ) );

		Ogre::uint32 indexFirstVertex = 0;
		const Ogre::uint16 inds[6] = {	0, 1, 2, 3, 0, 2 };
		for ( unsigned int i=0; i<vertices.size(); ++i )
		{
			for ( unsigned int j=0; j<6; ++j )
			{
				*indices = indexFirstVertex + inds[j];
				indices++;
			}
			indexFirstVertex +=4;
		}
		ibuf->unlock();
	}

    // Set material
    this->setMaterial("GPUBillboard");
}
void GPUBillboardSet::createVertexDataForVertexAndGeometryShaders(const std::vector<PhotoSynth::Vertex>& vertices)
{
	// Setup render operation
	mRenderOp.operationType = Ogre::RenderOperation::OT_POINT_LIST; 
	mRenderOp.vertexData = OGRE_NEW Ogre::VertexData();
	mRenderOp.vertexData->vertexCount = vertices.size(); 
	mRenderOp.vertexData->vertexStart = 0; 
	mRenderOp.useIndexes = false; 
	mRenderOp.indexData = 0;

	// Vertex format declaration
	unsigned short sourceBufferIdx = 0;
    Ogre::VertexDeclaration* decl = mRenderOp.vertexData->vertexDeclaration;
    size_t currOffset = 0;
	decl->addElement(sourceBufferIdx, currOffset, Ogre::VET_FLOAT3, Ogre::VES_POSITION);
	currOffset += Ogre::VertexElement::getTypeSize(Ogre::VET_FLOAT3);
	decl->addElement(sourceBufferIdx, currOffset, Ogre::VET_COLOUR, Ogre::VES_DIFFUSE);
	currOffset += Ogre::VertexElement::getTypeSize(Ogre::VET_COLOUR);

	// Create vertex buffer
	Ogre::HardwareVertexBufferSharedPtr vbuf = Ogre::HardwareBufferManager::getSingleton().createVertexBuffer(
		decl->getVertexSize(sourceBufferIdx),
		mRenderOp.vertexData->vertexCount,
		Ogre::HardwareBuffer::HBU_STATIC_WRITE_ONLY);

    // Bind vertex buffer
    Ogre::VertexBufferBinding* bind = mRenderOp.vertexData->vertexBufferBinding;
	bind->setBinding(sourceBufferIdx, vbuf);

	// Fill vertex buffer (see http://www.ogre3d.org/docs/manual/manual_59.html#SEC287)
	Ogre::RenderSystem* renderSystem = Ogre::Root::getSingletonPtr()->getRenderSystem();
	unsigned char* pVert = static_cast<unsigned char*>(vbuf->lock(Ogre::HardwareBuffer::HBL_DISCARD));
	Ogre::Real* pReal;
	Ogre::RGBA* pRGBA;
	Ogre::VertexDeclaration::VertexElementList elems = decl->findElementsBySource(sourceBufferIdx);
	Ogre::VertexDeclaration::VertexElementList::iterator itr;
	for (unsigned int i=0; i<vertices.size(); ++i )
	{
		const PhotoSynth::Vertex& vertex = vertices[i];
		for (itr=elems.begin(); itr!=elems.end(); ++itr)
		{
			Ogre::VertexElement& elem = *itr;
			if (elem.getSemantic() == Ogre::VES_POSITION)
			{
				elem.baseVertexPointerToElement(pVert, &pReal);
				*pReal = vertex.position.x; *pReal++;
				*pReal = vertex.position.y; *pReal++;
				*pReal = vertex.position.z; *pReal++;
			}
			else if (elem.getSemantic() == Ogre::VES_DIFFUSE)
			{
				elem.baseVertexPointerToElement(pVert, &pRGBA);
				renderSystem->convertColourValue(vertex.color, pRGBA);
			}
		}
		// Go to next vertex 
		pVert += vbuf->getVertexSize();
	}
	vbuf->unlock();

    // Set material
    this->setMaterial("GPUBillboardWithGS");
}
Example #3
0
 // Create an Ogre compatible vertex buffer
 bool Submesh::createOgreVertexBuffer(Ogre::SubMesh* pSubmesh,Ogre::VertexDeclaration* pDecl,const std::vector<vertex>& vertices)
 {
     Ogre::HardwareVertexBufferSharedPtr vbuf = 
         Ogre::HardwareBufferManager::getSingleton().createVertexBuffer(pDecl->getVertexSize(0),
         pSubmesh->vertexData->vertexCount, 
         Ogre::HardwareBuffer::HBU_STATIC_WRITE_ONLY );
     pSubmesh->vertexData->vertexBufferBinding->setBinding(0, vbuf);
     size_t vertexSize = pDecl->getVertexSize(0);
     char* pBase = static_cast<char*>(vbuf->lock(Ogre::HardwareBuffer::HBL_DISCARD));
     Ogre::VertexDeclaration::VertexElementList elems = pDecl->findElementsBySource(0);
     Ogre::VertexDeclaration::VertexElementList::iterator ei, eiend;
     eiend = elems.end();
     float* pFloat;
     Ogre::RGBA* pRGBA;
     // Fill the vertex buffer with shared geometry data
     unsigned long vi;
     Ogre::ColourValue col;
     float ucoord, vcoord;
     for (vi=0; vi<vertices.size(); vi++)
     {
         int iTexCoord = 0;
         vertex v = vertices[vi];
         for (ei = elems.begin(); ei != eiend; ++ei)
         {
             Ogre::VertexElement& elem = *ei;
             switch(elem.getSemantic())
             {
             case Ogre::VES_POSITION:
                 elem.baseVertexPointerToElement(pBase, &pFloat);
                 *pFloat++ = static_cast<float>(v.x);
                 *pFloat++ = static_cast<float>(v.y);
                 *pFloat++ = static_cast<float>(v.z);
                 break;
             case Ogre::VES_NORMAL:
                 elem.baseVertexPointerToElement(pBase, &pFloat);
                 *pFloat++ = static_cast<float>(v.n.x);
                 *pFloat++ = static_cast<float>(v.n.y);
                 *pFloat++ = static_cast<float>(v.n.z);
                 break;
             case Ogre::VES_DIFFUSE:
                 {
                     elem.baseVertexPointerToElement(pBase, &pRGBA);
                     Ogre::ColourValue col(v.r, v.g, v.b, v.a);
                     *pRGBA = Ogre::VertexElement::convertColourValue(col, 
                         Ogre::VertexElement::getBestColourVertexElementType());
                 }
                 break;
             case Ogre::VES_TEXTURE_COORDINATES:
                 elem.baseVertexPointerToElement(pBase, &pFloat);
                 ucoord = v.texcoords[iTexCoord].u;
                 vcoord = v.texcoords[iTexCoord].v;
                 *pFloat++ = static_cast<float>(ucoord);
                 *pFloat++ = static_cast<float>(vcoord);
                 iTexCoord++;
                 break;
             }
         }
         pBase += vertexSize;
     }
     vbuf->unlock();
     return true;
 }