1/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield
3 * This library is open source and may be redistributed and/or modified under
4 * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
5 * (at your option) any later version. The full license is in LICENSE file
6 * included with this distribution, and on the openscenegraph.org website.
8 * This library is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * OpenSceneGraph Public License for more details.
17#include <osg/Transform>
18#include <osg/Viewport>
19#include <osg/ColorMask>
20#include <osg/CullSettings>
23#include <osg/GraphicsContext>
26#include <OpenThreads/Mutex>
29#if defined(OSG_GLES1_AVAILABLE) || defined(OSG_GLES2_AVAILABLE) || defined(OSG_GLES3_AVAILABLE) && !defined(OSG_GL3_AVAILABLE)
30 #define GL_FRONT_LEFT 0x0400
31 #define GL_FRONT_RIGHT 0x0401
32 #define GL_BACK_LEFT 0x0402
33 #define GL_BACK_RIGHT 0x0403
38// forward declare View to allow Camera to point back to the View that its within
42/** Camera - is a subclass of Transform which represents encapsulates the settings of a Camera.
44class OSG_EXPORT Camera : public Transform, public CullSettings
51 /** Copy constructor using CopyOp to manage deep vs shallow copy.*/
52 Camera(const Camera&,const CopyOp& copyop=CopyOp::SHALLOW_COPY);
54 META_Node(osg, Camera);
56 virtual Camera* asCamera() { return this; }
57 virtual const Camera* asCamera() const { return this; }
59 /** Set the View that this Camera is part of. */
60 void setView(View* view) { _view = view; }
62 /** Get the View that this Camera is part of. */
63 View* getView() { return _view; }
65 /** Get the const View that this Camera is part of. */
66 const View* getView() const { return _view; }
69 /** Set the Stats object used to collect various frame related
70 * timing and scene graph stats. */
71 void setStats(osg::Stats* stats) { _stats = stats; }
73 /** Get the Stats object.*/
74 osg::Stats* getStats() { return _stats.get(); }
76 /** Get the const Stats object.*/
77 const osg::Stats* getStats() const { return _stats.get(); }
80 /** Set whether this camera allows events to be generated by the
81 * associated graphics window to be associated with this camera. */
82 void setAllowEventFocus(bool focus) { _allowEventFocus = focus; }
84 /** Get whether this camera allows events to be generated by the
85 * associated graphics window to be associated with this camera. */
86 bool getAllowEventFocus() const { return _allowEventFocus; }
89 /** Set the DisplaySettings object associated with this view.*/
90 void setDisplaySettings(osg::DisplaySettings* ds) { _displaySettings = ds; }
92 /** Get the DisplaySettings object associated with this view.*/
93 osg::DisplaySettings* getDisplaySettings() { return _displaySettings.get(); }
95 /** Get the const DisplaySettings object associated with this view.*/
96 const osg::DisplaySettings* getDisplaySettings() const { return _displaySettings.get(); }
99 /** Set the clear mask used in glClear().
100 * Defaults to GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT. */
101 inline void setClearMask(GLbitfield mask) { _clearMask = mask; applyMaskAction(CLEAR_MASK); }
103 /** Get the clear mask.*/
104 inline GLbitfield getClearMask() const { return _clearMask; }
106 /** Set the clear color used in glClearColor().
107 * glClearColor is only called if mask & GL_COLOR_BUFFER_BIT is true*/
108 void setClearColor(const osg::Vec4& color) { _clearColor=color; applyMaskAction(CLEAR_COLOR); }
110 /** Get the clear color.*/
111 const osg::Vec4& getClearColor() const { return _clearColor; }
113 /** Set the clear accum used in glClearAccum().
114 * glClearAcumm is only called if mask & GL_ACCUM_BUFFER_BIT is true. */
115 void setClearAccum(const osg::Vec4& color) { _clearAccum=color; }
117 /** Get the clear accum value.*/
118 const osg::Vec4& getClearAccum() const { return _clearAccum; }
120 /** Set the clear depth used in glClearDepth(). Defaults to 1.0
121 * glClearDepth is only called if mask & GL_DEPTH_BUFFER_BIT is true. */
122 void setClearDepth(double depth) { _clearDepth=depth; }
124 /** Get the clear depth value.*/
125 double getClearDepth() const { return _clearDepth; }
127 /** Set the clear stencil value used in glClearStencil(). Defaults to 0;
128 * glClearStencil is only called if mask & GL_STENCIL_BUFFER_BIT is true*/
129 void setClearStencil(int stencil) { _clearStencil=stencil; }
131 /** Get the clear stencil value.*/
132 int getClearStencil() const { return _clearStencil; }
135 /** Set the color mask of the camera to use specified osg::ColorMask. */
136 void setColorMask(osg::ColorMask* colorMask);
139 /** Set the color mask of the camera to specified values. */
140 void setColorMask(bool red, bool green, bool blue, bool alpha);
142 /** Get the const ColorMask. */
143 const ColorMask* getColorMask() const { return _colorMask.get(); }
145 /** Get the ColorMask. */
146 ColorMask* getColorMask() { return _colorMask.get(); }
149 /** Set the viewport of the camera to use specified osg::Viewport. */
150 void setViewport(osg::Viewport* viewport);
152 /** Set the viewport of the camera to specified dimensions. */
153 void setViewport(int x,int y,int width,int height);
155 /** Get the const viewport. */
156 const Viewport* getViewport() const { return _viewport.get(); }
158 /** Get the viewport. */
159 Viewport* getViewport() { return _viewport.get(); }
169 /** Set the transformation order for world-to-local and local-to-world transformation.*/
170 void setTransformOrder(TransformOrder order) { _transformOrder = order; }
172 /** Get the transformation order.*/
173 TransformOrder getTransformOrder() const { return _transformOrder; }
175 enum ProjectionResizePolicy
177 FIXED, /**< Keep the projection matrix fixed, despite window resizes.*/
178 HORIZONTAL, /**< Adjust the HORIZONTAL field of view on window resizes.*/
179 VERTICAL /**< Adjust the VERTICAL field of view on window resizes.*/
183 /** Set the policy used to determine if and how the projection matrix should be adjusted on window resizes. */
184 inline void setProjectionResizePolicy(ProjectionResizePolicy policy) { _projectionResizePolicy = policy; }
186 /** Get the policy used to determine if and how the projection matrix should be adjusted on window resizes. */
187 inline ProjectionResizePolicy getProjectionResizePolicy() const { return _projectionResizePolicy; }
190 /** Set the projection matrix. Can be thought of as setting the lens of a camera. */
191 inline void setProjectionMatrix(const osg::Matrixf& matrix) { _projectionMatrix.set(matrix); }
193 /** Set the projection matrix. Can be thought of as setting the lens of a camera. */
194 inline void setProjectionMatrix(const osg::Matrixd& matrix) { _projectionMatrix.set(matrix); }
196 /** Set to an orthographic projection. See OpenGL glOrtho for documentation further details.*/
197 void setProjectionMatrixAsOrtho(double left, double right,
198 double bottom, double top,
199 double zNear, double zFar);
201 /** Set to a 2D orthographic projection. See OpenGL glOrtho2D documentation for further details.*/
202 void setProjectionMatrixAsOrtho2D(double left, double right,
203 double bottom, double top);
205 /** Set to a perspective projection. See OpenGL glFrustum documentation for further details.*/
206 void setProjectionMatrixAsFrustum(double left, double right,
207 double bottom, double top,
208 double zNear, double zFar);
210 /** Create a symmetrical perspective projection, See OpenGL gluPerspective documentation for further details.
211 * Aspect ratio is defined as width/height.*/
212 void setProjectionMatrixAsPerspective(double fovy,double aspectRatio,
213 double zNear, double zFar);
215 /** Get the projection matrix.*/
216 osg::Matrixd& getProjectionMatrix() { return _projectionMatrix; }
218 /** Get the const projection matrix.*/
219 const osg::Matrixd& getProjectionMatrix() const { return _projectionMatrix; }
221 /** Get the orthographic settings of the orthographic projection matrix.
222 * Returns false if matrix is not an orthographic matrix, where parameter values are undefined.*/
223 bool getProjectionMatrixAsOrtho(double& left, double& right,
224 double& bottom, double& top,
225 double& zNear, double& zFar) const;
227 /** Get the frustum setting of a perspective projection matrix.
228 * Returns false if matrix is not a perspective matrix, where parameter values are undefined.*/
229 bool getProjectionMatrixAsFrustum(double& left, double& right,
230 double& bottom, double& top,
231 double& zNear, double& zFar) const;
233 /** Get the frustum setting of a symmetric perspective projection matrix.
234 * Returns false if matrix is not a perspective matrix, where parameter values are undefined.
235 * Note, if matrix is not a symmetric perspective matrix then the shear will be lost.
236 * Asymmetric matrices occur when stereo, power walls, caves and reality center display are used.
237 * In these configurations one should use the 'getProjectionMatrixAsFrustum' method instead.*/
238 bool getProjectionMatrixAsPerspective(double& fovy,double& aspectRatio,
239 double& zNear, double& zFar) const;
243 /** Set the view matrix. Can be thought of as setting the position of the world relative to the camera in camera coordinates. */
244 inline void setViewMatrix(const osg::Matrixf& matrix) { _viewMatrix.set(matrix); dirtyBound();}
246 /** Set the view matrix. Can be thought of as setting the position of the world relative to the camera in camera coordinates. */
247 inline void setViewMatrix(const osg::Matrixd& matrix) { _viewMatrix.set(matrix); dirtyBound();}
249 /** Get the view matrix. */
250 osg::Matrixd& getViewMatrix() { return _viewMatrix; }
252 /** Get the const view matrix. */
253 const osg::Matrixd& getViewMatrix() const { return _viewMatrix; }
255 /** Set to the position and orientation of view matrix, using the same convention as gluLookAt. */
256 void setViewMatrixAsLookAt(const osg::Vec3d& eye,const osg::Vec3d& center,const osg::Vec3d& up);
258 /** Get to the position and orientation of a modelview matrix, using the same convention as gluLookAt. */
259 void getViewMatrixAsLookAt(osg::Vec3d& eye,osg::Vec3d& center,osg::Vec3d& up,double lookDistance=1.0) const;
261 /** Get to the position and orientation of a modelview matrix, using the same convention as gluLookAt. */
262 void getViewMatrixAsLookAt(osg::Vec3f& eye,osg::Vec3f& center,osg::Vec3f& up,float lookDistance=1.0f) const;
264 /** Get the inverse view matrix.*/
265 Matrixd getInverseViewMatrix() const;
275 /** Set the rendering order of this camera's subgraph relative to any camera that this subgraph is nested within.
276 * For rendering to a texture, one typically uses PRE_RENDER.
277 * For Head Up Displays, one would typically use POST_RENDER.*/
278 void setRenderOrder(RenderOrder order, int orderNum = 0) { _renderOrder = order; _renderOrderNum = orderNum; }
280 /** Get the rendering order of this camera's subgraph relative to any camera that this subgraph is nested within.*/
281 RenderOrder getRenderOrder() const { return _renderOrder; }
283 /** Get the rendering order number of this camera relative to any sibling cameras in this subgraph.*/
284 int getRenderOrderNum() const { return _renderOrderNum; }
286 /** Return true if this Camera is set up as a render to texture camera, i.e. it has textures assigned to it.*/
287 bool isRenderToTextureCamera() const;
289 enum RenderTargetImplementation
298 /** Set the render target.*/
299 void setRenderTargetImplementation(RenderTargetImplementation impl);
301 /** Set the render target and fall-back that's used if the former isn't available.*/
302 void setRenderTargetImplementation(RenderTargetImplementation impl, RenderTargetImplementation fallback);
304 /** Get the render target.*/
305 RenderTargetImplementation getRenderTargetImplementation() const { return _renderTargetImplementation; }
307 /** Get the render target fallback.*/
308 RenderTargetImplementation getRenderTargetFallback() const { return _renderTargetFallback; }
311 /** Set the draw buffer used at the start of each frame draw.
312 * Note, a buffer value of GL_NONE is used to specify that the rendering back-end should choose the most appropriate buffer.*/
313 void setDrawBuffer(GLenum buffer) { _drawBuffer = buffer; applyMaskAction( DRAW_BUFFER ); }
315 /** Get the draw buffer used at the start of each frame draw. */
316 GLenum getDrawBuffer() const { return _drawBuffer; }
318 /** Set the read buffer for any required copy operations to use.
319 * Note, a buffer value of GL_NONE is used to specify that the rendering back-end should choose the most appropriate buffer.*/
320 void setReadBuffer(GLenum buffer) { _readBuffer = buffer; applyMaskAction( READ_BUFFER ); }
322 /** Get the read buffer for any required copy operations to use. */
323 GLenum getReadBuffer() const { return _readBuffer; }
329 PACKED_DEPTH_STENCIL_BUFFER,
332 COLOR_BUFFER1 = COLOR_BUFFER0+1,
333 COLOR_BUFFER2 = COLOR_BUFFER0+2,
334 COLOR_BUFFER3 = COLOR_BUFFER0+3,
335 COLOR_BUFFER4 = COLOR_BUFFER0+4,
336 COLOR_BUFFER5 = COLOR_BUFFER0+5,
337 COLOR_BUFFER6 = COLOR_BUFFER0+6,
338 COLOR_BUFFER7 = COLOR_BUFFER0+7,
339 COLOR_BUFFER8 = COLOR_BUFFER0+8,
340 COLOR_BUFFER9 = COLOR_BUFFER0+9,
341 COLOR_BUFFER10 = COLOR_BUFFER0+10,
342 COLOR_BUFFER11 = COLOR_BUFFER0+11,
343 COLOR_BUFFER12 = COLOR_BUFFER0+12,
344 COLOR_BUFFER13 = COLOR_BUFFER0+13,
345 COLOR_BUFFER14 = COLOR_BUFFER0+14,
346 COLOR_BUFFER15 = COLOR_BUFFER0+15
349 static const unsigned int FACE_CONTROLLED_BY_GEOMETRY_SHADER;
351 /** Attach a buffer with specified OpenGL internal format.*/
352 void attach(BufferComponent buffer, GLenum internalFormat);
354 /** Attach a Texture to specified buffer component.
355 * The level parameter controls the mip map level of the texture that is attached.
356 * The face parameter controls the face of texture cube map or z level of 3d texture.
357 * The mipMapGeneration flag controls whether mipmap generation should be done for texture.*/
358 void attach(BufferComponent buffer, osg::Texture* texture, unsigned int level = 0, unsigned int face=0, bool mipMapGeneration=false,
359 unsigned int multisampleSamples = 0,
360 unsigned int multisampleColorSamples = 0);
362 /** Attach a Image to specified buffer component.*/
363 void attach(BufferComponent buffer, osg::Image* image,
364 unsigned int multisampleSamples = 0,
365 unsigned int multisampleColorSamples = 0);
367 /** Detach specified buffer component.*/
368 void detach(BufferComponent buffer);
373 _internalFormat(GL_NONE),
376 _mipMapGeneration(false),
377 _multisampleSamples(0),
378 _multisampleColorSamples(0) {}
382 if (_texture.valid()) return _texture->getTextureWidth();
383 if (_image.valid()) return _image->s();
389 if (_texture.valid()) return _texture->getTextureHeight();
390 if (_image.valid()) return _image->t();
396 if (_texture.valid()) return _texture->getTextureDepth();
397 if (_image.valid()) return _image->r();
401 GLenum _internalFormat;
402 ref_ptr<Image> _image;
403 ref_ptr<Texture> _texture;
406 bool _mipMapGeneration;
407 unsigned int _multisampleSamples;
408 unsigned int _multisampleColorSamples;
411 typedef std::map< BufferComponent, Attachment> BufferAttachmentMap;
413 /** Get the BufferAttachmentMap, used to configure frame buffer objects, pbuffers and texture reads.*/
414 BufferAttachmentMap& getBufferAttachmentMap() { return _bufferAttachmentMap; }
416 /** Get the const BufferAttachmentMap, used to configure frame buffer objects, pbuffers and texture reads.*/
417 const BufferAttachmentMap& getBufferAttachmentMap() const { return _bufferAttachmentMap; }
420 /** Increment the _attachementMapModifiedCount so that the rendering backend will know that it needs to be updated to handle any new settings (such as format change/resizes.).*/
421 void dirtyAttachmentMap() { ++_attachmentMapModifiedCount; }
423 /** Set the AttachmentMapModifiedCount to a specific value. Note, normal usage you would simply call dirtyAttachmentMap(). */
424 void setAttachmentMapModifiedCount(unsigned int v) { _attachmentMapModifiedCount = v; }
426 /** Get the AttachmentMapModifiedCount. */
427 unsigned int getAttachmentMapModifiedCount() const { return _attachmentMapModifiedCount; }
429 /** Resize the image and textures in the AttachementMap.*/
430 void resizeAttachments(int width, int height);
436 RESIZE_ATTACHMENTS=2,
437 RESIZE_PROJECTIONMATRIX=4,
438 RESIZE_DEFAULT=RESIZE_VIEWPORT|RESIZE_ATTACHMENTS
441 /** Resize, to the specified width and height, the viewport, attachments and projection matrix according to the resizeMask provided.
442 * Note, the adjustment of the projection matrix is done if the RESIZE_PROJECTIONMATRIX mask to set and according to the rules specified in the ProjectionResizePolicy. */
443 void resize(int width, int height, int resizeMask=RESIZE_DEFAULT);
446 /** Explicit control over implicit allocation of buffers when using FBO.
447 Implicit buffers are automatically substituted when user have not attached such buffer.
449 Camera may set up two FBOs: primary Render FBO and secondary Resolve FBO for multisample usage.
450 So in practice we have two masks defined for the Camera:
451 implicitBufferAttachmentRenderMask
452 implicitBufferAttachmentResolveMask
453 They can be set together by setImplicitBufferAttachmentMask method, or separately
454 by setImplicitBufferAttachmentRenderMask and setImplicitBufferAttachmentResolveMask.
456 Camera defaults are USE_DISPLAY_SETTINGS_MASK which means that by default
457 Camera chooses to substitute buffer attachments as defined by DisplaySettings.
459 Usually DisplaySettings implicit buffer attachment selection defaults to: DEPTH and COLOR
460 for both primary (Render) FBO and seconday Multisample (Resolve) FBO
461 ie: IMPLICIT_DEPTH_BUFFER_ATTACHMENT | IMPLICIT_COLOR_BUFFER_ATTACHMENT
463 If these masks are not changed and user did not attach depth buffer and/or color buffer
464 to Camera, then OSG implicitly substitutes these buffers.
465 By default it does not implicitly allocate a stencil buffer.
466 Use implicit buffer attachment masks to override default behavior:
467 to turn off DEPTH or COLOR buffer substitution or to enforce STENCIL buffer substitution.
469 Note that both values are ignored if not using FBO.
470 Note that the second mask value is ignored if not using MSFBO.
472 enum ImplicitBufferAttachment
474 IMPLICIT_DEPTH_BUFFER_ATTACHMENT = DisplaySettings::IMPLICIT_DEPTH_BUFFER_ATTACHMENT,
475 IMPLICIT_STENCIL_BUFFER_ATTACHMENT = DisplaySettings::IMPLICIT_STENCIL_BUFFER_ATTACHMENT,
476 IMPLICIT_COLOR_BUFFER_ATTACHMENT = DisplaySettings::IMPLICIT_COLOR_BUFFER_ATTACHMENT,
477 USE_DISPLAY_SETTINGS_MASK = (~0)
480 typedef int ImplicitBufferAttachmentMask;
482 void setImplicitBufferAttachmentMask(ImplicitBufferAttachmentMask renderMask = DisplaySettings::DEFAULT_IMPLICIT_BUFFER_ATTACHMENT, ImplicitBufferAttachmentMask resolveMask = DisplaySettings::DEFAULT_IMPLICIT_BUFFER_ATTACHMENT)
484 _implicitBufferAttachmentRenderMask = renderMask;
485 _implicitBufferAttachmentResolveMask = resolveMask;
488 void setImplicitBufferAttachmentRenderMask(ImplicitBufferAttachmentMask implicitBufferAttachmentRenderMask)
490 _implicitBufferAttachmentRenderMask = implicitBufferAttachmentRenderMask;
493 void setImplicitBufferAttachmentResolveMask(ImplicitBufferAttachmentMask implicitBufferAttachmentResolveMask)
495 _implicitBufferAttachmentResolveMask = implicitBufferAttachmentResolveMask;
498 ImplicitBufferAttachmentMask getImplicitBufferAttachmentRenderMask() const
500 return _implicitBufferAttachmentRenderMask;
504 Get mask selecting implicit buffer attachments for Camera primary FBO
505 if effectiveMask parameter is set, method follows USE_DISPLAY_SETTINGS_MASK dependence and returns effective mask
506 if effectiveMask parameter is reset, method returns nominal mask set by the Camera
508 ImplicitBufferAttachmentMask getImplicitBufferAttachmentRenderMask(bool effectiveMask) const
510 if( effectiveMask && _implicitBufferAttachmentRenderMask == USE_DISPLAY_SETTINGS_MASK )
512 const DisplaySettings * ds = _displaySettings.valid() ? _displaySettings.get() : DisplaySettings::instance().get();
513 return ds->getImplicitBufferAttachmentRenderMask();
517 return _implicitBufferAttachmentRenderMask;
521 ImplicitBufferAttachmentMask getImplicitBufferAttachmentResolveMask() const
523 return _implicitBufferAttachmentResolveMask;
527 Get mask selecting implicit buffer attachments for Camera secondary MULTISAMPLE FBO
528 if effectiveMask parameter is set, method follows USE_DISPLAY_SETTINGS_MASK dependence and returns effective mask
529 if effectiveMask parameter is reset, method returns nominal mask set by the Camera
531 ImplicitBufferAttachmentMask getImplicitBufferAttachmentResolveMask(bool effectiveMask) const
533 if( effectiveMask && _implicitBufferAttachmentResolveMask == USE_DISPLAY_SETTINGS_MASK )
535 const DisplaySettings * ds = _displaySettings.valid() ? _displaySettings.get() : DisplaySettings::instance().get();
536 return ds->getImplicitBufferAttachmentResolveMask();
540 return _implicitBufferAttachmentResolveMask;
544 /** Set the process affinity hint for any Camera Threads that are/will be assigned to this Camera.*/
545 void setProcessorAffinity(const OpenThreads::Affinity& affinity);
546 OpenThreads::Affinity& getProcessorAffinity() { return _affinity; }
547 const OpenThreads::Affinity& getProcessorAffinity() const { return _affinity; }
549 /** Create a operation thread for this camera.*/
550 void createCameraThread();
552 /** Assign a operation thread to the camera.*/
553 void setCameraThread(OperationThread* gt);
555 /** Get the operation thread assigned to this camera.*/
556 OperationThread* getCameraThread() { return _cameraThread.get(); }
558 /** Get the const operation thread assigned to this camera.*/
559 const OperationThread* getCameraThread() const { return _cameraThread.get(); }
563 /** Set the GraphicsContext that provides the mechansim for managing the OpenGL graphics context associated with this camera.*/
564 void setGraphicsContext(GraphicsContext* context);
566 /** Get the GraphicsContext.*/
567 GraphicsContext* getGraphicsContext() { return _graphicsContext.get(); }
569 /** Get the const GraphicsContext.*/
570 const GraphicsContext* getGraphicsContext() const { return _graphicsContext.get(); }
573 /** Set the Rendering object that is used to implement rendering of the subgraph.*/
574 void setRenderer(osg::GraphicsOperation* rc) { _renderer = rc; }
576 /** Get the Rendering object that is used to implement rendering of the subgraph.*/
577 osg::GraphicsOperation* getRenderer() { return _renderer.get(); }
579 /** Get the const Rendering object that is used to implement rendering of the subgraph.*/
580 const osg::GraphicsOperation* getRenderer() const { return _renderer.get(); }
583 /** Set the Rendering cache that is used for cached objects associated with rendering of subgraphs.*/
584 void setRenderingCache(osg::Object* rc) { _renderingCache = rc; }
586 /** Get the Rendering cache that is used for cached objects associated with rendering of subgraphs.*/
587 osg::Object* getRenderingCache() { return _renderingCache.get(); }
589 /** Get the const Rendering cache that is used for cached objects associated with rendering of subgraphs.*/
590 const osg::Object* getRenderingCache() const { return _renderingCache.get(); }
593 /** Draw callback for custom operations.*/
594 struct OSG_EXPORT DrawCallback : Callback
598 DrawCallback(const DrawCallback& org,const CopyOp& copyop):
599 Callback(org, copyop) {}
601 META_Object(osg, DrawCallback);
603 /** Functor method called by rendering thread to recursively launch operator() on _nestedcallback **/
604 inline void run(osg::RenderInfo& renderInfo) const
606 operator () (renderInfo);
608 if (_nestedCallback.valid())
609 ((const DrawCallback*)_nestedCallback.get())->run(renderInfo);
612 /** Users will typically override this method to carry tasks such as screen capture or bufferobject readback. **/
613 virtual void operator () (osg::RenderInfo& renderInfo) const;
615 /** Functor method, provided for backwards compatibility, called by operator() (osg::RenderInfo& renderInfo) method.**/
616 virtual void operator () (const osg::Camera& /*camera*/) const {}
618 /** Resize any per context GLObject buffers to specified size. */
619 virtual void resizeGLObjectBuffers(unsigned int maxSize)
621 if (_nestedCallback.valid())
622 _nestedCallback->resizeGLObjectBuffers(maxSize);
625 /** If State is non-zero, this function releases any associated OpenGL objects for
626 * the specified graphics context. Otherwise, releases OpenGL objexts
627 * for all graphics contexts. */
628 virtual void releaseGLObjects(osg::State* state = 0) const
630 if (_nestedCallback.valid())
631 _nestedCallback->releaseGLObjects(state);
636 /** Set the initial draw callback for custom operations to be done before the drawing of the camera's subgraph and pre render stages.*/
637 void setInitialDrawCallback(DrawCallback* cb) { _initialDrawCallback = cb; }
639 /** Get the initial draw callback.*/
640 DrawCallback* getInitialDrawCallback() { return _initialDrawCallback.get(); }
642 /** Get the const initial draw callback.*/
643 const DrawCallback* getInitialDrawCallback() const { return _initialDrawCallback.get(); }
645 /** Convenience method that sets DrawCallback Initial callback of the node if it doesn't exist, or nest it into the existing one. */
646 inline void addInitialDrawCallback(DrawCallback* nc)
650 if (_initialDrawCallback.valid()) _initialDrawCallback->addNestedCallback(nc);
651 else setInitialDrawCallback(nc);
655 template<class T> void addInitialDrawCallback(const ref_ptr<T>& nc) { addInitialDrawCallback(nc.get()); }
657 /** Convenience method that removes a given callback from a node, even if that callback is nested. There is no error return in case the given callback is not found. */
658 inline void removeInitialDrawCallback(DrawCallback* nc)
660 if (nc != NULL && _initialDrawCallback.valid())
662 if (_initialDrawCallback == nc)
664 ref_ptr< DrawCallback> new_nested_callback = (DrawCallback*) nc->getNestedCallback();
665 nc->setNestedCallback(0);
666 setInitialDrawCallback(new_nested_callback.get());
668 else _initialDrawCallback->removeNestedCallback(nc);
672 template<class T> void removeInitialDrawCallback(const ref_ptr<T>& nc) { removeInitialDrawCallback(nc.get()); }
674 /** 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.*/
675 void setPreDrawCallback(DrawCallback* cb) { _preDrawCallback = cb; }
677 /** Get the pre draw callback.*/
678 DrawCallback* getPreDrawCallback() { return _preDrawCallback.get(); }
680 /** Get the const pre draw callback.*/
681 const DrawCallback* getPreDrawCallback() const { return _preDrawCallback.get(); }
683 /** Convenience method that sets DrawCallback Initial callback of the node if it doesn't exist, or nest it into the existing one. */
684 inline void addPreDrawCallback(DrawCallback* nc)
688 if (_preDrawCallback.valid()) _preDrawCallback->addNestedCallback(nc);
689 else setPreDrawCallback(nc);
693 template<class T> void addPreDrawCallback(const ref_ptr<T>& nc) { addPreDrawCallback(nc.get()); }
695 /** Convenience method that removes a given callback from a node, even if that callback is nested. There is no error return in case the given callback is not found. */
696 inline void removePreDrawCallback(DrawCallback* nc)
698 if (nc != NULL && _preDrawCallback.valid())
700 if (_preDrawCallback == nc)
702 ref_ptr< DrawCallback> new_nested_callback = (DrawCallback*) nc->getNestedCallback();
703 nc->setNestedCallback(0);
704 setPreDrawCallback(new_nested_callback.get());
706 else _preDrawCallback->removeNestedCallback(nc);
710 template<class T> void removePreDrawCallback(const ref_ptr<T>& nc) { removePreDrawCallback(nc.get()); }
712 /** 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.*/
713 void setPostDrawCallback(DrawCallback* cb) { _postDrawCallback = cb; }
715 /** Get the post draw callback.*/
716 DrawCallback* getPostDrawCallback() { return _postDrawCallback.get(); }
718 /** Get the const post draw callback.*/
719 const DrawCallback* getPostDrawCallback() const { return _postDrawCallback.get(); }
721 /** Convenience method that sets DrawCallback Initial callback of the node if it doesn't exist, or nest it into the existing one. */
722 inline void addPostDrawCallback(DrawCallback* nc)
726 if (_postDrawCallback.valid()) _postDrawCallback->addNestedCallback(nc);
727 else setPostDrawCallback(nc);
731 template<class T> void addPostDrawCallback(const ref_ptr<T>& nc) { addPostDrawCallback(nc.get()); }
733 /** Convenience method that removes a given callback from a node, even if that callback is nested. There is no error return in case the given callback is not found. */
734 inline void removePostDrawCallback(DrawCallback* nc)
736 if (nc != NULL && _postDrawCallback.valid())
738 if (_postDrawCallback == nc)
740 ref_ptr< DrawCallback> new_nested_callback = (DrawCallback*) nc->getNestedCallback();
741 nc->setNestedCallback(0);
742 setPostDrawCallback(new_nested_callback.get());
744 else _postDrawCallback->removeNestedCallback(nc);
748 template<class T> void removePostDrawCallback(const ref_ptr<T>& nc) { removePostDrawCallback(nc.get()); }
750 /** 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.*/
751 void setFinalDrawCallback(DrawCallback* cb) { _finalDrawCallback = cb; }
753 /** Get the final draw callback.*/
754 DrawCallback* getFinalDrawCallback() { return _finalDrawCallback.get(); }
756 /** Get the const final draw callback.*/
757 const DrawCallback* getFinalDrawCallback() const { return _finalDrawCallback.get(); }
759 /** Convenience method that sets DrawCallback Initial callback of the node if it doesn't exist, or nest it into the existing one. */
760 inline void addFinalDrawCallback(DrawCallback* nc)
764 if (_finalDrawCallback.valid()) _finalDrawCallback->addNestedCallback(nc);
765 else setFinalDrawCallback(nc);
769 template<class T> void addFinalDrawCallback(const ref_ptr<T>& nc) { addFinalDrawCallback(nc.get()); }
771 /** Convenience method that removes a given callback from a node, even if that callback is nested. There is no error return in case the given callback is not found. */
772 inline void removeFinalDrawCallback(DrawCallback* nc)
774 if (nc != NULL && _finalDrawCallback.valid())
776 if (_finalDrawCallback == nc)
778 ref_ptr< DrawCallback> new_nested_callback = (DrawCallback*) nc->getNestedCallback();
779 nc->setNestedCallback(0);
780 setFinalDrawCallback(new_nested_callback.get());
782 else _finalDrawCallback->removeNestedCallback(nc);
786 template<class T> void removeFinalDrawCallback(const ref_ptr<T>& nc) { removeFinalDrawCallback(nc.get()); }
788 OpenThreads::Mutex* getDataChangeMutex() const { return &_dataChangeMutex; }
790 /** Resize any per context GLObject buffers to specified size. */
791 virtual void resizeGLObjectBuffers(unsigned int maxSize);
793 /** If State is non-zero, this function releases any associated OpenGL objects for
794 * the specified graphics context. Otherwise, releases OpenGL objexts
795 * for all graphics contexts. */
796 virtual void releaseGLObjects(osg::State* = 0) const;
800 /** Transform method that must be defined to provide generic interface for scene graph traversals.*/
801 virtual bool computeLocalToWorldMatrix(Matrix& matrix,NodeVisitor*) const;
803 /** Transform method that must be defined to provide generic interface for scene graph traversals.*/
804 virtual bool computeWorldToLocalMatrix(Matrix& matrix,NodeVisitor*) const;
806 /** Inherit the local cull settings variable from specified CullSettings object, according to the inheritance mask.*/
807 virtual void inheritCullSettings(const CullSettings& settings, unsigned int inheritanceMask);
813 mutable OpenThreads::Mutex _dataChangeMutex;
818 osg::ref_ptr<osg::Stats> _stats;
820 bool _allowEventFocus;
822 osg::ref_ptr<osg::DisplaySettings> _displaySettings;
824 GLbitfield _clearMask;
825 osg::Vec4 _clearColor;
826 osg::Vec4 _clearAccum;
830 ref_ptr<ColorMask> _colorMask;
831 ref_ptr<Viewport> _viewport;
833 TransformOrder _transformOrder;
834 ProjectionResizePolicy _projectionResizePolicy;
836 Matrixd _projectionMatrix;
839 RenderOrder _renderOrder;
845 RenderTargetImplementation _renderTargetImplementation;
846 RenderTargetImplementation _renderTargetFallback;
847 BufferAttachmentMap _bufferAttachmentMap;
848 ImplicitBufferAttachmentMask _implicitBufferAttachmentRenderMask;
849 ImplicitBufferAttachmentMask _implicitBufferAttachmentResolveMask;
851 unsigned int _attachmentMapModifiedCount;
853 OpenThreads::Affinity _affinity;
854 ref_ptr<OperationThread> _cameraThread;
856 ref_ptr<GraphicsContext> _graphicsContext;
858 ref_ptr<GraphicsOperation> _renderer;
859 ref_ptr<Object> _renderingCache;
861 ref_ptr<DrawCallback> _initialDrawCallback;
862 ref_ptr<DrawCallback> _preDrawCallback;
863 ref_ptr<DrawCallback> _postDrawCallback;
864 ref_ptr<DrawCallback> _finalDrawCallback;
868/** Functor to assist with ordering cameras in the order they should be rendered in.*/
869struct CameraRenderOrderSortOp
871 inline bool operator() (const Camera* lhs,const Camera* rhs) const
873 if (lhs->getRenderOrder()<rhs->getRenderOrder()) return true;
874 if (rhs->getRenderOrder()<lhs->getRenderOrder()) return false;
875 return lhs->getRenderOrderNum()<rhs->getRenderOrderNum();