Reputation: 933
I have an app where a several QOpenGLFramebufferObject
needs to be blitted onto a larger QOpenGLFramebufferObject
. In order to do so, I thought I could simply "paste" the fbos onto the large fbo using the standard coordinates in Qt. The QOpenGLFramebufferObject::blitFramebuffer requires a "source" rect and a "target" rect. So for example, if my large fbo is 1000x1000 and my smaller fbos are 500x500. Then I would simply need to do the following:
auto sourceRect = QRect(0,0,500,500);
// i here would be the row of my grid of fbos
// j would be the column
for(int i =0; i < 2; i++){
for(int j= 0; j < 2; j++){
auto targetRect = QRect(i*500,j*500, 500, 500);
// tileFbo are the small fbos
QOpenGLFramebufferObject::blitFramebuffer(largeFbo,targetRect, tileFbo,sourceRect)
}
}
However, this doesn't work as it seems that QOpenGLFramebufferObject uses OpenGL coordinates. So how I can convert my QRect to use OpenGL coordinates?
Here is an example where I draw a line a small fbo (500x500) and then blit the small fbo on a large fbo (1000x1000). The line on the large fbo appears to be at the bottom-left instead of the top-left.
#include <QGuiApplication>
#include <QOffscreenSurface>
#include <QOpenGLFramebufferObject>
#include <QOpenGLContext>
#include <QPainter>
#include <QOpenGLPaintDevice>
#include <QDebug>
int main(int argc, char *argv[])
{
QGuiApplication a(argc, argv);
QSurfaceFormat format;
format.setSamples(8);
QOffscreenSurface* surface = new QOffscreenSurface;
surface->setFormat(format);
surface->create();
QOpenGLContext* context = new QOpenGLContext;
if(!context->create()){
qDebug() << "Failed to create context";
}
context->makeCurrent(surface);
auto smallFbo = new QOpenGLFramebufferObject(QSize(500,500));
auto largeFbo = new QOpenGLFramebufferObject(QSize(1000,1000));
smallFbo->bind();
QOpenGLPaintDevice paintDevice(smallFbo->size());
QPainter painter(&paintDevice);
painter.drawLine(QLine(0,0,400,400));
smallFbo->release();
// save small fbo to disk
smallFbo->toImage().save("/home/Desktop/smallfbo.png");
// blit the frame buffers
QOpenGLFramebufferObject::blitFramebuffer(largeFbo, QRect(0,0,500,500), smallFbo, QRect(0,0,500,500));
// save large fbo to disk
largeFbo->toImage().save("/home/Desktop/largefbo.png");
return 0;
}
Upvotes: 1
Views: 237
Reputation: 126
As far as i understand, this function is everything you need
QRect to_OpenGL_coordinates(const QRect& qt_coordinateRect, const QOpenGLFramebufferObject& fbo){
return QRect(qt_coordinateRect.x(), fbo.height() - qt_coordinateRect.y(),
qt_coordinateRect.width(), qt_coordinateRect.height() * -1);
}
and use it like this
// blit the frame buffers
QOpenGLFramebufferObject::blitFramebuffer(largeFbo, to_OpenGL_coordinates(QRect(0,0,500,500), *largeFbo),
smallFbo, to_OpenGL_coordinates(QRect(0,0,500,500), *smallFbo));
as a result.
Upvotes: 1