diff --git a/include/osg/Camera b/include/osg/Camera index ce1346402..a6592775b 100644 --- a/include/osg/Camera +++ b/include/osg/Camera @@ -123,6 +123,19 @@ class OSG_EXPORT Camera : public Transform, public CullSettings /** Get the transformation order.*/ TransformOrder getTransformOrder() const { return _transformOrder; } + enum ProjectionResizePolicy + { + FIXED, /** Keep the projection matrix fixed, despite window resizes.*/ + HORIZONTAL, /** Adjust the HORIZOTNAL field of view on window resizes.*/ + VERTICAL /** Adjust the VERTICAL field of view on window resizes.*/ + }; + + /** Set the policy used to determin if and how the projection matrix should be adjusted on window resizes. */ + inline void setProjectionResizePolicy(ProjectionResizePolicy policy) { _projectionResizePolicy = policy; } + + /** Get the policy used to determin if and how the projection matrix should be adjusted on window resizes. */ + inline ProjectionResizePolicy getProjectionResizePolicy() const { return _projectionResizePolicy; } + /** Set the projection matrix. Can be thought of as setting the lens of a camera. */ inline void setProjectionMatrix(const osg::Matrixf& matrix) { _projectionMatrix.set(matrix); } @@ -417,6 +430,8 @@ class OSG_EXPORT Camera : public Transform, public CullSettings ref_ptr _viewport; TransformOrder _transformOrder; + ProjectionResizePolicy _projectionResizePolicy; + Matrixd _projectionMatrix; Matrixd _viewMatrix; diff --git a/src/osg/Camera.cpp b/src/osg/Camera.cpp index 6dd6a4414..c247020bf 100644 --- a/src/osg/Camera.cpp +++ b/src/osg/Camera.cpp @@ -22,6 +22,7 @@ Camera::Camera(): _clearMask(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT), _transformOrder(PRE_MULTIPLY), _renderOrder(POST_RENDER), + _projectionResizePolicy(HORIZONTAL), _renderOrderNum(0), _drawBuffer(GL_NONE), _readBuffer(GL_NONE), @@ -41,6 +42,7 @@ Camera::Camera(const Camera& camera,const CopyOp& copyop): _colorMask(camera._colorMask), _viewport(camera._viewport), _transformOrder(camera._transformOrder), + _projectionResizePolicy(camera._projectionResizePolicy), _projectionMatrix(camera._projectionMatrix), _viewMatrix(camera._viewMatrix), _renderOrder(camera._renderOrder), diff --git a/src/osg/GraphicsContext.cpp b/src/osg/GraphicsContext.cpp index 34a16f86d..2de310617 100644 --- a/src/osg/GraphicsContext.cpp +++ b/src/osg/GraphicsContext.cpp @@ -487,42 +487,24 @@ void GraphicsContext::resizedImplementation(int x, int y, int width, int height) { osg::View* view = camera->getView(); osg::View::Slave* slave = view ? view->findSlaveForCamera(camera) : 0; - + if (slave && camera->getReferenceFrame()==osg::Transform::RELATIVE_RF) { - slave->_projectionOffset *= osg::Matrix::scale(1.0/aspectRatioChange,1.0,1.0); + switch(view->getCamera()->getProjectionResizePolicy()) + { + case(osg::Camera::HORIZONTAL): slave->_projectionOffset *= osg::Matrix::scale(1.0/aspectRatioChange,1.0,1.0); break; + case(osg::Camera::VERTICAL): slave->_projectionOffset *= osg::Matrix::scale(1.0, aspectRatioChange,1.0); break; + default: break; + } } else { -#if 0 - osg::Matrixd& pm = camera->getProjectionMatrix(); - bool orthographicCamera = (pm(0,3)==0.0) && (pm(1,3)==0.0) && (pm(2,3)==0.0) && (pm(3,3)==1.0); - - if (orthographicCamera) + switch(view->getCamera()->getProjectionResizePolicy()) { - double left, right, bottom, top, zNear, zFar; - camera->getProjectionMatrixAsOrtho(left, right, bottom, top, zNear, zFar); - - double mid = (right+left)*0.5; - double halfWidth = (right-left)*0.5; - left = mid - halfWidth * aspectRatioChange; - right = mid + halfWidth * aspectRatioChange; - camera->setProjectionMatrixAsOrtho(left, right, bottom, top, zNear, zFar); + case(osg::Camera::HORIZONTAL): camera->getProjectionMatrix() *= osg::Matrix::scale(1.0/aspectRatioChange,1.0,1.0); break; + case(osg::Camera::VERTICAL): camera->getProjectionMatrix() *= osg::Matrix::scale(1.0, aspectRatioChange,1.0); break; + default: break; } - else - { - double left, right, bottom, top, zNear, zFar; - camera->getProjectionMatrixAsFrustum(left, right, bottom, top, zNear, zFar); - - double mid = (right+left)*0.5; - double halfWidth = (right-left)*0.5; - left = mid - halfWidth * aspectRatioChange; - right = mid + halfWidth * aspectRatioChange; - camera->setProjectionMatrixAsFrustum(left, right, bottom, top, zNear, zFar); - } -#else - camera->getProjectionMatrix() *= osg::Matrix::scale(1.0/aspectRatioChange,1.0,1.0); -#endif } } diff --git a/src/osgWrappers/osg/Camera.cpp b/src/osgWrappers/osg/Camera.cpp index 172f637b2..9153a908d 100644 --- a/src/osgWrappers/osg/Camera.cpp +++ b/src/osgWrappers/osg/Camera.cpp @@ -45,6 +45,12 @@ BEGIN_ENUM_REFLECTOR(osg::Camera::TransformOrder) I_EnumLabel(osg::Camera::POST_MULTIPLY); END_REFLECTOR +BEGIN_ENUM_REFLECTOR(osg::Camera::ProjectionResizePolicy) + I_EnumLabel(osg::Camera::FIXED); + I_EnumLabel(osg::Camera::HORIZONTAL); + I_EnumLabel(osg::Camera::VERTICAL); +END_REFLECTOR + BEGIN_ENUM_REFLECTOR(osg::Camera::RenderOrder) I_EnumLabel(osg::Camera::PRE_RENDER); I_EnumLabel(osg::Camera::NESTED_RENDER); @@ -223,6 +229,16 @@ BEGIN_OBJECT_REFLECTOR(osg::Camera) __TransformOrder__getTransformOrder, "Get the transformation order. ", ""); + I_Method1(void, setProjectionResizePolicy, IN, osg::Camera::ProjectionResizePolicy, policy, + Properties::NON_VIRTUAL, + __void__setProjectionResizePolicy__ProjectionResizePolicy, + "Set the policy used to determin if and how the projection matrix should be adjusted on window resizes. ", + ""); + I_Method0(osg::Camera::ProjectionResizePolicy, getProjectionResizePolicy, + Properties::NON_VIRTUAL, + __ProjectionResizePolicy__getProjectionResizePolicy, + "Get the policy used to determin if and how the projection matrix should be adjusted on window resizes. ", + ""); I_Method1(void, setProjectionMatrix, IN, const osg::Matrixf &, matrix, Properties::NON_VIRTUAL, __void__setProjectionMatrix__C5_osg_Matrixf_R1, @@ -529,6 +545,9 @@ BEGIN_OBJECT_REFLECTOR(osg::Camera) I_SimpleProperty(const osg::Matrixd &, ProjectionMatrix, __C5_osg_Matrixd_R1__getProjectionMatrix, __void__setProjectionMatrix__C5_osg_Matrixd_R1); + I_SimpleProperty(osg::Camera::ProjectionResizePolicy, ProjectionResizePolicy, + __ProjectionResizePolicy__getProjectionResizePolicy, + __void__setProjectionResizePolicy__ProjectionResizePolicy); I_SimpleProperty(GLenum, ReadBuffer, __GLenum__getReadBuffer, __void__setReadBuffer__GLenum);