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 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); }
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(); } } }