// I will use std::auto_ptr so I need to include 'memory'.
// If you don't know std::auto_ptr, you should check some C++ tutorials/lesson on this matter.
#include <memory>
// I will check for std::exception. If you don't know what exception/try/catch means, you should learn C++ first.
#include <exception>
// These are some files that we need to include to use Ogre3D. Note that you can at the beginnings use directly "Ogre.h", to include lots of commonly used classes.
#include "OgreRoot.h"
#include "OgreRenderWindow.h"
#include "OgreWindowEventUtilities.h"
#include "OgreEntity.h"
#include "OgreMaterial.h"
#include "OgreMaterialManager.h"
//Here I include my other files, like the one for SimpleOgreInit...
#include "SimpleOgreInit.h"
#include "EasyDefines.h"
#include <cmath>
#include <cstdlib>
Ogre::SceneManager* lScene = 0;
Ogre::SceneNode* lRootSceneNode = 0;
class TempraryObject
{
public:
Ogre::SceneNode *node;
Ogre::Entity* entity;
int lifetime;
bool free;
void process()
{
lifetime--;
int lt = lifetime;
if(lifetime<0 && node !=0 && entity != 0)
{
// node->detachAllObjects();
lRootSceneNode->removeChild(node);
// lScene->destroySceneNode(node);
node = 0;
entity = 0;
}
free = (lifetime<0);
}
};
void AnOgreApplication()
{
// I construct my object that will allow me to initialise Ogre easily.
OgreEasy::SimpleOgreInit lOgreInit;
if(!lOgreInit.initOgre())
{
std::cout<<"Impossible to init Ogre correctly."<<std::endl;
return;
}
//I prefer to be able to access my variables directly.
Ogre::Root* lRoot = lOgreInit.mRoot.get();
Ogre::RenderWindow* lWindow = lOgreInit.mWindow;
lScene = lRoot->createSceneManager(Ogre::ST_GENERIC, "MyFirstSceneManager");
lRootSceneNode = lScene->getRootSceneNode();
// I create a camera. It represent a 'point of view' in the scene.
Ogre::Camera* lCamera = lScene->createCamera("MyFirstCamera");
// I attach the camera to a new SceneNode. It will be easier then to move it in the scene.
Ogre::SceneNode* lCameraNode = lRootSceneNode->createChildSceneNode("MyFirstCameraNode");
lCameraNode->attachObject(lCamera);
float lViewportWidth = 1.0f;
float lViewportHeight = 1.0f;
float lViewportLeft = (1.0f - lViewportWidth) * 0.5f;
float lViewportTop = (1.0f - lViewportHeight) * 0.5f;
unsigned short lMainViewportZOrder = 100;
Ogre::Viewport * vp = lWindow->addViewport(lCamera, lMainViewportZOrder, lViewportLeft, lViewportTop, lViewportWidth, lViewportHeight);
// I want the viewport to draw the scene automatically
// when I will call lWindow->update();
vp->setAutoUpdated(true);
// I choose a color for this viewport.
// I prefer to have a bright color, to detect holes in geometry etc...
vp->setBackgroundColour(Ogre::ColourValue(0.2,0.2,0.2));
// I choose the visual ratio of the camera. To make it looks real, I want it the same as the viewport.
float ratio = float(vp->getActualWidth()) / float(vp->getActualHeight());
lCamera->setAspectRatio(ratio);
// I choose the clipping far& near planes. if far/near>2000, you can get z buffer problem.
// eg : far/near = 10000/5 = 2000 . it's ok.
// If (far/near)>2000 then you will likely get 'z fighting' issues.
lCamera->setNearClipDistance(15.0f);
lCamera->setFarClipDistance(5000.0f);
// I want my window to be active
lWindow->setActive(true);
// I want to update myself the content of the window, not automatically.
lWindow->setAutoUpdated(false);
lRoot->clearEventTimes();
Ogre::String lNameOfResourceGroup = "SHARED";
Ogre::ResourceGroupManager& lRgMgr = Ogre::ResourceGroupManager::getSingleton();
lRgMgr.createResourceGroup(lNameOfResourceGroup);
Ogre::String lDirectoryToLoad = "../media";
bool lIsRecursive = false;
lRgMgr.addResourceLocation(lDirectoryToLoad, "FileSystem", lNameOfResourceGroup, lIsRecursive);
// The function 'initialiseResourceGroup' parses scripts if any in the locations.
lRgMgr.initialiseResourceGroup(lNameOfResourceGroup);
// Files that can be loaded are loaded.
lRgMgr.loadResourceGroup(lNameOfResourceGroup);
// Now the loaded Mesh is available from its ResourceGroup,
// as well as from the Ogre::MeshManager. A shared pointer to
// it can be accessed by : Ogre::MeshManager::getSingleton().getByName(name_of_the_mesh);
// Now I can create Entities using that mesh.
Ogre::String lNameOfTheMesh = "cube.mesh";
int lNumberOfEntities = 4096;
float x = - 1500;
float y = - 900;
Ogre::MaterialPtr mat = Ogre::MaterialManager::getSingletonPtr()->create("tex1",lNameOfResourceGroup);
mat->getTechnique(0)->getPass(0)->createTextureUnitState("terrain_texture.jpg");
float z = 4000;
std::list<TempraryObject> objects;
struct process
{
void operator()(TempraryObject &obj)
{
obj.process();
}
};
struct pred
{
bool operator()(TempraryObject &obj)
{
return obj.free;
}
};
unsigned long uuid =0;
while(!lOgreInit.mWindow->isClosed())
{
int cadd = (rand() % 20) + 30;
for(int i=0;i<cadd;++i)
{
uuid++;
TempraryObject temp;
temp.entity = lScene->createEntity(lNameOfTheMesh);
temp.entity->setMaterial(mat);
// Now I attach it to a scenenode, so that it becomes present in the scene.
char buff[80];
itoa(uuid,buff,10);
temp.node = lRootSceneNode->createChildSceneNode(buff);
temp.node->attachObject(temp.entity);
temp.node->translate(float(rand() % 10000 - 5000) * 0.33, float(rand() % 10000 - 5000) * 0.33, float(rand() % 1000 - 500) * 0.33);
temp.node->scale(0.1,0.1,0.1);
temp.free = false;
temp.lifetime = 10 + (rand() % 10);
objects.push_back(temp);
}
std::for_each(objects.begin(),objects.end(),process());
std::remove_if(objects.begin(),objects.end(),pred());
if(GetAsyncKeyState(VK_UP))
{
z -= 10;
}
if(GetAsyncKeyState(VK_DOWN))
{
z += 10;
}
lCameraNode->setPosition(0,0,z);
lWindow->update(false);
bool lVerticalSynchro = false;
lWindow->swapBuffers(lVerticalSynchro);
lRoot->renderOneFrame();
Ogre::WindowEventUtilities::messagePump();
}
return;
}
int main()
{
try
{
AnOgreApplication();
std::cout<<"end of the program"<<std::endl;
}catch(Ogre::Exception &e)
{
MWARNING("!!!!Ogre::Exception!!!!\n" << e.what());
}catch(std::exception &e)
{
MWARNING("!!!!std::exception!!!!\n"<<e.what());
}
OgreEasy::waitForUser();
return 0;
}
ненужные кубики не исчезают окончательно. как правильно удалить ноды и ентити?