801 lines
20 KiB
C++
801 lines
20 KiB
C++
#include <iostream>
|
|
|
|
#include <Ogre.h>
|
|
#include <OgreApplicationContext.h>
|
|
#include <OgreOverlaySystem.h>
|
|
#include <OgreOverlayManager.h>
|
|
#include <OgreImGuiOverlay.h>
|
|
#include <OgreImGuiInputListener.h>
|
|
#include <OgreTrays.h>
|
|
#include <OgreTimer.h>
|
|
#include <OgreMeshLodGenerator.h>
|
|
|
|
// #include "water/water.h"
|
|
#include "GameData.h"
|
|
#include "Components.h"
|
|
#include "CharacterModule.h"
|
|
#include "TerrainModule.h"
|
|
#include "GUIModule.h"
|
|
#include "AppModule.h"
|
|
#include "sound.h"
|
|
class App;
|
|
class SkyRenderer : public Ogre::SceneManager::Listener {
|
|
protected:
|
|
Ogre::SceneManager *mSceneManager;
|
|
virtual void _updateRenderQueue(Ogre::RenderQueue *queue) = 0;
|
|
|
|
public:
|
|
enum BoxPlane {
|
|
BP_FRONT = 0,
|
|
BP_BACK = 1,
|
|
BP_LEFT = 2,
|
|
BP_RIGHT = 3,
|
|
BP_UP = 4,
|
|
BP_DOWN = 5
|
|
};
|
|
|
|
SkyRenderer(Ogre::SceneManager *owner)
|
|
: mSceneManager(owner)
|
|
, mSceneNode(0)
|
|
, mEnabled(false)
|
|
{
|
|
}
|
|
|
|
virtual ~SkyRenderer()
|
|
{
|
|
setEnabled(false);
|
|
if (mSceneNode)
|
|
mSceneManager->destroySceneNode(mSceneNode);
|
|
}
|
|
|
|
Ogre::SceneNode *mSceneNode;
|
|
bool mEnabled;
|
|
|
|
void setEnabled(bool enable)
|
|
{
|
|
if (enable == mEnabled)
|
|
return;
|
|
mEnabled = enable;
|
|
enable ? mSceneManager->addListener(this) :
|
|
mSceneManager->removeListener(this);
|
|
}
|
|
void
|
|
postFindVisibleObjects(Ogre::SceneManager *source,
|
|
Ogre::SceneManager::IlluminationRenderStage irs,
|
|
Ogre::Viewport *vp) override
|
|
{
|
|
// Queue skies, if viewport seems it
|
|
if (!vp->getSkiesEnabled() ||
|
|
irs == Ogre::SceneManager::IRS_RENDER_TO_TEXTURE)
|
|
return;
|
|
|
|
if (!mEnabled || !mSceneNode)
|
|
return;
|
|
|
|
// Update nodes
|
|
// Translate the box by the camera position (constant distance)
|
|
mSceneNode->setPosition(vp->getCamera()->getDerivedPosition());
|
|
_updateRenderQueue(source->getRenderQueue());
|
|
}
|
|
};
|
|
class SkyBoxRenderer : public SkyRenderer {
|
|
std::unique_ptr<Ogre::ManualObject> mSkyBoxObj;
|
|
|
|
Ogre::Quaternion mSkyBoxOrientation;
|
|
void _updateRenderQueue(Ogre::RenderQueue *queue) override
|
|
{
|
|
if (mSkyBoxObj->isVisible()) {
|
|
mSkyBoxObj->_updateRenderQueue(queue);
|
|
}
|
|
}
|
|
|
|
public:
|
|
SkyBoxRenderer(Ogre::SceneManager *owner)
|
|
: SkyRenderer(owner)
|
|
{
|
|
}
|
|
Ogre::SceneManager::SkyBoxGenParameters mSkyBoxGenParameters;
|
|
void create(const Ogre::String &materialName, Ogre::Real distance,
|
|
uint8_t renderQueue, const Ogre::Quaternion &orientation,
|
|
const Ogre::String &groupName)
|
|
{
|
|
Ogre::MaterialPtr m =
|
|
Ogre::MaterialManager::getSingleton().getByName(
|
|
materialName, groupName);
|
|
OgreAssert(m, "Sky box material '" + materialName +
|
|
"' not found.");
|
|
// Ensure loaded
|
|
m->load();
|
|
|
|
bool valid = m->getBestTechnique() &&
|
|
m->getBestTechnique()->getNumPasses();
|
|
#if 0
|
|
if (valid) {
|
|
Pass *pass = m->getBestTechnique()->getPass(0);
|
|
valid = valid && pass->getNumTextureUnitStates() &&
|
|
pass->getTextureUnitState(0)->getTextureType() ==
|
|
TEX_TYPE_CUBE_MAP;
|
|
}
|
|
|
|
if (!valid) {
|
|
LogManager::getSingleton().logWarning(
|
|
"skybox material " + materialName +
|
|
" is not supported, defaulting");
|
|
m = MaterialManager::getSingleton().getDefaultSettings();
|
|
}
|
|
#endif
|
|
OgreAssert(valid, "Bad material" + materialName);
|
|
|
|
// Create node
|
|
mSceneNode = mSceneManager->createSceneNode();
|
|
|
|
// Create object
|
|
mSkyBoxObj = std::make_unique<Ogre::ManualObject>("SkyBox");
|
|
mSkyBoxObj->setCastShadows(false);
|
|
mSceneNode->attachObject(mSkyBoxObj.get());
|
|
|
|
mSkyBoxObj->setRenderQueueGroup(renderQueue);
|
|
mSkyBoxObj->begin(materialName,
|
|
Ogre::RenderOperation::OT_TRIANGLE_STRIP,
|
|
groupName);
|
|
|
|
// rendering cube, only using 14 vertices
|
|
const Ogre::Vector3 cube_strip[14] = {
|
|
{ -1.f, 1.f, 1.f }, // Front-top-left
|
|
{ 1.f, 1.f, 1.f }, // Front-top-right
|
|
{ -1.f, -1.f, 1.f }, // Front-bottom-left
|
|
{ 1.f, -1.f, 1.f }, // Front-bottom-right
|
|
{ 1.f, -1.f, -1.f }, // Back-bottom-right
|
|
{ 1.f, 1.f, 1.f }, // Front-top-right
|
|
{ 1.f, 1.f, -1.f }, // Back-top-right
|
|
{ -1.f, 1.f, 1.f }, // Front-top-left
|
|
{ -1.f, 1.f, -1.f }, // Back-top-left
|
|
{ -1.f, -1.f, 1.f }, // Front-bottom-left
|
|
{ -1.f, -1.f, -1.f }, // Back-bottom-left
|
|
{ 1.f, -1.f, -1.f }, // Back-bottom-right
|
|
{ -1.f, 1.f, -1.f }, // Back-top-left
|
|
{ 1.f, 1.f, -1.f } // Back-top-right
|
|
};
|
|
|
|
for (const auto &vtx : cube_strip) {
|
|
mSkyBoxObj->position(orientation * (vtx * distance));
|
|
// Note UVs mirrored front/back
|
|
mSkyBoxObj->textureCoord(vtx.normalisedCopy() *
|
|
Ogre::Vector3(1, 1, -1));
|
|
}
|
|
|
|
mSkyBoxObj->end();
|
|
mSkyBoxGenParameters.skyBoxDistance = distance;
|
|
}
|
|
};
|
|
class App;
|
|
class KeyboardListener : public OgreBites::InputListener {
|
|
App *mApp;
|
|
|
|
uint32_t control;
|
|
ECS::Vector2 mouse;
|
|
float wheel_y;
|
|
bool mouse_moved, wheel_moved;
|
|
float mInitDelay;
|
|
|
|
public:
|
|
Ogre::Timer fps_timer;
|
|
bool fast;
|
|
KeyboardListener(App *app)
|
|
: OgreBites::InputListener()
|
|
, mApp(app)
|
|
, fast(false)
|
|
, control(0)
|
|
, mouse({ 0, 0 })
|
|
, wheel_y(0.0f)
|
|
, mouse_moved(false)
|
|
, wheel_moved(false)
|
|
, mInitDelay(1.0)
|
|
{
|
|
}
|
|
bool isGuiEnabled()
|
|
{
|
|
if (!ECS::get().has<ECS::GUI>())
|
|
return false;
|
|
return (ECS::get().get<ECS::GUI>().enabled);
|
|
}
|
|
void setGuiEnabled(bool value)
|
|
{
|
|
if (!ECS::get().has<ECS::GUI>())
|
|
return;
|
|
ECS::get().get_mut<ECS::GUI>().enabled = value;
|
|
ECS::get().modified<ECS::GUI>();
|
|
}
|
|
bool keyPressed(const OgreBites::KeyboardEvent &evt) override
|
|
{
|
|
bool updated = false;
|
|
if (isGuiEnabled())
|
|
return false;
|
|
if (evt.keysym.sym == OgreBites::SDLK_ESCAPE) {
|
|
OgreAssert(ECS::get().has<ECS::GUI>(), "");
|
|
setGuiEnabled(true);
|
|
if (ECS::get().has<ECS::GUI>())
|
|
ECS::get<ECS::GUI>().setWindowGrab(false);
|
|
return true;
|
|
}
|
|
OgreBites::Keycode key = evt.keysym.sym;
|
|
if (key == 'w')
|
|
control |= 1;
|
|
else if (key == 'a')
|
|
control |= 2;
|
|
else if (key == 's')
|
|
control |= 4;
|
|
else if (key == 'd')
|
|
control |= 8;
|
|
else if (key == OgreBites::SDLK_LSHIFT)
|
|
control |= 16;
|
|
else if (key == 'e')
|
|
control |= 32;
|
|
else if (key == 'f')
|
|
control |= 64;
|
|
if (key == 'w' || key == 'a' || key == 's' || key == 'd' ||
|
|
key == 'e' || key == OgreBites::SDLK_LSHIFT)
|
|
return true;
|
|
return false;
|
|
}
|
|
bool keyReleased(const OgreBites::KeyboardEvent &evt) override
|
|
{
|
|
OgreBites::Keycode key = evt.keysym.sym;
|
|
if (isGuiEnabled())
|
|
return false;
|
|
if (key == 'w')
|
|
control &= ~1;
|
|
else if (key == 'a')
|
|
control &= ~2;
|
|
else if (key == 's')
|
|
control &= ~4;
|
|
else if (key == 'd')
|
|
control &= ~8;
|
|
else if (key == OgreBites::SDLK_LSHIFT)
|
|
control &= ~16;
|
|
if (key == 'w' || key == 'a' || key == 's' || key == 'd' ||
|
|
key == OgreBites::SDLK_LSHIFT)
|
|
return true;
|
|
return false;
|
|
}
|
|
bool mouseMoved(const OgreBites::MouseMotionEvent &evt) override
|
|
{
|
|
if (isGuiEnabled())
|
|
return false;
|
|
mouse.x = evt.xrel;
|
|
mouse.y = evt.yrel;
|
|
mouse_moved = true;
|
|
/* no special mouse handling */
|
|
return true;
|
|
}
|
|
bool mouseWheelRolled(const OgreBites::MouseWheelEvent &evt) override
|
|
{
|
|
if (isGuiEnabled())
|
|
return false;
|
|
/* no special mouse wheel handling */
|
|
wheel_y = evt.y;
|
|
wheel_moved = true;
|
|
return true;
|
|
}
|
|
bool mousePressed(const OgreBites::MouseButtonEvent &evt) override
|
|
{
|
|
std::cout << "Mouse press " << (int)evt.button << " "
|
|
<< (int)evt.clicks << "\n";
|
|
if ((int)evt.button == 1)
|
|
control |= 256;
|
|
else
|
|
control &= ~256;
|
|
return false;
|
|
}
|
|
void frameRendered(const Ogre::FrameEvent &evt) override;
|
|
};
|
|
class App : public OgreBites::ApplicationContext {
|
|
Ogre::SceneNode *mCameraNode, *mCameraPivot, *mCameraGoal;
|
|
Ogre::Camera *mCamera;
|
|
Ogre::Real mPivotPitch;
|
|
Ogre::SceneManager *mScnMgr;
|
|
Ogre::Viewport *mViewport;
|
|
SkyBoxRenderer *sky;
|
|
bool mGrab;
|
|
KeyboardListener mKbd;
|
|
|
|
public:
|
|
App()
|
|
: OgreBites::ApplicationContext("ChoroGame")
|
|
, mKbd(this)
|
|
, mGrab(false)
|
|
{
|
|
}
|
|
virtual ~App()
|
|
{
|
|
}
|
|
void setup()
|
|
{
|
|
OgreBites::ApplicationContext::setup();
|
|
Ogre::Root *root = getRoot();
|
|
Ogre::SceneManager *scnMgr = root->createSceneManager();
|
|
mScnMgr = scnMgr;
|
|
Ogre::OverlaySystem *pOverlaySystem = getOverlaySystem();
|
|
mScnMgr->addRenderQueueListener(pOverlaySystem);
|
|
// mTrayMgr = new OgreBites::TrayManager("AppTrays",
|
|
// getRenderWindow());
|
|
}
|
|
bool isWindowGrab()
|
|
{
|
|
return mGrab;
|
|
}
|
|
void locateResources() override
|
|
{
|
|
Ogre::ResourceGroupManager::getSingleton().createResourceGroup(
|
|
"Water", true);
|
|
Ogre::ResourceGroupManager::getSingleton().createResourceGroup(
|
|
"LuaScripts", false);
|
|
Ogre::ResourceGroupManager::getSingleton().addResourceLocation(
|
|
"./lua-scripts", "FileSystem", "LuaScripts", true,
|
|
true);
|
|
OgreBites::ApplicationContext::locateResources();
|
|
}
|
|
void loadResources() override
|
|
{
|
|
}
|
|
void setWindowGrab(bool grab = true)
|
|
{
|
|
mGrab = grab;
|
|
ApplicationContextBase::setWindowGrab(grab);
|
|
}
|
|
|
|
void initCamera()
|
|
{
|
|
mCameraNode = mScnMgr->getRootSceneNode()->createChildSceneNode(
|
|
"CameraNode");
|
|
mCameraNode->setPosition(0, 2, 3);
|
|
mCameraNode->lookAt(Ogre::Vector3(0, 1, -1),
|
|
Ogre::Node::TS_PARENT);
|
|
|
|
// create the camera
|
|
mCamera = mScnMgr->createCamera("fps_camera");
|
|
mCamera->setNearClipDistance(0.05f);
|
|
mCamera->setAutoAspectRatio(true);
|
|
mCameraNode->attachObject(mCamera);
|
|
|
|
// and tell it to render into the main window
|
|
mViewport = getRenderWindow()->addViewport(mCamera);
|
|
mCameraPivot =
|
|
mScnMgr->getRootSceneNode()->createChildSceneNode(
|
|
"FPSCameraPivot");
|
|
mCameraGoal = mCameraPivot->createChildSceneNode(
|
|
"FPSCameraGoal", Ogre::Vector3(0, 2, 3));
|
|
mCameraNode->setPosition(mCameraPivot->getPosition() +
|
|
mCameraGoal->getPosition());
|
|
mCameraPivot->setFixedYawAxis(true);
|
|
mCameraGoal->setFixedYawAxis(true);
|
|
mCameraNode->setFixedYawAxis(true);
|
|
// our model is quite small, so reduce the clipping planes
|
|
mCamera->setNearClipDistance(0.1f);
|
|
mCamera->setFarClipDistance(800);
|
|
mPivotPitch = 0;
|
|
}
|
|
void configure()
|
|
{
|
|
std::cout << "Startup" << "\n";
|
|
initApp();
|
|
std::cout << "Set up RTSS" << "\n";
|
|
Ogre::Root *root = getRoot();
|
|
Ogre::SceneManager *scnMgr = getSceneManager();
|
|
|
|
// register our scene with the RTSS
|
|
Ogre::RTShader::ShaderGenerator *shadergen =
|
|
Ogre::RTShader::ShaderGenerator::getSingletonPtr();
|
|
shadergen->addSceneManager(scnMgr);
|
|
setWindowGrab(true);
|
|
std::cout << "Init camera" << "\n";
|
|
initCamera();
|
|
std::cout << "Set up water" << "\n";
|
|
std::cout << "Set up cursor" << "\n";
|
|
Ogre::ResourceGroupManager::getSingleton()
|
|
.initialiseAllResourceGroups();
|
|
// OgreBites::ApplicationContext::loadResources();
|
|
// setupCursor();
|
|
std::cout << "Setup input" << "\n";
|
|
setupInput();
|
|
std::cout << "Create content" << "\n";
|
|
createContent();
|
|
std::cout << "Setup done" << "\n";
|
|
#if 0
|
|
mDbgDraw->setDebugMode(mDbgDraw->getDebugMode() |
|
|
btIDebugDraw::DBG_DrawContactPoints);
|
|
#endif
|
|
}
|
|
Ogre::SceneManager *getSceneManager()
|
|
{
|
|
return mScnMgr;
|
|
}
|
|
Ogre::Timer mTerrainUpd;
|
|
bool isTerrainReady()
|
|
{
|
|
if (ECS::get().has<ECS::Terrain>())
|
|
return ECS::get().get<ECS::Terrain>().mTerrainReady;
|
|
return false;
|
|
}
|
|
// TODO: implement rough water level calculation
|
|
float getWaterLevel(const Ogre::Vector3 &position)
|
|
{
|
|
Ogre::Vector3::UNIT_Y;
|
|
float etime =
|
|
Ogre::ControllerManager::getSingleton().getElapsedTime();
|
|
return 0.0f;
|
|
}
|
|
void updateWorld(float delta)
|
|
{
|
|
#if 0
|
|
mDynWorld->getBtWorld()->stepSimulation(delta, 3);
|
|
#endif
|
|
if (!ECS::get().has<ECS::GUI>())
|
|
return;
|
|
/* Update window grab */
|
|
ECS::GUI &gui = ECS::get().get_mut<ECS::GUI>();
|
|
if (gui.grabChanged) {
|
|
setWindowGrab(gui.grab);
|
|
gui.grabChanged = false;
|
|
ECS::get().modified<ECS::GUI>();
|
|
}
|
|
ECS::update(delta);
|
|
|
|
#if 0
|
|
if (ECS::get<ECS::EngineData>().enableDbgDraw)
|
|
mDbgDraw->update();
|
|
#endif
|
|
}
|
|
class InputListenerChainFlexible : public OgreBites::InputListener {
|
|
protected:
|
|
std::vector<OgreBites::InputListener *> mListenerChain;
|
|
|
|
public:
|
|
InputListenerChainFlexible()
|
|
{
|
|
}
|
|
InputListenerChainFlexible(std::vector<InputListener *> chain)
|
|
: mListenerChain(chain)
|
|
{
|
|
}
|
|
|
|
void add(OgreBites::InputListener *listener)
|
|
{
|
|
mListenerChain.push_back(listener);
|
|
}
|
|
void erase(OgreBites::InputListener *listener)
|
|
{
|
|
mListenerChain.erase(std::find(mListenerChain.begin(),
|
|
mListenerChain.end(),
|
|
listener));
|
|
}
|
|
bool empty() const
|
|
{
|
|
return mListenerChain.empty();
|
|
}
|
|
|
|
InputListenerChainFlexible &
|
|
operator=(const InputListenerChainFlexible &o)
|
|
{
|
|
mListenerChain = o.mListenerChain;
|
|
return *this;
|
|
}
|
|
|
|
void frameRendered(const Ogre::FrameEvent &evt) override
|
|
{
|
|
for (auto listener : mListenerChain)
|
|
listener->frameRendered(evt);
|
|
}
|
|
|
|
bool keyPressed(const OgreBites::KeyboardEvent &evt) override
|
|
{
|
|
for (auto listner : mListenerChain) {
|
|
if (listner->keyPressed(evt))
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
bool keyReleased(const OgreBites::KeyboardEvent &evt) override
|
|
{
|
|
for (auto listner : mListenerChain) {
|
|
if (listner->keyReleased(evt))
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
bool touchMoved(const OgreBites::TouchFingerEvent &evt) override
|
|
{
|
|
for (auto listner : mListenerChain) {
|
|
if (listner->touchMoved(evt))
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
bool
|
|
touchPressed(const OgreBites::TouchFingerEvent &evt) override
|
|
{
|
|
for (auto listner : mListenerChain) {
|
|
if (listner->touchPressed(evt))
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
bool
|
|
touchReleased(const OgreBites::TouchFingerEvent &evt) override
|
|
{
|
|
for (auto listner : mListenerChain) {
|
|
if (listner->touchReleased(evt))
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
bool mouseMoved(const OgreBites::MouseMotionEvent &evt) override
|
|
{
|
|
for (auto listner : mListenerChain) {
|
|
if (listner->mouseMoved(evt))
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
bool
|
|
mouseWheelRolled(const OgreBites::MouseWheelEvent &evt) override
|
|
{
|
|
for (auto listner : mListenerChain) {
|
|
if (listner->mouseWheelRolled(evt))
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
bool
|
|
mousePressed(const OgreBites::MouseButtonEvent &evt) override
|
|
{
|
|
for (auto listner : mListenerChain) {
|
|
if (listner->mousePressed(evt))
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
bool
|
|
mouseReleased(const OgreBites::MouseButtonEvent &evt) override
|
|
{
|
|
for (auto listner : mListenerChain) {
|
|
if (listner->mouseReleased(evt))
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
bool textInput(const OgreBites::TextInputEvent &evt) override
|
|
{
|
|
for (auto listner : mListenerChain) {
|
|
if (listner->textInput(evt))
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
};
|
|
flecs::entity input_update;
|
|
flecs::entity find_wait_gui;
|
|
void setupInput()
|
|
{
|
|
}
|
|
void createContent()
|
|
{
|
|
int i;
|
|
sky = new SkyBoxRenderer(getSceneManager());
|
|
bool drawFirst = true;
|
|
uint8_t renderQueue = drawFirst ?
|
|
Ogre::RENDER_QUEUE_SKIES_EARLY :
|
|
Ogre::RENDER_QUEUE_SKIES_LATE;
|
|
sky->create("Skybox/Dynamic", 450, renderQueue,
|
|
Ogre::Quaternion::IDENTITY,
|
|
Ogre::ResourceGroupManager::
|
|
AUTODETECT_RESOURCE_GROUP_NAME);
|
|
sky->setEnabled(true);
|
|
|
|
Ogre::MaterialPtr m =
|
|
Ogre::MaterialManager::getSingleton().getByName(
|
|
"Skybox/Dynamic", "General");
|
|
OgreAssert(m, "Sky box material not found.");
|
|
m->load();
|
|
ECS::setup(mScnMgr, /*mDynWorld.get(), */ mCameraNode, mCamera,
|
|
getRenderWindow());
|
|
ECS::get().set<ECS::RenderWindow>(
|
|
{ getRenderWindow(), getDisplayDPI() });
|
|
ECS::get()
|
|
.observer<ECS::GUI>("UpdateGrab")
|
|
.event(flecs::OnSet)
|
|
.each([this](flecs::entity e, ECS::GUI &gui) {
|
|
if (gui.grabChanged)
|
|
setWindowGrab(gui.grab);
|
|
std::cout << "grab: " << gui.grab << "\n";
|
|
std::cout << "GUI enabled: " << gui.enabled
|
|
<< "\n";
|
|
});
|
|
ECS::get()
|
|
.observer<ECS::App>("UpdateInputListener")
|
|
.event(flecs::OnSet)
|
|
.each([this](flecs::entity e, ECS::App &app) {
|
|
if (app.mInput)
|
|
removeInputListener(app.mInput);
|
|
delete app.mInput;
|
|
app.mInput =
|
|
OGRE_NEW OgreBites::InputListenerChain(
|
|
app.listeners);
|
|
addInputListener(app.mInput);
|
|
});
|
|
#if 0
|
|
ECS::get()
|
|
.observer<ECS::GUI, ECS::App>("SetInputListener2")
|
|
.event(flecs::OnSet)
|
|
.each([this](ECS::GUI &gui, ECS::App &app) {
|
|
if (gui.mGuiInpitListener &&
|
|
app.listeners.size() == 1) {
|
|
app.listeners.clear();
|
|
app.listeners.push_back(
|
|
gui.mGuiInpitListener);
|
|
app.listeners.push_back(&mKbd);
|
|
ECS::modified<ECS::App>();
|
|
}
|
|
});
|
|
#endif
|
|
#if 0
|
|
input_update =
|
|
ECS::get()
|
|
.system<ECS::GUI, ECS::App>("SetInputListener")
|
|
.kind(flecs::OnUpdate)
|
|
.each([this](ECS::GUI &gui, ECS::App &app) {
|
|
if (app.listeners.size() < 2 &&
|
|
gui.mGuiInpitListener) {
|
|
OgreBites::InputListener *guiListener =
|
|
gui.mGuiInpitListener;
|
|
if (guiListener) {
|
|
app.listeners.clear();
|
|
app.listeners.push_back(
|
|
guiListener);
|
|
app.listeners.push_back(
|
|
&mKbd);
|
|
std::cout
|
|
<< "input update complete\n";
|
|
gui.mGuiInpitListener =
|
|
guiListener;
|
|
if (app.mInput)
|
|
removeInputListener(
|
|
app.mInput);
|
|
delete app.mInput;
|
|
app.mInput = new OgreBites::
|
|
InputListenerChain(
|
|
app.listeners);
|
|
addInputListener(
|
|
app.mInput);
|
|
std::cout
|
|
<< "update listeners: "
|
|
<< app.listeners
|
|
.size()
|
|
<< "\n";
|
|
if (app.listeners
|
|
.size() ==
|
|
2)
|
|
OgreAssert(
|
|
app.listeners.size() ==
|
|
2,
|
|
"");
|
|
input_update.disable();
|
|
OgreAssert(false, "");
|
|
} else {
|
|
app.listeners.clear();
|
|
app.listeners.push_back(
|
|
&mKbd);
|
|
}
|
|
} else
|
|
input_update.disable();
|
|
std::cout << "input update "
|
|
<< app.listeners.size()
|
|
<< "\n";
|
|
});
|
|
#endif
|
|
ECS::get().set<ECS::App>(
|
|
{ initialiseImGui(),
|
|
nullptr,
|
|
{ getImGuiInputListener(), &mKbd } });
|
|
Sound::setup();
|
|
Sound::ding();
|
|
}
|
|
void create_entity_node(const Ogre::String &name, int key)
|
|
{
|
|
Ogre::Entity *ent = mScnMgr->createEntity(name);
|
|
Ogre::SceneNode *pnode =
|
|
mScnMgr->getRootSceneNode()->createChildSceneNode(
|
|
"ent:" + name +
|
|
Ogre::StringConverter::toString(key),
|
|
mCameraPivot->getPosition(),
|
|
mCameraPivot->getOrientation());
|
|
pnode->attachObject(ent);
|
|
Ogre::Quaternion q = pnode->getOrientation();
|
|
Ogre::Radian yaw = q.getYaw();
|
|
Ogre::Quaternion nq(yaw, Ogre::Vector3(0, 1, 0));
|
|
pnode->setOrientation(nq);
|
|
set_gui_active(false);
|
|
ECS::get<ECS::GUI>().setWindowGrab(true);
|
|
}
|
|
bool get_gui_active()
|
|
{
|
|
return ECS::get().get<ECS::GUI>().enabled;
|
|
}
|
|
void set_gui_active(bool active)
|
|
{
|
|
ECS::get().get_mut<ECS::GUI>().enabled = active;
|
|
ECS::get().modified<ECS::GUI>();
|
|
}
|
|
Ogre::Camera *getCamera()
|
|
{
|
|
return mCamera;
|
|
}
|
|
flecs::entity getPlayer() const
|
|
{
|
|
flecs::entity player =
|
|
ECS::get().lookup("ECS::CharacterModule::player");
|
|
return player;
|
|
}
|
|
void enableDbgDraw(bool enable)
|
|
{
|
|
ECS::get_mut<ECS::EngineData>().enableDbgDraw = enable;
|
|
ECS::modified<ECS::EngineData>();
|
|
}
|
|
bool isEnabledDbgDraw() const
|
|
{
|
|
return ECS::get<ECS::EngineData>().enableDbgDraw;
|
|
}
|
|
};
|
|
void KeyboardListener::frameRendered(const Ogre::FrameEvent &evt)
|
|
{
|
|
if (fps_timer.getMilliseconds() > 1000.0f) {
|
|
std::cout << "FPS: "
|
|
<< mApp->getRenderWindow()->getStatistics().lastFPS
|
|
<< " ";
|
|
std::cout << "Draw calls: "
|
|
<< mApp->getRenderWindow()->getStatistics().batchCount
|
|
<< " ";
|
|
fps_timer.reset();
|
|
std::cout << "Drops: "
|
|
<< mApp->getRenderWindow()
|
|
->getStatistics()
|
|
.vBlankMissCount
|
|
<< "\n";
|
|
fps_timer.reset();
|
|
}
|
|
if (!isGuiEnabled() ||
|
|
(isGuiEnabled() && ECS::get<ECS::GUI>().narrationBox)) {
|
|
mApp->updateWorld(evt.timeSinceLastFrame);
|
|
if (mInitDelay >= 0.0f)
|
|
mInitDelay -= evt.timeSinceLastFrame;
|
|
}
|
|
|
|
if (!isGuiEnabled() && ECS::get().has<ECS::Input>()) {
|
|
ECS::Input &input = ECS::get().get_mut<ECS::Input>();
|
|
input.control = control;
|
|
input.mouse = mouse;
|
|
mouse.x = 0;
|
|
mouse.y = 0;
|
|
input.wheel_y = wheel_y;
|
|
wheel_y = 0;
|
|
input.mouse_moved = mouse_moved;
|
|
input.wheel_moved = wheel_moved;
|
|
}
|
|
}
|
|
|
|
int main()
|
|
{
|
|
App ctx;
|
|
ctx.configure();
|
|
// ctx.runRenderingSettingsDialog();
|
|
// get a pointer to the already created root
|
|
// register for input events
|
|
// KeyHandler keyHandler;
|
|
// ctx.addInputListener(&keyHandler);
|
|
ctx.enableDbgDraw(false);
|
|
ctx.getRoot()->startRendering();
|
|
ctx.setWindowGrab(false);
|
|
ctx.closeApp();
|
|
return 0;
|
|
}
|