QGLWidget won't display
-
Hi!
I am trying to setup an application for multi-device off-screen render (with reaching in for plaform-specific handles), and I got as far as testing the handles I get, but I cannot get my simple geometry to display. I believe something is wrong with the init part, or updating QGLWidget, or something similar.
I have read HEAPS of documentation, and my conclusion is that there is a big mess in terms of OpenGL related classes that can be used. QOpenGLXXX is something half done, QGLXXX is marked as deprecated, and we are left with deciding what suits us best. I myself would use QOpenGL stuff, but I couldn't get a window working with rendered stuff inside. So I decided to revert to QGLWidget (a decision I most certainly will regret).
Can someone tell me what's wrong in my code? There are two kinds of init I wrote, but right now I'm only using the second one. My window appears, but is not cleared black. Also, somehow I get a resize event handled before initalizeGL getting called, which as far as documentation goes should not happen. The first time resize or paint event is sent to QGLWidget, an initialize call is sent. Certainly there are multiple things I'm doing wrong (such as application termination, which simply does not work. Even if I close my QMainWindow and all other windows I opened, my application does not terminate.
I test my app under Win8 with VS2012.
Any remarks either on the OpenGL stuff (either pointing to something working using QWindow only), about the platformAbstraction part, or app termination is most welcome. If someone happens to know the objects, the functions needed to be called, and the magic strings in nativeResourceForXXX functions to obtain Display* and GLXContext handles, that would really rock. I had to dig elbow deep into Qt source code in debug mode to obtain these strings (since QPA module is undocumented yet).
"main.cpp":http://pastebin.com/MFTVWiVL
"Visualizer.hpp":http://pastebin.com/GvUFHVPV
"Visualizer.cpp":http://pastebin.com/xfG5FvZ6
Thank you in advance!
-
Forgive me for spaming my own topic, but is this question too lame to be answered, or just the contrary... is it too far away from casual programming? I really can't tell why no replies arrived. Or is my code really that awful, that it's beyond redemption?
I believe I did not venture into writing code without doing my homework, but I thought getting this thing to work would be less pain using Qt. When Qt5 was released, in the presentation showing off QtQuick2, the presenter stated "getting an OpenGL context let alone is enough reason to use Qt". I heard this when I was in the middle of coding my C++ interfaced cross-platform multi-device init, that was a real pain. I figured this must be hell of a lot easier in Qt. But it isn't.
All I want to do is off-screen render 2-3-4 cubes that occasionally occlude each other, and then a simple z-composition is done to merge the images with proper occlusion. Simple Object Distributed Render. But getting off-screen ready contexts that can work in parallel (and also get their low-level handles) seems too much for Qt. Or am I wrong?
-
Hi,
Just a few questions about your code:
Why do you have a generated UI in your QGLWidget ?
Why do you use a for loop to update your scenes ? This should rather be done using a timer (either timerEvent or QTimer)
Also this is done prior to the starting of the event loop, so you won't see your widgets.Does it work when you only have one of your widget ?
If i'm not wrong, you are closing every widget before even starting the event loop and further more you're calling exit before starting the event loop.
I can't say if you're wrong or not, I'm not that fluent in OpenGL. One thing you can try to get help is to ask in the #qt channel on freenode. There might be someone there knowing how to help you doing SODR.
Hope it helps
-
Thank you for the reply. Indeed I was in sort of a misconception about the use of exec(). Anyhow, I have abandoned the use of QGLWidget as it is, to use QWindow in favor. I have subclassed the example helper OpenGLWindow presented "here":http://qt-project.org/doc/qt-5.0/qtgui/openglwindow.html but have encountered a strange issue. I was thinking of opening a new topic, but I'll just add a tag to this one.
Why is it that QWindow is unable to refresh when allocated on heap? Having multiple QWindows on stack works, but ones allocated on heap don't refresh (they stay black). This prevents me from making a QList out of them (since QWindow is non-copyable, it cannot be put inside a QList without a pointer).
My code is simple as it gets. OpenGLWindow is exactly as it is in the example, and my subclasses look like:
ColorShifter.hpp
@#ifndef COLORSHIFTER
#define COLORSHIFTER#include <OpenGLWindow.hpp>
class ColorShifter : public OpenGLWindow
{
Q_OBJECTpublic:
ColorShifter();virtual void render() override; virtual void initialize() override;
private:
GLfloat r, g, b, a;
};#endif // COLORSHIFTER@
ColorShifter.cpp
@#include <ColorShifter.hpp>
ColorShifter::ColorShifter()
{
}void ColorShifter::initialize()
{
}void ColorShifter::render()
{
glViewport(0, 0, width(), height());// Update Scene r = r > 1. ? 0.0001 : r + 0.0001; g = g > 1. ? 0.0002 : g + 0.0002; b = b > 1. ? 0.0003 : b + 0.0003; a = 1.; glClearColor(r, g, b, a); glClear(GL_COLOR_BUFFER_BIT);
}@
main.cpp
@#include <QGuiApplication>
#include <ColorShifter.hpp>int main(int argc, char *argv[])
{
QGuiApplication app(argc, argv);// Qt5 constructs QList<QScreen*> my_screens; QSurfaceFormat my_surfaceformat; // Query number of screens my_screens = QGuiApplication::screens(); // Setup desired format my_surfaceformat.setRenderableType(QSurfaceFormat::RenderableType::OpenGL); my_surfaceformat.setProfile(QSurfaceFormat::OpenGLContextProfile::CoreProfile); my_surfaceformat.setSwapBehavior(QSurfaceFormat::SwapBehavior::DoubleBuffer); my_surfaceformat.setMajorVersion(3); my_surfaceformat.setMinorVersion(2); my_surfaceformat.setRedBufferSize(8); my_surfaceformat.setGreenBufferSize(8); my_surfaceformat.setBlueBufferSize(8); my_surfaceformat.setAlphaBufferSize(8); my_surfaceformat.setDepthBufferSize(32); // Create scene on stack (works) ColorShifter my_scene = ColorShifter(); my_scene.setScreen(*QGuiApplication::screens().begin()); my_scene.setFormat(my_surfaceformat); my_scene.resize(640, 480); my_scene.show(); my_scene.setAnimating(true); // Create scene on heap (doesn't work) ColorShifter* my_scene2 = new ColorShifter(); my_scene2->setScreen(*QGuiApplication::screens().begin()); my_scene2->setFormat(my_surfaceformat); my_scene2->resize(640, 480); my_scene2->show(); my_scene2->setAnimating(true); return app.exec();
}
@I am using Qt-5.1.0-alpha, since I'd like to use QOpenGLFunctions later with GL3.2, plus in the long run I will need X11Extras too (to get X11-specific handles of screens and contexts).
-
Hi everyone. I'm a little embarresed about this, but the problem was that the default values for the clear screen r,g,b,a were not initialized inside the constructor, and for some obscure compiler reason, when the object was created on the stack, thus all variables member variables with it were initialized to 0.0, however when it was created on the heap, they were all like -478972932375.0 . Naturally it would've taken years before they reached 0.1 to get some visible update.
My OpenGLWindow works fine now. I've head on to my InteropWindow base class and a simple test case with it. I've encountered a different problem now, but I'll open a new topic for that, as it is most likely related to QPA issues.
-
Great you found out !
In C++ you should always initialize all your values regardless of what type they are. AFAIK, there is no guaranty of the value given at construction time (that may change in new versions of the standard)
Don't forget to update the thread's title to solved so other forum users may know a solution has been found :)