Beispiel #1
0
void ShaderEffectSource::updateBackbuffer()
{
    if (!m_sourceItem || !QGLContext::currentContext())
        return;

    // Multisampling is not (for now) supported.
    QSize size = QSize(m_sourceItem->width(), m_sourceItem->height());
    if (!m_textureSize.isEmpty())
        size = m_textureSize;

    if (size.height() > 0 && size.width() > 0) {
        QGLFramebufferObjectFormat format;
        format.setAttachment(QGLFramebufferObject::CombinedDepthStencil);
        format.setInternalTextureFormat(m_format);

        if (!m_fbo) {
            m_fbo =  new ShaderEffectBuffer(size, format);
        } else {
            if (!m_fbo->isValid() || m_fbo->size() != size || m_fbo->format().internalTextureFormat() != GLenum(m_format)) {
                delete m_fbo;
                m_fbo = 0;
                m_fbo =  new ShaderEffectBuffer(size, format);
            }
        }
    }

    // Note that real update for the source content happens in shadereffect.cpp
    m_dirtyTexture = false;
}
Beispiel #2
0
void CubeItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
{
    // Render the inner scene into a framebuffer object.
    // We do this while the ordinary Qt paint engine has
    // control of the GL context rather than later when the
    // QGLPainter has control of the GL context.
    if (mScene) {
        if (!fbo) {
            QGLFramebufferObjectFormat format;
            format.setAttachment(QGLFramebufferObject::CombinedDepthStencil);
            //format.setSamples(8);
            fbo = new QGLFramebufferObject
                (mScene->sceneRect().size().toSize(), format);
        }
        QRectF rect(0, 0, fbo->size().width(), fbo->size().height());
        QPainter fboPainter(fbo);
        fboPainter.save();
        QLinearGradient gradient(rect.topLeft(), rect.bottomRight());
        gradient.setColorAt(0, QColor(0, 128, 192, 255));
        gradient.setColorAt(1, QColor(0, 0, 128, 255));
        fboPainter.setPen(QPen(Qt::black, 3));
        fboPainter.setBrush(gradient);
        fboPainter.drawRect(rect);
        fboPainter.restore();
        mScene->render(&fboPainter, rect);
    }

    // Now render the GL parts of the item using QGLPainter.
    QGLGraphicsViewportItem::paint(painter, option, widget);
}
Beispiel #3
0
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();
}
Beispiel #4
0
void SVG::renderToTexture(const QRectF& textureRect, QGLFramebufferObjectPtr targetFbo)
{
    saveGLState();

    // generate and set view box in logical coordinates
    QRectF viewbox(svgExtents_.x() + textureRect.x() * svgExtents_.width(),
                   svgExtents_.y() + textureRect.y() * svgExtents_.height(),
                   textureRect.width() * svgExtents_.width(),
                   textureRect.height() * svgExtents_.height());
    svgRenderer_.setViewBox(viewbox);

    // Multisampled FBO for anti-aliased rendering
    QGLFramebufferObjectFormat format;
    format.setAttachment(QGLFramebufferObject::CombinedDepthStencil);
    format.setSamples(MULTI_SAMPLE_ANTI_ALIASING_SAMPLES);

    QGLFramebufferObjectPtr renderFbo( new QGLFramebufferObject( targetFbo->size(), format ));

    // Render to multisampled FBO
    QPainter painter(renderFbo.get());
    painter.setRenderHints(QPainter::Antialiasing | QPainter::TextAntialiasing);
    svgRenderer_.render(&painter);
    painter.end();

    // Copy to texture FBO
    QGLFramebufferObject::blitFramebuffer(
            targetFbo.get(), QRect(0, 0, renderFbo->width(), renderFbo->height()),
            renderFbo.get(), QRect(0, 0, renderFbo->width(), renderFbo->height()));

    glBindTexture(GL_TEXTURE_2D, targetFbo->texture());
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);

    restoreGLState();
}
void FBORenderStrategy::createFBOs(const QSize& size)
{
    if (multisampleFBO && resolveFBO && resolveFBO->size() == size)
        return;

    // Create a multisample FBO and an FBO to resolve into
    QGLFramebufferObjectFormat fboFormat;
    fboFormat.setSamples(4);
    fboFormat.setAttachment(QGLFramebufferObject::CombinedDepthStencil);
    delete multisampleFBO;
    multisampleFBO = new QGLFramebufferObject(size, fboFormat);
    delete resolveFBO;
    resolveFBO = new QGLFramebufferObject(size);
}
Beispiel #6
0
QPaintEngine* QGLPixmapData::paintEngine() const
{
    if (!isValid())
        return 0;

    if (m_renderFbo)
        return m_engine;

    if (useFramebufferObjects()) {
        extern QGLWidget* qt_gl_share_widget();

        if (!QGLContext::currentContext())
            qt_gl_share_widget()->makeCurrent();
        QGLShareContextScope ctx(qt_gl_share_widget()->context());

        QGLFramebufferObjectFormat format;
        format.setAttachment(QGLFramebufferObject::CombinedDepthStencil);
        format.setSamples(4);
        format.setInternalTextureFormat(GLenum(m_hasAlpha ? GL_RGBA : GL_RGB));

        m_renderFbo = qgl_fbo_pool()->acquire(size(), format);

        if (m_renderFbo) {
            if (!m_engine)
                m_engine = new QGL2PaintEngineEx;
            return m_engine;
        }

        qWarning() << "Failed to create pixmap texture buffer of size " << size() << ", falling back to raster paint engine";
    }

    // If the application wants to paint into the QPixmap, we first
    // force it to QImage format and then paint into that.
    // This is simpler than juggling multiple GL contexts.
    const_cast<QGLPixmapData *>(this)->forceToImage();

    if (m_hasFillColor) {
        m_source.fill(PREMUL(m_fillColor.rgba()));
        m_hasFillColor = false;
    }
    return m_source.paintEngine();
}
Beispiel #7
0
QPaintEngine* QGLPixmapData::paintEngine() const
{
    if (!isValid())
        return 0;

    if (m_renderFbo)
        return m_engine;

    if (useFramebufferObjects()) {
        extern QGLWidget* qt_gl_share_widget();

        if (!QGLContext::currentContext())
            const_cast<QGLContext *>(qt_gl_share_context())->makeCurrent();
        QGLShareContextScope ctx(qt_gl_share_context());

        QGLFramebufferObjectFormat format;
        format.setAttachment(QGLFramebufferObject::CombinedDepthStencil);
        format.setSamples(4);
        format.setInternalTextureFormat(GLenum(m_hasAlpha ? GL_RGBA : GL_RGB));

        m_renderFbo = qgl_fbo_pool()->acquire(size(), format);

        if (m_renderFbo) {
            if (!m_engine)
                m_engine = new QGL2PaintEngineEx;
            return m_engine;
        }

        qWarning() << "Failed to create pixmap texture buffer of size " << size() << ", falling back to raster paint engine";
    }

    m_dirty = true;
    if (m_source.size() != size())
        m_source = QImage(size(), QImage::Format_ARGB32_Premultiplied);
    if (m_hasFillColor) {
        m_source.fill(PREMUL(m_fillColor.rgba()));
        m_hasFillColor = false;
    }
    return m_source.paintEngine();
}
Beispiel #8
0
GLWidget::GLWidget(QWidget *parent)
    : QGLWidget(QGLFormat(QGL::SampleBuffers|QGL::AlphaChannel), parent)
{
    setWindowTitle(tr("OpenGL framebuffer objects"));
    makeCurrent();

    if (QGLFramebufferObject::hasOpenGLFramebufferBlit()) {
        QGLFramebufferObjectFormat format;
        format.setSamples(4);
        format.setAttachment(QGLFramebufferObject::CombinedDepthStencil);

        render_fbo = new QGLFramebufferObject(512, 512, format);
        texture_fbo = new QGLFramebufferObject(512, 512);
    } else {
        render_fbo = new QGLFramebufferObject(1024, 1024);
        texture_fbo = render_fbo;
    }

    rot_x = rot_y = rot_z = 0.0f;
    scale = 0.1f;
    anim = new QTimeLine(750, this);
    anim->setUpdateInterval(20);
    connect(anim, SIGNAL(valueChanged(qreal)), SLOT(animate(qreal)));
    connect(anim, SIGNAL(finished()), SLOT(animFinished()));

    svg_renderer = new QSvgRenderer(QLatin1String(":/res/bubbles.svg"), this);
    connect(svg_renderer, SIGNAL(repaintNeeded()), this, SLOT(draw()));

    logo = QImage(":/res/designer.png");
    logo = logo.convertToFormat(QImage::Format_ARGB32);

    tile_list = glGenLists(1);
    glNewList(tile_list, GL_COMPILE);
    glBegin(GL_QUADS);
    {
        glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, -1.0f,  1.0f);
        glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f, -1.0f,  1.0f);
        glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f,  1.0f,  1.0f);
        glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f,  1.0f,  1.0f);

        glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f, -1.0f);
        glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f,  1.0f, -1.0f);
        glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f,  1.0f, -1.0f);
        glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f, -1.0f);

        glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f,  1.0f, -1.0f);
        glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f,  1.0f,  1.0f);
        glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f,  1.0f,  1.0f);
        glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f,  1.0f, -1.0f);

        glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f, -1.0f, -1.0f);
        glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f, -1.0f, -1.0f);
        glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f,  1.0f);
        glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f,  1.0f);

        glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f, -1.0f, -1.0f);
        glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f,  1.0f, -1.0f);
        glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f,  1.0f,  1.0f);
        glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f,  1.0f);

        glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, -1.0f, -1.0f);
        glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f,  1.0f);
        glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f,  1.0f,  1.0f);
        glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f,  1.0f, -1.0f);
    }
    glEnd();
    glEndList();

    wave = new GLfloat[logo.width()*logo.height()];
    memset(wave, 0, logo.width()*logo.height());
    startTimer(30); // wave timer
}
Beispiel #9
0
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
}
Beispiel #10
0
void FrameInfo::resize(uint w, uint h)
// ----------------------------------------------------------------------------
//   Change the size of the frame buffer used for rendering
// ----------------------------------------------------------------------------
{
    assert(QGLContext::currentContext() ||
           !"FrameInfo::resize without an OpenGL context???");
    
    // Don't change anything if size stays the same
    if (renderFBO && renderFBO->width()==int(w) && renderFBO->height()==int(h))
        return;
    
    IFTRACE(fbo)
        std::cerr << "[FrameInfo] Resize " << w << "x" << h << "\n";

    GraphicSave *save = GL.Save();

    // Delete anything we might have
    purge();

    // If the size is too big, we shouldn't use multisampling, it crashes
    // on MacOSX
    const uint SAMPLES = 4;
    const uint maxTextureSize = GL.MaxTextureSize();
    bool canMultiSample = QGLFramebufferObject::hasOpenGLFramebufferBlit() &&
                          TaoApp->hasFBOMultisample;
    if (w >= maxTextureSize || h >= maxTextureSize)
    {
        IFTRACE(fbo)
            std::cerr << "[FrameInfo] Disable multisample, too big "
                      << maxTextureSize << "\n";
        canMultiSample = false;
    }

    // Select whether we draw directly in texture or blit to it
    // If we can blit and suceed in creating a multisample buffer,
    // we first draw in a multisample buffer
    // with 4 samples per pixel. This cannot be used directly as texture.
    QGLFramebufferObjectFormat format;
    format.setInternalTextureFormat(this->format);

    // Enable mipmap for fbo
    if(PerformancesPage::texture2DMipmap())
        format.setMipmap(true);

    format.setAttachment(QGLFramebufferObject::CombinedDepthStencil);
    if (canMultiSample)
    {
        QGLFramebufferObjectFormat mformat(format);
        mformat.setSamples(SAMPLES);
        renderFBO = new QGLFramebufferObject(w, h, mformat);
        // REVISIT: we pass format to have a depth buffer attachment.
        // This is required only when we want to later use depthTexture().
        // TODO: specify at object creation?
        textureFBO = new QGLFramebufferObject(w, h, format);
    }
    else
    {
        renderFBO = new QGLFramebufferObject(w, h, format);
        textureFBO = renderFBO;
    }

    // The value of the min and mag filters of the underlying texture
    // are forced to GL_NEAREST by Qt, which are not the GL defaults.
    // => We must synchronize our cache or some later GL.TexParameter calls
    // may be ignored.
    GLint min, mag;
    GLuint tex = textureFBO->texture();
    glBindTexture(GL_TEXTURE_2D, tex);
    // Query the actual values to be safe
    glGetTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, &min);
    glGetTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, &mag);
    glBindTexture(GL_TEXTURE_2D, 0);
    GL.BindTexture(GL_TEXTURE_2D, tex);
    GL.TexParameter(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, min);
    GL.TexParameter(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, mag);
    if(PerformancesPage::texture2DMipmap())
        GL.GenerateMipmap(GL_TEXTURE_2D);
    GL.Sync(STATE_textures);
    GL.BindTexture(GL_TEXTURE_2D, 0);

    // depthTextureID is optional, resize if we have one
    if (depthTextureID)
        resizeDepthTexture(w, h);
    
    // Store what context we created things in
    this->w = w; this->h = h;
    this->context = (QGLContext *) QGLContext::currentContext();
    IFTRACE(fbo)
        std::cerr << "[FrameInfo] Resized " << w << "x" << h
                  << " in " << context << "\n";

    GL.Restore(save);
    
    // Clear the contents of the newly created frame buffer
    begin(true);
    end();
}
Beispiel #11
0
bool AmbientOcclusionPlugin::applyFilter(QAction *filter, MeshDocument &md, RichParameterSet & par, vcg::CallBackPos *cb)
{
    MeshModel &m=*(md.mm());
    if(ID(filter)==FP_FACE_AMBIENT_OCCLUSION ) perFace=true;
	else perFace = false;
	
	useGPU = par.getBool("useGPU");
	useVBO = par.getBool("useVBO");
	depthTexSize = par.getInt("depthTexSize");
	depthTexArea = depthTexSize*depthTexSize;
	numViews = par.getInt("reqViews");
	errInit = false;
	float dirBias = par.getFloat("dirBias");
	Point3f coneDir = par.getPoint3f("coneDir");
	float coneAngle = par.getFloat("coneAngle");
	
	if(perFace) 
	  m.updateDataMask(MeshModel::MM_FACEQUALITY | MeshModel::MM_FACECOLOR);
	else 
		m.updateDataMask(MeshModel::MM_VERTQUALITY | MeshModel::MM_VERTCOLOR);

	
	std::vector<Point3f> unifDirVec;
	GenNormal<float>::Uniform(numViews,unifDirVec);
	
	std::vector<Point3f> coneDirVec;
	GenNormal<float>::UniformCone(numViews, coneDirVec, math::ToRad(coneAngle), coneDir);
	
	std::random_shuffle(unifDirVec.begin(),unifDirVec.end());
	std::random_shuffle(coneDirVec.begin(),coneDirVec.end());

	int unifNum = floor(unifDirVec.size() * (1.0 - dirBias ));
	int coneNum = floor(coneDirVec.size() * (dirBias ));
									
	
	viewDirVec.clear();
	viewDirVec.insert(viewDirVec.end(),unifDirVec.begin(),unifDirVec.begin()+unifNum);
	viewDirVec.insert(viewDirVec.end(),coneDirVec.begin(),coneDirVec.begin()+coneNum);
	
	numViews = viewDirVec.size();


	this->glContext->makeCurrent();
	this->initGL(cb,m.cm.vn);
	unsigned int widgetSize = std::min(maxTexSize, depthTexSize);
	QSize fbosize(widgetSize,widgetSize);
	QGLFramebufferObjectFormat frmt;
	frmt.setInternalTextureFormat(GL_RGBA);
	frmt.setAttachment(QGLFramebufferObject::Depth);
	QGLFramebufferObject fbo(fbosize,frmt);
	qDebug("Start Painting window size %i %i", fbo.width(), fbo.height());
	GLenum err = glGetError();
	fbo.bind();
	processGL(m,viewDirVec);
	fbo.release();
	err = glGetError();
	const GLubyte* errname = gluErrorString(err);
	qDebug("End Painting");
	this->glContext->doneCurrent();
	return !errInit;
}
Beispiel #12
0
void MouseMagnifyingGlassInteractorComponent::generateMagnifyingGlassTexture(const Coord &magnifyingGlassCenterScr) {

  bool antialiased = false;

  bool canUseMultisampleFbo = OpenGlConfigManager::getInst().isExtensionSupported("GL_EXT_framebuffer_multisample");

  if (QGLFramebufferObject::hasOpenGLFramebufferBlit() && canUseMultisampleFbo) {
    antialiased = true;
  }

  int fboSize = static_cast<int>(radius * 2);

  // instantiate fbo if needed
  if (fbo == NULL) {
    QGLFramebufferObjectFormat fboFormat;
    fboFormat.setAttachment(QGLFramebufferObject::CombinedDepthStencil);

    if (antialiased) {
      fboFormat.setSamples(OpenGlConfigManager::getInst().maxNumberOfSamples());
    }

    fbo = new QGLFramebufferObject(fboSize, fboSize, fboFormat);

    if (antialiased) {
      fbo2 = new QGLFramebufferObject(fboSize, fboSize);
    }

    if (!antialiased) {
      GlTextureManager::getInst().registerExternalTexture(textureName, fbo->texture());
    }
    else {
      GlTextureManager::getInst().registerExternalTexture(textureName, fbo2->texture());
    }
  }

  Vector<int, 4> viewport = glWidget->getScene()->getViewport();

  // get the magnifying glass bounding box in screen space
  BoundingBox boundingBox;
  boundingBox[0] = Coord(magnifyingGlassCenterScr.getX() - radius, magnifyingGlassCenterScr.getY() - radius);
  boundingBox[1] = Coord(magnifyingGlassCenterScr.getX() + radius, magnifyingGlassCenterScr.getY() + radius);

  // compute the zoom factor to apply to scene's camera to get the area under the magnifying glass displayed entirely in the viewport
  float bbWidthScreen = boundingBox[1][0] - boundingBox[0][0];
  float bbHeightScreen = boundingBox[1][1] - boundingBox[0][1];
  float startSize = glWidget->screenToViewport(min(glWidget->width(), glWidget->height()));
  float endSize = max(bbHeightScreen, bbWidthScreen);
  float zoomFactor = startSize / endSize;

  // backup current camera parameters
  float sceneRadiusBak = camera->getSceneRadius();
  float zoomFactorBak = camera->getZoomFactor();
  Coord eyesBak = camera->getEyes();
  Coord centerBak = camera->getCenter();
  Coord upBak = camera->getUp();

  Coord move = boxCenter - centerBak;
  camera->setCenter(camera->getCenter() + move);
  camera->setEyes(camera->getEyes() + move);
  camera->setZoomFactor(magnifyPower * zoomFactor * zoomFactorBak);


  glPushAttrib(GL_ALL_ATTRIB_BITS);

  glMatrixMode(GL_PROJECTION);
  glPushMatrix();

  glMatrixMode(GL_MODELVIEW);
  glPushMatrix();

  // resize the viewport to the size of fbo and render the scene into this last one
  GlScene *scene = glWidget->getScene();
  scene->setViewport(0, 0, fboSize, fboSize);
  fbo->bind();
  Color color = scene->getBackgroundColor();
  glClearColor(color.getRGL(), color.getGGL(), color.getBGL(), color.getAGL());
  glClear(GL_COLOR_BUFFER_BIT);
  scene->draw();
  fbo->release();

  if (antialiased) {
    QGLFramebufferObject::blitFramebuffer(fbo2, QRect(0,0,fboSize, fboSize), fbo, QRect(0,0,fboSize, fboSize));
  }

  // restore original camera parameters
  scene->setViewport(viewport[0], viewport[1], viewport[2], viewport[3]);
  camera->setSceneRadius(sceneRadiusBak);
  camera->setZoomFactor(zoomFactorBak);
  camera->setEyes(eyesBak);
  camera->setCenter(centerBak);
  camera->setUp(upBak);

  glMatrixMode(GL_MODELVIEW);
  glPopMatrix();

  glMatrixMode(GL_PROJECTION);
  glPopMatrix();

  glPopAttrib();

  // need to call this explicitely otherwise we have to redraw the scene
  glViewport(viewport[0], viewport[1], viewport[2], viewport[3]);
}
Beispiel #13
0
void QwtPlotGLCanvas::paintGL()
{
    const bool hasFocusIndicator =
        hasFocus() && focusIndicator() == CanvasFocusIndicator;

    QPainter painter;

#if QT_VERSION < 0x040600
    painter.begin( this );
    draw( &painter );
#else
    if ( testPaintAttribute( QwtPlotGLCanvas::BackingStore ) )
    {
        if ( d_data->fbo == NULL || d_data->fbo->size() != size() )
        {
            invalidateBackingStore();

            const int numSamples = 16;

            QGLFramebufferObjectFormat format;
            format.setSamples( numSamples );
            format.setAttachment(QGLFramebufferObject::CombinedDepthStencil);

            QGLFramebufferObject fbo( size(), format );

            QPainter fboPainter( &fbo );
            draw( &fboPainter);
            fboPainter.end();

            d_data->fbo = new QGLFramebufferObject( size() );

            QRect rect(0, 0, width(), height());
            QGLFramebufferObject::blitFramebuffer(d_data->fbo, rect, &fbo, rect);
        }

        // drawTexture( QRectF( -1.0, 1.0, 2.0, -2.0 ), d_data->fbo->texture() );

        if ( hasFocusIndicator )
            painter.begin( this );
        
        glBindTexture(GL_TEXTURE_2D, d_data->fbo->texture());
        
        glEnable(GL_TEXTURE_2D);
        
        glBegin(GL_QUADS);
        
        glTexCoord2f(0.0f, 0.0f);
        glVertex2f(-1.0f, -1.0f);
        glTexCoord2f(1.0f, 0.0f);
        glVertex2f( 1.0f, -1.0f);
        glTexCoord2f(1.0f, 1.0f);
        glVertex2f( 1.0f,  1.0f);
        glTexCoord2f(0.0f, 1.0f);
        glVertex2f(-1.0f,  1.0f);
        
        glEnd();
    }
    else
    {
        painter.begin( this );
        draw( &painter );
    }
#endif

    if ( hasFocus() && focusIndicator() == CanvasFocusIndicator )
        drawFocusIndicator( &painter );
}
Beispiel #14
0
void RenderHelper::renderScene(vcg::Shotf &view, MeshModel *mesh, RenderingMode mode, float camNear = 0, float camFar = 0) 
{
  int wt = view.Intrinsics.ViewportPx[0];
  int ht = view.Intrinsics.ViewportPx[1];

  rendmode = mode;

  QSize fbosize(wt, ht);
  QGLFramebufferObjectFormat frmt;
  frmt.setInternalTextureFormat(GL_RGBA);
  frmt.setAttachment(QGLFramebufferObject::Depth);
  QGLFramebufferObject fbo(fbosize,frmt);

  float _near, _far;

  if((camNear <= 0) || (camFar == 0))  // if not provided by caller, then evaluate using bbox
  {
    _near=0.1;
    _far=20000;

    GlShot< vcg::Shot<float> >::GetNearFarPlanes(view, mesh->cm.bbox, _near, _far);
    if(_near <= 0) _near = 0.01;
    if(_far < _near) _far = 1000;
  }
  else
  {
    _near = camNear;
    _far  = camFar;
  }

  assert(_near <= _far);

  GLenum err = glGetError();

  //render to FBO
  fbo.bind();

  glViewport(0, 0, wt, ht);
  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  GlShot< vcg::Shot<float> >::SetView(view, _near, _far);

	err = glGetError();

  bool use_colors=false;
  bool use_normals=false;

  if(rendmode == NORMAL)
    use_normals = true;

  if(rendmode == COLOR)
    use_colors = true;

  int program = programs[rendmode]; 

  glDisable(GL_LIGHTING);
  //bind indices
  glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, ibo);

  //bind vertices
  glEnable(GL_COLOR_MATERIAL);
  glBindBufferARB(GL_ARRAY_BUFFER_ARB, vbo);
  glEnableClientState(GL_VERTEX_ARRAY);                 // activate vertex coords array
  glVertexPointer(3, GL_FLOAT, 0, 0);                   // last param is offset, not ptr

  err = glGetError();

  glUseProgram(program);

  err = glGetError();

  if(use_colors) 
  {
    glBindBufferARB(GL_ARRAY_BUFFER_ARB, cbo);
    glEnableClientState(GL_COLOR_ARRAY);
    glColorPointer(4, GL_UNSIGNED_BYTE, 0, 0);
  }
  if(use_normals) 
  {
    glBindBufferARB(GL_ARRAY_BUFFER_ARB, nbo);
    glEnableClientState(GL_NORMAL_ARRAY);
    glNormalPointer(GL_FLOAT, 0, 0);
  }

  err = glGetError();


  if (mesh->cm.fn > 0)
  {
    glDrawElements(GL_TRIANGLES, mesh->cm.fn*3, GL_UNSIGNED_INT, (void *)0); 
  }
  else 
  {
    glDrawArrays(GL_POINTS, 0, mesh->cm.vn);
  }

  if(color != NULL)  delete []color;
  if(depth != NULL)  delete []depth;

  color  = new unsigned char[wt * ht * 3];
  depth  = new floatbuffer();
  depth->init(wt,ht);

  glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
  glPixelStorei(GL_PACK_ALIGNMENT, 1);

  glReadPixels( 0, 0, wt, ht, GL_RGB, GL_UNSIGNED_BYTE, color);
  glReadPixels( 0, 0, wt, ht, GL_DEPTH_COMPONENT, GL_FLOAT, depth->data);


  //----- convert depth in world units
  mindepth =  1000000;
  maxdepth = -1000000;
	for(int pixit = 0; pixit<wt*ht; pixit++)
	{
	 if (depth->data[pixit] == 1.0)
		depth->data[pixit] = 0;
	 else
		depth->data[pixit] = _near*_far / (_far - depth->data[pixit]*(_far-_near));

   // min and max for normalization purposes (e.g. weighting)
   if(depth->data[pixit] > maxdepth)
     maxdepth = depth->data[pixit];
   if(depth->data[pixit] > maxdepth)
     maxdepth = depth->data[pixit];
	}

  //-----

  err = glGetError();

  glDisableClientState(GL_VERTEX_ARRAY);                // deactivate vertex array
  if(use_colors) glDisableClientState(GL_COLOR_ARRAY);
  if(use_normals) glDisableClientState(GL_NORMAL_ARRAY);

  err = glGetError();

  // bind with 0, so, switch back to normal pointer operation
  glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0);
  glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0);

  glEnable(GL_LIGHTING);

  // standard opengl pipeline is re-activated
  glUseProgram(0);

  GlShot< vcg::Shot<float> >::UnsetView();

  glFinish();
  
  //QImage l=fbo.toImage();
  //l.save("rendering.jpg");

  fbo.release();
}