OpenSceneGraph/include/osg/Camera
Robert Osfield 5056f6fee6 Added osg::Camera::ProjectionResizePolicy enum and associated methods for controlling
how the field of view is adjust on window resizes.
2007-05-22 09:32:38 +00:00

460 lines
19 KiB
C++

/* -*-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;
/** 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; }
/** Sets the clear color. */
inline void setClearColor(const Vec4& color) { _clearColor = color; }
/** Returns the clear color. */
inline const Vec4& getClearColor() const { return _clearColor; }
/** 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 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 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); }
/** 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 othographic 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);
/** 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);
/** 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);
/** 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();}
/** Set to the position and orientation of view matrix, using the same convention as gluLookAt. */
void setViewMatrixAsLookAt(const osg::Vec3& eye,const osg::Vec3& center,const osg::Vec3& up);
/** Get the view matrix. */
osg::Matrixd& getViewMatrix() { return _viewMatrix; }
/** Get the const view matrix. */
const osg::Matrixd& getViewMatrix() const { return _viewMatrix; }
/** Get to the position and orientation of a modelview matrix, using the same convention as gluLookAt. */
void getViewMatrixAsLookAt(osg::Vec3& eye,osg::Vec3& center,osg::Vec3& up,float lookDistance=1.0f);
/** 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,
COLOR_BUFFER,
COLOR_BUFFER0 = COLOR_BUFFER,
COLOR_BUFFER1 = COLOR_BUFFER+1,
COLOR_BUFFER2 = COLOR_BUFFER+2,
COLOR_BUFFER3 = COLOR_BUFFER+3,
COLOR_BUFFER4 = COLOR_BUFFER+4,
COLOR_BUFFER5 = COLOR_BUFFER+5,
COLOR_BUFFER6 = COLOR_BUFFER+6,
COLOR_BUFFER7 = COLOR_BUFFER+7
};
void attach(BufferComponent buffer, GLenum internalFormat);
void attach(BufferComponent buffer, osg::Texture* texture, unsigned int level = 0, unsigned int face=0, bool mipMapGeneration=false);
void attach(BufferComponent buffer, osg::Image* image);
void detach(BufferComponent buffer);
struct Attachment
{
Attachment():
_internalFormat(GL_NONE),
_level(0),
_face(0),
_mipMapGeneration(false) {}
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;
};
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(OperationsThread* gt);
/** Get the operation thread assigned to this camera.*/
OperationsThread* getCameraThread() { return _cameraThread.get(); }
/** Get the const operation thread assigned to this camera.*/
const OperationsThread* 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 setRenderingCache(unsigned int contextID, osg::Object* rc) { _renderingCache[contextID] = rc; }
/** Get the Rendering object that is used to implement rendering of the subgraph.*/
osg::Object* getRenderingCache(unsigned int contextID) { return _renderingCache[contextID].get(); }
/** Get the const Rendering object that is used to implement rendering of the subgraph.*/
const osg::Object* getRenderingCache(unsigned int contextID) const { return _renderingCache[contextID].get(); }
/** Draw callback for custom operations.*/
struct DrawCallback : virtual public Object
{
DrawCallback() {}
DrawCallback(const DrawCallback&,const CopyOp&) {}
META_Object(osg,DrawCallback)
virtual void operator () (const osg::Camera& /*camera*/) const {}
};
/** Set the post draw callback for custom operations to do done after the drawing of the camera's subgraph has 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(); }
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;
protected :
virtual ~Camera();
mutable OpenThreads::Mutex _dataChangeMutex;
View* _view;
osg::ref_ptr<osg::Stats> _stats;
bool _allowEventFocus;
Vec4 _clearColor;
GLbitfield _clearMask;
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;
ref_ptr<OperationsThread> _cameraThread;
ref_ptr<GraphicsContext> _graphicsContext;
buffered_object< ref_ptr<Object> > _renderingCache;
ref_ptr<DrawCallback> _postDrawCallback;
};
}
#endif