Select OpenGL device
-
Hi!
This is my first post to the forum, so forgive me if my Search skills are not sufficient enough to find the answer on this forum, although I'm sure someone has already asked this, since it's no black magic I'm trying to do.
I'm trying to find a cross-platform way of getting handles to all the OpenGL capable devices in a system. I need this for flexible OpenCL-OpenGL interop, later on multi-GPGPU with interop. In both Windows and Linux there are system and windowing API functions to change the actual desktop screen being queried and get the OS-specific handle to a device. What is the simplest way to do this in Qt?
I have found QDesktopWidget::screenCount() function returning the number of screens available to a system. With this number, I could iterate through the screens with QDesktopWidget::screen() which return a QWidget* representing the screen. Then I could use QScreen::handle() function to get the OS-specific handle and use that to my needs in OpenCL and OpenGL.
The only problem is that this method seems like it's not type-correct. QDesktopWidget::screen() whould return a QScreen*, if I want it to have a handle() function, and not QWidget*.
Can someone tell me what is the proper way of doing what I want?
-
OpenGL context creation (and thus device detection) is really platform specific: WGL on Windows, GLX on X11, CGL on Mac OS X... A good start would be to look at the implementations of QGLContext across the different Qt-supported platforms directly in the Qt code source and try to figure out a way of doing what you want. OpenCL/OpenGL interop work within a GL context anyway.
-
Thank you rcari for your answer. This is sort of what I was trying to avoid. I wasn't hoping for someone to do my homework instead of me, but was hoping a little that I could solve the problem without having to dig into source code.
I read the documentation, but as I said, it seems to be type miscorrect, and I'd hate to waste time one writing code, that seems to be faulty from start. If someone knows the answer, I'd be glad to hear it. If noone has enough experience in Device Context magic with Qt, then that will leave me with no choice, but to dig into the code.
I have written several interop applications, but as with all windowing APIs, getting a context for the default display is always easy. One for non-default devices is always what is a lot trickier.
-
Someone posted in this topic that I would like to react to, but it got lost. I got the notification mail, so let me paste it here:
Hi,
IIRC for Qt 5 there's qtXXXextras that provides the platform specific stuff
(XXX being win, mac, x11)
Hope it helpsWhile I did not find anything related in winextras.h neither did I find anything in qwindowscontexts that could be accessed from outside, so I thought of trying an alternate solution. Do the entire window or offscreen render init in Qt, makeActive() the context, then call wglGetCurrentContext() and wglGetCurrentDevice() to obtain HGLRC and HDC values, use them to my own purposes, and the do what I like. Something similar could surely be done under linux too.
However my code crashes and I do not know what I am doing wrong. My QtGuiApp_test class is an emtpy class inheriting from QMainWindow.
@#include <QtGuiApp_test.hpp>
#include <QtWidgets/QApplication>#include <QScreen>
#include <QOpenGLContext>
#include <QWindow>#include <QDebug>
#include <typeinfo>
#include <fstream>#include <Windows.h>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);QtGuiApp_test w; w.show(); std::ofstream output("print.dat", std::ios::ate); output << "Querying desktop for screens..." << std::endl; QList<QScreen*> my_screens(a.screens()); QList<QOpenGLContext*> my_qgl_contexts; QList<HGLRC> my_wgl_contexts; QList<HDC> my_wgl_devices; for(auto& screen : my_screens) { QWindow temp_window(screen); my_qgl_contexts.push_back(new QOpenGLContext()); (*my_qgl_contexts.end())->setScreen(temp_window.screen()); (*my_qgl_contexts.end())->create(); (*my_qgl_contexts.end())->makeCurrent(&temp_window); my_wgl_contexts.push_back(wglGetCurrentContext()); my_wgl_devices.push_back(wglGetCurrentDC()); } output.close(); return a.exec();
}
@My program crashes inside WinMain called from create. Is this not the way to cycle through screens, create window on each of them and then a context that I makeCurrent on? It would be more elegant if I could get this to work in a fully off-screen mode, but I did not find a QSurface, other than QWindow that I could activate the QOpenGLConext on.
Any ideas?
p.s.: it's a shame Qt does not allow to be interfaced with low-level tools.
-
Code providing a solution to this problem can be found "here":http://qt-project.org/forums/viewthread/27305/.