Example #1
0
bool OpenGL2Common::testGL()
{
    QOpenGLContext glCtx;
    if ((isOK = glCtx.create()))
    {
        QOffscreenSurface offscreenSurface;
        offscreenSurface.create();
        if ((isOK = glCtx.makeCurrent(&offscreenSurface)))
            testGLInternal();
    }
    return isOK;
}
Example #2
0
void QuickMozView::clearThreadRenderObject()
{
    QOpenGLContext* ctx = QOpenGLContext::currentContext();
    Q_ASSERT(ctx != NULL && ctx->makeCurrent(ctx->surface()));
    if (gSGRenderer != NULL) {
        delete gSGRenderer;
        gSGRenderer = NULL;
    }
    QQuickWindow *win = window();
    if (!win) return;
    connect(win, SIGNAL(beforeSynchronizing()), this, SLOT(createThreadRenderObject()), Qt::DirectConnection);
}
Example #3
0
    GraphicsSurfacePrivate(const PlatformGraphicsContext3D shareContext = 0)
        : m_display(0)
        , m_xPixmap(0)
        , m_glxPixmap(0)
        , m_glContext(0)
        , m_detachedContext(0)
        , m_detachedSurface(0)
        , m_textureIsYInverted(false)
        , m_hasAlpha(false)
    {
        GLXContext shareContextObject = 0;
        m_display = XOpenDisplay(0);

#if PLATFORM(QT)
        if (shareContext) {
#if 0
            // This code path requires QXcbNativeInterface::nativeResourceForContext() which is not availble in Qt5 on the build bots yet.
            QPlatformNativeInterface* nativeInterface = QGuiApplication::platformNativeInterface();
            shareContextObject = static_cast<GLXContext>(nativeInterface->nativeResourceForContext(QByteArrayLiteral("glxcontext"), shareContext));
            if (!shareContextObject)
                return;
#else
            // This code path should be removed as soon as QXcbNativeInterface::nativeResourceForContext() can provide the GLXContext.
            QOpenGLContext* previousContext = QOpenGLContext::currentContext();
            QSurface* previousSurface = previousContext->surface();
            QSurface* currentSurface = shareContext->surface();
            shareContext->makeCurrent(currentSurface);

            shareContextObject = glXGetCurrentContext();

            previousContext->makeCurrent(previousSurface);
#endif
        }
#endif

        m_display = m_offScreenWindow.display();
        int attributes[] = {
            GLX_LEVEL, 0,
            GLX_DRAWABLE_TYPE, GLX_WINDOW_BIT,
            GLX_RENDER_TYPE,   GLX_RGBA_BIT,
            GLX_RED_SIZE,      1,
            GLX_GREEN_SIZE,    1,
            GLX_BLUE_SIZE,     1,
            GLX_DOUBLEBUFFER,  True,
            None
        };

        int numReturned;
        m_fbConfigs = glXChooseFBConfig(m_display, DefaultScreen(m_display), attributes, &numReturned);
        // Create a GLX context for OpenGL rendering
        m_glContext = glXCreateNewContext(m_display, m_fbConfigs[0], GLX_RGBA_TYPE, shareContextObject, true);
    }
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;
    ctx.create();

    QSurfaceFormat format = ctx.format();
    if (format.majorVersion() < 2)
        QSKIP("This test requires at least OpenGL 2.0");
    ctx.makeCurrent(surface.data());

    QImage image(128, 128, 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(128, 128);
    fbo.bind();

    QOpenGLPaintDevice device(128, 128);
    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();

    QCOMPARE(image, fbo.toImage().convertToFormat(QImage::Format_RGB32));

    p.begin(&device);
    p.fillRect(0, 0, image.width(), image.height(), Qt::black);
    p.drawImage(0, 0, image);
    p.end();

    QCOMPARE(image, fbo.toImage().convertToFormat(QImage::Format_RGB32));

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

    QCOMPARE(image, fbo.toImage().convertToFormat(QImage::Format_RGB32));
}
Example #5
0
GraphicsSurfaceToken ImageBufferDataPrivateAccelerated::graphicsSurfaceToken() const
{
    if (!m_graphicsSurface) {
        QOpenGLContext *previousContext = QOpenGLContext::currentContext();
        GLSharedContext::makeCurrent();

        m_graphicsSurface = GraphicsSurface::create(m_fbo->size(), graphicsSurfaceFlags(), QOpenGLContext::currentContext());

        previousContext->makeCurrent(previousContext->surface());
    }

    return m_graphicsSurface->exportToken();
}
Example #6
0
uint32_t ImageBufferDataPrivateAccelerated::copyToGraphicsSurface()
{
    QOpenGLContext *previousContext = QOpenGLContext::currentContext();
    GLSharedContext::makeCurrent();
    if (!m_graphicsSurface) {
        m_graphicsSurface = GraphicsSurface::create(m_fbo->size(), graphicsSurfaceFlags(), QOpenGLContext::currentContext());
    }

    commitChanges();
    m_graphicsSurface->copyFromTexture(m_fbo->texture(), IntRect(IntPoint(), m_fbo->size()));
    previousContext->makeCurrent(previousContext->surface());
    return m_graphicsSurface->frontBuffer();
}
Example #7
0
void ImageBufferDataPrivateAccelerated::paintToTextureMapper(TextureMapper* textureMapper, const FloatRect& targetRect, const TransformationMatrix& matrix, float opacity)
{
    if (textureMapper->accelerationMode() != TextureMapper::OpenGLMode) {
        return;
    }

    QOpenGLContext *previousContext = QOpenGLContext::currentContext();
    GLSharedContext::makeCurrent();
    commitChanges();
    previousContext->makeCurrent(previousContext->surface());

    static_cast<TextureMapperGL*>(textureMapper)->drawTexture(m_fbo->texture(), TextureMapperGL::ShouldFlipTexture | TextureMapperGL::ShouldBlend, m_fbo->size(), targetRect, matrix, opacity);

}
Example #8
0
bool RenderableWebEntityItem::buildWebSurface(EntityTreeRenderer* renderer) {
    if (_currentWebCount >= MAX_CONCURRENT_WEB_VIEWS) {
        qWarning() << "Too many concurrent web views to create new view";
        return false;
    }
    qDebug() << "Building web surface";

    ++_currentWebCount;
    // Save the original GL context, because creating a QML surface will create a new context
    QOpenGLContext * currentContext = QOpenGLContext::currentContext();
    QSurface * currentSurface = currentContext->surface();
    _webSurface = new OffscreenQmlSurface();
    _webSurface->create(currentContext);
    _webSurface->setBaseUrl(QUrl::fromLocalFile(PathUtils::resourcesPath() + "/qml/controls/"));
    _webSurface->load("WebView.qml");
    _webSurface->resume();
    _webSurface->getRootItem()->setProperty("url", _sourceUrl);
    _webSurface->getRootContext()->setContextProperty("desktop", QVariant());
    _connection = QObject::connect(_webSurface, &OffscreenQmlSurface::textureUpdated, [&](GLuint textureId) {
        _texture = textureId;
    });
    // Restore the original GL context
    currentContext->makeCurrent(currentSurface);

    auto forwardPointerEvent = [=](const EntityItemID& entityItemID, const PointerEvent& event) {
        if (entityItemID == getID()) {
            handlePointerEvent(event);
        }
    };
    _mousePressConnection = QObject::connect(renderer, &EntityTreeRenderer::mousePressOnEntity, forwardPointerEvent);
    _mouseReleaseConnection = QObject::connect(renderer, &EntityTreeRenderer::mouseReleaseOnEntity, forwardPointerEvent);
    _mouseMoveConnection = QObject::connect(renderer, &EntityTreeRenderer::mouseMoveOnEntity, forwardPointerEvent);
    _hoverLeaveConnection = QObject::connect(renderer, &EntityTreeRenderer::hoverLeaveEntity, [=](const EntityItemID& entityItemID, const PointerEvent& event) {
        if (this->_pressed && this->getID() == entityItemID) {
            // If the user mouses off the entity while the button is down, simulate a touch end.
            QTouchEvent::TouchPoint point;
            point.setId(event.getID());
            point.setState(Qt::TouchPointReleased);
            glm::vec2 windowPos = event.getPos2D() * (METERS_TO_INCHES * _dpi);
            QPointF windowPoint(windowPos.x, windowPos.y);
            point.setPos(windowPoint);
            QList<QTouchEvent::TouchPoint> touchPoints;
            touchPoints.push_back(point);
            QTouchEvent* touchEvent = new QTouchEvent(QEvent::TouchEnd, nullptr, Qt::NoModifier, Qt::TouchPointReleased, touchPoints);
            QCoreApplication::postEvent(_webSurface->getWindow(), touchEvent);
        }
    });
    return true;
}
Example #9
0
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;
}
Example #10
0
void
WebView::CreateGLContext() {
  QOpenGLContext* context = window_->GLContext();
  context->makeCurrent(window_);

  static bool firstClearDone = false;
  if (!firstClearDone) {
    QOpenGLFunctions* functions = context->functions();
    Q_ASSERT(functions);
    functions->glClearColor(1.0, 1.0, 1.0, 0.0);
    functions->glClear(GL_COLOR_BUFFER_BIT);
    context->swapBuffers(window_);
    firstClearDone = true;
  }
}
Example #11
0
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();
}
Example #12
0
void TestWindow::draw() {
    if (_aboutToQuit) {
        return;
    }

    // Attempting to draw before we're visible and have a valid size will
    // produce GL errors.
    if (!isVisible() || _size.width() <= 0 || _size.height() <= 0) {
        return;
    }

    static std::once_flag once;
    std::call_once(once, [&] { initGl(); });

    if (!_glContext.makeCurrent(this)) {
        return;
    }

    updateSurfaces();

    auto size = this->geometry().size();
    auto incrementX = size.width() / DIVISIONS_X;
    auto incrementY = size.height() / DIVISIONS_Y;
    _glf.glViewport(0, 0, size.width(), size.height());
    _glf.glClearColor(1, 0, 0, 1);
    _glf.glClear(GL_COLOR_BUFFER_BIT);
    for (uint32_t x = 0; x < DIVISIONS_X; ++x) {
        for (uint32_t y = 0; y < DIVISIONS_Y; ++y) {
            auto& qmlInfo = _surfaces[x][y];
            if (!qmlInfo.surface || !qmlInfo.texture) {
                continue;
            }
            _glf.glBindFramebuffer(GL_READ_FRAMEBUFFER, _fbo);
            _glf.glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, qmlInfo.texture, 0);
            _glf.glBlitFramebuffer(
                // src coordinates
                0, 0, _qmlSize.width() - 1, _qmlSize.height() - 1,
                // dst coordinates
                incrementX * x, incrementY * y, incrementX * (x + 1), incrementY * (y + 1),
                // blit mask and filter
                GL_COLOR_BUFFER_BIT, GL_NEAREST);
        }
    }
    _glf.glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0, 0);
    _glf.glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);
    _glContext.swapBuffers(this);
}
// 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);
}
Example #14
0
void Web3DOverlay::render(RenderArgs* args) {
    if (!_visible || !getParentVisible()) {
        return;
    }

    QOpenGLContext * currentContext = QOpenGLContext::currentContext();
    QSurface * currentSurface = currentContext->surface();
    if (!_webSurface) {
        _webSurface = new OffscreenQmlSurface();
        _webSurface->create(currentContext);
        _webSurface->setBaseUrl(QUrl::fromLocalFile(PathUtils::resourcesPath() + "/qml/"));
        _webSurface->load("WebEntity.qml");
        _webSurface->resume();
        _webSurface->getRootItem()->setProperty("url", _url);
        _webSurface->resize(QSize(_resolution.x, _resolution.y));
        _connection = QObject::connect(_webSurface, &OffscreenQmlSurface::textureUpdated, [&](GLuint textureId) {
            _texture = textureId;
        });
        currentContext->makeCurrent(currentSurface);
    }

    vec2 size = _resolution / _dpi * INCHES_TO_METERS;
    vec2 halfSize = size / 2.0f;
    vec4 color(toGlm(getColor()), getAlpha());

    applyTransformTo(_transform, true);
    Transform transform = _transform;
    if (glm::length2(getDimensions()) != 1.0f) {
        transform.postScale(vec3(getDimensions(), 1.0f));
    }

    Q_ASSERT(args->_batch);
    gpu::Batch& batch = *args->_batch;
    if (_texture) {
        batch._glActiveBindTexture(GL_TEXTURE0, GL_TEXTURE_2D, _texture);
    } else {
        batch.setResourceTexture(0, DependencyManager::get<TextureCache>()->getWhiteTexture());
    }

    batch.setModelTransform(transform);
    DependencyManager::get<DeferredLightingEffect>()->bindSimpleProgram(batch, true, false, false, true);
    DependencyManager::get<GeometryCache>()->renderQuad(batch, halfSize * -1.0f, halfSize, vec2(0), vec2(1), color);
    batch.setResourceTexture(0, args->_whiteTexture); // restore default white color after me
}
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;
}
Example #18
0
void ImageBufferDataPrivateAccelerated::draw(GraphicsContext* destContext, ColorSpace styleColorSpace, const FloatRect& destRect,
                                             const FloatRect& srcRect, CompositeOperator op, BlendMode blendMode,
                                             bool useLowQualityScale, bool ownContext)
{
    if (destContext->isAcceleratedContext()) {
        QOpenGLContext *previousContext = QOpenGLContext::currentContext();
        GLSharedContext::makeCurrent();
        commitChanges();
        previousContext->makeCurrent(previousContext->surface());

        QOpenGL2PaintEngineEx* acceleratedPaintEngine = static_cast<QOpenGL2PaintEngineEx*>(destContext->platformContext()->paintEngine());
        FloatRect flippedSrc = srcRect;
        flippedSrc.setY(m_fbo->size().height() - flippedSrc.height() - flippedSrc.y());
        acceleratedPaintEngine->drawTexture(destRect, m_fbo->texture(), m_fbo->size(), flippedSrc);
    } else {
        RefPtr<Image> image = StillImage::create(QPixmap::fromImage(toQImage()));
        destContext->drawImage(image.get(), styleColorSpace, destRect, srcRect, op, blendMode,
                               DoNotRespectImageOrientation, useLowQualityScale);
    }
}
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);
}
Example #20
0
QImage QFramebufferPaintDevice::toImage() const
{
    QOpenGLContext* currentContext = QOpenGLContext::currentContext();
    QSurface* currentSurface = currentContext ? currentContext->surface() : 0;

    context()->makeCurrent(m_surface);

#if QT_VERSION >= QT_VERSION_CHECK(5, 4, 0)
    QImage image = m_framebufferObject.toImage(false);
#else
    QImage image = m_framebufferObject.toImage();
#endif

    if (currentContext)
        currentContext->makeCurrent(currentSurface);
    else
        context()->doneCurrent();

    return image;
}
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();
}
Example #23
0
bool RenderableWebEntityItem::buildWebSurface(EntityTreeRenderer* renderer) {
    if (_currentWebCount >= MAX_CONCURRENT_WEB_VIEWS) {
        qWarning() << "Too many concurrent web views to create new view";
        return false;
    }
    qDebug() << "Building web surface";

    ++_currentWebCount;
    // Save the original GL context, because creating a QML surface will create a new context
    QOpenGLContext * currentContext = QOpenGLContext::currentContext();
    QSurface * currentSurface = currentContext->surface();
    _webSurface = new OffscreenQmlSurface();
    _webSurface->create(currentContext);
    _webSurface->setBaseUrl(QUrl::fromLocalFile(PathUtils::resourcesPath() + "/qml/"));
    _webSurface->load("WebEntity.qml");
    _webSurface->resume();
    _webSurface->getRootItem()->setProperty("url", _sourceUrl);
    _connection = QObject::connect(_webSurface, &OffscreenQmlSurface::textureUpdated, [&](GLuint textureId) {
        _texture = textureId;
    });
    // Restore the original GL context
    currentContext->makeCurrent(currentSurface);

    auto forwardMouseEvent = [=](const RayToEntityIntersectionResult& intersection, const QMouseEvent* event) {
        // Ignore mouse interaction if we're locked
        if (this->getLocked()) {
            return;
        }

        if (event->button() == Qt::MouseButton::RightButton) {
            if (event->type() == QEvent::MouseButtonPress) {
                const QMouseEvent* mouseEvent = static_cast<const QMouseEvent*>(event);
                _lastPress = toGlm(mouseEvent->pos());
            }
        }

        if (intersection.entityID == getID()) {
            if (event->button() == Qt::MouseButton::RightButton) {
                if (event->type() == QEvent::MouseButtonRelease) {
                    const QMouseEvent* mouseEvent = static_cast<const QMouseEvent*>(event);
                    ivec2 dist = glm::abs(toGlm(mouseEvent->pos()) - _lastPress);
                    if (!glm::any(glm::greaterThan(dist, ivec2(1)))) {
                        AbstractViewStateInterface::instance()->postLambdaEvent([this] {
                            QMetaObject::invokeMethod(_webSurface->getRootItem(), "goBack");
                        });
                    }
                    _lastPress = ivec2(INT_MIN);
                }
                return;
            }

            // FIXME doesn't work... double click events not received
            if (event->type() == QEvent::MouseButtonDblClick) {
                AbstractViewStateInterface::instance()->postLambdaEvent([this] {
                    _webSurface->getRootItem()->setProperty("url", _sourceUrl);
                });
            }

            if (event->button() == Qt::MouseButton::MiddleButton) {
                if (event->type() == QEvent::MouseButtonRelease) {
                    AbstractViewStateInterface::instance()->postLambdaEvent([this] {
                        _webSurface->getRootItem()->setProperty("url", _sourceUrl);
                    });
                }
                return;
            }

            // Map the intersection point to an actual offscreen pixel
            glm::vec3 point = intersection.intersection;
            glm::vec3 dimensions = getDimensions();
            point -= getPosition();
            point = glm::inverse(getRotation()) * point;
            point /= dimensions;
            point += 0.5f;
            point.y = 1.0f - point.y;
            point *= dimensions * (METERS_TO_INCHES * DPI);

            if (event->button() == Qt::MouseButton::LeftButton) {
                if (event->type() == QEvent::MouseButtonPress) {
                    this->_pressed = true;
                    this->_lastMove = ivec2((int)point.x, (int)point.y);
                } else if (event->type() == QEvent::MouseButtonRelease) {
                    this->_pressed = false;
                }
            }
            if (event->type() == QEvent::MouseMove) {
                this->_lastMove = ivec2((int)point.x, (int)point.y);
            }

            // Forward the mouse event.  
            QMouseEvent mappedEvent(event->type(),
                QPoint((int)point.x, (int)point.y),
                event->screenPos(), event->button(),
                event->buttons(), event->modifiers());
            QCoreApplication::sendEvent(_webSurface->getWindow(), &mappedEvent);
        }
    };
    _mousePressConnection = QObject::connect(renderer, &EntityTreeRenderer::mousePressOnEntity, forwardMouseEvent);
    _mouseReleaseConnection = QObject::connect(renderer, &EntityTreeRenderer::mouseReleaseOnEntity, forwardMouseEvent);
    _mouseMoveConnection = QObject::connect(renderer, &EntityTreeRenderer::mouseMoveOnEntity, forwardMouseEvent);
    _hoverLeaveConnection = QObject::connect(renderer, &EntityTreeRenderer::hoverLeaveEntity, [=](const EntityItemID& entityItemID, const MouseEvent& event) {
        if (this->_pressed && this->getID() == entityItemID) {
            // If the user mouses off the entity while the button is down, simulate a mouse release
            QMouseEvent mappedEvent(QEvent::MouseButtonRelease,
                QPoint(_lastMove.x, _lastMove.y),
                Qt::MouseButton::LeftButton,
                Qt::MouseButtons(), Qt::KeyboardModifiers());
            QCoreApplication::sendEvent(_webSurface->getWindow(), &mappedEvent);
        }
    });
    return true;
}
Example #24
0
void Web3DOverlay::render(RenderArgs* args) {
    QOpenGLContext * currentContext = QOpenGLContext::currentContext();
    QSurface * currentSurface = currentContext->surface();
    if (!_webSurface) {
        _webSurface = DependencyManager::get<OffscreenQmlSurfaceCache>()->acquire(pickURL());
        // FIXME, the max FPS could be better managed by being dynamic (based on the number of current surfaces
        // and the current rendering load)
        if (_currentMaxFPS != _desiredMaxFPS) {
            setMaxFPS(_desiredMaxFPS);
        }
        loadSourceURL();
        _webSurface->resume();
        _webSurface->resize(QSize(_resolution.x, _resolution.y));
        _webSurface->getRootItem()->setProperty("url", _url);
        _webSurface->getRootItem()->setProperty("scriptURL", _scriptURL);
        currentContext->makeCurrent(currentSurface);

        auto selfOverlayID = getOverlayID();
        std::weak_ptr<Web3DOverlay> weakSelf = std::dynamic_pointer_cast<Web3DOverlay>(qApp->getOverlays().getOverlay(selfOverlayID));
        auto forwardPointerEvent = [=](OverlayID overlayID, const PointerEvent& event) {
            auto self = weakSelf.lock();
            if (self && overlayID == selfOverlayID) {
                self->handlePointerEvent(event);
            }
        };

        auto overlays = &(qApp->getOverlays());
        QObject::connect(overlays, &Overlays::mousePressOnOverlay, this, forwardPointerEvent);
        QObject::connect(overlays, &Overlays::mouseReleaseOnOverlay, this, forwardPointerEvent);
        QObject::connect(overlays, &Overlays::mouseMoveOnOverlay, this, forwardPointerEvent);
        QObject::connect(overlays, &Overlays::hoverLeaveOverlay, this, [=](OverlayID overlayID, const PointerEvent& event) {
            auto self = weakSelf.lock();
            if (!self) {
                return;
            }
            if (overlayID == selfOverlayID && (self->_pressed || (!self->_activeTouchPoints.empty() && self->_touchBeginAccepted))) {
                PointerEvent endEvent(PointerEvent::Release, event.getID(), event.getPos2D(), event.getPos3D(), event.getNormal(), event.getDirection(),
                                      event.getButton(), event.getButtons(), event.getKeyboardModifiers());
                forwardPointerEvent(overlayID, endEvent);
            }
        });

        QObject::connect(this, &Web3DOverlay::scriptEventReceived, _webSurface.data(), &OffscreenQmlSurface::emitScriptEvent);
        QObject::connect(_webSurface.data(), &OffscreenQmlSurface::webEventReceived, this, &Web3DOverlay::webEventReceived);
    } else {
        if (_currentMaxFPS != _desiredMaxFPS) {
            setMaxFPS(_desiredMaxFPS);
        }
    }

    if (_mayNeedResize) {
        _mayNeedResize = false;
        _webSurface->resize(QSize(_resolution.x, _resolution.y));
    }

    if (!_visible || !getParentVisible()) {
        return;
    }

    vec2 halfSize = getSize() / 2.0f;
    vec4 color(toGlm(getColor()), getAlpha());

    Transform transform = getTransform();

    // FIXME: applyTransformTo causes tablet overlay to detach from tablet entity.
    // Perhaps rather than deleting the following code it should be run only if isFacingAvatar() is true?
    /*
    applyTransformTo(transform, true);
    setTransform(transform);
    */

    if (glm::length2(getDimensions()) != 1.0f) {
        transform.postScale(vec3(getDimensions(), 1.0f));
    }

    if (!_texture) {
        auto webSurface = _webSurface;
        _texture = gpu::Texture::createExternal(OffscreenQmlSurface::getDiscardLambda());
        _texture->setSource(__FUNCTION__);
    }
    OffscreenQmlSurface::TextureAndFence newTextureAndFence;
    bool newTextureAvailable = _webSurface->fetchTexture(newTextureAndFence);
    if (newTextureAvailable) {
        _texture->setExternalTexture(newTextureAndFence.first, newTextureAndFence.second);
    }

    Q_ASSERT(args->_batch);
    gpu::Batch& batch = *args->_batch;
    batch.setResourceTexture(0, _texture);
    batch.setModelTransform(transform);
    auto geometryCache = DependencyManager::get<GeometryCache>();
    if (color.a < OPAQUE_ALPHA_THRESHOLD) {
        geometryCache->bindTransparentWebBrowserProgram(batch, _isAA);
    } else {
        geometryCache->bindOpaqueWebBrowserProgram(batch, _isAA);
    }
    geometryCache->renderQuad(batch, halfSize * -1.0f, halfSize, vec2(0), vec2(1), color, _geometryId);
    batch.setResourceTexture(0, nullptr); // restore default white color after me
}
Example #25
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();
}
void RenderableWebEntityItem::render(RenderArgs* args) {
    QOpenGLContext * currentContext = QOpenGLContext::currentContext();
    QSurface * currentSurface = currentContext->surface();
    if (!_webSurface) {
        _webSurface = new OffscreenQmlSurface();
        _webSurface->create(currentContext);
        _webSurface->setBaseUrl(QUrl::fromLocalFile(PathUtils::resourcesPath() + "/qml/"));
        _webSurface->load("WebEntity.qml");
        _webSurface->resume();
        _webSurface->getRootItem()->setProperty("url", _sourceUrl);
        _connection = QObject::connect(_webSurface, &OffscreenQmlSurface::textureUpdated, [&](GLuint textureId) {
            _webSurface->lockTexture(textureId);
            assert(!glGetError());
            // TODO change to atomic<GLuint>?
            withLock(_textureLock, [&] {
                std::swap(_texture, textureId);
            });
            if (textureId) {
                _webSurface->releaseTexture(textureId);
            }
            if (_texture) {
                _webSurface->makeCurrent();
                glBindTexture(GL_TEXTURE_2D, _texture);
                glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
                glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
                glBindTexture(GL_TEXTURE_2D, 0);
                _webSurface->doneCurrent();
            }
        });

        auto forwardMouseEvent = [=](const RayToEntityIntersectionResult& intersection, const QMouseEvent* event, unsigned int deviceId) {
            // Ignore mouse interaction if we're locked
            if (this->getLocked()) {
                return;
            }

            if (event->button() == Qt::MouseButton::RightButton) {
                if (event->type() == QEvent::MouseButtonPress) {
                    const QMouseEvent* mouseEvent = static_cast<const QMouseEvent*>(event);
                    _lastPress = toGlm(mouseEvent->pos());
                }
            }

            if (intersection.entityID == getID()) {
                if (event->button() == Qt::MouseButton::RightButton) {
                    if (event->type() == QEvent::MouseButtonRelease) {
                        const QMouseEvent* mouseEvent = static_cast<const QMouseEvent*>(event);
                        ivec2 dist = glm::abs(toGlm(mouseEvent->pos()) - _lastPress);
                        if (!glm::any(glm::greaterThan(dist, ivec2(1)))) {
                            AbstractViewStateInterface::instance()->postLambdaEvent([this] {
                                QMetaObject::invokeMethod(_webSurface->getRootItem(), "goBack");
                            });
                        }
                        _lastPress = ivec2(INT_MIN);
                    }
                    return;
                }

                // FIXME doesn't work... double click events not received
                if (event->type() == QEvent::MouseButtonDblClick) {
                    AbstractViewStateInterface::instance()->postLambdaEvent([this] {
                        _webSurface->getRootItem()->setProperty("url", _sourceUrl);
                    });
                }

                if (event->button() == Qt::MouseButton::MiddleButton) {
                    if (event->type() == QEvent::MouseButtonRelease) {
                        AbstractViewStateInterface::instance()->postLambdaEvent([this] {
                            _webSurface->getRootItem()->setProperty("url", _sourceUrl);
                        });
                    }
                    return;
                }

                // Map the intersection point to an actual offscreen pixel
                glm::vec3 point = intersection.intersection;
                point -= getPosition();
                point = glm::inverse(getRotation()) * point;
                point /= getDimensions();
                point += 0.5f;
                point.y = 1.0f - point.y;
                point *= getDimensions() * METERS_TO_INCHES * DPI;
                // Forward the mouse event.  
                QMouseEvent mappedEvent(event->type(),
                    QPoint((int)point.x, (int)point.y),
                    event->screenPos(), event->button(),
                    event->buttons(), event->modifiers());
                QCoreApplication::sendEvent(_webSurface->getWindow(), &mappedEvent);
            }
        };

        EntityTreeRenderer* renderer = static_cast<EntityTreeRenderer*>(args->_renderer);
        QObject::connect(renderer, &EntityTreeRenderer::mousePressOnEntity, forwardMouseEvent);
        QObject::connect(renderer, &EntityTreeRenderer::mouseReleaseOnEntity, forwardMouseEvent);
        QObject::connect(renderer, &EntityTreeRenderer::mouseMoveOnEntity, forwardMouseEvent);
    }

    glm::vec2 dims = glm::vec2(getDimensions());
    dims *= METERS_TO_INCHES * DPI;
    // The offscreen surface is idempotent for resizes (bails early
    // if it's a no-op), so it's safe to just call resize every frame 
    // without worrying about excessive overhead.
    _webSurface->resize(QSize(dims.x, dims.y));
    currentContext->makeCurrent(currentSurface);

    PerformanceTimer perfTimer("RenderableWebEntityItem::render");
    Q_ASSERT(getType() == EntityTypes::Web);
    static const glm::vec2 texMin(0.0f), texMax(1.0f), topLeft(-0.5f), bottomRight(0.5f);

    Q_ASSERT(args->_batch);
    gpu::Batch& batch = *args->_batch;
    batch.setModelTransform(getTransformToCenter());
    bool textured = false, culled = false, emissive = false;
    if (_texture) {
        batch._glActiveBindTexture(GL_TEXTURE0, GL_TEXTURE_2D, _texture);
        textured = emissive = true;
    }
    
    DependencyManager::get<DeferredLightingEffect>()->bindSimpleProgram(batch, textured, culled, emissive);
    DependencyManager::get<GeometryCache>()->renderQuad(batch, topLeft, bottomRight, texMin, texMax, glm::vec4(1.0f));
}
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);
}
Example #28
0
void OculusWin32DisplayPlugin::preRender() {
    ovr_GetEyePoses(_hmd, 0, _eyeOffsets, _eyePoses, nullptr);
    bool result = _context->makeCurrent(_window);
    Q_ASSERT(result);
}
Example #29
0
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);
}
Example #30
0
 void makeCurrent()
 {
     QOpenGLContext* glContext = QOpenGLContext::currentContext();
     if (m_surface && glContext)
         glContext->makeCurrent(m_surface.get());
 }