Opengl underlay
-
Hi forum,
I have followed the video tutorial about integrating qt quick 2 with opengl as underlay from KDAB. I am having the following console output:
@QSGContext::initialize: stencil buffer support missing, expect rendering errors@
I can see the opengl scene though with qt quick 2 scene with erratic behavior. I have checked the quick 2 scene separately and it works fine. While integration i get something otherwise.
Any hint to solve this issue ?
Thanks
-
Yes. When you pass in the custom QSurfaceFormat to QQuickWindow's setFormat() function, make sure that you have requested a stencil buffer by calling QSurfaceFormat::setStencilBufferSize(8). Qt Quick requiers the stencil buffer for some operations.
Ideally, grab the surface format from QQuickWindow, make your changes to it and set it back. In your QQuickView subclass ctor do something like:
@
MyQuickView::MyQuickView()
: QQuickView()
{
QSurfaceFormat f = format();
format.setVersion(...);
format.setProfile(...);
setFormat(f);
}
@This way, the surface format will already be set up to have a stencil buffer.
-
Thanks for the hint!
I got rid of the console output :
@ QSGContext::initialize: stencil buffer support missing, expect rendering errors @
But the erratic behavior persists. To debug this issue, i noticed that opengl rendering as underlay is not even clearing the window with the clear color. Check the following screen-shot:
!http://imgur.com/colEAty(screen-shot)!
Do you see the roughly tessellated teapot. Do you see the white background ? I have set the clearing color to:
@ //set the clearing color for the background
glClearColor(0.5f,0.5f,0.5f,1.0f); @This is the very first anomaly i can notice among many others. I though solving step by step.
Any thoughts ?
Thanks
-
Oops i just noticed that the link is not functional. Please check this :
-
You need to explicitly set up any OpenGL state that you need as QtQuick can and will mess with the OpenGL state. Qt Quick assumes that nothing else is using it's context.
Try calling QQuickWindow::resetOpenGLState() at the start and end of your custom OpenGL rendering function.
The reason that the buffer is not being cleared is likely that Qt Quick has masked off some or all of the buffers. The above call should reset that and a bunch of other state.
Try running your application in apitrace and then inspecting the trace file. You can check the checkbox in qapitrace to show only non-default OpenGL state to make it easier to see what is set.
-
Really? since i followed the tutorial video by Sean Harmer, i believe that he mentined something otherwise when it comes to integrate qtquick2 with opengl. Check the following snippet:
@
Window::Window(QWindow *parent)
: QQuickView(parent),
mScene(new TeapotTessellation(this))
{
setClearBeforeRendering(false);QObject::connect(this,SIGNAL(beforeRendering()),SLOT(renderOpenGLScene()),Qt::DirectConnection); QTimer *timer = new QTimer(this); connect(timer,SIGNAL(timeout()),this,SLOT(update())); timer->start(16); QSurfaceFormat f = format(); f.setMajorVersion(4); f.setMinorVersion(3); f.setSamples(4); f.setStencilBufferSize(8); f.setProfile(QSurfaceFormat::CompatibilityProfile); setFormat(f);
}
@Check the connection for the signal beforeRendering() and Qt::DirectConnection. I believe that i am borrowing the opengl context created by qtquick2 .
I did call the resetOpenGLState as suggested and now i get black background and if you see my last post you will see that i set a grey background. So i am not getting what i am expecting. Here goes more snippet:
@
void Window::update()
{
float time = mTime.elapsed() / 1000.0f;mScene->update(time); QQuickView::update();
}
void Window::renderOpenGLScene()
{
static bool firstTime = true;if(firstTime) { mScene->initialise(); mScene->resize(width(),height()); firstTime = false; } resetOpenGLState(); mScene->render(); resetOpenGLState();
}@
and more of the scene class
@
#ifndef TEAPOTTESSELLATION_H
#define TEAPOTTESSELLATION_H#include <QOpenGLFunctions_4_3_Compatibility>
#include "defines.h"
#include "AbstractScene.h"class GLSLShader;
class TeapotVboPatch;class TeapotTessellation : public AbstractScene, protected QOpenGLFunctions_4_3_Compatibility
{
Q_OBJECTpublic:
explicit TeapotTessellation(QObject *parent = 0); ~TeapotTessellation(); //scene related functions virtual void initialise(); virtual void update(float t); virtual void render(); virtual void resize(int w,int h);
private:
void loadShaders(); GLSLShader *mTessellationShader; TeapotVboPatch *mTeapotPatch; ...................... ......................
};
#endif // TEAPOTTESSELLATION_H
...........................
...........................
void TeapotTessellation::initialise()
{
//initialize the opengl functions
initializeOpenGLFunctions();loadShaders(); //initialize the teapot patch mTeapotPatch = new TeapotVboPatch(mTessellationShader); //set the clearing color for the background glClearColor(0.5f,0.5f,0.5f,1.0f); glGetIntegerv(GL_MAX_PATCH_VERTICES,&mMaxPatchVertices); ModelViewMatrix = glm::mat4(1.0f); ProjectionMatrix = glm::mat4(1.0f); ViewportMatrix = glm::mat4(1.0f); ViewMatrix = glm::mat4(1.0f); ModelMatrix = glm::mat4(1.0f); NormalMatrix = glm::mat3(1.0f); //enable depth testing glEnable(GL_DEPTH_TEST); glEnable(GL_CULL_FACE);
}
void TeapotTessellation::render()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);glm::mat4 Ty = glm::translate(glm::mat4(1.0f),glm::vec3(0.0f,1.5f,0.0f)); glm::mat4 Tz = glm::translate(glm::mat4(1.0f),glm::vec3(0.0f,0.0f,-mZoom)); glm::mat4 Ry = glm::rotate(glm::mat4(1.0),mTime,glm::vec3(0.0f,1.0f,0.0f)); glm::mat4 Rx = glm::rotate(glm::mat4(1.0f),20.0f,glm::vec3(1.0f,0.0f,0.0f)); ModelMatrix = Tz * Ty * Ry * Rx; ModelViewMatrix = ViewMatrix * ModelMatrix; NormalMatrix = glm::inverseTranspose(glm::mat3(ModelViewMatrix)); mTessellationShader->Use(); glUniformMatrix4fv((*mTessellationShader)("ModelviewMatrix"),1,GL_FALSE,glm::value_ptr(ModelViewMatrix)); glUniformMatrix4fv((*mTessellationShader)("ProjectionMatrix"),1,GL_FALSE,glm::value_ptr(ProjectionMatrix)); glUniformMatrix4fv((*mTessellationShader)("ViewportMatrix"),1,GL_FALSE,glm::value_ptr(ViewportMatrix)); glUniformMatrix3fv((*mTessellationShader)("NormalMatrix"),1,GL_FALSE,glm::value_ptr(NormalMatrix)); glUniform1f((*mTessellationShader)("outer"),mOuterTessellationFactor); glUniform1f((*mTessellationShader)("inner"),mInnerTessellationFactor); mTeapotPatch->render(); mTessellationShader->UnUse();
}
@
One more issue to discuss is that if you have opengl rendering commands to be spread across several class object, is not that better to have a singleton instance of the QOpenGLFunctions_4_3_Compatibility class , intialize it once and use a reference to it for the rest of the application's life-time ?
I shall be waiting for more thoughts on this issue
Thanks
-
It will be fun then. Here goes the link to the repository:
https://sajis997@bitbucket.org/sajis997/teapottessellationqt.git
I am using Qt 5.2 with QtCreator 3.0.1 at ubuntu 14.04 at my end.
Thanks