[Interest] Problems with OpenGL in Windows and Qt5
Till Oliver Knoll
till.oliver.knoll at gmail.com
Sat Mar 22 15:56:58 CET 2014
Am 21.03.14 22:06, schrieb Carlos:
> Hello Oliver
>
> Thanks for your help. In Windows and Linux it does not flickers and
> you can see two small rectangles (one yellow and one green).
I gave it another try, and it seems that "depening on the draw buffer
state" I sometimes do get two rectangles (green and yellow) on a black
background. The whole "black background" seems to be shifted to the
right and bottom, by (roughly) half the width and height of the window.
That is, it seems that drawing starts in the middle of the widget and
fills the bottom right quarter of the widget.
But as soon as I resize the window things get messy: the rectangles
are torn apart and "pixel garbage" starts to appear.
I tried to remove anything from your code which had to do with
"rotation" (it seems that this is related to mobile device
orientation), but to no avail.
However what I find odd is that you do seem to set the glViewport, but
I do not see the place where you would calculate a "model-view"
matrix, which one usually does (one would setup either an orthogonal
or a perspective matrix).
You do seem to calculate a m_Matrix2D in class Device::SetViewPort,
but I fail to see where you actually use that member variable (also, I
did not investigate too closely what that matrix is actually supposed
to do - is that the "model-view" matrix for a 2D scene?).
When I launch your app your Device::SetViewPort is called at least 4
times, each time with different "width" and "height" parameters! The
first pair is 640/1024 (coming from your defines SCREEN_RES_HZ and
SCREEN_RES_VT, triggered by MainWindow::Create), then followed by
160/160 (probably the initial size of the QGLWidget), then other sizes
such as 818/1280 and 752/1280 - very funky!
That probably all comes from the following oddness: upon resizing your
QMainWindow you seem to actively try to also resize your QGLWidget in
MainWindow::resizeEvent
by calling
m_QTOGLSystemDevice.resize(size().width(),size().height());
What is probably also very risky is to call QWidget::size() during a
resize. I don't know whether that is supposed to return the *old* or
the *new* size of the widget (it might even be undefined, which could
explain why you are seeing different results with different Qt/Platforms).
Anyway, the way to query the *new* size is with
QResizeEvent::size()
Also, it just feels wrong that you "actively" set the new size to your
QGLWidget (via m_QTOGLSystemDevice.resize) and even in a separate step
to your "rendering device" (in m_Device.SetViewPort).
Sorry, I did not find the root cause of your problem, except the above
odd points, maybe they give you some idea where to look further.
The way you /normally/ ("the Qt way") would resize a GL window is
basically:
* You do not actively set the new size of your QGLWidget! Instead, you
add it to your QMainWindow as parent, make sure it is contained in a
layout and let Qt do all the resizing for you (e.g. as triggered by
the user resizing the main window).
* So all you have to do is to get the new width and height in
QGLWidget::resizeGL (and again, that is normally called by Qt for
you!) and then...
* ... you set the glViewport and your
* new model-view matrix, apply that model-view matrix to your shader
and re-render the scene (which is also done for you by Qt which calls
QGLWidget::paintGL after the resize for you)
That can be as simple as e.g. the following:
void MainWidget::resizeGL(int w, int h)
{
// Set OpenGL viewport to cover whole widget
glViewport(0, 0, w, h);
// Calculate aspect ratio
qreal aspect = qreal(w) / qreal(h ? h : 1);
// Set near plane to 3.0, far plane to 7.0, field of view 45 degrees
const qreal zNear = 3.0, zFar = 7.0, fov = 45.0;
// Reset projection
projection.setToIdentity();
// Set perspective projection (or any other projection matrix)
projection.perspective(fov, aspect, zNear, zFar);
}
Done! No need to actively set the new size of the QGLWidget. And most
importantly, the resizing of your GL draw buffer should be triggered
by the QGLWidget, and not by some other QMainWindow which tries to
resize both a QGLWidget and some "rendering device". :)
I suggest you have a look at the following example:
http://qt-project.org/doc/qt-5.0/qtopengl/cube.html
(which by the way also uses OpenGL ES 2.0).
It also shows that Qt basically provides everything you need to setup
a nice "model-view" matrix and co. (QMatrix4x4 and friends).
> The code is as minimal as I could get in a couple of hours. I
> developed it for a couple of games I have published. If you have an
> iOS device let me know and I will send you a promo code.
I indeed have an iOS device - would be nice to see what you have done,
thanks :)
> Which version of Qt did you use?
Yes, I forgot to tell: I experimented with latest Qt 5.2.1 (binary
download) on OS X Mavericks 10.9.2 (and as I said, my older MacBook
Pro maxes out with OpenGL 3.3, but that does not matter here).
Cheers,
Oliver
More information about the Interest
mailing list