234 lines
8.7 KiB
C++
234 lines
8.7 KiB
C++
#include <OgreWidget.hpp>
|
|
#include <QApplication>
|
|
#include <filesystem>
|
|
|
|
#include <OGRE/Bites/OgreSGTechniqueResolverListener.h>
|
|
#include <OGRE/OgreDefaultDebugDrawer.h>
|
|
#include <OGRE/Overlay/OgreOverlaySystem.h>
|
|
#include <OGRE/Overlay/OgreOverlayManager.h>
|
|
#include <OGRE/Overlay/OgreFontManager.h>
|
|
#include <App/V8/DataModel/Lighting.hpp>
|
|
|
|
#ifdef __unix__
|
|
#include <qpa/qplatformnativeinterface.h>
|
|
#include <X11/Xlib.h>
|
|
#endif
|
|
|
|
// credits to https://github.com/Ekman/Qt-Ogre-Widget
|
|
namespace RNR
|
|
{
|
|
OgreWidget::OgreWidget(Ogre::Root *root, QWidget *parent) : QWidget(parent)
|
|
{
|
|
this->ogreRoot = root;
|
|
this->setMinimumSize(640, 480);
|
|
this->ogreWindow = NULL;
|
|
|
|
this->setAttribute(Qt::WA_OpaquePaintEvent);
|
|
this->setAttribute(Qt::WA_PaintOnScreen);
|
|
this->setMouseTracking(true);
|
|
//this->setCursor(QCursor(Qt::BlankCursor));
|
|
this->setFocusPolicy(Qt::StrongFocus);
|
|
this->selectedInstance = 0;
|
|
|
|
inputManager = new QtInputManager(this);
|
|
}
|
|
|
|
void OgreWidget::initializeOgre()
|
|
{
|
|
Ogre::NameValuePairList options = this->getRenderOptions();
|
|
|
|
printf("OgreWidget::initializeOgre: initializing render window\n");
|
|
Ogre::OverlaySystem* ogreOverlay = new Ogre::OverlaySystem();
|
|
|
|
ogreWindow = ogreRoot->createRenderWindow("GLWidget-RenderWindow", width(), height(), false, &options);
|
|
ogreWindow->setActive(true);
|
|
ogreWindow->setVisible(true);
|
|
ogreWindow->setAutoUpdated(true);
|
|
|
|
|
|
Ogre::ResourceGroupManager::getSingletonPtr()->addResourceLocation("shaders", "FileSystem", Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);
|
|
|
|
//Ogre::ResourceGroupManager::getSingletonPtr()->addResourceLocation("../Content/OgrePrivate/RTShaderLib/GLSL/", "FileSystem", Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); // rtshader path
|
|
//Ogre::ResourceGroupManager::getSingletonPtr()->initialiseAllResourceGroups();
|
|
|
|
ogreSceneManager = ogreRoot->createSceneManager();
|
|
ogreSceneManager->setAmbientLight(Ogre::ColourValue(0.2f,0.2f,0.2f));
|
|
ogreSceneManager->addRenderQueueListener(ogreOverlay);
|
|
|
|
Ogre::SceneNode* camNode = ogreSceneManager->getRootSceneNode()->createChildSceneNode();
|
|
camNode->setPosition(0, 0, 5);
|
|
camNode->lookAt(Ogre::Vector3(0, sinf(render_time), cosf(render_time)), Ogre::Node::TS_PARENT);
|
|
|
|
ogreCamera = ogreSceneManager->createCamera("myCam");
|
|
ogreCamera->setNearClipDistance(0.1); // specific to this sample
|
|
ogreCamera->setFarClipDistance(1000.f);
|
|
ogreCamera->setAutoAspectRatio(true);
|
|
ogreCamera->setFOVy(Ogre::Degree(70.f));
|
|
ogreCamera->setUseRenderingDistance(true);
|
|
camNode->attachObject(ogreCamera);
|
|
|
|
ogreViewport = ogreWindow->addViewport(ogreCamera);
|
|
|
|
if(Ogre::RTShader::ShaderGenerator::initialize())
|
|
{
|
|
ogreShaderGen = Ogre::RTShader::ShaderGenerator::getSingletonPtr();
|
|
|
|
if (!std::filesystem::is_directory("ShaderCache") || !std::filesystem::exists("ShaderCache")) {
|
|
std::filesystem::create_directory("ShaderCache");
|
|
}
|
|
|
|
ogreShaderGen->setShaderCachePath("ShaderCache/");
|
|
ogreShaderGen->addSceneManager(ogreSceneManager);
|
|
|
|
OgreBites::SGTechniqueResolverListener* technique_resolver = new OgreBites::SGTechniqueResolverListener(ogreShaderGen);
|
|
Ogre::MaterialManager::getSingleton().addListener(technique_resolver);
|
|
|
|
printf("OgreWidget::initializeOgre: initialized ShaderGenerator successfully\n");
|
|
}
|
|
else
|
|
printf("OgreWidget::initializeOgre: unable to initialize ShaderGenerator\n");
|
|
|
|
Ogre::ResourceGroupManager::getSingletonPtr()->addResourceLocation("content", "FileSystem", Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, true);
|
|
Ogre::ResourceGroupManager::getSingletonPtr()->initialiseAllResourceGroups();
|
|
|
|
Ogre::FontPtr pFont = Ogre::FontManager::getSingletonPtr()->create("ComicSans", Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);
|
|
pFont->setType(Ogre::FT_TRUETYPE);
|
|
pFont->setSource("fonts/comic.ttf");
|
|
pFont->setTrueTypeSize(16);
|
|
pFont->load();
|
|
|
|
ogreSceneManager->setShadowTechnique(Ogre::ShadowTechnique::SHADOWTYPE_STENCIL_MODULATIVE);
|
|
ogreSceneManager->setShadowFarDistance(500.f);
|
|
|
|
ogreSceneLight = ogreSceneManager->createLight("SunLight");
|
|
Ogre::SceneNode* lightNode = ogreSceneManager->getRootSceneNode()->createChildSceneNode();
|
|
lightNode->setPosition(0, 10, 15);
|
|
lightNode->setDirection(-0.25, -0.5, -0.5);
|
|
lightNode->attachObject(ogreSceneLight);
|
|
|
|
ogreSceneLight->setCastShadows(true);
|
|
ogreSceneLight->setDiffuseColour(0.9, 0.9, 1.0);
|
|
ogreSceneLight->setSpecularColour(1.0, 1.0, 1.0);
|
|
ogreSceneLight->setType(Ogre::Light::LT_DIRECTIONAL);
|
|
|
|
Ogre::MaterialManager::getSingletonPtr()->reloadAll();
|
|
Ogre::MaterialManager::getSingletonPtr()->load("sky/null_plainsky512", Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);
|
|
ogreSceneManager->setSkyBox(true, "sky/null_plainsky512");
|
|
|
|
this->render_time = 0.0;
|
|
}
|
|
|
|
void OgreWidget::render()
|
|
{
|
|
if(!world)
|
|
return;
|
|
|
|
this->delta = ogreRoot->getTimer()->getMicroseconds() / 1000000.0;
|
|
this->render_time += ogreRoot->getTimer()->getMilliseconds() / 1000.0;
|
|
ogreRoot->getTimer()->reset();
|
|
|
|
if(world->getWorkspace()->getCurrentCamera())
|
|
{
|
|
Camera* cam = world->getWorkspace()->getCurrentCamera();
|
|
ogreCamera->getParentSceneNode()->setPosition(cam->getCFrame().getPosition());
|
|
ogreCamera->getParentSceneNode()->setOrientation(Ogre::Quaternion(cam->getCFrame().getRotation()));
|
|
}
|
|
|
|
RNR::Lighting* lighting = (RNR::Lighting*)world->getDatamodel()->getService("Lighting");
|
|
if(lighting)
|
|
{
|
|
Ogre::Vector3 clearColor = lighting->getClearColor();
|
|
ogreViewport->setBackgroundColour(Ogre::ColourValue(clearColor.x, clearColor.y, clearColor.z));
|
|
Ogre::Vector3 shadowColor = lighting->getShadowColor();
|
|
ogreSceneManager->setShadowColour(Ogre::ColourValue(shadowColor.x, shadowColor.y, shadowColor.z));
|
|
Ogre::Vector3 topAmbient = lighting->getTopAmbient();
|
|
ogreSceneLight->setDiffuseColour(Ogre::ColourValue(topAmbient.x, topAmbient.y, topAmbient.z));
|
|
Ogre::Vector3 bottomAmbient = lighting->getBottomAmbient();
|
|
ogreSceneManager->setAmbientLight(Ogre::ColourValue(bottomAmbient.x, bottomAmbient.y, bottomAmbient.z));
|
|
Ogre::Vector3 spotLight = lighting->getSpotLight();
|
|
ogreSceneLight->setSpecularColour(Ogre::ColourValue(spotLight.x, spotLight.y, spotLight.z));
|
|
}
|
|
|
|
if(isVisible())
|
|
ogreRoot->renderOneFrame(this->delta);
|
|
}
|
|
|
|
Ogre::NameValuePairList OgreWidget::getRenderOptions()
|
|
{
|
|
Ogre::NameValuePairList options;
|
|
|
|
options["externalWindowHandle"] = getWindowHandle();
|
|
options["FSAA"] = "4";
|
|
#ifdef FORCE_ENABLE_VSYNC
|
|
options["vsync"] = "true";
|
|
#endif
|
|
#if OGRE_PLATFORM == OGRE_PLATFORM_APPLE
|
|
options["macAPI"] = "cocoa";
|
|
options["macAPICocoaUseNSView"] = "true";
|
|
#endif
|
|
|
|
return options;
|
|
}
|
|
|
|
Ogre::String OgreWidget::getWindowHandle()
|
|
{
|
|
Ogre::String windowHandle;
|
|
windowHandle = Ogre::StringConverter::toString((unsigned long)winId());
|
|
printf("OgreWidget::getWindowHandle(): %s\n", windowHandle.c_str());
|
|
return windowHandle;
|
|
}
|
|
|
|
void OgreWidget::resizeEvent(QResizeEvent *rEvent)
|
|
{
|
|
QWidget::resizeEvent(rEvent);
|
|
if(ogreWindow)
|
|
{
|
|
QSize size = rEvent->size();
|
|
ogreWindow->resize(size.width(), size.height());
|
|
}
|
|
}
|
|
|
|
void OgreWidget::paintEvent(QPaintEvent *pEvent)
|
|
{
|
|
//
|
|
}
|
|
|
|
void OgreWidget::keyPressEvent(QKeyEvent *e)
|
|
{
|
|
inputManager->keyEvent(e);
|
|
}
|
|
|
|
void OgreWidget::keyReleaseEvent(QKeyEvent *e)
|
|
{
|
|
inputManager->keyEvent(e);
|
|
}
|
|
|
|
void OgreWidget::mousePressEvent(QMouseEvent *e)
|
|
{
|
|
inputManager->mouseEvent(e);
|
|
}
|
|
|
|
void OgreWidget::mouseReleaseEvent(QMouseEvent *e)
|
|
{
|
|
inputManager->mouseEvent(e);
|
|
}
|
|
|
|
void OgreWidget::mouseMoveEvent(QMouseEvent *mEvent)
|
|
{
|
|
inputManager->mouseEvent(mEvent);
|
|
}
|
|
|
|
void OgreWidget::closeEvent(QCloseEvent* event)
|
|
{
|
|
delete world;
|
|
|
|
ogreWindow->destroy();
|
|
ogreRoot->destroySceneManager(ogreSceneManager);
|
|
ogreRoot->shutdown();
|
|
}
|
|
|
|
QPaintEngine* OgreWidget::paintEngine() const
|
|
{
|
|
return 0;
|
|
}
|
|
} |