osg::ref_ptr<osg::Node> TerrainGrid::buildTerrain (osg::Group* parent, float chunkSize, const osg::Vec2f& chunkCenter) { if (chunkSize * mNumSplits > 1.f) { // keep splitting osg::ref_ptr<osg::Group> group (new osg::Group); if (parent) parent->addChild(group); float newChunkSize = chunkSize/2.f; buildTerrain(group, newChunkSize, chunkCenter + osg::Vec2f(newChunkSize/2.f, newChunkSize/2.f)); buildTerrain(group, newChunkSize, chunkCenter + osg::Vec2f(newChunkSize/2.f, -newChunkSize/2.f)); buildTerrain(group, newChunkSize, chunkCenter + osg::Vec2f(-newChunkSize/2.f, newChunkSize/2.f)); buildTerrain(group, newChunkSize, chunkCenter + osg::Vec2f(-newChunkSize/2.f, -newChunkSize/2.f)); return group; } else { osg::ref_ptr<osg::Node> node = mChunkManager->getChunk(chunkSize, chunkCenter, 0, 0); if (!node) return NULL; if (parent) parent->addChild(node); return node; } }
Terrain* TerrainGenerator::getTerrain() { if (!_terrain || _isDirty) { buildTerrain(); } return _terrain; }
void TerrainGrid::loadCell(int x, int y) { if (mGrid.find(std::make_pair(x, y)) != mGrid.end()) return; // already loaded // try to get it from the cache osg::ref_ptr<osg::Node> terrainNode; { OpenThreads::ScopedLock<OpenThreads::Mutex> lock(mGridCacheMutex); Grid::const_iterator found = mGridCache.find(std::make_pair(x,y)); if (found != mGridCache.end()) { terrainNode = found->second; if (!terrainNode) return; // no terrain defined } } // didn't find in cache, build it if (!terrainNode) { osg::Vec2f center(x+0.5f, y+0.5f); terrainNode = buildTerrain(NULL, 1.f, center); if (!terrainNode) return; // no terrain defined } mTerrainRoot->addChild(terrainNode); mGrid[std::make_pair(x,y)] = terrainNode; }
osg::ref_ptr<osg::Node> TerrainGrid::cacheCell(int x, int y) { { OpenThreads::ScopedLock<OpenThreads::Mutex> lock(mGridCacheMutex); Grid::iterator found = mGridCache.find(std::make_pair(x,y)); if (found != mGridCache.end()) return found->second; } osg::ref_ptr<osg::Node> node = buildTerrain(NULL, 1.f, osg::Vec2f(x+0.5, y+0.5)); OpenThreads::ScopedLock<OpenThreads::Mutex> lock(mGridCacheMutex); mGridCache.insert(std::make_pair(std::make_pair(x,y), node)); return node; }
void TerrainGrid::loadCell(int x, int y) { if (mGrid.find(std::make_pair(x, y)) != mGrid.end()) return; // already loaded osg::Vec2f center(x+0.5f, y+0.5f); osg::ref_ptr<osg::Node> terrainNode = buildTerrain(NULL, 1.f, center); if (!terrainNode) return; // no terrain defined mTerrainRoot->addChild(terrainNode); mGrid[std::make_pair(x,y)] = terrainNode; }
PlatformDemoState::PlatformDemoState(xy::StateStack& stateStack, Context context) : State (stateStack, context), m_messageBus (context.appInstance.getMessageBus()), m_scene (m_messageBus), m_physWorld (m_messageBus), m_meshRenderer ({ context.appInstance.getVideoSettings().VideoMode.width, context.appInstance.getVideoSettings().VideoMode.height }, m_scene) { launchLoadingScreen(); xy::Stats::clear(); m_physWorld.setGravity({ 0.f, 1180.f }); m_physWorld.setPixelScale(120.f); m_scene.setView(context.defaultView); m_scene.setAmbientColour({ 76, 70, 72 }); m_scene.getSkyLight().setIntensity(0.5f); m_scene.getSkyLight().setDiffuseColour({ 255, 255, 200 }); m_scene.getSkyLight().setSpecularColour({ 120, 255, 58 }); m_scene.getSkyLight().setDirection({ 0.2f, 0.4f, -0.4f }); m_meshRenderer.setView(context.defaultView); cacheMeshes(); buildTerrain(); buildPhysics(); addItems(); addPlayer(); auto e = xy::Entity::create(m_messageBus); auto md = m_meshRenderer.createDrawable(m_messageBus); //md->enableWater(true); e->addComponent(md); m_scene.addEntity(e, xy::Scene::Layer::FrontFront); REPORT("Q", "Show Debug"); xy::App::setMouseCursorVisible(true); quitLoadingScreen(); }
void TerrainGrid::loadCell(int x, int y) { if (mGrid.find(std::make_pair(x, y)) != mGrid.end()) return; // already loaded osg::Vec2f center(x+0.5f, y+0.5f); osg::ref_ptr<osg::Node> terrainNode = buildTerrain(NULL, 1.f, center); if (!terrainNode) return; // no terrain defined std::auto_ptr<GridElement> element (new GridElement); element->mNode = terrainNode; mTerrainRoot->addChild(element->mNode); // kdtree probably not needed with mNumSplits=4 /* // build a kdtree to speed up intersection tests with the terrain // Note, the build could be optimized using a custom kdtree builder, since we know that the terrain can be represented by a quadtree geode->accept(*mKdTreeBuilder); */ mGrid[std::make_pair(x,y)] = element.release(); }
osg::ref_ptr<osg::Node> TerrainGrid::buildTerrain (osg::Group* parent, float chunkSize, const osg::Vec2f& chunkCenter) { if (chunkSize * mNumSplits > 1.f) { // keep splitting osg::ref_ptr<osg::Group> group (new osg::Group); if (parent) parent->addChild(group); float newChunkSize = chunkSize/2.f; buildTerrain(group, newChunkSize, chunkCenter + osg::Vec2f(newChunkSize/2.f, newChunkSize/2.f)); buildTerrain(group, newChunkSize, chunkCenter + osg::Vec2f(newChunkSize/2.f, -newChunkSize/2.f)); buildTerrain(group, newChunkSize, chunkCenter + osg::Vec2f(-newChunkSize/2.f, newChunkSize/2.f)); buildTerrain(group, newChunkSize, chunkCenter + osg::Vec2f(-newChunkSize/2.f, -newChunkSize/2.f)); return group; } else { float minH, maxH; if (!mStorage->getMinMaxHeights(chunkSize, chunkCenter, minH, maxH)) return NULL; // no terrain defined osg::Vec2f worldCenter = chunkCenter*mStorage->getCellWorldSize(); osg::ref_ptr<SceneUtil::PositionAttitudeTransform> transform (new SceneUtil::PositionAttitudeTransform); transform->setPosition(osg::Vec3f(worldCenter.x(), worldCenter.y(), 0.f)); if (parent) parent->addChild(transform); osg::ref_ptr<osg::Vec3Array> positions (new osg::Vec3Array); osg::ref_ptr<osg::Vec3Array> normals (new osg::Vec3Array); osg::ref_ptr<osg::Vec4Array> colors (new osg::Vec4Array); osg::ref_ptr<osg::VertexBufferObject> vbo (new osg::VertexBufferObject); positions->setVertexBufferObject(vbo); normals->setVertexBufferObject(vbo); colors->setVertexBufferObject(vbo); mStorage->fillVertexBuffers(0, chunkSize, chunkCenter, positions, normals, colors); osg::ref_ptr<osg::Geometry> geometry (new osg::Geometry); geometry->setVertexArray(positions); geometry->setNormalArray(normals, osg::Array::BIND_PER_VERTEX); geometry->setColorArray(colors, osg::Array::BIND_PER_VERTEX); geometry->setUseDisplayList(false); geometry->setUseVertexBufferObjects(true); geometry->addPrimitiveSet(mCache.getIndexBuffer(0)); // we already know the bounding box, so no need to let OSG compute it. osg::Vec3f min(-0.5f*mStorage->getCellWorldSize()*chunkSize, -0.5f*mStorage->getCellWorldSize()*chunkSize, minH); osg::Vec3f max (0.5f*mStorage->getCellWorldSize()*chunkSize, 0.5f*mStorage->getCellWorldSize()*chunkSize, maxH); osg::BoundingBox bounds(min, max); geometry->setComputeBoundingBoxCallback(new StaticBoundingBoxCallback(bounds)); std::vector<LayerInfo> layerList; std::vector<osg::ref_ptr<osg::Image> > blendmaps; mStorage->getBlendmaps(chunkSize, chunkCenter, false, blendmaps, layerList); // For compiling textures, I don't think the osgFX::Effect does it correctly osg::ref_ptr<osg::Node> textureCompileDummy (new osg::Node); unsigned int dummyTextureCounter = 0; bool useShaders = mResourceSystem->getSceneManager()->getForceShaders(); if (!mResourceSystem->getSceneManager()->getClampLighting()) useShaders = true; // always use shaders when lighting is unclamped, this is to avoid lighting seams between a terrain chunk with normal maps and one without normal maps std::vector<TextureLayer> layers; { OpenThreads::ScopedLock<OpenThreads::Mutex> lock(mTextureCacheMutex); for (std::vector<LayerInfo>::const_iterator it = layerList.begin(); it != layerList.end(); ++it) { TextureLayer textureLayer; textureLayer.mSpecular = it->mSpecular; osg::ref_ptr<osg::Texture2D> texture = mTextureCache[it->mDiffuseMap]; if (!texture) { texture = new osg::Texture2D(mResourceSystem->getImageManager()->getImage(it->mDiffuseMap)); texture->setWrap(osg::Texture::WRAP_S, osg::Texture::REPEAT); texture->setWrap(osg::Texture::WRAP_T, osg::Texture::REPEAT); mResourceSystem->getSceneManager()->applyFilterSettings(texture); mTextureCache[it->mDiffuseMap] = texture; } textureLayer.mDiffuseMap = texture; textureCompileDummy->getOrCreateStateSet()->setTextureAttributeAndModes(dummyTextureCounter++, texture); if (!it->mNormalMap.empty()) { texture = mTextureCache[it->mNormalMap]; if (!texture) { texture = new osg::Texture2D(mResourceSystem->getImageManager()->getImage(it->mNormalMap)); texture->setWrap(osg::Texture::WRAP_S, osg::Texture::REPEAT); texture->setWrap(osg::Texture::WRAP_T, osg::Texture::REPEAT); mResourceSystem->getSceneManager()->applyFilterSettings(texture); mTextureCache[it->mNormalMap] = texture; } textureCompileDummy->getOrCreateStateSet()->setTextureAttributeAndModes(dummyTextureCounter++, texture); textureLayer.mNormalMap = texture; } if (it->requiresShaders()) useShaders = true; layers.push_back(textureLayer); } } std::vector<osg::ref_ptr<osg::Texture2D> > blendmapTextures; for (std::vector<osg::ref_ptr<osg::Image> >::const_iterator it = blendmaps.begin(); it != blendmaps.end(); ++it) { osg::ref_ptr<osg::Texture2D> texture (new osg::Texture2D); texture->setImage(*it); texture->setWrap(osg::Texture::WRAP_S, osg::Texture::CLAMP_TO_EDGE); texture->setWrap(osg::Texture::WRAP_T, osg::Texture::CLAMP_TO_EDGE); texture->setResizeNonPowerOfTwoHint(false); blendmapTextures.push_back(texture); textureCompileDummy->getOrCreateStateSet()->setTextureAttributeAndModes(dummyTextureCounter++, blendmapTextures.back()); } // use texture coordinates for both texture units, the layer texture and blend texture for (unsigned int i=0; i<2; ++i) geometry->setTexCoordArray(i, mCache.getUVBuffer()); float blendmapScale = ESM::Land::LAND_TEXTURE_SIZE*chunkSize; osg::ref_ptr<osgFX::Effect> effect (new Terrain::Effect(mShaderManager ? useShaders : false, mResourceSystem->getSceneManager()->getForcePerPixelLighting(), mResourceSystem->getSceneManager()->getClampLighting(), mShaderManager, layers, blendmapTextures, blendmapScale, blendmapScale)); effect->addCullCallback(new SceneUtil::LightListCallback); transform->addChild(effect); osg::Node* toAttach = geometry.get(); effect->addChild(toAttach); if (mIncrementalCompileOperation) { mIncrementalCompileOperation->add(toAttach); mIncrementalCompileOperation->add(textureCompileDummy); } return transform; } }
// Initialize GLUT & OpenSG and set up the rootNode int main(int argc, char **argv) { // OSG init osgInit(argc,argv); { // Set up Window WindowEventProducerRecPtr TutorialWindow = createNativeWindow(); TutorialWindow->initWindow(); // Create the SimpleSceneManager helper SimpleSceneManager sceneManager; TutorialWindow->setDisplayCallback(boost::bind(display, &sceneManager)); TutorialWindow->setReshapeCallback(boost::bind(reshape, _1, &sceneManager)); // Tell the Manager what to manage sceneManager.setWindow(TutorialWindow); //Attach to events TutorialWindow->connectMousePressed(boost::bind(mousePressed, _1, &sceneManager)); TutorialWindow->connectMouseReleased(boost::bind(mouseReleased, _1, &sceneManager)); TutorialWindow->connectMouseMoved(boost::bind(mouseMoved, _1, &sceneManager)); TutorialWindow->connectMouseDragged(boost::bind(mouseDragged, _1, &sceneManager)); TutorialWindow->connectMouseWheelMoved(boost::bind(mouseWheelMoved, _1, &sceneManager)); TutorialWindow->connectKeyReleased(boost::bind(keyReleased, _1)); //Make Main Scene Node NodeRefPtr scene = makeCoredNode<Group>(); setName(scene, "scene"); NodeRecPtr rootNode = Node::create(); setName(rootNode, "rootNode"); ComponentTransformRefPtr Trans = ComponentTransform::create(); rootNode->setCore(Trans); rootNode->addChild(scene); //Light Beacon Matrix LightTransformMat; LightTransformMat.setTranslate(Vec3f(50.0,0.0,100.0)); TransformRefPtr LightTransform = Transform::create(); LightTransform->setMatrix(LightTransformMat); NodeRefPtr TutorialLightBeacon = Node::create(); TutorialLightBeacon->setCore(LightTransform); //Light Node PointLightRefPtr TutorialLight = PointLight::create(); TutorialLight->setBeacon(TutorialLightBeacon); NodeRefPtr TutorialLightNode = Node::create(); TutorialLightNode->setCore(TutorialLight); scene->addChild(TutorialLightNode); scene->addChild(TutorialLightBeacon); //Setup Physics Scene PhysicsWorldRecPtr physicsWorld = PhysicsWorld::create(); physicsWorld->setWorldContactSurfaceLayer(0.005); physicsWorld->setAutoDisableFlag(1); physicsWorld->setAutoDisableTime(0.75); physicsWorld->setWorldContactMaxCorrectingVel(100.0); physicsWorld->setGravity(Vec3f(0.0, 0.0, -9.81)); PhysicsHashSpaceRecPtr physicsSpace = PhysicsHashSpace::create(); //Setup the default collision parameters CollisionContactParametersRefPtr DefaultCollisionParams = CollisionContactParameters::createEmpty(); DefaultCollisionParams->setMode(dContactApprox1); DefaultCollisionParams->setMu(1.0); DefaultCollisionParams->setMu2(0.0); DefaultCollisionParams->setBounce(0.0); DefaultCollisionParams->setBounceSpeedThreshold(0.0); DefaultCollisionParams->setSoftCFM(0.1); DefaultCollisionParams->setSoftERP(0.2); DefaultCollisionParams->setMotion1(0.0); DefaultCollisionParams->setMotion2(0.0); DefaultCollisionParams->setMotionN(0.0); DefaultCollisionParams->setSlip1(0.0); DefaultCollisionParams->setSlip2(0.0); physicsSpace->setDefaultCollisionParameters(DefaultCollisionParams); PhysicsHandlerRecPtr physHandler = PhysicsHandler::create(); physHandler->setWorld(physicsWorld); physHandler->pushToSpaces(physicsSpace); physHandler->setUpdateNode(rootNode); physHandler->attachUpdateProducer(TutorialWindow); rootNode->addAttachment(physHandler); rootNode->addAttachment(physicsWorld); rootNode->addAttachment(physicsSpace); /************************************************************************/ /* create spaces, geoms and bodys */ /************************************************************************/ //create a group for our space GroupRefPtr spaceGroup; NodeRecPtr spaceGroupNode = makeCoredNode<Group>(&spaceGroup); //create the ground terrain GeometryRefPtr TerrainGeo = buildTerrain(Vec2f(400.0,400.0),25,25); //and its Material SimpleMaterialRefPtr TerrainMat = SimpleMaterial::create(); TerrainMat->setAmbient(Color3f(0.3,0.5,0.3)); TerrainMat->setDiffuse(Color3f(0.5,0.9,0.5)); TerrainGeo->setMaterial(TerrainMat); NodeRefPtr TerrainNode = Node::create(); TerrainNode->setCore(TerrainGeo); //create ODE data PhysicsGeomRefPtr TerrainODEGeom = PhysicsTriMeshGeom::create(); //add geom to space for collision TerrainODEGeom->setSpace(physicsSpace); //set the geometryNode to fill the ode-triMesh dynamic_pointer_cast<PhysicsTriMeshGeom>(TerrainODEGeom)->setGeometryNode(TerrainNode); //add attachments //add Attachments to nodes... spaceGroupNode->addAttachment(physicsSpace); spaceGroupNode->addChild(TerrainNode); TerrainNode->addAttachment(TerrainODEGeom); TutorialLightNode->addChild(spaceGroupNode); //Create Character PhysicsBodyRefPtr CharacterPhysicsBody = buildCharacter(Vec3f(5.0,5.0,10.0), Pnt3f((Real32)(rand()%100)-50.0,(Real32)(rand()%100)-50.0,25.0), spaceGroupNode, physicsWorld, physicsSpace); PhysicsLMotorJointRefPtr CharacterMover = buildMover(CharacterPhysicsBody); TutorialWindow->connectKeyPressed(boost::bind(keyPressed, _1, spaceGroupNode.get(), physicsWorld.get(), physicsSpace.get())); TutorialWindow->connectUpdate(boost::bind(handleUpdate, _1, CharacterPhysicsBody.get(), CharacterMover.get())); // tell the manager what to manage sceneManager.setRoot (rootNode); // show the whole rootNode sceneManager.showAll(); Vec2f WinSize(TutorialWindow->getDesktopSize() * 0.85f); Pnt2f WinPos((TutorialWindow->getDesktopSize() - WinSize) *0.5); TutorialWindow->openWindow(WinPos, WinSize, "03CharacterTerrain"); //Enter main Loop TutorialWindow->mainLoop(); } osgExit(); return 0; }
int main(int argc, char **argv) { buildTerrain(); //Make the mian plane the lead friendly plane friendlyPlanes.push_back(mainPlane); cDetector.carriers = &carriers; cDetector.tiles = &tiles; cDetector.friendlyPlanes = &friendlyPlanes; cDetector.enemyPlanes = &enemyPlanes; cDetector.mainPlane = &mainPlane; cDetector.explosives = &explosives; //buildEnemyPlanes(); buildCarrierGroup(); buildSilos(); mainPlane.y = 45; mainPlane.explosives = &explosives; //explosives.generateExplosion(0, 45, -100, 0, 0, 0); glutInit(&argc, argv); glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA); glutInitWindowPosition(100,100); glutInitWindowSize(1024,768); //glutInitWindowSize(600,400); glutCreateWindow("Flight Simulator Basic"); initScene(); // Enable lighting glEnable(GL_LIGHTING); glEnable(GL_LIGHT0); glEnable(GL_LIGHT1); GLfloat light_ambient[] = { 1, 1, 1, 1 }; GLfloat light_diffuse[] = { 1.0, 1.0, 1.0, 1.0 }; GLfloat light_specular[] = { 1.0, 1.0, 1.0, 1.0 }; GLfloat light_pos[] = { 0.0, 30.0, 0.0, 1 }; GLfloat light_dir[] = { 0.0, 0, 0}; GLfloat mat_specular[] = {0.3, 0.3, 0.3, 1.0}; GLfloat mat_shininess[] = { 10.0 }; glLightfv(GL_LIGHT0, GL_AMBIENT, light_ambient); glLightfv(GL_LIGHT0, GL_POSITION, light_pos); glLightfv(GL_LIGHT0, GL_SPOT_DIRECTION, light_dir); glLightfv(GL_LIGHT1, GL_AMBIENT, light_ambient); glLightfv(GL_LIGHT1, GL_SPECULAR, light_specular); glLightfv(GL_LIGHT1, GL_DIFFUSE, light_diffuse); glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular); glMaterialfv(GL_FRONT, GL_SHININESS, mat_shininess); glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE); glEnable(GL_COLOR_MATERIAL); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glEnable(GL_BLEND); glClearColor(0.0f, 0.0f, .6f, .5f); glutIgnoreKeyRepeat(.05); glutSpecialFunc(pressKey); //glutKeyboardFunc(pressKey); glutSpecialUpFunc(releaseKey); glutDisplayFunc(renderScene); glutIdleFunc(renderScene); glutReshapeFunc(changeSize); glutMainLoop(); return(0); }
osg::ref_ptr<osg::Node> TerrainGrid::buildTerrain (osg::Group* parent, float chunkSize, const osg::Vec2f& chunkCenter) { if (chunkSize * mNumSplits > 1.f) { // keep splitting osg::ref_ptr<osg::Group> group (new osg::Group); if (parent) parent->addChild(group); float newChunkSize = chunkSize/2.f; buildTerrain(group, newChunkSize, chunkCenter + osg::Vec2f(newChunkSize/2.f, newChunkSize/2.f)); buildTerrain(group, newChunkSize, chunkCenter + osg::Vec2f(newChunkSize/2.f, -newChunkSize/2.f)); buildTerrain(group, newChunkSize, chunkCenter + osg::Vec2f(-newChunkSize/2.f, newChunkSize/2.f)); buildTerrain(group, newChunkSize, chunkCenter + osg::Vec2f(-newChunkSize/2.f, -newChunkSize/2.f)); return group; } else { float minH, maxH; if (!mStorage->getMinMaxHeights(chunkSize, chunkCenter, minH, maxH)) return NULL; // no terrain defined osg::Vec2f worldCenter = chunkCenter*mStorage->getCellWorldSize(); osg::ref_ptr<SceneUtil::PositionAttitudeTransform> transform (new SceneUtil::PositionAttitudeTransform); transform->setPosition(osg::Vec3f(worldCenter.x(), worldCenter.y(), 0.f)); if (parent) parent->addChild(transform); osg::ref_ptr<osg::Vec3Array> positions (new osg::Vec3Array); osg::ref_ptr<osg::Vec3Array> normals (new osg::Vec3Array); osg::ref_ptr<osg::Vec4Array> colors (new osg::Vec4Array); osg::ref_ptr<osg::VertexBufferObject> vbo (new osg::VertexBufferObject); positions->setVertexBufferObject(vbo); normals->setVertexBufferObject(vbo); colors->setVertexBufferObject(vbo); mStorage->fillVertexBuffers(0, chunkSize, chunkCenter, positions, normals, colors); osg::ref_ptr<osg::Geometry> geometry (new osg::Geometry); geometry->setVertexArray(positions); geometry->setNormalArray(normals, osg::Array::BIND_PER_VERTEX); geometry->setColorArray(colors, osg::Array::BIND_PER_VERTEX); geometry->setUseDisplayList(false); geometry->setUseVertexBufferObjects(true); geometry->addPrimitiveSet(mCache.getIndexBuffer(0)); // we already know the bounding box, so no need to let OSG compute it. osg::Vec3f min(-0.5f*mStorage->getCellWorldSize()*chunkSize, -0.5f*mStorage->getCellWorldSize()*chunkSize, minH); osg::Vec3f max (0.5f*mStorage->getCellWorldSize()*chunkSize, 0.5f*mStorage->getCellWorldSize()*chunkSize, maxH); osg::BoundingBox bounds(min, max); geometry->setComputeBoundingBoxCallback(new StaticBoundingBoxCallback(bounds)); std::vector<LayerInfo> layerList; std::vector<osg::ref_ptr<osg::Image> > blendmaps; mStorage->getBlendmaps(chunkSize, chunkCenter, false, blendmaps, layerList); // For compiling textures, I don't think the osgFX::Effect does it correctly osg::ref_ptr<osg::Node> textureCompileDummy (new osg::Node); std::vector<osg::ref_ptr<osg::Texture2D> > layerTextures; for (std::vector<LayerInfo>::const_iterator it = layerList.begin(); it != layerList.end(); ++it) { layerTextures.push_back(mResourceSystem->getTextureManager()->getTexture2D(it->mDiffuseMap, osg::Texture::REPEAT, osg::Texture::REPEAT)); textureCompileDummy->getOrCreateStateSet()->setTextureAttributeAndModes(0, layerTextures.back()); } std::vector<osg::ref_ptr<osg::Texture2D> > blendmapTextures; for (std::vector<osg::ref_ptr<osg::Image> >::const_iterator it = blendmaps.begin(); it != blendmaps.end(); ++it) { osg::ref_ptr<osg::Texture2D> texture (new osg::Texture2D); texture->setImage(*it); texture->setWrap(osg::Texture::WRAP_S, osg::Texture::CLAMP_TO_EDGE); texture->setWrap(osg::Texture::WRAP_T, osg::Texture::CLAMP_TO_EDGE); texture->setFilter(osg::Texture::MIN_FILTER, osg::Texture::LINEAR); texture->setFilter(osg::Texture::MAG_FILTER, osg::Texture::LINEAR); texture->setResizeNonPowerOfTwoHint(false); blendmapTextures.push_back(texture); textureCompileDummy->getOrCreateStateSet()->setTextureAttributeAndModes(0, layerTextures.back()); } // use texture coordinates for both texture units, the layer texture and blend texture for (unsigned int i=0; i<2; ++i) geometry->setTexCoordArray(i, mCache.getUVBuffer()); float blendmapScale = ESM::Land::LAND_TEXTURE_SIZE*chunkSize; osg::ref_ptr<osgFX::Effect> effect (new Terrain::Effect(layerTextures, blendmapTextures, blendmapScale, blendmapScale)); effect->addCullCallback(new SceneUtil::LightListCallback); transform->addChild(effect); #if OSG_VERSION_GREATER_OR_EQUAL(3,3,3) osg::Node* toAttach = geometry.get(); #else osg::ref_ptr<osg::Geode> geode (new osg::Geode); geode->addDrawable(geometry); osg::Node* toAttach = geode.get(); #endif effect->addChild(toAttach); if (mIncrementalCompileOperation) { mIncrementalCompileOperation->add(toAttach); mIncrementalCompileOperation->add(textureCompileDummy); } return transform; } }
void TerrainGrid::cacheCell(View* view, int x, int y) { osg::Vec2f center(x+0.5f, y+0.5f); static_cast<MyView*>(view)->mLoaded = buildTerrain(NULL, 1.f, center); }