void OgreSample8App::createScene() { mObjectNode = mSceneMgr->getRootSceneNode()->createChildSceneNode(); setupModes(); mSceneMgr->setAmbientLight(ColourValue::Black); // disable ambient lighting mObjectNode->attachObject(mSceneMgr->getEntity("ogrehead.mesh")); // create pivot nodes mLightPivot1 = mSceneMgr->getRootSceneNode()->createChildSceneNode(); mLightPivot2 = mSceneMgr->getRootSceneNode()->createChildSceneNode(); Light* l; Ogre::BillboardSet * bbs; // create white light l = mSceneMgr->createLight(); l->setPosition(200, 0, 0); l->setDiffuseColour(1, 1, 1); l->setSpecularColour(1, 1, 1); // create white flare bbs = mSceneMgr->createBillboardSet(); bbs->setMaterialName("Examples/Flare"); bbs->createBillboard(200,0,0)->setColour(Ogre::ColourValue::White); mLightPivot2->attachObject(l); mLightPivot2->attachObject(bbs); mMeshMenu->subscribeEvent(CEGUI::Combobox::EventListSelectionAccepted,CEGUI::Event::Subscriber(&OgreSample8App::handleItemSelected1,this)); mMaterialMenu->subscribeEvent(CEGUI::Combobox::EventListSelectionAccepted,CEGUI::Event::Subscriber(&OgreSample8App::handleItemSelected2,this)); }
void ResourceGroupReloader::UpdateMaterialRenderableVisitor::visit( Ogre::Renderable *rend, Ogre::ushort lodIndex, bool isDebug, Ogre::Any *pAny) { const Ogre::MaterialPtr mat = rend->getMaterial(); if(!mat.isNull()) { std::string newMatName = mat->getName(); Ogre::MaterialPtr newMat = Ogre::MaterialManager::getSingleton().getByName(newMatName); if(newMat.isNull()) { // this can happen if there was error during the reloading of the material. // in that case, we keep the ancient one. // Ice::Log::Instance().LogMessage(newMatName+" : new material is null!"); return; } // unfortunately, the renderable gives access only to a const MaterialPtr. // and there is no 'setMaterial' or 'setMaterialName' method on renderables. // so I have to try to down cast with known classes... { Ogre::SubEntity* lRend = dynamic_cast<Ogre::SubEntity*>(rend); if(lRend){lRend->setMaterialName(newMatName);return;} } { Ogre::SimpleRenderable* lRend = dynamic_cast<Ogre::SimpleRenderable*>(rend); if(lRend){lRend->setMaterial(newMatName);return;} } { Ogre::ShadowRenderable* lRend = dynamic_cast<Ogre::ShadowRenderable*>(rend); if(lRend){lRend->setMaterial(newMat);return;} } { Ogre::BillboardChain* lRend = dynamic_cast<Ogre::BillboardChain*>(rend); if(lRend){lRend->setMaterialName(newMatName);return;} } { Ogre::BillboardSet* lRend = dynamic_cast<Ogre::BillboardSet*>(rend); if(lRend){lRend->setMaterialName(newMatName);return;} } { Ogre::OverlayElement* lRend = dynamic_cast<Ogre::OverlayElement*>(rend); if(lRend){lRend->setMaterialName(newMatName);return;} } }else{ // was there for debug... // Ice::Log::Instance().LogMessage("material of renderable is null!"); } }
StarRepresentation::StarRepresentation(Scene* myScene, StarRepresentation* twin, Ogre::Sphere* skySphere, Ogre::Plane* waterPlane, Ogre::Plane* skyPlane) : GameObject(myScene), _twin(twin), _skySphere(skySphere), _waterPlane(waterPlane), _skyPlane(skyPlane) { //Ogre::Entity* ent = _myScene->sceneManager()->createEntity("Sinbad.mesh"); Ogre::BillboardSet* bSet = _myScene->sceneManager()->createBillboardSet(1); bSet->setMaterialName("SailingByTheStars/Star"); Billboard* b = bSet->createBillboard(0,0,0, Ogre::ColourValue(0.4,0.8,0.9, 0.7)); bSet->setBounds(Ogre::AxisAlignedBox(Ogre::AxisAlignedBox::EXTENT_INFINITE), 1000); _node->attachObject(bSet); _node->setScale(0.08,0.08,0.08); if (twin != NULL) { twin->setTwin(this); } }
Boat::Boat(Scene* myScene, const Star* star, Ogre::Terrain* terrain, Ogre::GpuProgramParametersSharedPtr fogParamPtr, Ogre::String& paramFogName) : GameObject(myScene), _repr( star->getWaterStar() ),_reactivity(1.5), _speed(3), _starPoint(new PointCollider(star->getWaterStar()->getNode()->_getDerivedPosition())), _starCollider(NULL), _terrain(terrain), _fogPtr(fogParamPtr), _posFloat4(new float[4]), _paramFogName(paramFogName) { _node->setPosition(0.2,star->getWaterStar()->getNode()->_getDerivedPosition().y,-20); _boatEnt = myScene->sceneManager()->createEntity("ColourCube"); _boatEnt->setMaterialName("Diffuse"); _node->attachObject(_boatEnt); _node->setScale(0.4,0.4,0.4); _frontNode = _node->createChildSceneNode(-Ogre::Vector3::UNIT_Z * 1); Ogre::Entity* frontNodEnt = myScene->sceneManager()->createEntity("ColourCube"); frontNodEnt->setMaterialName("Diffuse"); _frontNode->attachObject(frontNodEnt); _frontNode->setScale(0.2,1,0.2); _lightNode = _node->createChildSceneNode(Ogre::Vector3::UNIT_Y * 3); std::stringstream lightName; lightName << "boatLight" << count; Ogre::Light* portLight = myScene->sceneManager()->createLight(lightName.str()); portLight->setType(Ogre::Light::LT_POINT); portLight->setDiffuseColour(1,1,1); portLight->setSpecularColour(0.4,0.4,0.2); portLight->setAttenuation(800, 2.0, 0.5, 0.08); Ogre::BillboardSet* bSet = myScene->sceneManager()->createBillboardSet(1); bSet->setMaterialName("Examples/Flare"); Billboard* b = bSet->createBillboard(0,0,0, Ogre::ColourValue(0.4,0.4,0.2, 0.2)); _lightNode->attachObject(portLight); _lightNode->attachObject(bSet); _lightNode->scale(0.05,0.05,0.05); _starCollider = new SphereCollider(Vector3(0,0,0), _node, 0.6); _posFloat4[1] = 0; _posFloat4[3] = 1; count++; }
void GasCellPort::cellDraw( const coordInt2d_t& coord ) const { // Создаём образ // Содержимое ячейки представим в виде меша const int i = helper::ic( coord.get<0>(), coord.get<1>(), N, M ); assert( (i != -1) && "Получена координата за пределами матрицы порта." ); const GasFD c = content[i]; if (c.uid == 0) { // Вакуум не показываем return; } #if 0 // - Медленно. Переписано через биллборды. /* const std::string name = "smoke-pressure-" + Ogre::StringConverter::toString( (int)c.pressure ); */ const std::string meshName = "sphere.mesh"; /* - @todo Так ли каждый раз нужна новая сущность? const std::string entityName = meshName + ".entity"; const bool has = sm->hasEntity( entityName ); Ogre::Entity* image = has ? sm->getEntity( entityName ) : sm->createEntity( entityName, meshName ); */ Ogre::Entity* image = sm->createEntity( meshName ); auto childScene = sn->createChildSceneNode(); childScene->attachObject( image ); // Координаты образа кратны масштабу childScene->setPosition( (float)coord.get<0>() * scale, 0.0f, (float)coord.get<1>() * scale ); // Образ заполняет ячейку целиком //const Ogre::Vector3 fillScale( scale / image->getBoundingRadius() ); //childScene->setScale( fillScale ); #endif // Работаем через биллборды // @source http://89.151.96.106/forums/viewtopic.php?f=10&t=60455 const float S = scale * visualScale; // Готовим биллборды при первом обращении к ним // @todo Визаулизировать в зависимости от характеристики ячейки и соседей. std::string bsName = "GasCellPort-bs"; Ogre::BillboardSet* bs = nullptr; if ( sm->hasBillboardSet( bsName ) ) { bs = sm->getBillboardSet( bsName ); } else { // Дым - один образ на всю ячейку bs = sm->createBillboardSet( bsName, count() ); bs->setAutoextend( false ); const std::string prefixMaterial = "smokeport2d/smoke-"; const std::string nameMaterial = prefixMaterial + "0"; bs->setMaterialName( nameMaterial ); bs->setBillboardType( Ogre::BBT_PERPENDICULAR_COMMON ); bs->setCommonUpVector( Ogre::Vector3::UNIT_Z ); bs->setCommonDirection( -Ogre::Vector3::UNIT_Y ); bs->setBillboardsInWorldSpace( true ); bs->setBillboardOrigin( Ogre::BBO_CENTER ); bs->setDefaultDimensions( S, S ); sn->attachObject( bs ); } // Позиционируем биллборд Ogre::Billboard* b = bs->createBillboard( (float)coord.get<0>() * S, 0.0f, (float)coord.get<1>() * S ); //b->setRotation( Ogre::Degree( (float)rand() ) ); }
void CellDrawActor< C >::allDraw( const AllDrawMessage< C >& m ) { // Рисуем только если ещё не было нарисовано // или по просьбе "обновлять постоянно" const std::string sceneName = "CellDrawActor::allDraw::Scene"; const std::string bsName = "CellDrawActor::allDraw::BillboardSet"; // @test /* try { m.sm->getRootSceneNode()->removeAndDestroyChild( sceneName ); } catch ( ... ) { } try { m.sm->destroyBillboardSet( bsName ); } catch ( ... ) { } */ if ( m.update || !m.sm->hasSceneNode( sceneName ) ) { // Каждому образу - свой холст (общая сцена) auto scene = m.sm->hasSceneNode( sceneName ) ? m.sm->getSceneNode( sceneName ) : m.sm->getRootSceneNode()->createChildSceneNode( sceneName ); // Определяем общее кол-во элементов const size_t NM = m.N * m.M; // Готовим биллборды // Обращаются за отрисовкой первый раз? const bool virgin = m.sm->hasBillboardSet( bsName ); Ogre::BillboardSet* bs = nullptr; if ( virgin ) { bs = m.sm->getBillboardSet( bsName ); } else { // Один образ для всех ячеек // @todo Расширить кол-во образов. bs = m.sm->createBillboardSet( bsName, NM ); bs->setAutoextend( true ); const std::string nameMaterial = m.prefixMaterial + "0"; bs->setMaterialName( nameMaterial ); bs->setBillboardType( Ogre::BBT_PERPENDICULAR_COMMON ); bs->setCommonUpVector( Ogre::Vector3::UNIT_Z ); bs->setCommonDirection( -Ogre::Vector3::UNIT_Y ); bs->setBillboardsInWorldSpace( true ); bs->setBillboardOrigin( Ogre::BBO_CENTER ); bs->setDefaultDimensions( m.scale, m.scale ); bs->setUseAccurateFacing( false ); scene->attachObject( bs ); } // Визуализируем каждую ячейку /* - @todo Можно ускорить отрисовку > http://www.ogre3d.org/forums/viewtopic.php?f=2&t=11134&start=0 Ogre::Billboard b = Ogre::Billboard( Ogre::Vector3::ZERO, bs ); b.setColour( Ogre::ColourValue::White ); b.setRotation( Ogre::Degree( (float)rand() ) ); */ //bs->beginBillboards(); for (size_t z = 0; z < m.M; ++z) { for (size_t x = 0; x < m.N; ++x) { const coordInt2d_t coord( (int)x, (int)z ); // Создадим образ ячейки с указанной координатой const int i = helper::ic( coord.get<0>(), coord.get<1>(), m.N, m.M ); assert( (i != -1) && "Получена координата за пределами матрицы порта." ); const C c = m.content[i]; // Биллборд уже мог быть создан ранее const auto bi = helper::index( *bs, coord, m.scale ); if (bi != -1) { bs->removeBillboard( bi ); } if (c.uid == 0) { // Вакуум - отсутствие образа continue; } #if 0 // - Медленно. Переписано через биллборды. /* const std::string name = "smoke-pressure-" + Ogre::StringConverter::toString( (int)c.pressure ); */ const std::string meshName = "sphere.mesh"; /* - @todo Так ли каждый раз нужна новая сущность? const std::string entityName = meshName + ".entity"; const bool has = sm->hasEntity( entityName ); Ogre::Entity* image = has ? sm->getEntity( entityName ) : sm->createEntity( entityName, meshName ); */ Ogre::Entity* image = sm->createEntity( meshName ); auto childScene = sn->createChildSceneNode(); childScene->attachObject( image ); // Координаты образа кратны масштабу childScene->setPosition( (float)coord.get<0>() * scale, 0.0f, (float)coord.get<1>() * scale ); // Образ заполняет ячейку целиком //const Ogre::Vector3 fillScale( scale / image->getBoundingRadius() ); //childScene->setScale( fillScale ); #endif // Работаем через биллборды // @source http://89.151.96.106/forums/viewtopic.php?f=10&t=60455 // @todo Визаулизировать в зависимости от характеристики ячейки и соседей. // Позиционируем биллборд Ogre::Billboard* b = bs->createBillboard( (float)coord.get<0>() * m.scale, 0.0f, (float)coord.get<1>() * m.scale ); b->setRotation( Ogre::Degree( (float)rand() ) ); /* b.setPosition( (float)coord.get<0>() * m.scale, 0.0f, (float)coord.get<1>() * m.scale ); bs->injectBillboard( b ); */ // @test //break; } // for (size_t x = 0; x < m.N; ++x) } // for (size_t z = 0; z < m.M; ++z) //bs->endBillboards(); } // if ( m.update || !m.sm->hasSceneNode( sceneName ) ) }
int main(int argc, char* argv[]) { std::unique_ptr<ExecutionArgs> exArgs(new ExecutionArgs()); if (!processCommandLineArgs(argc, argv, *exArgs)) { return -1; } else if (exArgs->helpPrompt) { std::cout << "Usage: sts [--help] || [--config]" << std::endl; std::cout << "Options:" << std::endl; std::cout << "\t --help - print this message;" << std::endl; std::cout << "\t --config - show config dialog." << std::endl; std::cout << std::endl; return 0; } try { Ogre::String lConfigFileName = "ogre.cfg"; Ogre::String lPluginsFileName = "plugins.cfg"; Ogre::String lLogFileName = "Ogre_STS.log"; std::unique_ptr<Ogre::Root> lRoot(new Ogre::Root(lPluginsFileName, lConfigFileName, lLogFileName)); if (exArgs->showConfigDialog) { if (!lRoot->showConfigDialog()) { return 0; } } Ogre::String lWindowTitle = "STS"; Ogre::String lCustomCapacities = ""; /* Check for the valid ogre.cfg */ bool lCreateAWindowAutomatically = lRoot->restoreConfig(); if (!lCreateAWindowAutomatically) { initSomeRenderSystem(lRoot); } Ogre::RenderWindow* lWindow = lRoot->initialise(lCreateAWindowAutomatically, lWindowTitle, lCustomCapacities); if (!lWindow) { /* ogre.cfg is not available - start with hardcoded parameters */ unsigned int lSizeX = 800; unsigned int lSizeY = 600; bool lFullscreen = false; Ogre::NameValuePairList lParams; lParams["FSAA"] = "0"; lParams["vsync"] = "true"; lWindow = lRoot->createRenderWindow(lWindowTitle, lSizeX, lSizeY, lFullscreen, &lParams); } /* Create a scene manager */ Ogre::SceneManager* lScene = lRoot->createSceneManager(Ogre::ST_GENERIC, "SceneManager"); Ogre::SceneNode* lRootSceneNode = lScene->getRootSceneNode(); /* Create camera */ Ogre::Camera* lCamera = lScene->createCamera("MyCamera"); /* Create viewport (camera <-> window) */ Ogre::Viewport* vp = lWindow->addViewport(lCamera); vp->setAutoUpdated(true); vp->setBackgroundColour(Ogre::ColourValue(1, 0, 1)); lCamera->setAspectRatio(float(vp->getActualWidth()) / vp->getActualHeight()); lCamera->setPosition(Ogre::Vector3(0, 100, -1)); lCamera->lookAt(Ogre::Vector3(0, 0, 0)); /* Set clipping*/ lCamera->setNearClipDistance(1.5f); lCamera->setFarClipDistance(3000.0f); /* Lighting */ Ogre::Light* lLight = lScene->createLight("MainLight"); lLight->setPosition(Ogre::Vector3(0, 100, 0)); /* Resource manager */ Ogre::String lRcGroupName = "Main group"; initResourceMainGroup(lRcGroupName); /* Load model */ Ogre::Entity* lShipEntity = lScene->createEntity("airship.mesh"); lShipEntity->setCastShadows(false); Ogre::SceneNode* lShipNode = lRootSceneNode->createChildSceneNode(); lShipNode->attachObject(lShipEntity); lShipNode->setScale(Ogre::Vector3(3.15f, 3.15f, 3.15f)); /* Starship start point */ Ogre::Vector3 razorSP(0, -200, -100); lShipNode->setPosition(razorSP); /* Sprite billboard */ Ogre::SceneNode* lSpriteNode = lRootSceneNode->createChildSceneNode(); Ogre::BillboardSet* lBillboardSet = lScene->createBillboardSet(); lBillboardSet->setMaterialName("enemy_01", lRcGroupName); lBillboardSet->setTextureStacksAndSlices(1, 4); Ogre::Billboard* lSpriteBillboard = lBillboardSet->createBillboard(Ogre::Vector3(0, 0, 0)); lSpriteBillboard->setDimensions(48.0f / 2.0f, 58.0f / 2.0f); lSpriteBillboard->setTexcoordIndex(1); lSpriteNode->attachObject(lBillboardSet); lSpriteNode->setPosition(Ogre::Vector3(0, -200, 100)); /* Obtain the timer pointer */ Ogre::Timer* lTimer = lRoot->getTimer(); /* Skip all the messages */ lWindow->setAutoUpdated(false); lRoot->clearEventTimes(); while (!lWindow->isClosed()) { float angle = Ogre::Math::Sin(float(lTimer->getMilliseconds()) * Ogre::Math::PI / 2000.0f) * Ogre::Math::PI / 4.0f; float diplacement = Ogre::Math::Cos(float(lTimer->getMilliseconds()) * Ogre::Math::PI / 2000.0f) * 100.0f; lShipNode->setOrientation(Ogre::Quaternion(Ogre::Radian(angle), Ogre::Vector3(0, 0, 1))); lShipNode->setPosition(razorSP + Ogre::Vector3(diplacement, 0.0f, 0.0f)); unsigned int spriteFrame = (lTimer->getMilliseconds() / 125) % 2; lSpriteBillboard->setTexcoordIndex(spriteFrame); lWindow->update(false); lWindow->swapBuffers(); lRoot->renderOneFrame(); Ogre::WindowEventUtilities::messagePump(); } Ogre::LogManager::getSingleton().logMessage("Render window closed."); } catch (Ogre::Exception &e) { std::cerr << "Ogre::Exception: " << e.what() << std::endl; } catch (std::exception &e) { std::cerr << "std::exception: " << e.what() << std::endl; } return 0; }