QOpenGLFramebufferObject::QOpenGLFramebufferObject(const QSize &size, const QOpenGLFramebufferObjectFormat &format) : d_ptr(new QOpenGLFramebufferObjectPrivate) { Q_D(QOpenGLFramebufferObject); d->init(this, size, format.attachment(), format.textureTarget(), format.internalTextureFormat(), format.samples(), format.mipmap()); }
QOpenGLFramebufferObject *createFramebufferObject(const QSize &size) { QOpenGLFramebufferObjectFormat format; format.setAttachment(QOpenGLFramebufferObject::CombinedDepthStencil); format.setSamples(4); return new QOpenGLFramebufferObject(size, format); }
QOpenGLFramebufferObject::QOpenGLFramebufferObject(int width, int height, const QOpenGLFramebufferObjectFormat &format) : d_ptr(new QOpenGLFramebufferObjectPrivate) { Q_D(QOpenGLFramebufferObject); d->init(this, QSize(width, height), format.attachment(), format.textureTarget(), format.internalTextureFormat(), format.samples(), format.mipmap()); }
void tst_QOpenGL::fboSimpleRendering() { QFETCH(int, surfaceClass); QScopedPointer<QSurface> surface(createSurface(surfaceClass)); QOpenGLContext ctx; ctx.create(); ctx.makeCurrent(surface.data()); if (!QOpenGLFramebufferObject::hasOpenGLFramebufferObjects()) QSKIP("QOpenGLFramebufferObject not supported on this platform"); // No multisample with combined depth/stencil attachment: QOpenGLFramebufferObjectFormat fboFormat; fboFormat.setAttachment(QOpenGLFramebufferObject::NoAttachment); QOpenGLFramebufferObject *fbo = new QOpenGLFramebufferObject(200, 100, fboFormat); fbo->bind(); glClearColor(1.0, 0.0, 0.0, 1.0); glClear(GL_COLOR_BUFFER_BIT); glFinish(); QImage fb = fbo->toImage().convertToFormat(QImage::Format_RGB32); QImage reference(fb.size(), QImage::Format_RGB32); reference.fill(0xffff0000); QFUZZY_COMPARE_IMAGES(fb, reference); delete fbo; }
void RenderSurface::render(QPainter *painter) { Q_UNUSED(painter); QOpenGLFramebufferObjectFormat fboFormat; fboFormat.setSamples(1); fboFormat.setAttachment(QOpenGLFramebufferObject::CombinedDepthStencil); const QRect drawRect(0, 0, m_outWidth, m_outHeight); const QSize drawRectSize = drawRect.size(); QOpenGLFramebufferObject fbo(drawRectSize, fboFormat); fbo.bind(); glViewport(0, 0, m_outWidth, m_outHeight); glClear(GL_COLOR_BUFFER_BIT); glClearColor(0.0f, 0.0f, 0.0f, 1.0f); glEnable(GL_BLEND); glBlendFuncSeparate(GL_ONE, GL_ZERO, GL_ZERO, GL_ONE); m_program->bind(); int texCount = 0; for (size_t i = 0; i < sp.size(); ++i) { if (sp[i].bind == ShaderParameter::BindTextureSampler) { textures[sp[i].name].obj->bind(texCount); m_program->setUniformValue(sp[i].name.c_str(), texCount); texCount++; } else if (sp[i].bind == ShaderParameter::BindTextureResolution) { const QImage& image = textures[sp[i].texture].image; m_program->setUniformValue(sp[i].name.c_str(), QVector2D(image.width(),image.height())); } else if (sp[i].bind == ShaderParameter::BindGlobalTime) { m_program->setUniformValue(sp[i].name.c_str(), m_globalTime); } else if (sp[i].bind == ShaderParameter::BindOutputResolution) { m_program->setUniformValue(sp[i].name.c_str(), QVector2D(m_outWidth,m_outHeight)); } } GLfloat vertices[] = { -1.0f, -1.0f, 0.0f, 1.0f, -1.0f, 0.0f, -1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.0f }; glVertexAttribPointer(m_posAttr, 3, GL_FLOAT, GL_FALSE, 0, vertices); glEnableVertexAttribArray(0); glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); glDisableVertexAttribArray(0); m_program->release(); imageFrame = fbo.toImage(); }
void TApplication::initializeGL() { // Init shaders if (!Shader.addShaderFromSourceFile(QGLShader::Vertex, "vert.glsl")) { qFatal("failed to load shader vert.glsl"); } if (!Shader.addShaderFromSourceFile(QGLShader::Fragment, "frag.glsl")) { qFatal("failed to load shader frag.glsl"); } if (!Shader.link()) { qFatal("failed to link shader planet"); } if (!Shader.bind()) { qFatal("failed to bind shader"); } // Init framebuffers QOpenGLFramebufferObjectFormat format; format.setAttachment(QOpenGLFramebufferObject::CombinedDepthStencil); format.setSamples(8); Fbo.reset(new QOpenGLFramebufferObject(WINDOW_WIDTH, WINDOW_HEIGHT, format)); QOpenGLFramebufferObjectFormat format1; format.setAttachment(QOpenGLFramebufferObject::CombinedDepthStencil); Fbo1.reset(new QOpenGLFramebufferObject(WINDOW_WIDTH, WINDOW_HEIGHT, format1)); // Load model and textures Obj = LoadJsonModel("model.json"); ObjectSize = Obj.size(); VertexBuff.reset(new QOpenGLBuffer(QOpenGLBuffer::VertexBuffer)); VertexBuff->create(); VertexBuff->bind(); VertexBuff->setUsagePattern(QOpenGLBuffer::StaticDraw); VertexBuff->allocate(Obj.data(), Obj.size() * sizeof(TVertex)); VertexBuff->release(); Texture.reset(new QOpenGLTexture(QImage("diffuse.jpg"))); Texture->bind(); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR_MIPMAP_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); Texture->release(); NormalMap.reset(new QOpenGLTexture(QImage("normal.jpg"))); NormalMap->bind(); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR_MIPMAP_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); NormalMap->release(); // Initial angles AngleX = 0; AngleY = 0; AngleZ = 0; Paused = false; }
QOpenGLFramebufferObject* QQuickMapboxGLRenderer::createFramebufferObject(const QSize &size) { m_map->resize(size); QOpenGLFramebufferObjectFormat format; format.setAttachment(QOpenGLFramebufferObject::CombinedDepthStencil); return new QOpenGLFramebufferObject(size, format); }
QOpenGLFramebufferObject* COglRenderer::createFramebufferObject(const QSize &size) { // create opengl FBO QOpenGLFramebufferObjectFormat format; format.setAttachment(QOpenGLFramebufferObject::CombinedDepthStencil); format.setSamples(4); m_oglFBO = new QOpenGLFramebufferObject(size, format); // return opengl FBO return m_oglFBO; }
void CombinedTexture::create() { if (m_framebuffer) delete m_framebuffer; QOpenGLFramebufferObjectFormat format; format.setMipmap(true); m_framebuffer = new QOpenGLFramebufferObject(m_width, m_height, format); m_framebuffer->bind(); glViewport(0, 0, m_width, m_height); glClearColor(0.0f, 0.0f, 0.0f, 1.0f); glClear(GL_COLOR_BUFFER_BIT); glEnable(GL_TEXTURE_2D); glEnable(GL_ALPHA_TEST); for (int i = 0; i < m_textures.size(); i++) { Texture *texture = m_textures.at(i).first; float *position = m_textures.at(i).second; texture->bind(); glBegin(GL_QUADS); glTexCoord2f(0.0f, 0.0f); glVertex3f(position[0], position[1], 0.0f); glTexCoord2f(1.0f, 0.0f); glVertex3f(position[2], position[1], 0.0f); glTexCoord2f(1.0f, 1.0f); glVertex3f(position[2], position[3], 0.0f); glTexCoord2f(0.0f, 1.0f); glVertex3f(position[0], position[3], 0.0f); glEnd(); } m_framebuffer->release(); glBindTexture(GL_TEXTURE_2D, m_framebuffer->texture()); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); QOpenGLFunctions gl(QOpenGLContext::currentContext()); gl.initializeOpenGLFunctions(); gl.glGenerateMipmap(GL_TEXTURE_2D); m_created = true; }
std::unique_ptr<QOpenGLFramebufferObject> _createMultisampledFBO( const QSize& size ) { QOpenGLFramebufferObjectFormat format; format.setAttachment( QOpenGLFramebufferObject::CombinedDepthStencil ); format.setSamples( MULTI_SAMPLE_ANTI_ALIASING_SAMPLES ); auto fbo = make_unique<QOpenGLFramebufferObject>( size, format ); fbo->bind(); auto gl = QOpenGLContext::currentContext()->functions(); gl->glClearColor( 0.0f, 0.0f, 0.0f, 0.0f ); gl->glClear( GL_COLOR_BUFFER_BIT ); fbo->release(); return fbo; }
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(); }
// NOTE: This tests that CombinedDepthStencil attachment works by assuming the // GL2 engine is being used and is implemented the same way as it was when // this autotest was written. If this is not the case, there may be some // false-positives: I.e. The test passes when either the depth or stencil // buffer is actually missing. But that's probably ok anyway. void tst_QOpenGL::fboRendering() { #if defined(Q_OS_LINUX) && defined(Q_CC_GNU) && !defined(__x86_64__) QSKIP("QTBUG-22617"); #endif QFETCH(int, surfaceClass); QScopedPointer<QSurface> surface(createSurface(surfaceClass)); QOpenGLContext ctx; QVERIFY(ctx.create()); QVERIFY(ctx.makeCurrent(surface.data())); if (!QOpenGLFramebufferObject::hasOpenGLFramebufferObjects()) QSKIP("QOpenGLFramebufferObject not supported on this platform"); // No multisample with combined depth/stencil attachment: QOpenGLFramebufferObjectFormat fboFormat; fboFormat.setAttachment(QOpenGLFramebufferObject::CombinedDepthStencil); // Uncomplicate things by using NPOT: const QSize size(256, 128); QOpenGLFramebufferObject fbo(size, fboFormat); if (fbo.attachment() != QOpenGLFramebufferObject::CombinedDepthStencil) QSKIP("FBOs missing combined depth~stencil support"); QVERIFY(fbo.bind()); QPainter fboPainter; QOpenGLPaintDevice device(fbo.width(), fbo.height()); bool painterBegun = fboPainter.begin(&device); QVERIFY(painterBegun); qt_opengl_draw_test_pattern(&fboPainter, fbo.width(), fbo.height()); fboPainter.end(); const QImage fb = fbo.toImage().convertToFormat(QImage::Format_RGB32); QCOMPARE(fb.size(), size); qt_opengl_check_test_pattern(fb); }
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); } }
bool QGLPixelBuffer::makeCurrent() { Q_D(QGLPixelBuffer); if (d->invalid) return false; d->qctx->makeCurrent(); if (!d->fbo) { QOpenGLFramebufferObjectFormat format; if (d->req_format.stencil()) format.setAttachment(QOpenGLFramebufferObject::CombinedDepthStencil); else if (d->req_format.depth()) format.setAttachment(QOpenGLFramebufferObject::Depth); if (d->req_format.sampleBuffers()) format.setSamples(d->req_format.samples()); d->fbo = new QOpenGLFramebufferObject(d->req_size, format); d->fbo->bind(); } return true; }
void tst_QOpenGL::fboTextureOwnership() { QFETCH(int, surfaceClass); QScopedPointer<QSurface> surface(createSurface(surfaceClass)); QOpenGLContext ctx; QVERIFY(ctx.create()); ctx.makeCurrent(surface.data()); if (!QOpenGLFramebufferObject::hasOpenGLFramebufferObjects()) QSKIP("QOpenGLFramebufferObject not supported on this platform"); QOpenGLFramebufferObjectFormat fboFormat; fboFormat.setAttachment(QOpenGLFramebufferObject::NoAttachment); QOpenGLFramebufferObject *fbo = new QOpenGLFramebufferObject(200, 100, fboFormat); QVERIFY(fbo->texture() != 0); fbo->bind(); // pull out the texture GLuint texture = fbo->takeTexture(); QVERIFY(texture != 0); QVERIFY(fbo->texture() == 0); // verify that the next bind() creates a new texture fbo->bind(); QVERIFY(fbo->texture() != 0 && fbo->texture() != texture); glClearColor(1.0, 0.0, 0.0, 1.0); glClear(GL_COLOR_BUFFER_BIT); glFinish(); QImage fb = fbo->toImage().convertToFormat(QImage::Format_RGB32); QImage reference(fb.size(), QImage::Format_RGB32); reference.fill(0xffff0000); QFUZZY_COMPARE_IMAGES(fb, reference); glDeleteTextures(1, &texture); delete fbo; }
bool QGLPixelBuffer::makeCurrent() { Q_D(QGLPixelBuffer); if (d->invalid) return false; d->qctx->makeCurrent(); if (!d->fbo) { QOpenGLFramebufferObjectFormat format; if (d->req_format.stencil()) format.setAttachment(QOpenGLFramebufferObject::CombinedDepthStencil); else if (d->req_format.depth()) format.setAttachment(QOpenGLFramebufferObject::Depth); if (d->req_format.sampleBuffers()) format.setSamples(d->req_format.samples()); d->fbo = new QOpenGLFramebufferObject(d->req_size, format); d->fbo->bind(); d->glDevice.setFbo(d->fbo->handle()); QOpenGLContext::currentContext()->functions()->glViewport(0, 0, d->req_size.width(), d->req_size.height()); } return true; }
static PyObject *meth_QOpenGLFramebufferObjectFormat_setMipmap(PyObject *sipSelf, PyObject *sipArgs) { PyObject *sipParseErr = NULL; { bool a0; QOpenGLFramebufferObjectFormat *sipCpp; if (sipParseArgs(&sipParseErr, sipArgs, "Bb", &sipSelf, sipType_QOpenGLFramebufferObjectFormat, &sipCpp, &a0)) { sipCpp->setMipmap(a0); Py_INCREF(Py_None); return Py_None; } } /* Raise an exception if the arguments couldn't be parsed. */ sipNoMethod(sipParseErr, sipName_QOpenGLFramebufferObjectFormat, sipName_setMipmap, doc_QOpenGLFramebufferObjectFormat_setMipmap); return NULL; }
void GLImageProcessor::initialize() { initializeOpenGLFunctions(); texture.reset(new QOpenGLTexture(image.mirrored())); texture->setWrapMode(QOpenGLTexture::WrapMode::ClampToEdge); texture->setMinificationFilter(QOpenGLTexture::LinearMipMapLinear); texture->setMagnificationFilter(QOpenGLTexture::Linear); program.reset(buildProgram()); program->release(); plotProgram.reset(buildPassthorughProgram()); plotProgram->release(); vao.create(); vao.bind(); vbo.reset(buildQuadTextured()); vao.release(); QOpenGLFramebufferObjectFormat format; format.setAttachment(QOpenGLFramebufferObject::CombinedDepthStencil); renderFbo.reset(new QOpenGLFramebufferObject(image.size(), format)); }
void QSGPainterNode::updateRenderTarget() { if (!m_extensionsChecked) { const QSet<QByteArray> extensions = m_context->openglContext()->extensions(); m_multisamplingSupported = extensions.contains(QByteArrayLiteral("GL_EXT_framebuffer_multisample")) && extensions.contains(QByteArrayLiteral("GL_EXT_framebuffer_blit")); m_extensionsChecked = true; } m_dirtyContents = true; QQuickPaintedItem::RenderTarget oldTarget = m_actualRenderTarget; if (m_preferredRenderTarget == QQuickPaintedItem::Image) { m_actualRenderTarget = QQuickPaintedItem::Image; } else { if (!m_multisamplingSupported && m_smoothPainting) m_actualRenderTarget = QQuickPaintedItem::Image; else m_actualRenderTarget = m_preferredRenderTarget; } if (oldTarget != m_actualRenderTarget) { m_image = QImage(); delete m_fbo; delete m_multisampledFbo; delete m_gl_device; m_fbo = m_multisampledFbo = 0; m_gl_device = 0; } if (m_actualRenderTarget == QQuickPaintedItem::FramebufferObject || m_actualRenderTarget == QQuickPaintedItem::InvertedYFramebufferObject) { const QOpenGLContext *ctx = m_context->openglContext(); if (m_fbo && !m_dirtyGeometry && (!ctx->format().samples() || !m_multisamplingSupported)) return; if (m_fboSize.isEmpty()) updateFBOSize(); delete m_fbo; delete m_multisampledFbo; m_fbo = m_multisampledFbo = 0; if (m_gl_device) m_gl_device->setSize(m_fboSize); if (m_smoothPainting && ctx->format().samples() && m_multisamplingSupported) { { QOpenGLFramebufferObjectFormat format; format.setAttachment(QOpenGLFramebufferObject::CombinedDepthStencil); format.setSamples(8); m_multisampledFbo = new QOpenGLFramebufferObject(m_fboSize, format); } { QOpenGLFramebufferObjectFormat format; format.setAttachment(QOpenGLFramebufferObject::NoAttachment); m_fbo = new QOpenGLFramebufferObject(m_fboSize, format); } } else { QOpenGLFramebufferObjectFormat format; format.setAttachment(QOpenGLFramebufferObject::CombinedDepthStencil); m_fbo = new QOpenGLFramebufferObject(m_fboSize, format); } } else { if (!m_image.isNull() && !m_dirtyGeometry) return; m_image = QImage(m_size, QImage::Format_ARGB32_Premultiplied); m_image.fill(Qt::transparent); } QSGPainterTexture *texture = new QSGPainterTexture; if (m_actualRenderTarget == QQuickPaintedItem::Image) { texture->setOwnsTexture(true); texture->setTextureSize(m_size); } else { texture->setTextureId(m_fbo->texture()); texture->setOwnsTexture(false); texture->setTextureSize(m_fboSize); } if (m_texture) delete m_texture; texture->setTextureSize(m_size); m_texture = texture; }
void ExploreLiveView::paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidget * widget) { if(!isReady) return; prePaint(painter); postPaint(painter); auto glwidget = (Viewer*)widget; if (glwidget && meshes.size()) { QRectF parentRect = parentItem()->sceneBoundingRect(); if (isCacheImage && cachedImage.isNull()) { QOpenGLContext context; context.setShareContext(glwidget->context()); context.setFormat(glwidget->format()); context.create(); QOffscreenSurface m_offscreenSurface; m_offscreenSurface.setFormat(context.format()); m_offscreenSurface.create(); context.makeCurrent(&m_offscreenSurface); QOpenGLFramebufferObjectFormat fboformat; fboformat.setAttachment(QOpenGLFramebufferObject::CombinedDepthStencil); QOpenGLFramebufferObject renderFbo(cacheImageSize*1.5, cacheImageSize, fboformat); renderFbo.bind(); glwidget->glEnable(GL_DEPTH_TEST); glwidget->glEnable(GL_BLEND); glwidget->glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glwidget->glCullFace(GL_BACK); glwidget->glClearColor(0,0,0,0); glwidget->glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glwidget->glViewport(0, 0, cacheImageSize*1.5, cacheImageSize); // XXX Fix // glwidget->glPointSize(10); // Draw aux meshes for (auto mesh : meshes) { if (mesh.isPoints) glwidget->drawOrientedPoints(mesh.points, mesh.normals, mesh.color, glwidget->pvm); else glwidget->drawTriangles(mesh.color, mesh.points, mesh.normals, glwidget->pvm); } glwidget->glDisable(GL_DEPTH_TEST); glwidget->glFlush(); renderFbo.release(); cachedImage = renderFbo.toImage(); isReady = true; // Thanks for sharing! glwidget->makeCurrent(); } // Draw as image if(isCacheImage) { int w = shapeRect.width(); painter->drawImage(w * -0.5, w * -0.5, cachedImage.scaledToWidth(w)); } if(!isCacheImage) { auto r = shapeRect; // scale view double s = 1.5; r.setWidth(r.width() * s); r.setHeight(r.height() * s); r.moveCenter(this->mapToScene(boundingRect().center())); painter->beginNativePainting(); auto v = scene()->views().first(); QPoint viewDelta = v->mapFromScene(r.topLeft()); if (viewDelta.manhattanLength() > 5) r.moveTopLeft(viewDelta); auto camera = ExploreProcess::defaultCamera(document->extent().length()); glwidget->eyePos = camera.first; glwidget->pvm = camera.second; glwidget->glViewport(r.left(), v->height() - r.height() - r.top(), r.width(), r.height()); // Clipping OpenGL glwidget->glEnable(GL_SCISSOR_TEST); glwidget->glScissor(parentRect.x(), v->height() - parentRect.height() - parentRect.top(), parentRect.width(), parentRect.height()); glwidget->glClear(GL_DEPTH_BUFFER_BIT); // FIX XXX // glwidget->glPointSize(2); // Draw aux meshes for (auto mesh : meshes) { if (mesh.isPoints) glwidget->drawOrientedPoints(mesh.points, mesh.normals, mesh.color, glwidget->pvm); else glwidget->drawTriangles(mesh.color, mesh.points, mesh.normals, glwidget->pvm); } glwidget->glDisable(GL_SCISSOR_TEST); painter->endNativePainting(); } } }
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; }
QOpenGLFramebufferObject *createFramebufferObject(const QSize &size) override { m_heightMapRenderer.setAspectRatio(size.width(), size.height()); QOpenGLFramebufferObjectFormat format; format.setAttachment(QOpenGLFramebufferObject::Depth); return new QOpenGLFramebufferObject(size, format); }
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); }
int main(int argc, char **argv) { #ifdef CONSOLE_APPLICATION QApplication app(argc, argv, QApplication::Tty); #else QApplication app(argc, argv); #endif #ifdef DO_QWS_DEBUGGING qt_show_painter_debug_output = false; #endif DeviceType type = WidgetType; bool checkers_background = true; QImage::Format imageFormat = QImage::Format_ARGB32_Premultiplied; QLocale::setDefault(QLocale::c()); QStringList files; bool interactive = false; bool printdlg = false; bool highres = false; bool show_cmp = false; int width = 800, height = 800; int scaledWidth = width, scaledHeight = height; qreal scalefactor = 1.0; bool verboseMode = false; #ifndef QT_NO_OPENGL QGLFormat f = QGLFormat::defaultFormat(); f.setSampleBuffers(true); f.setStencil(true); f.setAlpha(true); f.setAlphaBufferSize(8); QGLFormat::setDefaultFormat(f); #endif char *arg; for (int i=1; i<argc; ++i) { arg = argv[i]; if (*arg == '-') { QString option = QString(arg + 1).toLower(); if (option == "widget") type = WidgetType; else if (option == "bitmap") type = BitmapType; else if (option == "pixmap") type = PixmapType; else if (option == "image") type = ImageType; else if (option == "imageformat") { Q_ASSERT_X(i + 1 < argc, "main", "-imageformat must be followed by a value"); QString format = QString(argv[++i]).toLower(); imageFormat = QImage::Format_Invalid; static const int formatCount = sizeof(imageFormats) / sizeof(imageFormats[0]); for (int ff = 0; ff < formatCount; ++ff) { if (QLatin1String(imageFormats[ff].name) == format) { imageFormat = imageFormats[ff].format; break; } } if (imageFormat == QImage::Format_Invalid) { printf("Invalid image format. Available formats are:\n"); for (int ff = 0; ff < formatCount; ++ff) printf("\t%s\n", imageFormats[ff].name); return -1; } } else if (option == "imagemono") type = ImageMonoType; else if (option == "imagewidget") type = ImageWidgetType; #ifndef QT_NO_OPENGL else if (option == "opengl") type = OpenGLType; else if (option == "glbuffer") type = OpenGLBufferType; #endif #ifdef USE_CUSTOM_DEVICE else if (option == "customdevice") type = CustomDeviceType; else if (option == "customwidget") type = CustomWidgetType; #endif else if (option == "pdf") type = PdfType; else if (option == "ps") type = PsType; else if (option == "picture") type = PictureType; else if (option == "printer") type = PrinterType; else if (option == "highres") { type = PrinterType; highres = true; } else if (option == "printdialog") { type = PrinterType; printdlg = true; } else if (option == "grab") type = GrabType; else if (option == "i") interactive = true; else if (option == "v") verboseMode = true; else if (option == "commands") { displayCommands(); return 0; } else if (option == "w") { Q_ASSERT_X(i + 1 < argc, "main", "-w must be followed by a value"); width = atoi(argv[++i]); } else if (option == "h") { Q_ASSERT_X(i + 1 < argc, "main", "-h must be followed by a value"); height = atoi(argv[++i]); } else if (option == "scalefactor") { Q_ASSERT_X(i + 1 < argc, "main", "-scalefactor must be followed by a value"); scalefactor = atof(argv[++i]); } else if (option == "cmp") { show_cmp = true; } else if (option == "bg-white") { checkers_background = false; } } else { #if defined (Q_WS_WIN) QString input = QString::fromLocal8Bit(argv[i]); if (input.indexOf('*') >= 0) { QFileInfo info(input); QDir dir = info.dir(); QFileInfoList infos = dir.entryInfoList(QStringList(info.fileName())); for (int ii=0; ii<infos.size(); ++ii) files.append(infos.at(ii).absoluteFilePath()); } else { files.append(input); } #else files.append(QString(argv[i])); #endif } } scaledWidth = width * scalefactor; scaledHeight = height * scalefactor; PaintCommands pcmd(QStringList(), 800, 800); pcmd.setVerboseMode(verboseMode); pcmd.setType(type); pcmd.setCheckersBackground(checkers_background); QWidget *activeWidget = 0; if (interactive) { runInteractive(); if (!files.isEmpty()) interactive_widget->load(files.at(0)); } else if (files.isEmpty()) { printHelp(); return 0; } else { for (int j=0; j<files.size(); ++j) { const QString &fileName = files.at(j); QStringList content; QFile file(fileName); QFileInfo fileinfo(file); if (file.open(QIODevice::ReadOnly)) { QTextStream textFile(&file); QString script = textFile.readAll(); content = script.split("\n", QString::SkipEmptyParts); } else { printf("failed to read file: '%s'\n", qPrintable(fileinfo.absoluteFilePath())); continue; } pcmd.setContents(content); if (show_cmp) { QString pmFile = QString(files.at(j)).replace(".qps", "_qps") + ".png"; qDebug() << pmFile << QFileInfo(pmFile).exists(); QPixmap pixmap(pmFile); if (!pixmap.isNull()) { QLabel *label = createLabel(); label->setWindowTitle("VERIFY: " + pmFile); label->setPixmap(pixmap); label->show(); } } switch (type) { case WidgetType: { OnScreenWidget<QWidget> *qWidget = new OnScreenWidget<QWidget>(files.at(j)); qWidget->setVerboseMode(verboseMode); qWidget->setType(type); qWidget->setCheckersBackground(checkers_background); qWidget->m_commands = content; qWidget->resize(width, height); qWidget->show(); activeWidget = qWidget; break; } case ImageWidgetType: { OnScreenWidget<QWidget> *qWidget = new OnScreenWidget<QWidget>(files.at(j)); qWidget->setVerboseMode(verboseMode); qWidget->setType(type); qWidget->setCheckersBackground(checkers_background); qWidget->m_commands = content; qWidget->resize(width, height); qWidget->show(); activeWidget = qWidget; break; } #ifndef QT_NO_OPENGL case OpenGLBufferType: { QWindow win; win.setSurfaceType(QSurface::OpenGLSurface); win.create(); QOpenGLFramebufferObjectFormat fmt; fmt.setAttachment(QOpenGLFramebufferObject::CombinedDepthStencil); fmt.setSamples(4); QOpenGLContext ctx; ctx.create(); ctx.makeCurrent(&win); QOpenGLFramebufferObject fbo(width, height, fmt); fbo.bind(); QOpenGLPaintDevice pdev(width, height); QPainter pt(&pdev); pcmd.setPainter(&pt); pcmd.setFilePath(fileinfo.absolutePath()); pcmd.runCommands(); pt.end(); QImage image = fbo.toImage(); QLabel *label = createLabel(); label->setPixmap(QPixmap::fromImage(image)); label->resize(label->sizeHint()); label->show(); activeWidget = label; break; } case OpenGLType: { OnScreenWidget<QGLWidget> *qGLWidget = new OnScreenWidget<QGLWidget>(files.at(j)); qGLWidget->setVerboseMode(verboseMode); qGLWidget->setType(type); qGLWidget->setCheckersBackground(checkers_background); qGLWidget->m_commands = content; qGLWidget->resize(width, height); qGLWidget->show(); activeWidget = qGLWidget; break; } #else case OpenGLType: case OpenGLBufferType: { printf("OpenGL type not supported in this Qt build\n"); break; } #endif #ifdef USE_CUSTOM_DEVICE case CustomDeviceType: { CustomPaintDevice custom(width, height); QPainter pt; pt.begin(&custom); pcmd.setPainter(&pt); pcmd.setFilePath(fileinfo.absolutePath()); pcmd.runCommands(); pt.end(); QImage *img = custom.image(); if (img) { QLabel *label = createLabel(); label->setPixmap(QPixmap::fromImage(*img)); label->resize(label->sizeHint()); label->show(); activeWidget = label; img->save("custom_output_pixmap.png", "PNG"); } else { custom.save("custom_output_pixmap.png", "PNG"); } break; } case CustomWidgetType: { OnScreenWidget<CustomWidget> *cWidget = new OnScreenWidget<CustomWidget>; cWidget->setVerboseMode(verboseMode); cWidget->setType(type); cWidget->setCheckersBackground(checkers_background); cWidget->m_filename = files.at(j); cWidget->setWindowTitle(fileinfo.filePath()); cWidget->m_commands = content; cWidget->resize(width, height); cWidget->show(); activeWidget = cWidget; break; } #endif case PixmapType: { QPixmap pixmap(scaledWidth, scaledHeight); pixmap.setDevicePixelRatio(scalefactor); pixmap.fill(Qt::white); QPainter pt(&pixmap); pcmd.setPainter(&pt); pcmd.setFilePath(fileinfo.absolutePath()); pcmd.runCommands(); pt.end(); pixmap.save("output_pixmap.png", "PNG"); break; } case BitmapType: { QBitmap bitmap(scaledWidth, scaledHeight); bitmap.setDevicePixelRatio(scalefactor); QPainter pt(&bitmap); pcmd.setPainter(&pt); pcmd.setFilePath(fileinfo.absolutePath()); pcmd.runCommands(); pt.end(); bitmap.save("output_bitmap.png", "PNG"); QLabel *label = createLabel(); label->setPixmap(bitmap); label->resize(label->sizeHint()); label->show(); activeWidget = label; break; } case ImageMonoType: case ImageType: { qDebug() << "Creating image"; QImage image(scaledWidth, scaledHeight, type == ImageMonoType ? QImage::Format_MonoLSB : imageFormat); image.setDevicePixelRatio(scalefactor); image.fill(0); QPainter pt(&image); pcmd.setPainter(&pt); pcmd.setFilePath(fileinfo.absolutePath()); pcmd.runCommands(); pt.end(); image.convertToFormat(QImage::Format_ARGB32).save("output_image.png", "PNG"); image.setDevicePixelRatio(1.0); // reset scale factor: display "large" image. #ifndef CONSOLE_APPLICATION QLabel *label = createLabel(); label->setPixmap(QPixmap::fromImage(image)); label->resize(label->sizeHint()); label->show(); activeWidget = label; #endif break; } case PictureType: { QPicture pic; QPainter pt(&pic); pcmd.setPainter(&pt); pcmd.setFilePath(fileinfo.absolutePath()); pcmd.runCommands(); pt.end(); QImage image(width, height, QImage::Format_ARGB32_Premultiplied); image.fill(0); pt.begin(&image); pt.drawPicture(0, 0, pic); pt.end(); QLabel *label = createLabel(); label->setWindowTitle(fileinfo.absolutePath()); label->setPixmap(QPixmap::fromImage(image)); label->resize(label->sizeHint()); label->show(); activeWidget = label; break; } case PrinterType: { #ifndef QT_NO_PRINTER PaintCommands pcmd(QStringList(), 800, 800); pcmd.setVerboseMode(verboseMode); pcmd.setType(type); pcmd.setCheckersBackground(checkers_background); pcmd.setContents(content); QString file = QString(files.at(j)).replace(".", "_") + ".ps"; QPrinter p(highres ? QPrinter::HighResolution : QPrinter::ScreenResolution); if (printdlg) { QPrintDialog printDialog(&p, 0); if (printDialog.exec() != QDialog::Accepted) break; } else { p.setOutputFileName(file); } QPainter pt(&p); pcmd.setPainter(&pt); pcmd.setFilePath(fileinfo.absolutePath()); pcmd.runCommands(); pt.end(); if (!printdlg) { printf("wrote file: %s\n", qPrintable(file)); } Q_ASSERT(!p.paintingActive()); #endif break; } case PsType: case PdfType: { #ifndef QT_NO_PRINTER PaintCommands pcmd(QStringList(), 800, 800); pcmd.setVerboseMode(verboseMode); pcmd.setType(type); pcmd.setCheckersBackground(checkers_background); pcmd.setContents(content); QPrinter p(highres ? QPrinter::HighResolution : QPrinter::ScreenResolution); QFileInfo input(files.at(j)); const QString file = input.baseName() + QLatin1Char('_') + input.suffix() + QStringLiteral(".pdf"); p.setOutputFormat(QPrinter::PdfFormat); p.setOutputFileName(file); p.setPageSize(QPrinter::A4); QPainter pt(&p); pcmd.setPainter(&pt); pcmd.setFilePath(fileinfo.absolutePath()); pcmd.runCommands(); pt.end(); printf("write file: %s\n", qPrintable(file)); #endif break; } case GrabType: { QImage image(width, height, QImage::Format_ARGB32_Premultiplied); image.fill(QColor(Qt::white).rgb()); QPainter pt(&image); pcmd.setPainter(&pt); pcmd.setFilePath(fileinfo.absolutePath()); pcmd.runCommands(); pt.end(); QImage image1(width, height, QImage::Format_RGB32); image1.fill(QColor(Qt::white).rgb()); QPainter pt1(&image1); pt1.drawImage(QPointF(0, 0), image); pt1.end(); QString filename = QString(files.at(j)).replace(".qps", "_qps") + ".png"; image1.save(filename, "PNG"); printf("%s grabbed to %s\n", qPrintable(files.at(j)), qPrintable(filename)); break; } default: break; } } } #ifndef CONSOLE_APPLICATION if (activeWidget || interactive) { QObject::connect(&app, SIGNAL(lastWindowClosed()), &app, SLOT(quit())); app.exec(); } delete activeWidget; #endif delete interactive_widget; return 0; }
QPaintDevice* QQuickContext2DFBOTexture::beginPainting() { QQuickContext2DTexture::beginPainting(); if (m_canvasWindow.size().isEmpty()) { delete m_fbo; delete m_multisampledFbo; delete m_paint_device; m_fbo = 0; m_multisampledFbo = 0; m_paint_device = 0; return 0; } else if (!m_fbo || m_canvasWindowChanged) { delete m_fbo; delete m_multisampledFbo; delete m_paint_device; m_paint_device = 0; m_fboSize = npotAdjustedSize(m_canvasWindow.size() * m_canvasDevicePixelRatio); m_canvasWindowChanged = false; if (doMultisampling()) { { QOpenGLFramebufferObjectFormat format; format.setAttachment(QOpenGLFramebufferObject::CombinedDepthStencil); format.setSamples(8); m_multisampledFbo = new QOpenGLFramebufferObject(m_fboSize, format); } { QOpenGLFramebufferObjectFormat format; format.setAttachment(QOpenGLFramebufferObject::NoAttachment); m_fbo = new QOpenGLFramebufferObject(m_fboSize, format); } } else { QOpenGLFramebufferObjectFormat format; format.setAttachment(QOpenGLFramebufferObject::CombinedDepthStencil); QSize s = m_fboSize; if (m_antialiasing) { // do supersampling since multisampling is not available GLint max; QOpenGLContext::currentContext()->functions()->glGetIntegerv(GL_MAX_TEXTURE_SIZE, &max); if (s.width() * 2 <= max && s.height() * 2 <= max) s = s * 2; } m_fbo = new QOpenGLFramebufferObject(s, format); } } if (doMultisampling()) m_multisampledFbo->bind(); else m_fbo->bind(); if (!m_paint_device) { QOpenGLPaintDevice *gl_device = new QOpenGLPaintDevice(m_fbo->size()); gl_device->setPaintFlipped(true); gl_device->setSize(m_fbo->size()); gl_device->setDevicePixelRatio(m_canvasDevicePixelRatio); qCDebug(lcCanvas, "%s size %.1lf x %.1lf painting with size %d x %d DPR %.1lf", (m_item->objectName().isEmpty() ? "Canvas" : qPrintable(m_item->objectName())), m_item->width(), m_item->height(), m_fbo->size().width(), m_fbo->size().height(), m_canvasDevicePixelRatio); m_paint_device = gl_device; } return m_paint_device; }
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'. }
void Thumbnail::paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidget *widget) { QRectF parentRect = parentItem()->sceneBoundingRect(); // Skip drawing thumbnails outside their parents if (!sceneBoundingRect().intersects(parentRect)) return; prePaint(painter, widget); // Draw image if(!img.isNull()) { auto imgRect = QRectF(img.rect()); imgRect.moveCenter(rect.center()); painter->drawImage(imgRect.topLeft(), img); } // Draw 3D mesh if(mesh.points.size() || auxMeshes.size()) { if (img.isNull() || isTempImage) { auto glwidget = (Viewer*)widget; if (glwidget) { QOpenGLContext context; context.setShareContext(glwidget->context()); context.setFormat(glwidget->format()); context.create(); QOffscreenSurface m_offscreenSurface; m_offscreenSurface.setFormat(context.format()); m_offscreenSurface.create(); context.makeCurrent(&m_offscreenSurface); QOpenGLFramebufferObjectFormat fboformat; fboformat.setAttachment(QOpenGLFramebufferObject::CombinedDepthStencil); QOpenGLFramebufferObject renderFbo(rect.width() * 2, rect.height() * 2, fboformat); renderFbo.bind(); glwidget->glEnable(GL_DEPTH_TEST); glwidget->glEnable(GL_BLEND); glwidget->glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glwidget->glCullFace(GL_BACK); glwidget->glClearColor(0,0,0,0); glwidget->glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glwidget->glViewport(0, 0, renderFbo.size().width(), renderFbo.size().height()); if(mesh.points.size()) glwidget->drawTriangles(mesh.color, mesh.points, mesh.normals, pvm); // Draw aux meshes for (auto auxmesh : auxMeshes) glwidget->drawTriangles(auxmesh.color, auxmesh.points, auxmesh.normals, pvm); glwidget->glDisable(GL_DEPTH_TEST); glwidget->glFlush(); renderFbo.release(); this->setImage( renderFbo.toImage().scaledToWidth(rect.width(), Qt::SmoothTransformation) ); // Thanks for sharing! glwidget->makeCurrent(); } /*painter->beginNativePainting(); auto glwidget = (Viewer*)widget; if (glwidget) { // Draw mesh auto r = sceneBoundingRect(); auto v = scene()->views().first(); QPoint viewDelta = v->mapFromScene(r.topLeft()); if (viewDelta.manhattanLength() > 5) r.moveTopLeft(viewDelta); glwidget->eyePos = eye; glwidget->pvm = pvm; glwidget->glViewport(r.left(), v->height() - r.height() - r.top(), r.width(), r.height()); // Clipping OpenGL glwidget->glEnable(GL_SCISSOR_TEST); glwidget->glScissor(parentRect.x(), v->height() - parentRect.height() - parentRect.top(), parentRect.width(), parentRect.height()); glwidget->glClear(GL_DEPTH_BUFFER_BIT); glwidget->drawTriangles(mesh.color, mesh.points, mesh.normals, pvm); // Draw aux meshes for (auto auxmesh : auxMeshes) { glwidget->drawTriangles(auxmesh.color, auxmesh.points, auxmesh.normals, pvm); } glwidget->glDisable(GL_SCISSOR_TEST); } painter->endNativePainting();*/ } } // Draw the caption if(caption.size()) { painter->setPen(QPen(Qt::white,1)); auto textRect = rect; textRect.setHeight(painter->fontMetrics().height() * 1.25); textRect.moveBottom(rect.height() - textRect.height() * 0.5); painter->drawText(textRect, caption, Qt::AlignVCenter | Qt::AlignHCenter); } postPaint(painter, widget); }