Creating a manual mesh in Ogre3d?

I am a little confused as to why my manually created grid is not showing correctly. I created vertex and index buffers, and they seem (although I'm not 100% sure) to contain the correct values.

Essentially, I create a mapSize * mapSize vetrices grid at a height of 0, and then create triangles from them.

void TerrainGeneration::createTerrainMesh() { /// Create the mesh via the MeshManager Ogre::MeshPtr msh = Ogre::MeshManager::getSingleton().createManual("TerrainTest", "General"); Ogre::SubMesh* sub = msh->createSubMesh(); const size_t nVertices = mapSize*mapSize; const size_t vbufCount = 3*2*nVertices; float vertices[vbufCount]; size_t vBufCounter = 0; for(int z = 0; z < mapSize; z++) { for(int x = 0; x < mapSize; x++) { //Position vertices[vBufCounter] = x; vertices[vBufCounter+1] = 0; vertices[vBufCounter+2] = z; //Normal vertices[vBufCounter+3] = 0; vertices[vBufCounter+4] = 1; vertices[vBufCounter+5] = 0; vBufCounter += 6; } } Ogre::RenderSystem* rs = Ogre::Root::getSingleton().getRenderSystem(); Ogre::RGBA colours[nVertices]; Ogre::RGBA *pColour = colours; //Create triangles const size_t ibufCount = 6*(mapSize - 1)*(mapSize - 1); unsigned int faces[ibufCount]; size_t iBufCounter = 0; for(int x=0; x <= mapSize -2; x++) { for(int y=0; y <= mapSize -2; y++) { faces[iBufCounter] = vertices[(y*mapSize) + x]; faces[iBufCounter+1] = vertices[((y+1)*mapSize) + x]; faces[iBufCounter+2] = vertices[((y+1)*mapSize) + (x+1)]; faces[iBufCounter+3] = vertices[(y*mapSize) + x]; faces[iBufCounter+4] = vertices[((y+1)*mapSize) + (x+1)]; faces[iBufCounter+5] = vertices[(y*mapSize) + (x+1)]; iBufCounter += 6; } } /// Create vertex data structure for n*n vertices shared between submeshes msh->sharedVertexData = new Ogre::VertexData(); msh->sharedVertexData->vertexCount = nVertices; /// Create declaration (memory format) of vertex data Ogre::VertexDeclaration* decl = msh->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); /// Allocate vertex buffer of the requested number of vertices (vertexCount) /// and bytes per vertex (offset) Ogre::HardwareVertexBufferSharedPtr vbuf = Ogre::HardwareBufferManager::getSingleton().createVertexBuffer( offset, msh->sharedVertexData->vertexCount, Ogre::HardwareBuffer::HBU_STATIC_WRITE_ONLY); /// Upload the vertex data to the card vbuf->writeData(0, vbuf->getSizeInBytes(), vertices, true); /// Set vertex buffer binding so buffer 0 is bound to our vertex buffer Ogre::VertexBufferBinding* bind = msh->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, ibufCount, Ogre::HardwareBuffer::HBU_STATIC_WRITE_ONLY); /// Upload the index data to the card ibuf->writeData(0, ibuf->getSizeInBytes(), faces, true); /// Set parameters of the submesh sub->useSharedVertices = true; sub->indexData->indexBuffer = ibuf; sub->indexData->indexCount = ibufCount; sub->indexData->indexStart = 0; /// Set bounding information (for culling) msh->_setBounds(Ogre::AxisAlignedBox(-5000,-5000,-5000,5000,5000,5000)); //msh->_setBoundingSphereRadius(Ogre::Math::Sqrt(3*100*100)); /// Notify -Mesh object that it has been loaded msh->load(); } 

I initialize the grid and load it as follows

 Ogre::Entity* thisEntity = mSceneMgr->createEntity("cc", "TerrainTest", "General"); thisEntity->setMaterialName("Examples/Rockwall"); Ogre::SceneNode* thisSceneNode = mSceneMgr->getRootSceneNode()->createChildSceneNode(); thisSceneNode->setPosition(0, 0, 0); thisSceneNode->attachObject(thisEntity); 

Any understanding would be greatly appreciated.

+6
source share
1 answer

Ok, so I got a response from the Ogre3d forums from a very helpful person called bstone.

It turns out that when creating my index list for creating faces, I mistakenly passed the coordinates from the vertex list, not the vertex indices.

  faces[iBufCounter] = vertices[(y*mapSize) + x]; faces[iBufCounter+1] = vertices[((y+1)*mapSize) + x]; faces[iBufCounter+2] = vertices[((y+1)*mapSize) + (x+1)]; faces[iBufCounter+3] = vertices[(y*mapSize) + x]; faces[iBufCounter+4] = vertices[((y+1)*mapSize) + (x+1)]; faces[iBufCounter+5] = vertices[(y*mapSize) + (x+1)]; 

Must be

  faces[iBufCounter] = (y*mapSize) + x; faces[iBufCounter+1] = ((y+1)*mapSize) + x; faces[iBufCounter+2] = ((y+1)*mapSize) + (x+1); faces[iBufCounter+3] = (y*mapSize) + x; faces[iBufCounter+4] = ((y+1)*mapSize) + (x+1); faces[iBufCounter+5] = (y*mapSize) + (x+1); 

However, I still have a problem in my code somewhere, although from what others said it is probably not in this code that I posted.

Another user also suggested creating the landscape much easier and posted the following code

 int mapSize = 16; Ogre::ManualObject *man = m_sceneManager->createManualObject("TerrainTest"); man->begin("Examples/Rockwall",Ogre::RenderOperation::OT_TRIANGLE_LIST); for(int z = 0; z < mapSize; ++z) { for(int x = 0; x < mapSize; ++x) { man->position(x,0,z); man->normal(0,1,0); man->textureCoord(x,z); } } for(int z = 0; z < mapSize-1; ++z) { for(int x = 0; x < mapSize-1; ++x) { man->quad((x) + (z) * mapSize, (x) + (z + 1) * mapSize, (x + 1) + (z + 1) * mapSize, (x + 1) + (z) * mapSize); } } man->end(); m_sceneManager->getRootSceneNode()->attachObject(man); 
+5
source

Source: https://habr.com/ru/post/918833/


All Articles