Steam overlay in Qt game
-
Hey,
I am working on a game using the C++ Qt interface, and recently I started integrating it with the Steamworks API. Is there anyone here with experience on doing that?
I managed to integrate the Steam API quite easily since it's also C++, however the Overlay (https://partner.steamgames.com/doc/features/overlay) doesn't want to work correctly. The overlay needs OpenGL, in order to hook into the drawing, and doesn't work with Qt's default drawing. I am using a QGraphicsView, which is also my main window, I enabled OpenGL in the QGraphicsView's constructor following Qt docs:
QOpenGLWidget* gl = new QOpenGLWidget(); setViewport(gl); setViewportUpdateMode(QGraphicsView::FullViewportUpdate);
This seems to be working as I have GPU usage now, and my FPS is synced to my monitor's refresh rate (previously I had ~800 FPS using a 1ms QTimer).
And here comes the interesting part: when I start my game, I get both the Steam popup, and the Geforce Experience popup. However, if I activate any of those using their regular hotkeys, they kinda appear in a semi-transparent way, and they don't react to mouse or keyboard. At the same time, I hear sfx from my game behind them, as if my QGraphicsView is still taking the inputs, and even trying to draw over those overlays. If I switch to another window and back, the overlays disappear as if they weren't drawn correctly in the first place.
I'd appreciate any pointers in what to change/configure/add to make the Steam overlay, or the Geforce Experience overlay work correctly. It's very possible my OpenGL setup is missing something, or my game should ungrab the keyboard/mouse when the overlays appear, but I couldn't find a clear next step here.
Thanks in advance!
-
Update:
The problem has nothing to do with Steam actually. After disabling the Steam integration, but keeping the QOpenGLWidget in my QGraphicsView, I am having the same problem with the Geforce Experience still.
The overlay appears, although a bit transparent, doesn't react to any inputs and seemingly freezes drawing as well.
-
@SGaist hi,
I am using the latest version of Qt5.
My whole app is built on a class inherited from QGraphicsView, acting as the main widget (and thus the window of the game). This widget uses Qt's raster drawing by default, which I am trying to modify into using OpenGL instead. https://doc.qt.io/qt-5/graphicsview.html#the-view and at least 3 other Qt docs talking about OpenGL say all I have to do is create a QOpenGLWidget and set that as the viewport for the QGraphicsView, which is exactly what I am doing (see code snippet in my first post).
I don't think I could rewrite my window system to use QWindow, or QOpenGLWidget (or OpenGL drawing) directly. That would take days, if not more. However, I might try a minimalist example of using them.
I also tried changing the OpenGL version via default QSurfaceFormat, because the default 2.0 is ancient. Interestingly, with most of the 3.x versions I got a black screen only (but reactive to inputs), and with 4.x it's the same as with 2.0.
I'd be happy for any pointers, or new things to try.
-
No problem, that's actually what I did today. I hacked together a mere 150 lines of a QGraphicsView with a single colored background brush, and a basic Steam integration. And.. it reproduced the issue perfectly.
Then, I started digging on Steam forums, and I found a question from years ago with the exact same problem, and THE SOLUTION! It looks like Qt stops the update (redrawing) loop when the overlay appears, I am guessing it thinks the window is inactive, or hidden, and thus there's no point in updating it. The trick is to run a timer while the overlay is active and force a redraw periodically. I tried both using QGraphicsView::update() and QGraphicsScene::update() and the result was the same, probably one calls the other. This way, the overlay works perfectly.
-