void NightModeGraphicsEffect::draw(QPainter* painter) { int pixelRatio = painter->device()->devicePixelRatio(); QSize size(painter->device()->width() * pixelRatio, painter->device()->height() * pixelRatio); if (fbo && fbo->size() != size) { delete fbo; fbo = NULL; } if (!fbo) { QGLFramebufferObjectFormat format; format.setAttachment(QGLFramebufferObject::CombinedDepthStencil); format.setInternalTextureFormat(GL_RGBA); fbo = new NightModeGraphicsEffectFbo(size, format, pixelRatio); } QPainter fboPainter(fbo); drawSource(&fboPainter); painter->save(); painter->beginNativePainting(); program->bind(); const GLfloat pos[] = {-1, -1, +1, -1, -1, +1, +1, +1}; const GLfloat texCoord[] = {0, 0, 1, 0, 0, 1, 1, 1}; program->setUniformValue(vars.source, 0); program->setAttributeArray(vars.pos, pos, 2); program->setAttributeArray(vars.texCoord, texCoord, 2); program->enableAttributeArray(vars.pos); program->enableAttributeArray(vars.texCoord); glBindTexture(GL_TEXTURE_2D, fbo->texture()); glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); program->release(); painter->endNativePainting(); painter->restore(); }
//! Initialize the frame buffer objects. void initFBOs() { invariant(); Q_ASSERT_X(useFBO(), Q_FUNC_INFO, "We're not using FBO"); if (NULL == backBuffer) { Q_ASSERT_X(NULL == frontBuffer, Q_FUNC_INFO, "frontBuffer is not null even though backBuffer is"); // If non-power-of-two textures are supported, // FBOs must have power of two size large enough to fit the viewport. const QSize bufferSize = nonPowerOfTwoTexturesSupported ? StelUtils::smallestPowerOfTwoSizeGreaterOrEqualTo(viewportSize) : viewportSize; // We want a depth and stencil buffer attached to our FBO if possible. const QGLFramebufferObject::Attachment attachment = QGLFramebufferObject::CombinedDepthStencil; backBuffer = new QGLFramebufferObject(bufferSize, attachment); frontBuffer = new QGLFramebufferObject(bufferSize, attachment); Q_ASSERT_X(backBuffer->isValid() && frontBuffer->isValid(), Q_FUNC_INFO, "Framebuffer objects failed to initialize"); } invariant(); }
MyPaintable(Gui::View3DInventorViewer* v) :view(v), img(v->getGLWidget()->size(), QImage::Format_ARGB32) { img.fill(qRgba(255, 255, 255, 0)); { QPainter p(&img); p.setPen(Qt::white); p.drawText(200,200,QString::fromLatin1("Render to QImage")); } img = QGLWidget::convertToGLFormat(img); fbo = new QGLFramebufferObject(v->getGLWidget()->size()); fbo->bind(); //glClear(GL_COLOR_BUFFER_BIT); fbo->release(); { QPainter p(fbo); p.setPen(Qt::white); p.drawText(200,200,QString::fromLatin1("Render to QGLFramebufferObject")); p.end(); //img = fbo->toImage(); //img = QGLWidget::convertToGLFormat(img); } //fbo->bind(); //glEnable(GL_DEPTH_TEST); //glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); //glDepthRange(0.1,1.0); //glEnable(GL_LINE_SMOOTH); //SoGLRenderAction a(SbViewportRegion(128,128)); //a.apply(v->getSceneManager()->getSceneGraph()); //fbo->release(); //img = fbo->toImage(); //img = QGLWidget::convertToGLFormat(img); view->getSoRenderManager()->scheduleRedraw(); }
void VideoView::paintGL(QGLPainter *painter) { QGLFramebufferObject *fbo = fboSurface->framebufferObject(); if (fbo) { painter->setStandardEffect(QGL::FlatReplaceTexture2D); painter->setTexture(QGLTexture2D::fromTextureId(fbo->texture(), fbo->size())); } else { painter->setStandardEffect(QGL::LitMaterial); } teapot.draw(painter); }
QGLFramebufferObject *QGLFramebufferObjectPool::acquire(const QSize &requestSize, const QGLFramebufferObjectFormat &requestFormat, bool strictSize) { QGLFramebufferObject *chosen = 0; QGLFramebufferObject *candidate = 0; for (int i = 0; !chosen && i < m_fbos.size(); ++i) { QGLFramebufferObject *fbo = m_fbos.at(i); if (strictSize) { if (fbo->size() == requestSize && fbo->format() == requestFormat) { chosen = fbo; break; } else { continue; } } if (fbo->format() == requestFormat) { // choose the fbo with a matching format and the closest size if (!candidate || areaDiff(requestSize, candidate) > areaDiff(requestSize, fbo)) candidate = fbo; } if (candidate) { m_fbos.removeOne(candidate); const QSize fboSize = candidate->size(); QSize sz = fboSize; if (sz.width() < requestSize.width()) sz.setWidth(qMax(requestSize.width(), qRound(sz.width() * 1.5))); if (sz.height() < requestSize.height()) sz.setHeight(qMax(requestSize.height(), qRound(sz.height() * 1.5))); // wasting too much space? if (sz.width() * sz.height() > requestSize.width() * requestSize.height() * 4) sz = requestSize; if (sz != fboSize) { delete candidate; candidate = new QGLFramebufferObject(maybeRoundToNextPowerOfTwo(sz), requestFormat); } chosen = candidate; } } if (!chosen) { if (strictSize) chosen = new QGLFramebufferObject(requestSize, requestFormat); else chosen = new QGLFramebufferObject(maybeRoundToNextPowerOfTwo(requestSize), requestFormat); } if (!chosen->isValid()) { delete chosen; chosen = 0; } return chosen; }
Selection* Sketcher::createSelection(int width, int height) { Selection *selection = new Selection(); //selection->setParameters(parameters, parameterNames); QGLFramebufferObject *fbo = new QGLFramebufferObject(width, height); glBindTexture(GL_TEXTURE_2D, fbo->texture()); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); selection->setSelectionMask(fbo); this->selections << selection; return selection; }
bool QGLViewPickSurface::activate(QGLAbstractSurface *prevSurface) { Q_UNUSED(prevSurface); if (m_fbo) m_fbo->bind(); return true; }
// -------------------------------------------------------- void TouchWidgetRenderer::drawMagnifyingGlass( GLResourceContainer * container, const MagnifyingGlass * mg, float alpha ) const { // draw contents to fbo QGLFramebufferObject * fbo = container->framebufferObject("mg_fbo"); drawSceneToFbo(fbo, mg->srcCenter(), mg->srcSize(), mg->angle()); //qDebug() << "drawing mg " << mg << mg->dstCenter() << mg->dstSize(); // draw magnifying glass including contents QGLShaderProgram * shader = container->shaderProgram("mglass"); shader->bind(); shader->setUniformValue("mglass_tex", 0); shader->setUniformValue("content_tex", 1); shader->setUniformValue("alpha", this->alpha()*alpha); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, container->texture("mglass")); glActiveTexture(GL_TEXTURE1); glBindTexture(GL_TEXTURE_2D, fbo->texture()); drawQuad(mg->dstCenter(), mg->dstSize(), -mg->angle(), this->alpha()*alpha); shader->release(); }
void resizeGL(int width, int height) { #if 0 fbObject->bind(); glDisable(GL_TEXTURE_2D); glEnable(GL_LIGHTING); glEnable(GL_DEPTH_TEST); glViewport(0, 0, width, height); glMatrixMode(GL_PROJECTION); glLoadIdentity(); if (width <= height) { glOrtho(0.0, 20.0, 0.0, 20.0 * GLfloat(height) / GLfloat(width), -10.0, 10.0); } else { glOrtho(0.0, 20.0 * GLfloat(width) / GLfloat(height), 0.0, 20.0, -10.0, 10.0); } glMatrixMode(GL_MODELVIEW); drawTeapots(); fbObject->release(); #else fbObject->bind(); glDisable(GL_TEXTURE_2D); glEnable(GL_LIGHTING); glEnable(GL_DEPTH_TEST); glEnable(GL_LINE_SMOOTH); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glDepthRange(0.1,1.0); SoGLRenderAction gl(SbViewportRegion(fbObject->size().width(),fbObject->size().height())); gl.apply(view->getSoRenderManager()->getSceneGraph()); fbObject->release(); #endif }
void QGLViewPickSurface::deactivate(QGLAbstractSurface *nextSurface) { Q_UNUSED(nextSurface); if (m_fbo) m_fbo->release(); }
void Layer::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) { QtPainter *qvpainter = NULL; #ifdef QT_OPENGL_LIB QPainter *fboPainter; QGLFramebufferObject *fbo = NULL; QGLWidget *qglWidget = qobject_cast<QGLWidget *>(widget); if (qglWidget) { // on-screen OpenGL QGLContext *context = const_cast<QGLContext *>(qglWidget->context()); qvpainter = new OpenGLPainter(painter, context); } else if (cacheMode() != QGraphicsItem::NoCache && QGLFramebufferObject::hasOpenGLFramebufferObjects()) { // caching, try FBO // if we have direct rendering and FBO support, make use of // FBO, but this could still just be in software // NOTE: In Qt 4.6, 'painter' would already target an FBO, if we // were using the 'OpenGL2' paint engine. We have decided to stick // with the original engine for now, as the OpenGL2 engine relies // heavily on shaders, which is slow for our use case. // Apparently, we must use the QGLContext associated with // the view being painted. Thus, PlotView tracks whether it is // inside a paintEvent, so we can get the current QGLWidget. OverlayScene *overlayScene = qobject_cast<OverlayScene *>(scene()); if (overlayScene) qglWidget = qobject_cast<QGLWidget *>(overlayScene->view()->viewport()); else { QList<QGraphicsView *> views = scene()->views(); for (int i = 0; i < views.size() && !qglWidget; i++) { PlotView *view = qobject_cast<PlotView *>(views[i]); if (view && view->isPainting()) qglWidget = qobject_cast<QGLWidget *>(view->viewport()); } } if (qglWidget) { QSize size(painter->device()->width(), painter->device()->height()); QGLContext *context = const_cast<QGLContext *>(qglWidget->context()); // GC during paint callback may have reset this if (qglWidget->context() != QGLContext::currentContext()) qglWidget->makeCurrent(); // NOTE: need Qt 4.6 for antialiasing to work with FBOs #if QT_VERSION >= 0x40600 if (!fboMultisamplingFailed) { QGLFramebufferObjectFormat fboFormat; fboFormat.setAttachment(QGLFramebufferObject::CombinedDepthStencil); fboFormat.setSamples(4); // 4X antialiasing should be enough? qInstallMsgHandler(fboDebugMsgCatcher); fbo = new QGLFramebufferObject(size, fboFormat); qInstallMsgHandler(0); if (fboMultisamplingFailed) { delete fbo; fbo = NULL; } } #endif if (!fbo) fbo = new QGLFramebufferObject(size); // clear the FBO fboPainter = new QPainter(fbo); fboPainter->setCompositionMode(QPainter::CompositionMode_Source); fboPainter->fillRect(0, 0, size.width(), size.height(), Qt::transparent); fboPainter->setCompositionMode(QPainter::CompositionMode_SourceOver); qvpainter = new OpenGLPainter(fboPainter, context); qvpainter->setTransform(painter->worldTransform()); } } #endif if (!qvpainter) // fallback to Qt renderer qvpainter = new QtPainter(painter); // NOTE: in QT 4.6 exposedRect will just be the bounding rect, by default paintPlot(qvpainter, option->exposedRect); delete qvpainter; #ifdef QT_OPENGL_LIB if (fbo) { // silliness: download to image, only to upload to texture painter->setWorldMatrixEnabled(false); qglWidget->makeCurrent(); // gc during callback may have cleared this // need to tell Qt that 'fboImage' is actually premultiplied QImage fboImage = fbo->toImage(); const uchar *data = fboImage.bits(); // no deep copy QImage premultImage = QImage(data, fboImage.width(), fboImage.height(), QImage::Format_ARGB32_Premultiplied); // Not sure why this can't be (0, 0)... painter->drawImage(QPointF(1, -1), premultImage); delete fboPainter; delete fbo; } #endif }
void paintGL() { const SbViewportRegion vp = view->getSoRenderManager()->getViewportRegion(); SbVec2s size = vp.getViewportSizePixels(); glDisable(GL_LIGHTING); glViewport(0, 0, size[0], size[1]); glMatrixMode(GL_PROJECTION); glLoadIdentity(); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); glDisable(GL_DEPTH_TEST); glClear(GL_COLOR_BUFFER_BIT); glEnable(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D, fbObject->texture()); glColor3f(1.0, 1.0, 1.0); GLfloat s = size[0] / GLfloat(fbObject->size().width()); GLfloat t = size[1] / GLfloat(fbObject->size().height()); glBegin(GL_QUADS); glTexCoord2f(0.0, 0.0); glVertex2f(-1.0, -1.0); glTexCoord2f(s, 0.0); glVertex2f(1.0, -1.0); glTexCoord2f(s, t); glVertex2f(1.0, 1.0); glTexCoord2f(0.0, t); glVertex2f(-1.0, 1.0); glEnd(); if (rubberBandIsShown) { glMatrixMode(GL_PROJECTION); glOrtho(0, size[0], size[1], 0, 0, 100); glMatrixMode(GL_MODELVIEW); glDisable(GL_TEXTURE_2D); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glLineWidth(4.0); glColor4f(1.0f, 1.0f, 1.0f, 0.2f); glRecti(rubberBandCorner1.x(), rubberBandCorner1.y(), rubberBandCorner2.x(), rubberBandCorner2.y()); glColor4f(1.0, 1.0, 0.0, 0.5); glLineStipple(3, 0xAAAA); glEnable(GL_LINE_STIPPLE); glBegin(GL_LINE_LOOP); glVertex2i(rubberBandCorner1.x(), rubberBandCorner1.y()); glVertex2i(rubberBandCorner2.x(), rubberBandCorner1.y()); glVertex2i(rubberBandCorner2.x(), rubberBandCorner2.y()); glVertex2i(rubberBandCorner1.x(), rubberBandCorner2.y()); glEnd(); glLineWidth(1.0); glDisable(GL_LINE_STIPPLE); glDisable(GL_BLEND); } glEnable(GL_LIGHTING); glEnable(GL_DEPTH_TEST); }