Selection2D::Selection2D(bool includeTextureCoords) { // use identity projection and view matrices mUseIdentityProjection = true; mUseIdentityView = true; mRenderOp.vertexData = OGRE_NEW Ogre::VertexData(); mRenderOp.indexData = 0; mRenderOp.vertexData->vertexCount = 5; mRenderOp.vertexData->vertexStart = 0; mRenderOp.operationType = Ogre::RenderOperation::OT_LINE_STRIP; mRenderOp.useIndexes = false; Ogre::VertexDeclaration* decl = mRenderOp.vertexData->vertexDeclaration; Ogre::VertexBufferBinding* bind = mRenderOp.vertexData->vertexBufferBinding; decl->addElement(0, 0, Ogre::VET_FLOAT3, Ogre::VES_POSITION); Ogre::HardwareVertexBufferSharedPtr vbuf = Ogre::HardwareBufferManager::getSingleton().createVertexBuffer( decl->getVertexSize(0), mRenderOp.vertexData->vertexCount, Ogre::HardwareBuffer::HBU_STATIC_WRITE_ONLY); // Bind buffer bind->setBinding(0, vbuf); this->setCastShadows(false); this->setQueryFlags(0); // set a query flag to exlude from queries (if necessary). // set basic white material this->setMaterial("BaseWhiteNoLighting"); }
/// @author https://bitbucket.org/ChaosCreator/imgui-ogre2.1-binding/src/8f1a01db510f543a987c3c16859d0a33400d9097/ImguiRenderable.cpp?at=master&fileviewer=file-view-default /// Commentary on OGRE forums: http://www.ogre3d.org/forums/viewtopic.php?f=5&t=89081#p531059 void OgreImGui::ImGUIRenderable::updateVertexData(const ImDrawVert* vtxBuf, const ImDrawIdx* idxBuf, unsigned int vtxCount, unsigned int idxCount) { Ogre::VertexBufferBinding* bind = mRenderOp.vertexData->vertexBufferBinding; if (bind->getBindings().empty() || mVertexBufferSize != vtxCount) { mVertexBufferSize = vtxCount; bind->setBinding(0, Ogre::HardwareBufferManager::getSingleton().createVertexBuffer(sizeof(ImDrawVert), mVertexBufferSize, Ogre::HardwareBuffer::HBU_WRITE_ONLY)); } if (mRenderOp.indexData->indexBuffer.isNull() || mIndexBufferSize != idxCount) { mIndexBufferSize = idxCount; mRenderOp.indexData->indexBuffer = Ogre::HardwareBufferManager::getSingleton().createIndexBuffer(Ogre::HardwareIndexBuffer::IT_16BIT, mIndexBufferSize, Ogre::HardwareBuffer::HBU_WRITE_ONLY); } // Copy all vertices ImDrawVert* vtxDst = (ImDrawVert*)(bind->getBuffer(0)->lock(Ogre::HardwareBuffer::HBL_DISCARD)); ImDrawIdx* idxDst = (ImDrawIdx*)(mRenderOp.indexData->indexBuffer->lock(Ogre::HardwareBuffer::HBL_DISCARD)); memcpy(vtxDst, vtxBuf, mVertexBufferSize * sizeof(ImDrawVert)); memcpy(idxDst, idxBuf, mIndexBufferSize * sizeof(ImDrawIdx)); mRenderOp.vertexData->vertexStart = 0; mRenderOp.vertexData->vertexCount = vtxCount; mRenderOp.indexData->indexStart = 0; mRenderOp.indexData->indexCount = idxCount; bind->getBuffer(0)->unlock(); mRenderOp.indexData->indexBuffer->unlock(); }
void OgreImGui::ImGUIRenderable::updateVertexData(ImDrawData* draw_data,unsigned int cmdIndex) { Ogre::VertexBufferBinding* bind = mRenderOp.vertexData->vertexBufferBinding; const ImDrawList* cmd_list = draw_data->CmdLists[cmdIndex]; if (bind->getBindings().empty() || mVertexBufferSize != cmd_list->VtxBuffer.size()) { mVertexBufferSize = cmd_list->VtxBuffer.size(); bind->setBinding(0,Ogre::HardwareBufferManager::getSingleton().createVertexBuffer(sizeof(ImDrawVert),mVertexBufferSize,Ogre::HardwareBuffer::HBU_WRITE_ONLY)); } if (mRenderOp.indexData->indexBuffer.isNull() || mIndexBufferSize != cmd_list->IdxBuffer.size()) { mIndexBufferSize = cmd_list->IdxBuffer.size(); mRenderOp.indexData->indexBuffer= Ogre::HardwareBufferManager::getSingleton().createIndexBuffer(Ogre::HardwareIndexBuffer::IT_16BIT,mIndexBufferSize,Ogre::HardwareBuffer::HBU_WRITE_ONLY); } // Copy all vertices ImDrawVert* vtx_dst = (ImDrawVert*)(bind->getBuffer(0)->lock(Ogre::HardwareBuffer::HBL_DISCARD)); ImDrawIdx* idx_dst = (ImDrawIdx*)(mRenderOp.indexData->indexBuffer->lock(Ogre::HardwareBuffer::HBL_DISCARD)); memcpy(vtx_dst, &cmd_list->VtxBuffer[0], mVertexBufferSize * sizeof(ImDrawVert)); memcpy(idx_dst, &cmd_list->IdxBuffer[0], mIndexBufferSize * sizeof(ImDrawIdx)); mRenderOp.vertexData->vertexStart = 0; mRenderOp.vertexData->vertexCount = cmd_list->VtxBuffer.size(); mRenderOp.indexData->indexStart = 0; mRenderOp.indexData->indexCount = cmd_list->IdxBuffer.size(); bind->getBuffer(0)->unlock(); mRenderOp.indexData->indexBuffer->unlock(); }
PortalOutlineRenderable::PortalOutlineRenderable(Ogre::String matname, Ogre::ColourValue colour) { mRenderOp.vertexData = OGRE_NEW Ogre::VertexData(); mRenderOp.indexData = 0; mRenderOp.vertexData->vertexCount = 10;//8 mRenderOp.vertexData->vertexStart = 0; mRenderOp.operationType = Ogre::RenderOperation::OT_LINE_LIST; mRenderOp.useIndexes = false; Ogre::VertexDeclaration* decl = mRenderOp.vertexData->vertexDeclaration; Ogre::VertexBufferBinding* bind = mRenderOp.vertexData->vertexBufferBinding; decl->addElement(0, 0, Ogre::VET_FLOAT3, Ogre::VES_POSITION); Ogre::HardwareVertexBufferSharedPtr vbuf = Ogre::HardwareBufferManager::getSingleton().createVertexBuffer( decl->getVertexSize(0), mRenderOp.vertexData->vertexCount, Ogre::HardwareBuffer::HBU_STATIC_WRITE_ONLY); // Bind buffer bind->setBinding(0, vbuf); // setup material createPortalMaterials(); //Ogre::ResourceManager::ResourceCreateOrRetrieveResult result = Ogre::MaterialManager::getSingleton().createOrRetrieve(matname, "General"); //if(result.second) //{ // Ogre::MaterialPtr matptrOBBoxManualMaterial = result.first; // matptrOBBoxManualMaterial->setReceiveShadows(false); // matptrOBBoxManualMaterial->getTechnique(0)->setLightingEnabled(true); // matptrOBBoxManualMaterial->getTechnique(0)->getPass(0)->setDiffuse(colour); // matptrOBBoxManualMaterial->getTechnique(0)->getPass(0)->setAmbient(colour); // matptrOBBoxManualMaterial->getTechnique(0)->getPass(0)->setSelfIllumination(colour); //} this->setCastShadows(false); this->setQueryFlags(0); // set a query flag to exlude from queries (if necessary). this->setMaterial("PortalOutlineMaterial"); }
Line3D::Line3D() { mRenderOp.vertexData = new Ogre::VertexData(); this->SelfNode = Entresol::GetSingletonPtr()->GetSceneManager()->GetGraphicsWorldPointer()->getRootSceneNode()->createChildSceneNode(); // Initialization stuff mRenderOp.indexData = 0; mRenderOp.vertexData->vertexCount = 1024; mRenderOp.vertexData->vertexStart = 0; mRenderOp.operationType = Ogre::RenderOperation::OT_LINE_LIST; mRenderOp.useIndexes = false; Ogre::VertexDeclaration* VDecl = mRenderOp.vertexData->vertexDeclaration; Ogre::VertexBufferBinding* VBind = mRenderOp.vertexData->vertexBufferBinding; size_t Offset = 0; // Position. VDecl->addElement(0,0,Ogre::VET_FLOAT3,Ogre::VES_POSITION); Offset += Ogre::VertexElement::getTypeSize(Ogre::VET_FLOAT3); // Colour VDecl->addElement(0,Offset,Ogre::VET_FLOAT4,Ogre::VES_DIFFUSE); Offset += Ogre::VertexElement::getTypeSize(Ogre::VET_FLOAT4); this->VertexBuffer = Ogre::HardwareBufferManager::getSingleton().createVertexBuffer( VDecl->getVertexSize(0), mRenderOp.vertexData->vertexCount, Ogre::HardwareBuffer::HBU_DYNAMIC_WRITE_ONLY_DISCARDABLE, false); VBind->setBinding(0,this->VertexBuffer); this->setMaterial("BaseWhiteNoLighting"); }
AxisRenderable::AxisRenderable(int lineCount,Ogre::Camera* camera,Ogre::Viewport* viewport) { // Disable cast shadows by default mCastShadows = false; mPrevAxisGizmoSelAxis = -1; mCamera = camera; mViewport = viewport; m_max_line_count = m_line_count = lineCount; m_line_count = 0; mLength = 200; mProjectDistance = mCamera->getFarClipDistance(); m_local = false; m_locked_data = 0; //m_locked_buffer = 0; mRenderOp.vertexData = new Ogre::VertexData(); m_radius = 0; mRenderOp.indexData = 0; mRenderOp.vertexData->vertexCount = m_line_count*2; mRenderOp.vertexData->vertexStart = 0; mRenderOp.operationType = Ogre::RenderOperation::OT_LINE_LIST; mRenderOp.useIndexes = false; Ogre::VertexDeclaration* decl = mRenderOp.vertexData->vertexDeclaration; Ogre::VertexBufferBinding* bind = mRenderOp.vertexData->vertexBufferBinding; decl->addElement(0, 0, Ogre::VET_FLOAT3, Ogre::VES_POSITION); decl->addElement(0, 3*sizeof(Ogre::Real), Ogre::VET_COLOUR, Ogre::VES_DIFFUSE); Ogre::HardwareVertexBufferSharedPtr vbuf = Ogre::HardwareBufferManager::getSingleton().createVertexBuffer( decl->getVertexSize(0), 2*m_max_line_count, Ogre::HardwareBuffer::HBU_WRITE_ONLY); bind->setBinding(0, vbuf); // Obtain the pure colour material Ogre::MaterialPtr pureColourMaterial = createPureColourMaterial(Ogre::ColourValue(1,1,0)); Ogre::String realName = pureColourMaterial->getName() + "_NoDepthBuffer"; Ogre::MaterialPtr material = Ogre::MaterialManager::getSingleton().getByName(realName); if (material.isNull()) { // Clone to avoid confuse somewhere else that using the same material material = pureColourMaterial->clone(realName); material->setDepthCheckEnabled(false); material->setDepthWriteEnabled(false); } setMaterial(material->getName()); mBox.setExtents(-10,-10,-10,10,10,10); setQueryFlags(0); }
void Canvas::resizeBuffers() { if(bufferSize < quadList.size()) { bufferSize = quadList.size() * 2; destroyBuffers(); } if(!vertexData) { vertexData = new Ogre::VertexData(); vertexData->vertexStart = 0; vertexData->vertexCount = bufferSize * 4; Ogre::VertexDeclaration* decl = vertexData->vertexDeclaration; Ogre::VertexBufferBinding* binding = vertexData->vertexBufferBinding; size_t offset = 0; decl->addElement(0, offset, Ogre::VET_FLOAT3, Ogre::VES_POSITION); offset += Ogre::VertexElement::getTypeSize(Ogre::VET_FLOAT3); decl->addElement(0, offset, Ogre::VET_COLOUR, Ogre::VES_DIFFUSE); offset += Ogre::VertexElement::getTypeSize(Ogre::VET_COLOUR); decl->addElement(0, offset, Ogre::VET_FLOAT2, Ogre::VES_TEXTURE_COORDINATES, 0); buffer = Ogre::HardwareBufferManager::getSingleton().createVertexBuffer( decl->getVertexSize(0), vertexData->vertexCount, Ogre::HardwareBuffer::HBU_DYNAMIC_WRITE_ONLY_DISCARDABLE); binding->setBinding(0, buffer); } if(!indexData) { indexData = new Ogre::IndexData(); indexData->indexStart = 0; indexData->indexCount = bufferSize * 6; indexData->indexBuffer = Ogre::HardwareBufferManager::getSingleton().createIndexBuffer( Ogre::HardwareIndexBuffer::IT_16BIT, indexData->indexCount, Ogre::HardwareBuffer::HBU_STATIC_WRITE_ONLY); unsigned short* indexBuffer = (unsigned short*)indexData->indexBuffer->lock(0, indexData->indexBuffer->getSizeInBytes(), Ogre::HardwareBuffer::HBL_DISCARD); // Indexes are generated here because we know that we will only be rendering quads // This means that we only have to handle updating the vertex buffer in Canvas::updateGeometry for(size_t indexIdx, vertexIdx, quadIdx = 0; quadIdx < bufferSize; quadIdx++) { indexIdx = quadIdx * 6; vertexIdx = quadIdx * 4; indexBuffer[indexIdx++] = (unsigned short)(vertexIdx + 0); indexBuffer[indexIdx++] = (unsigned short)(vertexIdx + 2); indexBuffer[indexIdx++] = (unsigned short)(vertexIdx + 1); indexBuffer[indexIdx++] = (unsigned short)(vertexIdx + 1); indexBuffer[indexIdx++] = (unsigned short)(vertexIdx + 2); indexBuffer[indexIdx++] = (unsigned short)(vertexIdx + 3); } indexData->indexBuffer->unlock(); } }
void DebugLines::draw() { if(_drawn) return; else _drawn = true; // Initialization stuff mRenderOp.indexData = 0; mRenderOp.vertexData->vertexCount = _points.size(); mRenderOp.vertexData->vertexStart = 0; mRenderOp.operationType = RenderOperation::OT_LINE_LIST; mRenderOp.useIndexes = false; Ogre::VertexDeclaration *decl = mRenderOp.vertexData->vertexDeclaration; Ogre::VertexBufferBinding *bind = mRenderOp.vertexData->vertexBufferBinding; decl->addElement(0, 0, VET_FLOAT3, VES_POSITION); HardwareVertexBufferSharedPtr vbuf = HardwareBufferManager::getSingleton().createVertexBuffer( decl->getVertexSize(0), mRenderOp.vertexData->vertexCount, HardwareBuffer::HBU_STATIC_WRITE_ONLY); bind->setBinding(0, vbuf); // Drawing stuff size_t size = _points.size(); Vector3 vaabMin = _points[0]; Vector3 vaabMax = _points[0]; Real *prPos = static_cast<Real*>(vbuf->lock(HardwareBuffer::HBL_DISCARD)); for(size_t i = 0; i < size; i++) { *prPos++ = _points[i].x; *prPos++ = _points[i].y; *prPos++ = _points[i].z; if(_points[i].x < vaabMin.x) vaabMin.x = _points[i].x; if(_points[i].y < vaabMin.y) vaabMin.y = _points[i].y; if(_points[i].z < vaabMin.z) vaabMin.z = _points[i].z; if(_points[i].x > vaabMax.x) vaabMax.x = _points[i].x; if(_points[i].y > vaabMax.y) vaabMax.y = _points[i].y; if(_points[i].z > vaabMax.z) vaabMax.z = _points[i].z; } vbuf->unlock(); mBox.setExtents(vaabMin, vaabMax); }
void ESKOgre::createFakeEntity(Ogre::SceneManager *mSceneMgr) { Ogre::MeshPtr msh = Ogre::MeshManager::getSingleton().createManual(name + "_skeleton", XENOVIEWER_RESOURCE_GROUP); msh->setSkeletonName(name); Ogre::SubMesh* sub = msh->createSubMesh(); const size_t nVertices = 3; const size_t nVertCount = 3; const size_t vbufCount = nVertCount*nVertices; float *vertices = (float *)malloc(sizeof(float)*vbufCount); for (size_t i = 0; i < nVertices; i++) { vertices[i*nVertCount] = 0.0; vertices[i*nVertCount + 1] = 0.0; vertices[i*nVertCount + 2] = 0.0; } const size_t ibufCount = 3; unsigned short *faces = (unsigned short *)malloc(sizeof(unsigned short) * ibufCount); for (size_t i = 0; i < ibufCount; i++) { faces[i] = i; } msh->sharedVertexData = new Ogre::VertexData(); msh->sharedVertexData->vertexCount = nVertices; Ogre::VertexDeclaration* decl = msh->sharedVertexData->vertexDeclaration; size_t offset = 0; decl->addElement(0, offset, Ogre::VET_FLOAT3, Ogre::VES_POSITION); offset += Ogre::VertexElement::getTypeSize(Ogre::VET_FLOAT3); Ogre::HardwareVertexBufferSharedPtr vbuf = Ogre::HardwareBufferManager::getSingleton().createVertexBuffer(offset, msh->sharedVertexData->vertexCount, Ogre::HardwareBuffer::HBU_STATIC_WRITE_ONLY); vbuf->writeData(0, vbuf->getSizeInBytes(), vertices, true); Ogre::VertexBufferBinding* bind = msh->sharedVertexData->vertexBufferBinding; bind->setBinding(0, vbuf); Ogre::HardwareIndexBufferSharedPtr ibuf = Ogre::HardwareBufferManager::getSingleton().createIndexBuffer(Ogre::HardwareIndexBuffer::IT_16BIT, ibufCount, Ogre::HardwareBuffer::HBU_STATIC_WRITE_ONLY); ibuf->writeData(0, ibuf->getSizeInBytes(), faces, true); sub->useSharedVertices = true; sub->indexData->indexBuffer = ibuf; sub->indexData->indexCount = ibufCount; sub->indexData->indexStart = 0; msh->_setBounds(Ogre::AxisAlignedBox(-100, -100, -100, 100, 100, 100)); msh->_setBoundingSphereRadius(100); msh->load(); free(faces); free(vertices); skeleton_entity = mSceneMgr->createEntity(name + "_skeleton"); skeleton_node = mSceneMgr->getRootSceneNode()->createChildSceneNode(); skeleton_node->attachObject(skeleton_entity); skeleton_node->setVisible(false); }
BufferType* ManualObject::createBuffer( const BufferBinding binding ,Ogre::VertexElementType type ,Ogre::VertexElementSemantic semantic ) { Ogre::VertexDeclaration* decl = m_section->vertexData->vertexDeclaration; Ogre::VertexBufferBinding* bind = m_section->vertexData->vertexBufferBinding; decl->addElement( binding, 0, type, semantic ); size_t vertex_size( decl->getVertexSize( binding ) ); VertexBuffer buffer = Ogre::HardwareBufferManager::getSingleton() .createVertexBuffer( vertex_size ,m_section->vertexData->vertexCount ,Ogre::HardwareBuffer::HBU_STATIC_WRITE_ONLY); bind->setBinding( binding, buffer ); m_vertex_buffers[binding] = buffer; return static_cast<BufferType*>( buffer->lock( Ogre::HardwareBuffer::HBL_DISCARD ) ); }
void TerrainGridRenderable::initTerrainGrid(int vertexCount) { m_locked_data = 0; mRenderOp.vertexData = new Ogre::VertexData(); mRenderOp.indexData = 0; mRenderOp.vertexData->vertexCount = mVertexCount; mRenderOp.vertexData->vertexStart = 0; mRenderOp.operationType = Ogre::RenderOperation::OT_LINE_LIST; mRenderOp.useIndexes = false; Ogre::VertexDeclaration* decl = mRenderOp.vertexData->vertexDeclaration; Ogre::VertexBufferBinding* bind = mRenderOp.vertexData->vertexBufferBinding; decl->addElement(0, 0, Ogre::VET_FLOAT3, Ogre::VES_POSITION); decl->addElement(0, 3*sizeof(Ogre::Real), Ogre::VET_COLOUR, Ogre::VES_DIFFUSE); Ogre::HardwareVertexBufferSharedPtr vbuf = Ogre::HardwareBufferManager::getSingleton().createVertexBuffer( decl->getVertexSize(0), vertexCount, Ogre::HardwareBuffer::HBU_WRITE_ONLY); bind->setBinding(0, vbuf); // set basic white material this->setMaterial("BaseWhiteNoLighting"); mBox.setExtents(-10,-10,-10,10,10,10); lock(); drawGridLines(); unlock(); // getMaterial()->setSceneBlending(Ogre::SBT_TRANSPARENT_ALPHA); setQueryFlags(0); }
void MeshManager::_createGeometry() { int numVertices = mSteps * mCircles + 1; int numEle = 6 * mSteps * (mCircles - 1) + 3 * mSteps; // Vertex buffers mSubMesh->vertexData = new Ogre::VertexData(); mSubMesh->vertexData->vertexStart = 0; mSubMesh->vertexData->vertexCount = numVertices; Ogre::VertexDeclaration* vdecl = mSubMesh->vertexData->vertexDeclaration; Ogre::VertexBufferBinding* vbind = mSubMesh->vertexData->vertexBufferBinding; size_t offset = 0; vdecl->addElement(0, offset, Ogre::VET_FLOAT3, Ogre::VES_POSITION); offset += Ogre::VertexElement::getTypeSize(Ogre::VET_FLOAT3); vdecl->addElement(0, offset, Ogre::VET_FLOAT3, Ogre::VES_TEXTURE_COORDINATES, 0); offset += Ogre::VertexElement::getTypeSize(Ogre::VET_FLOAT3); vdecl->addElement(0, offset, Ogre::VET_FLOAT2, Ogre::VES_TEXTURE_COORDINATES, 1); offset += Ogre::VertexElement::getTypeSize(Ogre::VET_FLOAT2); vdecl->addElement(0, offset, Ogre::VET_FLOAT1, Ogre::VES_TEXTURE_COORDINATES, 2); mVertexBuffer = Ogre::HardwareBufferManager::getSingleton(). createVertexBuffer(sizeof(POS_UV_VERTEX), numVertices, Ogre::HardwareBuffer::HBU_DYNAMIC_WRITE_ONLY); vbind->setBinding(0, mVertexBuffer); unsigned int *indexbuffer = new unsigned int[numEle]; for(int k = 0; k < mSteps; k++) { indexbuffer[k * 3] = 0; indexbuffer[k * 3 + 1] = k + 1; if(k != mSteps - 1) { indexbuffer[k * 3 + 2] = k + 2; } else { indexbuffer[k * 3 + 2] = 1; } } for(int y = 0; y < mCircles - 1; y++) { for(int x = 0; x < mSteps; x++) { unsigned int *twoface = indexbuffer + (y * mSteps + x) * 6 + 3 * mSteps; int p0 = 1 + y * mSteps + x ; int p1 = 1 + y * mSteps + x + 1 ; int p2 = 1 + (y + 1) * mSteps + x ; int p3 = 1 + (y + 1) * mSteps + x + 1 ; if(x == mSteps - 1) { p1 -= x + 1; p3 -= x + 1; } // First triangle twoface[2] = p0; twoface[1] = p1; twoface[0] = p2; // Second triangle twoface[5] = p1; twoface[4] = p3; twoface[3] = p2; } } // Prepare buffer for indices mIndexBuffer = Ogre::HardwareBufferManager::getSingleton().createIndexBuffer( Ogre::HardwareIndexBuffer::IT_32BIT, numEle, Ogre::HardwareBuffer::HBU_STATIC, true); mIndexBuffer-> writeData(0, mIndexBuffer->getSizeInBytes(), indexbuffer, true); delete []indexbuffer; // Set index buffer for this submesh mSubMesh->indexData->indexBuffer = mIndexBuffer; mSubMesh->indexData->indexStart = 0; mSubMesh->indexData->indexCount = numEle; // Create our internal buffer for manipulations mVertices = new POS_UV_VERTEX[1 + mSteps * mCircles]; }
GrassPatch::GrassPatch(int nb_blades, int nb_blade_segments, float width, float height, Ogre::SceneManager* ScnMgr) { int i, nb_particles; // Create the particle field nb_particles = nb_blades * (nb_blade_segments + 1); m_Particles = new GrassParticleField(nb_particles, 1); // Allocate the blade list m_Blades = new Blade *[nb_blades]; m_NbBlades = nb_blades; Ogre::Radian *angle = new Ogre::Radian(Ogre::Math::PI * ((rand()%1000) / 1000.0f)); // Create the blades of grass for (i = 0; i < nb_blades; i++) { m_Blades[i] = new Blade(m_Particles, i * (nb_blade_segments + 1), nb_blade_segments, 4 + ((rand()%1000) / 1000.0f)*0.5f, 0.3f + ((rand()%1000) / 1000.0f)*0.1f, width / 2 - ((rand()%1000) / 500.0f) * width, height / 2 - ((rand()%1000) / 500.0f) * height, *angle); m_Blades[i]->moving = true; m_Blades[i]->timeout = 0; } m_VertexCount = nb_blades * m_Blades[0]->GetStrippedVertexCount(); m_TriangleCount = ((nb_blade_segments - 1) << 1) + 1; mvertexData = new Ogre::VertexData (); // Vertex declaration Ogre::VertexDeclaration* decl = mvertexData->vertexDeclaration; Ogre::VertexBufferBinding* binding = mvertexData->vertexBufferBinding; size_t offset = 0; //position decl->addElement (POSITION_BINDING, 0, Ogre::VET_FLOAT3, Ogre::VES_POSITION); offset += Ogre::VertexElement::getTypeSize(Ogre::VET_FLOAT3); // normal here decl->addElement(POSITION_BINDING, offset, Ogre::VET_FLOAT3, Ogre::VES_NORMAL); offset += Ogre::VertexElement::getTypeSize(Ogre::VET_FLOAT3); // Diffuse Color decl->addElement(POSITION_BINDING, offset, Ogre::VET_COLOUR, Ogre::VES_DIFFUSE); offset += Ogre::VertexElement::getTypeSize(Ogre::VET_COLOUR); // texture here decl->addElement(POSITION_BINDING, offset, Ogre::VET_FLOAT2, Ogre::VES_TEXTURE_COORDINATES); offset += Ogre::VertexElement::getTypeSize(Ogre::VET_FLOAT2); //position updated each frame Ogre::HardwareVertexBufferSharedPtr vbuf1 = Ogre::HardwareBufferManager::getSingleton().createVertexBuffer (offset, // size of one whole vertex m_VertexCount, // number of vertices Ogre::HardwareBuffer::HBU_DYNAMIC_WRITE_ONLY, // usage false); // no shadow buffer binding->setBinding(POSITION_BINDING, vbuf1); Ogre::HardwareVertexBufferSharedPtr vVertices = binding->getBuffer(POSITION_BINDING); Ogre::Real *pVertices = static_cast<Ogre::Real*>( vVertices->lock( Ogre::HardwareBuffer::HBL_DISCARD ) ); // Colour up the blades for (i = 0; i < m_NbBlades; i++) m_Blades[i]->Paint (i, pVertices); vVertices->unlock(); // Index buffer to handle triangle strip vertex buffer as triangle list // Create index buffer int nIndexes = m_TriangleCount*3*m_NbBlades; Ogre::HardwareIndexBufferSharedPtr iBuf = Ogre::HardwareBufferManager::getSingleton().createIndexBuffer (Ogre::HardwareIndexBuffer::IT_32BIT, nIndexes, Ogre::HardwareBuffer::HBU_STATIC_WRITE_ONLY, false); // Fill index buffer unsigned int* pIdx = static_cast<unsigned int*> (iBuf->lock (Ogre::HardwareBuffer::HBL_DISCARD)); unsigned int j = 0; for (i = 0; i < m_NbBlades; i++) m_Blades[i]->UpdateIndexBuffer(&j, i, pIdx); iBuf->unlock (); mRenderOp.vertexData = mvertexData; // mRenderOp.vertexData->vertexCount = m_VertexCount; mRenderOp.vertexData->vertexCount= nIndexes; mRenderOp.vertexData->vertexStart = 0; mRenderOp.operationType = Ogre::RenderOperation::OT_TRIANGLE_LIST; mRenderOp.indexData = new Ogre::IndexData(); mRenderOp.indexData->indexBuffer = iBuf; mRenderOp.indexData->indexCount = nIndexes; mRenderOp.indexData->indexStart = 0; mRenderOp.useIndexes = true; mRenderOp.srcRenderable = this; setMaterial ("Examples/Grass"); // setup radius the bounding box of this SimpleRenderable to big values to be sure to achieve drawing. mRadius = 100; setBoundingBox(Ogre::AxisAlignedBox(-300, -300, -300, 600, 600, 600)); }
void MilkshapePlugin::doExportMesh(msModel* pModel) { // Create singletons Ogre::SkeletonManager skelMgr; Ogre::DefaultHardwareBufferManager defHWBufMgr; Ogre::LogManager& logMgr = Ogre::LogManager::getSingleton(); Ogre::MeshManager meshMgr; // // choose filename // OPENFILENAME ofn; memset (&ofn, 0, sizeof (OPENFILENAME)); char szFile[MS_MAX_PATH]; char szFileTitle[MS_MAX_PATH]; char szDefExt[32] = "mesh"; char szFilter[128] = "OGRE .mesh Files (*.mesh)\0*.mesh\0All Files (*.*)\0*.*\0\0"; szFile[0] = '\0'; szFileTitle[0] = '\0'; ofn.lStructSize = sizeof (OPENFILENAME); ofn.lpstrDefExt = szDefExt; ofn.lpstrFilter = szFilter; ofn.lpstrFile = szFile; ofn.nMaxFile = MS_MAX_PATH; ofn.lpstrFileTitle = szFileTitle; ofn.nMaxFileTitle = MS_MAX_PATH; ofn.Flags = OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT | OFN_PATHMUSTEXIST; ofn.lpstrTitle = "Export to OGRE Mesh"; if (!::GetSaveFileName (&ofn)) return /*0*/; logMgr.logMessage("Creating Mesh object..."); Ogre::MeshPtr ogreMesh = Ogre::MeshManager::getSingleton().create("export", Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); logMgr.logMessage("Mesh object created."); bool foundBoneAssignment = false; // No shared geometry int i; int wh, numbones; int intweight[3], intbones[3]; size_t j; Ogre::Vector3 min, max, currpos; Ogre::Real maxSquaredRadius; bool first = true; for (i = 0; i < msModel_GetMeshCount (pModel); i++) { msMesh *pMesh = msModel_GetMeshAt (pModel, i); logMgr.logMessage("Creating SubMesh object..."); Ogre::SubMesh* ogreSubMesh = ogreMesh->createSubMesh(); logMgr.logMessage("SubMesh object created."); // Set material logMgr.logMessage("Getting SubMesh Material..."); int matIdx = msMesh_GetMaterialIndex(pMesh); if (matIdx == -1) { // No material, use blank ogreSubMesh->setMaterialName("BaseWhite"); logMgr.logMessage("No Material, using default 'BaseWhite'."); } else { msMaterial *pMat = msModel_GetMaterialAt(pModel, matIdx); ogreSubMesh->setMaterialName(pMat->szName); logMgr.logMessage("SubMesh Material Done."); } logMgr.logMessage("Setting up geometry..."); // Set up mesh geometry ogreSubMesh->vertexData = new Ogre::VertexData(); ogreSubMesh->vertexData->vertexCount = msMesh_GetVertexCount (pMesh); ogreSubMesh->vertexData->vertexStart = 0; Ogre::VertexBufferBinding* bind = ogreSubMesh->vertexData->vertexBufferBinding; Ogre::VertexDeclaration* decl = ogreSubMesh->vertexData->vertexDeclaration; // Always 1 texture layer, 2D coords #define POSITION_BINDING 0 #define NORMAL_BINDING 1 #define TEXCOORD_BINDING 2 decl->addElement(POSITION_BINDING, 0, Ogre::VET_FLOAT3, Ogre::VES_POSITION); decl->addElement(NORMAL_BINDING, 0, Ogre::VET_FLOAT3, Ogre::VES_NORMAL); decl->addElement(TEXCOORD_BINDING, 0, Ogre::VET_FLOAT2, Ogre::VES_TEXTURE_COORDINATES); // Create buffers Ogre::HardwareVertexBufferSharedPtr pbuf = Ogre::HardwareBufferManager::getSingleton(). createVertexBuffer(decl->getVertexSize(POSITION_BINDING), ogreSubMesh->vertexData->vertexCount, Ogre::HardwareBuffer::HBU_DYNAMIC, false); Ogre::HardwareVertexBufferSharedPtr nbuf = Ogre::HardwareBufferManager::getSingleton(). createVertexBuffer(decl->getVertexSize(NORMAL_BINDING), ogreSubMesh->vertexData->vertexCount, Ogre::HardwareBuffer::HBU_DYNAMIC, false); Ogre::HardwareVertexBufferSharedPtr tbuf = Ogre::HardwareBufferManager::getSingleton(). createVertexBuffer(decl->getVertexSize(TEXCOORD_BINDING), ogreSubMesh->vertexData->vertexCount, Ogre::HardwareBuffer::HBU_DYNAMIC, false); bind->setBinding(POSITION_BINDING, pbuf); bind->setBinding(NORMAL_BINDING, nbuf); bind->setBinding(TEXCOORD_BINDING, tbuf); ogreSubMesh->useSharedVertices = false; float* pPos = static_cast<float*>( pbuf->lock(Ogre::HardwareBuffer::HBL_DISCARD)); logMgr.logMessage("Doing positions and texture coords..."); for (j = 0; j < ogreSubMesh->vertexData->vertexCount; ++j) { logMgr.logMessage("Doing vertex " + Ogre::StringConverter::toString(j)); msVertex *pVertex = msMesh_GetVertexAt (pMesh, (int)j); msVertexEx *pVertexEx=msMesh_GetVertexExAt(pMesh, (int)j); msVec3 Vertex; msVertex_GetVertex (pVertex, Vertex); *pPos++ = Vertex[0]; *pPos++ = Vertex[1]; *pPos++ = Vertex[2]; // Deal with bounds currpos = Ogre::Vector3(Vertex[0], Vertex[1], Vertex[2]); if (first) { min = max = currpos; maxSquaredRadius = currpos.squaredLength(); first = false; } else { min.makeFloor(currpos); max.makeCeil(currpos); maxSquaredRadius = std::max(maxSquaredRadius, currpos.squaredLength()); } int boneIdx = msVertex_GetBoneIndex(pVertex); if (boneIdx != -1) { foundBoneAssignment = true; numbones = 1; intbones[0] = intbones[1] = intbones[2] = -1; intweight[0] = intweight[1] = intweight[2] = 0; for(wh = 0; wh < 3; ++wh) { intbones[wh] = msVertexEx_GetBoneIndices(pVertexEx, wh); if(intbones[wh] == -1) break; ++numbones; intweight[wh] = msVertexEx_GetBoneWeights(pVertexEx, wh); } // for(k) Ogre::VertexBoneAssignment vertAssign; vertAssign.boneIndex = boneIdx; vertAssign.vertexIndex = (unsigned int)j; if(numbones == 1) { vertAssign.weight = 1.0; } // single assignment else { vertAssign.weight=(Ogre::Real)intweight[0]/100.0; } ogreSubMesh->addBoneAssignment(vertAssign); if(numbones > 1) { // this somewhat contorted logic is because the first weight [0] matches to the bone assignment // located with pVertex. The next two weights [1][2] match up to the first two bones found // with pVertexEx [0][1]. The weight for the fourth bone, if present, is the unassigned weight for(wh = 0; wh < 3; wh++) { boneIdx = intbones[wh]; if(boneIdx == -1) break; vertAssign.boneIndex = boneIdx; vertAssign.vertexIndex = (unsigned int)j; if(wh == 2) { // fourth weight is 1.0-(sumoffirstthreeweights) vertAssign.weight = 1.0-(((Ogre::Real)intweight[0]/100.0)+ ((Ogre::Real)intweight[1]/100.0)+((Ogre::Real)intweight[2]/100.0)); } else { vertAssign.weight=(Ogre::Real)intweight[wh+1]; } ogreSubMesh->addBoneAssignment(vertAssign); } // for(k) } // if(numbones) } } pbuf->unlock(); float* pTex = static_cast<float*>( tbuf->lock(Ogre::HardwareBuffer::HBL_DISCARD)); logMgr.logMessage("Doing uvs, normals and indexes (v2)..."); // Aargh, Milkshape uses stupid separate normal indexes for the same vertex like 3DS // Normals aren't described per vertex but per triangle vertex index // Pain in the arse, we have to do vertex duplication again if normals differ at a vertex (non smooth) // WHY don't people realise this format is a pain for passing to 3D APIs in vertex buffers? float* pNorm = static_cast<float*>( nbuf->lock(Ogre::HardwareBuffer::HBL_DISCARD)); ogreSubMesh->indexData->indexCount = msMesh_GetTriangleCount (pMesh) * 3; // Always use 16-bit buffers, Milkshape can't handle more anyway Ogre::HardwareIndexBufferSharedPtr ibuf = Ogre::HardwareBufferManager::getSingleton(). createIndexBuffer(Ogre::HardwareIndexBuffer::IT_16BIT, ogreSubMesh->indexData->indexCount, Ogre::HardwareBuffer::HBU_STATIC_WRITE_ONLY); ogreSubMesh->indexData->indexBuffer = ibuf; unsigned short *pIdx = static_cast<unsigned short*>( ibuf->lock(Ogre::HardwareBuffer::HBL_DISCARD)); for (j = 0; j < ogreSubMesh->indexData->indexCount; j+=3) { msTriangle *pTriangle = msMesh_GetTriangleAt (pMesh, (int)j/3); msTriangleEx *pTriangleEx=msMesh_GetTriangleExAt(pMesh, (int)j/3); word nIndices[3]; msTriangle_GetVertexIndices (pTriangle, nIndices); msVec3 Normal; msVec2 uv; int k, vertIdx; for (k = 0; k < 3; ++k) { vertIdx = nIndices[k]; // Face index pIdx[j+k] = vertIdx; // Vertex normals // For the moment, ignore any discrepancies per vertex msTriangleEx_GetNormal(pTriangleEx, k, &Normal[0]); msTriangleEx_GetTexCoord(pTriangleEx, k, &uv[0]); pTex[(vertIdx*2)]=uv[0]; pTex[(vertIdx*2)+1]=uv[1]; pNorm[(vertIdx*3)] = Normal[0]; pNorm[(vertIdx*3)+1] = Normal[1]; pNorm[(vertIdx*3)+2] = Normal[2]; } } // Faces nbuf->unlock(); ibuf->unlock(); tbuf->unlock(); // Now use Ogre's ability to reorganise the vertex buffers the best way Ogre::VertexDeclaration* newDecl = ogreSubMesh->vertexData->vertexDeclaration->getAutoOrganisedDeclaration( foundBoneAssignment, false); Ogre::BufferUsageList bufferUsages; for (size_t u = 0; u <= newDecl->getMaxSource(); ++u) bufferUsages.push_back(Ogre::HardwareBuffer::HBU_STATIC_WRITE_ONLY); ogreSubMesh->vertexData->reorganiseBuffers(newDecl, bufferUsages); logMgr.logMessage("Geometry done."); } // SubMesh // Set bounds ogreMesh->_setBoundingSphereRadius(Ogre::Math::Sqrt(maxSquaredRadius)); ogreMesh->_setBounds(Ogre::AxisAlignedBox(min, max), false); // Keep hold of a Skeleton pointer for deletion later // Mesh uses Skeleton pointer for skeleton name Ogre::SkeletonPtr pSkel; if (exportSkeleton && foundBoneAssignment) { // export skeleton, also update mesh to point to it pSkel = doExportSkeleton(pModel, ogreMesh); } else if (!exportSkeleton && foundBoneAssignment) { // We've found bone assignments, but skeleton is not to be exported // Prompt the user to find the skeleton if (!locateSkeleton(ogreMesh)) return; } // Export logMgr.logMessage("Creating MeshSerializer.."); Ogre::MeshSerializer serializer; logMgr.logMessage("MeshSerializer created."); // Generate LODs if required if (generateLods) { // Build LOD depth list Ogre::Mesh::LodDistanceList distList; float depth = 0; for (unsigned short depthidx = 0; depthidx < numLods; ++depthidx) { depth += lodDepthIncrement; distList.push_back(depth); } ogreMesh->generateLodLevels(distList, lodReductionMethod, lodReductionAmount); } if (generateEdgeLists) { ogreMesh->buildEdgeList(); } if (generateTangents) { unsigned short src, dest; ogreMesh->suggestTangentVectorBuildParams(tangentSemantic, src, dest); ogreMesh->buildTangentVectors(tangentSemantic, src, dest, tangentsSplitMirrored, tangentsSplitRotated, tangentsUseParity); } // Export Ogre::String msg; msg = "Exporting mesh data to file '" + Ogre::String(szFile) + "'"; logMgr.logMessage(msg); serializer.exportMesh(ogreMesh.getPointer(), szFile); logMgr.logMessage("Export successful"); Ogre::MeshManager::getSingleton().remove(ogreMesh->getHandle()); if (!pSkel.isNull()) Ogre::SkeletonManager::getSingleton().remove(pSkel->getHandle()); if (exportMaterials && msModel_GetMaterialCount(pModel) > 0) { doExportMaterials(pModel); } }
void NIFMeshLoader::createSubMesh(Ogre::Mesh *mesh, const Nif::NiTriShape *shape) { const Nif::NiTriShapeData *data = shape->data.getPtr(); const Nif::NiSkinInstance *skin = (shape->skin.empty() ? NULL : shape->skin.getPtr()); std::vector<Ogre::Vector3> srcVerts = data->vertices; std::vector<Ogre::Vector3> srcNorms = data->normals; Ogre::HardwareBuffer::Usage vertUsage = Ogre::HardwareBuffer::HBU_STATIC; bool vertShadowBuffer = false; bool geomMorpherController = false; if(!shape->controller.empty()) { Nif::ControllerPtr ctrl = shape->controller; do { if(ctrl->recType == Nif::RC_NiGeomMorpherController) { vertUsage = Ogre::HardwareBuffer::HBU_DYNAMIC_WRITE_ONLY; vertShadowBuffer = true; geomMorpherController = true; break; } } while(!(ctrl=ctrl->next).empty()); } if(skin != NULL) { vertUsage = Ogre::HardwareBuffer::HBU_DYNAMIC_WRITE_ONLY; vertShadowBuffer = true; // Only set a skeleton when skinning. Unskinned meshes with a skeleton will be // explicitly attached later. mesh->setSkeletonName(mName); // Convert vertices and normals to bone space from bind position. It would be // better to transform the bones into bind position, but there doesn't seem to // be a reliable way to do that. std::vector<Ogre::Vector3> newVerts(srcVerts.size(), Ogre::Vector3(0.0f)); std::vector<Ogre::Vector3> newNorms(srcNorms.size(), Ogre::Vector3(0.0f)); const Nif::NiSkinData *data = skin->data.getPtr(); const Nif::NodeList &bones = skin->bones; for(size_t b = 0;b < bones.length();b++) { Ogre::Matrix4 mat; mat.makeTransform(data->bones[b].trafo.trans, Ogre::Vector3(data->bones[b].trafo.scale), Ogre::Quaternion(data->bones[b].trafo.rotation)); mat = bones[b]->getWorldTransform() * mat; const std::vector<Nif::NiSkinData::VertWeight> &weights = data->bones[b].weights; for(size_t i = 0;i < weights.size();i++) { size_t index = weights[i].vertex; float weight = weights[i].weight; newVerts.at(index) += (mat*srcVerts[index]) * weight; if(newNorms.size() > index) { Ogre::Vector4 vec4(srcNorms[index][0], srcNorms[index][1], srcNorms[index][2], 0.0f); vec4 = mat*vec4 * weight; newNorms[index] += Ogre::Vector3(&vec4[0]); } } } srcVerts = newVerts; srcNorms = newNorms; } else { Ogre::SkeletonManager *skelMgr = Ogre::SkeletonManager::getSingletonPtr(); if(skelMgr->getByName(mName).isNull()) { // No skinning and no skeleton, so just transform the vertices and // normals into position. Ogre::Matrix4 mat4 = shape->getWorldTransform(); for(size_t i = 0;i < srcVerts.size();i++) { Ogre::Vector4 vec4(srcVerts[i].x, srcVerts[i].y, srcVerts[i].z, 1.0f); vec4 = mat4*vec4; srcVerts[i] = Ogre::Vector3(&vec4[0]); } for(size_t i = 0;i < srcNorms.size();i++) { Ogre::Vector4 vec4(srcNorms[i].x, srcNorms[i].y, srcNorms[i].z, 0.0f); vec4 = mat4*vec4; srcNorms[i] = Ogre::Vector3(&vec4[0]); } } } // Set the bounding box first BoundsFinder bounds; bounds.add(&srcVerts[0][0], srcVerts.size()); if(!bounds.isValid()) { float v[3] = { 0.0f, 0.0f, 0.0f }; bounds.add(&v[0], 1); } mesh->_setBounds(Ogre::AxisAlignedBox(bounds.minX()-0.5f, bounds.minY()-0.5f, bounds.minZ()-0.5f, bounds.maxX()+0.5f, bounds.maxY()+0.5f, bounds.maxZ()+0.5f)); mesh->_setBoundingSphereRadius(bounds.getRadius()); // This function is just one long stream of Ogre-barf, but it works // great. Ogre::HardwareBufferManager *hwBufMgr = Ogre::HardwareBufferManager::getSingletonPtr(); Ogre::HardwareVertexBufferSharedPtr vbuf; Ogre::HardwareIndexBufferSharedPtr ibuf; Ogre::VertexBufferBinding *bind; Ogre::VertexDeclaration *decl; int nextBuf = 0; Ogre::SubMesh *sub = mesh->createSubMesh(); // Add vertices sub->useSharedVertices = false; sub->vertexData = new Ogre::VertexData(); sub->vertexData->vertexStart = 0; sub->vertexData->vertexCount = srcVerts.size(); decl = sub->vertexData->vertexDeclaration; bind = sub->vertexData->vertexBufferBinding; if(srcVerts.size()) { vbuf = hwBufMgr->createVertexBuffer(Ogre::VertexElement::getTypeSize(Ogre::VET_FLOAT3), srcVerts.size(), vertUsage, vertShadowBuffer); vbuf->writeData(0, vbuf->getSizeInBytes(), &srcVerts[0][0], true); decl->addElement(nextBuf, 0, Ogre::VET_FLOAT3, Ogre::VES_POSITION); bind->setBinding(nextBuf++, vbuf); } // Vertex normals if(srcNorms.size()) { vbuf = hwBufMgr->createVertexBuffer(Ogre::VertexElement::getTypeSize(Ogre::VET_FLOAT3), srcNorms.size(), vertUsage, vertShadowBuffer); vbuf->writeData(0, vbuf->getSizeInBytes(), &srcNorms[0][0], true); decl->addElement(nextBuf, 0, Ogre::VET_FLOAT3, Ogre::VES_NORMAL); bind->setBinding(nextBuf++, vbuf); } // Vertex colors const std::vector<Ogre::Vector4> &colors = data->colors; if(colors.size()) { Ogre::RenderSystem *rs = Ogre::Root::getSingleton().getRenderSystem(); std::vector<Ogre::RGBA> colorsRGB(colors.size()); for(size_t i = 0;i < colorsRGB.size();i++) { Ogre::ColourValue clr(colors[i][0], colors[i][1], colors[i][2], colors[i][3]); rs->convertColourValue(clr, &colorsRGB[i]); } vbuf = hwBufMgr->createVertexBuffer(Ogre::VertexElement::getTypeSize(Ogre::VET_COLOUR), colorsRGB.size(), Ogre::HardwareBuffer::HBU_STATIC); vbuf->writeData(0, vbuf->getSizeInBytes(), &colorsRGB[0], true); decl->addElement(nextBuf, 0, Ogre::VET_COLOUR, Ogre::VES_DIFFUSE); bind->setBinding(nextBuf++, vbuf); } // Texture UV coordinates size_t numUVs = data->uvlist.size(); if (numUVs) { size_t elemSize = Ogre::VertexElement::getTypeSize(Ogre::VET_FLOAT2); for(size_t i = 0; i < numUVs; i++) decl->addElement(nextBuf, elemSize*i, Ogre::VET_FLOAT2, Ogre::VES_TEXTURE_COORDINATES, i); vbuf = hwBufMgr->createVertexBuffer(decl->getVertexSize(nextBuf), srcVerts.size(), Ogre::HardwareBuffer::HBU_STATIC); std::vector<Ogre::Vector2> allUVs; allUVs.reserve(srcVerts.size()*numUVs); for (size_t vert = 0; vert<srcVerts.size(); ++vert) for(size_t i = 0; i < numUVs; i++) allUVs.push_back(data->uvlist[i][vert]); vbuf->writeData(0, elemSize*srcVerts.size()*numUVs, &allUVs[0], true); bind->setBinding(nextBuf++, vbuf); } // Triangle faces const std::vector<short> &srcIdx = data->triangles; if(srcIdx.size()) { ibuf = hwBufMgr->createIndexBuffer(Ogre::HardwareIndexBuffer::IT_16BIT, srcIdx.size(), Ogre::HardwareBuffer::HBU_STATIC); ibuf->writeData(0, ibuf->getSizeInBytes(), &srcIdx[0], true); sub->indexData->indexBuffer = ibuf; sub->indexData->indexCount = srcIdx.size(); sub->indexData->indexStart = 0; } // Assign bone weights for this TriShape if(skin != NULL) { Ogre::SkeletonPtr skel = Ogre::SkeletonManager::getSingleton().getByName(mName); const Nif::NiSkinData *data = skin->data.getPtr(); const Nif::NodeList &bones = skin->bones; for(size_t i = 0;i < bones.length();i++) { Ogre::VertexBoneAssignment boneInf; boneInf.boneIndex = skel->getBone(bones[i]->name)->getHandle(); const std::vector<Nif::NiSkinData::VertWeight> &weights = data->bones[i].weights; for(size_t j = 0;j < weights.size();j++) { boneInf.vertexIndex = weights[j].vertex; boneInf.weight = weights[j].weight; sub->addBoneAssignment(boneInf); } } } const Nif::NiTexturingProperty *texprop = NULL; const Nif::NiMaterialProperty *matprop = NULL; const Nif::NiAlphaProperty *alphaprop = NULL; const Nif::NiVertexColorProperty *vertprop = NULL; const Nif::NiZBufferProperty *zprop = NULL; const Nif::NiSpecularProperty *specprop = NULL; const Nif::NiWireframeProperty *wireprop = NULL; bool needTangents = false; shape->getProperties(texprop, matprop, alphaprop, vertprop, zprop, specprop, wireprop); std::string matname = NIFMaterialLoader::getMaterial(data, mesh->getName(), mGroup, texprop, matprop, alphaprop, vertprop, zprop, specprop, wireprop, needTangents); if(matname.length() > 0) sub->setMaterialName(matname); // build tangents if the material needs them if (needTangents) { unsigned short src,dest; if (!mesh->suggestTangentVectorBuildParams(Ogre::VES_TANGENT, src,dest)) mesh->buildTangentVectors(Ogre::VES_TANGENT, src,dest); } // Create a dummy vertex animation track if there's a geom morpher controller // This is required to make Ogre create the buffers we will use for software vertex animation if (srcVerts.size() && geomMorpherController) mesh->createAnimation("dummy", 0)->createVertexTrack(1, sub->vertexData, Ogre::VAT_MORPH); }
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"); }
void MapView::createTerrain() { unsigned int sizeX = mMap->getTerrainSize().x; unsigned int sizeZ = mMap->getTerrainSize().z; mTileX = 33; mTileZ = 33; unsigned int tileCount = ((sizeX - 1) / (mTileX - 1)) * ((sizeZ - 1) / (mTileZ - 1)); unsigned int vertexPerTile = mTileX * mTileZ; unsigned int trianglesPerTile = (mTileX - 1) * (mTileZ - 1) * 2; mMeshes.resize(tileCount); mEntities.resize(tileCount); mSceneNodes.resize(tileCount); // vertexPerTile * 3 vertices * 2 texture coordinates * 3 colours * 3 normals VertexVector vertices(vertexPerTile * 11); // trianglesPerTile * 3 indices per each triangle IndexVector indices[3] = { IndexVector(trianglesPerTile * 3 ), IndexVector(trianglesPerTile * 3 / 4), IndexVector(trianglesPerTile * 3 / 8) }; unsigned int vertexIndex, indexIndex = 0, tileIndex = 0; for (unsigned int zIndex = 0; zIndex < mTileZ - 1; ++zIndex) { for (unsigned int xIndex = 0; xIndex < mTileX - 1; ++xIndex) { indices[0][indexIndex++] = zIndex * mTileX + xIndex; indices[0][indexIndex++] = (zIndex + 1) * mTileX + xIndex; indices[0][indexIndex++] = zIndex * mTileX + xIndex + 1; indices[0][indexIndex++] = (zIndex + 1) * mTileX + xIndex; indices[0][indexIndex++] = (zIndex + 1) * mTileX + xIndex + 1; indices[0][indexIndex++] = zIndex * mTileX + xIndex + 1; } } indexIndex = 0; for (unsigned int zIndex = 0; zIndex < mTileZ - 1; zIndex += 2) { for (unsigned int xIndex = 0; xIndex < mTileX - 1; xIndex += 2) { indices[1][indexIndex++] = zIndex * mTileX + xIndex; indices[1][indexIndex++] = (zIndex + 2) * mTileX + xIndex; indices[1][indexIndex++] = zIndex * mTileX + xIndex + 2; indices[1][indexIndex++] = (zIndex + 2) * mTileX + xIndex; indices[1][indexIndex++] = (zIndex + 2) * mTileX + xIndex + 2; indices[1][indexIndex++] = zIndex * mTileX + xIndex + 2; } } indexIndex = 0; for (unsigned int zIndex = 0; zIndex < mTileZ - 1; zIndex += 4) { for (unsigned int xIndex = 0; xIndex < mTileX - 1; xIndex += 4) { indices[2][indexIndex++] = zIndex * mTileX + xIndex; indices[2][indexIndex++] = (zIndex + 4) * mTileX + xIndex; indices[2][indexIndex++] = zIndex * mTileX + xIndex + 4; indices[2][indexIndex++] = (zIndex + 4) * mTileX + xIndex; indices[2][indexIndex++] = (zIndex + 4) * mTileX + xIndex + 4; indices[2][indexIndex++] = zIndex * mTileX + xIndex + 4; } } float scaleX = mMap->getSize().x / (float)(sizeX - 1); float scaleZ = mMap->getSize().z / (float)(sizeZ - 1); for (unsigned int zTile = 0; zTile < (sizeZ - 1); zTile += (mTileZ - 1)) { for (unsigned int xTile = 0; xTile < (sizeX - 1); xTile += (mTileX - 1)) { vertexIndex = 0; for (unsigned int zVertex = zTile; zVertex < zTile + mTileZ; ++zVertex) { for (unsigned int xVertex = xTile; xVertex < xTile + mTileX; ++xVertex) { float yVertex = mMap->getTerrainData()[zVertex * sizeX + xVertex]; vertices[vertexIndex++] = (float)xVertex * scaleX; vertices[vertexIndex++] = (float)yVertex; vertices[vertexIndex++] = (float)zVertex * scaleZ; vertices[vertexIndex++] = (float)xVertex / (float)(sizeX - 1); vertices[vertexIndex++] = (float)zVertex / (float)(sizeZ - 1); vertices[vertexIndex++] = 1.0f; vertices[vertexIndex++] = 1.0f; vertices[vertexIndex++] = 1.0f; vertices[vertexIndex++] = 0.0f; vertices[vertexIndex++] = 1.0f; vertices[vertexIndex++] = 0.0f; } } std::string name = "MapView_" + Convert::ToString(mID) + "_Tile_" + Convert::ToString(tileIndex); // Create mesh. mMeshes[tileIndex] = Ogre::MeshManager::getSingleton().createManual( name, "General").get(); // Create one submesh. Ogre::SubMesh* subMesh = mMeshes[tileIndex]->createSubMesh(); // Create vertex data structure for vertices shared between submeshes. mMeshes[tileIndex]->sharedVertexData = new Ogre::VertexData(); mMeshes[tileIndex]->sharedVertexData->vertexCount = vertexPerTile; // Create declaration (memory format) of vertex data. Ogre::VertexDeclaration* decl = mMeshes[tileIndex]->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_FLOAT2, Ogre::VES_TEXTURE_COORDINATES); offset += Ogre::VertexElement::getTypeSize(Ogre::VET_FLOAT2); decl->addElement(0, offset, Ogre::VET_FLOAT3, Ogre::VES_DIFFUSE); offset += Ogre::VertexElement::getTypeSize(Ogre::VET_FLOAT3); decl->addElement(0, offset, Ogre::VET_FLOAT3, Ogre::VES_NORMAL); offset += Ogre::VertexElement::getTypeSize(Ogre::VET_FLOAT3); // Allocate vertex buffer of the requested number of vertices (vertexPerTile) // and bytes per vertex (offset). Ogre::HardwareVertexBufferSharedPtr vbuf = Ogre::HardwareBufferManager::getSingleton().createVertexBuffer( offset, vertexPerTile, Ogre::HardwareBuffer::HBU_STATIC_WRITE_ONLY); // Upload the vertex data to the card vbuf->writeData(0, vbuf->getSizeInBytes(), &(vertices.front()), true); // Set vertex buffer binding so buffer 0 is bound to our vertex buffer. Ogre::VertexBufferBinding* bind = mMeshes[tileIndex]->sharedVertexData->vertexBufferBinding; bind->setBinding(0, vbuf); // Allocate index buffer of the requested number of vertices . Ogre::HardwareIndexBufferSharedPtr ibuf = Ogre::HardwareBufferManager::getSingleton(). createIndexBuffer( Ogre::HardwareIndexBuffer::IT_16BIT, trianglesPerTile * 3, Ogre::HardwareBuffer::HBU_STATIC_WRITE_ONLY); // Upload the index data to the card. ibuf->writeData(0, ibuf->getSizeInBytes(), &(indices[0].front()), true); /// Set parameters of the submesh subMesh->useSharedVertices = true; subMesh->indexData->indexBuffer = ibuf; subMesh->indexData->indexCount = indices[0].size(); subMesh->indexData->indexStart = 0; subMesh->setMaterialName("terrain"); float xMin = vertices[0]; float yMin = vertices[1]; float zMin = vertices[2]; float xMax = vertices[0]; float yMax = vertices[1]; float zMax = vertices[2]; for (unsigned int i = 0; i < vertexPerTile * 11; i += 11) { if (vertices[i ] < xMin) xMin = vertices[i ]; else if (vertices[i ] > xMax) xMax = vertices[i ]; if (vertices[i + 1] < yMin) yMin = vertices[i + 1]; else if (vertices[i + 1] > yMax) yMax = vertices[i + 1]; if (vertices[i + 2] < zMin) zMin = vertices[i + 2]; else if (vertices[i + 2] > zMax) zMax = vertices[i + 2]; } // Set bounding information (for culling). mMeshes[tileIndex]->_setBounds(Ogre::AxisAlignedBox(xMin, yMin, zMin, xMax, yMax, zMax)); mMeshes[tileIndex]->_setBoundingSphereRadius(1.0f); // Notify Mesh object that it has been loaded. mMeshes[tileIndex]->load(); // Create entity. mEntities[tileIndex] = createEntity(name, name); mEntities[tileIndex]->setCastShadows(false); mEntities[tileIndex]->setUserAny(Ogre::Any(this)); // Create scene node. mSceneNodes[tileIndex] = createSceneNode(); mSceneNodes[tileIndex]->attachObject(mEntities[tileIndex]); // Advance to next tile. tileIndex++; } } }
void TerrainTileEditable::initBuffers(TerrainData* data, int xbase, int zbase, int xsize, int zsize) { int x, z; float* pFloat; size_t vertexCount = xsize * zsize * 4; // Create and fill hardware buffers Ogre::HardwareVertexBufferSharedPtr posNormBuffer; Ogre::HardwareVertexBufferSharedPtr layerBuffer[2]; Ogre::HardwareVertexBufferSharedPtr lightmapBuffer; { // Compute position and normals float* buffer = new float[(xsize+1)*(zsize+1)*6]; pFloat = buffer; for (z = 0; z <= zsize; ++z) { for (x = 0; x <= xsize; ++x) { Ogre::Vector3 v; v = data->_getPosition(x+xbase, z+zbase); *pFloat++ = v.x; *pFloat++ = v.y; *pFloat++ = v.z; v = data->_getNormal(x+xbase, z+zbase); *pFloat++ = v.x; *pFloat++ = v.y; *pFloat++ = v.z; } } // Create buffer posNormBuffer = Ogre::HardwareBufferManager::getSingleton().createVertexBuffer( 6 * sizeof(float), vertexCount, Ogre::HardwareBuffer::HBU_STATIC_WRITE_ONLY); // Fill the buffer pFloat = static_cast<float*>(posNormBuffer->lock(Ogre::HardwareBuffer::HBL_DISCARD)); for (z = 0; z < zsize; ++z) { for (x = 0; x < xsize; ++x) { // NOTE: This algorithm is dependence with 'Corner', search [Corner Map] for detail memcpy(pFloat + 0*2*6, buffer + ((z+0) * (xsize+1) + x) * 6, 2*6 * sizeof(float)); memcpy(pFloat + 1*2*6, buffer + ((z+1) * (xsize+1) + x) * 6, 2*6 * sizeof(float)); pFloat += 2*2*6; } } posNormBuffer->unlock(); delete [] buffer; } for (size_t layerIndex = 0; layerIndex < 2; ++layerIndex) { layerBuffer[layerIndex] = Ogre::HardwareBufferManager::getSingleton().createVertexBuffer( 2 * sizeof(float), vertexCount, Ogre::HardwareBuffer::HBU_STATIC_WRITE_ONLY); } bool includeLightmap = mOwner->_isLightmapUsed(); if (includeLightmap) { Real xscale = 1.0 / xsize; Real zscale = 1.0 / zsize; lightmapBuffer = Ogre::HardwareBufferManager::getSingleton().createVertexBuffer( 2 * sizeof(float), vertexCount, Ogre::HardwareBuffer::HBU_STATIC_WRITE_ONLY); pFloat = static_cast<float*>(lightmapBuffer->lock(Ogre::HardwareBuffer::HBL_DISCARD)); for (z = 0; z < zsize; ++z) { for (x = 0; x < xsize; ++x) { *pFloat++ = xscale * (x+0); *pFloat++ = zscale * (z+0); *pFloat++ = xscale * (x+1); *pFloat++ = zscale * (z+0); *pFloat++ = xscale * (x+0); *pFloat++ = zscale * (z+1); *pFloat++ = xscale * (x+1); *pFloat++ = zscale * (z+1); } } lightmapBuffer->unlock(); } // Create vertex data for (size_t layerIndex = 0; layerIndex < 2; ++layerIndex) { Ogre::VertexData* vertexData = new Ogre::VertexData; mVertexDatas.push_back(vertexData); vertexData->vertexStart = 0; vertexData->vertexCount = vertexCount; Ogre::VertexDeclaration* decl = vertexData->vertexDeclaration; Ogre::VertexBufferBinding* bind = vertexData->vertexBufferBinding; size_t offset; size_t texCoordSet = 0; int source = 0; // position and normal offset = 0; decl->addElement(source, offset, Ogre::VET_FLOAT3, Ogre::VES_POSITION); offset += 3 * sizeof(float); decl->addElement(source, offset, Ogre::VET_FLOAT3, Ogre::VES_NORMAL); offset += 3 * sizeof(float); bind->setBinding(source++, posNormBuffer); // texture layer 0 offset = 0; decl->addElement(source, offset, Ogre::VET_FLOAT2, Ogre::VES_TEXTURE_COORDINATES, texCoordSet++); offset += 2 * sizeof(float); bind->setBinding(source++, layerBuffer[0]); // texture layer 1 if (layerIndex == 1) { offset = 0; decl->addElement(source, offset, Ogre::VET_FLOAT2, Ogre::VES_TEXTURE_COORDINATES, texCoordSet++); offset += 2 * sizeof(float); bind->setBinding(source++, layerBuffer[1]); } // light-map layer if (includeLightmap) { offset = 0; decl->addElement(source, offset, Ogre::VET_FLOAT2, Ogre::VES_TEXTURE_COORDINATES, texCoordSet++); offset += 2 * sizeof(float); bind->setBinding(source++, lightmapBuffer); } } }
//------------------------------------------------------ void DrawBuffer::buildBuffer() { // if size differs, we reallocate the buffers if (mQuadCount < mQuadList.size()) { // raise the buffer, with some padding to avoid frequent reallocations mQuadCount = mQuadList.size() * 2; destroyBuffers(); } if (mQuadCount == 0) return; if (!mVertexData) { // no vertex data, let's reallocate some! mVertexData = new Ogre::VertexData(); mVertexData->vertexStart = 0; mVertexData->vertexCount = mQuadCount * 4; Ogre::VertexDeclaration* decl = mVertexData->vertexDeclaration; Ogre::VertexBufferBinding* binding = mVertexData->vertexBufferBinding; size_t offset = 0; decl->addElement(0, offset, Ogre::VET_FLOAT3, Ogre::VES_POSITION); offset += Ogre::VertexElement::getTypeSize(Ogre::VET_FLOAT3); decl->addElement(0, offset, Ogre::VET_FLOAT2, Ogre::VES_TEXTURE_COORDINATES, 0); offset += Ogre::VertexElement::getTypeSize(Ogre::VET_FLOAT2); decl->addElement(0, offset, Ogre::VET_COLOUR, Ogre::VES_DIFFUSE); mBuffer = Ogre::HardwareBufferManager::getSingleton().createVertexBuffer( decl->getVertexSize(0), mVertexData->vertexCount, Ogre::HardwareBuffer::HBU_DYNAMIC_WRITE_ONLY_DISCARDABLE); binding->setBinding(0, mBuffer); } if (!mIndexData) { // no index data, so let's rebuilt it. mIndexData = new Ogre::IndexData(); mIndexData->indexStart = 0; mIndexData->indexCount = mQuadCount * 6; // quad count, so we have a reserve // As canvas does it - build the IBO statically, we don't need no per-update updates mIndexData->indexBuffer = Ogre::HardwareBufferManager::getSingleton().createIndexBuffer( Ogre::HardwareIndexBuffer::IT_16BIT, mIndexData->indexCount, Ogre::HardwareBuffer::HBU_DYNAMIC_WRITE_ONLY_DISCARDABLE, false); // now we'll fill the buffer with indices of triangles (0,2,1; 1,2,3) unsigned short* iData = reinterpret_cast<unsigned short*>(mIndexData->indexBuffer->lock(0, mIndexData->indexBuffer->getSizeInBytes(), Ogre::HardwareBuffer::HBL_DISCARD)); // Inspired by Canvas. It's true we don't need to do this per frame, // we'll just set the mIndexData->indexCount to the proper value after building for (size_t iindex = 0, ivertex = 0, iquad = 0; iquad < mQuadCount; ++iquad, ivertex += 4) { iindex = iquad * 6; // tri 1 iData[iindex++] = (unsigned short)(ivertex); iData[iindex++] = (unsigned short)(ivertex + 2); iData[iindex++] = (unsigned short)(ivertex + 1); // tri 2 iData[iindex++] = (unsigned short)(ivertex + 1); iData[iindex++] = (unsigned short)(ivertex + 2); iData[iindex++] = (unsigned short)(ivertex + 3); } mIndexData->indexBuffer->unlock(); }; // now we'll build the vertex part - we are already sorted so we'll just need quad rewritten // to the vertex part float* buf = reinterpret_cast<float*>(mBuffer->lock(0, mQuadList.size() * mBuffer->getVertexSize() * 4, Ogre::HardwareBuffer::HBL_DISCARD)); Ogre::RGBA* colptr; for (DrawQuadList::iterator it = mQuadList.begin(); it != mQuadList.end(); ++it) { // all the vertices const DrawQuad* dq = *it; /// Top Left corner *buf++ = dq->positions.left; *buf++ = dq->positions.top; *buf++ = dq->depth; *buf++ = dq->texCoords.left; *buf++ = dq->texCoords.top; colptr = reinterpret_cast<Ogre::RGBA*>(buf); Ogre::Root::getSingleton().convertColourValue(dq->color, colptr); colptr++; buf = reinterpret_cast<float*>(colptr); /// Top right corner *buf++ = dq->positions.right; *buf++ = dq->positions.top; *buf++ = dq->depth; *buf++ = dq->texCoords.right; *buf++ = dq->texCoords.top; colptr = reinterpret_cast<Ogre::RGBA*>(buf); Ogre::Root::getSingleton().convertColourValue(dq->color, colptr); colptr++; buf = reinterpret_cast<float*>(colptr); /// Bottom left corner *buf++ = dq->positions.left; *buf++ = dq->positions.bottom; *buf++ = dq->depth; *buf++ = dq->texCoords.left; *buf++ = dq->texCoords.bottom; colptr = reinterpret_cast<Ogre::RGBA*>(buf); Ogre::Root::getSingleton().convertColourValue(dq->color, colptr); colptr++; buf = reinterpret_cast<float*>(colptr); /// Bottom right corner *buf++ = dq->positions.right; *buf++ = dq->positions.bottom; *buf++ = dq->depth; *buf++ = dq->texCoords.right; *buf++ = dq->texCoords.bottom; colptr = reinterpret_cast<Ogre::RGBA*>(buf); Ogre::Root::getSingleton().convertColourValue(dq->color, colptr); colptr++; buf = reinterpret_cast<float*>(colptr); } // ibo length to the number of quads times six mIndexData->indexCount = mQuadList.size() * 6; mBuffer->unlock(); };
void MeshExtractor( const MeshData& mesh_data, const Ogre::String& material_name, File* file, int offset_to_data, VectorTexForGen& textures, const Ogre::MeshPtr& mesh, const Ogre::String& name, int bone_id ) { int offset_to_vertex = offset_to_data; int offset_to_triangle_t = offset_to_vertex + 0x04 + file->GetU32LE( offset_to_vertex ); int number_of_triangle_t = file->GetU16LE( offset_to_triangle_t ); u16 tpage = file->GetU16LE( offset_to_triangle_t + 0x02 ); int offset_to_quad_t = offset_to_triangle_t + 0x04 + number_of_triangle_t * 0x10; int number_of_quad_t = file->GetU16LE( offset_to_quad_t ); int offset_to_triangle = offset_to_quad_t + 0x4 + number_of_quad_t * 0x14; int number_of_triangle = file->GetU16LE( offset_to_triangle ); int offset_to_quad = offset_to_triangle + 0x4 + number_of_triangle * 0x14; int number_of_quad = file->GetU16LE( offset_to_quad ); Ogre::SubMesh* sub_mesh = mesh->createSubMesh( name ); sub_mesh->setMaterialName( material_name ); sub_mesh->useSharedVertices = false; sub_mesh->operationType = Ogre::RenderOperation::OT_TRIANGLE_LIST; // Allocate and prepare vertex data sub_mesh->vertexData = new Ogre::VertexData(); sub_mesh->vertexData->vertexStart = 0; sub_mesh->vertexData->vertexCount = static_cast< size_t >( number_of_triangle_t * 3 + number_of_quad_t * 6 + number_of_triangle * 3 + number_of_quad * 6 ); sub_mesh->indexData = new Ogre::IndexData(); sub_mesh->indexData->indexStart = 0; sub_mesh->indexData->indexCount = sub_mesh->vertexData->vertexCount; sub_mesh->indexData->indexBuffer = Ogre::HardwareBufferManager::getSingleton().createIndexBuffer( Ogre::HardwareIndexBuffer::IT_16BIT, sub_mesh->indexData->indexCount, Ogre::HardwareBuffer::HBU_STATIC_WRITE_ONLY ); u16* idata = static_cast< u16* >( sub_mesh->indexData->indexBuffer->lock( Ogre::HardwareBuffer::HBL_DISCARD ) ); u32 cur_index = 0; Ogre::VertexDeclaration* decl = sub_mesh->vertexData->vertexDeclaration; Ogre::VertexBufferBinding* bind = sub_mesh->vertexData->vertexBufferBinding; // 1st buffer decl->addElement( POSITION_BINDING, 0, Ogre::VET_FLOAT3, Ogre::VES_POSITION ); Ogre::HardwareVertexBufferSharedPtr vbuf0 = Ogre::HardwareBufferManager::getSingleton().createVertexBuffer( decl->getVertexSize( POSITION_BINDING ), sub_mesh->vertexData->vertexCount, Ogre::HardwareBuffer::HBU_STATIC_WRITE_ONLY ); bind->setBinding( POSITION_BINDING, vbuf0 ); // 2nd buffer decl->addElement( COLOUR_BINDING, 0, Ogre::VET_COLOUR, Ogre::VES_DIFFUSE ); Ogre::HardwareVertexBufferSharedPtr vbuf1 = Ogre::HardwareBufferManager::getSingleton().createVertexBuffer( decl->getVertexSize( COLOUR_BINDING ), sub_mesh->vertexData->vertexCount, Ogre::HardwareBuffer::HBU_STATIC_WRITE_ONLY ); // Set vertex buffer binding so buffer 1 is bound to our colour buffer bind->setBinding( COLOUR_BINDING, vbuf1 ); // 3rd buffer decl->addElement( TEXTURE_BINDING, 0, Ogre::VET_FLOAT2, Ogre::VES_TEXTURE_COORDINATES, 0 ); Ogre::HardwareVertexBufferSharedPtr vbuf2 = Ogre::HardwareBufferManager::getSingleton().createVertexBuffer( decl->getVertexSize( TEXTURE_BINDING ), sub_mesh->vertexData->vertexCount, Ogre::HardwareBuffer::HBU_STATIC_WRITE_ONLY ); bind->setBinding( TEXTURE_BINDING, vbuf2 ); float* pPos = static_cast< float* >( vbuf0->lock( Ogre::HardwareBuffer::HBL_DISCARD ) ); float* tPos = static_cast< float* >( vbuf2->lock( Ogre::HardwareBuffer::HBL_DISCARD ) ); Ogre::RenderSystem* rs = Ogre::Root::getSingleton().getRenderSystem(); Ogre::RGBA colours[ sub_mesh->vertexData->vertexCount ]; // add textured triangle for (int j = 0; j < number_of_triangle_t; ++j) { int offset_a = file->GetU16LE(offset_to_triangle_t + 0x4 + j * 0x10 + 0x0); int offset_b = file->GetU16LE(offset_to_triangle_t + 0x4 + j * 0x10 + 0x2); int offset_c = file->GetU16LE(offset_to_triangle_t + 0x4 + j * 0x10 + 0x4); Ogre::Vector3 a((s16)file->GetU16LE(offset_to_vertex + 0x04 + offset_a + 00), (s16)file->GetU16LE(offset_to_vertex + 0x04 + offset_a + 02), (s16)file->GetU16LE(offset_to_vertex + 0x04 + offset_a + 04)); Ogre::Vector3 b((s16)file->GetU16LE(offset_to_vertex + 0x04 + offset_b + 00), (s16)file->GetU16LE(offset_to_vertex + 0x04 + offset_b + 02), (s16)file->GetU16LE(offset_to_vertex + 0x04 + offset_b + 04)); Ogre::Vector3 c((s16)file->GetU16LE(offset_to_vertex + 0x04 + offset_c + 00), (s16)file->GetU16LE(offset_to_vertex + 0x04 + offset_c + 02), (s16)file->GetU16LE(offset_to_vertex + 0x04 + offset_c + 04)); a /= 512; b /= 512; c /= 512; u16 clut = file->GetU16LE(offset_to_triangle_t + 0x4 + j * 0x10 + 0xa); int clut_x = (clut & 0x003f) << 3; int clut_y = (clut & 0xffc0) >> 6; int bpp = (tpage >> 0x7) & 0x3; int vram_x = (tpage & 0xf) * 64; int vram_y = ((tpage & 0x10) >> 4) * 256; TexForGen texture; texture.palette_x = clut_x; texture.palette_y = clut_y; texture.texture_x = vram_x; texture.texture_y = vram_y; texture.bpp = ( BPP )bpp; AddTexture( texture, mesh_data, textures, LOGGER ); Ogre::Vector2 at(0, 0); Ogre::Vector2 bt(0, 0); Ogre::Vector2 ct(0, 0); int x = file->GetU8(offset_to_triangle_t + 0x4 + j * 0x10 + 0x8) + texture.start_x; at.x = x / (float)mesh_data.tex_width; int y = file->GetU8(offset_to_triangle_t + 0x4 + j * 0x10 + 0x9) + texture.start_y; at.y = y / (float)mesh_data.tex_height; x = file->GetU8(offset_to_triangle_t + 0x4 + j * 0x10 + 0xc) + texture.start_x; bt.x = x / (float)mesh_data.tex_width; y = file->GetU8(offset_to_triangle_t + 0x4 + j * 0x10 + 0xd) + texture.start_y; bt.y = y / (float)mesh_data.tex_height; x = file->GetU8(offset_to_triangle_t + 0x4 + j * 0x10 + 0xe) + texture.start_x; ct.x = x / (float)mesh_data.tex_width; y = file->GetU8(offset_to_triangle_t + 0x4 + j * 0x10 + 0xf) + texture.start_y; ct.y = y / (float)mesh_data.tex_height; *pPos++ = a.x; *pPos++ = a.y; *pPos++ = a.z; *pPos++ = c.x; *pPos++ = c.y; *pPos++ = c.z; *pPos++ = b.x; *pPos++ = b.y; *pPos++ = b.z; *tPos++ = at.x; *tPos++ = at.y; *tPos++ = ct.x; *tPos++ = ct.y; *tPos++ = bt.x; *tPos++ = bt.y; Ogre::ColourValue colour = Ogre::ColourValue(file->GetU8(offset_to_triangle_t + 0x4 + j * 0x10 + 0x6) / 256.0f, file->GetU8(offset_to_triangle_t + 0x4 + j * 0x10 + 0x6) / 256.0f, file->GetU8(offset_to_triangle_t + 0x4 + j * 0x10 + 0x6) / 256.0f, 1.0f); rs->convertColourValue(colour, colours + cur_index + 0); rs->convertColourValue(colour, colours + cur_index + 1); rs->convertColourValue(colour, colours + cur_index + 2); idata[cur_index + 0] = cur_index + 0; idata[cur_index + 1] = cur_index + 1; idata[cur_index + 2] = cur_index + 2; cur_index += 3; } // add textured quad for (int j = 0; j < number_of_quad_t; ++j) { int offset_a = file->GetU16LE(offset_to_quad_t + 0x4 + j * 0x14 + 0x0); int offset_b = file->GetU16LE(offset_to_quad_t + 0x4 + j * 0x14 + 0x2); int offset_c = file->GetU16LE(offset_to_quad_t + 0x4 + j * 0x14 + 0x4); int offset_d = file->GetU16LE(offset_to_quad_t + 0x4 + j * 0x14 + 0x6); Ogre::Vector3 a((s16)file->GetU16LE(offset_to_vertex + 0x04 + offset_a + 00), (s16)file->GetU16LE(offset_to_vertex + 0x04 + offset_a + 02), (s16)file->GetU16LE(offset_to_vertex + 0x04 + offset_a + 04)); Ogre::Vector3 b((s16)file->GetU16LE(offset_to_vertex + 0x04 + offset_b + 00), (s16)file->GetU16LE(offset_to_vertex + 0x04 + offset_b + 02), (s16)file->GetU16LE(offset_to_vertex + 0x04 + offset_b + 04)); Ogre::Vector3 c((s16)file->GetU16LE(offset_to_vertex + 0x04 + offset_c + 00), (s16)file->GetU16LE(offset_to_vertex + 0x04 + offset_c + 02), (s16)file->GetU16LE(offset_to_vertex + 0x04 + offset_c + 04)); Ogre::Vector3 d((s16)file->GetU16LE(offset_to_vertex + 0x04 + offset_d + 00), (s16)file->GetU16LE(offset_to_vertex + 0x04 + offset_d + 02), (s16)file->GetU16LE(offset_to_vertex + 0x04 + offset_d + 04)); a /= 512; b /= 512; c /= 512; d /= 512; u16 clut = file->GetU16LE(offset_to_quad_t + 0x4 + j * 0x14 + 0xa); int clut_x = (clut & 0x003f) << 3; int clut_y = (clut & 0xffc0) >> 6; int bpp = (tpage >> 0x7) & 0x3; int vram_x = (tpage & 0xf) * 64; int vram_y = ((tpage & 0x10) >> 4) * 256; TexForGen texture; texture.palette_x = clut_x; texture.palette_y = clut_y; texture.texture_x = vram_x; texture.texture_y = vram_y; texture.bpp = ( BPP )bpp; AddTexture( texture, mesh_data, textures, LOGGER ); Ogre::Vector2 at(0, 0); Ogre::Vector2 bt(0, 0); Ogre::Vector2 ct(0, 0); Ogre::Vector2 dt(0, 0); int x = file->GetU8(offset_to_quad_t + 0x4 + j * 0x14 + 0x8) + texture.start_x; at.x = x / (float)mesh_data.tex_width; int y = file->GetU8(offset_to_quad_t + 0x4 + j * 0x14 + 0x9) + texture.start_y; at.y = y / (float)mesh_data.tex_height; x = file->GetU8(offset_to_quad_t + 0x4 + j * 0x14 + 0xc) + texture.start_x; bt.x = x / (float)mesh_data.tex_width; y = file->GetU8(offset_to_quad_t + 0x4 + j * 0x14 + 0xd) + texture.start_y; bt.y = y / (float)mesh_data.tex_height; x = file->GetU8(offset_to_quad_t + 0x4 + j * 0x14 + 0xe) + texture.start_x; ct.x = x / (float)mesh_data.tex_width; y = file->GetU8(offset_to_quad_t + 0x4 + j * 0x14 + 0xf) + texture.start_y; ct.y = y / (float)mesh_data.tex_height; x = file->GetU8(offset_to_quad_t + 0x4 + j * 0x14 + 0x10) + texture.start_x; dt.x = x / (float)mesh_data.tex_width; y = file->GetU8(offset_to_quad_t + 0x4 + j * 0x14 + 0x11) + texture.start_y; dt.y = y / (float)mesh_data.tex_height; *pPos++ = a.x; *pPos++ = a.y; *pPos++ = a.z; *pPos++ = c.x; *pPos++ = c.y; *pPos++ = c.z; *pPos++ = b.x; *pPos++ = b.y; *pPos++ = b.z; *pPos++ = b.x; *pPos++ = b.y; *pPos++ = b.z; *pPos++ = c.x; *pPos++ = c.y; *pPos++ = c.z; *pPos++ = d.x; *pPos++ = d.y; *pPos++ = d.z; *tPos++ = at.x; *tPos++ = at.y; *tPos++ = ct.x; *tPos++ = ct.y; *tPos++ = bt.x; *tPos++ = bt.y; *tPos++ = bt.x; *tPos++ = bt.y; *tPos++ = ct.x; *tPos++ = ct.y; *tPos++ = dt.x; *tPos++ = dt.y; Ogre::ColourValue colour = Ogre::ColourValue(file->GetU8(offset_to_quad_t + 0x4 + j * 0x14 + 0x12) / 256.0f, file->GetU8(offset_to_quad_t + 0x4 + j * 0x14 + 0x12) / 256.0f, file->GetU8(offset_to_quad_t + 0x4 + j * 0x14 + 0x12) / 256.0f, 1.0f); rs->convertColourValue(colour, colours + cur_index + 0); rs->convertColourValue(colour, colours + cur_index + 1); rs->convertColourValue(colour, colours + cur_index + 2); rs->convertColourValue(colour, colours + cur_index + 3); rs->convertColourValue(colour, colours + cur_index + 4); rs->convertColourValue(colour, colours + cur_index + 5); idata[cur_index + 0] = cur_index + 0; idata[cur_index + 1] = cur_index + 1; idata[cur_index + 2] = cur_index + 2; idata[cur_index + 3] = cur_index + 3; idata[cur_index + 4] = cur_index + 4; idata[cur_index + 5] = cur_index + 5; cur_index += 6; } // add color triangle for (int j = 0; j < number_of_triangle; ++j) { int offset_a = file->GetU16LE(offset_to_triangle + 0x4 + j * 0x14 + 0x0); int offset_b = file->GetU16LE(offset_to_triangle + 0x4 + j * 0x14 + 0x2); int offset_c = file->GetU16LE(offset_to_triangle + 0x4 + j * 0x14 + 0x4); Ogre::Vector3 a((s16)file->GetU16LE(offset_to_vertex + 0x04 + offset_a + 00), (s16)file->GetU16LE(offset_to_vertex + 0x04 + offset_a + 02), (s16)file->GetU16LE(offset_to_vertex + 0x04 + offset_a + 04)); Ogre::Vector3 b((s16)file->GetU16LE(offset_to_vertex + 0x04 + offset_b + 00), (s16)file->GetU16LE(offset_to_vertex + 0x04 + offset_b + 02), (s16)file->GetU16LE(offset_to_vertex + 0x04 + offset_b + 04)); Ogre::Vector3 c((s16)file->GetU16LE(offset_to_vertex + 0x04 + offset_c + 00), (s16)file->GetU16LE(offset_to_vertex + 0x04 + offset_c + 02), (s16)file->GetU16LE(offset_to_vertex + 0x04 + offset_c + 04)); a /= 512; b /= 512; c /= 512; TexForGen texture; texture.palette_x = 0; texture.palette_y = 0; texture.texture_x = 0; texture.texture_y = 0; texture.bpp = BPP_BLACK; AddTexture( texture, mesh_data, textures, LOGGER ); Ogre::Vector2 at(0, 0); Ogre::Vector2 bt(0, 0); Ogre::Vector2 ct(0, 0); at.x = bt.x = ct.x = texture.start_x / (float)mesh_data.tex_width; at.y = bt.y = ct.y = texture.start_y / (float)mesh_data.tex_height; *pPos++ = a.x; *pPos++ = a.y; *pPos++ = a.z; *pPos++ = c.x; *pPos++ = c.y; *pPos++ = c.z; *pPos++ = b.x; *pPos++ = b.y; *pPos++ = b.z; *tPos++ = at.x; *tPos++ = at.y; *tPos++ = ct.x; *tPos++ = ct.y; *tPos++ = bt.x; *tPos++ = bt.y; Ogre::ColourValue a_colour = Ogre::ColourValue(file->GetU8(offset_to_triangle + 0x4 + j * 0x14 + 0x08) / 256.0f, file->GetU8(offset_to_triangle + 0x4 + j * 0x14 + 0x09) / 256.0f, file->GetU8(offset_to_triangle + 0x4 + j * 0x14 + 0x0a) / 256.0f, file->GetU8(offset_to_triangle + 0x4 + j * 0x14 + 0x0b) / 256.0f); Ogre::ColourValue b_colour = Ogre::ColourValue(file->GetU8(offset_to_triangle + 0x4 + j * 0x14 + 0x0c) / 256.0f, file->GetU8(offset_to_triangle + 0x4 + j * 0x14 + 0x0d) / 256.0f, file->GetU8(offset_to_triangle + 0x4 + j * 0x14 + 0x0e) / 256.0f, file->GetU8(offset_to_triangle + 0x4 + j * 0x14 + 0x0f) / 256.0f); Ogre::ColourValue c_colour = Ogre::ColourValue(file->GetU8(offset_to_triangle + 0x4 + j * 0x14 + 0x10) / 256.0f, file->GetU8(offset_to_triangle + 0x4 + j * 0x14 + 0x11) / 256.0f, file->GetU8(offset_to_triangle + 0x4 + j * 0x14 + 0x12) / 256.0f, file->GetU8(offset_to_triangle + 0x4 + j * 0x14 + 0x13) / 256.0f); rs->convertColourValue(a_colour, colours + cur_index + 0); rs->convertColourValue(c_colour, colours + cur_index + 1); rs->convertColourValue(b_colour, colours + cur_index + 2); idata[cur_index + 0] = cur_index + 0; idata[cur_index + 1] = cur_index + 1; idata[cur_index + 2] = cur_index + 2; cur_index += 3; } // add color quad for (int j = 0; j < number_of_quad; ++j) { int offset_a = file->GetU16LE(offset_to_quad + 0x4 + j * 0x18 + 0x0); int offset_b = file->GetU16LE(offset_to_quad + 0x4 + j * 0x18 + 0x2); int offset_c = file->GetU16LE(offset_to_quad + 0x4 + j * 0x18 + 0x4); int offset_d = file->GetU16LE(offset_to_quad + 0x4 + j * 0x18 + 0x6); Ogre::Vector3 a((s16)file->GetU16LE(offset_to_vertex + 0x04 + offset_a + 00), (s16)file->GetU16LE(offset_to_vertex + 0x04 + offset_a + 02), (s16)file->GetU16LE(offset_to_vertex + 0x04 + offset_a + 04)); Ogre::Vector3 b((s16)file->GetU16LE(offset_to_vertex + 0x04 + offset_b + 00), (s16)file->GetU16LE(offset_to_vertex + 0x04 + offset_b + 02), (s16)file->GetU16LE(offset_to_vertex + 0x04 + offset_b + 04)); Ogre::Vector3 c((s16)file->GetU16LE(offset_to_vertex + 0x04 + offset_c + 00), (s16)file->GetU16LE(offset_to_vertex + 0x04 + offset_c + 02), (s16)file->GetU16LE(offset_to_vertex + 0x04 + offset_c + 04)); Ogre::Vector3 d((s16)file->GetU16LE(offset_to_vertex + 0x04 + offset_d + 00), (s16)file->GetU16LE(offset_to_vertex + 0x04 + offset_d + 02), (s16)file->GetU16LE(offset_to_vertex + 0x04 + offset_d + 04)); a /= 512; b /= 512; c /= 512; d /= 512; TexForGen texture; texture.palette_x = 0; texture.palette_y = 0; texture.texture_x = 0; texture.texture_y = 0; texture.bpp = BPP_BLACK; AddTexture( texture, mesh_data, textures, LOGGER ); Ogre::Vector2 at(0, 0); Ogre::Vector2 bt(0, 0); Ogre::Vector2 ct(0, 0); Ogre::Vector2 dt(0, 0); at.x = bt.x = ct.x = dt.x = texture.start_x / (float)mesh_data.tex_width; at.y = bt.y = ct.y = dt.y = texture.start_y / (float)mesh_data.tex_height; *pPos++ = a.x; *pPos++ = a.y; *pPos++ = a.z; *pPos++ = c.x; *pPos++ = c.y; *pPos++ = c.z; *pPos++ = b.x; *pPos++ = b.y; *pPos++ = b.z; *pPos++ = b.x; *pPos++ = b.y; *pPos++ = b.z; *pPos++ = c.x; *pPos++ = c.y; *pPos++ = c.z; *pPos++ = d.x; *pPos++ = d.y; *pPos++ = d.z; *tPos++ = at.x; *tPos++ = at.y; *tPos++ = ct.x; *tPos++ = ct.y; *tPos++ = bt.x; *tPos++ = bt.y; *tPos++ = bt.x; *tPos++ = bt.y; *tPos++ = ct.x; *tPos++ = ct.y; *tPos++ = dt.x; *tPos++ = dt.y; Ogre::ColourValue a_colour = Ogre::ColourValue(file->GetU8(offset_to_quad + 0x4 + j * 0x18 + 0x08) / 256.0f, file->GetU8(offset_to_quad + 0x4 + j * 0x18 + 0x09) / 256.0f, file->GetU8(offset_to_quad + 0x4 + j * 0x18 + 0x0a) / 256.0f, file->GetU8(offset_to_quad + 0x4 + j * 0x18 + 0x0b) / 256.0f); Ogre::ColourValue b_colour = Ogre::ColourValue(file->GetU8(offset_to_quad + 0x4 + j * 0x18 + 0x0c) / 256.0f, file->GetU8(offset_to_quad + 0x4 + j * 0x18 + 0x0d) / 256.0f, file->GetU8(offset_to_quad + 0x4 + j * 0x18 + 0x0e) / 256.0f, file->GetU8(offset_to_quad + 0x4 + j * 0x18 + 0x0f) / 256.0f); Ogre::ColourValue c_colour = Ogre::ColourValue(file->GetU8(offset_to_quad + 0x4 + j * 0x18 + 0x10) / 256.0f, file->GetU8(offset_to_quad + 0x4 + j * 0x18 + 0x11) / 256.0f, file->GetU8(offset_to_quad + 0x4 + j * 0x18 + 0x12) / 256.0f, file->GetU8(offset_to_quad + 0x4 + j * 0x18 + 0x13) / 256.0f); Ogre::ColourValue d_colour = Ogre::ColourValue(file->GetU8(offset_to_quad + 0x4 + j * 0x18 + 0x14) / 256.0f, file->GetU8(offset_to_quad + 0x4 + j * 0x18 + 0x15) / 256.0f, file->GetU8(offset_to_quad + 0x4 + j * 0x18 + 0x16) / 256.0f, file->GetU8(offset_to_quad + 0x4 + j * 0x18 + 0x17) / 256.0f); rs->convertColourValue(a_colour, colours + cur_index + 0); rs->convertColourValue(c_colour, colours + cur_index + 1); rs->convertColourValue(b_colour, colours + cur_index + 2); rs->convertColourValue(b_colour, colours + cur_index + 3); rs->convertColourValue(c_colour, colours + cur_index + 4); rs->convertColourValue(d_colour, colours + cur_index + 5); idata[cur_index + 0] = cur_index + 0; idata[cur_index + 1] = cur_index + 1; idata[cur_index + 2] = cur_index + 2; idata[cur_index + 3] = cur_index + 3; idata[cur_index + 4] = cur_index + 4; idata[cur_index + 5] = cur_index + 5; cur_index += 6; } vbuf0->unlock(); vbuf1->writeData(0, vbuf1->getSizeInBytes(), colours, true); vbuf2->unlock(); sub_mesh->indexData->indexBuffer->unlock(); // Optimize index data sub_mesh->indexData->optimiseVertexCacheTriList(); if (bone_id != -1) { LOGGER->Log("Assign bones to vertexes\n"); int vertex_number = sub_mesh->vertexData->vertexCount; for( int i = 0; i < vertex_number; ++i ) { Ogre::VertexBoneAssignment vba; vba.vertexIndex = i; vba.boneIndex = bone_id; vba.weight = 1.0f; sub_mesh->addBoneAssignment( vba ); } } }
void Mesh::_createGeometry() { int& Complexity = mOptions.MeshComplexity; int numVertices = Complexity*Complexity; int numEle = 6 * (Complexity-1)*(Complexity-1); // Vertex buffers mSubMesh->vertexData = new Ogre::VertexData(); mSubMesh->vertexData->vertexStart = 0; mSubMesh->vertexData->vertexCount = numVertices; Ogre::VertexDeclaration* vdecl = mSubMesh->vertexData->vertexDeclaration; Ogre::VertexBufferBinding* vbind = mSubMesh->vertexData->vertexBufferBinding; size_t offset = 0; switch (mOptions.MeshVertexType) { case VT_POS_NORM_UV: { vdecl->addElement(0, 0, Ogre::VET_FLOAT3, Ogre::VES_POSITION); offset += Ogre::VertexElement::getTypeSize(Ogre::VET_FLOAT3); vdecl->addElement(0, offset, Ogre::VET_FLOAT3, Ogre::VES_NORMAL); offset += Ogre::VertexElement::getTypeSize(Ogre::VET_FLOAT3); vdecl->addElement(0, offset, Ogre::VET_FLOAT2, Ogre::VES_TEXTURE_COORDINATES); mVertexBuffer = Ogre::HardwareBufferManager::getSingleton(). createVertexBuffer(sizeof(POS_NORM_UV_VERTEX), numVertices, Ogre::HardwareBuffer::HBU_DYNAMIC_WRITE_ONLY); } break; case VT_POS_NORM: { vdecl->addElement(0, 0, Ogre::VET_FLOAT3, Ogre::VES_POSITION); offset += Ogre::VertexElement::getTypeSize(Ogre::VET_FLOAT3); vdecl->addElement(0, offset, Ogre::VET_FLOAT3, Ogre::VES_NORMAL); mVertexBuffer = Ogre::HardwareBufferManager::getSingleton(). createVertexBuffer(sizeof(POS_NORM_VERTEX), numVertices, Ogre::HardwareBuffer::HBU_DYNAMIC_WRITE_ONLY); } break; case VT_POS_UV: { vdecl->addElement(0, 0, Ogre::VET_FLOAT3, Ogre::VES_POSITION); offset += Ogre::VertexElement::getTypeSize(Ogre::VET_FLOAT3); vdecl->addElement(0, offset, Ogre::VET_FLOAT2, Ogre::VES_TEXTURE_COORDINATES); mVertexBuffer = Ogre::HardwareBufferManager::getSingleton(). createVertexBuffer(sizeof(POS_UV_VERTEX), numVertices, Ogre::HardwareBuffer::HBU_DYNAMIC_WRITE_ONLY); } break; case VT_POS: { vdecl->addElement(0, 0, Ogre::VET_FLOAT3, Ogre::VES_POSITION); mVertexBuffer = Ogre::HardwareBufferManager::getSingleton(). createVertexBuffer(sizeof(POS_VERTEX), numVertices, Ogre::HardwareBuffer::HBU_DYNAMIC_WRITE_ONLY); } break; } vbind->setBinding(0, mVertexBuffer); unsigned int *indexbuffer = new unsigned int[numEle]; int i = 0; for(int v=0; v<Complexity-1; v++){ for(int u=0; u<Complexity-1; u++){ // face 1 |/ indexbuffer[i++] = v*Complexity + u; indexbuffer[i++] = v*Complexity + u + 1; indexbuffer[i++] = (v+1)*Complexity + u; // face 2 /| indexbuffer[i++] = (v+1)*Complexity + u; indexbuffer[i++] = v*Complexity + u + 1; indexbuffer[i++] = (v+1)*Complexity + u + 1; } } // Prepare buffer for indices mIndexBuffer = Ogre::HardwareBufferManager::getSingleton().createIndexBuffer( Ogre::HardwareIndexBuffer::IT_32BIT, numEle, Ogre::HardwareBuffer::HBU_STATIC, true); mIndexBuffer-> writeData(0, mIndexBuffer->getSizeInBytes(), indexbuffer, true); delete []indexbuffer; // Set index buffer for this submesh mSubMesh->indexData->indexBuffer = mIndexBuffer; mSubMesh->indexData->indexStart = 0; mSubMesh->indexData->indexCount = numEle; }
//------------------------------------------------------------------------------------------------ void DebugLines::draw() { if (_drawn || _points.empty()) return; else _drawn = true; // Initialization stuff mRenderOp.vertexData->vertexCount = _points.size(); Ogre::VertexDeclaration *decl = mRenderOp.vertexData->vertexDeclaration; Ogre::VertexBufferBinding *bind = mRenderOp.vertexData->vertexBufferBinding; HardwareVertexBufferSharedPtr vbuf; if(decl->getElementCount() == 0) { decl->addElement(0, 0, VET_FLOAT3, VES_POSITION); decl->addElement(0, 12, VET_FLOAT1, VES_TEXTURE_COORDINATES); if ( mHasColours ) decl->addElement(0, 16, VET_COLOUR, VES_DIFFUSE); vbuf = HardwareBufferManager::getSingleton().createVertexBuffer( decl->getVertexSize(0), mRenderOp.vertexData->vertexCount, HardwareBuffer::HBU_DYNAMIC_WRITE_ONLY_DISCARDABLE); bind->setBinding(0, vbuf); } else { bind->unsetAllBindings(); vbuf = HardwareBufferManager::getSingleton().createVertexBuffer( decl->getVertexSize(0), mRenderOp.vertexData->vertexCount, HardwareBuffer::HBU_DYNAMIC_WRITE_ONLY_DISCARDABLE); bind->setBinding(0, vbuf); } // Drawing stuff unsigned int size = (unsigned int)_points.size(); Ogre::Vector3 vaabMin = _points[0]; Ogre::Vector3 vaabMax = _points[0]; float *prPos = static_cast<float*>(vbuf->lock(HardwareBuffer::HBL_DISCARD)); for(unsigned int i = 0; i < size; i++) { *prPos++ = _points[i].x; *prPos++ = _points[i].y; *prPos++ = _points[i].z; *prPos++ = 0; if ( mHasColours ) { unsigned int* colorPtr = reinterpret_cast<unsigned int*>(prPos++); Ogre::ColourValue col = _colours[i]; //col.setHSB( (float)(i%256)/256.0f, 1.0f, 1.0f ); Ogre::Root::getSingleton().convertColourValue(col, colorPtr); } if (_points[i].x < vaabMin.x) vaabMin.x = _points[i].x; else if (_points[i].x > vaabMax.x) vaabMax.x = _points[i].x; if (_points[i].y < vaabMin.y) vaabMin.y = _points[i].y; else if (_points[i].y > vaabMax.y) vaabMax.y = _points[i].y; if (_points[i].z < vaabMin.z) vaabMin.z = _points[i].z; else if (_points[i].z > vaabMax.z) vaabMax.z = _points[i].z; } vbuf->unlock(); mBox.setInfinite(); //mBox.Extents(vaabMin, vaabMax); }
void Line3D::drawLines() { // Declarations Ogre::VertexDeclaration* pDeclaration; Ogre::VertexBufferBinding* pBinding; Ogre::HardwareVertexBufferSharedPtr vbuf; if (m_bDrawn) return; else m_bDrawn = true; // Initialization stuff mRenderOp.indexData = 0; mRenderOp.vertexData->vertexCount = m_points.size(); mRenderOp.vertexData->vertexStart = 0; mRenderOp.operationType = Ogre::RenderOperation::OT_LINE_STRIP; mRenderOp.useIndexes = false; pDeclaration = mRenderOp.vertexData->vertexDeclaration; pBinding = mRenderOp.vertexData->vertexBufferBinding; pDeclaration->addElement(0, 0, Ogre::VET_FLOAT3, Ogre::VES_POSITION); vbuf = Ogre::HardwareBufferManager::getSingleton().createVertexBuffer( pDeclaration->getVertexSize(0), mRenderOp.vertexData->vertexCount, Ogre::HardwareBuffer::HBU_STATIC_WRITE_ONLY); pBinding->setBinding(0, vbuf); // Drawing stuff int size = (int) m_points.size(); Vector3 vaabMin = m_points[0]; Vector3 vaabMax = m_points[0]; Real* prPos = static_cast<Real*>(vbuf->lock(Ogre::HardwareBuffer::HBL_DISCARD)); for (int i = 0; i < size; ++i) { *prPos++ = m_points[i].x; *prPos++ = m_points[i].y; *prPos++ = m_points[i].z; if(m_points[i].x < vaabMin.x) vaabMin.x = m_points[i].x; if(m_points[i].y < vaabMin.y) vaabMin.y = m_points[i].y; if(m_points[i].z < vaabMin.z) vaabMin.z = m_points[i].z; if(m_points[i].x > vaabMax.x) vaabMax.x = m_points[i].x; if(m_points[i].y > vaabMax.y) vaabMax.y = m_points[i].y; if(m_points[i].z > vaabMax.z) vaabMax.z = m_points[i].z; } vbuf->unlock(); mBox.setExtents(vaabMin.x, vaabMin.y, vaabMin.z, vaabMax.x, vaabMax.y, vaabMax.z); }
EntityCollision::EntityCollision() { mRenderOp.vertexData = new Ogre::VertexData(); mRenderOp.indexData = 0; mRenderOp.vertexData->vertexCount = 74; mRenderOp.vertexData->vertexStart = 0; mRenderOp.operationType = Ogre::RenderOperation::OT_LINE_LIST; mRenderOp.useIndexes = false; Ogre::VertexDeclaration* decl = mRenderOp.vertexData->vertexDeclaration; Ogre::VertexBufferBinding* bind = mRenderOp.vertexData->vertexBufferBinding; decl->addElement( 0, 0, Ogre::VET_FLOAT3, Ogre::VES_POSITION ); Ogre::HardwareVertexBufferSharedPtr vbuf0 = Ogre::HardwareBufferManager::getSingleton().createVertexBuffer( decl->getVertexSize( 0 ), mRenderOp.vertexData->vertexCount, Ogre::HardwareBuffer::HBU_STATIC_WRITE_ONLY ); bind->setBinding( 0, vbuf0 ); float* pPos = static_cast< float* >( vbuf0->lock( Ogre::HardwareBuffer::HBL_DISCARD ) ); *pPos++ = -1.0f; *pPos++ = 0.0f; *pPos++ = 0.0f; *pPos++ = -1.0f; *pPos++ = 0.0f; *pPos++ = 1.0f; *pPos++ = -1.0f; *pPos++ = 0.0f; *pPos++ = 0.0f; *pPos++ = -0.9f; *pPos++ = 0.5f; *pPos++ = 0.0f; *pPos++ = -0.9f; *pPos++ = 0.5f; *pPos++ = 0.0f; *pPos++ = -0.9f; *pPos++ = 0.5f; *pPos++ = 1.0f; *pPos++ = -0.9f; *pPos++ = 0.5f; *pPos++ = 1.0f; *pPos++ = -1.0f; *pPos++ = 0.0f; *pPos++ = 1.0f; *pPos++ = -0.9f; *pPos++ = 0.5f; *pPos++ = 0.0f; *pPos++ = -0.5f; *pPos++ = 0.9f; *pPos++ = 0.0f; *pPos++ = -0.5f; *pPos++ = 0.9f; *pPos++ = 0.0f; *pPos++ = -0.5f; *pPos++ = 0.9f; *pPos++ = 1.0f; *pPos++ = -0.5f; *pPos++ = 0.9f; *pPos++ = 1.0f; *pPos++ = -0.9f; *pPos++ = 0.5f;*pPos++ = 1.0f; *pPos++ = -0.5f; *pPos++ = 0.9f; *pPos++ = 0.0f; *pPos++ = 0.0f; *pPos++ = 1.0f; *pPos++ = 0.0f; *pPos++ = 0.0f; *pPos++ = 1.0f; *pPos++ = 0.0f; *pPos++ = 0.0f; *pPos++ = 1.0f; *pPos++ = 1.0f; *pPos++ = 0.0f; *pPos++ = 1.0f; *pPos++ = 1.0f; *pPos++ = -0.5f; *pPos++ = 0.9f; *pPos++ = 1.0f; *pPos++ = 0.0f; *pPos++ = 1.0f; *pPos++ = 0.0f; *pPos++ = 0.5f; *pPos++ = 0.9f; *pPos++ = 0.0f; *pPos++ = 0.5f; *pPos++ = 0.9f; *pPos++ = 0.0f; *pPos++ = 0.5f; *pPos++ = 0.9f; *pPos++ = 1.0f; *pPos++ = 0.5f; *pPos++ = 0.9f; *pPos++ = 1.0f; *pPos++ = 0.0f; *pPos++ = 1.0f; *pPos++ = 1.0f; *pPos++ = 0.5f; *pPos++ = 0.9f; *pPos++ = 0.0f; *pPos++ = 0.9f; *pPos++ = 0.5f; *pPos++ = 0.0f; *pPos++ = 0.9f; *pPos++ = 0.5f; *pPos++ = 0.0f; *pPos++ = 0.9f; *pPos++ = 0.5f; *pPos++ = 1.0f; *pPos++ = 0.9f; *pPos++ = 0.5f; *pPos++ = 1.0f; *pPos++ = 0.5f; *pPos++ = 0.9f; *pPos++ = 1.0f; *pPos++ = 0.9f; *pPos++ = 0.5f; *pPos++ = 0.0f; *pPos++ = 1.0f; *pPos++ = 0.0f; *pPos++ = 0.0f; *pPos++ = 1.0f; *pPos++ = 0.0f; *pPos++ = 0.0f; *pPos++ = 1.0f; *pPos++ = 0.0f; *pPos++ = 1.0f; *pPos++ = 1.0f; *pPos++ = 0.0f; *pPos++ = 1.0f; *pPos++ = 0.9f; *pPos++ = 0.5f; *pPos++ = 1.0f; *pPos++ = -1.0f; *pPos++ = 0.0f; *pPos++ = 0.0f; *pPos++ = -0.9f; *pPos++ = -0.5f; *pPos++ = 0.0f; *pPos++ = -0.9f; *pPos++ = -0.5f; *pPos++ = 0.0f; *pPos++ = -0.9f; *pPos++ = -0.5f; *pPos++ = 1.0f; *pPos++ = -0.9f; *pPos++ = -0.5f; *pPos++ = 1.0f; *pPos++ = -1.0f; *pPos++ = 0.0f; *pPos++ = 1.0f; *pPos++ = -0.9f; *pPos++ = -0.5f; *pPos++ = 0.0f; *pPos++ = -0.5f; *pPos++ = -0.9f; *pPos++ = 0.0f; *pPos++ = -0.5f; *pPos++ = -0.9f; *pPos++ = 0.0f; *pPos++ = -0.5f; *pPos++ = -0.9f; *pPos++ = 1.0f; *pPos++ = -0.5f; *pPos++ = -0.9f; *pPos++ = 1.0f; *pPos++ = -0.9f; *pPos++ = -0.5f; *pPos++ = 1.0f; *pPos++ = -0.5f; *pPos++ = -0.9f; *pPos++ = 0.0f; *pPos++ = 0.0f; *pPos++ = -1.0f; *pPos++ = 0.0f; *pPos++ = 0.0f; *pPos++ = -1.0f; *pPos++ = 0.0f; *pPos++ = 0.0f; *pPos++ = -1.0f; *pPos++ = 1.0f; *pPos++ = 0.0f; *pPos++ = -1.0f; *pPos++ = 1.0f; *pPos++ = -0.5f; *pPos++ = -0.9f; *pPos++ = 1.0f; *pPos++ = 0.0f; *pPos++ = -1.0f; *pPos++ = 0.0f; *pPos++ = 0.5f; *pPos++ = -0.9f; *pPos++ = 0.0f; *pPos++ = 0.5f; *pPos++ = -0.9f; *pPos++ = 0.0f; *pPos++ = 0.5f; *pPos++ = -0.9f; *pPos++ = 1.0f; *pPos++ = 0.5f; *pPos++ = -0.9f; *pPos++ = 1.0f; *pPos++ = 0.0f; *pPos++ = -1.0f; *pPos++ = 1.0f; *pPos++ = 0.5f; *pPos++ = -0.9f; *pPos++ = 0.0f; *pPos++ = 0.9f; *pPos++ = -0.5f; *pPos++ = 0.0f; *pPos++ = 0.9f; *pPos++ = -0.5f; *pPos++ = 0.0f; *pPos++ = 0.9f; *pPos++ = -0.5f; *pPos++ = 1.0f; *pPos++ = 0.9f; *pPos++ = -0.5f; *pPos++ = 1.0f; *pPos++ = 0.5f; *pPos++ = -0.9f; *pPos++ = 1.0f; *pPos++ = 0.9f; *pPos++ = -0.5f; *pPos++ = 0.0f; *pPos++ = 1.0f; *pPos++ = 0.0f; *pPos++ = 0.0f; *pPos++ = 1.0f; *pPos++ = 0.0f; *pPos++ = 0.0f; *pPos++ = 1.0f; *pPos++ = 0.0f; *pPos++ = 1.0f; *pPos++ = 1.0f; *pPos++ = 0.0f; *pPos++ = 1.0f; *pPos++ = 0.9f; *pPos++ = -0.5f; *pPos++ = 1.0f; vbuf0->unlock(); Ogre::AxisAlignedBox aabb; aabb.setInfinite(); setBoundingBox( aabb ); }
Mesh* OgreSubsystem::createMesh(const MeshData& data,String name) { String nombre = name; if(name=="AUTO_NAME_ME") { nombre = "OryxSceneNodeAutoNamed"+StringUtils::toString(mAutoNameIndex); ++mAutoNameIndex; } using namespace Ogre; bool hasVertexColor = data.getDiffuse(); bool hasNormals = data.getNormals(); int numFaces = data.indices.size()/3; int numVertices = data.vertices.size()/3; HardwareVertexBufferSharedPtr posVertexBuffer; HardwareVertexBufferSharedPtr normVertexBuffer; std::vector<HardwareVertexBufferSharedPtr> texcoordsVertexBuffer; HardwareVertexBufferSharedPtr diffuseVertexBuffer; HardwareIndexBufferSharedPtr indexBuffer; Ogre::Mesh* m = Ogre::MeshManager::getSingletonPtr()->createManual( nombre,ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME).get(); Ogre::SubMesh* sm = m->createSubMesh(); sm->useSharedVertices = false; sm->vertexData = new VertexData(); sm->vertexData->vertexStart = 0; sm->vertexData->vertexCount = numVertices; Ogre::VertexDeclaration* vdecl = sm->vertexData->vertexDeclaration; Ogre::VertexBufferBinding* vbind = sm->vertexData->vertexBufferBinding; size_t bufferCount = 0; vdecl->addElement(bufferCount, 0, VET_FLOAT3, VES_POSITION); if(hasNormals) vdecl->addElement(++bufferCount, 0, VET_FLOAT3, VES_NORMAL); if(hasVertexColor) vdecl->addElement(++bufferCount, 0, VET_FLOAT4, VES_DIFFUSE); for(int i=0;i<data.texcoords.size();++i) vdecl->addElement(++bufferCount, 0, VET_FLOAT2, VES_TEXTURE_COORDINATES,i); bufferCount = 0; // Positions posVertexBuffer = HardwareBufferManager::getSingleton().createVertexBuffer( 3*sizeof(float),numVertices,Ogre::HardwareBuffer::HBU_DYNAMIC_WRITE_ONLY_DISCARDABLE); vbind->setBinding(bufferCount, posVertexBuffer); float* vertices = data.getVertices(); float* normals = data.getNormals(); float* diffuse = data.getDiffuse(); unsigned short* indices = data.getIndices(); posVertexBuffer->writeData(0,posVertexBuffer->getSizeInBytes(),vertices, true); // Normals if(hasNormals) { normVertexBuffer = HardwareBufferManager::getSingleton().createVertexBuffer( 3*sizeof(float),numVertices,HardwareBuffer::HBU_DYNAMIC_WRITE_ONLY_DISCARDABLE); vbind->setBinding(++bufferCount, normVertexBuffer); normVertexBuffer->writeData(0,normVertexBuffer->getSizeInBytes(),normals, true); } if(hasVertexColor) { diffuseVertexBuffer = HardwareBufferManager::getSingleton().createVertexBuffer( 4*sizeof(float),numVertices,HardwareBuffer::HBU_STATIC_WRITE_ONLY); vbind->setBinding(++bufferCount, diffuseVertexBuffer); diffuseVertexBuffer->writeData(0,diffuseVertexBuffer->getSizeInBytes(), diffuse, true); } // Texcoords for(int i=0;i<data.texcoords.size();++i) { texcoordsVertexBuffer.push_back(HardwareBufferManager::getSingleton().createVertexBuffer( 2*sizeof(float),numVertices,HardwareBuffer::HBU_STATIC_WRITE_ONLY)); vbind->setBinding(++bufferCount, texcoordsVertexBuffer[i]); texcoordsVertexBuffer[i]->writeData(0,sizeof(float)*data.texcoords[i].size(),&data.texcoords[i][0], false); } if(!data.indices.empty()) { // Prepare buffer for indices indexBuffer = HardwareBufferManager::getSingleton().createIndexBuffer( HardwareIndexBuffer::IT_16BIT,3*numFaces,HardwareBuffer::HBU_STATIC_WRITE_ONLY, true); //unsigned short *faceVertexIndices = (unsigned short*) //indexBuffer->lock(0, numFaces*3*2, HardwareBuffer::HBL_DISCARD); // Set index buffer for this submesh sm->indexData->indexBuffer = indexBuffer; sm->indexData->indexStart = 0; sm->indexData->indexCount = 3*numFaces; indexBuffer->writeData(0,indexBuffer->getSizeInBytes(),indices,true); } //vdecl->sort(); m->load(); m->touch(); m->_setBounds(AxisAlignedBox(data.bbox[0],data.bbox[1],data.bbox[2], data.bbox[3],data.bbox[4],data.bbox[5]), false); sm->setMaterialName("Terrain"); Ogre::Entity* ent = mSceneManager->createEntity(nombre,m->getName()); Ogre::SceneNode* node = mSceneManager->createSceneNode(nombre); node->attachObject(ent); ent->setCastShadows(false); Mesh* mm = new Mesh(nombre,node,ent); mSceneNodes.push_back(mm); return mm; }
void EMDOgre::createOgreMesh(EMDSubmesh *submesh, string mesh_name) { string ogre_mesh_name = mesh_name + "_" + submesh->getMaterialName(); Ogre::MeshPtr ogre_mesh = Ogre::MeshManager::getSingleton().createManual(ogre_mesh_name, XENOVIEWER_RESOURCE_GROUP); LibXenoverse::AABB mesh_aabb; mesh_aabb.reset(); if (skeleton) { ogre_mesh->setSkeletonName(skeleton->getName()); } // Create Vertex Pool vector<EMDVertex> submesh_vertices = submesh->getVertices(); const size_t nVertices = submesh_vertices.size(); const size_t nVertCount = 8; const size_t vbufCount = nVertCount*nVertices; float *vertices = (float *)malloc(sizeof(float)*vbufCount); for (size_t i = 0; i < nVertices; i++) { vertices[i*nVertCount] = submesh_vertices[i].x; vertices[i*nVertCount + 1] = submesh_vertices[i].y; vertices[i*nVertCount + 2] = submesh_vertices[i].z; vertices[i*nVertCount + 3] = submesh_vertices[i].nx; vertices[i*nVertCount + 4] = submesh_vertices[i].ny; vertices[i*nVertCount + 5] = submesh_vertices[i].nz; vertices[i*nVertCount + 6] = submesh_vertices[i].u; vertices[i*nVertCount + 7] = submesh_vertices[i].v; mesh_aabb.addPoint(submesh_vertices[i].x, submesh_vertices[i].y, submesh_vertices[i].z); } // Create Submeshes for each Triangle List vector<EMDTriangles> submesh_triangles = submesh->getTriangles(); for (size_t i = 0; i < submesh_triangles.size(); i++) { Ogre::SubMesh *sub = createOgreSubmesh(&submesh_triangles[i], ogre_mesh); } // Create Shared Vertex Data for all submeshes Ogre::VertexData *vertex_data = new Ogre::VertexData(); ogre_mesh->sharedVertexData = vertex_data; vertex_data->vertexCount = nVertices; Ogre::VertexDeclaration* decl = vertex_data->vertexDeclaration; size_t offset = 0; 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); Ogre::HardwareVertexBufferSharedPtr vbuf = Ogre::HardwareBufferManager::getSingleton().createVertexBuffer(offset, nVertices, Ogre::HardwareBuffer::HBU_STATIC_WRITE_ONLY); vbuf->writeData(0, vbuf->getSizeInBytes(), vertices, true); Ogre::VertexBufferBinding* bind = vertex_data->vertexBufferBinding; bind->setBinding(0, vbuf); // Create Bone Assignments if Skeleton name exists if (skeleton) { Ogre::Skeleton *ogre_skeleton = skeleton->getOgreSkeleton(); if (ogre_skeleton) { for (size_t i = 0; i < submesh_triangles.size(); i++) { EMDTriangles *triangles = &submesh_triangles[i]; vector<unsigned int> vertex_indices; size_t face_count = triangles->faces.size(); // Make a list of all vertex indices being used in the submesh vertex_indices.reserve(face_count); for (size_t j = 0; j < face_count; j++) { bool found = false; for (size_t k = 0; k < vertex_indices.size(); k++) { if (vertex_indices[k] == triangles->faces[j]) { found = true; break; } } if (!found) vertex_indices.push_back(triangles->faces[j]); } // Build Bone Mapping Table vector<unsigned short> bone_table; bone_table.resize(triangles->bone_names.size()); for (size_t j = 0; j < bone_table.size(); j++) { string bone_name = triangles->bone_names[j]; LOG_DEBUG("Bone Skin Table %d: %s\n", j, bone_name.c_str()); if (ogre_skeleton->hasBone(bone_name)) { Ogre::Bone *mBone = ogre_skeleton->getBone(bone_name); bone_table[j] = mBone->getHandle(); } else { LOG_DEBUG("Couldn't find %s in ogre skeleton!\n", bone_name.c_str()); } } // Add bone assignments to all the vertices that were found for (size_t j = 0; j < vertex_indices.size(); j++) { Ogre::VertexBoneAssignment vba; vba.vertexIndex = vertex_indices[j]; EMDVertex *vertex = &submesh_vertices[vba.vertexIndex]; for (size_t k = 0; k < 4; k++) { unsigned char bone_index = vertex->bone[3 - k]; float bone_weight = vertex->bone_weight[k]; if (bone_weight > 0.0f) { vba.boneIndex = bone_table[bone_index]; vba.weight = bone_weight; ogre_mesh->addBoneAssignment(vba); } } } } // Apply changes, build the buffer ogre_mesh->_compileBoneAssignments(); ogre_mesh->sharedVertexData->reorganiseBuffers(decl->getAutoOrganisedDeclaration(true, false, false)); } } //ogre_mesh->_setBounds(Ogre::AxisAlignedBox(mesh_aabb.start_x, mesh_aabb.start_y, mesh_aabb.start_z, mesh_aabb.end_x, mesh_aabb.end_y, mesh_aabb.end_z)); ogre_mesh->_setBounds(Ogre::AxisAlignedBox(-1000, -1000, -1000, 1000, 1000, 1000)); ogre_mesh->_setBoundingSphereRadius(mesh_aabb.sizeMax()); ogre_mesh->load(); free(vertices); created_meshes.push_back(ogre_mesh_name); }
void MeshExtractor( const MeshData& mesh_data, const Ogre::String& material_name, File* file, int offset_to_data, VectorTexForGen& textures, const Ogre::MeshPtr& mesh ) { File* file12 = new File( "./data/field/5/1b/1/12/1" ); u32 offset_to_clut_tex = 4 + file12->GetU32LE( 4 + 4 ) & 0x00ffffff; LOGGER->Log( "offset_to_clut_tex = \"" + HexToString( offset_to_clut_tex, 8, '0' ) + "\".\n" ); u32 offset_to_tx_ty = offset_to_clut_tex + file12->GetU8( 4 + 7 ) * 4; LOGGER->Log( "offset_to_tx_ty = \"" + HexToString( offset_to_tx_ty, 8, '0' ) + "\".\n" ); int number_of_monochrome_textured_quads = file->GetU16LE( offset_to_data + 0x02 ); int number_of_monochrome_textured_triangles = file->GetU16LE( offset_to_data + 0x04 ); int number_of_shaded_textured_quads = file->GetU16LE( offset_to_data + 0x06 ); int number_of_shaded_textured_triangles = file->GetU16LE( offset_to_data + 0x08 ); int number_of_gradated_quads = file->GetU16LE( offset_to_data + 0x0a ); int number_of_gradated_triangles = file->GetU16LE( offset_to_data + 0x0c ); int number_of_monochrome_quads = file->GetU16LE( offset_to_data + 0x0e ); int number_of_monochrome_triangles = file->GetU16LE( offset_to_data + 0x10 ); u32 pointer_to_vertex_groups = file->GetU32LE( offset_to_data + 0x14 ); u32 pointer_to_vertex_data = file->GetU32LE( offset_to_data + 0x18 ); u32 pointer_to_mesh_data = file->GetU32LE( offset_to_data + 0x1c ); u32 pointer_to_texture_data = file->GetU32LE( offset_to_data + 0x20 ); Ogre::SubMesh* sub_mesh = mesh->createSubMesh(/* name */); sub_mesh->setMaterialName( material_name ); sub_mesh->useSharedVertices = false; sub_mesh->operationType = Ogre::RenderOperation::OT_TRIANGLE_LIST; // Allocate and prepare vertex data sub_mesh->vertexData = new Ogre::VertexData(); sub_mesh->vertexData->vertexStart = 0; sub_mesh->vertexData->vertexCount = static_cast< size_t >( number_of_monochrome_textured_quads * 6 + number_of_monochrome_textured_triangles * 3/* + number_of_shaded_textured_quads * 6 + number_of_shaded_textured_triangles * 3 + number_of_gradated_quads * 6 + number_of_gradated_triangles * 3 + number_of_monochrome_quads * 6 + number_of_monochrome_triangles * 3*/ ); sub_mesh->indexData = new Ogre::IndexData(); sub_mesh->indexData->indexStart = 0; sub_mesh->indexData->indexCount = sub_mesh->vertexData->vertexCount; sub_mesh->indexData->indexBuffer = Ogre::HardwareBufferManager::getSingleton().createIndexBuffer( Ogre::HardwareIndexBuffer::IT_16BIT, sub_mesh->indexData->indexCount, Ogre::HardwareBuffer::HBU_STATIC_WRITE_ONLY ); u16* idata = static_cast< u16* >( sub_mesh->indexData->indexBuffer->lock( Ogre::HardwareBuffer::HBL_DISCARD ) ); u32 cur_index = 0; Ogre::VertexDeclaration* decl = sub_mesh->vertexData->vertexDeclaration; Ogre::VertexBufferBinding* bind = sub_mesh->vertexData->vertexBufferBinding; // 1st buffer decl->addElement( POSITION_BINDING, 0, Ogre::VET_FLOAT3, Ogre::VES_POSITION ); Ogre::HardwareVertexBufferSharedPtr vbuf0 = Ogre::HardwareBufferManager::getSingleton().createVertexBuffer( decl->getVertexSize( POSITION_BINDING ), sub_mesh->vertexData->vertexCount, Ogre::HardwareBuffer::HBU_STATIC_WRITE_ONLY ); bind->setBinding( POSITION_BINDING, vbuf0 ); // 2nd buffer decl->addElement( COLOUR_BINDING, 0, Ogre::VET_COLOUR, Ogre::VES_DIFFUSE ); Ogre::HardwareVertexBufferSharedPtr vbuf1 = Ogre::HardwareBufferManager::getSingleton().createVertexBuffer( decl->getVertexSize( COLOUR_BINDING ), sub_mesh->vertexData->vertexCount, Ogre::HardwareBuffer::HBU_STATIC_WRITE_ONLY ); // Set vertex buffer binding so buffer 1 is bound to our colour buffer bind->setBinding( COLOUR_BINDING, vbuf1 ); // 3rd buffer decl->addElement( TEXTURE_BINDING, 0, Ogre::VET_FLOAT2, Ogre::VES_TEXTURE_COORDINATES, 0 ); Ogre::HardwareVertexBufferSharedPtr vbuf2 = Ogre::HardwareBufferManager::getSingleton().createVertexBuffer( decl->getVertexSize( TEXTURE_BINDING ), sub_mesh->vertexData->vertexCount, Ogre::HardwareBuffer::HBU_STATIC_WRITE_ONLY ); bind->setBinding( TEXTURE_BINDING, vbuf2 ); float* pPos = static_cast< float* >( vbuf0->lock( Ogre::HardwareBuffer::HBL_DISCARD ) ); float* tPos = static_cast< float* >( vbuf2->lock( Ogre::HardwareBuffer::HBL_DISCARD ) ); Ogre::RenderSystem* rs = Ogre::Root::getSingleton().getRenderSystem(); std::vector<Ogre::RGBA> coloursVec(sub_mesh->vertexData->vertexCount); Ogre::RGBA* colours = coloursVec.data(); for( int i = 0; i < number_of_monochrome_textured_quads; ++i ) { int index_a = file->GetU16LE( pointer_to_mesh_data + 0x0 ); int index_b = file->GetU16LE( pointer_to_mesh_data + 0x2 ); int index_c = file->GetU16LE( pointer_to_mesh_data + 0x4 ); int index_d = file->GetU16LE( pointer_to_mesh_data + 0x6 ); Ogre::Vector3 a( ( s16 )file->GetU16LE( pointer_to_vertex_data + index_a * 0x8 + 0x0 ), ( s16 )file->GetU16LE( pointer_to_vertex_data + index_a * 0x8 + 0x2 ), ( s16 )file->GetU16LE( pointer_to_vertex_data + index_a * 0x8 + 0x4 ) ); Ogre::Vector3 b( ( s16 )file->GetU16LE( pointer_to_vertex_data + index_b * 0x8 + 0x0 ), ( s16 )file->GetU16LE( pointer_to_vertex_data + index_b * 0x8 + 0x2 ), ( s16 )file->GetU16LE( pointer_to_vertex_data + index_b * 0x8 + 0x4 ) ); Ogre::Vector3 c( ( s16 )file->GetU16LE( pointer_to_vertex_data + index_c * 0x8 + 0x0 ), ( s16 )file->GetU16LE( pointer_to_vertex_data + index_c * 0x8 + 0x2 ), ( s16 )file->GetU16LE( pointer_to_vertex_data + index_c * 0x8 + 0x4 ) ); Ogre::Vector3 d( ( s16 )file->GetU16LE( pointer_to_vertex_data + index_d * 0x8 + 0x0 ), ( s16 )file->GetU16LE( pointer_to_vertex_data + index_d * 0x8 + 0x2 ), ( s16 )file->GetU16LE( pointer_to_vertex_data + index_d * 0x8 + 0x4 ) ); a /= 512; b /= 512; c /= 512; d /= 512; int image_id = file->GetU8( pointer_to_mesh_data + 0x13 ); u16 blend = file12->GetU16LE( offset_to_clut_tex + image_id * 4 + 0 ); u16 clut = file12->GetU16LE( offset_to_clut_tex + image_id * 4 + 2 ); LOGGER->Log( "image_id = \"" + HexToString( image_id, 2, '0' ) + "\", clut = \"" + HexToString( clut, 4, '0' ) + "\", blend = \"" + HexToString( blend, 4, '0' ) + "\".\n" ); /* int clut_x = (clut & 0x003f) << 3; int clut_y = (clut & 0xffc0) >> 6; int bpp = (tpage >> 0x7) & 0x3; int vram_x = (tpage & 0xf) * 64; int vram_y = ((tpage & 0x10) >> 4) * 256; */ TexForGen texture; texture.palette_x = 128/*clut_x*/; texture.palette_y = 224/*clut_y*/; if( image_id == 1 ) { texture.texture_x = 768/*vram_x*/; } else { texture.texture_x = 832/*vram_x*/; } texture.texture_y = 256/*vram_y*/; texture.bpp = BPP_8/*bpp*/; AddTexture( texture, mesh_data, textures, LOGGER ); Ogre::Vector2 at( 0, 0 ); Ogre::Vector2 bt( 0, 0 ); Ogre::Vector2 ct( 0, 0 ); Ogre::Vector2 dt( 0, 0 ); u16 vertex1_uv = file->GetU16LE( pointer_to_mesh_data + 0x8 ); at.x = ( file->GetU8( pointer_to_texture_data + vertex1_uv * 2 + 0x0 ) + texture.start_x ) / ( float )mesh_data.tex_width; at.y = ( file->GetU8( pointer_to_texture_data + vertex1_uv * 2 + 0x1 ) + texture.start_y ) / ( float )mesh_data.tex_height; u16 vertex2_uv = file->GetU16LE( pointer_to_mesh_data + 0xa ); bt.x = ( file->GetU8( pointer_to_texture_data + vertex2_uv * 2 + 0x0 ) + texture.start_x ) / ( float )mesh_data.tex_width; bt.y = ( file->GetU8( pointer_to_texture_data + vertex2_uv * 2 + 0x1 ) + texture.start_y ) / ( float )mesh_data.tex_height; u16 vertex3_uv = file->GetU16LE( pointer_to_mesh_data + 0xc ); ct.x = ( file->GetU8( pointer_to_texture_data + vertex3_uv * 2 + 0x0 ) + texture.start_x ) / ( float )mesh_data.tex_width; ct.y = ( file->GetU8( pointer_to_texture_data + vertex3_uv * 2 + 0x1 ) + texture.start_y ) / ( float )mesh_data.tex_height; u16 vertex4_uv = file->GetU16LE( pointer_to_mesh_data + 0xe ); dt.x = ( file->GetU8( pointer_to_texture_data + vertex4_uv * 2 + 0x0 ) + texture.start_x ) / ( float )mesh_data.tex_width; dt.y = ( file->GetU8( pointer_to_texture_data + vertex4_uv * 2 + 0x1 ) + texture.start_y ) / ( float )mesh_data.tex_height; *pPos++ = a.x; *pPos++ = a.y; *pPos++ = a.z; *pPos++ = c.x; *pPos++ = c.y; *pPos++ = c.z; *pPos++ = b.x; *pPos++ = b.y; *pPos++ = b.z; *pPos++ = b.x; *pPos++ = b.y; *pPos++ = b.z; *pPos++ = c.x; *pPos++ = c.y; *pPos++ = c.z; *pPos++ = d.x; *pPos++ = d.y; *pPos++ = d.z; *tPos++ = at.x; *tPos++ = at.y; *tPos++ = ct.x; *tPos++ = ct.y; *tPos++ = bt.x; *tPos++ = bt.y; *tPos++ = bt.x; *tPos++ = bt.y; *tPos++ = ct.x; *tPos++ = ct.y; *tPos++ = dt.x; *tPos++ = dt.y; Ogre::ColourValue colour = Ogre::ColourValue( file->GetU8( pointer_to_mesh_data + 0x10 ) / 256.0f, file->GetU8( pointer_to_mesh_data + 0x11 ) / 256.0f, file->GetU8( pointer_to_mesh_data + 0x12 ) / 256.0f, 1.0f ); rs->convertColourValue( colour, colours + cur_index + 0 ); rs->convertColourValue( colour, colours + cur_index + 1 ); rs->convertColourValue( colour, colours + cur_index + 2 ); rs->convertColourValue( colour, colours + cur_index + 3 ); rs->convertColourValue( colour, colours + cur_index + 4 ); rs->convertColourValue( colour, colours + cur_index + 5 ); idata[ cur_index + 0 ] = cur_index + 0; idata[ cur_index + 1 ] = cur_index + 1; idata[ cur_index + 2 ] = cur_index + 2; idata[ cur_index + 3 ] = cur_index + 3; idata[ cur_index + 4 ] = cur_index + 4; idata[ cur_index + 5 ] = cur_index + 5; Ogre::VertexBoneAssignment vba; vba.weight = 1.0f; vba.vertexIndex = cur_index + 0; vba.boneIndex = file->GetU8( pointer_to_vertex_data + index_a * 0x8 + 0x6 ) * 2 + 3; sub_mesh->addBoneAssignment( vba ); vba.vertexIndex = cur_index + 1; vba.boneIndex = file->GetU8( pointer_to_vertex_data + index_c * 0x8 + 0x6 ) * 2 + 3; sub_mesh->addBoneAssignment( vba ); vba.vertexIndex = cur_index + 2; vba.boneIndex = file->GetU8( pointer_to_vertex_data + index_b * 0x8 + 0x6 ) * 2 + 3; sub_mesh->addBoneAssignment( vba ); vba.vertexIndex = cur_index + 3; vba.boneIndex = file->GetU8( pointer_to_vertex_data + index_b * 0x8 + 0x6 ) * 2 + 3; sub_mesh->addBoneAssignment( vba ); vba.vertexIndex = cur_index + 4; vba.boneIndex = file->GetU8( pointer_to_vertex_data + index_c * 0x8 + 0x6 ) * 2 + 3; sub_mesh->addBoneAssignment( vba ); vba.vertexIndex = cur_index + 5; vba.boneIndex = file->GetU8( pointer_to_vertex_data + index_d * 0x8 + 0x6 ) * 2 + 3; sub_mesh->addBoneAssignment( vba ); cur_index += 6; pointer_to_mesh_data += 0x18; } for( int i = 0; i < number_of_monochrome_textured_triangles; ++i ) { int index_a = file->GetU16LE( pointer_to_mesh_data + 0x0 ); int index_b = file->GetU16LE( pointer_to_mesh_data + 0x2 ); int index_c = file->GetU16LE( pointer_to_mesh_data + 0x4 ); Ogre::Vector3 a( ( s16 )file->GetU16LE( pointer_to_vertex_data + index_a * 0x8 + 0x0 ), ( s16 )file->GetU16LE( pointer_to_vertex_data + index_a * 0x8 + 0x2 ), ( s16 )file->GetU16LE( pointer_to_vertex_data + index_a * 0x8 + 0x4 ) ); Ogre::Vector3 b( ( s16 )file->GetU16LE( pointer_to_vertex_data + index_b * 0x8 + 0x0 ), ( s16 )file->GetU16LE( pointer_to_vertex_data + index_b * 0x8 + 0x2 ), ( s16 )file->GetU16LE( pointer_to_vertex_data + index_b * 0x8 + 0x4 ) ); Ogre::Vector3 c( ( s16 )file->GetU16LE( pointer_to_vertex_data + index_c * 0x8 + 0x0 ), ( s16 )file->GetU16LE( pointer_to_vertex_data + index_c * 0x8 + 0x2 ), ( s16 )file->GetU16LE( pointer_to_vertex_data + index_c * 0x8 + 0x4 ) ); a /= 512; b /= 512; c /= 512; int image_id = file->GetU8( pointer_to_mesh_data + 0x6 ); u16 blend = file12->GetU16LE( offset_to_clut_tex + image_id * 4 + 0 ); u16 clut = file12->GetU16LE( offset_to_clut_tex + image_id * 4 + 2 ); LOGGER->Log( "image_id = \"" + HexToString( image_id, 2, '0' ) + "\", clut = \"" + HexToString( clut, 4, '0' ) + "\", blend = \"" + HexToString( blend, 4, '0' ) + "\".\n" ); /* int clut_x = (clut & 0x003f) << 3; int clut_y = (clut & 0xffc0) >> 6; int bpp = (tpage >> 0x7) & 0x3; int vram_x = (tpage & 0xf) * 64; int vram_y = ((tpage & 0x10) >> 4) * 256; */ TexForGen texture; texture.palette_x = 128/*clut_x*/; texture.palette_y = 224/*clut_y*/; if( image_id == 1 ) { texture.texture_x = 768/*vram_x*/; } else { texture.texture_x = 832/*vram_x*/; } texture.texture_y = 256/*vram_y*/; texture.bpp = BPP_8/*bpp*/; AddTexture( texture, mesh_data, textures, LOGGER ); Ogre::Vector2 at( 0, 0 ); Ogre::Vector2 bt( 0, 0 ); Ogre::Vector2 ct( 0, 0 ); u16 vertex1_uv = file->GetU16LE( pointer_to_mesh_data + 0xc ); at.x = ( file->GetU8( pointer_to_texture_data + vertex1_uv * 2 + 0x0 ) + texture.start_x ) / ( float )mesh_data.tex_width; at.y = ( file->GetU8( pointer_to_texture_data + vertex1_uv * 2 + 0x1 ) + texture.start_y ) / ( float )mesh_data.tex_height; u16 vertex2_uv = file->GetU16LE( pointer_to_mesh_data + 0xe ); bt.x = ( file->GetU8( pointer_to_texture_data + vertex2_uv * 2 + 0x0 ) + texture.start_x ) / ( float )mesh_data.tex_width; bt.y = ( file->GetU8( pointer_to_texture_data + vertex2_uv * 2 + 0x1 ) + texture.start_y ) / ( float )mesh_data.tex_height; u16 vertex3_uv = file->GetU16LE( pointer_to_mesh_data + 0x10 ); ct.x = ( file->GetU8( pointer_to_texture_data + vertex3_uv * 2 + 0x0 ) + texture.start_x ) / ( float )mesh_data.tex_width; ct.y = ( file->GetU8( pointer_to_texture_data + vertex3_uv * 2 + 0x1 ) + texture.start_y ) / ( float )mesh_data.tex_height; *pPos++ = a.x; *pPos++ = a.y; *pPos++ = a.z; *pPos++ = c.x; *pPos++ = c.y; *pPos++ = c.z; *pPos++ = b.x; *pPos++ = b.y; *pPos++ = b.z; *tPos++ = at.x; *tPos++ = at.y; *tPos++ = ct.x; *tPos++ = ct.y; *tPos++ = bt.x; *tPos++ = bt.y; Ogre::ColourValue colour = Ogre::ColourValue( file->GetU8( pointer_to_mesh_data + 0x08 ) / 256.0f, file->GetU8( pointer_to_mesh_data + 0x09 ) / 256.0f, file->GetU8( pointer_to_mesh_data + 0x0a ) / 256.0f, 1.0f ); rs->convertColourValue( colour, colours + cur_index + 0 ); rs->convertColourValue( colour, colours + cur_index + 1 ); rs->convertColourValue( colour, colours + cur_index + 2 ); idata[ cur_index + 0 ] = cur_index + 0; idata[ cur_index + 1 ] = cur_index + 1; idata[ cur_index + 2 ] = cur_index + 2; Ogre::VertexBoneAssignment vba; vba.weight = 1.0f; vba.vertexIndex = cur_index + 0; vba.boneIndex = file->GetU8( pointer_to_vertex_data + index_a * 0x8 + 0x6 ) * 2 + 3; sub_mesh->addBoneAssignment( vba ); vba.vertexIndex = cur_index + 1; vba.boneIndex = file->GetU8( pointer_to_vertex_data + index_c * 0x8 + 0x6 ) * 2 + 3; sub_mesh->addBoneAssignment( vba ); vba.vertexIndex = cur_index + 2; vba.boneIndex = file->GetU8( pointer_to_vertex_data + index_b * 0x8 + 0x6 ) * 2 + 3; sub_mesh->addBoneAssignment( vba ); cur_index += 3; pointer_to_mesh_data += 0x14; } vbuf0->unlock(); vbuf1->writeData( 0, vbuf1->getSizeInBytes(), colours, true ); vbuf2->unlock(); sub_mesh->indexData->indexBuffer->unlock(); // Optimize index data sub_mesh->indexData->optimiseVertexCacheTriList(); delete file12; }
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(); } }
void GeometryFactory::generateSphericDome (const Ogre::String &name, int segments, DomeType type) { // Return now if already exists if (Ogre::MeshManager::getSingleton ().resourceExists (name)) { return; } Ogre::LogManager::getSingleton ().logMessage ( "Caelum: Creating " + name + " sphere mesh resource..."); // Use the mesh manager to create the mesh Ogre::MeshPtr msh = Ogre::MeshManager::getSingleton ().createManual (name, RESOURCE_GROUP_NAME); // Create a submesh Ogre::SubMesh *sub = msh->createSubMesh (); // Create the shared vertex data Ogre::VertexData *vertexData = new Ogre::VertexData (); msh->sharedVertexData = vertexData; // Define the vertices' format Ogre::VertexDeclaration *vertexDecl = vertexData->vertexDeclaration; size_t currOffset = 0; // Position vertexDecl->addElement (0, currOffset, Ogre::VET_FLOAT3, Ogre::VES_POSITION); currOffset += Ogre::VertexElement::getTypeSize (Ogre::VET_FLOAT3); // Normal vertexDecl->addElement (0, currOffset, Ogre::VET_FLOAT3, Ogre::VES_NORMAL); currOffset += Ogre::VertexElement::getTypeSize (Ogre::VET_FLOAT3); // Texture coordinates vertexDecl->addElement (0, currOffset, Ogre::VET_FLOAT2, Ogre::VES_TEXTURE_COORDINATES, 0); currOffset += Ogre::VertexElement::getTypeSize (Ogre::VET_FLOAT2); // Allocate the vertex buffer switch (type) { case DT_GRADIENTS: vertexData->vertexCount = segments * (segments - 1) + 2; break; case DT_STARFIELD: vertexData->vertexCount = (segments + 1) * (segments + 1); break; }; Ogre::HardwareVertexBufferSharedPtr vBuf = Ogre::HardwareBufferManager::getSingleton ().createVertexBuffer (vertexDecl->getVertexSize (0), vertexData->vertexCount, Ogre::HardwareBuffer::HBU_STATIC_WRITE_ONLY, false); Ogre::VertexBufferBinding *binding = vertexData->vertexBufferBinding; binding->setBinding (0, vBuf); float *pVertex = static_cast<float *>(vBuf->lock (Ogre::HardwareBuffer::HBL_DISCARD)); // Allocate the index buffer switch (type) { case DT_GRADIENTS: sub->indexData->indexCount = 2 * segments * (segments - 1) * 3; break; case DT_STARFIELD: sub->indexData->indexCount = 2 * (segments - 1) * segments * 3; break; }; sub->indexData->indexBuffer = Ogre::HardwareBufferManager::getSingleton ().createIndexBuffer (Ogre::HardwareIndexBuffer::IT_16BIT, sub->indexData->indexCount, Ogre::HardwareBuffer::HBU_STATIC_WRITE_ONLY, false); Ogre::HardwareIndexBufferSharedPtr iBuf = sub->indexData->indexBuffer; unsigned short *pIndices = static_cast<unsigned short *>(iBuf->lock (Ogre::HardwareBuffer::HBL_DISCARD)); // Fill the buffers switch (type) { case DT_GRADIENTS: fillGradientsDomeBuffers (pVertex, pIndices, segments); break; case DT_STARFIELD: fillStarfieldDomeBuffers (pVertex, pIndices, segments); break; }; // Close the vertex buffer vBuf->unlock (); // Close the index buffer iBuf->unlock (); // Finishing it... sub->useSharedVertices = true; msh->_setBounds (Ogre::AxisAlignedBox (-1, -1, -1, 1, 1, 1), false); msh->_setBoundingSphereRadius (1); msh->load (); Ogre::LogManager::getSingleton ().logMessage ( "Caelum: generateSphericDome DONE"); }