776 lines
20 KiB
C++
776 lines
20 KiB
C++
/* -*-c++-*- Producer - Copyright (C) 2001-2004 Don Burns
|
|
*
|
|
* 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.
|
|
*/
|
|
|
|
#ifdef WIN32
|
|
#include <windows.h>
|
|
#endif
|
|
|
|
#include <string.h>
|
|
#include <algorithm>
|
|
|
|
#include "Camera.h"
|
|
|
|
using namespace osgProducer;
|
|
|
|
Camera::Camera( void )
|
|
{
|
|
_index = 0;
|
|
|
|
_projrectLeft = 0.0;
|
|
_projrectRight = 1.0;
|
|
_projrectBottom = 0.0;
|
|
_projrectTop = 1.0;
|
|
|
|
osg::Matrix::value_type id[] = {
|
|
1, 0, 0, 0,
|
|
0, 1, 0, 0,
|
|
0, 0, 1, 0,
|
|
0, 0, 0, 1
|
|
};
|
|
|
|
memcpy( _viewMatrix, id, sizeof(osg::Matrix::value_type[16]));
|
|
_offset._xshear = _offset._yshear = 0.0f;
|
|
memcpy( _offset._matrix, id, sizeof(osg::Matrix::value_type[16]));
|
|
_offset._multiplyMethod = Offset::PreMultiply;
|
|
|
|
_lens = new Lens;
|
|
_lens->setAutoAspect(true);
|
|
_rs = new RenderSurface;
|
|
|
|
_clear_color[0] = 0.2f;
|
|
_clear_color[1] = 0.2f;
|
|
_clear_color[2] = 0.4f;
|
|
_clear_color[3] = 1.0f;
|
|
|
|
_focal_distance = 1.0;
|
|
|
|
_shareLens = true;
|
|
_shareView = true;
|
|
|
|
_enabled = true;
|
|
_initialized = false;
|
|
|
|
}
|
|
|
|
Camera::~Camera( void )
|
|
{
|
|
}
|
|
|
|
|
|
const osg::Matrix::value_type * Camera::getViewMatrix( void ) const
|
|
{
|
|
return _viewMatrix;
|
|
}
|
|
|
|
void Camera::setViewByMatrix( const osg::Matrix &mat )
|
|
{
|
|
osg::Matrix m;
|
|
if ( _offset._multiplyMethod == Offset::PostMultiply )
|
|
m = osg::Matrix( _offset._matrix ) * mat;
|
|
else if( _offset._multiplyMethod == Offset::PreMultiply )
|
|
m = mat * osg::Matrix( _offset._matrix );
|
|
memcpy( _viewMatrix, m.ptr(), sizeof( osg::Matrix::value_type[16] ));
|
|
}
|
|
|
|
void Camera::setViewByLookat( const osg::Vec3 &eye, const osg::Vec3 ¢er, const osg::Vec3 &up )
|
|
{
|
|
osg::Matrix m;
|
|
m.makeLookAt(eye,center,up);
|
|
setViewByMatrix( m );
|
|
}
|
|
|
|
void Camera::setViewByLookat( float eyeX, float eyeY, float eyeZ,
|
|
float centerX, float centerY, float centerZ,
|
|
float upX, float upY, float upZ )
|
|
{
|
|
setViewByLookat( osg::Vec3(eyeX, eyeY, eyeZ),
|
|
osg::Vec3(centerX, centerY, centerZ ),
|
|
osg::Vec3(upX, upY, upZ) );
|
|
}
|
|
|
|
|
|
Camera::Lens::Lens( void )
|
|
{
|
|
// original defaults.
|
|
// _left = -0.5;
|
|
// _right = 0.5;
|
|
// _bottom = -0.5;
|
|
// _top = 0.5;
|
|
|
|
// Setting of the frustum which are appropriate for
|
|
// a monitor which is 26cm high, 50cm distant from the
|
|
// viewer and an horzintal/vetical aspect ratio of 1.25.
|
|
// This assumed to be a reasonable average setting for end users.
|
|
_left = -0.32;
|
|
_right = 0.32;
|
|
_bottom = -0.26;
|
|
_top = 0.26;
|
|
_ortho_left = -1.0;
|
|
_ortho_right = 1.0;
|
|
_ortho_bottom = -1.0;
|
|
_ortho_top = 1.0;
|
|
_nearClip = 1.0;
|
|
_farClip = 1e6;
|
|
_updateFOV();
|
|
_projection = Perspective;
|
|
}
|
|
|
|
void Camera::Lens::setAspectRatio( double aspectRatio )
|
|
{
|
|
_aspect_ratio = aspectRatio;
|
|
_left = -0.5 * (_top - _bottom) * _aspect_ratio;
|
|
_right = 0.5 * (_top - _bottom) * _aspect_ratio;
|
|
_ortho_left = -0.5 * (_ortho_top - _ortho_bottom) * _aspect_ratio;
|
|
_ortho_right = 0.5 * (_ortho_top - _ortho_bottom) * _aspect_ratio;
|
|
|
|
if( _projection == Perspective )
|
|
_updateFOV();
|
|
}
|
|
|
|
void Camera::Lens::setPerspective( double hfov, double vfov,
|
|
double nearClip, double farClip )
|
|
{
|
|
_hfov = osg::DegreesToRadians(hfov);
|
|
_vfov = osg::DegreesToRadians(vfov);
|
|
_aspect_ratio = tan(0.5*_hfov)/tan(0.5*_vfov);
|
|
|
|
_nearClip = nearClip;
|
|
_farClip = farClip;
|
|
|
|
_left = -_nearClip * tan(_hfov/2.0);
|
|
_right = _nearClip * tan(_hfov/2.0);
|
|
_bottom = -_nearClip * tan(_vfov/2.0);
|
|
_top = _nearClip * tan(_vfov/2.0);
|
|
|
|
_projection = Perspective;
|
|
setAutoAspect(false);
|
|
}
|
|
|
|
void Camera::Lens::setFrustum( double left, double right,
|
|
double bottom, double top,
|
|
double nearClip, double farClip )
|
|
{
|
|
_left = left;
|
|
_right = right;
|
|
_bottom = bottom;
|
|
_top = top;
|
|
_nearClip = nearClip;
|
|
_farClip = farClip;
|
|
_projection = Perspective;
|
|
_updateFOV();
|
|
setAutoAspect(false);
|
|
}
|
|
|
|
void Camera::Lens::setOrtho( double left, double right,
|
|
double bottom, double top,
|
|
double nearClip, double farClip )
|
|
{
|
|
_ortho_left = left;
|
|
_ortho_right = right;
|
|
_ortho_bottom = bottom;
|
|
_ortho_top = top;
|
|
_nearClip = nearClip;
|
|
_farClip = farClip;
|
|
_projection = Orthographic;
|
|
setAutoAspect(false);
|
|
}
|
|
|
|
void Camera::Lens::setMatrix( const osg::Matrix::value_type matrix[16] )
|
|
{
|
|
memcpy( _matrix, matrix, sizeof(osg::Matrix::value_type[16]) );
|
|
_projection = Manual;
|
|
setAutoAspect(false);
|
|
}
|
|
|
|
bool Camera::Lens::getFrustum( double& left, double& right,
|
|
double& bottom, double& top,
|
|
double& zNear, double& zFar ) const
|
|
{
|
|
//The following code was taken from osg's matrix implementation of getFrustum
|
|
if (_matrix[3]!=0.0 || _matrix[7]!=0.0 || _matrix[11]!=-1.0 || _matrix[15]!=0.0) return false;
|
|
|
|
zNear = _matrix[14] / (_matrix[10]-1.0);
|
|
zFar = _matrix[14] / (1.0+_matrix[10]);
|
|
|
|
left = zNear * (_matrix[8]-1.0) / _matrix[0];
|
|
right = zNear * (1.0+_matrix[8]) / _matrix[0];
|
|
|
|
top = zNear * (1.0+_matrix[9]) / _matrix[5];
|
|
bottom = zNear * (_matrix[9]-1.0) / _matrix[5];
|
|
|
|
return true;
|
|
}
|
|
|
|
bool Camera::Lens::getOrtho( double& left, double& right,
|
|
double& bottom, double& top,
|
|
double& zNear, double& zFar ) const
|
|
{
|
|
//The following code was taken from osg's matrix implementation of getOrtho
|
|
if (_matrix[3]!=0.0 || _matrix[7]!=0.0 || _matrix[11]!=0.0 || _matrix[15]!=1.0) return false;
|
|
|
|
zNear = (_matrix[14]+1.0) / _matrix[10];
|
|
zFar = (_matrix[14]-1.0) / _matrix[10];
|
|
|
|
left = -(1.0+_matrix[12]) / _matrix[0];
|
|
right = (1.0-_matrix[12]) / _matrix[0];
|
|
|
|
bottom = -(1.0+_matrix[13]) / _matrix[5];
|
|
top = (1.0-_matrix[13]) / _matrix[5];
|
|
|
|
return true;
|
|
}
|
|
|
|
bool Camera::Lens::convertToOrtho( float d )
|
|
{
|
|
|
|
if( _projection == Manual )
|
|
{
|
|
//Need to extract frustum values from manual matrix
|
|
if( !getFrustum(_left,_right,_bottom,_top,_nearClip,_farClip) )
|
|
return false;
|
|
|
|
_updateFOV();
|
|
}
|
|
|
|
double s = d * tan(_vfov*0.5);
|
|
_ortho_bottom = -s;
|
|
_ortho_top = s;
|
|
_ortho_left = -s*_aspect_ratio;
|
|
_ortho_right = s*_aspect_ratio;
|
|
_projection = Orthographic;
|
|
return true;
|
|
}
|
|
|
|
bool Camera::Lens::convertToPerspective( float d )
|
|
{
|
|
|
|
if( _projection == Manual )
|
|
{
|
|
//Need to extract ortho values from manual matrix
|
|
if( !getOrtho(_ortho_left,_ortho_right,_ortho_bottom,_ortho_top,_nearClip,_farClip) )
|
|
return false;
|
|
}
|
|
|
|
double hfov = 2 * atan( 0.5 * (_ortho_right - _ortho_left)/d);
|
|
double vfov = 2 * atan( 0.5 * (_ortho_top - _ortho_bottom)/d);
|
|
|
|
_left = -_nearClip * tan(hfov*0.5);
|
|
_right = _nearClip * tan(hfov*0.5);
|
|
_bottom = -_nearClip * tan(vfov*0.5);
|
|
_top = _nearClip * tan(vfov*0.5);
|
|
|
|
_projection = Perspective;
|
|
//_updateMatrix();
|
|
|
|
return true;
|
|
}
|
|
|
|
void Camera::Lens::apply(float xshear, float yshear)
|
|
{
|
|
generateMatrix(xshear,yshear,_matrix);
|
|
}
|
|
|
|
void Camera::Lens::getParams( double &left, double &right, double &bottom, double &top,
|
|
double &nearClip, double &farClip )
|
|
{
|
|
if( _projection == Perspective )
|
|
{
|
|
left = _left;
|
|
right = _right;
|
|
bottom = _bottom;
|
|
top = _top;
|
|
}
|
|
else if( _projection == Orthographic )
|
|
{
|
|
left = _ortho_left;
|
|
right = _ortho_right;
|
|
bottom = _ortho_bottom;
|
|
top = _ortho_top;
|
|
}
|
|
else if( _projection == Manual ) // could only be Manual, but best to make this clear
|
|
{
|
|
// Check if Manual matrix is either a valid perspective or orthographic matrix
|
|
// If neither, then return bogus values -- nothing better we can do
|
|
if(getFrustum(left,right,bottom,top,nearClip,farClip))
|
|
return;
|
|
|
|
if(getOrtho(left,right,bottom,top,nearClip,farClip))
|
|
return;
|
|
|
|
left = _left;
|
|
right = _right;
|
|
bottom = _bottom;
|
|
top = _top;
|
|
}
|
|
nearClip = _nearClip;
|
|
farClip = _farClip;
|
|
}
|
|
|
|
void Camera::setProjectionRectangle( const float left, const float right,
|
|
const float bottom, const float top )
|
|
{
|
|
_projrectLeft = left;
|
|
_projrectRight = right;
|
|
_projrectBottom = bottom;
|
|
_projrectTop = top;
|
|
}
|
|
|
|
void Camera::getProjectionRectangle( float &left, float &right,
|
|
float &bottom, float &top ) const
|
|
{
|
|
left = _projrectLeft;
|
|
right = _projrectRight;
|
|
bottom = _projrectBottom;
|
|
top = _projrectTop;
|
|
}
|
|
|
|
void Camera::setProjectionRectangle( int x, int y, unsigned int width, unsigned int height )
|
|
{
|
|
int _x, _y;
|
|
unsigned int _w, _h;
|
|
|
|
_rs->getWindowRectangle( _x, _y, _w, _h );
|
|
#if 0
|
|
if( _w == osgProducer::RenderSurface::UnknownDimension || _h == Producer::RenderSurface::UnknownDimension)
|
|
{
|
|
unsigned int ww;
|
|
unsigned int hh;
|
|
_rs->getScreenSize( ww, hh );
|
|
if( _w == osgProducer::RenderSurface::UnknownDimension )
|
|
_w = ww;
|
|
if( _h == osgProducer::RenderSurface::UnknownDimension )
|
|
_h = hh;
|
|
}
|
|
#endif
|
|
|
|
_projrectLeft = float(x - _x)/float(_w);
|
|
_projrectRight = float((x + width) - _x)/float(_w);
|
|
_projrectBottom = float(y - _y)/float(_h);
|
|
_projrectTop = float((y+height) - _y)/float(_h);
|
|
}
|
|
|
|
void Camera::getProjectionRectangle( int &x, int &y, unsigned int &width, unsigned int &height ) const
|
|
{
|
|
int _x, _y;
|
|
unsigned int _w, _h;
|
|
float fx, fy, fw, fh;
|
|
|
|
_rs->getWindowRectangle( _x, _y, _w, _h );
|
|
#if 0
|
|
if( _w == Producer::RenderSurface::UnknownDimension || _h == Producer::RenderSurface::UnknownDimension )
|
|
{
|
|
unsigned int ww;
|
|
unsigned int hh;
|
|
_rs->getScreenSize( ww, hh );
|
|
if( _w == Producer::RenderSurface::UnknownDimension )
|
|
_w = ww;
|
|
if( _h == Producer::RenderSurface::UnknownDimension )
|
|
_h = hh;
|
|
}
|
|
#endif
|
|
|
|
fx = _projrectLeft * _w;
|
|
fy = _projrectBottom * _h;
|
|
fw = _w * _projrectRight;
|
|
fh = _h * _projrectTop;
|
|
|
|
x = int(fx);
|
|
y = int(fy);
|
|
|
|
width = int(fw) - x;
|
|
height = int(fh) - y;
|
|
}
|
|
|
|
void Camera::setClearColor( float r, float g, float b, float a )
|
|
{
|
|
_clear_color[0] = r;
|
|
_clear_color[1] = g;
|
|
_clear_color[2] = b;
|
|
_clear_color[3] = a;
|
|
}
|
|
|
|
void Camera::getClearColor( float& red, float& green, float& blue, float& alpha)
|
|
{
|
|
red = _clear_color[0];
|
|
green = _clear_color[1];
|
|
blue = _clear_color[2];
|
|
alpha = _clear_color[3];
|
|
}
|
|
|
|
|
|
void Camera::clear( void )
|
|
{
|
|
#if 0
|
|
if( !_initialized ) _initialize();
|
|
int x, y;
|
|
unsigned int w, h;
|
|
getProjectionRectangle( x, y, w, h );
|
|
glViewport( x, y, w, h );
|
|
glScissor( x, y, w, h );
|
|
glClearColor( _clear_color[0], _clear_color[1], _clear_color[2], _clear_color[3] );
|
|
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT );
|
|
#endif
|
|
}
|
|
|
|
|
|
#if 0
|
|
void Camera::Lens::_updateMatrix( void )
|
|
{
|
|
switch( _projection )
|
|
{
|
|
case Perspective :
|
|
_matrix[ 0] = (2 * _nearClip)/(_right - _left);
|
|
_matrix[ 1] = 0.0;
|
|
_matrix[ 2] = 0.0;
|
|
_matrix[ 3] = 0.0;
|
|
|
|
_matrix[ 4] = 0.0;
|
|
_matrix[ 5] = (2 * _nearClip)/(_top-_bottom);
|
|
_matrix[ 6] = 0.0;
|
|
_matrix[ 7] = 0.0;
|
|
|
|
_matrix[ 8] = (_right + _left)/(_right-_left);
|
|
_matrix[ 9] = (_top+_bottom)/(_top-_bottom);
|
|
_matrix[10] = -(_farClip + _nearClip)/(_farClip-_nearClip);
|
|
_matrix[11] = -1.0;
|
|
|
|
_matrix[12] = 0.0;
|
|
_matrix[13] = 0.0;
|
|
_matrix[14] = -(2 * _farClip * _nearClip)/(_farClip-_nearClip);
|
|
_matrix[15] = 0.0;
|
|
|
|
_matrix[ 8] += -_xshear;
|
|
_matrix[ 9] += -_yshear;
|
|
|
|
_hfov = 2.0 * atan(((_right - _left) * 0.5)/_nearClip);
|
|
_vfov = 2.0 * atan(((_top - _bottom) * 0.5)/_nearClip);
|
|
|
|
break;
|
|
|
|
case Orthographic :
|
|
|
|
_matrix[ 0] = 2/(_ortho_right - _ortho_left);
|
|
_matrix[ 1] = 0.0;
|
|
_matrix[ 2] = 0.0;
|
|
_matrix[ 3] = 0.0;
|
|
|
|
_matrix[ 4] = 0.0;
|
|
_matrix[ 5] = 2/(_ortho_top - _ortho_bottom);
|
|
_matrix[ 6] = 0.0;
|
|
_matrix[ 7] = 0.0;
|
|
|
|
_matrix[ 8] = 0.0;
|
|
_matrix[ 9] = 0.0;
|
|
//_matrix[10] = -2.0/(_farClip - (-_farClip));
|
|
_matrix[10] = -2.0/(_farClip - _nearClip);
|
|
_matrix[11] = 0.0;
|
|
|
|
_matrix[12] = -(_ortho_right+_ortho_left)/(_ortho_right-_ortho_left);
|
|
_matrix[13] = -(_ortho_top+_ortho_bottom)/(_ortho_top-_ortho_bottom);
|
|
//_matrix[14] = -(_farClip+(-_farClip))/(_farClip-(-_farClip));
|
|
_matrix[14] = -(_farClip+_nearClip)/(_farClip-_nearClip);
|
|
_matrix[15] = 1.0;
|
|
|
|
_matrix[12] += _xshear;
|
|
_matrix[13] += _yshear;
|
|
|
|
//_hfov = 0.0;
|
|
//_vfov = 0.0;
|
|
|
|
break;
|
|
}
|
|
}
|
|
#endif
|
|
|
|
void Camera::Lens::generateMatrix(float xshear, float yshear, osg::Matrix::value_type matrix[16] )
|
|
{
|
|
switch( _projection )
|
|
{
|
|
case Perspective :
|
|
matrix[ 0] = (2 * _nearClip)/(_right - _left);
|
|
matrix[ 1] = 0.0;
|
|
matrix[ 2] = 0.0;
|
|
matrix[ 3] = 0.0;
|
|
|
|
matrix[ 4] = 0.0;
|
|
matrix[ 5] = (2 * _nearClip)/(_top-_bottom);
|
|
matrix[ 6] = 0.0;
|
|
matrix[ 7] = 0.0;
|
|
|
|
matrix[ 8] = (_right + _left)/(_right-_left);
|
|
matrix[ 9] = (_top+_bottom)/(_top-_bottom);
|
|
matrix[10] = -(_farClip + _nearClip)/(_farClip-_nearClip);
|
|
matrix[11] = -1.0;
|
|
|
|
matrix[12] = 0.0;
|
|
matrix[13] = 0.0;
|
|
matrix[14] = -(2 * _farClip * _nearClip)/(_farClip-_nearClip);
|
|
matrix[15] = 0.0;
|
|
|
|
matrix[ 8] += -xshear;
|
|
matrix[ 9] += -yshear;
|
|
|
|
|
|
break;
|
|
|
|
case Orthographic :
|
|
|
|
matrix[ 0] = 2/(_ortho_right - _ortho_left);
|
|
matrix[ 1] = 0.0;
|
|
matrix[ 2] = 0.0;
|
|
matrix[ 3] = 0.0;
|
|
|
|
matrix[ 4] = 0.0;
|
|
matrix[ 5] = 2/(_ortho_top - _ortho_bottom);
|
|
matrix[ 6] = 0.0;
|
|
matrix[ 7] = 0.0;
|
|
|
|
matrix[ 8] = 0.0;
|
|
matrix[ 9] = 0.0;
|
|
//_matrix[10] = -2.0/(_farClip - (-_farClip));
|
|
matrix[10] = -2.0/(_farClip - _nearClip);
|
|
matrix[11] = 0.0;
|
|
|
|
matrix[12] = -(_ortho_right+_ortho_left)/(_ortho_right-_ortho_left);
|
|
matrix[13] = -(_ortho_top+_ortho_bottom)/(_ortho_top-_ortho_bottom);
|
|
//_matrix[14] = -(_farClip+(-_farClip))/(_farClip-(-_farClip));
|
|
matrix[14] = -(_farClip+_nearClip)/(_farClip-_nearClip);
|
|
matrix[15] = 1.0;
|
|
|
|
matrix[12] += xshear;
|
|
matrix[13] += yshear;
|
|
|
|
break;
|
|
|
|
case Manual:
|
|
|
|
memcpy( matrix, _matrix, sizeof(osg::Matrix::value_type[16]));
|
|
|
|
if(xshear || yshear)
|
|
{
|
|
if (matrix[3]!=0.0 || matrix[7]!=0.0 || matrix[11]!=0.0 || matrix[15]!=1.0)
|
|
{
|
|
// It's not an orthographic matrix so just assume a perspective shear
|
|
matrix[ 8] += -xshear;
|
|
matrix[ 9] += -yshear;
|
|
}
|
|
else
|
|
{
|
|
matrix[12] += xshear;
|
|
matrix[13] += yshear;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
void Camera::Lens::_updateFOV()
|
|
{
|
|
_hfov = 2.0 * atan(((_right - _left) * 0.5)/_nearClip);
|
|
_vfov = 2.0 * atan(((_top - _bottom) * 0.5)/_nearClip);
|
|
_aspect_ratio = tan(0.5*_hfov)/tan(0.5*_vfov);
|
|
}
|
|
|
|
|
|
void Camera::setOffset( const osg::Matrix::value_type matrix[16], const osg::Matrix::value_type xshear, const osg::Matrix::value_type yshear )
|
|
{
|
|
memcpy( _offset._matrix, matrix, sizeof(osg::Matrix::value_type[16]));
|
|
_offset._xshear = xshear;
|
|
_offset._yshear = yshear;
|
|
}
|
|
|
|
void Camera::setOffset( double xshear, double yshear )
|
|
{
|
|
_offset._xshear = xshear;
|
|
_offset._yshear = yshear;
|
|
}
|
|
|
|
#if 0
|
|
void Camera::setSyncBarrier( RefBarrier *b )
|
|
{
|
|
_syncBarrier = b;
|
|
}
|
|
|
|
void Camera::setFrameBarrier( RefBarrier *b )
|
|
{
|
|
_frameBarrier = b;
|
|
}
|
|
|
|
int Camera::cancel()
|
|
{
|
|
#if 1
|
|
_done = true;
|
|
#endif
|
|
|
|
Thread::cancel();
|
|
return 0;
|
|
}
|
|
|
|
void Camera::advance()
|
|
{
|
|
_rs->makeCurrent();
|
|
_rs->swapBuffers();
|
|
}
|
|
|
|
void Camera::run( void )
|
|
{
|
|
if( !_syncBarrier.valid() || !_frameBarrier.valid() )
|
|
{
|
|
std::cerr << "Camera::run() : Threaded Camera requires a Barrier\n";
|
|
return;
|
|
}
|
|
|
|
_done = false;
|
|
|
|
_initialize();
|
|
_syncBarrier->block();
|
|
while( !_done )
|
|
{
|
|
// printf(" Camera::run before frame block\n");
|
|
|
|
_frameBarrier->block();
|
|
|
|
if (_done) break;
|
|
|
|
// printf(" Camera::run after frame block\n");
|
|
|
|
frame(false);
|
|
|
|
if (_done) break;
|
|
|
|
// printf(" Camera::run before sycn block\n");
|
|
|
|
_syncBarrier->block();
|
|
|
|
if (_done) break;
|
|
|
|
// printf(" Camera::run after sycn block\n");
|
|
|
|
advance();
|
|
}
|
|
|
|
// printf("Exiting Camera::run cleanly\n");
|
|
}
|
|
|
|
|
|
|
|
bool Camera::removePreCullCallback( Callback *cb )
|
|
{
|
|
return _removeCallback( preCullCallbacks, cb );
|
|
}
|
|
|
|
bool Camera::removePostCullCallback( Callback *cb )
|
|
{
|
|
return _removeCallback( postCullCallbacks, cb );
|
|
}
|
|
|
|
bool Camera::removePreDrawCallback( Callback *cb )
|
|
{
|
|
return _removeCallback( preDrawCallbacks, cb );
|
|
}
|
|
|
|
bool Camera::removePostDrawCallback( Callback *cb )
|
|
{
|
|
return _removeCallback( postDrawCallbacks, cb );
|
|
}
|
|
|
|
bool Camera::removePostSwapCallback( Callback *cb )
|
|
{
|
|
return _removeCallback( postSwapCallbacks, cb );
|
|
}
|
|
|
|
|
|
bool Camera::_removeCallback( std::vector < ref_ptr<Callback> > &callbackList, Callback *callback )
|
|
{
|
|
std::vector < Producer::ref_ptr< Producer::Camera::Callback> >::iterator p;
|
|
p = std::find( callbackList.begin(), callbackList.end(), callback );
|
|
if( p == callbackList.end() )
|
|
return false;
|
|
|
|
callbackList.erase( p );
|
|
return true;
|
|
}
|
|
|
|
Camera::FrameTimeStampSet::FrameTimeStampSet():
|
|
_pipeStatsDoubleBufferIndex(0),
|
|
_pipeStatsFirstSync(true),
|
|
_initialized(false)
|
|
{
|
|
for( unsigned int i = 0; i < LastPipeStatsID; i++ )
|
|
_pipeStats[i] = 0.0;
|
|
}
|
|
|
|
Camera::FrameTimeStampSet::~FrameTimeStampSet()
|
|
{
|
|
}
|
|
|
|
void Camera::FrameTimeStampSet::syncPipeStats()
|
|
{
|
|
if( !_initialized )
|
|
return;
|
|
|
|
if( _pipeStatsFirstSync == true )
|
|
{
|
|
_pipeStatsFirstSync = false;
|
|
return;
|
|
}
|
|
|
|
// We get the stats from the previous frame
|
|
for( int i = 0; i < LastPipeStatsID; i++ )
|
|
{
|
|
if( _pipeStatsSetMask[1 - _pipeStatsDoubleBufferIndex] & (1<<i) )
|
|
_pipeStats[i] = PipeTimer::instance()->getElapsedTime( _pipeStatsNames[i][ 1 - _pipeStatsDoubleBufferIndex] );
|
|
}
|
|
|
|
_pipeStatsFrameNumber = _frameNumber - 1;
|
|
_pipeStatsDoubleBufferIndex = 1 - _pipeStatsDoubleBufferIndex;
|
|
_pipeStatsSetMask[_pipeStatsDoubleBufferIndex] = 0;
|
|
}
|
|
|
|
void Camera::FrameTimeStampSet::beginPipeTimer( PipeStatsID id)
|
|
{
|
|
if( !_initialized )
|
|
_init();
|
|
|
|
PipeTimer::instance()->begin( _pipeStatsNames[id][_pipeStatsDoubleBufferIndex] );
|
|
_pipeStatsSetMask[_pipeStatsDoubleBufferIndex] |= (1<<id);
|
|
}
|
|
|
|
void Camera::FrameTimeStampSet::endPipeTimer()
|
|
{
|
|
if( !_initialized )
|
|
return;
|
|
|
|
PipeTimer::instance()->end() ;
|
|
}
|
|
|
|
void Camera::FrameTimeStampSet::_init()
|
|
{
|
|
if( _initialized )
|
|
return;
|
|
|
|
for( unsigned int i = 0; i < (unsigned int)LastPipeStatsID; i++ )
|
|
PipeTimer::instance()->genQueries( 2, _pipeStatsNames[i] );
|
|
|
|
_pipeStatsSetMask[0] = 0;
|
|
_pipeStatsSetMask[1] = 0;
|
|
|
|
_initialized = true;
|
|
}
|
|
|
|
const Camera::FrameTimeStampSet &Camera::getFrameStats()
|
|
{
|
|
return _frameStamps;
|
|
}
|
|
#endif
|