2012-06-23 36 views
6

Tôi nhận được một chút bối rối là tại sao lưới được tạo thủ công của tôi không xuất hiện chính xác. Tôi đã tạo ra các vertex và index buffer và chúng dường như (mặc dù tôi không chắc chắn 100%) để chứa các giá trị chính xác.Tạo lưới bằng tay trong Ogre3d?

Về bản chất tôi đang tạo một lưới bản đồSize * mapSize vetrices, ở độ cao 0, sau đó tạo các tam giác ra khỏi chúng.

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(); 

} 

tôi khởi lưới và tải nó như sau

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); 

Bất kỳ cái nhìn sâu sắc sẽ được đánh giá rất nhiều.

+0

Tôi không thể nói chuyện trực tiếp cho câu hỏi của bạn, nhưng đây là một ý nghĩ: Có lưới của bạn có được tất cả các tam giác định hướng chính xác? Đầu vào tam giác ABC nơi tam giác BAC là cần thiết, và bạn có thể nhầm lẫn nhiều động cơ lưới. – Managu

+0

Vâng tôi tin rằng hình tam giác của tôi là chính xác, Ogre đòi hỏi phải lựa chọn ngược chiều kim đồng hồ của các đỉnh cho một khuôn mặt. Tôi đã cố gắng chiều kim đồng hồ quá, chỉ cần incase. Vấn đề có vẻ là các đỉnh không được trải ra như tôi mong đợi nhưng tôi không thực sự chắc chắn tại sao. –

Trả lời

5

Ok vì vậy tôi đã nhận được câu trả lời ngoài diễn đàn Ogre3d từ một người rất hữu ích được gọi là bstone.

Nó chỉ ra rằng khi tạo danh sách chỉ mục của tôi để tạo các khuôn mặt tôi đã nhầm lẫn truyền tọa độ từ danh sách đỉnh thay vì chỉ mục của các đỉnh.

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)]; 

nên đã

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); 

Tuy nhiên tôi vẫn còn có một vấn đề trong mã của tôi ở đâu đó, mặc dù so với những gì người khác đã nói nó có lẽ không có trong mã này mà tôi đã đăng.

Một người dùng khác cũng đề nghị mà tôi tạo ra ina địa hình cách đơn giản hơn nhiều và đăng đoạn mã sau

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); 
Các vấn đề liên quan