How can I track these OpenGL calls that distort objects in my scene?

I am mixing two libraries that use OpenGL: Qt and OpenSceneGraph. I am targeting OpenGL ES 2, so everything is done using shaders and ES 2 compatible calls.

I am using OSG with QtDeclarative, trying to draw OSG on QDeclarativeItem. I do this as suggested in the Qt documentation: wrap all OpenGL calls between beginNativePainting () / endNativePainting ().

This works fine until I use textures in my OpenSceneGraph scene. When I do this, my QML window becomes “confused” due to the lack of a better word. To keep it as simple as possible, my OSG scene consists of a plane with a texture applied to it. I recreated the scene using the main OpenGL calls, and the problem no longer occurs. Here the problem sums up like a bunch of images:

  • The QtDeclarative mechanism uses OpenGL for drawing. I created a simple QML page:

enter image description here

  • I am creating a simple scene using OpenGL directly. This is a plane with a texture drawn on it.

enter image description here

  • Now I'm trying to set up the same scene in OSG ... same shaders, etc.

enter image description here

You can see that something strange is happening with the last screenshot. Don’t worry about the black background where the original OpenGL scene was transparent, which is just OSG using a black transparent color. The problem is that other elements created with QML (rectangles) are confused.

Change To find out what happens: the rectangles I draw using QML are stretched to the right edge of the screen. I also noticed that if I draw rectangles after the OpenSceneGraph element in QML, they are not displayed (I have not noticed this before). I draw a purple black rectangle after the OSG element in the following screenshots ... note that it disappears. It may be weirder, but that’s all I saw playing with rectangles.

Before enter image description here

After enter image description here

I am new to OpenGL, so I don’t know which call / state mode will cause something like this. I think OpenSceneGraph is making some OpenGL state changes that confuse Qt's drawing mechanism. I also know that this only happens when OSG uses textures ... if I do not apply textures in my OSG scene, this does not happen. I'm stuck here.

In addition, I tried to use BuGLe to get an OpenGL call trace with and without textures included in OSG, to see if I can identify state change problems (states). I found several differences and even some global state that changed OSG (for example, glPixelStorei ()) between the two, but did not change the reset I found. It would help a lot if I knew what to look for. If someone feels crazy, I also have stack traces:

Edit 2: Diff may be useful here. You need to scroll down before the corresponding lines appear. http://www.mergely.com/nUEePufa/

Edit 3: Wow! Okay, that difference helped me quite a bit. OSG allows VertexAttribArray 3, but does not disable it. Calling glDisableVertexAttribArray (3) after the OSG renders its frame seems to partially solve the problem; no longer stretching QML rectangles. However, rectangles drawn after the OSG element are still not displayed .

+7
source share
2 answers

After numbing over the trace logs, I think I found two OpenGL things that should be reset before passing control back to Qt so that the problems mentioned above go away. I mentioned one in editing ... I will summarize both in this answer.

Rectangle / QML element distortion

QPainter uses the Vertex attributes 3, 4, and 5 directly for what looks like its geometry for these rectangles. This can be seen on the track:

[INFO] trace.call: glVertexAttrib3fv(3, 0x2d94a14 -> { 0.00195312, 0, 0 }) [INFO] trace.call: glVertexAttrib3fv(4, 0x2d94a20 -> { 0, -0.00333333, 0 }) [INFO] trace.call: glVertexAttrib3fv(5, 0x2d94a2c -> { 0.2, 0.4, 1 }) 

Disabling the corresponding vertex attribute arrays eliminates the problem with stretch rectangles:

  glDisableVertexAttribArray(3); glDisableVertexAttribArray(4); glDisableVertexAttribArray(5); 

Items created after an OSG item is not displayed

In retrospect, this was easy and had nothing to do with texturing. I did not notice this before trying to add textures to my scene, so mixing the two problems was my mistake. I also messed up the traces and diff that I posted; I never updated them to take into account the order problem after I discovered it (sorry!)

In any case, QPainter expects depth testing to be disabled. Qt will turn off depth testing when you call beginNativePainting (), and also when it starts to draw its elements ... but you expect to cancel it when passing control back:

  • QPainter draws material (DEPTH_TEST = off)
  • OSG draws material (DEPTH_TEST = on)
  • QPainter draws more things [expects DEPTH_TEST = off]

The correct trace logs showed that I did not do this ... Therefore, the fix

 glDisable(GL_DEPTH_TEST) 
+2
source

Perhaps you just need to reuse GL_TEXTURE_2D? I notice in your example the textures that OSG provides, and then disables GL_TEXTURE_2D. So the difference between your two cases (with texture versus without) is that the one that uses the textures ends up with the texturing turned off, and the one that doesn't have the texturing leaves the initial state GL_TEXTURE_2D in it.

If Qt requires / expects texturing to be enabled for drawing quads, this may not cause anything.

+1
source

All Articles