1 /*---------------------------------------------------------------------------*\
5 * Copyright(C) 2000-2002 by the OpenSG Forum *
9 * contact: dirk@opensg.org, gerrit.voss@vossg.org, jbehr@zgdv.de *
11 \*---------------------------------------------------------------------------*/
12 /*---------------------------------------------------------------------------*\
15 * This library is free software; you can redistribute it and/or modify it *
16 * under the terms of the GNU Library General Public License as published *
17 * by the Free Software Foundation, version 2. *
19 * This library is distributed in the hope that it will be useful, but *
20 * WITHOUT ANY WARRANTY; without even the implied warranty of *
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
22 * Library General Public License for more details. *
24 * You should have received a copy of the GNU Library General Public *
25 * License along with this library; if not, write to the Free Software *
26 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *
28 \*---------------------------------------------------------------------------*/
29 /*---------------------------------------------------------------------------*\
37 \*---------------------------------------------------------------------------*/
39 //---------------------------------------------------------------------------
41 //---------------------------------------------------------------------------
46 #include "OSGConfig.h"
51 #include "OSGFieldContainer.h"
52 #include "OSGAction.h"
54 #include "OSGRenderActionBase.h"
56 #include "OSGDrawEnv.h"
58 #include "OSGBackground.h"
59 #include "OSGViewport.h"
60 #include "OSGWindow.h"
61 #include "OSGCamera.h"
62 #include "OSGForeground.h"
63 #include "OSGFrameBufferObject.h"
65 #include "OSGTraversalValidator.h"
69 // Documentation for this class is emited in the
70 // OSGViewportBase.cpp file.
71 // To modify it, please change the .fcd file (OSGViewport.fcd) and
72 // regenerate the base file.
74 /***************************************************************************\
76 \***************************************************************************/
78 /*-------------------------------------------------------------------------*\
80 \*-------------------------------------------------------------------------*/
82 void Viewport::initMethod(InitPhase ePhase
)
84 Inherited::initMethod(ePhase
);
87 void Viewport::onCreate (const Viewport
*source
)
89 Inherited::onCreate(source
);
92 void Viewport::onCreateAspect(const Viewport
*createAspect
,
93 const Viewport
*source
)
95 Inherited::onCreateAspect(createAspect
, source
);
97 // Don't add the prototype instances to the list
98 if(GlobalSystemState
!= Running
)
102 void Viewport::onDestroy(UInt32 uiContainerId
)
104 Inherited::onDestroy(uiContainerId
);
107 void Viewport::onDestroyAspect(UInt32 uiContainerId
,
110 _pForegroundTask
= NULL
;
112 Inherited::onDestroyAspect(uiContainerId
, uiAspect
);
115 /***************************************************************************\
117 \***************************************************************************/
119 /*------------- constructors & destructors --------------------------------*/
121 Viewport::Viewport(void) :
123 _pForegroundTask(NULL
)
127 Viewport::Viewport(const Viewport
&source
) :
129 _pForegroundTask(NULL
)
134 Viewport::~Viewport(void)
138 void Viewport::changed(ConstFieldMaskArg whichField
,
142 Inherited::changed(whichField
, origin
, details
);
145 /*---------------------------- properties ---------------------------------*/
147 /*! Calculate the positon of the left border of the viewport. Needs a valid
151 Int32
Viewport::calcPixelLeft(void) const
154 return Int32(getLeft());
156 if(getParent() == NULL
)
158 SWARNING
<< "Viewport::getPixelLeft: viewport has no parent window!"
164 return Int32(getParent()->getWidth() * getLeft());
167 /*! Calculate the positon of the right border of the viewport. Needs a valid
171 Int32
Viewport::calcPixelRight(void) const
175 return Int32(getRight());
177 if(getParent() == NULL
)
179 SWARNING
<< "Viewport::getPixelRight: viewport has no parent window!"
185 // <=1: partial screen, use 1 less to not overlap other windows
186 return Int32(getParent()->getWidth() * getRight() - 1);
189 /*! Calculate the positon of the bottom border of the viewport. Needs a valid
193 Int32
Viewport::calcPixelBottom(void) const
196 return Int32(getBottom());
198 if(getParent() == NULL
)
200 SWARNING
<< "Viewport::getPixelBottom: viewport has no parent window!"
206 return Int32(getParent()->getHeight() * getBottom());
209 /*! Calculate the positon of the top border of the viewport. Needs a valid
213 Int32
Viewport::calcPixelTop(void) const
217 return Int32(getTop());
219 if(getParent() == NULL
)
221 SWARNING
<< "Viewport::getPixelTop: viewport has no parent window!"
227 // <=1: partial screen, use 1 less to not overlap other windows
228 return Int32(getParent()->getHeight() * getTop() - 1);
231 /*! Checks if the viewport fills the whole window. Needs a valid
234 bool Viewport::calcIsFullWindow(void) const
236 if(getParent() == NULL
)
238 SWARNING
<< "Viewport::isFullWindow: viewport has no parent window!"
245 calcPixelBottom() == 0 &&
246 calcPixelLeft() == 0 &&
247 calcPixelTop() == getParent()->getHeight() - 1 &&
248 calcPixelRight() == getParent()->getWidth () - 1;
251 Window
*Viewport::getParent(void) const
253 return dynamic_cast<Window
*>(_sfParent
.getValue());
256 /*! Returns normalized coordintes from viewport coordinates.
258 @param normX Normalized X coordinate in the range [-1.0,1.0].
259 @param normY Normalized Y coordinate in the range [-1.0,1.0].
260 @param vpX X coordinate of this viewport in the range [0,width].
261 @param vpY Y coordinate of this viewport in the range [0,height].
263 @note Out-of-range input values lead to out-of-range output values.
265 void Viewport::calcNormalizedCoordinates( Real32
& normX
,
268 const Int32 vpY
) const
271 (vpX
- calcPixelLeft()) /
272 static_cast<Real32
>(calcPixelWidth()) * 2.f
- 1.f
;
275 (vpY
- (getParent()->getHeight() - calcPixelTop())) /
276 static_cast<Real32
>(calcPixelHeight())) * 2.f
;
279 /*-------------------------- your_category---------------------------------*/
281 /*! Draw the viewport. Restrict the OpenGL rendering to the given part of the
282 window, clear it, draw it using the given DrawAction and add the Foregrounds.
284 The _sfCamera, _sfBackground and _sfRoot Fields need to be valid, otherwise
289 Activates scissoring only if the viewport doesn't fill the wholw window, as
290 it significantly slows down some OpenGL implementations.
296 void Viewport::activateSize(void)
298 GLint pl
= calcPixelLeft();
299 GLint pr
= calcPixelRight();
300 GLint pb
= calcPixelBottom();
301 GLint pt
= calcPixelTop();
302 GLint pw
= pr
- pl
+ 1;
303 GLint ph
= pt
- pb
+ 1;
305 glViewport(pl
, pb
, pw
, ph
);
307 if(calcIsFullWindow() == false)
309 glScissor(pl
, pb
, pw
, ph
);
310 glEnable(GL_SCISSOR_TEST
);
314 glDisable(GL_SCISSOR_TEST
);
319 void Viewport::activate(void)
324 void Viewport::deactivate(void)
328 void Viewport::render(RenderActionBase
*action
)
330 _pTravValidator
->incEventCounter();
332 if(getTravMask() == 0x0000 || getEnabled() == false)
335 if(getCamera() == NULL
)
337 SWARNING
<< "Viewport::render: no Camera, can not render!" << std::endl
;
340 if(getBackground() == NULL
)
342 SWARNING
<< "Viewport::render: no Background, can not render!" << std::endl
;
345 if(getRoot() == NULL
)
347 SWARNING
<< "Viewport::render: no root, can not render!" << std::endl
;
351 action
->setCamera (getCamera ());
352 action
->setBackground (getBackground());
353 action
->setViewarea (this );
354 action
->setTraversalRoot(this->getRoot());
355 action
->setTravMask (getTravMask() );
357 action
->setRenderProperties(SystemRenderProperties
.ColorBuffer
|
358 SystemRenderProperties
.DepthBuffer
);
360 action
->apply(this->getRoot());
362 Window
*pWin
= action
->getWindow();
364 if((pWin
->getDrawMode() & Window::PartitionDrawMask
) ==
365 Window::SequentialPartitionDraw
)
369 oEnv
.setWindow(action
->getWindow());
371 oEnv
.setTileFullSize(getCamera()->tileGetFullSize());
372 oEnv
.setTileRegion (getCamera()->tileGetRegion ());
375 oEnv
.setViewportDimension(getPixelLeft (),
382 oEnv
.calcViewportDimension(this->getLeft (),
393 getCamera()->getProjection (m
,
396 getCamera()->getProjectionTranslation(t
,
400 getCamera()->getProjection (m
,
401 oEnv
.getPixelWidth (),
402 oEnv
.getPixelHeight());
403 getCamera()->getProjectionTranslation(t
,
404 oEnv
.getPixelWidth (),
405 oEnv
.getPixelHeight());
406 oEnv
.setupProjection(m
, t
);
409 getCamera()->getViewing(m
,
413 getCamera()->getViewing(m
,
414 oEnv
.getPixelWidth (),
415 oEnv
.getPixelHeight());
416 oEnv
.setupViewing(m
);
418 oEnv
.setDrawerId (action
->getDrawerId ());
419 oEnv
.setDrawableId(action
->getDrawableId());
421 glViewport(oEnv
.getPixelLeft (),
422 oEnv
.getPixelBottom(),
423 oEnv
.getPixelWidth (),
424 oEnv
.getPixelHeight());
426 for(UInt16 i
= 0; i
< getMFForegrounds()->size(); i
++)
428 Foreground
*pForeground
= getForegrounds(i
);
429 FrameBufferObject
*pTarget
= this->getTarget();
433 pTarget
->activate(&oEnv
);
436 pForeground
->draw(&oEnv
);
440 pTarget
->deactivate(&oEnv
);
446 if(_pForegroundTask
== NULL
)
449 new ViewportDrawTask(this, ViewportDrawTask::Foregrounds
);
452 _pForegroundTask
->setIds(action
->getDrawerId (),
453 action
->getDrawableId());
456 pWin
->queueTaskFromDrawer(_pForegroundTask
);
460 void Viewport::renderForegrounds(Window
*pWin
,
466 oEnv
.setWindow(pWin
);
468 oEnv
.setTileFullSize(getCamera()->tileGetFullSize());
469 oEnv
.setTileRegion (getCamera()->tileGetRegion ());
472 oEnv
.setViewportDimension(getPixelLeft (),
479 oEnv
.calcViewportDimension(this->getLeft (),
488 getCamera()->getProjection (m
,
489 oEnv
.getPixelWidth (),
490 oEnv
.getPixelHeight());
491 getCamera()->getProjectionTranslation(t
,
492 oEnv
.getPixelWidth (),
493 oEnv
.getPixelHeight());
494 oEnv
.setupProjection(m
, t
);
496 getCamera()->getViewing(m
,
497 oEnv
.getPixelWidth (),
498 oEnv
.getPixelHeight());
499 oEnv
.setupViewing(m
);
501 oEnv
.setDrawerId (iDrawerId
);
502 oEnv
.setDrawableId(iDrawableId
);
504 glViewport(oEnv
.getPixelLeft (),
505 oEnv
.getPixelBottom(),
506 oEnv
.getPixelWidth (),
507 oEnv
.getPixelHeight());
509 if(oEnv
.getFull() == false)
511 glScissor(oEnv
.getPixelLeft (),
512 oEnv
.getPixelBottom(),
513 oEnv
.getPixelWidth (),
514 oEnv
.getPixelHeight());
516 glEnable(GL_SCISSOR_TEST
);
520 glDisable(GL_SCISSOR_TEST
);
523 for(UInt16 i
=0; i
< getMFForegrounds()->size(); i
++)
525 Foreground
*pForeground
= getForegrounds(i
);
526 FrameBufferObject
*pTarget
= this->getTarget();
530 pTarget
->activate(&oEnv
);
533 pForeground
->draw(&oEnv
);
537 pTarget
->deactivate(&oEnv
);
542 /*------------------------------- dump ----------------------------------*/
544 void Viewport::dump( UInt32
OSG_CHECK_ARG(uiIndent
),
545 const BitVector
OSG_CHECK_ARG(bvFlags
)) const
547 SLOG
<< "Dump Viewport NI" << std::endl
;
549 fprintf(stderr
, "%p %p %p\n",
550 static_cast<const void *>(this),
551 static_cast< void *>(_sfCamera
.getValue()),
552 static_cast< void *>(getCamera()));