#ifndef OGREWIDGET8_H #define OGREWIDGET8_H #include <QWidget> #include <Ogre.h> #include <OISEvents.h> #include <OISInputManager.h> #include <OISKeyboard.h> #include <OISMouse.h> #include <SdkTrays.h> #include <SdkCameraMan.h> class OgreWidget8 : public QWidget, public Ogre::FrameListener, public Ogre::WindowEventListener, OgreBites::SdkTrayListener { Q_OBJECT public: explicit OgreWidget8(QWidget *parent = 0); ~OgreWidget8(); // Override QWidget::paintEngine to return NULL. QPaintEngine *paintEngine() const; // Turn off QT's paint engine for the Ogre Widget. // void go(); signals: void cameraPositionChanged(const Ogre::Vector3 &pos); public slots: void setBackgroundColor(QColor c); void setCameraPosition(const Ogre::Vector3 &pos); protected: void keyPressEvent(QKeyEvent *e); void keyReleaseEvent(QKeyEvent *e); void mousePressEvent(QMouseEvent *e); void mouseReleaseEvent(QMouseEvent *e); void mouseMoveEvent(QMouseEvent *e); void mouseDoubleClickEvent(QMouseEvent *e); void wheelEvent(QWheelEvent *e); void paintEvent(QPaintEvent *e); void resizeEvent(QResizeEvent *e); void showEvent(QShowEvent *e); void moveEvent(QMoveEvent *e); // bool configure(); void chooseSceneManager(); void createCamera(); void createViewports(); void createFrameListener(); void createScene(); // void destroyScene(); // void createResourceListener(); void loadOgreResources(); bool frameRenderingQueued(const Ogre::FrameEvent &evt); private: void initOgreSystem(); void setupViewport(Ogre::SceneManager *curr); void dualViewport(Ogre::SceneManager *priSceneMgr, Ogre::SceneManager *secSceneMgr); static const Ogre::Real turboModifier; static const QPoint invalidMousePoint; Ogre::Root *ogreRoot; Ogre::SceneManager *ogreSceneManager; Ogre::SceneManager *primarySceneMgr; Ogre::SceneManager *secondarySceneMgr; Ogre::RenderWindow *ogreRenderWindow; Ogre::Camera *ogreCamera; Ogre::Viewport *ogreViewport; QPoint oldPos; Ogre::SceneNode *selectedNode; bool mDual; // OgreBites OgreBites::SdkTrayManager *mTrayMgr; OgreBites::SdkCameraMan *mCameraMan; // basic camera controller OgreBites::ParamsPanel *mDetailsPanel; // sample details panel bool mCursorWasVisible; // was cursor visible before dialog appeared bool mShutDown; }; #endif // OGREWIDGET8_H #include <QtGui> #include <QX11Info> #include <algorithm> #include <OGRE/OgreStringVector.h> #include "ogrewidget8.h" using namespace std; const Ogre::Real OgreWidget8::turboModifier(10); const QPoint OgreWidget8::invalidMousePoint(-1, -1); #define CAMERA_NAME "SceneCamera" OgreWidget8::OgreWidget8(QWidget *parent) : QWidget(parent), ogreRoot(0), ogreSceneManager(0), primarySceneMgr(0), secondarySceneMgr(0), ogreRenderWindow(0), ogreCamera(0), ogreViewport(0), oldPos(invalidMousePoint), selectedNode(0), mDual(false), mTrayMgr(0), mCameraMan(0), mDetailsPanel(0), mCursorWasVisible(false), mShutDown(false) { setAttribute(Qt::WA_OpaquePaintEvent); setAttribute(Qt::WA_PaintOnScreen); setMinimumSize(250, 250); setFocusPolicy(Qt::ClickFocus); } OgreWidget8::~OgreWidget8() { if (mTrayMgr) delete mTrayMgr; if (mCameraMan) delete mCameraMan; // Ogre::WindowEventUtilities::removeWindowEventListener(ogreRenderWindow, this); // windowClosed(ogreRenderWindow); if (ogreRenderWindow) ogreRenderWindow->removeAllViewports(); if (ogreRoot) { ogreRoot->detachRenderTarget(ogreRenderWindow); if (ogreSceneManager) ogreRoot->destroySceneManager(ogreSceneManager); } delete ogreRoot; } QPaintEngine *OgreWidget8::paintEngine() const { // We don't want another paint engine to get in the way for our OGRE based paint engine. // So we return nothing. return NULL; } void OgreWidget8::setBackgroundColor(QColor c) { if (ogreViewport) { Ogre::ColourValue ogreColour; ogreColour.setAsRGBA(c.rgba()); ogreViewport->setBackgroundColour(ogreColour); } } void OgreWidget8::setCameraPosition(const Ogre::Vector3 &pos) { // ogreCamera->setPosition(pos); // ogreCamera->lookAt(0, 80, 0); // update(); // emit cameraPositionChanged(pos); } void OgreWidget8::keyPressEvent(QKeyEvent *e) { // if (mTrayMgr && mTrayMgr->isDialogVisible()) // return; // don't process any more keys if dialog is up static int i = 0; Ogre::PolygonMode pm[] = {Ogre::PM_WIREFRAME, Ogre::PM_POINTS, Ogre::PM_SOLID}; switch (e->key()) { case Qt::Key_V: mDual = !mDual; if (mDual) dualViewport(primarySceneMgr, secondarySceneMgr); else setupViewport(primarySceneMgr); update(); break; case Qt::Key_C: swap(primarySceneMgr, secondarySceneMgr); if (mDual) dualViewport(primarySceneMgr, secondarySceneMgr); else setupViewport(primarySceneMgr); update(); break; // case Qt::Key_F: // mTrayMgr->toggleAdvancedFrameStats(); // toggle visibility of advanced frame stats // update(); // break; case Qt::Key_R: ogreCamera->setPolygonMode(pm[i++ % 3]); update(); break; case Qt::Key_F5: // refresh all textures Ogre::TextureManager::getSingleton().reloadAll(); update(); break; case Qt::Key_F12: ogreRenderWindow->writeContentsToTimestampedFile("screenshot", ".jpg"); break; case Qt::Key_F11: if (isFullScreen()) showNormal(); else showFullScreen(); break; case Qt::Key_Escape: mShutDown = true; qApp->quit(); break; default: QWidget::keyPressEvent(e); } // static QMap<int, Ogre::Vector3> keyCoordModificationMapping; // static bool mappingInitialised = false; // if (!mappingInitialised) { // keyCoordModificationMapping[Qt::Key_W] = Ogre::Vector3(0, 0, -5); // keyCoordModificationMapping[Qt::Key_S] = Ogre::Vector3(0, 0, 5); // keyCoordModificationMapping[Qt::Key_A] = Ogre::Vector3(-5, 0, 0); // keyCoordModificationMapping[Qt::Key_D] = Ogre::Vector3(5, 0, 0); // keyCoordModificationMapping[Qt::Key_PageUp] = Ogre::Vector3(0, 5, 0); // keyCoordModificationMapping[Qt::Key_PageDown] = Ogre::Vector3(0, -5, 0); // mappingInitialised = true; // } // QMap<int, Ogre::Vector3>::iterator keyPressed = keyCoordModificationMapping.find(e->key()); // if (keyPressed != keyCoordModificationMapping.end() && ogreCamera) { // const Ogre::Vector3 &actualCamPos = ogreCamera->getPosition(); // setCameraPosition(actualCamPos + keyPressed.value()); // e->accept(); // } else // e->ignore(); } void OgreWidget8::keyReleaseEvent(QKeyEvent *e) { } void OgreWidget8::mousePressEvent(QMouseEvent *e) { if (e->buttons().testFlag(Qt::LeftButton)) { oldPos = e->pos(); e->accept(); } else e->ignore(); } void OgreWidget8::mouseReleaseEvent(QMouseEvent *e) { if (e->buttons().testFlag(Qt::LeftButton)) { oldPos = QPoint(invalidMousePoint); e->accept(); } else e->ignore(); } void OgreWidget8::mouseMoveEvent(QMouseEvent *e) { // if (e->buttons().testFlag(Qt::LeftButton) && oldPos != invalidMousePoint) { // const QPoint &pos = e->pos(); // Ogre::Real dx = e->x() - oldPos.x(); // Ogre::Real dy = e->y() - oldPos.y(); // if (e->modifiers().testFlag(Qt::ControlModifier)) { // dx *= turboModifier; // dy *= turboModifier; // } // Ogre::Vector3 camTranslation(dx, dy, 0); // const Ogre::Vector3 &actualCamPos = ogreCamera->getPosition(); // setCameraPosition(actualCamPos + camTranslation); // oldPos = e->pos(); // e->accept(); // } else // e->ignore(); } void OgreWidget8::mouseDoubleClickEvent(QMouseEvent *e) { // if (e->buttons().testFlag(Qt::LeftButton)) { // Ogre::Real x = e->x() / (float)width(); // Ogre::Real y = e->y() / (float)height(); // Ogre::Ray ray = ogreCamera->getCameraToViewportRay(x, y); // Ogre::RaySceneQuery *query = ogreSceneManager->createRayQuery(ray); // Ogre::RaySceneQueryResult &queryResult = query->execute(); // Ogre::RaySceneQueryResult::iterator queryResultIterator = queryResult.begin(); // if (queryResultIterator != queryResult.end()) { // if (queryResultIterator->movable) { // selectedNode = queryResultIterator->movable->getParentSceneNode(); // selectedNode->showBoundingBox(true); // } // } else { // if (selectedNode) // selectedNode->showBoundingBox(false); // selectedNode = 0; // } // ogreSceneManager->destroyQuery(query); // update(); // e->accept(); // } else // e->ignore(); } void OgreWidget8::wheelEvent(QWheelEvent *e) { // Ogre::Vector3 zTranslation(0, 0, -e->delta() / 60); // if (e->modifiers().testFlag(Qt::ControlModifier)) // zTranslation.z *= turboModifier; // const Ogre::Vector3 &actualCamPos = ogreCamera->getPosition(); // setCameraPosition(actualCamPos + zTranslation); // e->accept(); } void OgreWidget8::paintEvent(QPaintEvent *e) { ogreRoot->_fireFrameStarted(); ogreRenderWindow->update(); ogreRoot->_fireFrameEnded(); e->accept(); } void OgreWidget8::resizeEvent(QResizeEvent *e) { // QWidget::resizeEvent(e); // if (e->isAccepted()) { // const QSize &newSize = e->size(); // if (ogreRenderWindow) { // ogreRenderWindow->resize(newSize.width(), newSize.height()); // ogreRenderWindow->windowMovedOrResized(); // } // if (ogreCamera) { // Ogre::Real aspectRatio = Ogre::Real(newSize.width()) / Ogre::Real(newSize.height()); // ogreCamera->setAspectRatio(aspectRatio); // } // } // static bool flag = false; // if (flag) { // if (mDual) { // dualViewport(primarySceneMgr, secondarySceneMgr); // update(); // } else { // setupViewport(primarySceneMgr); // update(); // } // } // flag = true; QWidget::resizeEvent(e); if (e->isAccepted() && ogreRenderWindow) { ogreRenderWindow->windowMovedOrResized(); update(); } } void OgreWidget8::showEvent(QShowEvent *e) { if (!ogreRoot) initOgreSystem(); QWidget::showEvent(e); } void OgreWidget8::moveEvent(QMoveEvent *e) { QWidget::moveEvent(e); if (e->isAccepted() && ogreRenderWindow) { ogreRenderWindow->windowMovedOrResized(); update(); } } void OgreWidget8::chooseSceneManager() { primarySceneMgr = ogreRoot->createSceneManager(Ogre::ST_GENERIC, "primary"); secondarySceneMgr = ogreRoot->createSceneManager(Ogre::ST_GENERIC, "secondary"); } void OgreWidget8::createCamera() { primarySceneMgr->createCamera(CAMERA_NAME); secondarySceneMgr->createCamera(CAMERA_NAME); } void OgreWidget8::createViewports() { // Ogre::Viewport *vp = ogreRenderWindow->addViewport(ogreCamera); // vp->setBackgroundColour(Ogre::ColourValue(0, 0, 0)); // ogreCamera->setAspectRatio(Ogre::Real(vp->getActualWidth()) / Ogre::Real(vp->getActualHeight())); setupViewport(primarySceneMgr); } void OgreWidget8::createFrameListener() { Ogre::WindowEventUtilities::addWindowEventListener(ogreRenderWindow, this); // mTrayMgr = new OgreBites::SdkTrayManager("InterfaceName", ogreRenderWindow, mMouse, this); // create a params panel for displaying sample details // Ogre::StringVector items; // items.push_back("cam.pX"); // items.push_back("cam.pY"); // items.push_back("cam.pZ"); // items.push_back(""); // items.push_back("cam.oW"); // items.push_back("cam.oX"); // items.push_back("cam.oY"); // items.push_back("cam.oZ"); // items.push_back(""); // items.push_back("Filtering"); // items.push_back("Poly Mode"); // mDetailsPanel = mTrayMgr->createParamsPanel(OgreBites::TL_NONE, "DetailsPanel", 200, items); // mDetailsPanel->setParamValue(9, "Bilinear"); // mDetailsPanel->setParamValue(10, "Solid"); // mDetailsPanel->hide(); ogreRoot->addFrameListener(this); } bool OgreWidget8::frameRenderingQueued(const Ogre::FrameEvent &evt) { if (ogreRenderWindow->isClosed()) return false; if (mShutDown) return false; mTrayMgr->frameRenderingQueued(evt); // if (!mTrayMgr->isDialogVisible()) { // mCameraMan->frameRenderingQueued(evt); // if dialog isn't up, then update the camera // if (mDetailsPanel->isVisible()) { // if details panel is visible, then update its contents // mDetailsPanel->setParamValue(0, Ogre::StringConverter::toString(ogreCamera->getDerivedPosition().x)); // mDetailsPanel->setParamValue(1, Ogre::StringConverter::toString(ogreCamera->getDerivedPosition().y)); // mDetailsPanel->setParamValue(2, Ogre::StringConverter::toString(ogreCamera->getDerivedPosition().z)); // mDetailsPanel->setParamValue(3, Ogre::StringConverter::toString(ogreCamera->getDerivedOrientation().w)); // mDetailsPanel->setParamValue(3, Ogre::StringConverter::toString(ogreCamera->getDerivedOrientation().x)); // mDetailsPanel->setParamValue(3, Ogre::StringConverter::toString(ogreCamera->getDerivedOrientation().y)); // mDetailsPanel->setParamValue(3, Ogre::StringConverter::toString(ogreCamera->getDerivedOrientation().z)); // } // } return true; } void OgreWidget8::initOgreSystem() { ogreRoot = new Ogre::Root(); Ogre::RenderSystem *renderSystem = ogreRoot->getRenderSystemByName("OpenGL Rendering Subsystem"); ogreRoot->setRenderSystem(renderSystem); ogreRoot->initialise(false); ogreSceneManager = ogreRoot->createSceneManager(Ogre::ST_GENERIC); // ogreSceneManager = ogreRoot->createSceneManager("DefaultSceneManager"); Ogre::NameValuePairList viewConfig; Ogre::String widgetHandle; #ifdef Q_WS_WIN widgetHandle = Ogre::StringConverter::toString((size_t)((HWND)winId())); #else QWidget *q_parent = dynamic_cast<QWidget *>(parent()); QX11Info xInfo = x11Info(); widgetHandle = Ogre::StringConverter::toString((unsigned long)xInfo.display()) + ":" + Ogre::StringConverter::toString((unsigned int)xInfo.screen()) + ":" + Ogre::StringConverter::toString((unsigned long)q_parent->winId()); #endif viewConfig["externalWindowHandle"] = widgetHandle; ogreRenderWindow = ogreRoot->createRenderWindow("Ogre rendering window", width(), height(), false, &viewConfig); ogreCamera = ogreSceneManager->createCamera("PlayerCam"); Ogre::Vector3 camPos(0, 50, 150); ogreCamera->setPosition(camPos); ogreCamera->lookAt(0, 80, 0); ogreCamera->setNearClipDistance(5); emit cameraPositionChanged(camPos); ogreViewport = ogreRenderWindow->addViewport(ogreCamera); ogreViewport->setBackgroundColour(Ogre::ColourValue(0, 0, 0)); ogreCamera->setAspectRatio(Ogre::Real(width()) / Ogre::Real(height())); chooseSceneManager(); createCamera(); createViewports(); loadOgreResources(); createScene(); Ogre::TextureManager::getSingleton().setDefaultNumMipmaps(5); createFrameListener(); } void OgreWidget8::loadOgreResources() { // Load resource paths from config file Ogre::ConfigFile cf; cf.load("resources.cfg"); // Go through all sections & settings in the file Ogre::ConfigFile::SectionIterator seci = cf.getSectionIterator(); Ogre::String secName, typeName, archName; while (seci.hasMoreElements()) { secName = seci.peekNextKey(); Ogre::ConfigFile::SettingsMultiMap *settings = seci.getNext(); Ogre::ConfigFile::SettingsMultiMap::iterator i; for (i = settings->begin(); i != settings->end(); ++i) { typeName = i->first; archName = i->second; Ogre::ResourceGroupManager::getSingleton().addResourceLocation(archName, typeName, secName); } } // Initialise, parse scripts etc Ogre::ResourceGroupManager::getSingleton().initialiseAllResourceGroups(); } void OgreWidget8::createScene() { ogreSceneManager->setAmbientLight(Ogre::ColourValue(0.5, 0.5, 0.5)); Ogre::Light *light = ogreSceneManager->createLight("MainLight"); light->setPosition(20, 80, 50); Ogre::Entity *robotEntity = ogreSceneManager->createEntity("RobotEntity", "robot.mesh"); Ogre::SceneNode *robotNode = ogreSceneManager->getRootSceneNode()->createChildSceneNode("RobotNode"); robotNode->attachObject(robotEntity); robotNode->yaw(Ogre::Radian(Ogre::Degree(-90))); Ogre::Entity *ogreHead = ogreSceneManager->createEntity("OgreHead", "ogrehead.mesh"); Ogre::SceneNode *headNode = ogreSceneManager->getRootSceneNode()->createChildSceneNode("HeadNode"); headNode->attachObject(ogreHead); headNode->translate(Ogre::Vector3(0, 100, 0)); headNode->pitch(Ogre::Degree(60)); headNode->yaw(Ogre::Radian(Ogre::Degree(30))); headNode->roll(Ogre::Radian(Ogre::Degree(30))); // Setup the space SceneManager primarySceneMgr->setSkyBox(true, "Examples/SpaceSkyBox"); // Setup the cloudy SceneManager secondarySceneMgr->setSkyDome(true, "Examples/CloudySky", 5, 8); } void OgreWidget8::setupViewport(Ogre::SceneManager *curr) { ogreRenderWindow->removeAllViewports(); Ogre::Camera *cam = curr->getCamera(CAMERA_NAME); Ogre::Viewport *vp = ogreRenderWindow->addViewport(cam); // Our Viewport linked to the camera vp->setBackgroundColour(Ogre::ColourValue(0, 0, 0)); cam->setAspectRatio(Ogre::Real(vp->getActualWidth()) / Ogre::Real(vp->getActualHeight())); // cam->setAspectRatio(Ogre::Real(width()) / Ogre::Real(height())); } void OgreWidget8::dualViewport(Ogre::SceneManager *priSceneMgr, Ogre::SceneManager *secSceneMgr) { ogreRenderWindow->removeAllViewports(); Ogre::Viewport *vp = 0; // Ogre::Camera *cam = primarySceneMgr->getCamera(CAMERA_NAME); Ogre::Camera *cam = priSceneMgr->getCamera(CAMERA_NAME); vp = ogreRenderWindow->addViewport(cam, 0, 0, 0, 0.5, 1); vp->setBackgroundColour(Ogre::ColourValue(0, 0, 0)); cam->setAspectRatio(Ogre::Real(vp->getActualWidth()) / Ogre::Real(vp->getActualHeight())); // cam = secondarySceneMgr->getCamera(CAMERA_NAME); cam = secSceneMgr->getCamera(CAMERA_NAME); vp = ogreRenderWindow->addViewport(cam, 1, 0.5, 0, 0.5, 1); vp->setBackgroundColour(Ogre::ColourValue(0, 0, 0)); cam->setAspectRatio(Ogre::Real(vp->getActualWidth()) / Ogre::Real(vp->getActualHeight())); } #include <QtGui/QApplication> #include "ogrewidget8.h" int main(int argc, char *argv[]) { QApplication app(argc, argv); OgreWidget8 ogreWidget; // ogreWidget.show(); ogreWidget.showMaximized(); return app.exec(); }