2009-01-15 18:44:52 +08:00
/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield
2005-06-14 21:16:58 +08:00
*
2009-01-15 18:44:52 +08:00
* This library is open source and may be redistributed and / or modified under
* the terms of the OpenSceneGraph Public License ( OSGPL ) version 0.0 or
2005-06-14 21:16:58 +08:00
* ( at your option ) any later version . The full license is in LICENSE file
* included with this distribution , and on the openscenegraph . org website .
2009-01-15 18:44:52 +08:00
*
2005-06-14 21:16:58 +08:00
* This library is distributed in the hope that it will be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
2009-01-15 18:44:52 +08:00
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
2005-06-14 21:16:58 +08:00
* OpenSceneGraph Public License for more details .
*/
2006-11-27 22:52:07 +08:00
# include <osg/Camera>
2008-02-29 23:25:57 +08:00
# include <osg/RenderInfo>
2005-11-01 18:42:54 +08:00
# include <osg/Notify>
2005-06-14 21:16:58 +08:00
using namespace osg ;
2006-11-27 22:52:07 +08:00
Camera : : Camera ( ) :
2006-09-19 04:54:48 +08:00
_view ( 0 ) ,
2007-02-22 03:06:43 +08:00
_allowEventFocus ( true ) ,
2005-06-15 04:51:35 +08:00
_clearMask ( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ) ,
2008-03-31 19:44:31 +08:00
_clearColor ( osg : : Vec4 ( 0.0f , 0.0f , 0.0f , 1.0f ) ) ,
_clearAccum ( osg : : Vec4 ( 0.0f , 0.0f , 0.0f , 1.0f ) ) ,
_clearDepth ( 1.0 ) ,
_clearStencil ( 0 ) ,
2006-02-21 05:05:23 +08:00
_transformOrder ( PRE_MULTIPLY ) ,
2007-05-22 17:32:38 +08:00
_projectionResizePolicy ( HORIZONTAL ) ,
2007-09-07 23:03:56 +08:00
_renderOrder ( POST_RENDER ) ,
2006-09-04 21:15:08 +08:00
_renderOrderNum ( 0 ) ,
2005-08-17 18:12:49 +08:00
_drawBuffer ( GL_NONE ) ,
_readBuffer ( GL_NONE ) ,
2005-11-01 18:42:54 +08:00
_renderTargetImplementation ( FRAME_BUFFER ) ,
_renderTargetFallback ( FRAME_BUFFER )
2005-06-14 21:16:58 +08:00
{
2005-07-20 00:30:55 +08:00
setStateSet ( new StateSet ) ;
2005-06-14 21:16:58 +08:00
}
2006-11-27 22:52:07 +08:00
Camera : : Camera ( const Camera & camera , const CopyOp & copyop ) :
2005-06-14 21:16:58 +08:00
Transform ( camera , copyop ) ,
2005-06-15 04:51:35 +08:00
CullSettings ( camera ) ,
2006-09-19 04:54:48 +08:00
_view ( camera . _view ) ,
2007-02-22 03:06:43 +08:00
_allowEventFocus ( camera . _allowEventFocus ) ,
2007-06-09 18:06:38 +08:00
_displaySettings ( camera . _displaySettings ) ,
2005-06-14 21:16:58 +08:00
_clearMask ( camera . _clearMask ) ,
2008-03-31 19:44:31 +08:00
_clearColor ( camera . _clearColor ) ,
_clearAccum ( camera . _clearAccum ) ,
_clearDepth ( camera . _clearDepth ) ,
_clearStencil ( camera . _clearStencil ) ,
2005-07-20 00:30:55 +08:00
_colorMask ( camera . _colorMask ) ,
2005-06-14 21:16:58 +08:00
_viewport ( camera . _viewport ) ,
2005-06-15 18:59:10 +08:00
_transformOrder ( camera . _transformOrder ) ,
2007-05-22 17:32:38 +08:00
_projectionResizePolicy ( camera . _projectionResizePolicy ) ,
2005-06-14 21:16:58 +08:00
_projectionMatrix ( camera . _projectionMatrix ) ,
2005-06-15 04:51:35 +08:00
_viewMatrix ( camera . _viewMatrix ) ,
_renderOrder ( camera . _renderOrder ) ,
2006-09-04 21:15:08 +08:00
_renderOrderNum ( camera . _renderOrderNum ) ,
2005-08-17 18:12:49 +08:00
_drawBuffer ( camera . _drawBuffer ) ,
_readBuffer ( camera . _readBuffer ) ,
2005-06-15 04:51:35 +08:00
_renderTargetImplementation ( camera . _renderTargetImplementation ) ,
2005-11-01 18:42:54 +08:00
_renderTargetFallback ( camera . _renderTargetFallback ) ,
2005-07-25 04:31:21 +08:00
_bufferAttachmentMap ( camera . _bufferAttachmentMap ) ,
2008-02-29 23:25:57 +08:00
_initialDrawCallback ( camera . _initialDrawCallback ) ,
2007-06-02 03:45:24 +08:00
_preDrawCallback ( camera . _preDrawCallback ) ,
2008-02-29 23:25:57 +08:00
_postDrawCallback ( camera . _postDrawCallback ) ,
_finalDrawCallback ( camera . _finalDrawCallback )
2005-07-20 00:30:55 +08:00
{
2007-01-02 02:20:10 +08:00
// need to copy/share graphics context?
2005-06-14 21:16:58 +08:00
}
2006-11-27 22:52:07 +08:00
Camera : : ~ Camera ( )
2005-06-14 21:16:58 +08:00
{
2007-02-05 21:44:16 +08:00
setCameraThread ( 0 ) ;
2009-01-15 18:44:52 +08:00
2007-01-02 02:20:10 +08:00
if ( _graphicsContext . valid ( ) ) _graphicsContext - > removeCamera ( this ) ;
2005-06-14 21:16:58 +08:00
}
2008-02-29 23:25:57 +08:00
void Camera : : DrawCallback : : operator ( ) ( osg : : RenderInfo & renderInfo ) const
{
if ( renderInfo . getCurrentCamera ( ) )
{
operator ( ) ( * ( renderInfo . getCurrentCamera ( ) ) ) ;
}
else
{
osg : : notify ( osg : : WARN ) < < " Error: Camera::DrawCallback called without valid camera. " < < std : : endl ;
}
}
2009-01-15 18:44:52 +08:00
void Camera : : setGraphicsContext ( GraphicsContext * context )
2007-01-02 02:20:10 +08:00
{
if ( _graphicsContext = = context ) return ;
2009-01-15 18:44:52 +08:00
2007-01-02 02:20:10 +08:00
if ( _graphicsContext . valid ( ) ) _graphicsContext - > removeCamera ( this ) ;
2009-01-15 18:44:52 +08:00
2007-01-02 02:20:10 +08:00
_graphicsContext = context ;
if ( _graphicsContext . valid ( ) ) _graphicsContext - > addCamera ( this ) ;
}
2006-11-27 22:52:07 +08:00
bool Camera : : isRenderToTextureCamera ( ) const
2005-12-07 19:36:56 +08:00
{
return ( ! _bufferAttachmentMap . empty ( ) ) ;
}
2006-11-27 22:52:07 +08:00
void Camera : : setRenderTargetImplementation ( RenderTargetImplementation impl )
2005-11-01 18:42:54 +08:00
{
_renderTargetImplementation = impl ;
if ( impl < FRAME_BUFFER ) _renderTargetFallback = ( RenderTargetImplementation ) ( impl + 1 ) ;
else _renderTargetFallback = impl ;
2009-01-15 18:44:52 +08:00
}
2005-11-01 18:42:54 +08:00
2006-11-27 22:52:07 +08:00
void Camera : : setRenderTargetImplementation ( RenderTargetImplementation impl , RenderTargetImplementation fallback )
2005-11-01 18:42:54 +08:00
{
2005-11-04 20:08:16 +08:00
if ( impl < fallback | | ( impl = = FRAME_BUFFER & & fallback = = FRAME_BUFFER ) )
2005-11-01 18:42:54 +08:00
{
_renderTargetImplementation = impl ;
_renderTargetFallback = fallback ;
}
2009-01-15 18:44:52 +08:00
else
2005-11-01 18:42:54 +08:00
{
2006-11-27 22:52:07 +08:00
osg : : notify ( osg : : NOTICE ) < < " Warning: Camera::setRenderTargetImplementation(impl,fallback) must have a lower rated fallback than the main target implementation. " < < std : : endl ;
2005-11-01 18:42:54 +08:00
setRenderTargetImplementation ( impl ) ;
}
}
2006-11-27 22:52:07 +08:00
void Camera : : setColorMask ( osg : : ColorMask * colorMask )
2005-07-20 00:30:55 +08:00
{
if ( _colorMask = = colorMask ) return ;
osg : : StateSet * stateset = getOrCreateStateSet ( ) ;
if ( _colorMask . valid ( ) & & stateset )
{
stateset - > removeAttribute ( _colorMask . get ( ) ) ;
}
2009-01-15 18:44:52 +08:00
2005-07-20 00:30:55 +08:00
_colorMask = colorMask ;
2009-01-15 18:44:52 +08:00
2005-07-20 00:30:55 +08:00
if ( _colorMask . valid ( ) & & stateset )
{
stateset - > setAttribute ( _colorMask . get ( ) ) ;
}
}
2006-11-27 22:52:07 +08:00
void Camera : : setColorMask ( bool red , bool green , bool blue , bool alpha )
2005-07-20 00:30:55 +08:00
{
if ( ! _colorMask ) setColorMask ( new osg : : ColorMask ) ;
if ( _colorMask . valid ( ) ) _colorMask - > setMask ( red , green , blue , alpha ) ;
}
2006-11-27 22:52:07 +08:00
void Camera : : setViewport ( osg : : Viewport * viewport )
2005-07-20 00:30:55 +08:00
{
if ( _viewport = = viewport ) return ;
osg : : StateSet * stateset = getOrCreateStateSet ( ) ;
if ( _viewport . valid ( ) & & stateset )
{
stateset - > removeAttribute ( _viewport . get ( ) ) ;
}
2009-01-15 18:44:52 +08:00
2005-07-20 00:30:55 +08:00
_viewport = viewport ;
2009-01-15 18:44:52 +08:00
2005-07-20 00:30:55 +08:00
if ( _viewport . valid ( ) & & stateset )
{
stateset - > setAttribute ( _viewport . get ( ) ) ;
}
}
2006-11-27 22:52:07 +08:00
void Camera : : setViewport ( int x , int y , int width , int height )
2005-07-20 00:30:55 +08:00
{
if ( ! _viewport ) setViewport ( new osg : : Viewport ) ;
if ( _viewport . valid ( ) ) _viewport - > setViewport ( x , y , width , height ) ;
}
2006-11-27 22:52:07 +08:00
Matrixd Camera : : getInverseViewMatrix ( ) const
2005-06-14 21:16:58 +08:00
{
Matrixd inverse ;
inverse . invert ( _viewMatrix ) ;
return inverse ;
}
2006-11-27 22:52:07 +08:00
void Camera : : setProjectionMatrixAsOrtho ( double left , double right ,
2005-06-14 21:16:58 +08:00
double bottom , double top ,
double zNear , double zFar )
{
setProjectionMatrix ( osg : : Matrixd : : ortho ( left , right ,
bottom , top ,
zNear , zFar ) ) ;
2009-01-15 18:44:52 +08:00
}
2005-06-14 21:16:58 +08:00
2006-11-27 22:52:07 +08:00
void Camera : : setProjectionMatrixAsOrtho2D ( double left , double right ,
2005-06-14 21:16:58 +08:00
double bottom , double top )
{
setProjectionMatrix ( osg : : Matrixd : : ortho2D ( left , right ,
bottom , top ) ) ;
}
2006-11-27 22:52:07 +08:00
void Camera : : setProjectionMatrixAsFrustum ( double left , double right ,
2005-06-14 21:16:58 +08:00
double bottom , double top ,
double zNear , double zFar )
{
setProjectionMatrix ( osg : : Matrixd : : frustum ( left , right ,
bottom , top ,
zNear , zFar ) ) ;
}
2006-11-27 22:52:07 +08:00
void Camera : : setProjectionMatrixAsPerspective ( double fovy , double aspectRatio ,
2005-06-14 21:16:58 +08:00
double zNear , double zFar )
{
setProjectionMatrix ( osg : : Matrixd : : perspective ( fovy , aspectRatio ,
zNear , zFar ) ) ;
2009-01-15 18:44:52 +08:00
}
2005-06-14 21:16:58 +08:00
2006-11-27 22:52:07 +08:00
bool Camera : : getProjectionMatrixAsOrtho ( double & left , double & right ,
2005-06-14 21:16:58 +08:00
double & bottom , double & top ,
2009-01-15 18:36:04 +08:00
double & zNear , double & zFar ) const
2005-06-14 21:16:58 +08:00
{
return _projectionMatrix . getOrtho ( left , right ,
bottom , top ,
zNear , zFar ) ;
}
2006-11-27 22:52:07 +08:00
bool Camera : : getProjectionMatrixAsFrustum ( double & left , double & right ,
2005-06-14 21:16:58 +08:00
double & bottom , double & top ,
2009-01-15 18:36:04 +08:00
double & zNear , double & zFar ) const
2005-06-14 21:16:58 +08:00
{
return _projectionMatrix . getFrustum ( left , right ,
bottom , top ,
zNear , zFar ) ;
2009-01-15 18:44:52 +08:00
}
2005-06-14 21:16:58 +08:00
2006-11-27 22:52:07 +08:00
bool Camera : : getProjectionMatrixAsPerspective ( double & fovy , double & aspectRatio ,
2009-01-15 18:36:04 +08:00
double & zNear , double & zFar ) const
2005-06-14 21:16:58 +08:00
{
return _projectionMatrix . getPerspective ( fovy , aspectRatio , zNear , zFar ) ;
2009-01-15 18:44:52 +08:00
}
2005-06-14 21:16:58 +08:00
2008-03-04 19:53:09 +08:00
void Camera : : setViewMatrixAsLookAt ( const Vec3d & eye , const Vec3d & center , const Vec3d & up )
2005-06-14 21:16:58 +08:00
{
setViewMatrix ( osg : : Matrixd : : lookAt ( eye , center , up ) ) ;
}
2009-01-15 18:36:04 +08:00
void Camera : : getViewMatrixAsLookAt ( Vec3d & eye , Vec3d & center , Vec3d & up , double lookDistance ) const
2008-03-04 19:53:09 +08:00
{
_viewMatrix . getLookAt ( eye , center , up , lookDistance ) ;
}
2009-01-15 18:36:04 +08:00
void Camera : : getViewMatrixAsLookAt ( Vec3f & eye , Vec3f & center , Vec3f & up , float lookDistance ) const
2005-06-14 21:16:58 +08:00
{
_viewMatrix . getLookAt ( eye , center , up , lookDistance ) ;
}
2005-06-15 04:51:35 +08:00
2006-11-27 22:52:07 +08:00
void Camera : : attach ( BufferComponent buffer , GLenum internalFormat )
2005-06-15 04:51:35 +08:00
{
2008-11-25 18:57:14 +08:00
switch ( buffer )
{
case DEPTH_BUFFER :
if ( _bufferAttachmentMap . find ( PACKED_DEPTH_STENCIL_BUFFER ) ! = _bufferAttachmentMap . end ( ) )
{
2009-01-15 18:44:52 +08:00
notify ( WARN )
< < " Camera: DEPTH_BUFFER already attached as PACKED_DEPTH_STENCIL_BUFFER ! "
2008-11-25 18:57:14 +08:00
< < std : : endl ;
}
break ;
case STENCIL_BUFFER :
if ( _bufferAttachmentMap . find ( PACKED_DEPTH_STENCIL_BUFFER ) ! = _bufferAttachmentMap . end ( ) )
{
2009-01-15 18:44:52 +08:00
notify ( WARN )
< < " Camera: STENCIL_BUFFER already attached as PACKED_DEPTH_STENCIL_BUFFER ! "
2008-11-25 18:57:14 +08:00
< < std : : endl ;
}
break ;
case PACKED_DEPTH_STENCIL_BUFFER :
if ( _bufferAttachmentMap . find ( DEPTH_BUFFER ) ! = _bufferAttachmentMap . end ( ) )
{
notify ( WARN ) < < " Camera: DEPTH_BUFFER already attached ! " < < std : : endl ;
}
if ( _bufferAttachmentMap . find ( STENCIL_BUFFER ) ! = _bufferAttachmentMap . end ( ) )
{
notify ( WARN ) < < " Camera: STENCIL_BUFFER already attached ! " < < std : : endl ;
}
break ;
2008-12-17 19:00:16 +08:00
default :
break ;
2008-11-25 18:57:14 +08:00
}
2005-06-15 04:51:35 +08:00
_bufferAttachmentMap [ buffer ] . _internalFormat = internalFormat ;
}
2008-06-18 22:09:11 +08:00
void Camera : : attach ( BufferComponent buffer , osg : : Texture * texture , unsigned int level , unsigned int face , bool mipMapGeneration ,
2009-01-15 18:44:52 +08:00
unsigned int multisampleSamples ,
2008-06-18 22:09:11 +08:00
unsigned int multisampleColorSamples )
2005-06-15 04:51:35 +08:00
{
_bufferAttachmentMap [ buffer ] . _texture = texture ;
2005-06-16 04:06:10 +08:00
_bufferAttachmentMap [ buffer ] . _level = level ;
2005-06-15 04:51:35 +08:00
_bufferAttachmentMap [ buffer ] . _face = face ;
2005-07-26 00:12:24 +08:00
_bufferAttachmentMap [ buffer ] . _mipMapGeneration = mipMapGeneration ;
2008-06-18 22:09:11 +08:00
_bufferAttachmentMap [ buffer ] . _multisampleSamples = multisampleSamples ;
_bufferAttachmentMap [ buffer ] . _multisampleColorSamples = multisampleColorSamples ;
2005-06-15 04:51:35 +08:00
}
2008-06-18 22:09:11 +08:00
void Camera : : attach ( BufferComponent buffer , osg : : Image * image ,
2009-01-15 18:44:52 +08:00
unsigned int multisampleSamples ,
2008-06-18 22:09:11 +08:00
unsigned int multisampleColorSamples )
2005-06-15 04:51:35 +08:00
{
_bufferAttachmentMap [ buffer ] . _image = image ;
2008-06-18 22:09:11 +08:00
_bufferAttachmentMap [ buffer ] . _multisampleSamples = multisampleSamples ;
_bufferAttachmentMap [ buffer ] . _multisampleColorSamples = multisampleColorSamples ;
2005-06-15 04:51:35 +08:00
}
2006-11-27 22:52:07 +08:00
void Camera : : detach ( BufferComponent buffer )
2005-06-15 04:51:35 +08:00
{
_bufferAttachmentMap . erase ( buffer ) ;
}
2007-01-04 22:11:51 +08:00
void Camera : : resizeGLObjectBuffers ( unsigned int maxSize )
{
2007-08-02 19:02:47 +08:00
if ( _renderingCache . valid ( ) )
2007-07-28 18:28:40 +08:00
{
2007-08-02 19:02:47 +08:00
const_cast < Camera * > ( this ) - > _renderingCache - > resizeGLObjectBuffers ( maxSize ) ;
2007-07-28 18:28:40 +08:00
}
2009-01-15 18:44:52 +08:00
2007-01-04 22:11:51 +08:00
Transform : : resizeGLObjectBuffers ( maxSize ) ;
}
2006-11-27 22:52:07 +08:00
void Camera : : releaseGLObjects ( osg : : State * state ) const
2005-12-08 18:06:57 +08:00
{
2007-08-02 19:02:47 +08:00
if ( _renderingCache . valid ( ) )
2007-07-28 18:28:40 +08:00
{
2007-08-02 19:02:47 +08:00
const_cast < Camera * > ( this ) - > _renderingCache - > releaseGLObjects ( state ) ;
2007-07-28 18:28:40 +08:00
}
2009-01-15 18:44:52 +08:00
2005-12-08 18:06:57 +08:00
Transform : : releaseGLObjects ( state ) ;
}
2005-06-15 04:51:35 +08:00
2006-11-27 22:52:07 +08:00
bool Camera : : computeLocalToWorldMatrix ( Matrix & matrix , NodeVisitor * ) const
2005-06-14 21:16:58 +08:00
{
if ( _referenceFrame = = RELATIVE_RF )
{
2006-02-21 05:05:23 +08:00
if ( _transformOrder = = PRE_MULTIPLY )
2005-06-15 18:59:10 +08:00
{
matrix . preMult ( _viewMatrix ) ;
}
else
{
matrix . postMult ( _viewMatrix ) ;
}
2005-06-14 21:16:58 +08:00
}
else // absolute
{
matrix = _viewMatrix ;
}
return true ;
}
2006-11-27 22:52:07 +08:00
bool Camera : : computeWorldToLocalMatrix ( Matrix & matrix , NodeVisitor * ) const
2005-06-14 21:16:58 +08:00
{
const Matrixd & inverse = getInverseViewMatrix ( ) ;
if ( _referenceFrame = = RELATIVE_RF )
{
2006-02-21 05:05:23 +08:00
if ( _transformOrder = = PRE_MULTIPLY )
2005-06-15 18:59:10 +08:00
{
// note doing inverse so pre becomes post.
matrix . postMult ( inverse ) ;
}
else
{
// note doing inverse so post becomes pre.
matrix . preMult ( inverse ) ;
}
2005-06-14 21:16:58 +08:00
}
else // absolute
{
matrix = inverse ;
}
return true ;
}
2008-06-17 04:22:16 +08:00
void Camera : : inheritCullSettings ( const CullSettings & settings , unsigned int inheritanceMask )
{
CullSettings : : inheritCullSettings ( settings , inheritanceMask ) ;
2009-01-15 18:44:52 +08:00
2009-08-21 17:34:48 +08:00
const Camera * camera = dynamic_cast < const Camera * > ( & settings ) ;
if ( camera )
2008-06-17 04:22:16 +08:00
{
//osg::notify(osg::NOTICE)<<"Inheriting slave Camera"<<std::endl;
2009-08-21 17:34:48 +08:00
if ( inheritanceMask & CLEAR_COLOR )
_clearColor = camera - > _clearColor ;
if ( inheritanceMask & DRAW_BUFFER )
_drawBuffer = camera - > _drawBuffer ;
if ( inheritanceMask & READ_BUFFER )
_drawBuffer = camera - > _readBuffer ;
2008-06-17 04:22:16 +08:00
}
}
2007-02-05 21:44:16 +08:00
void Camera : : createCameraThread ( )
{
if ( ! _cameraThread )
{
2007-07-12 23:54:45 +08:00
setCameraThread ( new OperationThread ) ;
2007-02-05 21:44:16 +08:00
}
}
2007-07-12 23:54:45 +08:00
void Camera : : setCameraThread ( OperationThread * gt )
2007-02-05 21:44:16 +08:00
{
2009-01-15 18:44:52 +08:00
if ( _cameraThread = = gt ) return ;
2007-02-05 21:44:16 +08:00
2009-01-15 18:44:52 +08:00
if ( _cameraThread . valid ( ) )
2007-02-05 21:44:16 +08:00
{
// need to kill the thread in some way...
_cameraThread - > cancel ( ) ;
_cameraThread - > setParent ( 0 ) ;
}
_cameraThread = gt ;
2009-01-15 18:44:52 +08:00
if ( _cameraThread . valid ( ) )
2007-02-05 21:44:16 +08:00
{
_cameraThread - > setParent ( this ) ;
}
}