Qt& OpenGLWindow-调整大小时闪烁 [英] Qt & OpenGLWindow - flicker on resizing

查看:551
本文介绍了Qt& OpenGLWindow-调整大小时闪烁的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如果我足够快地进行拖动调整大小,似乎会通过子类化qwindow并在其上创建openGLcontext来创建窗口本身

It appears if I drag-resize fast enough, the window itself is created by subclassing qwindow and making an openGLcontext on it

代码:

#include <QGuiApplication>
#include <QOpenGLContext>
#include <QWindow>
#include <QOpenGLFunctions_3_3_Core>
#include <stdio.h>

class OpenGLWindow : public QWindow, protected QOpenGLFunctions_3_3_Core{

     public:
     explicit OpenGLWindow();
     ~OpenGLWindow();
     virtual void render();
     bool isWindowInitialized;
     void exposeEvent(QExposeEvent *event);
     bool event(QEvent *event);

     private:
     QOpenGLContext* ctx;
     QSurfaceFormat* fmt;
     bool isGLInitialized;
     GLuint VertexArrayID;
     GLuint buffer1;
     GLuint ProgramID;
};

bool OpenGLWindow::event(QEvent *event)
{
     switch (event->type()) {
     case QEvent::UpdateRequest:
     render();
     return true;
     case QEvent::Close:
     glDisableVertexAttribArray(0);
     glDeleteBuffers(1, &buffer1);
     glDeleteVertexArrays(1, &VertexArrayID);
     glDeleteProgram(ProgramID);
     return QWindow::event(event);
     case QEvent::Resize:
     if(isWindowInitialized && isGLInitialized)glViewport(0,0,width(),height());
     return QWindow::event(event);
     default:
     return QWindow::event(event);
     }
}

void OpenGLWindow::exposeEvent(QExposeEvent *event)
{
    Q_UNUSED(event);
    if (isExposed())render();
}

OpenGLWindow::OpenGLWindow()
    :ctx(new QOpenGLContext)
    ,fmt(new QSurfaceFormat)
    ,isGLInitialized(0)
{
     setSurfaceType(OpenGLSurface);
     fmt->setRenderableType(QSurfaceFormat::OpenGL);
     fmt->setVersion(3,3);
     resize(640,480);
     fmt->setProfile(QSurfaceFormat::CoreProfile);
     setFormat(*fmt);
     ctx->setFormat(*fmt);
     ctx->create();
}

OpenGLWindow::~OpenGLWindow()
{}

void OpenGLWindow::render(){

 //if(Image::isWindowInitialized || isExposed())return;

 if(!isGLInitialized){

         ctx->makeCurrent(this);
         initializeOpenGLFunctions();

         GLuint vsID = glCreateShader(GL_VERTEX_SHADER);
         GLuint fsID = glCreateShader(GL_FRAGMENT_SHADER);

         const char* vs="#version 330 core\n layout(location = 0) in vec3 vertexPosition_modelspace; \n void main(){ gl_Position.xyz = vertexPosition_modelspace; gl_Position.w = 1.0;}";

         const char* fs="#version 330 core\n out vec4 color;\n void main(){ color = vec4(1,0,0,1);}";

         glShaderSource(vsID, 1, &vs , NULL);
         glCompileShader(vsID);
         GLint isCompiled = 0;
         glGetShaderiv(vsID, GL_COMPILE_STATUS, &isCompiled);

         if(isCompiled == GL_FALSE){
         GLint maxLength = 0;
         glGetShaderiv(vsID, GL_INFO_LOG_LENGTH, &maxLength);
         char info[512];
         glGetShaderInfoLog(vsID, maxLength, &maxLength, info);
         printf("%s",info);}

        glShaderSource(fsID, 1, &fs , NULL);
         glCompileShader(fsID);
         glGetShaderiv(fsID, GL_COMPILE_STATUS, &isCompiled);

        if(isCompiled == GL_FALSE){
         GLint maxLength = 0;
         glGetShaderiv(fsID, GL_INFO_LOG_LENGTH, &maxLength);
         char info[512];
         glGetShaderInfoLog(fsID, maxLength, &maxLength, info);
         printf("%s",info);
        }

        GLuint ProgramID = glCreateProgram();
         glAttachShader(ProgramID, vsID);
         glAttachShader(ProgramID, fsID);
         glLinkProgram(ProgramID);
         glDeleteShader(vsID);
         glDeleteShader(fsID);

        static const GLfloat data1[] = { -1.0f, -1.0f, 0.0f, 1.0f, -1.0f, 0.0f, 0.0f, 1.0f, 0.0f };


        glGenVertexArrays(1, &VertexArrayID);
        glBindVertexArray(VertexArrayID);
        glGenBuffers(1, &buffer1);
        glBindBuffer(GL_ARRAY_BUFFER,buffer1);
        glBufferData(GL_ARRAY_BUFFER, sizeof(data1),data1, GL_STATIC_DRAW);
        glEnableVertexAttribArray(0);
        glVertexAttribPointer(0 ,3 ,GL_FLOAT ,GL_FALSE,0 ,(void*)0 );
        glClearColor(1.0f, 0.0f, 0.4f,1.0f);
        glUseProgram(ProgramID);
        glViewport(0,0,width(),height());
        isGLInitialized=true;
    }

     if(isExposed()){
     glClear( GL_COLOR_BUFFER_BIT );
     glDrawArrays(GL_TRIANGLES, 0, 3);
     ctx->swapBuffers(this);
     }
}

int main(int argc, char **argv)
{
     QGuiApplication app(argc, argv);
     OpenGLWindow* win = new OpenGLWindow();
     win->show();
     win->isWindowInitialized=true;
     return app.exec();
}

我正在Qt Creator 3.4.1上使用Qt 5.4.2 套件:台式机Qt 5.4.2 MSVC2013 64位

I'm using Qt 5.4.2 on Qt Creator 3.4.1 Kit : Desktop Qt 5.4.2 MSVC2013 64bit

由于我从未在qt中使用过openGL,所以我在这里迷路了,我很难想象问题可能出在哪里

I'm kida lost here since i've never used openGL in qt and it's hard for me to picture where the problem might originate

推荐答案

尝试设置以下任意属性的组合:

Try setting a combination of any of the following attributes:

this->setAttribute(Qt::WA_OpaquePaintEvent, true);
this->setAttribute(Qt::WA_PaintOnScreen, true);
this->setAttribute(Qt::WA_DontCreateNativeAncestors, true);
this->setAttribute(Qt::WA_NativeWindow, true);
this->setAttribute(Qt::WA_NoSystemBackground, true);
this->setAttribute(Qt::WA_MSWindowsUseDirect3D, true);
this->setAutoFillBackground(false);

这篇关于Qt&amp; OpenGLWindow-调整大小时闪烁的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆