Qt& OpenGLWindow - 调整大小时闪烁

时间:2015-12-14 13:12:35

标签: c++ qt opengl

enter image description here

看来,如果我足够快地拖动调整大小,窗口本身就是通过子类化qwindow并在其上创建一个openGLcontext来创建的

代码:

#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位

我因为我从来没有在qt中使用openGL而失去了这里,并且我很难想象问题可能来自哪里

1 个答案:

答案 0 :(得分:0)

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

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);