我似乎无法让Qt5以有意义的速度更新我的场景。我的场景是一个512x512纹理矩形。我得到的速度大约是每秒1帧(!)。
在我的构造函数中
aTimer.setSingleShot(false);
aTimer->setTimerType(Qt::PreciseTimer);
connect(&aTimer,SIGNAL(timeout()),this,SLOT(animate()));
aTimer.start(50);
setAutoFillBackground(false);
和
void GLWidget::animate()
{
//Logic for every time step
updateGL();
}
有没有办法设定优先权?我做的事情完全是错的吗?在Qt中是否存在某种内在的更新限制,它肯定不是1 FPS的量级?我的理论是,Qt忽略了我实际更新屏幕的要求。
我试过了
QCoreApplication::processEvents();
,但这没有帮助forever{}
并从其中调用update wigglywidget
示例似乎有效,这暗示我QT OpenGL以某种方式折叠帧,忽略了我的更新调用。是否存在控制此问题的启发式方法?重新创建的最小代码
(版本有点不同,在wigglywidget类之后建模,但有完全相同的问题)
git clone https://bitbucket.org/FunFarm/qtcapturesoftware.git
glwidget.h
/****************************************************************************/
#ifndef GLWIDGET_H
#define GLWIDGET_H
#include <QGLWidget>
#include <QtOpenGL/qglshaderprogram.h>
#include <QTimer>
#include <math.h>
#include "time.h"
#include <assert.h>
#include <random>
class GLWidget : public QGLWidget
{
Q_OBJECT
public:
GLWidget(QWidget *parent = 0);
~GLWidget();
void addNoise();
protected:
void initializeGL();
void paintGL();
void timerEvent(QTimerEvent *event);
void resizeGL(int width, int height);
private:
QBasicTimer timer;
QPoint lastPos;
GLuint textures[6];
QVector<QVector2D> vertices;
QVector<QVector2D> texCoords;
QGLShaderProgram program1;
int vertexAttr1;
int vertexTexr1;
//
int heightGL;
int widthGL;
//
GLubyte* noise;
//
QTimer* aTimer;
//
};
#endif
glwidget.cpp
#include <QtWidgets>
#include <QtOpenGL>
#include "glwidget.h"
#ifndef GL_MULTISAMPLE
#define GL_MULTISAMPLE 0x809D
#endif
GLWidget::GLWidget(QWidget *parent)
: QGLWidget(QGLFormat(QGL::SampleBuffers), parent)
{
setAutoFillBackground(false);
aTimer = new QTimer();
timer.start(30, this); // 30 fps?
}
void GLWidget::timerEvent(QTimerEvent *event)
{
addNoise();
update();// Doesn't matter which update function I call, this is the one from the wigglywidget example
}
GLWidget::~GLWidget(){}
void GLWidget::initializeGL()
{
glEnable(GL_DEPTH_TEST);
glEnable(GL_CULL_FACE);
glShadeModel(GL_SMOOTH);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glEnable(GL_MULTISAMPLE);
static GLfloat lightPosition[4] = { 0.5, 5.0, 7.0, 1.0 };
glLightfv(GL_LIGHT0, GL_POSITION, lightPosition);
QGLShader *vshader1 = new QGLShader(QGLShader::Vertex, this);
const char *vsrc1 =
"attribute vec2 coord2d; \n"
"attribute mediump vec4 texCoord;\n"
"varying mediump vec4 texc;\n"
"void main() \n"
"{ \n"
" gl_Position = vec4(coord2d, 0.0, 1.0); \n"
" texc = texCoord;\n"
"} \n";
vshader1->compileSourceCode(vsrc1);
QGLShader *fshader1 = new QGLShader(QGLShader::Fragment, this);
const char *fsrc1 =
"uniform sampler2D texture;\n"
"varying mediump vec4 texc;\n"
"void main(void)\n"
"{\n"
" gl_FragColor = texture2D(texture, texc.st);\n"
"}\n" ;
fshader1->compileSourceCode(fsrc1);
program1.addShader(vshader1);
program1.addShader(fshader1);
program1.link();
vertexAttr1 = program1.attributeLocation( "coord2d");
vertexTexr1 = program1.attributeLocation( "texCoord");
// Create the vertex buffer.
vertices.clear();
float u=1;
#define AVEC -u,u
#define BVEC -u,-u
#define CVEC u,u
#define DVEC u,-u
vertices << QVector2D(AVEC);
vertices << QVector2D(BVEC);
vertices << QVector2D(CVEC);
vertices << QVector2D(BVEC);
vertices << QVector2D(DVEC);
vertices << QVector2D(CVEC);
// Create the texture vertex buffer
#define TAVEC 0,1
#define TBVEC 0,0
#define TCVEC 1,1
#define TDVEC 1,0
texCoords << QVector2D(TAVEC);
texCoords << QVector2D(TBVEC);
texCoords << QVector2D(TCVEC);
texCoords << QVector2D(TBVEC);
texCoords << QVector2D(TDVEC);
texCoords << QVector2D(TCVEC);
QPixmap aMap(":/images/testmap.jpg");
assert(aMap.width());
heightGL = aMap.height();
widthGL = aMap.width();
textures[0] =bindTexture(aMap,GL_TEXTURE_2D,GL_LUMINANCE);
noise = (GLubyte*) calloc(1*widthGL*heightGL,sizeof(GLubyte));//GL_RGB8
memset(noise,100,1*widthGL*heightGL);
//
}
void GLWidget::addNoise()
{
std::default_random_engine e((unsigned int)(time(0)));
GLubyte c = e()%256;
assert(noise);
for (int i = 0; i<heightGL;i++)
{
for(int j =0;j<widthGL;j++)
noise[i*widthGL+j]= c;
}
}
void GLWidget::paintGL()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
//
//
program1.bind();
program1.setUniformValue("texture", 0);
program1.enableAttributeArray(vertexAttr1);
program1.enableAttributeArray(vertexTexr1);
program1.setAttributeArray(vertexAttr1, vertices.constData());
program1.setAttributeArray(vertexTexr1, texCoords.constData());
glBindTexture(GL_TEXTURE_2D, textures[0]);
glTexSubImage2D(GL_TEXTURE_2D,0,0,0,
widthGL,heightGL,GL_LUMINANCE,GL_UNSIGNED_BYTE, //lets hope these are correct
noise);
glDrawArrays(GL_TRIANGLES, 0, vertices.size());
program1.disableAttributeArray(vertexTexr1);
program1.disableAttributeArray(vertexAttr1);
program1.release();
}
void GLWidget::resizeGL(int width, int height)
{
int side = qMin(width, height);
glViewport((width - side) / 2, (height - side) / 2, side, side);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(-0.5, +0.5, -0.5, +0.5, 4.0, 15.0);
glMatrixMode(GL_MODELVIEW);
}
的main.cpp
/****************************************************************************/
#include <QApplication>
#include <QDesktopWidget>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
//cameraView cV;
//cV.show();
GLWidget mW;
mW.show();
return a.exec();
}
test.pro
HEADERS = glwidget.h \
cameraview.h
SOURCES = glwidget.cpp \
main.cpp \
cameraview.cpp
QT += opengl widgets
CONFIG += console
CONFIG += c++11
# install
target.path = $$[QT_INSTALL_EXAMPLES]/qt_OpenGL_3x/02_First_Triangle
sources.files = $$SOURCES $$HEADERS $$RESOURCES $$FORMS 02-first-triangle.pro
sources.path = $$[QT_INSTALL_EXAMPLES]/qt_OpenGL_3x/02_First_Triangle
INSTALLS += target sources
simulator: warning(This example might not fully work on Simulator platform)
FORMS += \
cameraview.ui
RESOURCES += \
images.qrc
OTHER_FILES +=
答案 0 :(得分:10)
我克隆了存储库并对代码进行了一些更改,以帮助您调试问题。首先,使用 std :: cout 在paintGL()
的开头打印一条消息:
void GLWidget::paintGL()
{
static int xyz = 0;
std::cout << "PaintGL begin " << xyz << std::endl;
和paintGL
末尾的另一条消息。之后,递增计数器变量:
program1.release();
std::cout << "PaintGL end " << xyz << std::endl;
xyz++;
}
这种方法清楚地表明,由于在2秒内打印到控制台的消息量,paintGL()
每秒被调用近30次:
PaintGL begin 0
PaintGL end 0
PaintGL begin 1
PaintGL end 1
...
...
PaintGL begin 60
PaintGL end 60
PaintGL begin 61
PaintGL end 61
因此可以放弃计时器存在问题的理论。 计时器很好,你确实每秒刷一次30个计时器。
问题可能在您的代码中的其他位置。由于您只在存储库中共享了一部分应用程序,我担心我将无法再为您提供帮助。
修改强>:
我注意到addNoise()
里面有一个随机数生成器。如果您希望根据其他方法生成的数字在每{{}}}次呼叫时更改绘图,您会感到失望。
实现的当前数字生成机制对毫秒更改不敏感,因此在同一秒内对paintGL()
的所有调用都将生成相同的数字,这反过来会在窗口上绘制相同的内容整个第二个。这就解释了为什么图纸每秒只改变一次。
要解决此问题,我建议您查看: