c++ - Qt 和 OpenGL 窗口 - 调整大小时闪烁

标签 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,而且我很难想象问题可能出在哪里

最佳答案

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

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

关于c++ - Qt 和 OpenGL 窗口 - 调整大小时闪烁,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34267979/

相关文章:

c++ - 是否有替换 X-macros 的模板/constexpr/C++11 方法?

qt - Commonqt 无法在 OS X Lion 上使用 Clozure CL

c++ - 从 GPU 大量传输到 RAM 后渲染缓慢?

c++ - Qt 5 让 QQuickItem 在不使用 QPainter 的情况下绘制椭圆

opengl - FPS怎么计算这个?

c++ - Qt Creator Qt 5.7,未找到 OpenGL 函数

c++ - 从长(且合理)稀疏 vector 中选择随机元素的最有效方法是什么?

c++ - 为什么我收到此错误 : constexpr' is not valid here

c++ - 我可以在 DLL 中创建第二个单例实例吗?

qt - 调整pyqt tableview大小时如何裁剪列单元格的左侧