Woo woo woo… you know it!

One of the things I’ve been working on recently is an in app editor for the OGRE based 3D GUI that forms the front end of one of our main products. One of the features that I added was the ability to switch between scenes with the click of a button. I was able to get this working on Windows with little difficulty, but on Linux I constantly got the same assert.

ogre/RenderSystems/GL/src/OgreGLSupport.cpp:56: virtual void Ogre::GLSupport::initialiseExtensions(): Assertion `pcVer && "Problems getting GL version string using glGetString"' failed.

I have revisited this problem several times in recent months and each time my investigation faltered at the same point. The first time a scene was loaded, everything was fine, the second time a scene was loaded OGRE failed to initialize the OpenGL Context. Something wasn’t being released correctly when the first scene was shutdown. I tried everything. With OGRE it should really be as simple as calling shutdown() on the root node and then deleting the root node using OGRE_DELETE, but it just wouldn’t work.

This past Friday I finally got it working though. The following code snippet is from the second time that OGRE tried to initialize the OpenGL render system. The dimensions of the target render window are wrong. For whatever reason, Qt was not able to finish initializing the container widget before I was grabbing the X11 info and passing this onto the OGRE initialization code. A simple decouple using a 1ms timer sorted the issue.

******************************
*** Starting GLX Subsystem ***
******************************
GLRenderSystem::_createRenderWindow "SomeWidget", 1059x0 windowed  miscParams: parentWindowHandle=135727904:0:56624998
GLXWindow::create used FBConfigID = 117

I’m not going to lie, I fist bumped like The Long Island Iced Z when I saw that model reload! :D

QSpacerItem: Stretched to breaking point

My days of using the Qt Designer application have trained me to define all QSpacerItems with a size hint of 1 by 1, a habit that I’ve yet to drop even though I no longer use Qt Designer. This week I was working on a GUI which requried a large horizontal spacer, around 2000px, but I could not get QSpacerItem to behave the way I wanted it to, it would stretch so far across the screen and then just stop. Long story short, it seems that QSpacerItems will only stretch so far beyond their size hint – defining the width of the size hint to 10000px resolved the problem. Virtual fist bump to El Jefe for having previously suffered this problem and remembering the fix. (Qt 3.3.8)

public class FakeButtonFrame : public QPushButton

So today I found myself fighting against the short comings of Qt 3.3.8, I should point out right from the off that I am fully aware of the existence of Qt 4.5.x (Mr Pandy is performing a port to 4.5.1 as I type), but for the project I was working on I had to use 3.3.8. I wanted to draw some QWidgets on to a mainly black, but multi coloured background without losing the nice curved corners. I am sure some of you are thinking that this sounds easy, but it is not as simple as you think. Qt 3.3.8 doesn’t support transparent backgrounds; the way in which the curved corners are achieved in standard Qt 3.3.8 GUIs is to ensure that the background colour of the widget matches that of the widget it is being placed on to. Setting the background colour of the widget to black worked for the most part, but not for the non black parts of the GUI where the black pixels in the corner of each right angle alerted everyone to their presence.

I subsequently discovered the real kicker to this conundrum was that only QPushButtons support foreground and background colours properly, meaning that the background colour trick did not work on the other widgets: they turned completely black. My frustration at this point was reaching fever point  and my sighs were audible enough for El Jefe to hear them and ask me a question that still leaves me horrified, “I wonder if you can you add widgets to a QPushButton?”. I could see what he was thinking, but I didn’t like it… surely it wouldn’t work… but it did… sort of. The fact that a QPushButton is a QWidget meant that adding a layout and widgets to a QPushButton was cake, creating my own subclass of QPushButton with a custom method to eat any mouse events ( virtual void nomNomNom( QMouseEvent* e ) ) was cake too, but preventing the button from responding to mouse overs like a QPushButton was not so easy. I disabled the button to prevent it from responding, performed a switcheroo on the active and disabled colour palettes, compiled, ran the code and discovered that disabling the button had Haitianed it – it had forgotten how to perform the foreground-background trick and  it turned black too!

QString::null WTF!

I recently discovered the cause of a bug feature in some software that I wrote (Qt 3.3.8) and thought that I’d share the information since it feels like the sort of thing that lots of people might have done. Essentially, the problem was my assumption that QString::null is some sort of special value, it isn’t, it is just a reference to a static empty QString. Given this information, consider the following three QStringLists:

QStringList listOne = QStringList();
QStringList listTwo = QStringList( QString::null );
QStringList listThree = QStringList( "" );

If, like me, you assumed that QString::null was a special null value, then you might reasonably expect both listOne and listTwo to be empty QStringLists and listThree a QStringList containing a single empty QString. The reality is that listTwo is actually equivalent to listThree, so when you are tearing your hair out trying to work out why your nice empty QStringList has a length of 1, remember this post. You have been warned.

It is worth noting that QString::null has been deprecated as of Qt4.0 and calls to it now evaluate to seperate calls to QString(), I guess I wasn’t the only person that fell into this trap! I know that assumption is the Mother of all fuck ups, but I can’t help thinking that this could have all been avoided by naming it QString::empty instead.