int main(int argc, char **argv) { ::testing::InitGoogleTest(&argc, argv); QGuiApplication app(argc, argv); Q_UNUSED(app); QSurfaceFormat format; format.setMajorVersion(3); format.setMinorVersion(0); QOpenGLContext context; context.setFormat(format); context.create(); if (!context.isValid()) return 1; qDebug() << QString::fromLatin1("Context created."); QOffscreenSurface surface; surface.setFormat(format); surface.create(); if(!surface.isValid()) return 2; qDebug() << QString::fromLatin1("Surface created."); context.makeCurrent(&surface); return RUN_ALL_TESTS(); }
// Verify that QOpenGLContext works with QWindows that do // not have an explicit size set. void tst_QOpenGL::sizeLessWindow() { // top-level window { QWindow window; window.setSurfaceType(QWindow::OpenGLSurface); QOpenGLContext context; QVERIFY(context.create()); window.show(); QVERIFY(context.makeCurrent(&window)); QVERIFY(QOpenGLContext::currentContext()); } QVERIFY(!QOpenGLContext::currentContext()); // child window { QWindow parent; QWindow window(&parent); window.setSurfaceType(QWindow::OpenGLSurface); QOpenGLContext context; QVERIFY(context.create()); parent.show(); window.show(); QVERIFY(context.makeCurrent(&window)); QVERIFY(QOpenGLContext::currentContext()); } QVERIFY(!QOpenGLContext::currentContext()); }
void XCompositeGLXClientBufferIntegration::initializeHardware(QtWayland::Display *) { qDebug() << "Initializing GLX integration"; QPlatformNativeInterface *nativeInterface = QGuiApplicationPrivate::platformIntegration()->nativeInterface(); if (nativeInterface) { mDisplay = static_cast<Display *>(nativeInterface->nativeResourceForWindow("Display",m_compositor->window())); if (!mDisplay) qFatal("could not retireve Display from platform integration"); } else { qFatal("Platform integration doesn't have native interface"); } mScreen = XDefaultScreen(mDisplay); mHandler = new XCompositeHandler(m_compositor->handle(), mDisplay); QOpenGLContext *glContext = new QOpenGLContext(); glContext->create(); m_glxBindTexImageEXT = reinterpret_cast<PFNGLXBINDTEXIMAGEEXTPROC>(glContext->getProcAddress("glXBindTexImageEXT")); if (!m_glxBindTexImageEXT) { qDebug() << "Did not find glxBindTexImageExt, everything will FAIL!"; } m_glxReleaseTexImageEXT = reinterpret_cast<PFNGLXRELEASETEXIMAGEEXTPROC>(glContext->getProcAddress("glXReleaseTexImageEXT")); if (!m_glxReleaseTexImageEXT) { qDebug() << "Did not find glxReleaseTexImageExt"; } delete glContext; }
int getMaxTextureSize() { int maxSize = 0; // Create a temp context - required if this is called from another thread QOpenGLContext ctx; if ( !ctx.create() ) { // TODO handle the error qDebug() << "No OpenGL context could be created, this is clearly bad..."; exit(-1); } // rather than using a QWindow - which actually dosen't seem to work in this case either! QOffscreenSurface surface; surface.setFormat( ctx.format() ); surface.create(); ctx.makeCurrent(&surface); // Now the call works QOpenGLFunctions glFuncs(QOpenGLContext::currentContext()); glFuncs.glEnable(GL_TEXTURE_2D); glFuncs.glGetIntegerv(GL_MAX_TEXTURE_SIZE, &maxSize); return maxSize; }
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 tst_QOpenGL::fboHandleNulledAfterContextDestroyed() { QWindow window; window.setSurfaceType(QWindow::OpenGLSurface); window.setGeometry(0, 0, 10, 10); window.create(); QOpenGLFramebufferObject *fbo = 0; { QOpenGLContext ctx; ctx.create(); ctx.makeCurrent(&window); if (!QOpenGLFramebufferObject::hasOpenGLFramebufferObjects()) QSKIP("QOpenGLFramebufferObject not supported on this platform"); fbo = new QOpenGLFramebufferObject(128, 128); QVERIFY(fbo->handle() != 0); } QCOMPARE(fbo->handle(), 0U); }
void tst_QOpenGL::openGLPaintDevice() { #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()); QSurfaceFormat format = ctx.format(); if (format.majorVersion() < 2) QSKIP("This test requires at least OpenGL 2.0"); QVERIFY(ctx.makeCurrent(surface.data())); const QSize size(128, 128); QImage image(size, QImage::Format_RGB32); QPainter p(&image); p.fillRect(0, 0, image.width() / 2, image.height() / 2, Qt::red); p.fillRect(image.width() / 2, 0, image.width() / 2, image.height() / 2, Qt::green); p.fillRect(image.width() / 2, image.height() / 2, image.width() / 2, image.height() / 2, Qt::blue); p.fillRect(0, image.height() / 2, image.width() / 2, image.height() / 2, Qt::white); p.end(); QOpenGLFramebufferObject fbo(size); QVERIFY(fbo.bind()); QOpenGLPaintDevice device(size); QVERIFY(p.begin(&device)); p.fillRect(0, 0, image.width() / 2, image.height() / 2, Qt::red); p.fillRect(image.width() / 2, 0, image.width() / 2, image.height() / 2, Qt::green); p.fillRect(image.width() / 2, image.height() / 2, image.width() / 2, image.height() / 2, Qt::blue); p.fillRect(0, image.height() / 2, image.width() / 2, image.height() / 2, Qt::white); p.end(); QImage actual = fbo.toImage().convertToFormat(QImage::Format_RGB32); QCOMPARE(image.size(), actual.size()); QCOMPARE(image, actual); QVERIFY(p.begin(&device)); p.fillRect(0, 0, image.width(), image.height(), Qt::black); p.drawImage(0, 0, image); p.end(); actual = fbo.toImage().convertToFormat(QImage::Format_RGB32); QCOMPARE(image.size(), actual.size()); QCOMPARE(image, actual); QVERIFY(p.begin(&device)); p.fillRect(0, 0, image.width(), image.height(), Qt::black); p.fillRect(0, 0, image.width(), image.height(), QBrush(image)); p.end(); actual = fbo.toImage().convertToFormat(QImage::Format_RGB32); QCOMPARE(image.size(), actual.size()); QCOMPARE(image, actual); }
void KisOpenGL::initialize() { if (initialized) return; setDefaultFormat(); // we need a QSurface active to get our GL functions from the context QWindow surface; surface.setSurfaceType( QSurface::OpenGLSurface ); surface.create(); QOpenGLContext context; context.create(); context.makeCurrent( &surface ); QOpenGLFunctions *funcs = context.functions(); funcs->initializeOpenGLFunctions(); qDebug() << "OpenGL Info"; qDebug() << " Vendor: " << reinterpret_cast<const char *>(funcs->glGetString(GL_VENDOR)); qDebug() << " Renderer: " << reinterpret_cast<const char *>(funcs->glGetString(GL_RENDERER)); qDebug() << " Version: " << reinterpret_cast<const char *>(funcs->glGetString(GL_VERSION)); qDebug() << " Shading language: " << reinterpret_cast<const char *>(funcs->glGetString(GL_SHADING_LANGUAGE_VERSION)); qDebug() << " Requested format: " << QSurfaceFormat::defaultFormat(); qDebug() << " Current format: " << context.format(); glMajorVersion = context.format().majorVersion(); glMinorVersion = context.format().minorVersion(); supportsDeprecatedFunctions = (context.format().options() & QSurfaceFormat::DeprecatedFunctions); initialized = true; }
void tst_QOpenGL::sharedResourceCleanup() { QFETCH(int, surfaceClass); QScopedPointer<QSurface> surface(createSurface(surfaceClass)); QOpenGLContext *ctx = new QOpenGLContext; ctx->create(); ctx->makeCurrent(surface.data()); SharedResourceTracker tracker; SharedResource *resource = new SharedResource(&tracker); resource->free(); QCOMPARE(tracker.invalidateResourceCalls, 0); QCOMPARE(tracker.freeResourceCalls, 1); QCOMPARE(tracker.destructorCalls, 1); tracker.reset(); resource = new SharedResource(&tracker); QOpenGLContext *ctx2 = new QOpenGLContext; ctx2->setShareContext(ctx); ctx2->create(); delete ctx; resource->free(); // no current context, freeResource() delayed QCOMPARE(tracker.invalidateResourceCalls, 0); QCOMPARE(tracker.freeResourceCalls, 0); QCOMPARE(tracker.destructorCalls, 0); ctx2->makeCurrent(surface.data()); // freeResource() should now have been called QCOMPARE(tracker.invalidateResourceCalls, 0); QCOMPARE(tracker.freeResourceCalls, 1); QCOMPARE(tracker.destructorCalls, 1); tracker.reset(); resource = new SharedResource(&tracker); // this should cause invalidateResource() to be called delete ctx2; QCOMPARE(tracker.invalidateResourceCalls, 1); QCOMPARE(tracker.freeResourceCalls, 0); QCOMPARE(tracker.destructorCalls, 0); // should have no effect other than destroying the resource, // as it has already been invalidated resource->free(); QCOMPARE(tracker.invalidateResourceCalls, 1); QCOMPARE(tracker.freeResourceCalls, 0); QCOMPARE(tracker.destructorCalls, 1); }
void dumpGlInfo(QTextStream &str, bool listExtensions) { QOpenGLContext context; if (context.create()) { # ifdef QT_OPENGL_DYNAMIC str << "Dynamic GL "; # endif switch (context.openGLModuleType()) { case QOpenGLContext::LibGL: str << "LibGL"; break; case QOpenGLContext::LibGLES: str << "LibGLES"; break; } QWindow window; window.setSurfaceType(QSurface::OpenGLSurface); window.create(); context.makeCurrent(&window); QOpenGLFunctions functions(&context); str << " Vendor: " << reinterpret_cast<const char *>(functions.glGetString(GL_VENDOR)) << "\nRenderer: " << reinterpret_cast<const char *>(functions.glGetString(GL_RENDERER)) << "\nVersion: " << reinterpret_cast<const char *>(functions.glGetString(GL_VERSION)) << "\nShading language: " << reinterpret_cast<const char *>(functions.glGetString(GL_SHADING_LANGUAGE_VERSION)) << "\nFormat: " << context.format(); if (listExtensions) { QList<QByteArray> extensionList = context.extensions().toList(); std::sort(extensionList.begin(), extensionList.end()); str << " \nFound " << extensionList.size() << " extensions:\n"; foreach (const QByteArray &extension, extensionList) str << " " << extension << '\n'; } } else {
bool OpenGL2Common::testGL() { QOpenGLContext glCtx; if ((isOK = glCtx.create())) { QOffscreenSurface offscreenSurface; offscreenSurface.create(); if ((isOK = glCtx.makeCurrent(&offscreenSurface))) testGLInternal(); } return isOK; }
void QEglFSWindow::create() { if (m_flags.testFlag(Created)) return; QEGLPlatformWindow::create(); m_flags = Created; if (window()->type() == Qt::Desktop) return; // Stop if there is already a window backed by a native window and surface. Additional // raster windows will not have their own native window, surface and context. Instead, // they will be composited onto the root window's surface. QEglFSScreen *screen = this->screen(); if (screen->primarySurface() != EGL_NO_SURFACE) { if (isRaster() && screen->compositingWindow()) return; #if !defined(Q_OS_ANDROID) || defined(Q_OS_ANDROID_NO_SDK) // We can have either a single OpenGL window or multiple raster windows. // Other combinations cannot work. qFatal("EGLFS: OpenGL windows cannot be mixed with others."); #endif return; } m_flags |= HasNativeWindow; setGeometry(QRect()); // will become fullscreen QWindowSystemInterface::handleExposeEvent(window(), geometry()); EGLDisplay display = static_cast<QEglFSScreen *>(screen)->display(); QSurfaceFormat platformFormat = QEglFSHooks::hooks()->surfaceFormatFor(window()->requestedFormat()); m_config = QEglFSIntegration::chooseConfig(display, platformFormat); m_format = q_glFormatFromConfig(display, m_config, platformFormat); resetSurface(); screen->setPrimarySurface(m_surface); if (isRaster()) { QOpenGLContext *context = new QOpenGLContext(QGuiApplication::instance()); context->setFormat(window()->requestedFormat()); context->setScreen(window()->screen()); if (!context->create()) qFatal("EGLFS: Failed to create compositing context"); screen->setRootContext(context); screen->setRootWindow(this); } }
static QSurfaceFormat* getFirstSupported(std::vector<QSurfaceFormat> &formats) { QOpenGLContext context; for (QSurfaceFormat &format : formats) { context.setFormat(format); if (context.create()) { if (checkVersion(context, format)) return &format; } } return NULL; }
QString openGlContext() { QString result; QTextStream str(&result); QOpenGLContext context; if (context.create()) { # ifdef QT_OPENGL_DYNAMIC str << "Dynamic GL "; # endif switch (context.openGLModuleType()) { case QOpenGLContext::LibGL: str << "LibGL"; break; case QOpenGLContext::LibGLES: str << "LibGLES"; break; } QWindow window; if (QGuiApplication::platformName() == QLatin1String("greenisland")) window.setFlags(Qt::Desktop); window.setSurfaceType(QSurface::OpenGLSurface); //window.setScreen(QGuiApplication::primaryScreen()); window.create(); if (context.makeCurrent(&window)) { QOpenGLFunctions functions(&context); str << " Vendor: " << reinterpret_cast<const char *>(functions.glGetString(GL_VENDOR)) << "\nRenderer: " << reinterpret_cast<const char *>(functions.glGetString(GL_RENDERER)) << "\nVersion: " << reinterpret_cast<const char *>(functions.glGetString(GL_VERSION)) << "\nGLSL version: " << reinterpret_cast<const char *>(functions.glGetString(GL_SHADING_LANGUAGE_VERSION)) << "\nFormat: " << context.format(); QList<QByteArray> extensionList = context.extensions().toList(); std::sort(extensionList.begin(), extensionList.end()); QByteArray extensions = extensionList.join(' '); str << " \nFound " << extensionList.size() << " extensions:\n"; str << wordWrap(extensions, 78); context.doneCurrent(); } window.destroy(); } else { str << "Unable to create an Open GL context.\n"; } return result; }
void TestWindow::initGl() { _glContext.setFormat(format()); if (!_glContext.create() || !_glContext.makeCurrent(this)) { qFatal("Unable to intialize Window GL context"); } gl::initModuleGl(); _glf.initializeOpenGLFunctions(); _glf.glGenFramebuffers(1, &_fbo); if (!_sharedContext.create(&_glContext) || !_sharedContext.makeCurrent()) { qFatal("Unable to intialize Shared GL context"); } hifi::qml::OffscreenSurface::setSharedContext(_sharedContext.getContext()); _discardLamdba = hifi::qml::OffscreenSurface::getDiscardLambda(); }
// 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 tst_QOpenGL::aboutToBeDestroyed() { QWindow window; window.setSurfaceType(QWindow::OpenGLSurface); window.setGeometry(0, 0, 128, 128); window.create(); QOpenGLContext *context = new QOpenGLContext; QSignalSpy spy(context, SIGNAL(aboutToBeDestroyed())); context->create(); context->makeCurrent(&window); QCOMPARE(spy.size(), 0); delete context; QCOMPARE(spy.size(), 1); }
void tst_QOpenGL::multiGroupSharedResourceCleanup() { QFETCH(int, surfaceClass); QScopedPointer<QSurface> surface(createSurface(surfaceClass)); for (int i = 0; i < 10; ++i) { QOpenGLContext *gl = new QOpenGLContext(); gl->create(); gl->makeCurrent(surface.data()); { // Cause QOpenGLMultiGroupSharedResource instantiation. QOpenGLFunctions func(gl); } delete gl; // Cause context group's deleteLater() to be processed. QCoreApplication::sendPostedEvents(0, QEvent::DeferredDelete); } // Shouldn't crash when application exits. }
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; }
void tst_QOpenGL::multiGroupSharedResourceCleanupCustom() { QFETCH(int, surfaceClass); QScopedPointer<QSurface> surface(createSurface(surfaceClass)); QOpenGLContext *ctx = new QOpenGLContext(); ctx->create(); ctx->makeCurrent(surface.data()); QOpenGLMultiGroupSharedResource multiGroupSharedResource; SharedResource *resource = multiGroupSharedResource.value<SharedResource>(ctx); SharedResourceTracker tracker; resource->tracker = &tracker; delete ctx; QCOMPARE(tracker.invalidateResourceCalls, 1); QCOMPARE(tracker.freeResourceCalls, 0); QCOMPARE(tracker.destructorCalls, 1); }
int main(int argc, char *argv[]) { { std::random_device rd; srand(rd()); qsrand(rd()); } QApplication app(argc, argv); QApplication::setAttribute(Qt::AA_UseHighDpiPixmaps); QOpenGLContext context; context.create(); qt_gl_set_global_share_context(&context); Core::ModuleManagerImpl core; Q_UNUSED(core); return app.exec(); }
void OpenGLWindow::Init() { // OpenGL //auto surface = new QOffscreenSurface(); //surface->setFormat(format); //surface->create(); //setSwapInterval QSurfaceFormat format; format.setVersion(4, 0); format.setSwapInterval(0); format.setProfile(QSurfaceFormat::CoreProfile); setFormat(format); auto glfwCTX = glfwGetWGLContext(Engine::Window->window); auto window = glfwGetWin32Window(Engine::Window->window); auto newNative = new QWGLNativeContext(glfwCTX, window); QOpenGLContext* qtctx = new QOpenGLContext(); //qtctx->setFormat(format); qtctx->setNativeHandle(QVariant::fromValue<QWGLNativeContext>(*newNative)); bool created = qtctx->create(); bool value = qtctx->makeCurrent(this); // Test auto nativeHandle = qtctx->nativeHandle(); auto windowsNative = nativeHandle.value<QWGLNativeContext>(); // Share context qtGLContext = new QOpenGLContext(this); //qtGLContext->setFormat(format); qtGLContext->setShareContext(qtctx); bool success = qtGLContext->create(); nativeHandle = qtGLContext->nativeHandle(); windowsNative = nativeHandle.value<QWGLNativeContext>(); bool sharing = qtGLContext->areSharing(qtctx, qtGLContext); bool sharing2 = qtGLContext->shareContext(); }
OpenGLInfo::OpenGLInfo() { QOpenGLContext context; QOffscreenSurface surface; surface.create(); if (!context.create()) { qCritical() << "Could not create QOpenGLContext"; return; } if (context.makeCurrent(&surface)) { KWin::GLPlatform *platform = KWin::GLPlatform::instance(); if (context.isOpenGLES() || !QX11Info::isPlatformX11()) { platform->detect(KWin::EglPlatformInterface); } else { platform->detect(KWin::GlxPlatformInterface); } if (platform->glRendererString().isEmpty()) { qCritical() << "Neither GLX or EGL detection worked!"; } openGLRenderer = QString::fromUtf8(platform->glRendererString()); openGLVersion = QString::fromUtf8(platform->glVersionString()); mesaVersion = KWin::GLPlatform::versionToString(platform->mesaVersion()); if (platform->driver() == KWin::Driver::Driver_Unknown) { kwinDriver = platform->glVendorString(); } else { kwinDriver = KWin::GLPlatform::driverToString(platform->driver()); } displayServerVersion = KWin::GLPlatform::versionToString(platform->serverVersion()); } else { qCritical() <<"Error: makeCurrent() failed\n"; } context.doneCurrent(); }
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; }
void ResultRecorder::startResults(const QString &id) { // sub process will get all this. // safer that way, as then we keep OpenGL (and QGuiApplication) out of the host if (!Options::instance.isSubProcess) return; m_results["id"] = id; QString prettyProductName = #if QT_VERSION >= 0x050400 QSysInfo::prettyProductName(); #else # if defined(Q_OS_IOS) QStringLiteral("iOS"); # elif defined(Q_OS_OSX) QString::fromLatin1("OSX %d").arg(QSysInfo::macVersion()); # elif defined(Q_OS_WIN) QString::fromLatin1("Windows %d").arg(QSysInfo::windowsVersion()); # elif defined(Q_OS_LINUX) QStringLiteral("Linux"); # elif defined(Q_OS_ANDROID) QStringLiteral("Android"); # else QStringLiteral("unknown"); # endif #endif QVariantMap osMap; osMap["prettyProductName"] = prettyProductName; osMap["platformPlugin"] = QGuiApplication::platformName(); m_results["os"] = osMap; m_results["qt"] = QT_VERSION_STR; m_results["command-line"] = qApp->arguments().join(' '); // The following code makes the assumption that an OpenGL context the GUI // thread will get the same capabilities as the render thread's OpenGL // context. Not 100% accurate, but it works... QOpenGLContext context; context.create(); QOffscreenSurface surface; // In very odd cases, we can get incompatible configs here unless we pass the // GL context's format on to the offscreen format. surface.setFormat(context.format()); surface.create(); if (!context.makeCurrent(&surface)) { qWarning() << "failed to acquire GL context to get version info."; return; } QOpenGLFunctions *func = context.functions(); #if QT_VERSION >= 0x050300 const char *vendor = (const char *) func->glGetString(GL_VENDOR); const char *renderer = (const char *) func->glGetString(GL_RENDERER); const char *version = (const char *) func->glGetString(GL_VERSION); #else Q_UNUSED(func); const char *vendor = (const char *) glGetString(GL_VENDOR); const char *renderer = (const char *) glGetString(GL_RENDERER); const char *version = (const char *) glGetString(GL_VERSION); #endif if (!Options::instance.printJsonToStdout) { std::cout << "ID: " << id.toStdString() << std::endl; std::cout << "OS: " << prettyProductName.toStdString() << std::endl; std::cout << "QPA: " << QGuiApplication::platformName().toStdString() << std::endl; std::cout << "GL_VENDOR: " << vendor << std::endl; std::cout << "GL_RENDERER: " << renderer << std::endl; std::cout << "GL_VERSION: " << version << std::endl; } QVariantMap glInfo; glInfo["vendor"] = vendor; glInfo["renderer"] = renderer; glInfo["version"] = version; m_results["opengl"] = glInfo; context.doneCurrent(); }
int main(int argc, char* argv[]) { // Parse command line arguments std::vector<string> input_paths, seg_paths; string output_path, landmarks_path; string model_3dmm_h5_path, model_3dmm_dat_path; string reg_model_path, reg_deploy_path, reg_mean_path; string seg_model_path, seg_deploy_path; string cfg_path; bool generic, with_expr, with_gpu; unsigned int gpu_device_id, verbose; try { options_description desc("Allowed options"); desc.add_options() ("help,h", "display the help message") ("verbose,v", value<unsigned int>(&verbose)->default_value(0), "output debug information [0, 4]") ("input,i", value<std::vector<string>>(&input_paths)->required(), "image paths [source target]") ("output,o", value<string>(&output_path)->required(), "output path") ("segmentations,s", value<std::vector<string>>(&seg_paths), "segmentation paths [source target]") ("landmarks,l", value<string>(&landmarks_path)->required(), "path to landmarks model file") ("model_3dmm_h5", value<string>(&model_3dmm_h5_path)->required(), "path to 3DMM file (.h5)") ("model_3dmm_dat", value<string>(&model_3dmm_dat_path)->required(), "path to 3DMM file (.dat)") ("reg_model,r", value<string>(®_model_path)->required(), "path to 3DMM regression CNN model file (.caffemodel)") ("reg_deploy,d", value<string>(®_deploy_path)->required(), "path to 3DMM regression CNN deploy file (.prototxt)") ("reg_mean,m", value<string>(®_mean_path)->required(), "path to 3DMM regression CNN mean file (.binaryproto)") ("seg_model", value<string>(&seg_model_path), "path to face segmentation CNN model file (.caffemodel)") ("seg_deploy", value<string>(&seg_deploy_path), "path to face segmentation CNN deploy file (.prototxt)") ("generic,g", value<bool>(&generic)->default_value(false), "use generic model without shape regression") ("expressions,e", value<bool>(&with_expr)->default_value(true), "with expressions") ("gpu", value<bool>(&with_gpu)->default_value(true), "toggle GPU / CPU") ("gpu_id", value<unsigned int>(&gpu_device_id)->default_value(0), "GPU's device id") ("cfg", value<string>(&cfg_path)->default_value("face_swap_image.cfg"), "configuration file (.cfg)") ; variables_map vm; store(command_line_parser(argc, argv).options(desc). positional(positional_options_description().add("input", -1)).run(), vm); if (vm.count("help")) { cout << "Usage: face_swap_image [options]" << endl; cout << desc << endl; exit(0); } // Read config file std::ifstream ifs(vm["cfg"].as<string>()); store(parse_config_file(ifs, desc), vm); notify(vm); if(input_paths.size() != 2) throw error("Both source and target must be specified in input!"); if (!is_regular_file(input_paths[0])) throw error("source input must be a path to an image!"); if (!is_regular_file(input_paths[1])) throw error("target input target must be a path to an image!"); if (seg_paths.size() > 0 && !is_regular_file(seg_paths[0])) throw error("source segmentation must be a path to an image!"); if (seg_paths.size() > 1 && !is_regular_file(seg_paths[1])) throw error("target segmentation must be a path to an image!"); if (!is_regular_file(landmarks_path)) throw error("landmarks must be a path to a file!"); if (!is_regular_file(model_3dmm_h5_path)) throw error("model_3dmm_h5 must be a path to a file!"); if (!is_regular_file(model_3dmm_dat_path)) throw error("model_3dmm_dat must be a path to a file!"); if (!is_regular_file(reg_model_path)) throw error("reg_model must be a path to a file!"); if (!is_regular_file(reg_deploy_path)) throw error("reg_deploy must be a path to a file!"); if (!is_regular_file(reg_mean_path)) throw error("reg_mean must be a path to a file!"); if (!seg_model_path.empty() && !is_regular_file(seg_model_path)) throw error("seg_model must be a path to a file!"); if (!seg_deploy_path.empty() && !is_regular_file(seg_deploy_path)) throw error("seg_deploy must be a path to a file!"); } catch (const error& e) { cerr << "Error while parsing command-line arguments: " << e.what() << endl; cerr << "Use --help to display a list of options." << endl; exit(1); } try { // Intialize OpenGL context QApplication a(argc, argv); QSurfaceFormat surfaceFormat; surfaceFormat.setMajorVersion(1); surfaceFormat.setMinorVersion(5); QOpenGLContext openGLContext; openGLContext.setFormat(surfaceFormat); openGLContext.create(); if (!openGLContext.isValid()) return -1; QOffscreenSurface surface; surface.setFormat(surfaceFormat); surface.create(); if (!surface.isValid()) return -2; openGLContext.makeCurrent(&surface); // Initialize GLEW GLenum err = glewInit(); if (GLEW_OK != err) { // Problem: glewInit failed, something is seriously wrong fprintf(stderr, "Error: %s\n", glewGetErrorString(err)); throw std::runtime_error("Failed to initialize GLEW!"); } // Initialize face swap face_swap::FaceSwap fs(landmarks_path, model_3dmm_h5_path, model_3dmm_dat_path, reg_model_path, reg_deploy_path, reg_mean_path, generic, with_expr, with_gpu, (int)gpu_device_id); // Read source and target images cv::Mat source_img = cv::imread(input_paths[0]); cv::Mat target_img = cv::imread(input_paths[1]); // Read source and target segmentations or initialize segmentation model cv::Mat source_seg, target_seg; if (seg_model_path.empty() || seg_deploy_path.empty()) { if (seg_paths.size() > 0) source_seg = cv::imread(seg_paths[0], cv::IMREAD_GRAYSCALE); if (seg_paths.size() > 1) target_seg = cv::imread(seg_paths[1], cv::IMREAD_GRAYSCALE); } else fs.setSegmentationModel(seg_model_path, seg_deploy_path); // Set source and target if (!fs.setSource(source_img, source_seg)) throw std::runtime_error("Failed to find faces in source image!"); if (!fs.setTarget(target_img, target_seg)) throw std::runtime_error("Failed to find faces in target image!"); // Do face swap cv::Mat rendered_img = fs.swap(); if (rendered_img.empty()) throw std::runtime_error("Face swap failed!"); // Write output to file path out_file_path = output_path; path out_dir_path = output_path; if (is_directory(output_path)) { path outputName = (path(input_paths[0]).stem() += "_") += (path(input_paths[1]).stem() += ".jpg"); out_file_path = path(output_path) /= outputName; } else out_dir_path = path(output_path).parent_path(); cv::imwrite(out_file_path.string(), rendered_img); // Debug if (verbose > 0) { // Write rendered image path debug_render_path = out_dir_path / (out_file_path.stem() += "_render.jpg"); cv::Mat debug_render_img = fs.debugRender(); cv::imwrite(debug_render_path.string(), debug_render_img); } if (verbose > 1) { // Write projected meshes path debug_src_mesh_path = out_dir_path / (out_file_path.stem() += "_src_mesh.jpg"); cv::Mat debug_src_mesh_img = fs.debugSourceMesh(); cv::imwrite(debug_src_mesh_path.string(), debug_src_mesh_img); path debug_tgt_mesh_path = out_dir_path / (out_file_path.stem() += "_tgt_mesh.jpg"); cv::Mat debug_tgt_mesh_img = fs.debugTargetMesh(); cv::imwrite(debug_tgt_mesh_path.string(), debug_tgt_mesh_img); } if (verbose > 2) { // Write landmarks render path debug_src_lms_path = out_dir_path / (out_file_path.stem() += "_src_landmarks.jpg"); cv::Mat debug_src_lms_img = fs.debugSourceLandmarks(); cv::imwrite(debug_src_lms_path.string(), debug_src_lms_img); path debug_tgt_lms_path = out_dir_path / (out_file_path.stem() += "_tgt_landmarks.jpg"); cv::Mat debug_tgt_lms_img = fs.debugTargetLandmarks(); cv::imwrite(debug_tgt_lms_path.string(), debug_tgt_lms_img); } if (verbose > 3) { // Write meshes path debug_src_ply_path = out_dir_path / (out_file_path.stem() += "_src_mesh.ply"); path debug_tgt_ply_path = out_dir_path / (out_file_path.stem() += "_tgt_mesh.ply"); face_swap::Mesh::save_ply(fs.getSourceMesh(), debug_src_ply_path.string()); face_swap::Mesh::save_ply(fs.getTargetMesh(), debug_tgt_ply_path.string()); } } catch (std::exception& e) { cerr << e.what() << endl; return 1; } return 0; }
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(); } } }
void tst_QOpenGL::QTBUG15621_triangulatingStrokerDivZero() { #if defined(Q_OS_LINUX) && defined(Q_CC_GNU) && !defined(__x86_64__) QSKIP("QTBUG-22617"); #endif QWindow window; window.setSurfaceType(QWindow::OpenGLSurface); window.setGeometry(0, 0, 128, 128); window.create(); QOpenGLContext ctx; ctx.create(); ctx.makeCurrent(&window); if (!QOpenGLFramebufferObject::hasOpenGLFramebufferObjects()) QSKIP("QOpenGLFramebufferObject not supported on this platform"); QOpenGLFramebufferObject fbo(128, 128); fbo.bind(); QOpenGLPaintDevice device(128, 128); // QTBUG-15621 is only a problem when qreal is double, but do the test anyway. qreal delta = sizeof(qreal) == sizeof(float) ? 1e-4 : 1e-8; QVERIFY(128 != 128 + delta); QPainterPath path; path.moveTo(16 + delta, 16); path.moveTo(16, 16); path.lineTo(16 + delta, 16); // Short lines to check for division by zero. path.lineTo(112 - delta, 16); path.lineTo(112, 16); path.quadTo(112, 16, 112, 16 + delta); path.quadTo(112, 64, 112, 112 - delta); path.quadTo(112, 112, 112, 112); path.cubicTo(112, 112, 112, 112, 112 - delta, 112); path.cubicTo(80, 112, 48, 112, 16 + delta, 112); path.cubicTo(16 + delta, 112, 16 + delta, 112, 16, 112); path.closeSubpath(); QPen pen(Qt::red, 28, Qt::SolidLine, Qt::FlatCap, Qt::MiterJoin); QPainter p(&device); p.fillRect(QRect(0, 0, 128, 128), Qt::blue); p.strokePath(path, pen); p.end(); QImage image = fbo.toImage().convertToFormat(QImage::Format_RGB32); const QRgb red = 0xffff0000; const QRgb blue = 0xff0000ff; QCOMPARE(image.pixel(8, 8), red); QCOMPARE(image.pixel(119, 8), red); QCOMPARE(image.pixel(8, 119), red); QCOMPARE(image.pixel(119, 119), red); QCOMPARE(image.pixel(0, 0), blue); QCOMPARE(image.pixel(127, 0), blue); QCOMPARE(image.pixel(0, 127), blue); QCOMPARE(image.pixel(127, 127), blue); QCOMPARE(image.pixel(32, 32), blue); QCOMPARE(image.pixel(95, 32), blue); QCOMPARE(image.pixel(32, 95), blue); QCOMPARE(image.pixel(95, 95), blue); }
bool OculusWin32DisplayPlugin::start() { { ovrInitParams initParams; memset(&initParams, 0, sizeof(initParams)); #ifdef DEBUG initParams.Flags |= ovrInit_Debug; #endif ovrResult result = ovr_Initialize(&initParams); Q_ASSERT(OVR_SUCCESS(result)); result = ovr_Create(&_hmd, &_luid); _hmdDesc = ovr_GetHmdDesc(_hmd); for_each_eye([&](ovrEyeType eye) { _eyeFovs[eye] = _hmdDesc.DefaultEyeFov[eye]; _eyeProjections[eye] = toGlm(ovrMatrix4f_Projection(_eyeFovs[eye], 0.01f, 100.0f, ovrProjection_RightHanded)); ovrEyeRenderDesc erd = ovr_GetRenderDesc(_hmd, eye, _eyeFovs[eye]); _eyeOffsets[eye] = erd.HmdToEyeViewOffset; }); _eyeTextureSize = ovr_GetFovTextureSize(_hmd, ovrEye_Left, _eyeFovs[ovrEye_Left], 1.0f); _renderTargetSize = { _eyeTextureSize.w * 2, _eyeTextureSize.h }; ovr_ConfigureTracking(_hmd, ovrTrackingCap_Orientation | ovrTrackingCap_Position | ovrTrackingCap_MagYawCorrection, ovrTrackingCap_Orientation); } Q_ASSERT(!_window); Q_ASSERT(_shareContext); _window = new QWindow; _window->setSurfaceType(QSurface::OpenGLSurface); _window->setFormat(getDesiredSurfaceFormat()); _context = new QOpenGLContext; _context->setFormat(getDesiredSurfaceFormat()); _context->setShareContext(_shareContext); _context->create(); _window->show(); _window->setGeometry(QRect(100, -800, 1280, 720)); bool result = _context->makeCurrent(_window); #if defined(Q_OS_WIN) if (wglewGetExtension("WGL_EXT_swap_control")) { wglSwapIntervalEXT(0); int swapInterval = wglGetSwapIntervalEXT(); qDebug("V-Sync is %s\n", (swapInterval > 0 ? "ON" : "OFF")); } #elif defined(Q_OS_LINUX) #else qCDebug(interfaceapp, "V-Sync is FORCED ON on this system\n"); #endif Q_ASSERT(result); { // The geometry and shader for rendering the 2D UI surface when needed _program = oria::loadProgram( Resource::SHADERS_TEXTURED_VS, Resource::SHADERS_TEXTURED_FS); _quad = oria::loadPlane(_program, 1.0f); glClearColor(0, 1, 1, 1); glDisable(GL_DEPTH_TEST); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); _mirrorFbo = new MirrorFramebufferWrapper(_hmd); _sceneSwapFbo = new SwapFramebufferWrapper(_hmd); _sceneSwapFbo->Init(toGlm(_renderTargetSize)); _uiSwapFbo = new SwapFramebufferWrapper(_hmd); _uiSwapFbo->Init(_uiSize); _mirrorFbo->Init(uvec2(100, 100)); _context->doneCurrent(); } _sceneLayer.ColorTexture[0] = _sceneSwapFbo->color; _sceneLayer.ColorTexture[1] = nullptr; _sceneLayer.Viewport[0].Pos = { 0, 0 }; _sceneLayer.Viewport[0].Size = _eyeTextureSize; _sceneLayer.Viewport[1].Pos = { _eyeTextureSize.w, 0 }; _sceneLayer.Viewport[1].Size = _eyeTextureSize; _sceneLayer.Header.Type = ovrLayerType_EyeFov; _sceneLayer.Header.Flags = ovrLayerFlag_TextureOriginAtBottomLeft; for_each_eye([&](ovrEyeType eye) { _eyeViewports[eye] = _sceneLayer.Viewport[eye]; _sceneLayer.Fov[eye] = _eyeFovs[eye]; }); _uiLayer.ColorTexture = _uiSwapFbo->color; _uiLayer.Header.Type = ovrLayerType_QuadInWorld; _uiLayer.Header.Flags = ovrLayerFlag_TextureOriginAtBottomLeft; _uiLayer.QuadPoseCenter.Orientation = { 0, 0, 0, 1 }; _uiLayer.QuadPoseCenter.Position = { 0, 0, -1 }; _uiLayer.QuadSize = { aspect(_uiSize), 1.0f }; _uiLayer.Viewport = { { 0, 0 }, { (int)_uiSize.x, (int)_uiSize.y } }; _timer.start(0); connect(_window, &QWindow::widthChanged, this, &OculusWin32DisplayPlugin::resizedMirror); connect(_window, &QWindow::heightChanged, this, &OculusWin32DisplayPlugin::resizedMirror); resizedMirror(); return true; }
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); }