void Renderer::render() { if (context == 0) initialize(); if (newSize != size || reset) { frame = 0; reset = false; size = newSize; context->makeCurrent(this); glViewport(0, 0, size.width(), size.height()); QOpenGLFramebufferObjectFormat fboFormat; fboFormat.setInternalTextureFormat(GL_RGB32F); delete backBuffer; backBuffer = new QOpenGLFramebufferObject(size, fboFormat); delete frameBuffer; frameBuffer = new QOpenGLFramebufferObject(size, fboFormat); context->doneCurrent(); } if (backBuffer == 0 || frameBuffer == 0 || shader == 0) return; context->makeCurrent(this); if (!shader->isCompiled()) shader->compile(); GLfloat elapsed = (GLfloat)time.elapsed() / 1000.f; draw(shader->getMainProgram(), backBuffer, elapsed); if (shader->usePostProcessing()) draw(shader->getPostProgram(), frameBuffer, elapsed); emit updatePixmap((shader->usePostProcessing() ? frameBuffer : backBuffer)->toImage()); frame++; context->doneCurrent(); }
void QQuickContext2DFBOTile::setRect(const QRect& r) { if (m_rect == r) return; m_rect = r; m_dirty = true; if (!m_fbo || m_fbo->size() != r.size()) { QOpenGLFramebufferObjectFormat format; format.setAttachment(QOpenGLFramebufferObject::CombinedDepthStencil); format.setInternalTextureFormat(GL_RGBA); format.setMipmap(false); if (m_painter.isActive()) m_painter.end(); delete m_fbo; m_fbo = new QOpenGLFramebufferObject(r.size(), format); } }
static PyObject *meth_QOpenGLFramebufferObjectFormat_setInternalTextureFormat(PyObject *sipSelf, PyObject *sipArgs) { PyObject *sipParseErr = NULL; { GLenum a0; QOpenGLFramebufferObjectFormat *sipCpp; if (sipParseArgs(&sipParseErr, sipArgs, "Bu", &sipSelf, sipType_QOpenGLFramebufferObjectFormat, &sipCpp, &a0)) { sipCpp->setInternalTextureFormat(a0); Py_INCREF(Py_None); return Py_None; } } /* Raise an exception if the arguments couldn't be parsed. */ sipNoMethod(sipParseErr, sipName_QOpenGLFramebufferObjectFormat, sipName_setInternalTextureFormat, doc_QOpenGLFramebufferObjectFormat_setInternalTextureFormat); return NULL; }
int indexAt( /*GLuint *buffer,*/ NifModel * model, Scene * scene, QList<DrawFunc> drawFunc, int cycle, const QPoint & pos, int & furn ) { Q_UNUSED( model ); Q_UNUSED( cycle ); // Color Key O(1) selection // Open GL 3.0 says glRenderMode is deprecated // ATI OpenGL API implementation of GL_SELECT corrupts NifSkope memory // // Create FBO for sharp edges and no shading. // Texturing, blending, dithering, lighting and smooth shading should be disabled. // The FBO can be used for the drawing operations to keep the drawing operations invisible to the user. GLint viewport[4]; glGetIntegerv( GL_VIEWPORT, viewport ); // Create new FBO with multisampling disabled QOpenGLFramebufferObjectFormat fboFmt; fboFmt.setTextureTarget( GL_TEXTURE_2D ); fboFmt.setInternalTextureFormat( GL_RGB32F_ARB ); fboFmt.setAttachment( QOpenGLFramebufferObject::Attachment::CombinedDepthStencil ); QOpenGLFramebufferObject fbo( viewport[2], viewport[3], fboFmt ); fbo.bind(); glEnable( GL_LIGHTING ); glDisable( GL_MULTISAMPLE ); glDisable( GL_MULTISAMPLE_ARB ); glDisable( GL_LINE_SMOOTH ); glDisable( GL_POINT_SMOOTH ); glDisable( GL_POLYGON_SMOOTH ); glDisable( GL_TEXTURE_1D ); glDisable( GL_TEXTURE_2D ); glDisable( GL_TEXTURE_3D ); glDisable( GL_BLEND ); glDisable( GL_DITHER ); glDisable( GL_FOG ); glDisable( GL_LIGHTING ); glShadeModel( GL_FLAT ); glEnable( GL_DEPTH_TEST ); glDepthFunc( GL_LEQUAL ); glClearColor( 0, 0, 0, 1 ); glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ); // Rasterize the scene Node::SELECTING = 1; for ( DrawFunc df : drawFunc ) { (scene->*df)(); } Node::SELECTING = 0; fbo.release(); QImage img( fbo.toImage() ); QColor pixel = img.pixel( pos ); #ifndef QT_NO_DEBUG img.save( "fbo.png" ); #endif // Encode RGB to Int int a = 0; a |= pixel.red() << 0; a |= pixel.green() << 8; a |= pixel.blue() << 16; // Decode: // R = (id & 0x000000FF) >> 0 // G = (id & 0x0000FF00) >> 8 // B = (id & 0x00FF0000) >> 16 int choose = COLORKEY2ID( a ); // Pick BSFurnitureMarker if ( choose > 0 ) { auto furnBlock = model->getBlock( model->index( 3, 0, model->getBlock( choose & 0x0ffff ) ), "BSFurnitureMarker" ); if ( furnBlock.isValid() ) { furn = choose >> 16; choose &= 0x0ffff; }
void GLWidget::paintGL() { QOpenGLFunctions* f = openglContext()->functions(); int width = this->width() * devicePixelRatio(); int height = this->height() * devicePixelRatio(); glDisable(GL_BLEND); glDisable(GL_DEPTH_TEST); glDepthMask(GL_FALSE); glViewport(0, 0, width, height); check_error(f); QColor color(KdenliveSettings::window_background()); //= QPalette().color(QPalette::Window); glClearColor(color.redF(), color.greenF(), color.blueF(), color.alphaF()); glClear(GL_COLOR_BUFFER_BIT); check_error(f); if (!m_texture[0]) return; // Bind textures. for (int i = 0; i < 3; ++i) { if (m_texture[i]) { glActiveTexture(GL_TEXTURE0 + i); glBindTexture(GL_TEXTURE_2D, m_texture[i]); check_error(f); } } // Init shader program. m_shader->bind(); if (m_glslManager) { m_shader->setUniformValue(m_textureLocation[0], 0); } else { m_shader->setUniformValue(m_textureLocation[0], 0); m_shader->setUniformValue(m_textureLocation[1], 1); m_shader->setUniformValue(m_textureLocation[2], 2); m_shader->setUniformValue(m_colorspaceLocation, m_monitorProfile->colorspace()); } check_error(f); // Setup an orthographic projection. QMatrix4x4 projection; projection.scale(2.0f / width, 2.0f / height); m_shader->setUniformValue(m_projectionLocation, projection); check_error(f); // Set model view. QMatrix4x4 modelView; if (m_zoom != 1.0) { if (offset().x() || offset().y()) modelView.translate(-offset().x() * devicePixelRatio(), offset().y() * devicePixelRatio()); modelView.scale(zoom(), zoom()); } m_shader->setUniformValue(m_modelViewLocation, modelView); check_error(f); // Provide vertices of triangle strip. QVector<QVector2D> vertices; width = m_rect.width() * devicePixelRatio(); height = m_rect.height() * devicePixelRatio(); vertices << QVector2D(float(-width)/2.0f, float(-height)/2.0f); vertices << QVector2D(float(-width)/2.0f, float( height)/2.0f); vertices << QVector2D(float( width)/2.0f, float(-height)/2.0f); vertices << QVector2D(float( width)/2.0f, float( height)/2.0f); m_shader->enableAttributeArray(m_vertexLocation); check_error(f); m_shader->setAttributeArray(m_vertexLocation, vertices.constData()); check_error(f); // Provide texture coordinates. QVector<QVector2D> texCoord; texCoord << QVector2D(0.0f, 1.0f); texCoord << QVector2D(0.0f, 0.0f); texCoord << QVector2D(1.0f, 1.0f); texCoord << QVector2D(1.0f, 0.0f); m_shader->enableAttributeArray(m_texCoordLocation); check_error(f); m_shader->setAttributeArray(m_texCoordLocation, texCoord.constData()); check_error(f); // Render glDrawArrays(GL_TRIANGLE_STRIP, 0, vertices.size()); check_error(f); // Render RGB frame for analysis if (sendFrameForAnalysis) { if (!m_fbo || m_fbo->size() != QSize(width, height)) { delete m_fbo; QOpenGLFramebufferObjectFormat f; f.setSamples(0); f.setInternalTextureFormat(GL_RGB); //GL_RGBA32F); // which one is the fastest ? m_fbo = new QOpenGLFramebufferObject(width, height, f); //GL_TEXTURE_2D); } m_fbo->bind(); glViewport(0, 0, width, height); projection.scale((double) this->width() / width, (double) this->height() / height); m_shader->setUniformValue(m_projectionLocation, projection); glDrawArrays(GL_TRIANGLE_STRIP, 0, vertices.size()); check_error(f); m_fbo->release(); emit analyseFrame(m_fbo->toImage()); } // Cleanup m_shader->disableAttributeArray(m_vertexLocation); m_shader->disableAttributeArray(m_texCoordLocation); m_shader->release(); for (int i = 0; i < 3; ++i) { if (m_texture[i]) { glActiveTexture(GL_TEXTURE0 + i); glBindTexture(GL_TEXTURE_2D, 0); check_error(f); } } glActiveTexture(GL_TEXTURE0); check_error(f); }
void SSGQuickLayer::grab() { if (!m_item || m_size.isNull()) { delete m_fbo; delete m_secondaryFbo; m_fbo = m_secondaryFbo = 0; m_depthStencilBuffer.clear(); m_dirtyTexture = false; return; } QSGNode *root = m_item; while (root->firstChild() && root->type() != QSGNode::RootNodeType) root = root->firstChild(); if (root->type() != QSGNode::RootNodeType) return; if (!m_renderer) { m_renderer = m_context->createRenderer(); connect(m_renderer, SIGNAL(sceneGraphChanged()), this, SLOT(markDirtyTexture())); } m_renderer->setDevicePixelRatio(m_device_pixel_ratio); m_renderer->setRootNode(static_cast<QSGRootNode *>(root)); QOpenGLFunctions *funcs = QOpenGLContext::currentContext()->functions(); bool deleteFboLater = false; if (!m_fbo || m_fbo->size() != m_size || m_fbo->format().internalTextureFormat() != m_format || (!m_fbo->format().mipmap() && m_mipmap)) { if (!m_multisamplingChecked) { if (m_context->openglContext()->format().samples() <= 1) { m_multisampling = false; } else { const QSet<QByteArray> extensions = m_context->openglContext()->extensions(); m_multisampling = extensions.contains(QByteArrayLiteral("GL_EXT_framebuffer_multisample")) && extensions.contains(QByteArrayLiteral("GL_EXT_framebuffer_blit")); } m_multisamplingChecked = true; } if (m_multisampling) { // Don't delete the FBO right away in case it is used recursively. deleteFboLater = true; delete m_secondaryFbo; QOpenGLFramebufferObjectFormat format; format.setInternalTextureFormat(m_format); format.setSamples(m_context->openglContext()->format().samples()); m_secondaryFbo = new QOpenGLFramebufferObject(m_size, format); m_depthStencilBuffer = m_context->depthStencilBufferForFbo(m_secondaryFbo); } else { QOpenGLFramebufferObjectFormat format; format.setInternalTextureFormat(m_format); format.setMipmap(m_mipmap); if (m_recursive) { deleteFboLater = true; delete m_secondaryFbo; m_secondaryFbo = new QOpenGLFramebufferObject(m_size, format); funcs->glBindTexture(GL_TEXTURE_2D, m_secondaryFbo->texture()); updateBindOptions(true); m_depthStencilBuffer = m_context->depthStencilBufferForFbo(m_secondaryFbo); } else { delete m_fbo; delete m_secondaryFbo; m_fbo = new QOpenGLFramebufferObject(m_size, format); m_secondaryFbo = 0; funcs->glBindTexture(GL_TEXTURE_2D, m_fbo->texture()); updateBindOptions(true); m_depthStencilBuffer = m_context->depthStencilBufferForFbo(m_fbo); } } } if (m_recursive && !m_secondaryFbo) { // m_fbo already created, m_recursive was just set. Q_ASSERT(m_fbo); Q_ASSERT(!m_multisampling); m_secondaryFbo = new QOpenGLFramebufferObject(m_size, m_fbo->format()); funcs->glBindTexture(GL_TEXTURE_2D, m_secondaryFbo->texture()); updateBindOptions(true); } // Render texture. root->markDirty(QSGNode::DirtyForceUpdate); // Force matrix, clip and opacity update. m_renderer->nodeChanged(root, QSGNode::DirtyForceUpdate); // Force render list update. #ifdef QSG_DEBUG_FBO_OVERLAY if (qmlFboOverlay()) { if (!m_debugOverlay) m_debugOverlay = new QSGSimpleRectNode(); m_debugOverlay->setRect(QRectF(0, 0, m_size.width(), m_size.height())); m_debugOverlay->setColor(QColor(0xff, 0x00, 0x80, 0x40)); root->appendChildNode(m_debugOverlay); } #endif m_dirtyTexture = false; m_renderer->setDeviceRect(m_size); m_renderer->setViewportRect(m_size); QRectF mirrored(m_mirrorHorizontal ? m_rect.right() : m_rect.left(), m_mirrorVertical ? m_rect.bottom() : m_rect.top(), m_mirrorHorizontal ? -m_rect.width() : m_rect.width(), m_mirrorVertical ? -m_rect.height() : m_rect.height()); m_renderer->setProjectionMatrixToRect(mirrored); m_renderer->setClearColor(Qt::transparent); if (m_multisampling) { m_renderer->renderScene(BindableFbo(m_secondaryFbo, m_depthStencilBuffer.data())); if (deleteFboLater) { delete m_fbo; QOpenGLFramebufferObjectFormat format; format.setInternalTextureFormat(m_format); format.setAttachment(QOpenGLFramebufferObject::NoAttachment); format.setMipmap(m_mipmap); format.setSamples(0); m_fbo = new QOpenGLFramebufferObject(m_size, format); funcs->glBindTexture(GL_TEXTURE_2D, m_fbo->texture()); updateBindOptions(true); } QRect r(QPoint(), m_size); QOpenGLFramebufferObject::blitFramebuffer(m_fbo, r, m_secondaryFbo, r); } else { if (m_recursive) { m_renderer->renderScene(BindableFbo(m_secondaryFbo, m_depthStencilBuffer.data())); if (deleteFboLater) { delete m_fbo; QOpenGLFramebufferObjectFormat format; format.setAttachment(QOpenGLFramebufferObject::CombinedDepthStencil); format.setInternalTextureFormat(m_format); format.setMipmap(m_mipmap); m_fbo = new QOpenGLFramebufferObject(m_size, format); funcs->glBindTexture(GL_TEXTURE_2D, m_fbo->texture()); updateBindOptions(true); } qSwap(m_fbo, m_secondaryFbo); } else { m_renderer->renderScene(BindableFbo(m_fbo, m_depthStencilBuffer.data())); } } if (m_mipmap) { funcs->glBindTexture(GL_TEXTURE_2D, textureId()); funcs->glGenerateMipmap(GL_TEXTURE_2D); } root->markDirty(QSGNode::DirtyForceUpdate); // Force matrix, clip, opacity and render list update. #ifdef QSG_DEBUG_FBO_OVERLAY if (qmlFboOverlay()) root->removeChildNode(m_debugOverlay); #endif if (m_recursive) markDirtyTexture(); // Continuously update if 'live' and 'recursive'. }