QT + Ogre3d + Mac without X11

Problems building or running the engine, queries about how to use features etc.
bramsc
Gnoblar
Posts: 5
Joined: Fri Feb 04, 2011 11:51 pm
x 1

QT + Ogre3d + Mac without X11

Post by bramsc »

Hi, I'm currently trying to get an Ogre3d (1.7.2) scene to render in a QT window (4.7) on Mac. I've found a few examples on these forums (as well as a few others) that to do this for Windows and Linux (e.g. the QtOgre Framework), but in all these cases X11 had to be used (which is possible for the Mac, but I much rather used Carbon).

I've tried to implement code using either the QGLWidget as well as just the QWidget, but I haven't gotten the Ogre3d window to embed. I think part of my problem is that while QX11Info can give a display to pass to Ogre, I can't find a working equivalent for Carbon. QT does give the window id (winId()) for each window, but from what I understand that's not what Ogre needs. One snippet of code I found said I needed to convert the winId() to a WindowRef:

Code: Select all

WId wid = (size_t) HIViewGetWindow(HIViewRef(winId()));
params["externalWindowHandle"] = Ogre::StringConverter::toString((size_t) wid);
However, when I do this, wid is NULL, resulting in a blank window.

I did find links to code that purported to do this correctly, but unfortunately those links are now dead (they were 4 years old).

Any help would be greatly appreciated. Even if it's just in the form of code lying around (e.g. from the dead links) or suggestions of what to try next.

Thanks!
User avatar
jacmoe
OGRE Retired Moderator
OGRE Retired Moderator
Posts: 20570
Joined: Thu Jan 22, 2004 10:13 am
Location: Denmark
x 179

Re: QT + Ogre3d + Mac without X11

Post by jacmoe »

This works for Ogitor:

Code: Select all

    params["externalWindowHandle"] = Ogre::StringConverter::toString((size_t) (this->winId()));
I am not sure if it works for carbon, though.
We haven't got a Mac developer on our team currently.
/* Less noise. More signal. */
Ogitor Scenebuilder - powered by Ogre, presented by Qt, fueled by Passion.
OgreAddons - the Ogre code suppository.
User avatar
DanielSefton
Ogre Magi
Posts: 1235
Joined: Fri Oct 26, 2007 12:36 am
Location: Mountain View, CA
x 10

Re: QT + Ogre3d + Mac without X11

Post by DanielSefton »

Don't use Carbon, Qt 4.7 supports Cocoa, and so does the latest Ogre 1.7 branch.

Make sure you have the right Ogre version then combine jacmoe's code with:

Code: Select all

#ifdef QT_MAC_USE_COCOA
	params["macAPI"] = "cocoa";
	params["macAPICocoaUseNSView"] = "true";
#endif
bramsc
Gnoblar
Posts: 5
Joined: Fri Feb 04, 2011 11:51 pm
x 1

Re: QT + Ogre3d + Mac without X11

Post by bramsc »

Awesome, thanks! I won't get to try this out until tomorrow or Monday, but I'll post back with the results as soon as possible.
bramsc
Gnoblar
Posts: 5
Joined: Fri Feb 04, 2011 11:51 pm
x 1

Re: QT + Ogre3d + Mac without X11

Post by bramsc »

I've made the changes suggested which have stopped the code from crashing. However, nothing appears to get rendered -- not even the blue background that was set. I've checked the logs, and I don't see any errors. I can verify that robot.mesh even loads successfully. I'm assuming since there's no blue background, that means that the OpenGL canvas simply isn't getting display...

Below is the code I'm currently using. Note, this code is made up almost entirely of examples people have previously posted to the forums. So hopefully it's as succint as possible.

Any help is greatly appreciate!

ogrewidget.h

Code: Select all

#ifndef OGREWIDGET_H
#define OGREWIDGET_H

#include <QtGui>
#include <Ogre.h>

class OgreWidget : public QWidget
{
    Q_OBJECT

public:
    OgreWidget(QWidget *parent = 0);
    ~OgreWidget();

protected:
    virtual void moveEvent(QMoveEvent *e);
    virtual void paintEvent(QPaintEvent *e);
    virtual void resizeEvent(QResizeEvent *e);
    virtual void showEvent(QShowEvent *e);
 //   virtual QPaintEngine* paintEngine() const;

private:
    void initOgreSystem();
    void setupNLoadResources();
    void createScene();

private:
    Ogre::Root         *ogreRoot;
    Ogre::SceneManager *ogreSceneManager;
    Ogre::RenderWindow *ogreRenderWindow;
    Ogre::Viewport     *ogreViewport;
    Ogre::Camera       *ogreCamera;
};

#endif // OGREWIDGET_H
ogrewidget.cpp

Code: Select all

#include <QtDebug>
#include <QtGui/QX11Info>

#include "OgreWidget.h"
#include "OSX/macUtils.h"

#include <iostream>

OgreWidget::OgreWidget(QWidget *parent) :
        QWidget(parent),ogreRoot(0), ogreSceneManager(0), ogreRenderWindow(0), ogreViewport(0),ogreCamera(0)
{
    setAttribute(Qt::WA_OpaquePaintEvent,true);
    setAttribute(Qt::WA_PaintOnScreen,true);
    setMinimumSize(800,600);

}

OgreWidget::~OgreWidget()
{
    if(ogreRenderWindow)
    {
        ogreRenderWindow->removeAllViewports();
    }

    if(ogreRoot)
    {
        ogreRoot->detachRenderTarget(ogreRenderWindow);
        if(ogreSceneManager)
        {
            ogreRoot->destroySceneManager(ogreSceneManager);
        }
    }
    delete ogreRoot;
}

void OgreWidget::moveEvent(QMoveEvent *e)
{
    QWidget::moveEvent(e);

    if(e->isAccepted() && ogreRenderWindow)
    {
        ogreRenderWindow->windowMovedOrResized();
        update();
    }
}

void OgreWidget::paintEvent(QPaintEvent *e)
{
    ogreRoot->_fireFrameStarted();
    ogreRenderWindow->update();
    ogreRoot->_fireFrameEnded();

    e->accept();
}

void OgreWidget::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);
        }
    }
}

void OgreWidget::showEvent(QShowEvent *e)
{
    if(!ogreRoot)
    {
        initOgreSystem();
    }

    QWidget::showEvent(e);
}

void OgreWidget::initOgreSystem()
{
    ogreRoot = new Ogre::Root();

    setAttribute(Qt::WA_PaintOnScreen);
    setAttribute(Qt::WA_NoSystemBackground);

    Ogre::RenderSystem *renderSystem = ogreRoot->getRenderSystemByName("OpenGL Rendering Subsystem");
    ogreRoot->setRenderSystem(renderSystem);
    ogreRoot->initialise(false);

    Ogre::NameValuePairList params;
    params["externalWindowHandle"] = Ogre::StringConverter::toString((size_t) (this->winId()));
    params["macAPI"] = "cocoa";
    params["macAPICocoaUseNSView"] = "true";

    QSize size=this->size();
    ogreRenderWindow = ogreRoot->createRenderWindow("Ogre rendering window",size.width(),size.height(),false,&params);

    setupNLoadResources();
    createScene();
}

void OgreWidget::setupNLoadResources()
{
        // 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;
#if OGRE_PLATFORM == OGRE_PLATFORM_APPLE
                        std::cout << "adding: " << Ogre::String(Ogre::macBundlePath() + "/" + archName) << std::endl;
                        Ogre::ResourceGroupManager::getSingleton().addResourceLocation(
                                Ogre::String(Ogre::macBundlePath() + "/" + archName), typeName, secName);
#else
                        Ogre::ResourceGroupManager::getSingleton().addResourceLocation(
                                archName, typeName, secName);
#endif
                }
        }

        // Initialise, parse scripts etc
        Ogre::ResourceGroupManager::getSingleton().initialiseAllResourceGroups();
        std::cout << "finished with resource initialization" << std::endl;
}

void OgreWidget::createScene()
{
    ogreSceneManager = ogreRoot->createSceneManager(Ogre::ST_GENERIC);
    ogreCamera = ogreSceneManager->createCamera("myCamera");

    ogreViewport = ogreRenderWindow->addViewport(ogreCamera);
    ogreViewport->setBackgroundColour(Ogre::ColourValue(0,0,255)); // Blue background
    ogreCamera->setAspectRatio(Ogre::Real(width()) / Ogre::Real(height()));

    ogreSceneManager->setAmbientLight(Ogre::ColourValue(0,0,0));

    Ogre::Entity *robotEntity = ogreSceneManager->createEntity("Robot", "robot.mesh");
    Ogre::SceneNode *robotNode = ogreSceneManager->getRootSceneNode()->createChildSceneNode("RobotNode");
    robotNode->attachObject(robotEntity);
    robotNode->yaw(Ogre::Radian(Ogre::Degree(-90)));

    ogreCamera->setPosition(Ogre::Vector3(0, 0, 250));
    ogreCamera->lookAt(Ogre::Vector3(0, 0, -100));
    ogreCamera->setAutoAspectRatio(true);
    ogreCamera->setNearClipDistance(5);
}

I can provide the rest of the code (main.cpp and mainwindow.cpp if it helps -- I just didn't want to overload the post).


Thanks again!
bramsc
Gnoblar
Posts: 5
Joined: Fri Feb 04, 2011 11:51 pm
x 1

Re: QT + Ogre3d + Mac without X11

Post by bramsc »

Just as a follow up, I had to use the trunk for 1.7 to get things working. For some reason I couldn't compile 1.7 on my machine, but had a co-worker whose machine it did compile on.
cypherluc
Gnoblar
Posts: 5
Joined: Sun Jun 05, 2011 7:29 pm
x 1

Re: QT + Ogre3d + Mac without X11

Post by cypherluc »

Dear Ogre users,

I just added a code snippet in the wiki OgreQt http://www.ogre3d.org/tikiwiki/QtOgre that fixed most of my Mac OS related issues.
Indeed, I have got now a minimal project Qt 4.7.4 & Ogre 1.7.3 (taken from the original wiki OgreQt code and following suggestions in the forum) that runs successfully on Mac OSX 10.6 using Cocoa (Qt's choice). You can find the source code attached and download the full project at http://www.cyberbotics.com/files/beta/A ... or_Mac.zip.

Still, I am annoyed by two series of warnings:

2011-12-06 17:00:26.230 main[14966:903] invalid drawable
2011-12-06 17:00:33.609 main[14966:903] *** __NSAutoreleaseNoPool(): Object 0x38a30e0 of class NSCFNumber autoreleased with no pool in place - just leaking
2011-12-06 17:00:33.610 main[14966:903] *** __NSAutoreleaseNoPool(): Object 0x38058b0 of class NSConcreteValue autoreleased with no pool in place - just leaking
2011-12-06 17:00:33.611 main[14966:903] *** __NSAutoreleaseNoPool(): Object 0x2425340 of class NSCFNumber autoreleased with no pool in place - just leaking
2011-12-06 17:00:33.612 main[14966:903] *** __NSAutoreleaseNoPool(): Object 0x2443920 of class NSConcreteValue autoreleased with no pool in place - just leaking
2011-12-06 17:00:33.612 main[14966:903] *** __NSAutoreleaseNoPool(): Object 0x382e3c0 of class NSCFDictionary autoreleased with no pool in place - just leaking

The first warning (invalid drawable) is issued when calling mOgreRoot->createRenderWindow().
I already tried to set many different Qt widget attributes through setAttribute(Qt::WidgetAttribute) in order fix them, but so far my attempts remain unsuccessful. So I would be glad to share your insight about it.

The other warnings are issued when the destructor of OgreWidget is called, more precisely when the Ogre::Root::unloadPlugin() method is triggered by the "delete mOgreRoot" instruction.
I already tried to free mOgreWindow instead or to reset the render system to NULL, but the same warning keeps prompting.

With best regards.

PS: I noticed that adding the line

Code: Select all

params["FSAA"] = Ogre::StringConverter::toString(4);
before the creation of mOgreWindow removes the complain about the leaks but causes an "invalid pixel" warning followed by an "invalid context" warning.
You do not have the required permissions to view the files attached to this post.