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