#ifndef OGREWIDGET10_H #define OGREWIDGET10_H #include <QWidget> #include <Ogre.h> class OgreWidget10 : public QWidget { Q_OBJECT public: explicit OgreWidget10(QWidget *parent = 0); ~OgreWidget10(); QPaintEngine *paintEngine() const; signals: public slots: protected: void initOgre(); void loadOgreResources(); void createScene(); void chooseSceneManager(); void createFrameListener(); void frameRenderingQueued(const Ogre::FrameEvent &evt); void showEvent(QShowEvent *e); void paintEvent(QPaintEvent *e); void resizeEvent(QResizeEvent *e); // void update(); void keyPressEvent(QKeyEvent *e); void mousePressEvent(QMouseEvent *e); void mouseMoveEvent(QMouseEvent *e); void mouseReleaseEvent(QMouseEvent *e); void wheelEvent(QWheelEvent *e); Ogre::RaySceneQuery *mRaySceneQuery; int mCount; // The number of robots on the screen Ogre::SceneNode *mCurrentObject; // The newly created object float mRotateSpeed; private: Ogre::Root *mRoot; Ogre::SceneManager *mSceneMgr; Ogre::RenderWindow *mRenderWindow; Ogre::Camera *mCamera; Ogre::Real mCameraSpeed; Ogre::Viewport *mViewport; QPoint lastPos; }; #endif // OGREWIDGET10_H /* RaySceneQueries and Basic Mouse Usage CrazyWind comfanter@gmail.com */ #include <QtGui> #include "ogrewidget10.h" OgreWidget10::OgreWidget10(QWidget *parent) : QWidget(parent), mRoot(0), mSceneMgr(0), mRenderWindow(0), mCamera(0), mViewport(0), mRaySceneQuery(0), mCurrentObject(0), mCount(0), mRotateSpeed(0.1), mCameraSpeed(5.0) { setAttribute(Qt::WA_OpaquePaintEvent); setAttribute(Qt::WA_PaintOnScreen); setFocusPolicy(Qt::StrongFocus); setMinimumSize(250, 250); resize(800, 600); QRect r = qApp->desktop()->availableGeometry(); move((r.width() - width()) / 2, (r.height() - height()) / 2); setWindowTitle(tr("RaySceneQuery")); } OgreWidget10::~OgreWidget10() { mSceneMgr->destroyQuery(mRaySceneQuery); } QPaintEngine *OgreWidget10::paintEngine() const { return NULL; } void OgreWidget10::initOgre() { mRoot = new Ogre::Root(); Ogre::RenderSystem *renderSystem = mRoot->getRenderSystemByName("OpenGL Rendering Subsystem"); mRoot->setRenderSystem(renderSystem); chooseSceneManager(); mRoot->initialise(false); // chooseSceneManager(); //! Error! Must called after creating the window! Ogre::NameValuePairList viewConfig; Ogre::String widgetHandle; widgetHandle = Ogre::StringConverter::toString((size_t)((HWND)winId())); viewConfig["externalWindowHandle"] = widgetHandle; mRenderWindow = mRoot->createRenderWindow("Ogre rendering window", width(), height(), false, &viewConfig); chooseSceneManager(); mCamera = mSceneMgr->createCamera("PlayerCam"); mCamera->setPosition(0, 50, 150); mCamera->lookAt(0, 80, 0); mCamera->setNearClipDistance(5); mViewport = mRenderWindow->addViewport(mCamera); mViewport->setBackgroundColour(Ogre::ColourValue(0.0, 0.0, 0.0)); mCamera->setAspectRatio(Ogre::Real(width()) / Ogre::Real(height())); loadOgreResources(); createScene(); mRaySceneQuery = mSceneMgr->createRayQuery(Ogre::Ray()); } void OgreWidget10::loadOgreResources() { Ogre::ConfigFile cf; cf.load("resources.cfg"); 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); } } Ogre::ResourceGroupManager::getSingleton().initialiseAllResourceGroups(); } void OgreWidget10::createScene() { mSceneMgr->setAmbientLight(Ogre::ColourValue(0.5, 0.5, 0.5)); mSceneMgr->setSkyDome(true, "Examples/CloudySky", 5, 8); mSceneMgr->setWorldGeometry("terrain.cfg"); mCamera->setPosition(40, 100, 580); mCamera->pitch(Ogre::Degree(-30)); mCamera->yaw(Ogre::Degree(-45)); } void OgreWidget10::chooseSceneManager() { // Use the terrain scene manager. mSceneMgr = mRoot->createSceneManager(Ogre::ST_EXTERIOR_CLOSE); } void OgreWidget10::createFrameListener() { } void OgreWidget10::frameRenderingQueued(const Ogre::FrameEvent &evt) { } void OgreWidget10::showEvent(QShowEvent *e) { if (!mRoot) initOgre(); QWidget::showEvent(e); } void OgreWidget10::paintEvent(QPaintEvent *e) { // Setup the scene query Ogre::Vector3 camPos = mCamera->getPosition(); Ogre::Ray cameraRay(Ogre::Vector3(camPos.x, 5000.0, camPos.z), Ogre::Vector3::NEGATIVE_UNIT_Y); mRaySceneQuery->setRay(cameraRay); // Perform the scene query Ogre::RaySceneQueryResult &result = mRaySceneQuery->execute(); Ogre::RaySceneQueryResult::iterator itr = result.begin(); // Get the results, set the camera height if (itr != result.end() && itr->worldFragment) { Ogre::Real terrainHeight = itr->worldFragment->singleIntersection.y; if ((terrainHeight + 10.0) > camPos.y) mCamera->setPosition(camPos.x, terrainHeight + 10.0, camPos.z); } mRoot->_fireFrameStarted(); mRenderWindow->update(); // mRoot->_fireFrameRenderingQueued(); mRoot->_fireFrameEnded(); e->accept(); } void OgreWidget10::resizeEvent(QResizeEvent *e) { QWidget::resizeEvent(e); if (e->isAccepted() && mRenderWindow) { mRenderWindow->resize(width(), height()); mRenderWindow->windowMovedOrResized(); for (int i = 0; i < mRenderWindow->getNumViewports(); ++i) { Ogre::Viewport *viewport = mRenderWindow->getViewport(i); Ogre::Camera *camera = viewport->getCamera(); camera->setAspectRatio(static_cast<Ogre::Real>(width()) / static_cast<Ogre::Real>(height())); } } update(); } void OgreWidget10::keyPressEvent(QKeyEvent *e) { switch (e->key()) { case Qt::Key_Escape: close(); case Qt::Key_W: mCamera->setPosition(mCamera->getPosition() + mCamera->getDirection() * mCameraSpeed); update(); break; case Qt::Key_S: mCamera->setPosition(mCamera->getPosition() - mCamera->getDirection() * mCameraSpeed); update(); break; case Qt::Key_A: mCamera->setPosition(mCamera->getPosition() - mCamera->getRight() * mCameraSpeed); update(); break; case Qt::Key_D: mCamera->setPosition(mCamera->getPosition() + mCamera->getRight() * mCameraSpeed); update(); break; default: QWidget::keyPressEvent(e); } } void OgreWidget10::mousePressEvent(QMouseEvent *e) { if (e->buttons().testFlag(Qt::RightButton)) { lastPos = e->pos(); } else if (e->buttons().testFlag(Qt::LeftButton)) { // Setup the ray scene query Ogre::Real x = e->pos().x() / (float)width(); Ogre::Real y = e->pos().y() / (float)height(); Ogre::Ray ray = mCamera->getCameraToViewportRay(x, y); mRaySceneQuery->setRay(ray); Ogre::RaySceneQueryResult &result = mRaySceneQuery->execute(); Ogre::RaySceneQueryResult::iterator itr = result.begin(); if (itr != result.end() && itr->worldFragment) { char name[16]; sprintf(name, "Robot%d", mCount++); Ogre::Entity *ent = mSceneMgr->createEntity(name, "robot.mesh"); mCurrentObject = mSceneMgr->getRootSceneNode()->createChildSceneNode(std::string(name) + "Node", itr->worldFragment->singleIntersection); mCurrentObject->attachObject(ent); mCurrentObject->setScale(0.2, 0.2, 0.2); update(); } } } void OgreWidget10::mouseMoveEvent(QMouseEvent *e) { if (e->buttons().testFlag(Qt::RightButton)) { QPoint mouseDelta = e->pos() - lastPos; mCamera->yaw(Ogre::Radian(-mouseDelta.x() * 0.005)); mCamera->pitch(Ogre::Radian(-mouseDelta.y() * 0.005)); lastPos = e->pos(); update(); } else if (e->buttons().testFlag(Qt::LeftButton)) { Ogre::Real x = e->pos().x() / (float)width(); Ogre::Real y = e->pos().y() / (float)height(); Ogre::Ray ray = mCamera->getCameraToViewportRay(x, y); mRaySceneQuery->setRay(ray); Ogre::RaySceneQueryResult &result = mRaySceneQuery->execute(); Ogre::RaySceneQueryResult::iterator itr = result.begin(); if (itr != result.end() && itr->worldFragment) mCurrentObject->setPosition(itr->worldFragment->singleIntersection); update(); } } void OgreWidget10::mouseReleaseEvent(QMouseEvent *e) { } void OgreWidget10::wheelEvent(QWheelEvent *e) { Ogre::Radian fov = mCamera->getFOVy(); fov += Ogre::Radian(-e->delta() * 0.001); fov = qBound(Ogre::Radian(0.5), fov, Ogre::Radian(2.0)); mCamera->setFOVy(fov); update(); } 参考资料:http://www.ogre3d.org/tikiwiki/Intermediate+Tutorial+2&structure=Tutorials