void ReliefApp::GenerateRelief() { //Get depth data Ogre::TexturePtr depthTex = Ogre::TextureManager::getSingleton().createManual( "DepthTexture", // name Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, Ogre::TEX_TYPE_2D, // type 512, // width 512, // height 0, // number of mipmaps //Ogre::PF_B8G8R8A8, // pixel format Ogre::PF_FLOAT32_R, Ogre::TU_RENDERTARGET ); Ogre::RenderTarget* pTarget = depthTex->getBuffer()->getRenderTarget(); Ogre::Camera* pOrthCam = MagicCore::RenderSystem::GetSingleton()->GetMainCamera(); pOrthCam->setProjectionType(Ogre::PT_ORTHOGRAPHIC); pOrthCam->setOrthoWindow(3, 3); pOrthCam->setPosition(0, 0, 3); pOrthCam->lookAt(0, 0, 0); pOrthCam->setAspectRatio(1.0); pOrthCam->setNearClipDistance(0.5); pOrthCam->setFarClipDistance(5); Ogre::Viewport* pViewport = pTarget->addViewport(pOrthCam); pViewport->setDimensions(0, 0, 1, 1); MagicCore::RenderSystem::GetSingleton()->RenderLightMesh3D("RenderMesh", "Depth", mpLightMesh); MagicCore::RenderSystem::GetSingleton()->Update(); Ogre::Image img; depthTex->convertToImage(img); std::vector<double> heightField(512 * 512); for(int x = 0; x < 512; x++) { for(int y = 0; y < 512; y++) { heightField.at(x * 512 + y) = (img.getColourAt(x, 511 - y, 0))[1]; } } Ogre::TextureManager::getSingleton().remove("DepthTexture"); // MagicDGP::LightMesh3D* pReliefMesh = MagicDGP::ReliefGeneration::PlaneReliefFromHeightField(heightField, 511, 511); //MagicDGP::LightMesh3D* pReliefMesh = MagicDGP::ReliefGeneration::CylinderReliefFromHeightField(heightField, 511, 511); if (pReliefMesh != NULL) { delete mpLightMesh; mpLightMesh = pReliefMesh; mpLightMesh->UnifyPosition(2); mpLightMesh->UpdateNormal(); } MagicCore::RenderSystem::GetSingleton()->SetupCameraDefaultParameter(); MagicCore::RenderSystem::GetSingleton()->RenderLightMesh3D("RenderMesh", "MyCookTorrance", mpLightMesh); }
HRESULT initGeometry(){ LPD3DXBUFFER pD3DXMtrlBuffer; if(FAILED(D3DXLoadMeshFromX(L"seafloor.x", D3DXMESH_MANAGED, g_pDevice, NULL, &pD3DXMtrlBuffer, NULL, &g_dwNumMaterials, &g_pMesh))) return E_FAIL; //Extract material & texture D3DXMATERIAL* d3dxMaterials = (D3DXMATERIAL*)pD3DXMtrlBuffer->GetBufferPointer(); g_pMeshMaterials = new D3DMATERIAL9[g_dwNumMaterials]; if(g_pMeshMaterials == NULL) return E_OUTOFMEMORY; g_pMeshTextures = new LPDIRECT3DTEXTURE9[g_dwNumMaterials]; if(g_pMeshTextures == NULL) return E_OUTOFMEMORY; //Extract for(DWORD i=0; i<g_dwNumMaterials; ++i){ g_pMeshMaterials[i] = d3dxMaterials[i].MatD3D; g_pMeshMaterials[i].Ambient = g_pMeshMaterials[i].Diffuse; g_pMeshTextures[i] = NULL; if(d3dxMaterials[i].pTextureFilename != NULL && strlen(d3dxMaterials[i].pTextureFilename) > 0){ WCHAR name[256]; removePathFromFileName(d3dxMaterials[i].pTextureFilename, name); if(FAILED(D3DXCreateTextureFromFile(g_pDevice, name, &g_pMeshTextures[i]))){ MessageBox(NULL, L"Cound not find texture file", L"initGeometry()", MB_OK); } } } pD3DXMtrlBuffer->Release(); //Modify the mesh LPDIRECT3DVERTEXBUFFER9 pVB; if(SUCCEEDED(g_pMesh->GetVertexBuffer(&pVB))){ struct VERTEX{FLOAT x,y,z,tu,tv;}; VERTEX* pVertices; DWORD dwNumVertices = g_pMesh->GetNumVertices(); pVB->Lock(0,0,(void**)&pVertices, 0); for(DWORD i=0; i<dwNumVertices; ++i) pVertices[i].y = heightField(pVertices[i].x, pVertices[i].z); pVB->Unlock(); pVB->Release(); } return S_OK; };
TerrainRender::TerrainRender(boost::shared_ptr<Terrain> terrain) { rootNode_ = osg::ref_ptr<osg::PositionAttitudeTransform>( new osg::PositionAttitudeTransform); if (terrain->isFlat()) { // Generate a flat terrain osg::ref_ptr<osg::Shape> shape( new osg::Box(osg::Vec3(0, 0, -2.5), fromOde(terrain->getWidth()), fromOde(terrain->getDepth()), 5)); osg::ref_ptr<osg::ShapeDrawable> osgPlaneDrawable( new osg::ShapeDrawable(shape.get())); osg::ref_ptr<osg::Geode> osgGroundGeode(new osg::Geode()); osgGroundGeode->addDrawable(osgPlaneDrawable.get()); rootNode_->addChild(osgGroundGeode); } else { // Generate terrain from height field // 1) Load the height field unsigned int xPointsCount = terrain->getHeightFieldData()->s(); unsigned int yPointsCount = terrain->getHeightFieldData()->t(); osg::ref_ptr<osg::HeightField> heightField(new osg::HeightField); heightField->allocate(xPointsCount, yPointsCount); heightField->setOrigin(osg::Vec3(0, 0, 0)); heightField->setXInterval(fromOde(terrain->getWidth()) / xPointsCount); heightField->setXInterval(fromOde(terrain->getDepth()) / yPointsCount); heightField->setSkirtHeight(1.0f); // Copy height information to the glfloat array for (unsigned int i = 0; i < xPointsCount; ++i) { for (unsigned int j = 0; j < yPointsCount; ++j) { heightField->setHeight(i, j, ((*terrain->getHeightFieldData()->data(i, j)) / 255.0) * fromOde(terrain->getHeightFieldHeight())/2); } } // Create a terrain tile osg::ref_ptr<osgTerrain::Locator> terrainTileLocator( new osgTerrain::Locator()); terrainTileLocator->setCoordinateSystemType( osgTerrain::Locator::PROJECTED); terrainTileLocator->setTransformAsExtents(-fromOde(terrain->getWidth())/2, -fromOde(terrain->getDepth())/2, fromOde(terrain->getWidth())/2, fromOde(terrain->getDepth())/2); osg::ref_ptr<osgTerrain::HeightFieldLayer> heightFieldLayer = new osgTerrain::HeightFieldLayer(heightField.get()); heightFieldLayer->setLocator(terrainTileLocator); osg::ref_ptr<osgTerrain::GeometryTechnique> terrainGeomTechnique( new osgTerrain::GeometryTechnique()); osg::ref_ptr<osgTerrain::TerrainTile> terrainTile( new osgTerrain::TerrainTile()); terrainTile->setElevationLayer(heightFieldLayer.get()); terrainTile->setTerrainTechnique(terrainGeomTechnique.get()); // Generate an OSG terrain object osg::ref_ptr<osgTerrain::Terrain> osgTerrain(new osgTerrain::Terrain()); osgTerrain->setSampleRatio(1.0f); osgTerrain->addChild(terrainTile.get()); rootNode_->addChild(osgTerrain.get()); // Uncomment to debug terrain /*double minX, minY, minZ, maxX, maxY, maxZ; terrain->getBB(minX, maxX, minY, maxY, minZ, maxZ); std::cout << "Terrain AABB(minX, maxX, minY, maxY, minZ, maxZ) (" << minX << ", " << maxX << ", " << minY << ", " << maxY << ", " << minZ << ", " << maxZ << ")" << std::endl; osg::ref_ptr<osg::Shape> shape( new osg::Box(osg::Vec3(fromOde(minX + (maxX-minX)/2), fromOde(minY + (maxY-minY)/2), fromOde(minZ +(maxZ-minZ))/2), fromOde(maxX-minX), fromOde(maxY-minY), fromOde(maxZ-minZ))); osg::ref_ptr<osg::ShapeDrawable> osgPlaneDrawable( new osg::ShapeDrawable(shape.get())); osg::ref_ptr<osg::Geode> osgGroundGeode(new osg::Geode()); osgGroundGeode->addDrawable(osgPlaneDrawable.get()); rootNode_->addChild(osgGroundGeode);*/ } }