void GlMetaNodeRenderer::render(node n, float, Camera *camera) { bool viewMeta = _inputData->renderingParameters() ->isDisplayMetaNodes(); // Checks if user wants to see metanode content bool viewMetaLabels = _inputData->renderingParameters() ->isViewMetaLabel(); // Checks if user wants to see metanode content labels if (!viewMeta && !viewMetaLabels) { return; } GLint renderMode; glGetIntegerv(GL_RENDER_MODE, &renderMode); if (renderMode == GL_SELECT) return; Graph *metaGraph = _inputData->getGraph()->getNodeMetaInfo(n); GlScene *scene = nullptr; if (_metaGraphToSceneMap.count(metaGraph) != 0) { scene = _metaGraphToSceneMap[metaGraph]; } else { scene = createScene(metaGraph); assert(scene != nullptr); _metaGraphToSceneMap[metaGraph] = scene; metaGraph->addListener(this); } scene->getGlGraphComposite()->setRenderingParameters(*(_inputData->renderingParameters())); int metaStencil = _inputData->renderingParameters()->getMetaNodesStencil(); int metaSelectedStencil = _inputData->renderingParameters()->getSelectedMetaNodesStencil(); int metaLabelStencil = _inputData->renderingParameters()->getMetaNodesLabelStencil(); scene->getGlGraphComposite()->getRenderingParametersPointer()->setDisplayNodes(viewMeta); scene->getGlGraphComposite()->getRenderingParametersPointer()->setDisplayEdges(viewMeta); scene->getGlGraphComposite()->getRenderingParametersPointer()->setViewEdgeLabel(viewMetaLabels); scene->getGlGraphComposite()->getRenderingParametersPointer()->setViewNodeLabel(viewMetaLabels); scene->getGlGraphComposite()->getRenderingParametersPointer()->setNodesStencil(metaStencil); scene->getGlGraphComposite()->getRenderingParametersPointer()->setEdgesStencil(metaStencil); scene->getGlGraphComposite()->getRenderingParametersPointer()->setSelectedNodesStencil( metaSelectedStencil); scene->getGlGraphComposite()->getRenderingParametersPointer()->setSelectedEdgesStencil( metaSelectedStencil); scene->getGlGraphComposite()->getRenderingParametersPointer()->setNodesLabelStencil( metaLabelStencil); scene->getGlGraphComposite()->getRenderingParametersPointer()->setEdgesLabelStencil( metaLabelStencil); GlNode glNode(n.id); BoundingBox includeBB; _inputData->glyphs.get(_inputData->getElementShape()->getNodeValue(n)) ->getIncludeBoundingBox(includeBB, n); BoundingBox &&bbTmp = glNode.getBoundingBox(_inputData); BoundingBox bb(bbTmp.center() - Coord((bbTmp.width() / 2.f) * (includeBB[0][0] * -2.f), (bbTmp.height() / 2.f) * (includeBB[0][1] * -2.f), (bbTmp.depth() / 2.f) * (includeBB[0][2] * -2.f)), bbTmp.center() + Coord((bbTmp.width() / 2.f) * (includeBB[1][0] * 2.f), (bbTmp.height() / 2.f) * (includeBB[1][1] * 2.f), (bbTmp.depth() / 2.f) * (includeBB[1][2] * 2.f))); Coord eyeDirection = camera->getEyes() - camera->getCenter(); eyeDirection = eyeDirection / eyeDirection.norm(); Camera newCamera2(*camera); newCamera2.setEyes(newCamera2.getCenter() + Coord(0, 0, 1) * (newCamera2.getEyes() - newCamera2.getCenter()).norm()); newCamera2.setUp(Coord(0, 1, 0)); Coord center = camera->worldTo2DViewport((bb[0] + bb[1]) / 2.f); Coord &&first = newCamera2.worldTo2DViewport(bb[0]); Coord &&second = newCamera2.worldTo2DViewport(bb[1]); Coord &&size = second - first; Vector<int, 4> viewport; viewport[0] = center[0] - size[0] / 2; viewport[1] = center[1] - size[1] / 2; viewport[2] = size[0]; viewport[3] = size[1]; viewport[0] = camera->getViewport()[0] + viewport[0] - viewport[2] / 2; viewport[1] = camera->getViewport()[1] + viewport[1] - viewport[3] / 2; viewport[2] *= 2; viewport[3] *= 2; if (viewport[2] == 0 || viewport[3] == 0) return; scene->setViewport(viewport[0], viewport[1], viewport[2], viewport[3]); scene->setClearBufferAtDraw(false); scene->setClearDepthBufferAtDraw(false); scene->setClearStencilBufferAtDraw(false); scene->centerScene(); float baseNorm = (scene->getGraphLayer()->getCamera().getEyes() - scene->getGraphLayer()->getCamera().getCenter()) .norm(); Camera newCamera = scene->getGraphLayer()->getCamera(); Camera *oldCamera = new Camera(scene, true); newCamera.setScene(scene); *oldCamera = newCamera; newCamera.setUp(camera->getUp()); newCamera.setEyes(newCamera.getCenter() + (eyeDirection * baseNorm)); newCamera.setZoomFactor(newCamera.getZoomFactor() * 0.5); scene->getGraphLayer()->setSharedCamera(&newCamera); // small hack to avoid z-fighting between the rendering of the metanode content // and the rendering of the metanode that occurs afterwards glDepthRange(0.1, 1); scene->draw(); // restore default depth range glDepthRange(0, 1); scene->getGraphLayer()->setCamera(oldCamera); camera->getScene()->setClearBufferAtDraw(false); camera->getScene()->setClearDepthBufferAtDraw(false); camera->getScene()->setClearStencilBufferAtDraw(false); camera->getScene()->initGlParameters(); camera->getScene()->setClearBufferAtDraw(true); camera->getScene()->setClearDepthBufferAtDraw(true); camera->getScene()->setClearStencilBufferAtDraw(true); camera->initGl(); }
void MouseMagnifyingGlassInteractorComponent::generateMagnifyingGlassTexture(const Coord &magnifyingGlassCenterScr) { bool antialiased = false; bool canUseMultisampleFbo = OpenGlConfigManager::getInst().isExtensionSupported("GL_EXT_framebuffer_multisample"); if (QGLFramebufferObject::hasOpenGLFramebufferBlit() && canUseMultisampleFbo) { antialiased = true; } int fboSize = static_cast<int>(radius * 2); // instantiate fbo if needed if (fbo == NULL) { QGLFramebufferObjectFormat fboFormat; fboFormat.setAttachment(QGLFramebufferObject::CombinedDepthStencil); if (antialiased) { fboFormat.setSamples(OpenGlConfigManager::getInst().maxNumberOfSamples()); } fbo = new QGLFramebufferObject(fboSize, fboSize, fboFormat); if (antialiased) { fbo2 = new QGLFramebufferObject(fboSize, fboSize); } if (!antialiased) { GlTextureManager::getInst().registerExternalTexture(textureName, fbo->texture()); } else { GlTextureManager::getInst().registerExternalTexture(textureName, fbo2->texture()); } } Vector<int, 4> viewport = glWidget->getScene()->getViewport(); // get the magnifying glass bounding box in screen space BoundingBox boundingBox; boundingBox[0] = Coord(magnifyingGlassCenterScr.getX() - radius, magnifyingGlassCenterScr.getY() - radius); boundingBox[1] = Coord(magnifyingGlassCenterScr.getX() + radius, magnifyingGlassCenterScr.getY() + radius); // compute the zoom factor to apply to scene's camera to get the area under the magnifying glass displayed entirely in the viewport float bbWidthScreen = boundingBox[1][0] - boundingBox[0][0]; float bbHeightScreen = boundingBox[1][1] - boundingBox[0][1]; float startSize = glWidget->screenToViewport(min(glWidget->width(), glWidget->height())); float endSize = max(bbHeightScreen, bbWidthScreen); float zoomFactor = startSize / endSize; // backup current camera parameters float sceneRadiusBak = camera->getSceneRadius(); float zoomFactorBak = camera->getZoomFactor(); Coord eyesBak = camera->getEyes(); Coord centerBak = camera->getCenter(); Coord upBak = camera->getUp(); Coord move = boxCenter - centerBak; camera->setCenter(camera->getCenter() + move); camera->setEyes(camera->getEyes() + move); camera->setZoomFactor(magnifyPower * zoomFactor * zoomFactorBak); glPushAttrib(GL_ALL_ATTRIB_BITS); glMatrixMode(GL_PROJECTION); glPushMatrix(); glMatrixMode(GL_MODELVIEW); glPushMatrix(); // resize the viewport to the size of fbo and render the scene into this last one GlScene *scene = glWidget->getScene(); scene->setViewport(0, 0, fboSize, fboSize); fbo->bind(); Color color = scene->getBackgroundColor(); glClearColor(color.getRGL(), color.getGGL(), color.getBGL(), color.getAGL()); glClear(GL_COLOR_BUFFER_BIT); scene->draw(); fbo->release(); if (antialiased) { QGLFramebufferObject::blitFramebuffer(fbo2, QRect(0,0,fboSize, fboSize), fbo, QRect(0,0,fboSize, fboSize)); } // restore original camera parameters scene->setViewport(viewport[0], viewport[1], viewport[2], viewport[3]); camera->setSceneRadius(sceneRadiusBak); camera->setZoomFactor(zoomFactorBak); camera->setEyes(eyesBak); camera->setCenter(centerBak); camera->setUp(upBak); glMatrixMode(GL_MODELVIEW); glPopMatrix(); glMatrixMode(GL_PROJECTION); glPopMatrix(); glPopAttrib(); // need to call this explicitely otherwise we have to redraw the scene glViewport(viewport[0], viewport[1], viewport[2], viewport[3]); }