X-Git-Url: https://git.mxchange.org/?a=blobdiff_plain;f=src%2FMain%2FCameraGroup.cxx;h=e80e0c564bbc1cf61b5520055aa9cea426ea96a2;hb=38226af24ec01e8f0a20d7fd73ef838a69f6ef25;hp=954a591e55d0c41ad761b2772d557aec8eda639b;hpb=e653ed4598dfcfea634470d16b49b97fc87e1840;p=flightgear.git diff --git a/src/Main/CameraGroup.cxx b/src/Main/CameraGroup.cxx index 954a591e5..e80e0c564 100644 --- a/src/Main/CameraGroup.cxx +++ b/src/Main/CameraGroup.cxx @@ -35,10 +35,15 @@ #include #include +#include #include +#include #include #include +#include +#include #include +#include #include #include @@ -148,7 +153,18 @@ CameraInfo* CameraGroup::addCamera(unsigned flags, Camera* camera, // resized; if the the viewport isn't copied here, it gets updated // twice and ends up with the wrong value. farCamera->setViewport(simgear::clone(camera->getViewport())); - _viewer->addSlave(farCamera, view, projection, useMasterSceneData); + farCamera->setDrawBuffer(camera->getDrawBuffer()); + farCamera->setReadBuffer(camera->getReadBuffer()); + farCamera->setRenderTargetImplementation( + camera->getRenderTargetImplementation()); + const Camera::BufferAttachmentMap& bufferMap + = camera->getBufferAttachmentMap(); + if (bufferMap.count(Camera::COLOR_BUFFER) != 0) { + farCamera->attach( + Camera::COLOR_BUFFER, + bufferMap.find(Camera::COLOR_BUFFER)->second._texture.get()); + } + _viewer->addSlave(farCamera, projection, view, useMasterSceneData); installCullVisitor(farCamera); info->farCamera = farCamera; info->farSlaveIndex = _viewer->getNumSlaves() - 1; @@ -156,7 +172,7 @@ CameraInfo* CameraGroup::addCamera(unsigned flags, Camera* camera, camera->setCullMask(camera->getCullMask() & ~simgear::BACKGROUND_BIT); camera->setClearMask(GL_DEPTH_BUFFER_BIT); } - _viewer->addSlave(camera, view, projection, useMasterSceneData); + _viewer->addSlave(camera, projection, view, useMasterSceneData); installCullVisitor(camera); info->camera = camera; info->slaveIndex = _viewer->getNumSlaves() - 1; @@ -297,6 +313,199 @@ void buildViewport(flightgear::CameraInfo* info, SGPropertyNode* viewportNode, namespace flightgear { +// Mostly copied from osg's osgViewer/View.cpp + +static osg::Geometry* createParoramicSphericalDisplayDistortionMesh( + const Vec3& origin, const Vec3& widthVector, const Vec3& heightVector, + double sphere_radius, double collar_radius, + Image* intensityMap = 0, const Matrix& projectorMatrix = Matrix()) +{ + osg::Vec3d center(0.0,0.0,0.0); + osg::Vec3d eye(0.0,0.0,0.0); + + double distance = sqrt(sphere_radius*sphere_radius - collar_radius*collar_radius); + bool flip = false; + bool texcoord_flip = false; + + osg::Vec3d projector = eye - osg::Vec3d(0.0,0.0, distance); + +#if 0 + OSG_INFO<<"createParoramicSphericalDisplayDistortionMesh : Projector position = "<getStringValue(); + TextureMap::iterator itr = _textureTargets.find(texName); + if (itr == _textureTargets.end()) { + // error + return; + } + Viewport* viewport = camera->getViewport(); + float width = viewport->width(); + float height = viewport->height(); + TextureRectangle* texRect = itr->second.get(); + double radius = psNode->getDoubleValue("radius", 1.0); + double collar = psNode->getDoubleValue("collar", 0.45); + Geode* geode = new Geode(); + geode->addDrawable(createParoramicSphericalDisplayDistortionMesh( + Vec3(0.0f,0.0f,0.0f), Vec3(width,0.0f,0.0f), + Vec3(0.0f,height,0.0f), radius, collar)); + + // new we need to add the texture to the mesh, we do so by creating a + // StateSet to contain the Texture StateAttribute. + StateSet* stateset = geode->getOrCreateStateSet(); + stateset->setTextureAttributeAndModes(0, texRect, StateAttribute::ON); + stateset->setMode(GL_LIGHTING, StateAttribute::OFF); + + TexMat* texmat = new TexMat; + texmat->setScaleByTextureRectangleSize(true); + stateset->setTextureAttributeAndModes(0, texmat, osg::StateAttribute::ON); +#if 0 + if (!applyIntensityMapAsColours && intensityMap) + { + stateset->setTextureAttributeAndModes(1, new osg::Texture2D(intensityMap), osg::StateAttribute::ON); + } +#endif + // add subgraph to render + camera->addChild(geode); + camera->setClearMask(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT); + camera->setClearColor(osg::Vec4(0.0, 0.0, 0.0, 1.0)); + camera->setComputeNearFarMode(osg::CullSettings::DO_NOT_COMPUTE_NEAR_FAR); + camera->setCullingMode(osg::CullSettings::NO_CULLING); + camera->setName("DistortionCorrectionCamera"); +} + CameraInfo* CameraGroup::buildCamera(SGPropertyNode* cameraNode) { WindowBuilder *wBuild = WindowBuilder::getWindowBuilder(); @@ -390,13 +599,43 @@ CameraInfo* CameraGroup::buildCamera(SGPropertyNode* cameraNode) double sheary = cameraNode->getDoubleValue("shear-y", 0); pOff.makeTranslate(-shearx, -sheary, 0); } - CameraInfo* info = addCamera(cameraFlags, camera, pOff, vOff); + const SGPropertyNode* textureNode = cameraNode->getNode("texture"); + if (textureNode) { + string texName = textureNode->getStringValue("name"); + int tex_width = textureNode->getIntValue("width"); + int tex_height = textureNode->getIntValue("height"); + TextureRectangle* texture = new TextureRectangle; + + texture->setTextureSize(tex_width, tex_height); + texture->setInternalFormat(GL_RGB); + texture->setFilter(Texture::MIN_FILTER, Texture::LINEAR); + texture->setFilter(Texture::MAG_FILTER, Texture::LINEAR); + texture->setWrap(Texture::WRAP_S, Texture::CLAMP_TO_EDGE); + texture->setWrap(Texture::WRAP_T, Texture::CLAMP_TO_EDGE); + camera->setDrawBuffer(GL_FRONT); + camera->setReadBuffer(GL_FRONT); + camera->setRenderTargetImplementation(Camera::FRAME_BUFFER_OBJECT); + camera->attach(Camera::COLOR_BUFFER, texture); + _textureTargets[texName] = texture; + } else { + camera->setDrawBuffer(GL_BACK); + camera->setReadBuffer(GL_BACK); + } + const SGPropertyNode* psNode = cameraNode->getNode("panoramic-spherical"); + bool useMasterSceneGraph = !psNode; + CameraInfo* info = addCamera(cameraFlags, camera, vOff, pOff, + useMasterSceneGraph); // If a viewport isn't set on the camera, then it's hard to dig it // out of the SceneView objects in the viewer, and the coordinates // of mouse events are somewhat bizzare. SGPropertyNode* viewportNode = cameraNode->getNode("viewport", true); buildViewport(info, viewportNode, window->gc->getTraits()); updateCameras(info); + // Distortion camera needs the viewport which is created by addCamera(). + if (psNode) { + info->flags = info->flags | VIEW_ABSOLUTE; + buildDistortionCamera(psNode, camera); + } return info; } @@ -407,15 +646,16 @@ CameraInfo* CameraGroup::buildGUICamera(SGPropertyNode* cameraNode, const SGPropertyNode* windowNode = (cameraNode ? cameraNode->getNode("window") : 0); - if (!window) { - if (windowNode) { - // New style window declaration / definition - window = wBuild->buildWindow(windowNode); - - } else { - return 0; - } + if (!window && windowNode) { + // New style window declaration / definition + window = wBuild->buildWindow(windowNode); + } + + if (!window) { // buildWindow can fail + SG_LOG(SG_GENERAL, SG_WARN, "CameraGroup::buildGUICamera: failed to build a window"); + return NULL; } + Camera* camera = new Camera; camera->setAllowEventFocus(false); camera->setGraphicsContext(window->gc.get()); @@ -477,9 +717,15 @@ void CameraGroup::setCameraCullMasks(Node::NodeMask nm) continue; if (info->farCamera.valid() && info->farCamera->getNodeMask() != 0) { info->camera->setCullMask(nm & ~simgear::BACKGROUND_BIT); + info->camera->setCullMaskLeft(nm & ~simgear::BACKGROUND_BIT); + info->camera->setCullMaskRight(nm & ~simgear::BACKGROUND_BIT); info->farCamera->setCullMask(nm); + info->farCamera->setCullMaskLeft(nm); + info->farCamera->setCullMaskRight(nm); } else { info->camera->setCullMask(nm); + info->camera->setCullMaskLeft(nm); + info->camera->setCullMaskRight(nm); } } }