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 命令冻结直到窗口状态改变的主要内容,如果未能解决你的问题,请参考以下文章

OPENGL ES 2.0 知识串讲 ——OPENGL ES 详解III(纹理)

OPENGL ES 2.0 知识串讲 ——OPENGL ES 详解III(纹理)

OPENGL ES 2.0 知识串讲――OPENGL ES 2.0 概括

OPENGL ES 3.1是否比OPENGL ES 2.0慢?

如何在Android上使用OpenGL ES 2.0绘制点

如何在Android上将OpenGL ES 1.0代码转换为OpenGL Es 2.0?