OpenSceneGraph/include/osg/Camera

579 lines
25 KiB
Plaintext
Raw Normal View History

/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield
*
* 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
* (at your option) any later version. The full license is in LICENSE file
* included with this distribution, and on the openscenegraph.org website.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* OpenSceneGraph Public License for more details.
*/
#ifndef OSG_CAMERA
#define OSG_CAMERA 1
#include <osg/Transform>
#include <osg/Viewport>
#include <osg/ColorMask>
#include <osg/CullSettings>
#include <osg/Texture>
#include <osg/Image>
#include <osg/GraphicsContext>
#include <osg/Stats>
#include <OpenThreads/Mutex>
namespace osg {
// forward declare View to allow Camera to point back to the View that its within
class View;
class RenderInfo;
/** Camera - is a subclass of Transform which represents encapsulates the settings of a Camera.
*/
class OSG_EXPORT Camera : public Transform, public CullSettings
{
public :
Camera();
/** Copy constructor using CopyOp to manage deep vs shallow copy.*/
Camera(const Camera&,const CopyOp& copyop=CopyOp::SHALLOW_COPY);
META_Node(osg, Camera);
/** Set the View that this Camera is part of. */
void setView(View* view) { _view = view; }
/** Get the View that this Camera is part of. */
View* getView() { return _view; }
/** Get the const View that this Camera is part of. */
const View* getView() const { return _view; }
/** Set the Stats object used for collect various frame related timing and scene graph stats.*/
void setStats(osg::Stats* stats) { _stats = stats; }
/** Get the Stats object.*/
osg::Stats* getStats() { return _stats.get(); }
/** Get the const Stats object.*/
const osg::Stats* getStats() const { return _stats.get(); }
/** Set whether this camera allows events to be generated by the associated graphics window to be associated with this camera.*/
void setAllowEventFocus(bool focus) { _allowEventFocus = focus; }
/** Get whether this camera allows events to be generated by the associated graphics window to be associated with this camera.*/
bool getAllowEventFocus() const { return _allowEventFocus; }
/** Set the DsplaySettings object associated with this view.*/
void setDisplaySettings(osg::DisplaySettings* ds) { _displaySettings = ds; }
/** Set the DsplaySettings object associated with this view.*/
osg::DisplaySettings* getDisplaySettings() { return _displaySettings.get(); }
/** Set the DsplaySettings object associated with this view.*/
const osg::DisplaySettings* getDisplaySettings() const { return _displaySettings.get(); }
/** Set the clear mask used in glClear(..).
* Defaults to GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT. */
inline void setClearMask(GLbitfield mask) { _clearMask = mask; }
/** Get the clear mask.*/
inline GLbitfield getClearMask() const { return _clearMask; }
/** Set the clear color used in glClearColor(..).
* glClearColor is only called if mask & GL_COLOR_BUFFER_BIT is true*/
void setClearColor(const osg::Vec4& color) { _clearColor=color; applyMaskAction(CLEAR_COLOR); }
/** Get the clear color.*/
const osg::Vec4& getClearColor() const { return _clearColor; }
/** Set the clear accum used in glClearAccum(..).
* glClearAcumm is only called if mask & GL_ACCUM_BUFFER_BIT is true. */
void setClearAccum(const osg::Vec4& color) { _clearAccum=color; }
/** Get the clear accum value.*/
const osg::Vec4& getClearAccum() const { return _clearAccum; }
/** Set the clear depth used in glClearDepth(..). Defaults to 1.0
* glClearDepth is only called if mask & GL_DEPTH_BUFFER_BIT is true. */
void setClearDepth(double depth) { _clearDepth=depth; }
/** Get the clear depth value.*/
double getClearDepth() const { return _clearDepth; }
/** Set the clear stencil value used in glClearStencil(). Defaults to 0;
* glClearStencil is only called if mask & GL_STENCIL_BUFFER_BIT is true*/
void setClearStencil(int stencil) { _clearStencil=stencil; }
/** Get the clear stencil value.*/
int getClearStencil() const { return _clearStencil; }
/** Set the color mask of the camera to use specified osg::ColorMask. */
void setColorMask(osg::ColorMask* colorMask);
/** Set the color mask of the camera to specified values. */
void setColorMask(bool red, bool green, bool blue, bool alpha);
/** Get the const ColorMask. */
const ColorMask* getColorMask() const { return _colorMask.get(); }
/** Get the ColorMask. */
ColorMask* getColorMask() { return _colorMask.get(); }
/** Set the viewport of the camera to use specified osg::Viewport. */
void setViewport(osg::Viewport* viewport);
/** Set the viewport of the camera to specified dimensions. */
void setViewport(int x,int y,int width,int height);
/** Get the const viewport. */
const Viewport* getViewport() const { return _viewport.get(); }
/** Get the viewport. */
Viewport* getViewport() { return _viewport.get(); }
enum TransformOrder
{
PRE_MULTIPLY,
POST_MULTIPLY
};
/** Set the transformation order for world-to-local and local-to-world transformation.*/
void setTransformOrder(TransformOrder order) { _transformOrder = order; }
/** 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 determine if and how the projection matrix should be adjusted on window resizes. */
inline void setProjectionResizePolicy(ProjectionResizePolicy policy) { _projectionResizePolicy = policy; }
/** Get the policy used to determine 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); }
/** Set the projection matrix. Can be thought of as setting the lens of a camera. */
inline void setProjectionMatrix(const osg::Matrixd& matrix) { _projectionMatrix.set(matrix); }
/** Set to an orthographic projection. See OpenGL glOrtho for documentation further details.*/
void setProjectionMatrixAsOrtho(double left, double right,
double bottom, double top,
double zNear, double zFar);
/** Set to a 2D orthographic projection. See OpenGL glOrtho2D documentation for further details.*/
void setProjectionMatrixAsOrtho2D(double left, double right,
double bottom, double top);
/** Set to a perspective projection. See OpenGL glFrustum documentation for further details.*/
void setProjectionMatrixAsFrustum(double left, double right,
double bottom, double top,
double zNear, double zFar);
/** Create a symmetrical perspective projection, See OpenGL gluPerspective documentation for further details.
* Aspect ratio is defined as width/height.*/
void setProjectionMatrixAsPerspective(double fovy,double aspectRatio,
double zNear, double zFar);
/** Get the projection matrix.*/
osg::Matrixd& getProjectionMatrix() { return _projectionMatrix; }
/** Get the const projection matrix.*/
const osg::Matrixd& getProjectionMatrix() const { return _projectionMatrix; }
/** Get the orthographic settings of the orthographic projection matrix.
* Returns false if matrix is not an orthographic matrix, where parameter values are undefined.*/
bool getProjectionMatrixAsOrtho(double& left, double& right,
double& bottom, double& top,
double& zNear, double& zFar) const;
/** Get the frustum setting of a perspective projection matrix.
* Returns false if matrix is not a perspective matrix, where parameter values are undefined.*/
bool getProjectionMatrixAsFrustum(double& left, double& right,
double& bottom, double& top,
double& zNear, double& zFar) const;
/** Get the frustum setting of a symmetric perspective projection matrix.
* Returns false if matrix is not a perspective matrix, where parameter values are undefined.
* Note, if matrix is not a symmetric perspective matrix then the shear will be lost.
* Asymmetric matrices occur when stereo, power walls, caves and reality center display are used.
* In these configurations one should use the 'getProjectionMatrixAsFrustum' method instead.*/
bool getProjectionMatrixAsPerspective(double& fovy,double& aspectRatio,
double& zNear, double& zFar) const;
/** Set the view matrix. Can be thought of as setting the position of the world relative to the camera in camera coordinates. */
inline void setViewMatrix(const osg::Matrixf& matrix) { _viewMatrix.set(matrix); dirtyBound();}
/** Set the view matrix. Can be thought of as setting the position of the world relative to the camera in camera coordinates. */
inline void setViewMatrix(const osg::Matrixd& matrix) { _viewMatrix.set(matrix); dirtyBound();}
/** Get the view matrix. */
osg::Matrixd& getViewMatrix() { return _viewMatrix; }
/** Get the const view matrix. */
const osg::Matrixd& getViewMatrix() const { return _viewMatrix; }
/** Set to the position and orientation of view matrix, using the same convention as gluLookAt. */
void setViewMatrixAsLookAt(const osg::Vec3d& eye,const osg::Vec3d& center,const osg::Vec3d& up);
/** Get to the position and orientation of a modelview matrix, using the same convention as gluLookAt. */
void getViewMatrixAsLookAt(osg::Vec3d& eye,osg::Vec3d& center,osg::Vec3d& up,double lookDistance=1.0) const;
/** Get to the position and orientation of a modelview matrix, using the same convention as gluLookAt. */
void getViewMatrixAsLookAt(osg::Vec3f& eye,osg::Vec3f& center,osg::Vec3f& up,float lookDistance=1.0f) const;
/** Get the inverse view matrix.*/
Matrixd getInverseViewMatrix() const;
enum RenderOrder
{
PRE_RENDER,
NESTED_RENDER,
POST_RENDER
};
/** Set the rendering order of this camera's subgraph relative to any camera that this subgraph is nested within.
* For rendering to a texture, one typically uses PRE_RENDER.
* For Head Up Displays, one would typically use POST_RENDER.*/
void setRenderOrder(RenderOrder order, int orderNum = 0) { _renderOrder = order; _renderOrderNum = orderNum; }
/** Get the rendering order of this camera's subgraph relative to any camera that this subgraph is nested within.*/
RenderOrder getRenderOrder() const { return _renderOrder; }
/** Get the rendering order number of this camera relative to any sibling cameras in this subgraph.*/
int getRenderOrderNum() const { return _renderOrderNum; }
/** Return true if this Camera is set up as a render to texture camera, i.e. it has textures assigned to it.*/
bool isRenderToTextureCamera() const;
enum RenderTargetImplementation
{
FRAME_BUFFER_OBJECT,
PIXEL_BUFFER_RTT,
PIXEL_BUFFER,
FRAME_BUFFER,
SEPERATE_WINDOW
};
/** Set the render target.*/
void setRenderTargetImplementation(RenderTargetImplementation impl);
/** Set the render target and fall-back that's used if the former isn't available.*/
void setRenderTargetImplementation(RenderTargetImplementation impl, RenderTargetImplementation fallback);
/** Get the render target.*/
RenderTargetImplementation getRenderTargetImplementation() const { return _renderTargetImplementation; }
/** Get the render target fallback.*/
RenderTargetImplementation getRenderTargetFallback() const { return _renderTargetFallback; }
/** Set the draw buffer used at the start of each frame draw.
* Note, a buffer value of GL_NONE is used to sepecify that the rendering back-end should choose the most appropriate buffer.*/
void setDrawBuffer(GLenum buffer) { _drawBuffer = buffer; }
/** Get the draw buffer used at the start of each frame draw. */
GLenum getDrawBuffer() const { return _drawBuffer; }
/** Set the read buffer for any required copy operations to use.
* Note, a buffer value of GL_NONE is used to sepecify that the rendering back-end should choose the most appropriate buffer.*/
void setReadBuffer(GLenum buffer) { _readBuffer = buffer; }
/** Get the read buffer for any required copy operations to use. */
GLenum getReadBuffer() const { return _readBuffer; }
enum BufferComponent
{
DEPTH_BUFFER,
STENCIL_BUFFER,
PACKED_DEPTH_STENCIL_BUFFER,
COLOR_BUFFER,
COLOR_BUFFER0,
COLOR_BUFFER1 = COLOR_BUFFER0+1,
COLOR_BUFFER2 = COLOR_BUFFER0+2,
COLOR_BUFFER3 = COLOR_BUFFER0+3,
COLOR_BUFFER4 = COLOR_BUFFER0+4,
COLOR_BUFFER5 = COLOR_BUFFER0+5,
COLOR_BUFFER6 = COLOR_BUFFER0+6,
COLOR_BUFFER7 = COLOR_BUFFER0+7,
COLOR_BUFFER8 = COLOR_BUFFER0+8,
COLOR_BUFFER9 = COLOR_BUFFER0+9,
COLOR_BUFFER10 = COLOR_BUFFER0+10,
COLOR_BUFFER11 = COLOR_BUFFER0+11,
COLOR_BUFFER12 = COLOR_BUFFER0+12,
COLOR_BUFFER13 = COLOR_BUFFER0+13,
COLOR_BUFFER14 = COLOR_BUFFER0+14,
COLOR_BUFFER15 = COLOR_BUFFER0+15
};
2008-05-07 19:59:15 +08:00
/** Attach a buffer with specified OpenGL internal format.*/
void attach(BufferComponent buffer, GLenum internalFormat);
/** Attach a Texture to specified buffer component.
* The level parameter controls the mip map level of the texture that is attached.
* The face parameter controls the face of texture cube map or z level of 3d texture.
2008-05-07 19:59:15 +08:00
* The mipMapGeneration flag controls whether mipmap generation should be done for texture.*/
void attach(BufferComponent buffer, osg::Texture* texture, unsigned int level = 0, unsigned int face=0, bool mipMapGeneration=false,
unsigned int multisampleSamples = 0,
unsigned int multisampleColorSamples = 0);
2008-05-07 19:59:15 +08:00
/** Attach a Image to specified buffer component.*/
void attach(BufferComponent buffer, osg::Image* image,
unsigned int multisampleSamples = 0,
unsigned int multisampleColorSamples = 0);
2008-05-07 19:59:15 +08:00
/** Detach specified buffer component.*/
void detach(BufferComponent buffer);
struct Attachment
{
Attachment():
_internalFormat(GL_NONE),
_level(0),
_face(0),
_mipMapGeneration(false),
_multisampleSamples(0),
_multisampleColorSamples(0) {}
int width() const
{
if (_texture.valid()) return _texture->getTextureWidth();
if (_image.valid()) return _image->s();
return 0;
};
int height() const
{
if (_texture.valid()) return _texture->getTextureHeight();
if (_image.valid()) return _image->t();
return 0;
};
int depth() const
{
if (_texture.valid()) return _texture->getTextureDepth();
if (_image.valid()) return _image->r();
return 0;
};
GLenum _internalFormat;
ref_ptr<Image> _image;
ref_ptr<Texture> _texture;
unsigned int _level;
unsigned int _face;
bool _mipMapGeneration;
unsigned int _multisampleSamples;
unsigned int _multisampleColorSamples;
};
typedef std::map< BufferComponent, Attachment> BufferAttachmentMap;
/** Get the BufferAttachmentMap, used to configure frame buffer objects, pbuffers and texture reads.*/
BufferAttachmentMap& getBufferAttachmentMap() { return _bufferAttachmentMap; }
/** Get the const BufferAttachmentMap, used to configure frame buffer objects, pbuffers and texture reads.*/
const BufferAttachmentMap& getBufferAttachmentMap() const { return _bufferAttachmentMap; }
/** Create a operation thread for this camera.*/
void createCameraThread();
/** Assign a operation thread to the camera.*/
void setCameraThread(OperationThread* gt);
/** Get the operation thread assigned to this camera.*/
OperationThread* getCameraThread() { return _cameraThread.get(); }
/** Get the const operation thread assigned to this camera.*/
const OperationThread* getCameraThread() const { return _cameraThread.get(); }
/** Set the GraphicsContext that provides the mechansim for managing the OpenGL graphics context associated with this camera.*/
void setGraphicsContext(GraphicsContext* context);
/** Get the GraphicsContext.*/
GraphicsContext* getGraphicsContext() { return _graphicsContext.get(); }
/** Get the const GraphicsContext.*/
const GraphicsContext* getGraphicsContext() const { return _graphicsContext.get(); }
/** Set the Rendering object that is used to implement rendering of the subgraph.*/
void setRenderer(osg::GraphicsOperation* rc) { _renderer = rc; }
/** Get the Rendering object that is used to implement rendering of the subgraph.*/
osg::GraphicsOperation* getRenderer() { return _renderer.get(); }
/** Get the const Rendering object that is used to implement rendering of the subgraph.*/
const osg::GraphicsOperation* getRenderer() const { return _renderer.get(); }
/** Set the Rendering cache that is used for cached objects associated with rendering of subgraphs.*/
void setRenderingCache(osg::Object* rc) { _renderingCache = rc; }
/** Get the Rendering cache that is used for cached objects associated with rendering of subgraphs.*/
osg::Object* getRenderingCache() { return _renderingCache.get(); }
/** Get the const Rendering cache that is used for cached objects associated with rendering of subgraphs.*/
const osg::Object* getRenderingCache() const { return _renderingCache.get(); }
/** Draw callback for custom operations.*/
2008-03-01 21:40:57 +08:00
struct OSG_EXPORT DrawCallback : virtual public Object
{
DrawCallback() {}
DrawCallback(const DrawCallback&,const CopyOp&) {}
From Erik van Dekker, "I made several modifications: * The cause of my errors was that my OSG source directory path contains spaces. To fix this issue I wrapped all paths with quotes, as stated in doxygen documentation. * I also received some warning messages about deprecated doxygen settings, which I fixed by updating the doxygen file, i.e. running \u2018doxygen \u2013u doxygen.cmake\u2018. By running this command deprecated doxygen options are removed, some option comments have changed and quite some options have been added (I kept their default settings unless mentioned). * I was surprised to find that the doxygen OUTPUT_DIRECTORY was set to \u201c${OpenSceneGraph_SOURCE_DIR}/doc\u201d, which does not seem appropriate for out of source builds; I changed this to \u201c${OpenSceneGraph_BINARY_DIR}/doc\u201d. (On the other hand, maybe a cmake selectable option should be given to the user?) * Fixed two warnings I received about unexpected end-of-list-markers in \u2018osg\AnimationPath and \u2018osgUtil\CullVisitor due to excess trailing points in comments. * Fixed a warning in osgWidget\StyleInterface due to an #include directive (strangely) placed inside a namespace. * Fixed a warning in osg\Camera due to the META_Object macro that confused doxygen. Adding a semi-colon fixed this. * Removed auto_Mainpage from the INCLUDE option, because I am positive that this file does not belong there; It never generated useful documentation anyway. * I added the OSG version number environment variable to the PROJECT_NUMBER option so that the version number is now shown on the main page of generated documentation (e.g. index.html). * Changed option FULL_PATH_NAMES to YES, but made sure STRIP_FROM_PATH stripped the absolute path until the include dir. This fixed an issue that created mangled names for identical filenames in different directories. E.g. osg/Export and osgDB/Export are now correctly named. * Changed option SHOW_DIRECTORIES to yes, which is a case of preference I guess. "
2008-08-18 19:00:40 +08:00
META_Object(osg, DrawCallback);
/** Functor method called by rendering thread. Users will typically override this method to carry tasks such as screen capture.*/
virtual void operator () (osg::RenderInfo& renderInfo) const;
/** Functor method, provided for backwards compatibility, called by operator() (osg::RenderInfo& renderInfo) method.*/
virtual void operator () (const osg::Camera& /*camera*/) const {}
};
/** Set the initial draw callback for custom operations to be done before the drawing of the camera's subgraph and pre render stages.*/
void setInitialDrawCallback(DrawCallback* cb) { _initialDrawCallback = cb; }
/** Get the initial draw callback.*/
DrawCallback* getInitialDrawCallback() { return _initialDrawCallback.get(); }
/** Get the const initial draw callback.*/
2008-03-01 20:50:54 +08:00
const DrawCallback* getInitialDrawCallback() const { return _initialDrawCallback.get(); }
/** Set the pre draw callback for custom operations to be done before the drawing of the camera's subgraph but after any pre render stages have been completed.*/
void setPreDrawCallback(DrawCallback* cb) { _preDrawCallback = cb; }
/** Get the pre draw callback.*/
DrawCallback* getPreDrawCallback() { return _preDrawCallback.get(); }
/** Get the const pre draw callback.*/
const DrawCallback* getPreDrawCallback() const { return _preDrawCallback.get(); }
/** Set the post draw callback for custom operations to be done after the drawing of the camera's subgraph but before the any post render stages have been completed.*/
void setPostDrawCallback(DrawCallback* cb) { _postDrawCallback = cb; }
/** Get the post draw callback.*/
DrawCallback* getPostDrawCallback() { return _postDrawCallback.get(); }
/** Get the const post draw callback.*/
const DrawCallback* getPostDrawCallback() const { return _postDrawCallback.get(); }
/** Set the final draw callback for custom operations to be done after the drawing of the camera's subgraph and all of the post render stages has been completed.*/
void setFinalDrawCallback(DrawCallback* cb) { _finalDrawCallback = cb; }
/** Get the final draw callback.*/
DrawCallback* getFinalDrawCallback() { return _finalDrawCallback.get(); }
/** Get the const final draw callback.*/
const DrawCallback* getFinalDrawCallback() const { return _finalDrawCallback.get(); }
OpenThreads::Mutex* getDataChangeMutex() const { return &_dataChangeMutex; }
/** Resize any per context GLObject buffers to specified size. */
virtual void resizeGLObjectBuffers(unsigned int maxSize);
/** If State is non-zero, this function releases any associated OpenGL objects for
* the specified graphics context. Otherwise, releases OpenGL objexts
* for all graphics contexts. */
virtual void releaseGLObjects(osg::State* = 0) const;
public:
/** Transform method that must be defined to provide generic interface for scene graph traversals.*/
virtual bool computeLocalToWorldMatrix(Matrix& matrix,NodeVisitor*) const;
/** Transform method that must be defined to provide generic interface for scene graph traversals.*/
virtual bool computeWorldToLocalMatrix(Matrix& matrix,NodeVisitor*) const;
/** Inherit the local cull settings variable from specified CullSettings object, according to the inheritance mask.*/
virtual void inheritCullSettings(const CullSettings& settings, unsigned int inheritanceMask);
protected :
virtual ~Camera();
mutable OpenThreads::Mutex _dataChangeMutex;
View* _view;
osg::ref_ptr<osg::Stats> _stats;
bool _allowEventFocus;
osg::ref_ptr<osg::DisplaySettings> _displaySettings;
GLbitfield _clearMask;
osg::Vec4 _clearColor;
osg::Vec4 _clearAccum;
double _clearDepth;
int _clearStencil;
ref_ptr<ColorMask> _colorMask;
ref_ptr<Viewport> _viewport;
TransformOrder _transformOrder;
ProjectionResizePolicy _projectionResizePolicy;
Matrixd _projectionMatrix;
Matrixd _viewMatrix;
RenderOrder _renderOrder;
int _renderOrderNum;
GLenum _drawBuffer;
GLenum _readBuffer;
RenderTargetImplementation _renderTargetImplementation;
RenderTargetImplementation _renderTargetFallback;
BufferAttachmentMap _bufferAttachmentMap;
2007-07-28 18:28:40 +08:00
ref_ptr<OperationThread> _cameraThread;
ref_ptr<GraphicsContext> _graphicsContext;
ref_ptr<GraphicsOperation> _renderer;
ref_ptr<Object> _renderingCache;
ref_ptr<DrawCallback> _initialDrawCallback;
ref_ptr<DrawCallback> _preDrawCallback;
ref_ptr<DrawCallback> _postDrawCallback;
ref_ptr<DrawCallback> _finalDrawCallback;
};
}
#endif