QOpenGLFramebufferObject *createFramebufferObject(const QSize &size) { QOpenGLFramebufferObjectFormat format; format.setAttachment(QOpenGLFramebufferObject::CombinedDepthStencil); format.setSamples(4); return new QOpenGLFramebufferObject(size, format); }
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; }
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(); }
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; }
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; }
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; }
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_setSamples(PyObject *sipSelf, PyObject *sipArgs) { PyObject *sipParseErr = NULL; { int a0; QOpenGLFramebufferObjectFormat *sipCpp; if (sipParseArgs(&sipParseErr, sipArgs, "Bi", &sipSelf, sipType_QOpenGLFramebufferObjectFormat, &sipCpp, &a0)) { sipCpp->setSamples(a0); Py_INCREF(Py_None); return Py_None; } } /* Raise an exception if the arguments couldn't be parsed. */ sipNoMethod(sipParseErr, sipName_QOpenGLFramebufferObjectFormat, sipName_setSamples, doc_QOpenGLFramebufferObjectFormat_setSamples); return NULL; }
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'. }
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; }
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; }
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; }