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"); }
// 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; }