X-Git-Url: https://git.mxchange.org/?a=blobdiff_plain;f=src%2FMain%2FCameraGroup.cxx;h=e80e0c564bbc1cf61b5520055aa9cea426ea96a2;hb=38226af24ec01e8f0a20d7fd73ef838a69f6ef25;hp=c8e23c2293b721ada0adf5e33bbcb83ed3908f34;hpb=2b0ffae3398461271ef249624765fd6a5d44f7d4;p=flightgear.git diff --git a/src/Main/CameraGroup.cxx b/src/Main/CameraGroup.cxx index c8e23c229..e80e0c564 100644 --- a/src/Main/CameraGroup.cxx +++ b/src/Main/CameraGroup.cxx @@ -14,6 +14,10 @@ // along with this program; if not, write to the Free Software // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +#ifdef HAVE_CONFIG_H +# include +#endif + #include "CameraGroup.hxx" #include "globals.hxx" @@ -23,6 +27,7 @@ #include "WindowSystemAdapter.hxx" #include #include +#include #include #include @@ -30,16 +35,22 @@ #include #include +#include #include +#include #include #include +#include +#include #include +#include #include #include #include #include +#include namespace flightgear { @@ -100,14 +111,12 @@ void makeNewProjMat(Matrixd& oldProj, double znear, void installCullVisitor(Camera* camera) { -#if 0 // Not yet osgViewer::Renderer* renderer = static_cast(camera->getRenderer()); for (int i = 0; i < 2; ++i) { osgUtil::SceneView* sceneView = renderer->getSceneView(i); sceneView->setCullVisitor(new simgear::EffectCullVisitor); } -#endif } } @@ -144,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; @@ -152,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; @@ -198,7 +218,7 @@ void CameraGroup::update(const osg::Vec3d& position, camera->setProjectionMatrix(projectionMatrix); camera->setCullMask(camera->getCullMask() | simgear::BACKGROUND_BIT); - camera->setClearMask(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + camera->setClearMask(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); farCamera->setNodeMask(0); } else { Matrix nearProj, farProj; @@ -293,12 +313,204 @@ 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(); const SGPropertyNode* windowNode = cameraNode->getNode("window"); GraphicsWindow* window = 0; - static int cameraNum = 0; int cameraFlags = DO_INTERSECTION_TEST; if (windowNode) { // New style window declaration / definition @@ -318,7 +530,11 @@ CameraInfo* CameraGroup::buildCamera(SGPropertyNode* cameraNode) | CullSettings::VIEW_FRUSTUM_CULLING); camera->setInheritanceMask(CullSettings::ALL_VARIABLES & ~(CullSettings::CULL_MASK - | CullSettings::CULLING_MODE)); + | CullSettings::CULLING_MODE +#if defined(HAVE_CULLSETTINGS_CLEAR_MASK) + | CullSettings::CLEAR_MASK +#endif + )); osg::Matrix pOff; osg::Matrix vOff; @@ -383,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; } @@ -400,16 +646,16 @@ CameraInfo* CameraGroup::buildGUICamera(SGPropertyNode* cameraNode, const SGPropertyNode* windowNode = (cameraNode ? cameraNode->getNode("window") : 0); - static int cameraNum = 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()); @@ -420,7 +666,11 @@ CameraInfo* CameraGroup::buildGUICamera(SGPropertyNode* cameraNode, camera->setClearMask(0); camera->setInheritanceMask(CullSettings::ALL_VARIABLES & ~(CullSettings::COMPUTE_NEAR_FAR_MODE - | CullSettings::CULLING_MODE)); + | CullSettings::CULLING_MODE +#if defined(HAVE_CULLSETTINGS_CLEAR_MASK) + | CullSettings::CLEAR_MASK +#endif + )); camera->setComputeNearFarMode(osg::CullSettings::DO_NOT_COMPUTE_NEAR_FAR); camera->setCullingMode(osg::CullSettings::NO_CULLING); camera->setProjectionResizePolicy(Camera::FIXED); @@ -452,7 +702,7 @@ CameraGroup* CameraGroup::buildCameraGroup(osgViewer::Viewer* viewer, cgroup->buildGUICamera(pNode); } } - bindMemberToNode(gnode, "znear", cgroup, &CameraGroup::_zNear, .4f); + bindMemberToNode(gnode, "znear", cgroup, &CameraGroup::_zNear, .1f); bindMemberToNode(gnode, "zfar", cgroup, &CameraGroup::_zFar, 120000.0f); bindMemberToNode(gnode, "near-field", cgroup, &CameraGroup::_nearField, 100.0f); @@ -467,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); } } }