openscenegraph
Camera
Go to the documentation of this file.
1/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield
2 *
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.
7 *
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.
12*/
13
14#ifndef OSG_CAMERA
15#define OSG_CAMERA 1
16
17#include <osg/Transform>
18#include <osg/Viewport>
19#include <osg/ColorMask>
20#include <osg/CullSettings>
21#include <osg/Texture>
22#include <osg/Image>
23#include <osg/GraphicsContext>
24#include <osg/Stats>
25
26#include <OpenThreads/Mutex>
27
28
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
34#endif
35
36namespace osg {
37
38// forward declare View to allow Camera to point back to the View that its within
39class View;
40class RenderInfo;
41
42/** Camera - is a subclass of Transform which represents encapsulates the settings of a Camera.
43*/
44class OSG_EXPORT Camera : public Transform, public CullSettings
45{
46 public :
47
48
49 Camera();
50
51 /** Copy constructor using CopyOp to manage deep vs shallow copy.*/
52 Camera(const Camera&,const CopyOp& copyop=CopyOp::SHALLOW_COPY);
53
54 META_Node(osg, Camera);
55
56 virtual Camera* asCamera() { return this; }
57 virtual const Camera* asCamera() const { return this; }
58
59 /** Set the View that this Camera is part of. */
60 void setView(View* view) { _view = view; }
61
62 /** Get the View that this Camera is part of. */
63 View* getView() { return _view; }
64
65 /** Get the const View that this Camera is part of. */
66 const View* getView() const { return _view; }
67
68
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; }
72
73 /** Get the Stats object.*/
74 osg::Stats* getStats() { return _stats.get(); }
75
76 /** Get the const Stats object.*/
77 const osg::Stats* getStats() const { return _stats.get(); }
78
79
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; }
83
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; }
87
88
89 /** Set the DisplaySettings object associated with this view.*/
90 void setDisplaySettings(osg::DisplaySettings* ds) { _displaySettings = ds; }
91
92 /** Get the DisplaySettings object associated with this view.*/
93 osg::DisplaySettings* getDisplaySettings() { return _displaySettings.get(); }
94
95 /** Get the const DisplaySettings object associated with this view.*/
96 const osg::DisplaySettings* getDisplaySettings() const { return _displaySettings.get(); }
97
98
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); }
102
103 /** Get the clear mask.*/
104 inline GLbitfield getClearMask() const { return _clearMask; }
105
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); }
109
110 /** Get the clear color.*/
111 const osg::Vec4& getClearColor() const { return _clearColor; }
112
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; }
116
117 /** Get the clear accum value.*/
118 const osg::Vec4& getClearAccum() const { return _clearAccum; }
119
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; }
123
124 /** Get the clear depth value.*/
125 double getClearDepth() const { return _clearDepth; }
126
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; }
130
131 /** Get the clear stencil value.*/
132 int getClearStencil() const { return _clearStencil; }
133
134
135 /** Set the color mask of the camera to use specified osg::ColorMask. */
136 void setColorMask(osg::ColorMask* colorMask);
137
138
139 /** Set the color mask of the camera to specified values. */
140 void setColorMask(bool red, bool green, bool blue, bool alpha);
141
142 /** Get the const ColorMask. */
143 const ColorMask* getColorMask() const { return _colorMask.get(); }
144
145 /** Get the ColorMask. */
146 ColorMask* getColorMask() { return _colorMask.get(); }
147
148
149 /** Set the viewport of the camera to use specified osg::Viewport. */
150 void setViewport(osg::Viewport* viewport);
151
152 /** Set the viewport of the camera to specified dimensions. */
153 void setViewport(int x,int y,int width,int height);
154
155 /** Get the const viewport. */
156 const Viewport* getViewport() const { return _viewport.get(); }
157
158 /** Get the viewport. */
159 Viewport* getViewport() { return _viewport.get(); }
160
161
162
163 enum TransformOrder
164 {
165 PRE_MULTIPLY,
166 POST_MULTIPLY
167 };
168
169 /** Set the transformation order for world-to-local and local-to-world transformation.*/
170 void setTransformOrder(TransformOrder order) { _transformOrder = order; }
171
172 /** Get the transformation order.*/
173 TransformOrder getTransformOrder() const { return _transformOrder; }
174
175 enum ProjectionResizePolicy
176 {
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.*/
180
181 };
182
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; }
185
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; }
188
189
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); }
192
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); }
195
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);
200
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);
204
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);
209
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);
214
215 /** Get the projection matrix.*/
216 osg::Matrixd& getProjectionMatrix() { return _projectionMatrix; }
217
218 /** Get the const projection matrix.*/
219 const osg::Matrixd& getProjectionMatrix() const { return _projectionMatrix; }
220
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;
226
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;
232
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;
240
241
242
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();}
245
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();}
248
249 /** Get the view matrix. */
250 osg::Matrixd& getViewMatrix() { return _viewMatrix; }
251
252 /** Get the const view matrix. */
253 const osg::Matrixd& getViewMatrix() const { return _viewMatrix; }
254
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);
257
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;
260
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;
263
264 /** Get the inverse view matrix.*/
265 Matrixd getInverseViewMatrix() const;
266
267
268 enum RenderOrder
269 {
270 PRE_RENDER,
271 NESTED_RENDER,
272 POST_RENDER
273 };
274
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; }
279
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; }
282
283 /** Get the rendering order number of this camera relative to any sibling cameras in this subgraph.*/
284 int getRenderOrderNum() const { return _renderOrderNum; }
285
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;
288
289 enum RenderTargetImplementation
290 {
291 FRAME_BUFFER_OBJECT,
292 PIXEL_BUFFER_RTT,
293 PIXEL_BUFFER,
294 FRAME_BUFFER,
295 SEPARATE_WINDOW
296 };
297
298 /** Set the render target.*/
299 void setRenderTargetImplementation(RenderTargetImplementation impl);
300
301 /** Set the render target and fall-back that's used if the former isn't available.*/
302 void setRenderTargetImplementation(RenderTargetImplementation impl, RenderTargetImplementation fallback);
303
304 /** Get the render target.*/
305 RenderTargetImplementation getRenderTargetImplementation() const { return _renderTargetImplementation; }
306
307 /** Get the render target fallback.*/
308 RenderTargetImplementation getRenderTargetFallback() const { return _renderTargetFallback; }
309
310
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 ); }
314
315 /** Get the draw buffer used at the start of each frame draw. */
316 GLenum getDrawBuffer() const { return _drawBuffer; }
317
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 ); }
321
322 /** Get the read buffer for any required copy operations to use. */
323 GLenum getReadBuffer() const { return _readBuffer; }
324
325 enum BufferComponent
326 {
327 DEPTH_BUFFER,
328 STENCIL_BUFFER,
329 PACKED_DEPTH_STENCIL_BUFFER,
330 COLOR_BUFFER,
331 COLOR_BUFFER0,
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
347 };
348
349 static const unsigned int FACE_CONTROLLED_BY_GEOMETRY_SHADER;
350
351 /** Attach a buffer with specified OpenGL internal format.*/
352 void attach(BufferComponent buffer, GLenum internalFormat);
353
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);
361
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);
366
367 /** Detach specified buffer component.*/
368 void detach(BufferComponent buffer);
369
370 struct Attachment
371 {
372 Attachment():
373 _internalFormat(GL_NONE),
374 _level(0),
375 _face(0),
376 _mipMapGeneration(false),
377 _multisampleSamples(0),
378 _multisampleColorSamples(0) {}
379
380 int width() const
381 {
382 if (_texture.valid()) return _texture->getTextureWidth();
383 if (_image.valid()) return _image->s();
384 return 0;
385 };
386
387 int height() const
388 {
389 if (_texture.valid()) return _texture->getTextureHeight();
390 if (_image.valid()) return _image->t();
391 return 0;
392 };
393
394 int depth() const
395 {
396 if (_texture.valid()) return _texture->getTextureDepth();
397 if (_image.valid()) return _image->r();
398 return 0;
399 };
400
401 GLenum _internalFormat;
402 ref_ptr<Image> _image;
403 ref_ptr<Texture> _texture;
404 unsigned int _level;
405 unsigned int _face;
406 bool _mipMapGeneration;
407 unsigned int _multisampleSamples;
408 unsigned int _multisampleColorSamples;
409 };
410
411 typedef std::map< BufferComponent, Attachment> BufferAttachmentMap;
412
413 /** Get the BufferAttachmentMap, used to configure frame buffer objects, pbuffers and texture reads.*/
414 BufferAttachmentMap& getBufferAttachmentMap() { return _bufferAttachmentMap; }
415
416 /** Get the const BufferAttachmentMap, used to configure frame buffer objects, pbuffers and texture reads.*/
417 const BufferAttachmentMap& getBufferAttachmentMap() const { return _bufferAttachmentMap; }
418
419
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; }
422
423 /** Set the AttachmentMapModifiedCount to a specific value. Note, normal usage you would simply call dirtyAttachmentMap(). */
424 void setAttachmentMapModifiedCount(unsigned int v) { _attachmentMapModifiedCount = v; }
425
426 /** Get the AttachmentMapModifiedCount. */
427 unsigned int getAttachmentMapModifiedCount() const { return _attachmentMapModifiedCount; }
428
429 /** Resize the image and textures in the AttachementMap.*/
430 void resizeAttachments(int width, int height);
431
432
433 enum ResizeMask
434 {
435 RESIZE_VIEWPORT=1,
436 RESIZE_ATTACHMENTS=2,
437 RESIZE_PROJECTIONMATRIX=4,
438 RESIZE_DEFAULT=RESIZE_VIEWPORT|RESIZE_ATTACHMENTS
439 };
440
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);
444
445
446 /** Explicit control over implicit allocation of buffers when using FBO.
447 Implicit buffers are automatically substituted when user have not attached such buffer.
448
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.
455
456 Camera defaults are USE_DISPLAY_SETTINGS_MASK which means that by default
457 Camera chooses to substitute buffer attachments as defined by DisplaySettings.
458
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
462
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.
468
469 Note that both values are ignored if not using FBO.
470 Note that the second mask value is ignored if not using MSFBO.
471 */
472 enum ImplicitBufferAttachment
473 {
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)
478 };
479
480 typedef int ImplicitBufferAttachmentMask;
481
482 void setImplicitBufferAttachmentMask(ImplicitBufferAttachmentMask renderMask = DisplaySettings::DEFAULT_IMPLICIT_BUFFER_ATTACHMENT, ImplicitBufferAttachmentMask resolveMask = DisplaySettings::DEFAULT_IMPLICIT_BUFFER_ATTACHMENT)
483 {
484 _implicitBufferAttachmentRenderMask = renderMask;
485 _implicitBufferAttachmentResolveMask = resolveMask;
486 }
487
488 void setImplicitBufferAttachmentRenderMask(ImplicitBufferAttachmentMask implicitBufferAttachmentRenderMask)
489 {
490 _implicitBufferAttachmentRenderMask = implicitBufferAttachmentRenderMask;
491 }
492
493 void setImplicitBufferAttachmentResolveMask(ImplicitBufferAttachmentMask implicitBufferAttachmentResolveMask)
494 {
495 _implicitBufferAttachmentResolveMask = implicitBufferAttachmentResolveMask;
496 }
497
498 ImplicitBufferAttachmentMask getImplicitBufferAttachmentRenderMask() const
499 {
500 return _implicitBufferAttachmentRenderMask;
501 }
502
503 /**
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
507 */
508 ImplicitBufferAttachmentMask getImplicitBufferAttachmentRenderMask(bool effectiveMask) const
509 {
510 if( effectiveMask && _implicitBufferAttachmentRenderMask == USE_DISPLAY_SETTINGS_MASK )
511 {
512 const DisplaySettings * ds = _displaySettings.valid() ? _displaySettings.get() : DisplaySettings::instance().get();
513 return ds->getImplicitBufferAttachmentRenderMask();
514 }
515 else
516 {
517 return _implicitBufferAttachmentRenderMask;
518 }
519 }
520
521 ImplicitBufferAttachmentMask getImplicitBufferAttachmentResolveMask() const
522 {
523 return _implicitBufferAttachmentResolveMask;
524 }
525
526 /**
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
530 */
531 ImplicitBufferAttachmentMask getImplicitBufferAttachmentResolveMask(bool effectiveMask) const
532 {
533 if( effectiveMask && _implicitBufferAttachmentResolveMask == USE_DISPLAY_SETTINGS_MASK )
534 {
535 const DisplaySettings * ds = _displaySettings.valid() ? _displaySettings.get() : DisplaySettings::instance().get();
536 return ds->getImplicitBufferAttachmentResolveMask();
537 }
538 else
539 {
540 return _implicitBufferAttachmentResolveMask;
541 }
542 }
543
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; }
548
549 /** Create a operation thread for this camera.*/
550 void createCameraThread();
551
552 /** Assign a operation thread to the camera.*/
553 void setCameraThread(OperationThread* gt);
554
555 /** Get the operation thread assigned to this camera.*/
556 OperationThread* getCameraThread() { return _cameraThread.get(); }
557
558 /** Get the const operation thread assigned to this camera.*/
559 const OperationThread* getCameraThread() const { return _cameraThread.get(); }
560
561
562
563 /** Set the GraphicsContext that provides the mechansim for managing the OpenGL graphics context associated with this camera.*/
564 void setGraphicsContext(GraphicsContext* context);
565
566 /** Get the GraphicsContext.*/
567 GraphicsContext* getGraphicsContext() { return _graphicsContext.get(); }
568
569 /** Get the const GraphicsContext.*/
570 const GraphicsContext* getGraphicsContext() const { return _graphicsContext.get(); }
571
572
573 /** Set the Rendering object that is used to implement rendering of the subgraph.*/
574 void setRenderer(osg::GraphicsOperation* rc) { _renderer = rc; }
575
576 /** Get the Rendering object that is used to implement rendering of the subgraph.*/
577 osg::GraphicsOperation* getRenderer() { return _renderer.get(); }
578
579 /** Get the const Rendering object that is used to implement rendering of the subgraph.*/
580 const osg::GraphicsOperation* getRenderer() const { return _renderer.get(); }
581
582
583 /** Set the Rendering cache that is used for cached objects associated with rendering of subgraphs.*/
584 void setRenderingCache(osg::Object* rc) { _renderingCache = rc; }
585
586 /** Get the Rendering cache that is used for cached objects associated with rendering of subgraphs.*/
587 osg::Object* getRenderingCache() { return _renderingCache.get(); }
588
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(); }
591
592
593 /** Draw callback for custom operations.*/
594 struct OSG_EXPORT DrawCallback : Callback
595 {
596 DrawCallback() {}
597
598 DrawCallback(const DrawCallback& org,const CopyOp& copyop):
599 Callback(org, copyop) {}
600
601 META_Object(osg, DrawCallback);
602
603 /** Functor method called by rendering thread to recursively launch operator() on _nestedcallback **/
604 inline void run(osg::RenderInfo& renderInfo) const
605 {
606 operator () (renderInfo);
607
608 if (_nestedCallback.valid())
609 ((const DrawCallback*)_nestedCallback.get())->run(renderInfo);
610 }
611
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;
614
615 /** Functor method, provided for backwards compatibility, called by operator() (osg::RenderInfo& renderInfo) method.**/
616 virtual void operator () (const osg::Camera& /*camera*/) const {}
617
618 /** Resize any per context GLObject buffers to specified size. */
619 virtual void resizeGLObjectBuffers(unsigned int maxSize)
620 {
621 if (_nestedCallback.valid())
622 _nestedCallback->resizeGLObjectBuffers(maxSize);
623 }
624
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
629 {
630 if (_nestedCallback.valid())
631 _nestedCallback->releaseGLObjects(state);
632 }
633
634 };
635
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; }
638
639 /** Get the initial draw callback.*/
640 DrawCallback* getInitialDrawCallback() { return _initialDrawCallback.get(); }
641
642 /** Get the const initial draw callback.*/
643 const DrawCallback* getInitialDrawCallback() const { return _initialDrawCallback.get(); }
644
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)
647 {
648 if (nc != NULL)
649 {
650 if (_initialDrawCallback.valid()) _initialDrawCallback->addNestedCallback(nc);
651 else setInitialDrawCallback(nc);
652 }
653 }
654
655 template<class T> void addInitialDrawCallback(const ref_ptr<T>& nc) { addInitialDrawCallback(nc.get()); }
656
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)
659 {
660 if (nc != NULL && _initialDrawCallback.valid())
661 {
662 if (_initialDrawCallback == nc)
663 {
664 ref_ptr< DrawCallback> new_nested_callback = (DrawCallback*) nc->getNestedCallback();
665 nc->setNestedCallback(0);
666 setInitialDrawCallback(new_nested_callback.get());
667 }
668 else _initialDrawCallback->removeNestedCallback(nc);
669 }
670 }
671
672 template<class T> void removeInitialDrawCallback(const ref_ptr<T>& nc) { removeInitialDrawCallback(nc.get()); }
673
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; }
676
677 /** Get the pre draw callback.*/
678 DrawCallback* getPreDrawCallback() { return _preDrawCallback.get(); }
679
680 /** Get the const pre draw callback.*/
681 const DrawCallback* getPreDrawCallback() const { return _preDrawCallback.get(); }
682
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)
685 {
686 if (nc != NULL)
687 {
688 if (_preDrawCallback.valid()) _preDrawCallback->addNestedCallback(nc);
689 else setPreDrawCallback(nc);
690 }
691 }
692
693 template<class T> void addPreDrawCallback(const ref_ptr<T>& nc) { addPreDrawCallback(nc.get()); }
694
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)
697 {
698 if (nc != NULL && _preDrawCallback.valid())
699 {
700 if (_preDrawCallback == nc)
701 {
702 ref_ptr< DrawCallback> new_nested_callback = (DrawCallback*) nc->getNestedCallback();
703 nc->setNestedCallback(0);
704 setPreDrawCallback(new_nested_callback.get());
705 }
706 else _preDrawCallback->removeNestedCallback(nc);
707 }
708 }
709
710 template<class T> void removePreDrawCallback(const ref_ptr<T>& nc) { removePreDrawCallback(nc.get()); }
711
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; }
714
715 /** Get the post draw callback.*/
716 DrawCallback* getPostDrawCallback() { return _postDrawCallback.get(); }
717
718 /** Get the const post draw callback.*/
719 const DrawCallback* getPostDrawCallback() const { return _postDrawCallback.get(); }
720
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)
723 {
724 if (nc != NULL)
725 {
726 if (_postDrawCallback.valid()) _postDrawCallback->addNestedCallback(nc);
727 else setPostDrawCallback(nc);
728 }
729 }
730
731 template<class T> void addPostDrawCallback(const ref_ptr<T>& nc) { addPostDrawCallback(nc.get()); }
732
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)
735 {
736 if (nc != NULL && _postDrawCallback.valid())
737 {
738 if (_postDrawCallback == nc)
739 {
740 ref_ptr< DrawCallback> new_nested_callback = (DrawCallback*) nc->getNestedCallback();
741 nc->setNestedCallback(0);
742 setPostDrawCallback(new_nested_callback.get());
743 }
744 else _postDrawCallback->removeNestedCallback(nc);
745 }
746 }
747
748 template<class T> void removePostDrawCallback(const ref_ptr<T>& nc) { removePostDrawCallback(nc.get()); }
749
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; }
752
753 /** Get the final draw callback.*/
754 DrawCallback* getFinalDrawCallback() { return _finalDrawCallback.get(); }
755
756 /** Get the const final draw callback.*/
757 const DrawCallback* getFinalDrawCallback() const { return _finalDrawCallback.get(); }
758
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)
761 {
762 if (nc != NULL)
763 {
764 if (_finalDrawCallback.valid()) _finalDrawCallback->addNestedCallback(nc);
765 else setFinalDrawCallback(nc);
766 }
767 }
768
769 template<class T> void addFinalDrawCallback(const ref_ptr<T>& nc) { addFinalDrawCallback(nc.get()); }
770
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)
773 {
774 if (nc != NULL && _finalDrawCallback.valid())
775 {
776 if (_finalDrawCallback == nc)
777 {
778 ref_ptr< DrawCallback> new_nested_callback = (DrawCallback*) nc->getNestedCallback();
779 nc->setNestedCallback(0);
780 setFinalDrawCallback(new_nested_callback.get());
781 }
782 else _finalDrawCallback->removeNestedCallback(nc);
783 }
784 }
785
786 template<class T> void removeFinalDrawCallback(const ref_ptr<T>& nc) { removeFinalDrawCallback(nc.get()); }
787
788 OpenThreads::Mutex* getDataChangeMutex() const { return &_dataChangeMutex; }
789
790 /** Resize any per context GLObject buffers to specified size. */
791 virtual void resizeGLObjectBuffers(unsigned int maxSize);
792
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;
797
798 public:
799
800 /** Transform method that must be defined to provide generic interface for scene graph traversals.*/
801 virtual bool computeLocalToWorldMatrix(Matrix& matrix,NodeVisitor*) const;
802
803 /** Transform method that must be defined to provide generic interface for scene graph traversals.*/
804 virtual bool computeWorldToLocalMatrix(Matrix& matrix,NodeVisitor*) const;
805
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);
808
809 protected :
810
811 virtual ~Camera();
812
813 mutable OpenThreads::Mutex _dataChangeMutex;
814
815
816 View* _view;
817
818 osg::ref_ptr<osg::Stats> _stats;
819
820 bool _allowEventFocus;
821
822 osg::ref_ptr<osg::DisplaySettings> _displaySettings;
823
824 GLbitfield _clearMask;
825 osg::Vec4 _clearColor;
826 osg::Vec4 _clearAccum;
827 double _clearDepth;
828 int _clearStencil;
829
830 ref_ptr<ColorMask> _colorMask;
831 ref_ptr<Viewport> _viewport;
832
833 TransformOrder _transformOrder;
834 ProjectionResizePolicy _projectionResizePolicy;
835
836 Matrixd _projectionMatrix;
837 Matrixd _viewMatrix;
838
839 RenderOrder _renderOrder;
840 int _renderOrderNum;
841
842 GLenum _drawBuffer;
843 GLenum _readBuffer;
844
845 RenderTargetImplementation _renderTargetImplementation;
846 RenderTargetImplementation _renderTargetFallback;
847 BufferAttachmentMap _bufferAttachmentMap;
848 ImplicitBufferAttachmentMask _implicitBufferAttachmentRenderMask;
849 ImplicitBufferAttachmentMask _implicitBufferAttachmentResolveMask;
850
851 unsigned int _attachmentMapModifiedCount;
852
853 OpenThreads::Affinity _affinity;
854 ref_ptr<OperationThread> _cameraThread;
855
856 ref_ptr<GraphicsContext> _graphicsContext;
857
858 ref_ptr<GraphicsOperation> _renderer;
859 ref_ptr<Object> _renderingCache;
860
861 ref_ptr<DrawCallback> _initialDrawCallback;
862 ref_ptr<DrawCallback> _preDrawCallback;
863 ref_ptr<DrawCallback> _postDrawCallback;
864 ref_ptr<DrawCallback> _finalDrawCallback;
865};
866
867
868/** Functor to assist with ordering cameras in the order they should be rendered in.*/
869struct CameraRenderOrderSortOp
870{
871 inline bool operator() (const Camera* lhs,const Camera* rhs) const
872 {
873 if (lhs->getRenderOrder()<rhs->getRenderOrder()) return true;
874 if (rhs->getRenderOrder()<lhs->getRenderOrder()) return false;
875 return lhs->getRenderOrderNum()<rhs->getRenderOrderNum();
876 }
877};
878
879
880}
881
882#endif