QGLFramebufferObject可以比视口大吗?例如,如果我有一个300x300像素的视口,那么fbo可以是600x300吗? ...所以显示fbo的一半......然后应用翻译,显示另一半。第一次make_text();被称为缩放是正确的,第二次x维度被拉伸。
main.h
#include <QGLWidget>
#include <QGLFunctions>
#include <QGLFramebufferObject>
#include <QFont>
#include <QGLShader>
class glview : public QGLWidget, protected QGLFunctions
{
Q_OBJECT
public:
explicit glview(QWidget *parent = 0);
~glview();
QSize sizeHint() const;
protected:
void initializeGL();
void resizeGL(int w, int h);
void paintGL();
private:
void make_text(void);
QGLFramebufferObject *fbo;
QFont font;
quint32 vbo_id[1], texture_id;
QGLShaderProgram *txtovlp;
QTimer *delay;
private slots:
void refresh(void);
};
的main.cpp
#include <QApplication>
#include <QPainter>
#include <QTimer>
#include "main.h"
struct txtr_vrtx {
GLfloat x;
GLfloat y;
GLfloat z;
GLfloat tx;
GLfloat ty;
}__attribute__((packed)) txtr_geo[] = {
// x, y, z, tx,ty
{0, 0, 0, 0, 0},
{0, 3, 0, 0, 1},
{6, 3, 0, 1, 1},
{6, 0, 0, 1, 0},
};
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
glview widget;
widget.show();
return app.exec();
}
glview::glview(QWidget *parent) : QGLWidget(parent)
{
fbo = NULL;
font.setFamily("Helvetica");
delay = new QTimer;
delay->start(2000);
connect(delay, SIGNAL(timeout()), this, SLOT(refresh()));
}
glview::~glview()
{
delete fbo;
}
void glview::refresh(void)
{
delay->stop();
qDebug() << "refresh fired";
make_text();
updateGL();
}
void glview::make_text(void)
{
glBindBuffer(GL_ARRAY_BUFFER, 0); // must unbind for QPainter
glEnable(GL_TEXTURE_2D);
if (fbo)
delete fbo;
makeCurrent();
fbo = new QGLFramebufferObject(600, 300, GL_TEXTURE_2D);
fbo->bind();
texture_id = fbo->texture();
QPainter painter(fbo);
font.setPointSize(20);
painter.setFont(font);
painter.eraseRect(0,0,600,300);
painter.setPen(Qt::blue);
painter.drawText(100, 140, "FBO");
painter.setPen(Qt::red);
painter.drawText(400, 140, "FBO");
painter.end();
fbo->release();
}
QSize glview::sizeHint() const
{
return QSize(300, 300);
}
void glview::initializeGL()
{
initializeGLFunctions();
qglClearColor(Qt::white);
QGLShader *txtovlp_vshader = new QGLShader(QGLShader::Vertex, this);
const char *txtovlp_vsrc =
"attribute highp vec4 vertex;\n"
"attribute mediump vec2 texCoord;\n"
"varying mediump vec2 texc;\n"
"uniform mediump mat4 matrix;\n"
"void main(void)\n"
"{\n"
" gl_Position = matrix * vertex;\n"
" texc = texCoord;\n"
"}\n";
txtovlp_vshader->compileSourceCode(txtovlp_vsrc);
QGLShader *txtovlp_fshader = new QGLShader(QGLShader::Fragment, this);
const char *txtovlp_fsrc =
"uniform sampler2D texture;\n"
"varying mediump vec2 texc;\n"
"void main(void)\n"
"{\n"
" gl_FragColor = texture2D(texture, texc.st);\n"
"}\n";
txtovlp_fshader->compileSourceCode(txtovlp_fsrc);
txtovlp = new QGLShaderProgram(this);
txtovlp->addShader(txtovlp_vshader);
txtovlp->addShader(txtovlp_fshader);
txtovlp->link();
glGenBuffers(1, vbo_id);
glBindBuffer(GL_ARRAY_BUFFER, vbo_id[0]);
glBufferData(GL_ARRAY_BUFFER, sizeof(txtr_geo), txtr_geo, GL_STATIC_DRAW);
make_text();
glEnable(GL_DEPTH_TEST);
}
void glview::resizeGL(int w, int h)
{
glViewport(0, 0, w, h);
}
void glview::paintGL()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
QMatrix4x4 matrix;
matrix.ortho(0, 3, 0, 3, -1, 1);
//matrix.translate(-3,0,0);
txtovlp->bind();
txtovlp->setUniformValue("matrix", matrix);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_BLEND);
glEnable(GL_TEXTURE_2D);
glBindBuffer(GL_ARRAY_BUFFER, vbo_id[0]);
glBindTexture(GL_TEXTURE_2D, texture_id);
int txtr_vertexLocation = txtovlp->attributeLocation("vertex");
txtovlp->enableAttributeArray(txtr_vertexLocation);
glVertexAttribPointer(txtr_vertexLocation, 3, GL_FLOAT, GL_FALSE, sizeof(struct txtr_vrtx), 0);
int texCoordLocation = txtovlp->attributeLocation("texCoord");
txtovlp->enableAttributeArray(texCoordLocation);
glVertexAttribPointer(texCoordLocation, 2, GL_FLOAT, GL_FALSE, sizeof(struct txtr_vrtx), ((char*)NULL + 12));
glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
glDisable(GL_TEXTURE_2D);
glDisable(GL_BLEND);
glFlush();
}
答案 0 :(得分:0)
QPainter破坏GL上下文,我已经了解到还包括视口。通过添加glViewport(0,0,width(),height());在make_text()的末尾(在QPainter完成之后)恢复下一个绘制事件的视口。