OpenGL|ES 2.0 glClear 命令冻结直到窗口状态改变

Posted

技术标签:

【中文标题】OpenGL|ES 2.0 glClear 命令冻结直到窗口状态改变【英文标题】:OpenGL|ES 2.0 glClear command freeze until window state change 【发布时间】:2013-11-14 09:24:23 【问题描述】:

我的 OpenGL|ES 2.0 glClear 命令会冻结,直到窗口状态发生变化(例如,窗口被隐藏或显示)。

目标平台是带有 Mali 400 GPU 的 ARM7。

所有代码大部分都是从 Qt OpenGL ES Cube 示例中复制而来的。

我忘记了什么?

里昂

来源: #include "streamplayer.h"

#include <QtOpenGL>
#include <QGLFunctions>



StreamPlayer::StreamPlayer(QWidget *parent) :
    QGLWidget(QGLFormat(QGL::SampleBuffers), parent)

    program = new QGLShaderProgram();



StreamPlayer::~StreamPlayer()



void StreamPlayer::initializeGL()

    qDebug() << "Initializing GL";
    initShaders();

    glClearColor(0.5f, 0.5f, 0.7f, 1.0f);
    return;


void StreamPlayer::paintGL()

    qDebug() << "Paint GL";
    qDebug() << "Clearing buffers";
    glClear(GL_COLOR_BUFFER_BIT);
    qDebug() << "Never comes here until a window state change";



void StreamPlayer::resizeGL(int width, int height)

    qDebug() << "Resizing GL to " << width << "x" << height;
    glViewport(0, 0, width, height);
    qDebug() << "Done resizing";


void StreamPlayer::initShaders()

    qDebug() << "Initializing shaders";
    setlocale(LC_NUMERIC, "C");

    if(!program->addShaderFromSourceFile(QGLShader::Vertex, ":/shaders/vshader.glsl")) 
        qDebug() << "Failed to create vertex shader";
    
    if(!program->addShaderFromSourceFile(QGLShader::Fragment, ":/shaders/fshader.glsl")) 
        qDebug() << "Failed to create fragment shader";
    

    if(!program->link()) 
        qDebug() << "Failed to link";
    

    _gl_vertex = program->attributeLocation("vertex");
    _gl_texCoord = program->attributeLocation("texCoord");
    _gl_matrix = program->attributeLocation("matrix");
    _gl_texture = program->attributeLocation("tex");

    if(!program->bind()) 
        qDebug() << "Failed to bind";
    

    setlocale(LC_ALL, "");
    qDebug() << "Shaders ready";

【问题讨论】:

【参考方案1】:

您是否让计时器要求帧更新?正是这个计时器通过调用 glwidget 上的 updateGL() 来请求 openGL 重绘,它请求(延迟的)paintGL()。否则,paintGL 只会在 Qt 估计需要时调用(例如显示的窗口)。

QTimer *timer = new QTimer(this);
timer->setInterval(10);
QObject::connect(timer, SIGNAL(timeout()), glwidget, SLOT(updateGL()));
//And at the end of MainWindow initialization
timer->start();

相关问题请见this SO thread。

【讨论】:

是的,我确实有一个更新计时器(从包含的代码中看不出来)。从父类调用更新命令。问题不在于缺少更新,而是 glClear 的阻塞.. 那我就去找丢失的 QPainter。我个人自己管理缓冲区,但在示例中,您需要用以下这些包围 glClear:QPainterpainter(this);画家.beginNativePainting(); glClear(...);画家.endNativePainting();

以上是关于OpenGL|ES 2.0 glClear 命令冻结直到窗口状态改变的主要内容,如果未能解决你的问题,请参考以下文章