From Cedric Pinson, first cut at Producer .cfg camera configuration file support.

This commit is contained in:
Robert Osfield
2007-12-05 11:23:27 +00:00
parent 1b1c5bbdd1
commit b164c5e7a6
17 changed files with 10241 additions and 0 deletions

View File

@@ -48,6 +48,12 @@ ADD_SUBDIRECTORY(net)
ADD_SUBDIRECTORY(osg)
ADD_SUBDIRECTORY(ive)
############################################################
#
# Viewer plugins
#
ADD_SUBDIRECTORY(cfg)
############################################################
#

View File

@@ -0,0 +1,20 @@
SET(TARGET_SRC
CameraConfig.cpp
Camera.cpp
ConfigLexer.cpp
ConfigParser.cpp
ReaderWriterCFG.cpp
RenderSurface.cpp
VisualChooser.cpp
)
SET(TARGET_H
CameraConfig.h
Camera.h
ConfigParser.h
RenderSurface.h
VisualChooser.h
)
#### end var setup ###
SETUP_PLUGIN(cfg)

View File

@@ -0,0 +1,776 @@
/* -*-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 &center, 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)
{
osg::Matrix::value_type _matrix[16];
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], double xshear, double 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

399
src/osgPlugins/cfg/Camera.h Normal file
View File

@@ -0,0 +1,399 @@
/* -*-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.
*/
#ifndef OSGPRODUCER_CAMERA
#define OSGPRODUCER_CAMERA
#include "RenderSurface.h"
#include <osg/Referenced>
#include <osg/Matrix>
#include <osg/Math>
#include <osg/Vec3>
#include <vector>
#include <osg/Math>
namespace osgProducer {
class CameraGroup;
class RenderSurface;
/**
\class Camera
\brief A Camera provides a programming interface for 3D
graphics applications by means of an abstract camera analogy
The Camera contains a Lens class and has a RenderSurface. Methods
are provided to give the programmer control over the OpenGL PROJECTION
matrix throught the Lens and over the initial MODELVIEW matrix through
the camera's position and attitude.
The programmer must provide a class derived from Camera::SceneHandler
to prepare and render the scene. The Camera does not provide direct
control over rendering itself.
*/
class Camera : public osg::Referenced
{
public :
/**
\class SceneHandler
\brief A Scene Handler handles the preparation and rendering
of a scene for Camera
*/
/**
\class Lens
\brief A Lens provides control over the PROJECTION matrix.
It is entirely contained within the Camera class. A Lens may
be of type Perspective or Orthographic and set with one of the
setFrustum, setProjection() or setOrtho(). The Lens type is
implied by the method used to set it */
class Lens : public osg::Referenced
{
public :
/** Projection types */
enum Projection {
Perspective,
Orthographic,
Manual
};
Lens();
/** setMatrix() exists to allow external projection-management tools
(like elumens' spiclops) to do their magic and still work with producer */
void setMatrix( const osg::Matrix::value_type matrix[16] );
/** Set the Projection type to be of Perspective and provide
the following parameters to set the Projection matrix.
hfov - Horizontal Field of View in degrees
vfov - Vertical Field of View in degrees
nearClip - Distance from the viewer to the near plane of the
viewing frustum.
farClip - Distance from the viewer to the far plane of the
viewing frustum.
xshear- Assymetrical shear in viewing frustum in the horizontal
direction. Value given in normalized device coordinates
(see setShear() below).
yshear- Assymetrical shear in viewing frustum in the vertical
direction. Value given in normalized device coordinates
(see setShear() below).
*/
void setPerspective( double hfov, double vfov,
double nearClip, double farClip );
/** Set the Projection type to be of Perspective and provide
the dimensions of the left, right, bottom, top, nearClip and farClip
extents of the viewing frustum as indicated.
xshear- Assymetrical shear in viewing frustum in the horizontal
direction. Value given in normalized device coordinates
(see setShear() below).
yshear- Assymetrical shear in viewing frustum in the vertical
direction. Value given in normalized device coordinates
(see setShear() below).
*/
void setFrustum( double left, double right,
double bottom, double top,
double nearClip, double farClip );
/** Set the Projection type to be of Orthographic and provide
the left, right, bottom dimensions of the 2D rectangle*/
void setOrtho( double left, double right,
double bottom, double top,
double nearClip, double farClip );
/** convertToOrtho() converts the current perspective view to an
orthographic view with dimensions that conserve the scale of the
objects at distance d.
convertToPerspective() converts the current orthographic view
to a perspective view with parameters that conserve the scale of
objects at distance d. */
bool convertToOrtho( float d);
bool convertToPerspective( float d);
/** apply the lens. This generates a projection matrix for OpenGL */
void apply(float xshear=0.0f, float yshear=0.0);
void generateMatrix( float xshear, float yshear, osg::Matrix::value_type matrix[16] );
Projection getProjectionType() const { return _projection; }
void getParams( double &left, double &right, double &bottom, double &top,
double &nearClip, double &farClip ); //, double &xshear, double &yshear );
float getHorizontalFov() const { return osg::RadiansToDegrees(_hfov); }
float getVerticalFov() const { return osg::RadiansToDegrees(_vfov); }
void setAutoAspect(bool ar) { _auto_aspect = ar; }
bool getAutoAspect() const { return _auto_aspect; }
void setAspectRatio( double aspectRatio );
double getAspectRatio() { return _aspect_ratio; }
protected:
~Lens(){}
/* Internal convenience methods */
bool getFrustum( double& left, double& right,
double& bottom, double& top,
double& zNear, double& zFar ) const;
bool getOrtho( double& left, double& right,
double& bottom, double& top,
double& zNear, double& zFar ) const;
private :
double _ortho_left, _ortho_right, _ortho_bottom, _ortho_top;
double _left, _right, _bottom, _top, _nearClip, _farClip;
Projection _projection;
double _aspect_ratio;
bool _auto_aspect;
float _hfov, _vfov;
osg::Matrix::value_type _matrix[16];
private :
void _updateFOV( void );
};
struct Offset {
enum MultiplyMethod {
PreMultiply,
PostMultiply
};
double _xshear;
double _yshear;
osg::Matrix::value_type _matrix[16];
MultiplyMethod _multiplyMethod;
Offset():
_xshear(0.0),
_yshear(0.0),
_multiplyMethod(PreMultiply) {}
};
public :
Camera( void );
void setRenderSurface( RenderSurface *rs ) { _rs = rs; }
RenderSurface *getRenderSurface() { return _rs.get(); }
const RenderSurface *getRenderSurface() const { return _rs.get(); }
void setRenderSurfaceWindowRectangle( int x, int y, unsigned int width, unsigned int height, bool resize=true )
{ _rs->setWindowRectangle(x,y,width,height, resize); }
void setLens( Lens *lens )
{
if( _lens.get() != lens )
_lens = lens;
}
Lens *getLens() { return _lens.get(); }
const Lens *getLens() const { return _lens.get(); }
//////////////////////////////////////////////////////////////////////////////////////
/** Convenience method for setting the Lens Perspective.
See Camera::Lens::setPerspective(). */
void setLensPerspective( double hfov, double vfov,
double nearClip, double farClip,
double xshear=0, double yshear=0 )
{
_offset._xshear = xshear;
_offset._yshear = yshear;
_lens->setPerspective(hfov,vfov,nearClip,farClip);
}
/** Convenience method for setting the Lens Frustum.
See Camera::Lens::setFrustum(). */
void setLensFrustum( double left, double right,
double bottom, double top,
double nearClip, double farClip,
double xshear=0, double yshear=0 )
{
_offset._xshear = xshear;
_offset._yshear = yshear;
_lens->setFrustum(left,right,bottom,top,nearClip, farClip);
}
/** Convenience method for setting the lens Orthographic projection.
See Camera::Lens::setOrtho() */
void setLensOrtho( double left, double right,
double bottom, double top,
double nearClip, double farClip ,
double xshear=0, double yshear=0 )
{
_offset._xshear = xshear;
_offset._yshear = yshear;
_lens->setOrtho( left, right, bottom, top, nearClip, farClip);
}
/** Convenience method for setting the lens shear. See Camera::Lens::setShear()*/
void setLensShear( double xshear, double yshear )
{
_offset._xshear = xshear;
_offset._yshear = yshear;
}
/** Convenience method for getting the lens shear. See Camera::Lens::getShear() */
void getLensShear( double &xshear, double &yshear )
{
xshear = _offset._xshear;
yshear = _offset._yshear;
}
/** Convenience method for converting the Perpective lens to an
Orthographic lens. see Camera::lens:convertToOrtho() */
bool convertLensToOrtho( float d) { return _lens->convertToOrtho(d); }
/** Convenience method for converting the Orthographic lens to an
Perspective lens. see Camera::lens:convertToPerspective() */
bool convertLensToPerspective( float d) { return _lens->convertToPerspective(d); }
/** Convenience method for getting the lens projection type.
See Camera::Lens::setAspectRatio() */
Lens::Projection getLensProjectionType() { return _lens->getProjectionType(); }
/** Convenience method for applying the lens. See Camera::Lens::apply() */
void applyLens() { _lens->apply(_offset._xshear, _offset._yshear); }
/** Convenience method for getting the Lens parameters.
See Camera::Lens::apply() */
void getLensParams( double &left, double &right, double &bottom, double &top,
double &nearClip, double &farClip, double &xshear, double &yshear )
{
_lens->getParams(left,right,bottom,top,nearClip,farClip );
xshear = _offset._xshear;
yshear = _offset._yshear;
}
/** Convenience method for getting the Lens Horizontal field of view.
See Camera::Lens::getHorizontalFov() */
float getLensHorizontalFov() { return _lens->getHorizontalFov(); }
/** Convenience method for getting the Lens Horizontal field of view.
See Camera::Lens::getVerticalFov() */
float getLensVerticalFov() { return _lens->getVerticalFov(); }
/** Convenience method for setting the Lens ProjectionMatrix.
See Camera::Lens::setMatrix() */
// DEPRECATE
//void setLensMatrix( float mat[16] ) { _lens->setMatrix(mat); }
/** Convenience method for getting the Lens ProjectionMatrix.
See Camera::Lens::getMatrix() */
void getLensMatrix(osg::Matrix::value_type matrix[16] )
{
_lens->generateMatrix(_offset._xshear, _offset._yshear, matrix );
}
/** Convenience method for setting AutoAspect on the lens.
See Camera::Lens::setAutoAspect() */
void setLensAutoAspect(bool ar) { _lens->setAutoAspect(ar); }
/** Convenience method for getting AutoAspect on the lens.
See Camera::Lens::getAutoAspect() */
bool getLensAutoAspect() { return _lens->getAutoAspect(); }
/** Convenience method for setting the lens Aspect Ratio.
See Camera::Lens::setAspectRatio() */
void setLensAspectRatio( double aspectRatio ) { _lens->setAspectRatio(aspectRatio); }
double getLensAspectRatio() { return _lens->getAspectRatio(); }
//////////////////////////////////////////////////////////////////////////////////////
void setProjectionRectangle( const float left, const float right,
const float bottom, const float top );
void getProjectionRectangle( float &left, float &right,
float &bottom, float &top ) const;
void setProjectionRectangle( int x, int y, unsigned int width, unsigned int height );
void getProjectionRectangle( int &x, int &y, unsigned int &width, unsigned int &height ) const ;
osg::Matrix::value_type *getProjectionMatrix ()
{
_lens->generateMatrix(_offset._xshear, _offset._yshear, _projectionMatrix );
return _projectionMatrix;
}
void setViewByLookat( float eyex, float eyey, float eyez,
float centerx, float centery, float centerz,
float upx, float upy, float upz );
void setViewByLookat( const osg::Vec3 &eye, const osg::Vec3 &center, const osg::Vec3 &up );
void setViewByMatrix( const osg::Matrix &mat );
void setFocalDistance( double focal_distance ) { _focal_distance = focal_distance; }
const osg::Matrix::value_type *getViewMatrix( void ) const;
const osg::Matrix::value_type *getPositionAndAttitudeMatrix( void ) const { return _viewMatrix; }
void applyView();
void setOffset( const osg::Matrix::value_type matrix[16],
osg::Matrix::value_type _xshear=0.0,
osg::Matrix::value_type _yshear=0.0);
void setOffset( double _xshear, double _yshear);
void setOffsetMultiplyMethod( Offset::MultiplyMethod method )
{
_offset._multiplyMethod = method;
}
void setClearColor( float red, float green, float blue, float alpha);
void getClearColor( float& red, float& green, float& blue, float& alpha);
void clear( void );
void setIndex( unsigned int index ) { _index = index; }
unsigned int getIndex() const { return _index; }
void setShareLens( bool flag ) { _shareLens = flag; }
bool getShareLens() { return _shareLens; }
void setShareView( bool flag ) { _shareView = flag; }
bool getShareView() { return _shareView; }
protected :
virtual ~Camera( void );
osg::ref_ptr<Lens> _lens;
osg::ref_ptr<RenderSurface> _rs;
unsigned int _index;
private :
bool _initialized;
bool _initialize(void);
bool _enabled;
float _projrectLeft,
_projrectRight,
_projrectBottom,
_projrectTop;
Offset _offset;
osg::Matrix::value_type _projectionMatrix[16];
osg::Matrix::value_type _viewMatrix[16];
float _clear_color[4];
double _focal_distance;
friend class CameraGroup;
bool _shareLens;
bool _shareView;
};
}
#endif

View File

@@ -0,0 +1,672 @@
/* -*-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.
*/
#if defined(WIN32) && !defined(__CYGWIN__)
#include <Io.h>
#include <Windows.h>
#include <Winbase.h>
// set up for windows so acts just like unix access().
#define F_OK 4
#else // unix
#include <unistd.h>
#endif
#ifdef _X11_IMPLEMENTATION
# include <X11/Xlib.h>
#endif
#include <iostream>
#include <cmath>
#include "CameraConfig.h"
#include <osg/Notify>
#include <osg/ref_ptr>
#include <osg/io_utils>
using namespace osgProducer;
unsigned int CameraConfig::getNumberOfScreens()
{
#if 0
return RenderSurface::getNumberOfScreens();
#else
return 1;
#endif
}
//////////////////
CameraConfig::CameraConfig() :
_can_add_visual_attributes(false),
_current_render_surface(NULL),
_can_add_render_surface_attributes(false),
_current_camera(NULL),
_can_add_camera_attributes(false),
_input_area(NULL),
_can_add_input_area_entries(false),
_offset_shearx(0.0f),
_offset_sheary(0.0f),
_postmultiply(false)
{
_offset_matrix[0] = 1.0; _offset_matrix[1] = 0.0; _offset_matrix[2] = 0.0; _offset_matrix[3] = 0.0;
_offset_matrix[4] = 0.0; _offset_matrix[5] = 1.0; _offset_matrix[6] = 0.0; _offset_matrix[7] = 0.0;
_offset_matrix[8] = 0.0; _offset_matrix[9] = 0.0; _offset_matrix[10] = 1.0; _offset_matrix[11] = 0.0;
_offset_matrix[12] = 0.0; _offset_matrix[13] = 0.0; _offset_matrix[14] = 0.0; _offset_matrix[15] = 1.0;
_threadModelDirective = CameraGroup::getDefaultThreadModel();
}
void CameraConfig::beginVisual( void )
{
_current_visual_chooser = new VisualChooser;
_can_add_visual_attributes = true;
}
void CameraConfig::beginVisual( const char * name )
{
std::pair<std::map<std::string,VisualChooser *>::iterator,bool> res =
_visual_map.insert(std::pair<std::string,VisualChooser *>(std::string(name), new VisualChooser));
_current_visual_chooser = (res.first)->second;
_can_add_visual_attributes = true;
}
void CameraConfig::setVisualSimpleConfiguration( void )
{
if( !_current_visual_chooser.valid() || _can_add_visual_attributes == false )
{
std::cerr << "CameraConfig::setVisualSimpleConfiguration() : ERROR no current visual\n";
return;
}
_current_visual_chooser->setSimpleConfiguration();
}
void CameraConfig::setVisualByID( unsigned int id )
{
if( !_current_visual_chooser.valid() || _can_add_visual_attributes == false )
{
std::cerr << "CameraConfig::setVisualByID(id) : ERROR no current visual\n";
return;
}
_current_visual_chooser->setVisualID( id );
}
void CameraConfig::addVisualAttribute( VisualChooser::AttributeName token, int param )
{
if( !_current_visual_chooser.valid() || _can_add_visual_attributes == false )
{
std::cerr << "CameraConfig::addVisualAttribute(token,param) : ERROR no current visual\n";
return;
}
_current_visual_chooser->addAttribute( token, param );
}
void CameraConfig::addVisualAttribute( VisualChooser::AttributeName token )
{
if( !_current_visual_chooser.valid() || _can_add_visual_attributes == false)
{
std::cerr << "CameraConfig::addVisualAttribute(token) : ERROR no current visual\n";
return;
}
_current_visual_chooser->addAttribute( token );
}
void CameraConfig::addVisualExtendedAttribute( unsigned int token )
{
if( !_current_visual_chooser.valid() || _can_add_visual_attributes == false)
{
std::cerr << "CameraConfig::addVisualExtendedAttribute(token) : ERROR no current visual\n";
return;
}
_current_visual_chooser->addExtendedAttribute( token );
}
void CameraConfig::addVisualExtendedAttribute( unsigned int token, int param )
{
if( !_current_visual_chooser.valid() || _can_add_visual_attributes == false)
{
std::cerr << "CameraConfig::addVisualExtendedAttribute(token, param) : ERROR no current visual\n";
return;
}
_current_visual_chooser->addExtendedAttribute( token, param );
}
void CameraConfig::endVisual( void )
{
_can_add_visual_attributes = false;
}
VisualChooser *CameraConfig::findVisual( const char *name )
{
std::map<std::string, VisualChooser *>::iterator p;
p = _visual_map.find( std::string(name) );
if( p == _visual_map.end() )
return NULL;
else
return (*p).second;
}
void CameraConfig::beginRenderSurface( const char *name )
{
std::pair<std::map<std::string, osg::ref_ptr<RenderSurface> >::iterator,bool> res =
_render_surface_map.insert(std::pair<std::string, osg::ref_ptr< RenderSurface> >(
std::string(name),
new RenderSurface));
_current_render_surface = (res.first)->second.get();
_current_render_surface->setWindowName( std::string(name) );
_can_add_render_surface_attributes = true;
}
void CameraConfig::setRenderSurfaceVisualChooser( const char *name )
{
VisualChooser *vc = findVisual( name );
if( vc != NULL && _current_render_surface != NULL )
_current_render_surface->setVisualChooser( vc );
}
void CameraConfig::setRenderSurfaceVisualChooser( void )
{
if( _current_render_surface != NULL && _current_visual_chooser.valid() )
_current_render_surface->setVisualChooser( _current_visual_chooser.get() );
}
void CameraConfig::setRenderSurfaceWindowRectangle( int x, int y, unsigned int width, unsigned int height )
{
if( _current_render_surface != NULL )
_current_render_surface->setWindowRectangle( x, y, width, height );
}
void CameraConfig::setRenderSurfaceCustomFullScreenRectangle( int x, int y, unsigned int width, unsigned int height )
{
if( _current_render_surface != NULL )
_current_render_surface->setCustomFullScreenRectangle( x, y, width, height );
}
void CameraConfig::setRenderSurfaceOverrideRedirect( bool flag )
{
if( _current_render_surface != NULL )
_current_render_surface->useOverrideRedirect( flag );
}
void CameraConfig::setRenderSurfaceHostName( const std::string &name )
{
if( _current_render_surface != NULL )
_current_render_surface->setHostName( name );
}
void CameraConfig::setRenderSurfaceDisplayNum( int n )
{
if( _current_render_surface != NULL )
_current_render_surface->setDisplayNum( n );
}
void CameraConfig::setRenderSurfaceScreen( int n )
{
if( _current_render_surface != NULL )
_current_render_surface->setScreenNum( n );
}
void CameraConfig::setRenderSurfaceBorder( bool flag )
{
if( _current_render_surface != NULL )
_current_render_surface->useBorder( flag );
}
void CameraConfig::setRenderSurfaceDrawableType( RenderSurface::DrawableType drawableType )
{
if( _current_render_surface != NULL )
_current_render_surface->setDrawableType( drawableType );
}
void CameraConfig::setRenderSurfaceRenderToTextureMode( RenderSurface::RenderToTextureMode rttMode )
{
if( _current_render_surface != NULL )
_current_render_surface->setRenderToTextureMode( rttMode );
}
void CameraConfig::setRenderSurfaceReadDrawable( const char *name )
{
if( _current_render_surface != NULL )
{
osgProducer::RenderSurface *readDrawable = findRenderSurface( name );
if( readDrawable == NULL )
{
std::cerr << "setRenderSurfaceReadDrawable(): No Render Surface by name of \"" << name << "\" was found!\n";
return;
}
_current_render_surface->setReadDrawable( readDrawable );
}
}
void CameraConfig::setRenderSurfaceInputRectangle( float x0, float x1, float y0, float y1 )
{
if( _current_render_surface != NULL )
_current_render_surface->setInputRectangle( RenderSurface::InputRectangle(x0,x1,y0,y1) );
}
void CameraConfig::endRenderSurface( void )
{
_can_add_render_surface_attributes = false;
}
RenderSurface *CameraConfig::findRenderSurface( const char *name )
{
std::map<std::string, osg::ref_ptr<RenderSurface> >::iterator p;
p = _render_surface_map.find( std::string(name) );
if( p == _render_surface_map.end() )
return NULL;
else
return (*p).second.get();
}
unsigned int CameraConfig::getNumberOfRenderSurfaces()
{
return _render_surface_map.size();
}
RenderSurface *CameraConfig::getRenderSurface( unsigned int index )
{
if( index >= _render_surface_map.size() )
return NULL;
std::map <std::string, osg::ref_ptr<RenderSurface> >::iterator p;
unsigned int i = 0;
for( p = _render_surface_map.begin(); p != _render_surface_map.end(); p++ )
if( i++ == index )
break;
if( p == _render_surface_map.end() )
return NULL;
return (p->second.get());
}
void CameraConfig::addCamera( std::string name, Camera *camera )
{
std::pair<std::map<std::string, osg::ref_ptr<Camera> >::iterator,bool> res =
_camera_map.insert(std::pair<std::string, osg::ref_ptr<Camera> >(name, camera));
_current_camera = (res.first)->second.get();
_can_add_camera_attributes = true;
RenderSurface *rs = camera->getRenderSurface();
if( rs->getWindowName() == osgProducer::RenderSurface::defaultWindowName )
{
char name[80];
sprintf( name, "%s (%02d)", osgProducer::RenderSurface::defaultWindowName.c_str(), (int)_render_surface_map.size() );
rs->setWindowName( name );
}
_render_surface_map.insert(std::pair<std::string, osg::ref_ptr<RenderSurface> >( rs->getWindowName(), rs ));
}
void CameraConfig::beginCamera( std::string name )
{
Camera *camera = new Camera;
std::pair<std::map<std::string, osg::ref_ptr<Camera> >::iterator,bool> res =
_camera_map.insert(std::pair<std::string, osg::ref_ptr<Camera> >(name, camera));
_current_camera = (res.first)->second.get();
_can_add_camera_attributes = true;
}
void CameraConfig::setCameraRenderSurface( const char *name )
{
RenderSurface *rs = findRenderSurface( name );
if( rs == NULL )
{
std::cerr << "setCameraRenderSurface(): No Render Surface by name of \"" << name << "\" was found!\n";
return;
}
if( rs != NULL && _current_camera != NULL )
_current_camera->setRenderSurface( rs );
}
void CameraConfig::setCameraRenderSurface( void )
{
if( _current_camera != NULL && _current_render_surface != NULL )
_current_camera->setRenderSurface( _current_render_surface.get() );
}
void CameraConfig::setCameraProjectionRectangle( float x0, float x1, float y0, float y1 )
{
if( _current_camera != NULL )
_current_camera->setProjectionRectangle( x0, x1, y0, y1 );
}
void CameraConfig::setCameraProjectionRectangle( int x0, int x1, int y0, int y1 )
{
if( _current_camera != NULL )
_current_camera->setProjectionRectangle( x0, x1, y0, y1 );
}
void CameraConfig::setCameraOrtho( float left, float right, float bottom, float top, float nearClip, float farClip,
float xshear, float yshear )
{
if( _current_camera != NULL )
_current_camera->setLensOrtho( left, right, bottom, top, nearClip, farClip, xshear, yshear );
}
void CameraConfig::setCameraPerspective( float hfov, float vfov, float nearClip, float farClip,
float xshear, float yshear )
{
if( _current_camera != 0 )
_current_camera->setLensPerspective( hfov, vfov, nearClip, farClip, xshear, yshear );
}
void CameraConfig::setCameraFrustum( float left, float right, float bottom, float top, float nearClip, float farClip,
float xshear, float yshear )
{
if( _current_camera != 0 )
_current_camera->setLensFrustum( left, right, bottom, top, nearClip, farClip, xshear, yshear );
}
void CameraConfig::setCameraLensShear( osg::Matrix::value_type xshear, osg::Matrix::value_type yshear )
{
if( _current_camera != NULL )
_current_camera->setLensShear(xshear,yshear);
}
void CameraConfig::setCameraShareLens( bool shared )
{
if( _current_camera != NULL )
_current_camera->setShareLens( shared );
}
void CameraConfig::setCameraShareView( bool shared )
{
if( _current_camera != NULL )
_current_camera->setShareView( shared );
}
void CameraConfig::setCameraClearColor( float r, float g, float b, float a )
{
if( _current_camera != NULL )
_current_camera->setClearColor( r, g, b, a );
}
void CameraConfig::beginCameraOffset()
{
osg::Matrix::value_type id[] = {
1, 0, 0, 0,
0, 1, 0, 0,
0, 0, 1, 0,
0, 0, 0, 1
};
memcpy( _offset_matrix, id, sizeof(osg::Matrix::value_type[16]));
_offset_shearx = _offset_sheary = 0.0;
}
void CameraConfig::shearCameraOffset( osg::Matrix::value_type shearx, osg::Matrix::value_type sheary )
{
_offset_shearx = shearx;
_offset_sheary = sheary;
}
void CameraConfig::setCameraOffsetMultiplyMethod( Camera::Offset::MultiplyMethod method )
{
if( _current_camera != NULL )
_current_camera->setOffsetMultiplyMethod(method);
}
void CameraConfig::endCameraOffset()
{
if( _current_camera != NULL )
_current_camera->setOffset( _offset_matrix, _offset_shearx, _offset_sheary);
}
void CameraConfig::endCamera( void )
{
_can_add_camera_attributes = false;
}
Camera *CameraConfig::findCamera( const char *name )
{
std::map<std::string, osg::ref_ptr<Camera> >::iterator p;
p = _camera_map.find( std::string(name) );
if( p == _camera_map.end() )
return NULL;
else
return (*p).second.get();
}
unsigned int CameraConfig::getNumberOfCameras() const
{
return _camera_map.size();
}
const Camera *CameraConfig::getCamera( unsigned int n ) const
{
if( n >= _camera_map.size() )
return NULL;
unsigned int i;
std::map <std::string, osg::ref_ptr<Camera> >::const_iterator p;
for( i = 0, p = _camera_map.begin(); p != _camera_map.end(); p++ )
if( i++ == n )
break;
if( p == _camera_map.end() )
return NULL;
return p->second.get();
}
Camera *CameraConfig::getCamera( unsigned int n )
{
if( n >= _camera_map.size() )
return NULL;
unsigned int i;
std::map <std::string, osg::ref_ptr<Camera> >::iterator p;
for( i = 0, p = _camera_map.begin(); p != _camera_map.end(); p++ )
if( i++ == n )
break;
if( p == _camera_map.end() )
return NULL;
return p->second.get();
}
void CameraConfig::beginInputArea()
{
_input_area = new InputArea;
_can_add_input_area_entries = true;
}
void CameraConfig::addInputAreaEntry( char *renderSurfaceName )
{
osgProducer::RenderSurface *rs = findRenderSurface( renderSurfaceName );
if( rs == NULL )
{
std::cerr << "setInputAreaEntry(): No Render Surface by name of \"" << renderSurfaceName << "\" was found!\n";
return;
}
if( _input_area != NULL && _can_add_input_area_entries == true )
_input_area->addRenderSurface( rs );
}
void CameraConfig::endInputArea()
{
_can_add_input_area_entries = false;
}
void CameraConfig::setInputArea(InputArea *ia)
{
_input_area=ia;
}
InputArea *CameraConfig::getInputArea()
{
return _input_area.get();
}
const InputArea *CameraConfig::getInputArea() const
{
return _input_area.get();
}
#if 0
void CameraConfig::realize( void )
{
std::map <std::string, osg::ref_ptr<RenderSurface> >::iterator p;
for( p = _render_surface_map.begin(); p != _render_surface_map.end(); p++ )
{
((*p).second)->realize();
}
}
#endif
std::string findFile( std::string );
void CameraConfig::addStereoSystemCommand( int screen, std::string stereoCmd, std::string monoCmd )
{
_stereoSystemCommands.push_back(StereoSystemCommand( screen, stereoCmd, monoCmd ));
}
const std::vector<CameraConfig::StereoSystemCommand> &CameraConfig::getStereoSystemCommands()
{
return _stereoSystemCommands;
}
CameraConfig::~CameraConfig()
{
}
//////////////////////
void CameraConfig::rotateCameraOffset( osg::Matrix::value_type deg, osg::Matrix::value_type x, osg::Matrix::value_type y, osg::Matrix::value_type z )
{
osg::Matrix m;
m.invert(osg::Matrix::rotate( osg::DegreesToRadians(deg), x,y,z));
m = m * osg::Matrix(_offset_matrix);
memcpy( _offset_matrix, m.ptr(), sizeof( osg::Matrix::value_type[16] ));
}
void CameraConfig::translateCameraOffset( osg::Matrix::value_type x, osg::Matrix::value_type y, osg::Matrix::value_type z )
{
osg::Matrix m;
m.invert(osg::Matrix::translate( x,y,z));
m = m * osg::Matrix(_offset_matrix);
memcpy( _offset_matrix, m.ptr(), sizeof( osg::Matrix::value_type[16] ));
}
void CameraConfig::scaleCameraOffset( osg::Matrix::value_type x, osg::Matrix::value_type y, osg::Matrix::value_type z )
{
osg::Matrix m = osg::Matrix::scale( x,y,z) * osg::Matrix(_offset_matrix);
memcpy( _offset_matrix, m.ptr(), sizeof( osg::Matrix::value_type[16] ));
}
bool CameraConfig::fileExists(const std::string& filename)
{
return access( filename.c_str(), F_OK ) == 0;
}
// Order of precedence:
//
std::string CameraConfig::findFile( std::string filename )
{
if (filename.empty()) return filename;
std::string path;
// Check env var
char *ptr = getenv( "PRODUCER_CONFIG_FILE_PATH");
if( ptr != NULL )
{
path = std::string(ptr) + '/' + filename;
if( fileExists(path))
return path;
}
// Check standard location(s)
//path.clear();
path = std::string( "/usr/local/share/Producer/Config/") + filename;
if( fileExists(path) )
return path;
//path.clear();
path = std::string( "/usr/share/Producer/Config/") + filename;
if( fileExists(path) )
return path;
// Check local directory
if(fileExists(filename))
return filename;
// Fail
return std::string();
}
bool CameraConfig::defaultConfig()
{
if( getNumberOfCameras() != 0 ) return false;
char *env = getenv( "PRODUCER_CAMERA_CONFIG_FILE" );
// Backwards compatibility
if( env == NULL )
env = getenv( "PRODUCER_CONFIG_FILE" );
if( env != NULL )
{
std::string file = findFile(env);
return parseFile( file.c_str() );
}
unsigned int numScreens = getNumberOfScreens();
if( numScreens == 0 )
return false;
float xshear = float(numScreens-1);
float yshear = 0.0;
float input_xMin = -1.0f;
float input_yMin = -1.0f;
float input_width = 2.0f/float(numScreens);
float input_height = 2.0f;
// use an InputArea if there is more than one screen.
InputArea *ia = (numScreens>1) ? new InputArea : 0;
setInputArea(ia);
for( unsigned int i = 0; i < numScreens; i++ )
{
std::string name = "Screen" + i;
std::pair<std::map<std::string, osg::ref_ptr<Camera> >::iterator,bool> res =
_camera_map.insert(std::pair<std::string, osg::ref_ptr<Camera> >(name, new Camera));
((res.first)->second)->getRenderSurface()->setScreenNum( i );
((res.first)->second)->setLensShear( xshear, yshear );
RenderSurface *rs = ((res.first)->second)->getRenderSurface();
rs->setWindowName( name );
if (ia)
{
rs->setInputRectangle( RenderSurface::InputRectangle(input_xMin, input_xMin+input_width, input_yMin, input_yMin+input_height) );
input_xMin += input_width;
ia->addRenderSurface(rs);
}
_render_surface_map.insert(std::pair<std::string,
osg::ref_ptr<RenderSurface> >( rs->getWindowName(), rs ));
xshear -= 2.0;
}
_threadModelDirective = CameraGroup::getDefaultThreadModel();
return true;
}

View File

@@ -0,0 +1,246 @@
/* -*-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.
*/
#ifndef PRODUCER_CAMERA_CONFIG
#define PRODUCER_CAMERA_CONFIG
#include <stdio.h>
#include "Camera.h"
#include "RenderSurface.h"
#include <osg/Referenced>
#include <osg/Matrix>
#include <osgViewer/View>
#include <string>
#include <map>
#include <vector>
#include <osg/Notify>
#include <osg/Vec2>
#include <iostream>
//#undef SUPPORT_CPP
namespace osgProducer {
#define notImplemented {std::cout << __FILE__ << " " << __LINE__ << std::endl;}
struct CameraGroup : public osg::Referenced {
enum ThreadModel {
SingleThreaded,
ThreadPerRenderSurface,
ThreadPerCamera,
};
static ThreadModel getDefaultThreadModel() { return SingleThreaded;}
};
struct InputArea : public osg::Referenced {
void addRenderSurface(RenderSurface* s) { _rs.push_back(s); }
std::vector<osg::ref_ptr<RenderSurface> > _rs;
};
#undef notImplemented
class CameraConfig : public osg::Referenced
{
public :
CameraConfig();
void beginVisual( void );
void beginVisual( const char * name );
void setVisualSimpleConfiguration( void );
void setVisualByID( unsigned int id );
void addVisualAttribute( VisualChooser::AttributeName token, int param );
void addVisualAttribute( VisualChooser::AttributeName token );
void addVisualExtendedAttribute( unsigned int token );
void addVisualExtendedAttribute( unsigned int token, int param );
void endVisual( void );
VisualChooser *findVisual( const char *name );
bool parseFile( const std::string &file );
void beginRenderSurface( const char *name );
void setRenderSurfaceVisualChooser( const char *name );
void setRenderSurfaceVisualChooser( void );
void setRenderSurfaceWindowRectangle( int x, int y, unsigned int width, unsigned int height );
void setRenderSurfaceCustomFullScreenRectangle( int x, int y, unsigned int width, unsigned int height );
void setRenderSurfaceOverrideRedirect( bool flag );
void setRenderSurfaceHostName( const std::string &name );
void setRenderSurfaceDisplayNum( int n );
void setRenderSurfaceScreen( int n );
void setRenderSurfaceBorder( bool flag );
void setRenderSurfaceDrawableType( RenderSurface::DrawableType drawableType );
void setRenderSurfaceRenderToTextureMode( RenderSurface::RenderToTextureMode rttMode );
void setRenderSurfaceReadDrawable( const char *name );
void setRenderSurfaceInputRectangle( float x0, float x1, float y0, float y1 );
void endRenderSurface( void );
RenderSurface *findRenderSurface( const char *name );
unsigned int getNumberOfRenderSurfaces();
RenderSurface *getRenderSurface( unsigned int index );
void addCamera( std::string name, Camera *camera );
void beginCamera( std::string name );
void setCameraRenderSurface( const char *name );
void setCameraRenderSurface( void );
void setCameraProjectionRectangle( float x0, float x1, float y0, float y1 );
void setCameraProjectionRectangle( int x0, int x1, int y0, int y1 );
void setCameraOrtho( float left, float right, float bottom, float top, float nearClip, float farClip,
float xshear=0.0, float yshear=0.0 );
void setCameraPerspective( float hfov, float vfov, float nearClip, float farClip,
float xshear=0.0, float yshear=0.0 );
void setCameraFrustum( float left, float right, float bottom, float top, float nearClip, float farClip,
float xshear=0.0, float yshear=0.0 );
void setCameraLensShear( osg::Matrix::value_type xshear, osg::Matrix::value_type yshear );
void setCameraShareLens( bool shared );
void setCameraShareView( bool shared );
void setCameraClearColor( float r, float g, float b, float a );
void beginCameraOffset();
void rotateCameraOffset( osg::Matrix::value_type deg, osg::Matrix::value_type x, osg::Matrix::value_type y, osg::Matrix::value_type z );
void translateCameraOffset( osg::Matrix::value_type x, osg::Matrix::value_type y, osg::Matrix::value_type z );
void scaleCameraOffset( osg::Matrix::value_type x, osg::Matrix::value_type y, osg::Matrix::value_type z );
void shearCameraOffset( osg::Matrix::value_type shearx, osg::Matrix::value_type sheary );
void setCameraOffsetMultiplyMethod( Camera::Offset::MultiplyMethod method );
void endCameraOffset();
void endCamera( void );
Camera *findCamera( const char *name );
unsigned int getNumberOfCameras() const;
const Camera *getCamera( unsigned int n ) const;
Camera *getCamera( unsigned int n );
void beginInputArea();
void addInputAreaEntry( char *renderSurfaceName );
void endInputArea() ;
void setInputArea(InputArea *ia);
InputArea *getInputArea();
const InputArea *getInputArea() const;
void realize( void );
bool defaultConfig();
struct StereoSystemCommand
{
int _screen;
std::string _setStereoCommand;
std::string _restoreMonoCommand;
StereoSystemCommand(int screen, std::string setStereoCommand, std::string restoreMonoCommand ):
_screen(screen),
_setStereoCommand(setStereoCommand),
_restoreMonoCommand(restoreMonoCommand) {}
};
static std::string findFile( std::string );
void addStereoSystemCommand( int screen, std::string stereoCmd, std::string monoCmd );
const std::vector<StereoSystemCommand> &getStereoSystemCommands();
void setThreadModelDirective( CameraGroup::ThreadModel directive ) { _threadModelDirective = directive; }
CameraGroup::ThreadModel getThreadModelDirective() { return _threadModelDirective; }
protected:
virtual ~CameraConfig();
private :
std::map <std::string, VisualChooser *> _visual_map;
osg::ref_ptr< VisualChooser >_current_visual_chooser;
bool _can_add_visual_attributes;
std::map <std::string, osg::ref_ptr<RenderSurface > > _render_surface_map;
osg::ref_ptr<RenderSurface> _current_render_surface;
bool _can_add_render_surface_attributes;
std::map <std::string, osg::ref_ptr< Camera > > _camera_map;
osg::ref_ptr<Camera> _current_camera;
bool _can_add_camera_attributes;
osg::ref_ptr< InputArea > _input_area;
bool _can_add_input_area_entries;
unsigned int getNumberOfScreens();
static bool fileExists(const std::string& );
osg::Matrix::value_type _offset_matrix[16];
osg::Matrix::value_type _offset_shearx, _offset_sheary;
std::vector<StereoSystemCommand> _stereoSystemCommands;
bool _postmultiply;
CameraGroup::ThreadModel _threadModelDirective;
};
};
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,164 @@
/* -*-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.
*/
%{
#include <stdio.h>
#include <ctype.h>
#include "ConfigParser.h"
//#define DEBUG
#ifdef DEBUG
#define REPORT printf(" %s\n", yytext);
#else
#define REPORT
#endif
%}
%option noyywrap
%option c++
/*%option yyclass="ConfigParser"*/
DIGIT [0-9]
ALPHA [A-Za-z]
HEXALNUM [A-Fa-f0-9]
%%
[/][/]|[#]|[!] {
#ifdef DEBUG
char buff[128];
int i = 0;
#endif
char c;
while( (c = yyinput()) != '\n' )
{
if( c <= 0 )
break;
#ifdef DEBUG
buff[i++] = c;
#endif
}
#ifdef DEBUG
buff[i] = 0;
printf( "Single line comment: \"%s\"\n", buff );
#endif
}
[\n] { yylineno++;}
[ \t] { ; }
[{] { REPORT return '{'; }
[}] { REPORT return '}'; }
["] {
char c;
int i = 0;
while( (c = yyinput()) != '"' )
yytext[i++] = c;
yytext[i] = 0;
return PRTOKEN_QUOTED_STRING;
}
[,] { REPORT return ','; }
[:] { REPORT return ':'; }
[;] { REPORT return ';'; }
SetSimple { REPORT return PRTOKEN_SET_SIMPLE; }
VisualID { REPORT return PRTOKEN_VISUAL_ID; }
BUFFER_SIZE { REPORT return PRTOKEN_BUFFER_SIZE; }
LEVEL { REPORT return PRTOKEN_LEVEL; }
RGBA { REPORT return PRTOKEN_RGBA; }
DOUBLEBUFFER { REPORT return PRTOKEN_DOUBLEBUFFER; }
STEREO { REPORT return PRTOKEN_STEREO; }
AUX_BUFFERS { REPORT return PRTOKEN_AUX_BUFFERS; }
RED_SIZE { REPORT return PRTOKEN_RED_SIZE; }
GREEN_SIZE { REPORT return PRTOKEN_GREEN_SIZE; }
BLUE_SIZE { REPORT return PRTOKEN_BLUE_SIZE; }
ALPHA_SIZE { REPORT return PRTOKEN_ALPHA_SIZE; }
DEPTH_SIZE { REPORT return PRTOKEN_DEPTH_SIZE; }
STENCIL_SIZE { REPORT return PRTOKEN_STENCIL_SIZE; }
ACCUM_RED_SIZE { REPORT return PRTOKEN_ACCUM_RED_SIZE; }
ACCUM_GREEN_SIZE { REPORT return PRTOKEN_ACCUM_GREEN_SIZE; }
ACCUM_BLUE_SIZE { REPORT return PRTOKEN_ACCUM_BLUE_SIZE; }
ACCUM_ALPHA_SIZE { REPORT return PRTOKEN_ACCUM_ALPHA_SIZE; }
SAMPLES { REPORT return PRTOKEN_SAMPLES; }
SAMPLE_BUFFERS { REPORT return PRTOKEN_SAMPLE_BUFFERS; }
Visual { REPORT return PRTOKEN_VISUAL; }
RenderSurface { REPORT return PRTOKEN_RENDER_SURFACE; }
WindowRectangle { REPORT return PRTOKEN_WINDOW_RECT; }
WindowRect { REPORT return PRTOKEN_WINDOW_RECT; }
Hostname { REPORT return PRTOKEN_HOSTNAME; }
Display { REPORT return PRTOKEN_DISPLAY; }
Screen { REPORT return PRTOKEN_SCREEN; }
Border { REPORT return PRTOKEN_BORDER; }
InputRectangle { REPORT return PRTOKEN_INPUT_RECT; }
InputRect { REPORT return PRTOKEN_INPUT_RECT; }
DrawableType { REPORT return PRTOKEN_DRAWABLE_TYPE; }
PBUFFER_TYPE { REPORT return PRTOKEN_PBUFFER_TYPE; }
WINDOW_TYPE { REPORT return PRTOKEN_WINDOW_TYPE; }
ReadDrawable { REPORT return PRTOKEN_READ_DRAWABLE; }
RenderToTextureMode { REPORT return PRTOKEN_SET_RTT_MODE; }
RTT_NONE { REPORT return PRTOKEN_RTT_MODE_NONE; }
RTT_RGB { REPORT return PRTOKEN_RTT_MODE_RGB; }
RTT_RGBA { REPORT; return PRTOKEN_RTT_MODE_RGBA; }
CameraGroup { REPORT return PRTOKEN_CAMERA_GROUP; }
Camera { REPORT return PRTOKEN_CAMERA; }
ProjectionRectangle { REPORT return PRTOKEN_PROJECTION_RECT; }
ProjectionRect { REPORT return PRTOKEN_PROJECTION_RECT; }
Lens { REPORT return PRTOKEN_LENS; }
ShareLens { REPORT return PRTOKEN_SHARELENS; }
ShareView { REPORT return PRTOKEN_SHAREVIEW; }
Frustum { REPORT return PRTOKEN_FRUSTUM; }
Perspective { REPORT return PRTOKEN_PERSPECTIVE; }
Ortho { REPORT return PRTOKEN_ORTHO; }
ClearColor { REPORT return PRTOKEN_CLEAR_COLOR; }
Offset { REPORT return PRTOKEN_OFFSET; }
Rotate { REPORT return PRTOKEN_ROTATE; }
Translate { REPORT return PRTOKEN_TRANSLATE; }
Scale { REPORT return PRTOKEN_SCALE; }
Shear { REPORT return PRTOKEN_SHEAR; }
Method { REPORT return PRTOKEN_METHOD; }
PreMultiply { REPORT return PRTOKEN_PREMULTIPLY; }
PostMultiply { REPORT return PRTOKEN_POSTMULTIPLY; }
InputArea { REPORT return PRTOKEN_INPUT_AREA; }
StereoSystemCommands { REPORT return PRTOKEN_STEREO_SYSTEM_COMMANDS; }
CustomFullScreenRectangle { REPORT return PRTOKEN_CUSTOM_FULL_SCREEN_RECTANGLE; }
OverrideRedirect { REPORT return PRTOKEN_OVERRIDE_REDIRECT; }
ThreadModel { REPORT return PRTOKEN_THREAD_MODEL; }
SingleThreaded { REPORT return PRTOKEN_SINGLE_THREADED; }
ThreadPerCamera { REPORT return PRTOKEN_THREAD_PER_CAMERA; }
ThreadPerRenderSurface { REPORT return PRTOKEN_THREAD_PER_RENDER_SURFACE; }
on|ON|true|yes { REPORT return PRTOKEN_TRUE; }
off|OFF|false|no { REPORT return PRTOKEN_FALSE; }
[-]?0x{HEXALNUM}+ { REPORT return PRTOKEN_HEX_INTEGER; }
[-]?{DIGIT}+ { REPORT return PRTOKEN_INTEGER; }
[-]?{DIGIT}*"."{DIGIT}*[Ff]? { REPORT return PRTOKEN_FLOAT; }
[-]?{DIGIT}+[fF]{1} { REPORT return PRTOKEN_FLOAT; }
[-]?({DIGIT}+)([eE][-+]?{DIGIT}+)? { REPORT return PRTOKEN_FLOAT; }
[-]?({DIGIT}*\.{DIGIT}+)([eE][-+]?{DIGIT}+)? { REPORT return PRTOKEN_FLOAT; }
%%

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,194 @@
/* A Bison parser, made by GNU Bison 1.875. */
/* Skeleton parser for Yacc-like parsing with Bison,
Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002 Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
This program 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
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
/* As a special exception, when this file is copied by Bison into a
Bison output file, you may use that output file without restriction.
This special exception was added by the Free Software Foundation
in version 1.24 of Bison. */
/* Tokens. */
#ifndef YYTOKENTYPE
# define YYTOKENTYPE
/* Put the tokens into the symbol table, so that GDB and other debuggers
know about them. */
enum yytokentype {
PRTOKEN_VISUAL = 258,
PRTOKEN_SET_SIMPLE = 259,
PRTOKEN_VISUAL_ID = 260,
PRTOKEN_BUFFER_SIZE = 261,
PRTOKEN_LEVEL = 262,
PRTOKEN_RGBA = 263,
PRTOKEN_DOUBLEBUFFER = 264,
PRTOKEN_STEREO = 265,
PRTOKEN_AUX_BUFFERS = 266,
PRTOKEN_RED_SIZE = 267,
PRTOKEN_GREEN_SIZE = 268,
PRTOKEN_BLUE_SIZE = 269,
PRTOKEN_ALPHA_SIZE = 270,
PRTOKEN_DEPTH_SIZE = 271,
PRTOKEN_STENCIL_SIZE = 272,
PRTOKEN_ACCUM_RED_SIZE = 273,
PRTOKEN_ACCUM_GREEN_SIZE = 274,
PRTOKEN_ACCUM_BLUE_SIZE = 275,
PRTOKEN_ACCUM_ALPHA_SIZE = 276,
PRTOKEN_SAMPLES = 277,
PRTOKEN_SAMPLE_BUFFERS = 278,
PRTOKEN_RENDER_SURFACE = 279,
PRTOKEN_WINDOW_RECT = 280,
PRTOKEN_INPUT_RECT = 281,
PRTOKEN_HOSTNAME = 282,
PRTOKEN_DISPLAY = 283,
PRTOKEN_SCREEN = 284,
PRTOKEN_BORDER = 285,
PRTOKEN_DRAWABLE_TYPE = 286,
PRTOKEN_WINDOW_TYPE = 287,
PRTOKEN_PBUFFER_TYPE = 288,
PRTOKEN_CAMERA_GROUP = 289,
PRTOKEN_CAMERA = 290,
PRTOKEN_PROJECTION_RECT = 291,
PRTOKEN_LENS = 292,
PRTOKEN_FRUSTUM = 293,
PRTOKEN_PERSPECTIVE = 294,
PRTOKEN_ORTHO = 295,
PRTOKEN_OFFSET = 296,
PRTOKEN_ROTATE = 297,
PRTOKEN_TRANSLATE = 298,
PRTOKEN_SCALE = 299,
PRTOKEN_SHEAR = 300,
PRTOKEN_CLEAR_COLOR = 301,
PRTOKEN_INPUT_AREA = 302,
PRTOKEN_ERROR = 303,
PRTOKEN_INTEGER = 304,
PRTOKEN_HEX_INTEGER = 305,
PRTOKEN_FLOAT = 306,
PRTOKEN_TRUE = 307,
PRTOKEN_FALSE = 308,
PRTOKEN_QUOTED_STRING = 309,
PRTOKEN_STEREO_SYSTEM_COMMANDS = 310,
PRTOKEN_CUSTOM_FULL_SCREEN_RECTANGLE = 311,
PRTOKEN_METHOD = 312,
PRTOKEN_PREMULTIPLY = 313,
PRTOKEN_POSTMULTIPLY = 314,
PRTOKEN_OVERRIDE_REDIRECT = 315,
PRTOKEN_SHARELENS = 316,
PRTOKEN_SHAREVIEW = 317,
PRTOKEN_READ_DRAWABLE = 318,
PRTOKEN_SET_RTT_MODE = 319,
PRTOKEN_RTT_MODE_NONE = 320,
PRTOKEN_RTT_MODE_RGB = 321,
PRTOKEN_RTT_MODE_RGBA = 322,
PRTOKEN_THREAD_MODEL = 323,
PRTOKEN_SINGLE_THREADED = 324,
PRTOKEN_THREAD_PER_CAMERA = 325,
PRTOKEN_THREAD_PER_RENDER_SURFACE = 326
};
#endif
#define PRTOKEN_VISUAL 258
#define PRTOKEN_SET_SIMPLE 259
#define PRTOKEN_VISUAL_ID 260
#define PRTOKEN_BUFFER_SIZE 261
#define PRTOKEN_LEVEL 262
#define PRTOKEN_RGBA 263
#define PRTOKEN_DOUBLEBUFFER 264
#define PRTOKEN_STEREO 265
#define PRTOKEN_AUX_BUFFERS 266
#define PRTOKEN_RED_SIZE 267
#define PRTOKEN_GREEN_SIZE 268
#define PRTOKEN_BLUE_SIZE 269
#define PRTOKEN_ALPHA_SIZE 270
#define PRTOKEN_DEPTH_SIZE 271
#define PRTOKEN_STENCIL_SIZE 272
#define PRTOKEN_ACCUM_RED_SIZE 273
#define PRTOKEN_ACCUM_GREEN_SIZE 274
#define PRTOKEN_ACCUM_BLUE_SIZE 275
#define PRTOKEN_ACCUM_ALPHA_SIZE 276
#define PRTOKEN_SAMPLES 277
#define PRTOKEN_SAMPLE_BUFFERS 278
#define PRTOKEN_RENDER_SURFACE 279
#define PRTOKEN_WINDOW_RECT 280
#define PRTOKEN_INPUT_RECT 281
#define PRTOKEN_HOSTNAME 282
#define PRTOKEN_DISPLAY 283
#define PRTOKEN_SCREEN 284
#define PRTOKEN_BORDER 285
#define PRTOKEN_DRAWABLE_TYPE 286
#define PRTOKEN_WINDOW_TYPE 287
#define PRTOKEN_PBUFFER_TYPE 288
#define PRTOKEN_CAMERA_GROUP 289
#define PRTOKEN_CAMERA 290
#define PRTOKEN_PROJECTION_RECT 291
#define PRTOKEN_LENS 292
#define PRTOKEN_FRUSTUM 293
#define PRTOKEN_PERSPECTIVE 294
#define PRTOKEN_ORTHO 295
#define PRTOKEN_OFFSET 296
#define PRTOKEN_ROTATE 297
#define PRTOKEN_TRANSLATE 298
#define PRTOKEN_SCALE 299
#define PRTOKEN_SHEAR 300
#define PRTOKEN_CLEAR_COLOR 301
#define PRTOKEN_INPUT_AREA 302
#define PRTOKEN_ERROR 303
#define PRTOKEN_INTEGER 304
#define PRTOKEN_HEX_INTEGER 305
#define PRTOKEN_FLOAT 306
#define PRTOKEN_TRUE 307
#define PRTOKEN_FALSE 308
#define PRTOKEN_QUOTED_STRING 309
#define PRTOKEN_STEREO_SYSTEM_COMMANDS 310
#define PRTOKEN_CUSTOM_FULL_SCREEN_RECTANGLE 311
#define PRTOKEN_METHOD 312
#define PRTOKEN_PREMULTIPLY 313
#define PRTOKEN_POSTMULTIPLY 314
#define PRTOKEN_OVERRIDE_REDIRECT 315
#define PRTOKEN_SHARELENS 316
#define PRTOKEN_SHAREVIEW 317
#define PRTOKEN_READ_DRAWABLE 318
#define PRTOKEN_SET_RTT_MODE 319
#define PRTOKEN_RTT_MODE_NONE 320
#define PRTOKEN_RTT_MODE_RGB 321
#define PRTOKEN_RTT_MODE_RGBA 322
#define PRTOKEN_THREAD_MODEL 323
#define PRTOKEN_SINGLE_THREADED 324
#define PRTOKEN_THREAD_PER_CAMERA 325
#define PRTOKEN_THREAD_PER_RENDER_SURFACE 326
#if ! defined (YYSTYPE) && ! defined (YYSTYPE_IS_DECLARED)
typedef union YYSTYPE {
char * string;
int integer;
float real;
bool boolean;
} YYSTYPE;
/* Line 1249 of yacc.c. */
# define yystype YYSTYPE /* obsolescent; will be withdrawn */
# define YYSTYPE_IS_DECLARED 1
# define YYSTYPE_IS_TRIVIAL 1
#endif
extern YYSTYPE ConfigParser_lval;

View File

@@ -0,0 +1,654 @@
/* -*-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.
*/
%{
#ifndef WIN32
#include <unistd.h>
#include <sys/wait.h>
#include <stdlib.h>
#include <fcntl.h>
#endif
#ifndef WIN32
#define SUPPORT_CPP 1
#endif
#include <stdio.h>
#include <fstream>
#include <string>
#include "FlexLexer.h"
#include <Producer/CameraConfig>
using namespace std;
using namespace Producer;
static void ConfigParser_error( const char * );
static CameraConfig *cfg = 0L;
static std::string fileName = "(stdin)";
static yyFlexLexer *flexer = 0L;
static int yylex()
{
if( flexer == 0L )
fprintf( stderr, "Internal error!\n" );
return flexer->yylex();
}
%}
%token PRTOKEN_VISUAL
%token PRTOKEN_SET_SIMPLE
%token PRTOKEN_VISUAL_ID
%token PRTOKEN_BUFFER_SIZE
%token PRTOKEN_LEVEL
%token PRTOKEN_RGBA
%token PRTOKEN_DOUBLEBUFFER
%token PRTOKEN_STEREO
%token PRTOKEN_AUX_BUFFERS
%token PRTOKEN_RED_SIZE
%token PRTOKEN_GREEN_SIZE
%token PRTOKEN_BLUE_SIZE
%token PRTOKEN_ALPHA_SIZE
%token PRTOKEN_DEPTH_SIZE
%token PRTOKEN_STENCIL_SIZE
%token PRTOKEN_ACCUM_RED_SIZE
%token PRTOKEN_ACCUM_GREEN_SIZE
%token PRTOKEN_ACCUM_BLUE_SIZE
%token PRTOKEN_ACCUM_ALPHA_SIZE
%token PRTOKEN_ACCUM_ALPHA_SIZE
%token PRTOKEN_SAMPLES
%token PRTOKEN_SAMPLE_BUFFERS
%token PRTOKEN_RENDER_SURFACE
%token PRTOKEN_WINDOW_RECT
%token PRTOKEN_INPUT_RECT
%token PRTOKEN_HOSTNAME
%token PRTOKEN_DISPLAY
%token PRTOKEN_SCREEN
%token PRTOKEN_BORDER
%token PRTOKEN_DRAWABLE_TYPE
%token PRTOKEN_WINDOW_TYPE
%token PRTOKEN_PBUFFER_TYPE
%token PRTOKEN_CAMERA_GROUP
%token PRTOKEN_CAMERA
%token PRTOKEN_PROJECTION_RECT
%token PRTOKEN_LENS
%token PRTOKEN_FRUSTUM
%token PRTOKEN_PERSPECTIVE
%token PRTOKEN_ORTHO
%token PRTOKEN_OFFSET
%token PRTOKEN_ROTATE
%token PRTOKEN_TRANSLATE
%token PRTOKEN_SCALE
%token PRTOKEN_SHEAR
%token PRTOKEN_CLEAR_COLOR
%token PRTOKEN_INPUT_AREA
%token PRTOKEN_ERROR
%token PRTOKEN_INTEGER
%token PRTOKEN_HEX_INTEGER
%token PRTOKEN_FLOAT
%token PRTOKEN_TRUE
%token PRTOKEN_FALSE
%token PRTOKEN_QUOTED_STRING
%token PRTOKEN_STEREO_SYSTEM_COMMANDS
%token PRTOKEN_CUSTOM_FULL_SCREEN_RECTANGLE
%token PRTOKEN_METHOD
%token PRTOKEN_PREMULTIPLY
%token PRTOKEN_POSTMULTIPLY
%token PRTOKEN_OVERRIDE_REDIRECT
%token PRTOKEN_SHARELENS
%token PRTOKEN_SHAREVIEW
%token PRTOKEN_READ_DRAWABLE
%token PRTOKEN_SET_RTT_MODE
%token PRTOKEN_RTT_MODE_NONE
%token PRTOKEN_RTT_MODE_RGB
%token PRTOKEN_RTT_MODE_RGBA
%token PRTOKEN_THREAD_MODEL
%token PRTOKEN_SINGLE_THREADED
%token PRTOKEN_THREAD_PER_CAMERA
%token PRTOKEN_THREAD_PER_RENDER_SURFACE
%union {
char * string;
int integer;
float real;
bool boolean;
};
%type <string> name string;
%type <integer> intparam offset_multiply_method;
%type <integer> hex_integer;
%type <integer> drawableType rtt_mode;
%type <integer> threadModelDirective;
%type <real> floatparam;
%type <real> real;
%type <boolean> bool;
%%
config : entries
;
entries : entry | entries entry
;
entry : visual | render_surface | camera | input_area | camera_group | stereo_param | system_params
;
system_params : system_param | system_params system_param
;
system_param :
PRTOKEN_THREAD_MODEL threadModelDirective ';'
{
Producer::CameraGroup::ThreadModel tm = (Producer::CameraGroup::ThreadModel)$2;
cfg->setThreadModelDirective( tm );
}
;
threadModelDirective:
PRTOKEN_SINGLE_THREADED { $$ = CameraGroup::SingleThreaded; }
| PRTOKEN_THREAD_PER_CAMERA { $$ = CameraGroup::ThreadPerCamera; }
| PRTOKEN_THREAD_PER_RENDER_SURFACE { $$ = CameraGroup::ThreadPerRenderSurface; }
;
stereo_param : PRTOKEN_STEREO_SYSTEM_COMMANDS intparam string string ';'
{
cfg->addStereoSystemCommand( $2, $3, $4 );
};
camera_group: PRTOKEN_CAMERA_GROUP '{' camera_group_attributes '}'
;
camera_group_attributes: cameras
;
cameras : /* null */ | camera | cameras camera
;
camera : PRTOKEN_CAMERA name
{
cfg->beginCamera( $2 );
}
'{' camera_attributes '}'
{
cfg->endCamera();
};
camera_attributes : camera_attribute | camera_attributes camera_attribute
;
camera_attribute :
/* EMPTY */
| PRTOKEN_RENDER_SURFACE name ';'
{
cfg->setCameraRenderSurface( $2 );
}
| render_surface
{
cfg->setCameraRenderSurface();
}
| PRTOKEN_PROJECTION_RECT real real real real ';'
{
cfg->setCameraProjectionRectangle( $2, $3, $4, $5 );
}
| PRTOKEN_SHARELENS bool ';'
{
cfg->setCameraShareLens( $2 );
}
| PRTOKEN_SHAREVIEW bool ';'
{
cfg->setCameraShareView( $2 );
}
| PRTOKEN_CLEAR_COLOR real real real real ';'
{
cfg->setCameraClearColor( $2, $3, $4, $5 );
}
| lens
| camera_offset
;
camera_offset : PRTOKEN_OFFSET '{'
{
cfg->beginCameraOffset();
}
camera_offset_attributes '}'
{
cfg->endCameraOffset();
}
;
camera_offset_attributes : camera_offset_attribute | camera_offset_attributes camera_offset_attribute
;
camera_offset_attribute :
PRTOKEN_SHEAR real real ';'
{
cfg->shearCameraOffset( $2, $3 );
}
| PRTOKEN_ROTATE real real real real ';'
{
cfg->rotateCameraOffset( $2, $3, $4, $5 );
}
| PRTOKEN_TRANSLATE real real real ';'
{
cfg->translateCameraOffset( $2, $3, $4 );
}
| PRTOKEN_SCALE real real real ';'
{
cfg->scaleCameraOffset( $2, $3, $4 );
}
| PRTOKEN_METHOD offset_multiply_method ';'
{
cfg->setCameraOffsetMultiplyMethod( (Producer::Camera::Offset::MultiplyMethod)$2 );
}
;
offset_multiply_method:
PRTOKEN_PREMULTIPLY { $$ = Producer::Camera::Offset::PreMultiply; }
| PRTOKEN_POSTMULTIPLY { $$ = Producer::Camera::Offset::PostMultiply; }
;
lens : PRTOKEN_LENS '{' lens_attributes '}'
;
lens_attributes : lens_attribute | lens_attributes lens_attribute
;
lens_attribute :
/* Empty */
| PRTOKEN_ORTHO real real real real real real ';'
{
cfg->setCameraOrtho( $2, $3, $4, $5, $6, $7 );
}
| PRTOKEN_ORTHO real real real real real real real real ';'
{
cfg->setCameraOrtho( $2, $3, $4, $5, $6, $7, $8, $9 );
}
| PRTOKEN_PERSPECTIVE real real real real ';'
{
cfg->setCameraPerspective( $2, $3, $4, $5 );
}
| PRTOKEN_PERSPECTIVE real real real real real real ';'
{
cfg->setCameraPerspective( $2, $3, $4, $5, $6, $7 );
}
| PRTOKEN_FRUSTUM real real real real real real ';'
{
cfg->setCameraFrustum( $2, $3, $4, $5, $6, $7 );
}
| PRTOKEN_FRUSTUM real real real real real real real real ';'
{
cfg->setCameraFrustum( $2, $3, $4, $5, $6, $7, $8, $9 );
}
| PRTOKEN_SHEAR real real ';'
{
cfg->setCameraLensShear( $2, $3 );
}
;
render_surface : PRTOKEN_RENDER_SURFACE name
{
cfg->beginRenderSurface( $2 );
}
'{' render_surface_attributes '}'
{
cfg->endRenderSurface();
}
;
render_surface_attributes :
render_surface_attribute
| render_surface_attributes render_surface_attribute
;
render_surface_attribute :
/* Empty */
| PRTOKEN_VISUAL name ';'
{
cfg->setRenderSurfaceVisualChooser( $2 );
}
| visual
{
cfg->setRenderSurfaceVisualChooser();
}
| PRTOKEN_WINDOW_RECT intparam intparam intparam intparam ';'
{
cfg->setRenderSurfaceWindowRectangle( $2, $3, $4, $5 );
}
| PRTOKEN_INPUT_RECT floatparam floatparam floatparam floatparam ';'
{
cfg->setRenderSurfaceInputRectangle( $2, $3, $4, $5 );
}
| PRTOKEN_HOSTNAME name ';'
{
cfg->setRenderSurfaceHostName( std::string($2) );
}
| PRTOKEN_DISPLAY intparam ';'
{
cfg->setRenderSurfaceDisplayNum( $2 );
}
| PRTOKEN_SCREEN intparam ';'
{
cfg->setRenderSurfaceScreen( $2 );
}
| PRTOKEN_BORDER bool ';'
{
cfg->setRenderSurfaceBorder( $2 );
}
| PRTOKEN_CUSTOM_FULL_SCREEN_RECTANGLE intparam intparam intparam intparam ';'
{
cfg->setRenderSurfaceCustomFullScreenRectangle( $2, $3, $4, $5 );
}
| PRTOKEN_OVERRIDE_REDIRECT bool ';'
{
cfg->setRenderSurfaceOverrideRedirect( $2 );
}
| PRTOKEN_DRAWABLE_TYPE drawableType ';'
{
Producer::RenderSurface::DrawableType drawableType = (RenderSurface::DrawableType)$2;
cfg->setRenderSurfaceDrawableType( drawableType );
}
| PRTOKEN_READ_DRAWABLE name ';'
{
cfg->setRenderSurfaceReadDrawable( $2 );
}
| PRTOKEN_SET_RTT_MODE rtt_mode ';'
{
cfg->setRenderSurfaceRenderToTextureMode( (Producer::RenderSurface::RenderToTextureMode)$2 );
}
;
drawableType:
PRTOKEN_WINDOW_TYPE { $$ = RenderSurface::DrawableType_Window; }
| PRTOKEN_PBUFFER_TYPE { $$ = RenderSurface::DrawableType_PBuffer; }
;
rtt_mode :
PRTOKEN_RTT_MODE_NONE { $$ = RenderSurface::RenderToTextureMode_None; }
| PRTOKEN_RTT_MODE_RGB { $$ = RenderSurface::RenderToRGBTexture; }
| PRTOKEN_RTT_MODE_RGBA { $$ = RenderSurface::RenderToRGBATexture; }
;
visual : PRTOKEN_VISUAL name
{
cfg->beginVisual( $2 );
}
'{' visual_attributes '}'
{
cfg->endVisual();
}
| PRTOKEN_VISUAL
{
cfg->beginVisual();
}
'{' visual_attributes '}'
{
cfg->endVisual();
}
;
visual_attributes : visual_attribute | visual_attributes ',' visual_attribute
;
visual_attribute :
PRTOKEN_SET_SIMPLE
{
cfg->setVisualSimpleConfiguration();
}
| PRTOKEN_VISUAL_ID hex_integer
{
cfg->setVisualByID( $2 );
}
| PRTOKEN_BUFFER_SIZE intparam
{
cfg->addVisualAttribute( VisualChooser::BufferSize, $2 );
}
| PRTOKEN_LEVEL intparam
{
cfg->addVisualAttribute( VisualChooser::Level, $2 );
}
| PRTOKEN_RGBA
{
cfg->addVisualAttribute( VisualChooser::RGBA );
}
| PRTOKEN_DOUBLEBUFFER
{
cfg->addVisualAttribute( VisualChooser::DoubleBuffer );
}
| PRTOKEN_STEREO
{
cfg->addVisualAttribute( VisualChooser::Stereo );
}
| PRTOKEN_AUX_BUFFERS intparam
{
cfg->addVisualAttribute( VisualChooser::AuxBuffers, $2 );
}
| PRTOKEN_RED_SIZE intparam
{
cfg->addVisualAttribute( VisualChooser::RedSize, $2 );
}
| PRTOKEN_GREEN_SIZE intparam
{
cfg->addVisualAttribute( VisualChooser::GreenSize, $2 );
}
| PRTOKEN_BLUE_SIZE intparam
{
cfg->addVisualAttribute( VisualChooser::BlueSize, $2 );
}
| PRTOKEN_ALPHA_SIZE intparam
{
cfg->addVisualAttribute( VisualChooser::AlphaSize, $2 );
}
| PRTOKEN_DEPTH_SIZE intparam
{
cfg->addVisualAttribute( VisualChooser::DepthSize, $2 );
}
| PRTOKEN_STENCIL_SIZE intparam
{
cfg->addVisualAttribute( VisualChooser::StencilSize, $2 );
}
| PRTOKEN_ACCUM_RED_SIZE intparam
{
cfg->addVisualAttribute( VisualChooser::AccumRedSize, $2 );
}
| PRTOKEN_ACCUM_GREEN_SIZE intparam
{
cfg->addVisualAttribute( VisualChooser::AccumGreenSize, $2 );
}
| PRTOKEN_ACCUM_BLUE_SIZE intparam
{
cfg->addVisualAttribute( VisualChooser::AccumBlueSize, $2 );
}
| PRTOKEN_ACCUM_ALPHA_SIZE intparam
{
cfg->addVisualAttribute( VisualChooser::AccumAlphaSize, $2 );
}
| PRTOKEN_SAMPLES intparam
{
cfg->addVisualAttribute( VisualChooser::Samples, $2 );
}
| PRTOKEN_SAMPLE_BUFFERS
{
cfg->addVisualAttribute( VisualChooser::SampleBuffers );
}
| intparam intparam
{
cfg->addVisualExtendedAttribute( $1, $2 );
}
;
input_area : PRTOKEN_INPUT_AREA
{ cfg->beginInputArea(); }
'{' input_area_entries '}'
{ cfg->endInputArea(); }
;
input_area_entries : input_area_entry | input_area_entries input_area_entry
;
input_area_entry :
PRTOKEN_RENDER_SURFACE name ';'
{
cfg->addInputAreaEntry( $2 );
}
;
real : PRTOKEN_FLOAT
{
$$ = atof(flexer->YYText());
}
| PRTOKEN_INTEGER
{
$$ = atof(flexer->YYText());
}
;
floatparam : PRTOKEN_FLOAT
{
$$ = atof(flexer->YYText());
}
;
intparam : PRTOKEN_INTEGER
{
$$ = atoi( flexer->YYText() );
}
;
name : PRTOKEN_QUOTED_STRING
{
$$ = strdup( flexer->YYText() );
}
;
string : PRTOKEN_QUOTED_STRING
{
$$ = strdup( flexer->YYText() );
}
;
hex_integer : PRTOKEN_HEX_INTEGER
{
int n;
sscanf( flexer->YYText(), "0x%x", &n );
$$ = n;
}
;
bool : PRTOKEN_TRUE { $$ = true;} | PRTOKEN_FALSE { $$ = false; }
;
%%
static void yyerror( const char *errmsg )
{
fprintf( stderr,
"CameraConfig::parseFile(\"%s\") : %s - Line %d at or before \"%s\"\n",
fileName.c_str(),
errmsg,
flexer->lineno(),
flexer->YYText() );
}
bool CameraConfig::parseFile( const std::string &file )
{
fileName.clear();
fileName = findFile(file);
if( fileName.empty() )
{
fprintf( stderr, "CameraConfig::parseFile() - Can't find file \"%s\".\n", file.c_str() );
return false;
}
bool retval = true;
#if defined (SUPPORT_CPP)
char *cpp_path =
#if defined(__APPLE__)
"/usr/bin/cpp";
#else
"/lib/cpp";
#endif
if( access( cpp_path, X_OK ) == 0 )
{
int pd[2];
pipe( pd );
flexer = new yyFlexLexer;
if( fork() == 0 )
{
// we don't want to read from the pipe in the child, so close it.
close( pd[0] );
close( 1 );
dup( pd[1] );
/* This was here to allow reading a config file from stdin.
* This has never been directly supported, so commenting out.
if( fileName.empty() )
execlp( cpp_path, "cpp", "-P", 0L );
else
*/
execlp( cpp_path, "cpp", "-P", fileName.c_str(), 0L );
// This should not execute unless an error happens
perror( "execlp" );
}
else
{
close( pd[1]);
close( 0 );
dup( pd[0] );
cfg = this;
retval = ConfigParser_parse() == 0 ? true : false;
// Wait on child process to finish
int stat;
wait( &stat );
}
}
else
#endif
{
std::ifstream ifs(fileName.c_str());
flexer = new yyFlexLexer(&ifs);
cfg = this;
retval = ConfigParser_parse() == 0 ? true : false;
ifs.close();
delete flexer;
}
return retval;
}

View File

@@ -0,0 +1,186 @@
// $Header: /cvs/Producer/Producer/src/FlexLexer.h,v 1.1 2003/04/08 23:01:09 donr Exp $
// FlexLexer.h -- define interfaces for lexical analyzer classes generated
// by flex
// Copyright (c) 1993 The Regents of the University of California.
// All rights reserved.
//
// This code is derived from software contributed to Berkeley by
// Kent Williams and Tom Epperly.
//
// Redistribution and use in source and binary forms with or without
// modification are permitted provided that: (1) source distributions retain
// this entire copyright notice and comment, and (2) distributions including
// binaries display the following acknowledgement: ``This product includes
// software developed by the University of California, Berkeley and its
// contributors'' in the documentation or other materials provided with the
// distribution and in all advertising materials mentioning features or use
// of this software. Neither the name of the University nor the names of
// its contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
// THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
// WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
// This file defines FlexLexer, an abstract class which specifies the
// external interface provided to flex C++ lexer objects, and yyFlexLexer,
// which defines a particular lexer class.
//
// If you want to create multiple lexer classes, you use the -P flag
// to rename each yyFlexLexer to some other xxFlexLexer. You then
// include <FlexLexer.h> in your other sources once per lexer class:
//
// #undef yyFlexLexer
// #define yyFlexLexer xxFlexLexer
// #include <FlexLexer.h>
//
// #undef yyFlexLexer
// #define yyFlexLexer zzFlexLexer
// #include <FlexLexer.h>
// ...
#ifndef __FLEX_LEXER_H
// Never included before - need to define base class.
#define __FLEX_LEXER_H
#include <iostream>
extern "C++" {
struct yy_buffer_state;
typedef int yy_state_type;
class FlexLexer {
public:
virtual ~FlexLexer() { }
const char* YYText() { return yytext; }
int YYLeng() { return yyleng; }
virtual void
yy_switch_to_buffer( struct yy_buffer_state* new_buffer ) = 0;
virtual struct yy_buffer_state*
yy_create_buffer( std::istream* s, int size ) = 0;
virtual void yy_delete_buffer( struct yy_buffer_state* b ) = 0;
virtual void yyrestart( std::istream* s ) = 0;
virtual int yylex() = 0;
// Call yylex with new input/output sources.
int yylex( std::istream* new_in, std::ostream* new_out = 0 )
{
switch_streams( new_in, new_out );
return yylex();
}
// Switch to new input/output streams. A nil stream pointer
// indicates "keep the current one".
virtual void switch_streams( std::istream* new_in = 0,
std::ostream* new_out = 0 ) = 0;
int lineno() const { return yylineno; }
int debug() const { return yy_flex_debug; }
void set_debug( int flag ) { yy_flex_debug = flag; }
protected:
char* yytext;
int yyleng;
int yylineno; // only maintained if you use %option yylineno
int yy_flex_debug; // only has effect with -d or "%option debug"
};
}
#endif
#if defined(yyFlexLexer) || ! defined(yyFlexLexerOnce)
// Either this is the first time through (yyFlexLexerOnce not defined),
// or this is a repeated include to define a different flavor of
// yyFlexLexer, as discussed in the flex man page.
#define yyFlexLexerOnce
class yyFlexLexer : public FlexLexer {
public:
// arg_yyin and arg_yyout default to the cin and cout, but we
// only make that assignment when initializing in yylex().
yyFlexLexer( std::istream* arg_yyin = 0, std::ostream* arg_yyout = 0 );
virtual ~yyFlexLexer();
void yy_switch_to_buffer( struct yy_buffer_state* new_buffer );
struct yy_buffer_state* yy_create_buffer( std::istream* s, int size );
void yy_delete_buffer( struct yy_buffer_state* b );
void yyrestart( std::istream* s );
virtual int yylex();
virtual void switch_streams( std::istream* new_in, std::ostream* new_out );
protected:
virtual int LexerInput( char* buf, int max_size );
virtual void LexerOutput( const char* buf, int size );
virtual void LexerError( const char* msg );
void yyunput( int c, char* buf_ptr );
int yyinput();
void yy_load_buffer_state();
void yy_init_buffer( struct yy_buffer_state* b, std::istream* s );
void yy_flush_buffer( struct yy_buffer_state* b );
int yy_start_stack_ptr;
int yy_start_stack_depth;
int* yy_start_stack;
void yy_push_state( int new_state );
void yy_pop_state();
int yy_top_state();
yy_state_type yy_get_previous_state();
yy_state_type yy_try_NUL_trans( yy_state_type current_state );
int yy_get_next_buffer();
std::istream* yyin; // input source for default LexerInput
std::ostream* yyout; // output sink for default LexerOutput
struct yy_buffer_state* yy_current_buffer;
// yy_hold_char holds the character lost when yytext is formed.
char yy_hold_char;
// Number of characters read into yy_ch_buf.
int yy_n_chars;
// Points to current character in buffer.
char* yy_c_buf_p;
int yy_init; // whether we need to initialize
int yy_start; // start state number
// Flag which is used to allow yywrap()'s to do buffer switches
// instead of setting up a fresh yyin. A bit of a hack ...
int yy_did_buffer_switch_on_eof;
// The following are not always needed, but may be depending
// on use of certain flex features (like REJECT or yymore()).
yy_state_type yy_last_accepting_state;
char* yy_last_accepting_cpos;
yy_state_type* yy_state_buf;
yy_state_type* yy_state_ptr;
char* yy_full_match;
int* yy_full_state;
int yy_full_lp;
int yy_lp;
int yy_looking_for_trail_begin;
int yy_more_flag;
int yy_more_len;
int yy_more_offset;
int yy_prev_more_offset;
};
#endif

View File

@@ -0,0 +1,199 @@
/* -*-c++-*- OpenSceneGraph - Copyright (C) 2007 Cedric Pinson
*
* This application is open source and may be redistributed and/or modified
* freely and without restriction, both in commericial and non commericial
* applications, as long as this copyright notice is maintained.
*
* This application 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.
*
* Authors:
* Cedric Pinson <mornifle@plopbyte.net>
*
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#ifndef DATADIR
#define DATADIR "."
#endif // DATADIR
#include <osg/GraphicsContext>
#include "RenderSurface.h"
#include "CameraConfig.h"
#include <osgDB/FileNameUtils>
#include <osgDB/FileUtils>
#include <osgDB/Registry>
#include <osgDB/Input>
#include <osgDB/Output>
#include <osgDB/ReadFile>
#include <osgDB/WriteFile>
#include <osg/io_utils>
using namespace osgProducer;
static osg::GraphicsContext::Traits* buildTrait(RenderSurface& rs)
{
VisualChooser& vc = *rs.getVisualChooser();
osg::GraphicsContext::Traits* trait = new osg::GraphicsContext::Traits;
for (std::vector<VisualChooser::VisualAttribute>::iterator it = vc._visual_attributes.begin(); it != vc._visual_attributes.end(); it++) {
if (it->_attribute == VisualChooser::DoubleBuffer)
trait->doubleBuffer = true;
else if (it->_attribute == VisualChooser::DepthSize)
trait->depth = it->_parameter;
else if (it->_attribute == VisualChooser::RedSize)
trait->red = it->_parameter;
else if (it->_attribute == VisualChooser::BlueSize)
trait->blue = it->_parameter;
else if (it->_attribute == VisualChooser::GreenSize)
trait->green = it->_parameter;
else if (it->_attribute == VisualChooser::AlphaSize)
trait->alpha = it->_parameter;
else
std::cout << it->_attribute << " value " << it->_parameter << std::endl;
}
trait->windowName = rs.getWindowName();
trait->x = rs.getWindowOriginX();
trait->y = rs.getWindowOriginY();
trait->width = rs.getWindowWidth();
trait->height = rs.getWindowHeight();
trait->windowDecoration = rs.usesBorder();
trait->sharedContext = 0;
return trait;
}
static osgViewer::View* load(const std::string& file, const osgDB::ReaderWriter::Options* option)
{
osg::ref_ptr<CameraConfig> config = new CameraConfig;
std::cout << "Parse file " << file << std::endl;
config->parseFile(file);
RenderSurface* rs = 0;
Camera* cm = 0;
std::map<RenderSurface*,osg::ref_ptr<osg::GraphicsContext> > surfaces;
osgViewer::View* _view = new osgViewer::View;
for (int i = 0; i < (int)config->getNumberOfCameras(); i++) {
cm = config->getCamera(i);
rs = cm->getRenderSurface();
if (rs->getDrawableType() != osgProducer::RenderSurface::DrawableType_Window)
continue;
osg::ref_ptr<const osg::GraphicsContext::Traits> traits;
osg::ref_ptr<osg::GraphicsContext> gc;
if (surfaces.find(rs) != surfaces.end()) {
gc = surfaces[rs];
traits = gc->getTraits();
} else {
osg::GraphicsContext::Traits* newtraits;
newtraits = buildTrait(*rs);
newtraits->readDISPLAY();
if (newtraits->displayNum<0) newtraits->displayNum = 0;
gc = osg::GraphicsContext::createGraphicsContext(newtraits);
surfaces[rs] = gc.get();
traits = gc->getTraits();
}
std::cout << rs->getWindowName() << " " << rs->getWindowOriginX() << " " << rs->getWindowOriginY() << " " << rs->getWindowWidth() << " " << rs->getWindowHeight() << std::endl;
if (gc.valid())
{
osg::notify(osg::INFO)<<" GraphicsWindow has been created successfully."<<std::endl;
}
else
{
osg::notify(osg::NOTICE)<<" GraphicsWindow has not been created successfully."<<std::endl;
}
osg::ref_ptr<osg::Camera> camera = new osg::Camera;
camera->setGraphicsContext(gc.get());
int x,y;
unsigned int width,height;
cm->applyLens();
cm->getProjectionRectangle(x, y, width, height);
camera->setViewport(new osg::Viewport(x, y, width, height));
GLenum buffer = traits->doubleBuffer ? GL_BACK : GL_FRONT;
camera->setDrawBuffer(buffer);
camera->setReadBuffer(buffer);
osg::Matrix projection(cm->getProjectionMatrix());
osg::Matrix offset = osg::Matrix::identity();
cm->setViewByMatrix(offset);
osg::Matrix view = osg::Matrix(cm->getPositionAndAttitudeMatrix());
#if 1
std::cout << "Matrix Projection " << projection << std::endl;
std::cout << "Matrix Projection master " << _view->getCamera()->getProjectionMatrix() << std::endl;
// will work only if it's a post multyply in the producer camera
std::cout << "Matrix View " << view << std::endl;
#endif
// setup projection from parent
osg::Matrix offsetProjection = osg::Matrix::inverse(_view->getCamera()->getProjectionMatrix()) * projection;
std::cout << _view->getCamera()->getProjectionMatrix() * offsetProjection << std::endl;
// std::cout << "setViewByMatrix " << offset << std::endl;
_view->addSlave(camera.get(), offsetProjection, view);
// _view->getCamera()->setProjectionMatrix(projection); //osg::Matrix::identity());
// _view->addSlave(camera.get(), osg::Matrix::identity(), view);
}
#if 0
if (_view->getNumberOfCameras() == 1) {
_view->addSlave(camera.get());
}
#endif
std::cout << "done" << std::endl;
return _view;
}
//
// OSG interface to read/write from/to a file.
//
class ReaderWriterProducerCFG : public osgDB::ReaderWriter {
public:
virtual const char* className() { return "Producer cfg object reader"; }
virtual bool acceptsExtension(const std::string& extension) const {
return osgDB::equalCaseInsensitive(extension, "cfg");
}
virtual ReadResult readObject(const std::string& fileName, const Options* options = NULL) const {
std::string ext = osgDB::getLowerCaseFileExtension(fileName);
if (!acceptsExtension(ext)) return ReadResult::FILE_NOT_HANDLED;
osgDB::FilePathList* filePathList = 0;
if(options) {
filePathList = const_cast<osgDB::FilePathList*>(&(options->getDatabasePathList()));
filePathList->push_back(DATADIR);
}
std::string path = osgDB::findDataFile(fileName);
if(path.empty()) return ReadResult::FILE_NOT_FOUND;
ReadResult result;
osg::ref_ptr<osg::View> view = load(path, options);
if(! view.valid())
result = ReadResult("failed to load " + path);
else
result = ReadResult(view.get());
osgDB::writeObjectFile(*view,"test.view");
if(options && filePathList)
filePathList->pop_back();
return result;
}
};
REGISTER_OSGPLUGIN(cfg, ReaderWriterProducerCFG)

View File

@@ -0,0 +1,689 @@
/* -*-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.
*/
#include "RenderSurface.h"
using namespace std;
using namespace osgProducer;
const std::string RenderSurface::defaultWindowName = std::string(" *** Producer::RenderSurface *** ");
const unsigned int RenderSurface::UnknownDimension = 0xFFFFFFFF;
const unsigned int RenderSurface::UnknownAmount = 0xFFFFFFFF;
unsigned int RenderSurface::_numScreens = RenderSurface::UnknownAmount;
bool RenderSurface::_shareAllGLContexts = false;
//GLContext RenderSurface::_globallySharedGLContext = 0L;
void RenderSurface::shareAllGLContexts(bool flag)
{
_shareAllGLContexts = flag;
}
bool RenderSurface::allGLContextsAreShared()
{
return _shareAllGLContexts;
}
const std::string &RenderSurface::getDefaultWindowName()
{
return defaultWindowName;
}
RenderSurface::RenderSurface( void )
{
_drawableType = DrawableType_Window;
_hostname = "";
_displayNum = 0;
// _screen = 0;
_mayFullScreen = true;
_isFullScreen = true;
// This used to be #ifdefed for the X11 implementation
// but the code is pure C++ and should compile anywhere
// The _dislayNum variable is used by CGL as well.
#if 0
char *envptr = getenv( "DISPLAY" );
if( envptr != NULL && *envptr != 0 )
{
size_t p0 = 0;
size_t p1 = string(envptr).find(":", p0);
_hostname = string(envptr).substr(p0,p1);
p0 = p1+1;
p1 = string(envptr).find(".", p0);
if( p1 > 0 )
{
_displayNum = atoi((string(envptr).substr(p0,p1)).c_str());
p0 = p1+1;
p1 = string(envptr).length() - p0;
if( p1 > 0 )
_screen = atoi((string(envptr).substr(p0,p1)).c_str());
}
else if( p1 < string(envptr).length() )
{
p1 = string(envptr).length();
_displayNum = atoi((string(envptr).substr(p0,p1)).c_str());
_screen = 0;
}
}
#endif
_windowLeft = 0;
_windowRight = 1;
_windowBottom = 0;
_windowTop = 1;
_windowX = 0;
_windowY = 0;
_windowWidth = UnknownDimension;
_windowHeight = UnknownDimension;
_screenWidth = UnknownDimension;
_screenHeight = UnknownDimension;
_customFullScreenOriginX = 0;
_customFullScreenOriginY = 0;
_customFullScreenWidth = UnknownDimension;
_customFullScreenHeight = UnknownDimension;
_useCustomFullScreen = false;
#if 0
_dpy = NULL;
_win = 0;
_parent = 0;
_readDrawableRenderSurface = 0L;
_visualInfo = NULL;
_visualID = 0;
_currentCursor = 0;
_nullCursor = 0;
_defaultCursor = 0;
_windowName = defaultWindowName;
_realized = false;
_useConfigEventThread = true;
_threadReady = new OpenThreads::Barrier(2);
_overrideRedirectFlag = false;
char *override_envptr = getenv( "PRODUCER_OVERRIDE_REDIRECT" );
if( override_envptr != NULL && *override_envptr != 0 )
{
if (strcmp(override_envptr,"true")==0 || strcmp(override_envptr,"True")==0 || strcmp(override_envptr,"TRUE")==0)
{
_overrideRedirectFlag = true;
}
else
{
_overrideRedirectFlag = false;
}
}
#endif
_decorations = true;
_useCursorFlag = true;
_useDefaultEsc = true;
_checkOwnEvents = true;
_inputRectangle.set( -1.0, 1.0, -1.0, 1.0 );
_bindInputRectangleToWindowSize = false;
_rtt_mode = RenderToTextureMode_None;
//_rtt_mode = RenderToRGBTexture;
_rtt_target = Texture2D;
_rtt_options = RenderToTextureOptions_Default;
_rtt_mipmap = 0;
_rtt_face = PositiveX;
_rtt_dirty_mipmap = true;
_rtt_dirty_face = true;
#ifdef _WIN32_IMPLEMENTATION
_ownWindow = true;
_ownVisualChooser = true;
_ownVisualInfo = true;
_hinstance = NULL;
_glcontext = NULL;
_mx = 0;
_my = 0;
_mbutton = 0;
#endif
}
RenderSurface::~RenderSurface( void )
{
#if 0
cancel();
_fini();
while (isRunning())
{
//std::cout << "waiting for RenderSurface to cancel"<<std::endl;
OpenThreads::Thread::YieldCurrentThread();
}
delete _threadReady;
#endif
}
void RenderSurface::setDrawableType( RenderSurface::DrawableType drawableType )
{
if( _realized )
{
std::cerr << "Warning: RenderSurface::setDrawableType() "
"has no effect after RenderSurface has been realized\n";
return;
}
_drawableType = drawableType;
}
RenderSurface::DrawableType RenderSurface::getDrawableType()
{
return _drawableType;
}
void RenderSurface::setReadDrawable( osgProducer::RenderSurface *rs )
{
_readDrawableRenderSurface = rs;
#if 0
if( _realized )
makeCurrent();
#endif
}
#if 0
void RenderSurface::setParentWindow( Window parent )
{
_parent = parent;
}
Producer::Window RenderSurface::getParentWindow( void ) const
{
return _parent;
}
#endif
void RenderSurface::setWindowName( const std::string &name )
{
// _setWindowName( name );
_windowName = name;
}
const std::string &RenderSurface::getWindowName( void ) const
{
return _windowName;
}
void RenderSurface::setHostName( const std::string &name )
{
_hostname = name;
}
const std::string &RenderSurface::getHostName( void ) const
{
return _hostname;
}
#if 0
void RenderSurface::setDisplay( Display *dpy )
{
_dpy = dpy;
}
Producer::Display *RenderSurface::getDisplay()
{
#ifdef WIN32
return &_hdc;
#else
return _dpy;
#endif
}
const Producer::Display *RenderSurface::getDisplay() const
{
#ifdef WIN32
return &_hdc;
#else
return _dpy;
#endif
}
#endif
void RenderSurface::setDisplayNum( int num )
{
_displayNum = num;
}
int RenderSurface::getDisplayNum( void ) const
{
return _displayNum;
}
void RenderSurface::setScreenNum( int num )
{
_screen = num;
}
int RenderSurface::getScreenNum( void ) const
{
return _screen;
}
void RenderSurface::setWindowRectangle( int x, int y, unsigned int width, unsigned int height, bool resize)
{
if( _useCustomFullScreen )
{
_windowX = x + _customFullScreenOriginX;
_windowY = y + _customFullScreenOriginY;
}
else
{
_windowX = x;
_windowY = y;
}
_windowWidth = width;
_windowHeight = height;
#ifdef _OSX_AGL_IMPLEMENTATION
fullScreen(false); // STH: this may break other implementations, but it is necessary for OSX
#else
_isFullScreen = false;
#endif
#if 0
if( _realized && resize )
_resizeWindow();
else
#endif
if( _bindInputRectangleToWindowSize == true )
_inputRectangle.set( 0.0, _windowWidth, 0.0, _windowHeight );
}
void RenderSurface::getWindowRectangle( int &x, int &y, unsigned int &width, unsigned int &height ) const
{
if( _isFullScreen )
{
x = 0;
y = 0;
if( _useCustomFullScreen == true )
{
width = _customFullScreenWidth;
height = _customFullScreenHeight;
}
else
{
width = _screenWidth;
height = _screenHeight;
}
}
else
{
x = _windowX;
y = _windowY;
width = _windowWidth;
height = _windowHeight;
}
}
void RenderSurface::useDefaultFullScreenRectangle()
{
_useCustomFullScreen = false;
}
void RenderSurface::setCustomFullScreenRectangle( int x, int y, unsigned int width, unsigned int height )
{
_customFullScreenOriginX = x;
_customFullScreenOriginY = y;
_customFullScreenWidth = width;
_customFullScreenHeight = height;
_useCustomFullScreen = true;
_windowX += _customFullScreenOriginX;
_windowY += _customFullScreenOriginY;
}
int RenderSurface::getWindowOriginX() const
{
if( _isFullScreen )
{
if( _useCustomFullScreen == true )
return _customFullScreenOriginX;
else
return 0;
}
return _windowX;
}
int RenderSurface::getWindowOriginY() const
{
if( _isFullScreen )
{
if( _useCustomFullScreen == true )
return _customFullScreenOriginY;
else
return 0;
}
return _windowY;
}
unsigned int RenderSurface::getWindowWidth() const
{
if( _isFullScreen )
{
if( _useCustomFullScreen == true )
return _customFullScreenWidth;
else
return _screenWidth;
}
return _windowWidth;
}
unsigned int RenderSurface::getWindowHeight() const
{
if( _isFullScreen )
{
if( _useCustomFullScreen == true )
return _customFullScreenHeight;
else
return _screenHeight;
}
return _windowHeight;
}
void RenderSurface::setInputRectangle( const InputRectangle &inputRectangle )
{
_inputRectangle = inputRectangle;
}
const RenderSurface::InputRectangle &RenderSurface::getInputRectangle() const
{
return _inputRectangle;
}
void RenderSurface::bindInputRectangleToWindowSize( bool flag)
{
_bindInputRectangleToWindowSize = flag;
if( _bindInputRectangleToWindowSize == true )
_inputRectangle.set( 0.0, float(_windowWidth), 0.0, float(_windowHeight) );
else
_inputRectangle.set( -1.0, 1.0, -1.0, 1.0 );
}
void RenderSurface::useBorder( bool flag )
{
_decorations = flag;
#if 0
if( _realized )
_setBorder(_decorations);
#endif
}
bool RenderSurface::usesBorder()
{
return _decorations;
}
#if 0
void RenderSurface::useCursor( bool flag )
{
_useCursor(flag);
}
void RenderSurface::setCursor( Cursor cursor )
{
_setCursor(cursor);
}
void RenderSurface::setCursorToDefault()
{
_setCursorToDefault();
}
void RenderSurface::setWindow( const Window win )
{
if( _realized )
{
std::cerr << "RenderSurface::setWindow() - cannot set window after RenderSurface has been realized\n";
return;
}
_win = win;
#ifdef WIN32
_ownWindow = false;
#endif
}
Producer::Window RenderSurface::getWindow( void ) const
{
return _win;
}
GLContext RenderSurface::getGLContext( void) const
{
return _glcontext;
}
void RenderSurface::setGLContext( GLContext glContext )
{
if( _realized )
{
std::cerr << "RenderSurface::setGLContext() - Warning: Must be set before realize()." << std::endl;
return;
}
_glcontext = glContext;
}
bool RenderSurface::isRealized() const
{
return _realized;
}
void RenderSurface::setVisualInfo( VisualInfo *vi )
{
if( _realized )
{
std::cerr << "RenderSurface::setVisualInfo():Warning - has no effect after RenderSurface has been realized\n";
return;
}
_visualInfo = vi;
#ifdef WIN32
_ownVisualInfo = false;
#endif
}
VisualInfo *RenderSurface::getVisualInfo( void )
{
return _visualInfo;
}
const VisualInfo *RenderSurface::getVisualInfo( void ) const
{
return _visualInfo;
}
#endif
void RenderSurface::setVisualChooser( VisualChooser *vc )
{
if( _realized )
{
std::cerr << "RenderSurface::setVisualChooser():Warning - has no effect after RenderSurface has been realized\n";
return;
}
_visualChooser = vc;
#ifdef WIN32
_ownVisualChooser = false;
#endif
}
VisualChooser *RenderSurface::getVisualChooser( void )
{
return _visualChooser.get();
}
const VisualChooser *RenderSurface::getVisualChooser( void ) const
{
return _visualChooser.get();
}
#if 0
void RenderSurface::getScreenSize( unsigned int &width, unsigned int &height ) const
{
if( _realized )
{
if( _useCustomFullScreen == true )
{
width = _customFullScreenWidth;
height = _customFullScreenHeight;
}
else
{
width = _screenWidth;
height = _screenHeight;
}
}
else
{
_computeScreenSize(width, height);
}
}
#endif
#if 0
void RenderSurface::useConfigEventThread( bool flag )
{
if( _realized )
{
// This message is annoying. Cameras that share a render surface will call this after the
// render surface has been realized, which is valid.
//std::cerr << "RenderSurface::useConfigEventThread():Warning - has no effect after RenderSurface has been realized\n";
return;
}
_useConfigEventThread = flag;
}
unsigned int RenderSurface::getRefreshRate() const
{
if( !_realized ) return 0;
return _refreshRate;
}
void RenderSurface::addRealizeCallback( Callback *realizeCB )
{
if( _realized )
{
std::cerr << "RenderSurface::addRealizeCallback() : Warning. RenderSurface is already realized. ignored.\n";
return;
}
_realizeCallbacks.push_back( realizeCB );
}
bool RenderSurface::waitForRealize()
{
if( _realized ) return true;
while( _realized == false )
_realizeBlock->block();
return true;
}
void RenderSurface::positionPointer( int x, int y )
{
_positionPointer(x,y);
}
void RenderSurface::initThreads()
{
_initThreads();
}
#endif
RenderSurface::RenderToTextureMode RenderSurface::getRenderToTextureMode() const
{
return _rtt_mode;
}
void RenderSurface::setRenderToTextureMode(RenderToTextureMode mode)
{
_rtt_mode = mode;
}
RenderSurface::RenderToTextureTarget RenderSurface::getRenderToTextureTarget() const
{
return _rtt_target;
}
void RenderSurface::setRenderToTextureTarget(RenderToTextureTarget target)
{
_rtt_target = target;
}
RenderSurface::RenderToTextureOptions RenderSurface::getRenderToTextureOptions() const
{
return _rtt_options;
}
void RenderSurface::setRenderToTextureOptions(RenderToTextureOptions options)
{
_rtt_options = options;
}
int RenderSurface::getRenderToTextureMipMapLevel() const
{
return _rtt_mipmap;
}
void RenderSurface::setRenderToTextureMipMapLevel(int level)
{
_rtt_mipmap = level;
_rtt_dirty_mipmap = true;
}
RenderSurface::CubeMapFace RenderSurface::getRenderToTextureFace() const
{
return _rtt_face;
}
void RenderSurface::setRenderToTextureFace(CubeMapFace face)
{
_rtt_face = face;
_rtt_dirty_face = true;
}
const std::vector<int> &RenderSurface::getPBufferUserAttributes() const
{
return _user_pbattr;
}
std::vector<int> &RenderSurface::getPBufferUserAttributes()
{
return _user_pbattr;
}
void RenderSurface::useOverrideRedirect(bool flag)
{
_overrideRedirectFlag = flag;
}
bool RenderSurface::usesOverrideRedirect()
{
return _overrideRedirectFlag;
}

View File

@@ -0,0 +1,613 @@
/* -*-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.
*/
#ifndef OSGPRODUCER_RENDER_SURFACE
#define OSGPRODUCER_RENDER_SURFACE 1
#include <map>
#include <string>
#include <iostream>
#include <osg/Referenced>
#include <osg/ref_ptr>
#include "VisualChooser.h"
#ifdef _WIN32_IMPLEMENTATION
#include <vector>
#endif
namespace osgProducer {
/**
\class RenderSurface
\brief A RenderSurface provides a rendering surface for 3D graphics applications.
A RenderSurface creates a window in a windowing system for the purpose of 3D
rendering. The focus of a RenderSurface differs from a windowing system window
in that it is not a user input/output device, but rather a context and screen area
specifically designed for 3D applications. Consequently, a RenderSurface does not
provide or impose a requirement on the caller to structure the application around
the capturing or handling of events. Further, RenderSurface provides increased
control over the quality of pixel formats.
*/
class RenderSurface : public osg::Referenced
{
public :
static const unsigned int UnknownDimension;
static const unsigned int UnknownAmount;
static unsigned int _numScreens;
class Callback : public osg::Referenced
{
public:
Callback() {}
virtual void operator()( const RenderSurface & ) = 0;
protected:
virtual ~Callback() {}
};
struct InputRectangle
{
public:
InputRectangle(): _left(-1.0), _bottom(-1.0), _width(2.0), _height(2.0) {}
InputRectangle( float left, float right, float bottom, float top ):
_left(left), _bottom(bottom), _width(right-left), _height(top-bottom) {}
InputRectangle(const InputRectangle &ir)
{
_left = ir._left;
_bottom = ir._bottom;
_width = ir._width;
_height = ir._height;
}
virtual ~InputRectangle() {}
void set( float left, float right, float bottom, float top )
{
_left = left;
_bottom = bottom;
_width = right - left;
_height = top - bottom;
}
float left() const { return _left; }
float bottom() const { return _bottom; }
float width() const { return _width; }
float height() const { return _height; }
protected:
private:
float _left, _bottom, _width, _height;
};
enum DrawableType {
DrawableType_Window,
DrawableType_PBuffer
};
RenderSurface( void );
static unsigned int getNumberOfScreens(void);
void setDrawableType( DrawableType );
DrawableType getDrawableType();
void setReadDrawable( RenderSurface *);
RenderSurface* getReadDrawable() { return _readDrawableRenderSurface; }
void setInputRectangle( const InputRectangle &ir );
const InputRectangle &getInputRectangle() const;
void bindInputRectangleToWindowSize(bool);
/** Set the name of the Host the window is to be created on.
Ignored on Win32*/
void setHostName( const std::string & );
/**
* Get the name of the Host the window is to be created on.
* Ignored on Win32 */
const std::string& getHostName( void ) const;
/**
* Set the number of the display the render surface is to
* be created on. In XWindows, this is the number of the
* XServer. Ignored on Win32 */
void setDisplayNum( int );
/** Get the number of the display the render surface is to
* be created on. In XWindows, this is the number of the
* XServer. Ignored on Win32 */
int getDisplayNum( void ) const;
/** Set the number of the screen the render surface is to
* be created on. In XWindows, this is the number of the
* XServer. Ignored on Win32 */
void setScreenNum( int );
/** Get the number of the screen the render surface is to
* be created on. In XWindows, this is the number of the
* XServer. Ignored on Win32 */
int getScreenNum( void ) const;
/** Get the size of the screen in pixels the render surface
* is to be created on. */
void getScreenSize( unsigned int &width, unsigned int &height ) const;
/** Default window name */
static const std::string defaultWindowName;
static const std::string &getDefaultWindowName();
/** Set the Window system Window name of the Render Surface */
void setWindowName( const std::string & );
/** Get the Window system Window name of the Render Surface */
const std::string& getWindowName( void ) const;
/** Set the windowing system rectangle the RenderSurface will
* occupy on the screen. The parameters are given as integers
* in screen space. x and y determine the lower left hand corner
* of the RenderSurface. Width and height are given in screen
* coordinates */
void setWindowRectangle( int x, int y, unsigned int width, unsigned int height,
bool resize=true );
/** Get the windowing system rectangle the RenderSurface will
* occupy on the screen. The parameters are given as integers
* in screen space. x and y determine the lower left hand corner
* of the RenderSurface. Width and height are given in screen
* coordinates */
void getWindowRectangle( int &x, int &y, unsigned int &width, unsigned int &height ) const;
/** Get the X coordinate of the origin of the RenderSurface's window */
int getWindowOriginX() const;
/** Get the Y coordinate of the origin of the RenderSurface's window */
int getWindowOriginY() const;
/** Get the width of the RenderSurface in windowing system screen coordinates */
unsigned int getWindowWidth() const;
/** Get the height of the RenderSurface in windowing system screen coordinates */
unsigned int getWindowHeight() const;
#if 0
/** Explicitely set the Display variable before realization. (X11 only). */
void setDisplay( Display *dpy );
/** Get the Display. (X11 only). */
Display* getDisplay( void );
/** Get the const Display. (X11 only). */
const Display* getDisplay( void ) const;
/** Explicitely set the Windowing system window before realization. */
void setWindow( const Window win );
/** Returns the Windowing system handle to the window */
Window getWindow( void ) const;
void setGLContext( GLContext );
/** Returns the OpenGL context */
GLContext getGLContext( void ) const;
/** Set the Windowing system's parent window */
void setParentWindow( Window parent );
/** Get the Windowing system's parent window */
Window getParentWindow( void ) const;
#endif
void setVisualChooser( VisualChooser *vc );
VisualChooser *getVisualChooser( void );
const VisualChooser *getVisualChooser( void ) const;
#if 0
void setVisualInfo( VisualInfo *vi );
VisualInfo *getVisualInfo( void );
const VisualInfo *getVisualInfo( void ) const;
/** Returns true if the RenderSurface has been realized, false if not. */
bool isRealized( void ) const;
#endif
/** Request the use of a window border. If flag is false, no border will
* appear after realization. If flag is true, the windowing system window
* will be created in default state. */
void useBorder( bool flag );
bool usesBorder();
/** Use overrideRedirect (X11 only). This bypasses the window manager
* control over the Window. Ignored on Win32 and Mac CGL versions.
* This call will only have effect if called before realize(). Calling
* it subsequent to realize() will issue a warning. */
void useOverrideRedirect(bool);
bool usesOverrideRedirect();
/** Request whether the window should have a visible cursor. If true, the
* windowing system's default cursor will be assigned to the window. If false
* the window will not have a visible cursor. */
void useCursor( bool flag );
#if 0
/** Set the current window cursor. Producer provides no functionality to create
* cursors. It is the application's responsiblity to create a Cursor using the
* windowing system of choice. setCursor() will simply set a predefined cursor
* as the current Cursor */
void setCursor( Cursor );
#endif
void setCursorToDefault();
/** Specify whether the RenderSurface should use a separate thread for
* window configuration events. If flag is set to true, then the
* RenderSurface will spawn a new thread to manage events caused by
* resizing the window, mapping or destroying the window. */
void useConfigEventThread(bool flag);
/** shareAllGLContexts will share all OpenGL Contexts between render surfaces
* upon realize. This must be called before any call to renderSurface::realize().
*/
static void shareAllGLContexts(bool);
/** Returns true or false indicating the the state flag for sharing contexts
* between RenderSurfaces
*/
static bool allGLContextsAreShared();
#if 0
/** Realize the RenderSurface. When realized, all components of the RenderSurface
* not already configured are configured, a window and a graphics context are
* created and made current. If an already existing graphics context is passed
* through "sharedGLContext", then the graphics context created will share certain
* graphics constructs (such as display lists) with "sharedGLContext". */
bool realize( VisualChooser *vc=NULL, GLContext sharedGLContext=0 );
void addRealizeCallback( Callback *realizeCB );
void setRealizeCallback( Callback *realizeCB ) { addRealizeCallback(realizeCB); }
/** Swaps buffers if RenderSurface quality attribute is DoubleBuffered */
virtual void swapBuffers(void);
/** Makes the graphics context and RenderSurface current for rendering */
bool makeCurrent(void) const;
/** Where supported, sync() will synchronize with the vertical retrace signal of the
* graphics display device. \a divisor specifies the number of vertical retace signals
* to allow before returning. */
virtual void sync( int divisor=1 );
/** Where supported, getRefreshRate() will return the frequency in hz of the vertical
* retrace signal of the graphics display device. If getRefreshRate() returns 0, then
* the underlying support to get the graphics display device's vertical retrace signal
* is not present. */
unsigned int getRefreshRate() const;
/** Where supported, initThreads will initialize all graphics components for thread
* safety. InitThreads() should be called before any other calls to Xlib, or OpenGL
* are made, and should always be called when multi-threaded environments are intended. */
static void initThreads();
/**
* Puts the calling thread to sleep until the RenderSurface is realized. Returns true
* if for success and false for failure.
* */
bool waitForRealize();
/** fullScreen(flag). If flag is true, RenderSurface resizes its window to fill the
* entire screen and turns off the border. If false, the window is returned to a size
* previously specified. If previous state specified a border around the window, a
* the border is replaced
* */
/** positionPointer(x,y) places the pointer at window coordinates x, y.
*/
void positionPointer( int x, int y );
/** set/getUseDefaultEsc is deprecated */
void setUseDefaultEsc( bool flag ) {_useDefaultEsc = flag; }
bool getUseDefaultEsc() { return _useDefaultEsc; }
/** map and unmap the window */
void mapWindow();
void unmapWindow();
#endif
void fullScreen( bool flag );
/** setCustomFullScreenRencangle(x,y,width,height). Programmer may set a customized
* rectangle to be interpreted as "fullscreen" when fullscreen(true) is called. This
* allows configurations that have large virtual screens that span more than one monitor
* to define a "local" full screen for each monitor.
*/
void setCustomFullScreenRectangle( int x, int y, unsigned int width, unsigned int height );
/** useDefaultFullScreenRetangle(). Sets the application back to using the default
* screen size as fullscreen rather than the custom full screen rectangle
*/
void useDefaultFullScreenRectangle();
/** isFullScreen() returns true if the RenderSurface's window fills the entire screen
* and has no border. */
bool isFullScreen() const { return _isFullScreen; }
// TEMPORARY PBUFFER RENDER TO TEXTURE SUPPORT
// Temporary PBuffer support for Windows. Somebody got really
// confused and mixed up PBuffers with a renderable texture and
// caused this messy headache.
// These have no meaning in GLX world.....
enum BufferType {
FrontBuffer,
BackBuffer
};
enum RenderToTextureMode {
RenderToTextureMode_None,
RenderToRGBTexture,
RenderToRGBATexture
};
enum RenderToTextureTarget {
Texture1D,
Texture2D,
TextureCUBE
};
enum RenderToTextureOptions {
RenderToTextureOptions_Default = 0,
RequestSpaceForMipMaps = 1,
RequestLargestPBuffer = 2
};
enum CubeMapFace {
PositiveX = 0,
NegativeX = 1,
PositiveY = 2,
NegativeY = 3,
PositiveZ = 4,
NegativeZ = 5
};
/**
* Bind PBuffer content to the currently selected texture.
* This method affects PBuffer surfaces only. */
void bindPBufferToTexture(BufferType buffer = FrontBuffer) const;
/**
* Get the render-to-texture mode (PBuffer drawables only).
* This method has no effect if it is called after realize() */
RenderToTextureMode getRenderToTextureMode() const;
/**
* Set the render-to-texture mode (PBuffer drawables only). You
* can pass int values different from the constants defined by
* RenderToTextureMode, in which case they will be applied
* directly as parameters to the WGL_TEXTURE_FORMAT attribute.
* This method has no effect if it is called after realize(). */
void setRenderToTextureMode(RenderToTextureMode mode);
/**
* Get the render-to-texture target (PBuffer drawables only).
* This method has no effect if it is called after realize(). */
RenderToTextureTarget getRenderToTextureTarget() const;
/**
* Set the render-to-texture target (PBuffer drawables only). You
* can pass int values different from the constants defined by
* RenderToTextureTarget, in which case they will be applied
* directly as parameters to the WGL_TEXTURE_TARGET attribute.
* This method has no effect if it is called after realize(). */
void setRenderToTextureTarget(RenderToTextureTarget target);
/**
* Get the render-to-texture options (PBuffer drawables only).
* This method has no effect if it is called after realize(). */
RenderToTextureOptions getRenderToTextureOptions() const;
/**
* Set the render-to-texture options (PBuffer drawables only).
* You can pass any combination of the constants defined in
* enum RenderToTextureOptions.
* This method has no effect if it is called after realize(). */
void setRenderToTextureOptions(RenderToTextureOptions options);
/**
* Get which mipmap level on the target texture will be
* affected by rendering. */
int getRenderToTextureMipMapLevel() const;
/**
* Select which mipmap level on the target texture will be
* affected by rendering. This method can be called after the
* PBuffer has been realized. */
void setRenderToTextureMipMapLevel(int level);
/**
* Get which face on the target cube map texture will be
* affected by rendering. */
CubeMapFace getRenderToTextureFace() const;
/**
* Select which face on the target cube map texture will be
* affected by rendering. This method can be called after the
* PBuffer has been realized. */
void setRenderToTextureFace(CubeMapFace face);
// END TEMPORARY PBUFFER RENDER TO TEXTURE SUPPORT
/**
* Get the (const) vector of user-defined PBuffer attributes. */
const std::vector<int> &getPBufferUserAttributes() const;
/**
* Get the vector of user-defined PBuffer attributes. This
* vector will be used to initialize the PBuffer's attribute list.*/
std::vector<int> &getPBufferUserAttributes();
private :
unsigned int _refreshRate;
#ifdef _X11_IMPLEMENTATION
int (*__glxGetRefreshRateSGI)(unsigned int *);
int (*__glxGetVideoSyncSGI)(unsigned int *);
int (*__glxWaitVideoSyncSGI)(int,int,unsigned int *);
void testVSync( void );
#endif
#if 0
bool _checkEvents( Display *);
void _setBorder( bool flag );
void _setWindowName( const std::string & );
void _useCursor(bool);
void _setCursor(Cursor);
void _setCursorToDefault();
void _positionPointer(int x, int y);
void _resizeWindow();
#endif
bool _overrideRedirectFlag;
protected :
virtual ~RenderSurface( void );
// void _useOverrideRedirect( bool );
DrawableType _drawableType;
std::string _hostname;
int _displayNum;
float _windowLeft, _windowRight,
_windowBottom, _windowTop;
int _windowX, _windowY;
unsigned int _windowWidth, _windowHeight;
unsigned int _screenWidth, _screenHeight;
bool _useCustomFullScreen;
int _customFullScreenOriginX;
int _customFullScreenOriginY;
unsigned int _customFullScreenWidth;
unsigned int _customFullScreenHeight;
int _screen;
#if 0
Display * _dpy;
Window _win;
Window _parent;
#endif
RenderSurface *_readDrawableRenderSurface;
unsigned int _parentWindowHeight;
bool _realized;
osg::ref_ptr< VisualChooser > _visualChooser;
#if 0
VisualInfo * _visualInfo;
unsigned int _visualID;
GLContext _glcontext;
GLContext _sharedGLContext;
Cursor _currentCursor;
Cursor _nullCursor;
Cursor _defaultCursor;
#endif
bool _decorations;
bool _useCursorFlag;
std::string _windowName;
unsigned int _frameCount;
bool _mayFullScreen;
bool _isFullScreen;
bool _bindInputRectangleToWindowSize;
// Temporary "Pbuffer support for Win32
RenderToTextureMode _rtt_mode;
RenderToTextureTarget _rtt_target;
RenderToTextureOptions _rtt_options;
int _rtt_mipmap;
CubeMapFace _rtt_face;
bool _rtt_dirty_mipmap;
bool _rtt_dirty_face;
#ifdef _OSX_AGL_IMPLEMENTATION
GLContext _windowGlcontext;
GLContext _fullscreenGlcontext;
CFDictionaryRef _oldDisplayMode;
bool _captureDisplayOrWindow();
void _releaseDisplayOrWindow();
#endif
// user-defined PBuffer attributes
std::vector<int> _user_pbattr;
bool _useConfigEventThread;
bool _checkOwnEvents;
bool _useDefaultEsc;
InputRectangle _inputRectangle;
// void _computeScreenSize( unsigned int &width, unsigned int &height ) const;
#if 0
bool _createVisualInfo();
virtual bool _init();
virtual void _fini();
virtual void run();
static void _initThreads();
#endif
#ifdef _WIN32_IMPLEMENTATION
class Client : public Producer::Referenced
{
public:
Client(unsigned long mask);
unsigned int mask() { return _mask; }
EventQueue *getQueue() { return q.get(); }
void queue( ref_ptr<Event> ev );
private :
unsigned int _mask;
Producer::ref_ptr<EventQueue> q;
};
std::vector < Producer::ref_ptr<Client> >clients;
void dispatch( ref_ptr<Event> );
int _ownWindow;
int _ownVisualChooser;
int _ownVisualInfo;
HDC _hdc;
HINSTANCE _hinstance;
BOOL CreateGLWindow(char* title, int width, int height, int bits, bool fullscreenflag);
void KillGLWindow();
LONG WINAPI proc( Window, UINT, WPARAM, LPARAM );
static LONG WINAPI s_proc( Window, UINT, WPARAM, LPARAM );
static std::map <Window, RenderSurface *>registry;
/* mouse things */
int _mx, _my;
unsigned int _mbutton;
WNDPROC _oldWndProc;
public:
EventQueue * selectInput( unsigned int mask );
// if _parent is set, resize the window to
// fill the client area of the parent
void resizeToParent();
#endif
static bool _shareAllGLContexts;
};
}
#endif

View File

@@ -0,0 +1,744 @@
/* -*-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.
*/
#include <stdio.h>
#include <iostream>
#include "VisualChooser.h"
#include <osg/Referenced>
using namespace std;
using namespace osgProducer;
VisualChooser::VisualChooser( void )
{
// _visual_id = 0;
// _vinfo = 0L;
_strictAdherence = false;
}
VisualChooser::~VisualChooser(void)
{
clear();
}
#if 0
void VisualChooser::setVisual( VisualInfo *vinfo )
{
clear();
_vinfo = vinfo;
}
#endif
void VisualChooser::resetVisualInfo()
{
#ifdef _WIN32_IMPLEMENTATION
if (_vinfo != NULL) delete _vinfo;
#endif
#ifdef _OSX_AGL_IMPLEMENTATION
if(_vinfo != NULL) free(_vinfo);
#endif
// _vinfo = 0L;
}
void VisualChooser::addAttribute( AttributeName attribute )
{
resetVisualInfo();
_visual_attributes.push_back( VisualAttribute( attribute ) );
}
void VisualChooser::addAttribute( AttributeName attribute, int parameter )
{
resetVisualInfo();
_visual_attributes.push_back( VisualAttribute( attribute, parameter ) );
}
void VisualChooser::addExtendedAttribute( unsigned int attribute )
{
resetVisualInfo();
_visual_attributes.push_back( VisualAttribute( attribute ) );
}
void VisualChooser::addExtendedAttribute( unsigned int attribute, int parameter )
{
resetVisualInfo();
_visual_attributes.push_back( VisualAttribute( attribute, parameter ) );
}
void VisualChooser::setBufferSize( unsigned int size )
{
addAttribute( BufferSize, size );
}
void VisualChooser::setLevel( int level )
{
addAttribute( Level, level );
}
void VisualChooser::useRGBA()
{
addAttribute( RGBA );
}
void VisualChooser::useDoubleBuffer()
{
addAttribute( DoubleBuffer );
}
void VisualChooser::useStereo()
{
addAttribute( Stereo );
}
void VisualChooser::setAuxBuffers( unsigned int num )
{
addAttribute( AuxBuffers, num );
}
void VisualChooser::setRedSize( unsigned int size )
{
addAttribute( RedSize, size );
}
void VisualChooser::setGreenSize( unsigned int size )
{
addAttribute( GreenSize, size );
}
void VisualChooser::setBlueSize( unsigned int size )
{
addAttribute( BlueSize, size );
}
void VisualChooser::setAlphaSize( unsigned int size )
{
addAttribute( AlphaSize, size );
}
void VisualChooser::setDepthSize( unsigned int size )
{
addAttribute( DepthSize, size );
}
void VisualChooser::setStencilSize( unsigned int size )
{
addAttribute( StencilSize, size );
}
void VisualChooser::setAccumRedSize( unsigned int size )
{
addAttribute( AccumRedSize, size );
}
void VisualChooser::setAccumGreenSize( unsigned int size )
{
addAttribute( AccumGreenSize, size );
}
void VisualChooser::setAccumBlueSize( unsigned int size )
{
addAttribute( AccumBlueSize, size );
}
void VisualChooser::setAccumAlphaSize( unsigned int size )
{
addAttribute( AccumAlphaSize, size );
}
void VisualChooser::setSamples( unsigned int size )
{
addAttribute( Samples, size );
}
void VisualChooser::setSampleBuffers( unsigned int size )
{
addAttribute( SampleBuffers, size );
}
void VisualChooser::setVisualID( unsigned int id )
{
_visual_id = id;
}
void VisualChooser::setSimpleConfiguration( bool doublebuffer )
{
clear();
addAttribute( RGBA );
addAttribute( DepthSize, 16 );
if (doublebuffer)
addAttribute( DoubleBuffer );
}
void VisualChooser::clear()
{
_visual_attributes.clear();
resetVisualInfo();
// Always use UseGL
addAttribute( UseGL );
}
#ifdef _OSX_AGL_IMPLEMENTATION
#include <AGL/agl.h>
void VisualChooser::applyAttribute(const VisualAttribute &va, std::vector<int> &attribs)
{
if(va.isExtension())
{
attribs.push_back(static_cast<int>(va.attribute()));
}
else
{
switch(va.attribute())
{
case UseGL: attribs.push_back(AGL_COMPLIANT); break;
case BufferSize: attribs.push_back(AGL_BUFFER_SIZE); break;
case Level: attribs.push_back(AGL_LEVEL); break;
case RGBA: attribs.push_back(AGL_RGBA); break;
case DoubleBuffer: attribs.push_back(AGL_DOUBLEBUFFER); break;
case Stereo: attribs.push_back(AGL_STEREO); break;
case AuxBuffers: attribs.push_back(AGL_AUX_BUFFERS); break;
case RedSize: attribs.push_back(AGL_RED_SIZE); break;
case GreenSize: attribs.push_back(AGL_GREEN_SIZE); break;
case BlueSize: attribs.push_back(AGL_BLUE_SIZE); break;
case AlphaSize: attribs.push_back(AGL_ALPHA_SIZE); break;
case DepthSize: attribs.push_back(AGL_DEPTH_SIZE); break;
case StencilSize: attribs.push_back(AGL_STENCIL_SIZE); break;
case AccumRedSize: attribs.push_back(AGL_ACCUM_RED_SIZE); break;
case AccumGreenSize: attribs.push_back(AGL_ACCUM_GREEN_SIZE); break;
case AccumBlueSize: attribs.push_back(AGL_ACCUM_BLUE_SIZE); break;
case AccumAlphaSize: attribs.push_back(AGL_ACCUM_ALPHA_SIZE); break;
#if defined (AGL_SAMPLE_BUFFERS_ARB) && defined (AGL_SAMPLES_ARB)
case SampleBuffers: attribs.push_back(AGL_SAMPLE_BUFFERS_ARB); break;
case Samples: attribs.push_back(AGL_SAMPLES_ARB); break;
#endif
default: attribs.push_back((int)va.attribute()); break;
}
}
if (va.hasParameter())
{
attribs.push_back(va.parameter());
}
}
VisualInfo *VisualChooser::choose( Display *dpy, int screen, bool strict_adherence)
{
if(_vinfo != NULL)
{
// If VisualInfo exists, then we may be able to reuse it
GLint val;
if((*_vinfo) && (aglDescribePixelFormat(*_vinfo, AGL_NO_RECOVERY, &val))) return _vinfo;
}
else
{
// Use malloc() since new() causes a bus error
_vinfo = (VisualInfo*)malloc(sizeof(VisualInfo*));
}
// Set up basic attributes if needed
if( _visual_attributes.size() == 0 ) setSimpleConfiguration();
bool fullscreen = (screen == 1); // Whether to fullscreen or not
std::vector<int> va; // Visual attributes
va.push_back(AGL_NO_RECOVERY);
if(fullscreen) va.push_back(AGL_FULLSCREEN);
vector<VisualAttribute>::const_iterator p;
for( p = _visual_attributes.begin(); p != _visual_attributes.end(); p++ )
{
applyAttribute(*p, va);
}
va.push_back(AGL_NONE); // Must be last element
// Copy to GLint vector, since this is what the agl functions require
std::vector<GLint> glva;
std::vector<int>::iterator i;
for(i = va.begin(); i != va.end(); i++)
{
glva.push_back(*i);
}
if(fullscreen)
{
GDHandle gdhDisplay;
DMGetGDeviceByDisplayID((DisplayIDType)*dpy, &gdhDisplay, false);
*_vinfo = aglChoosePixelFormat(&gdhDisplay, 1, &(glva.front()));
}
else
{
*_vinfo = aglChoosePixelFormat(NULL, 0, &(glva.front()));
}
if(*_vinfo == NULL)
{
std::cerr<< "aglChoosePixelFormat failed: " << aglGetError() << std::endl;
for(i=va.begin(); i!=va.end(); ++i)
{
std::cerr << (*i) << ", ";
}
std::cerr << std::endl;
}
return _vinfo;
}
#endif
#ifdef _OSX_CGL_IMPLEMENTATION
void VisualChooser::applyAttribute(const VisualAttribute &va, std::vector<int> &attribs)
{
if(va.isExtension())
{
attribs.push_back(static_cast<int>(va.attribute()));
}
else
{
switch(va.attribute())
{
case UseGL: attribs.push_back(kCGLPFACompliant); break;
case BufferSize: attribs.push_back(kCGLPFAColorSize); break;
//case Level: attribs.push_back(GLX_LEVEL); break;
//case RGBA: attribs.push_back(GLX_RGBA); break;
case DoubleBuffer: attribs.push_back(kCGLPFADoubleBuffer); break;
case Stereo: attribs.push_back(kCGLPFAStereo); break;
case AuxBuffers: attribs.push_back(kCGLPFAAuxBuffers); break;
case RedSize: attribs.push_back(kCGLPFAColorSize); break;
case GreenSize: attribs.push_back(kCGLPFAColorSize); break;
case BlueSize: attribs.push_back(kCGLPFAColorSize); break;
case AlphaSize: attribs.push_back(kCGLPFAAlphaSize); break;
case DepthSize: attribs.push_back(kCGLPFADepthSize); break;
case StencilSize: attribs.push_back(kCGLPFAStencilSize); break;
case AccumRedSize: attribs.push_back(kCGLPFAAccumSize); break;
case AccumGreenSize: attribs.push_back(kCGLPFAAccumSize); break;
case AccumBlueSize: attribs.push_back(kCGLPFAAccumSize); break;
case AccumAlphaSize: attribs.push_back(kCGLPFAAccumSize); break;
case SampleBuffers: attribs.push_back(kCGLPFASampleBuffers); break;
case Samples: attribs.push_back(kCGLPFASamples); break;
default: attribs.push_back(va.attribute()); break;
}
}
if (va.hasParameter())
{
attribs.push_back(va.parameter());
}
}
VisualInfo *VisualChooser::choose( Display *dpy, int screen, bool strict_adherence)
{
if(_vinfo != NULL)
{
// If VisualInfo exists, then we may be able to reuse it
GLint val;
if(!CGLDescribePixelFormat(*_vinfo, 0L, kCGLPFANoRecovery, &val))
return _vinfo;
}
// Set up basic attributes if needed
if( _visual_attributes.size() == 0 ) setSimpleConfiguration();
u_int32_t display_id = CGDisplayIDToOpenGLDisplayMask(*dpy);
std::vector<int> va; // Visual attributes
va.push_back(kCGLPFADisplayMask);
va.push_back((CGLPixelFormatAttribute)display_id);
va.push_back(kCGLPFANoRecovery);
va.push_back( kCGLPFAAccelerated );
va.push_back( kCGLPFAFullScreen );
vector<VisualAttribute>::const_iterator p;
for( p = _visual_attributes.begin(); p != _visual_attributes.end(); p++ )
{
applyAttribute(*p, va);
}
va.push_back(CGLPixelFormatAttribute(0)); // Must be last element
long nvirt;
CGLPixelFormatAttribute *array = new CGLPixelFormatAttribute[va.size()];
memcpy(array, &(va.front()), va.size()*sizeof(CGLPixelFormatAttribute));
CGLError err = CGLChoosePixelFormat(array, _vinfo, &nvirt);
if(err)
{
std::cerr<< "CGLChoosePixelFormat failed: " << CGLErrorString(err) << std::endl;
std::vector<int>::iterator i;
for(i=va.begin(); i!=va.end(); ++i)
{
std::cerr << (*i) << ", ";
}
std::cerr << std::endl;
}
return _vinfo;
}
#endif
#ifdef _X11_IMPLEMENTATION
#include <GL/glx.h>
void VisualChooser::applyAttribute(const VisualAttribute &va, std::vector<int> &attribs)
{
if (va.isExtension())
{
attribs.push_back(static_cast<int>(va.attribute()));
}
else
{
switch (va.attribute())
{
case UseGL: attribs.push_back(GLX_USE_GL); break;
case BufferSize: attribs.push_back(GLX_BUFFER_SIZE); break;
case Level: attribs.push_back(GLX_LEVEL); break;
case RGBA: attribs.push_back(GLX_RGBA); break;
case DoubleBuffer: attribs.push_back(GLX_DOUBLEBUFFER); break;
case Stereo: attribs.push_back(GLX_STEREO); break;
case AuxBuffers: attribs.push_back(GLX_AUX_BUFFERS); break;
case RedSize: attribs.push_back(GLX_RED_SIZE); break;
case GreenSize: attribs.push_back(GLX_GREEN_SIZE); break;
case BlueSize: attribs.push_back(GLX_BLUE_SIZE); break;
case AlphaSize: attribs.push_back(GLX_ALPHA_SIZE); break;
case DepthSize: attribs.push_back(GLX_DEPTH_SIZE); break;
case StencilSize: attribs.push_back(GLX_STENCIL_SIZE); break;
case AccumRedSize: attribs.push_back(GLX_ACCUM_RED_SIZE); break;
case AccumGreenSize: attribs.push_back(GLX_ACCUM_GREEN_SIZE); break;
case AccumBlueSize: attribs.push_back(GLX_ACCUM_BLUE_SIZE); break;
case AccumAlphaSize: attribs.push_back(GLX_ACCUM_ALPHA_SIZE); break;
#if defined(GLX_SAMPLE_BUFFERS) && defined (GLX_SAMPLES)
case SampleBuffers: attribs.push_back(GLX_SAMPLE_BUFFERS); break;
case Samples: attribs.push_back(GLX_SAMPLES); break;
#endif
default: attribs.push_back(static_cast<int>(va.attribute())); break;
}
}
if (va.hasParameter())
{
attribs.push_back(va.parameter());
}
}
// we now ignore this...
VisualInfo *VisualChooser::choose( Display *dpy, int screen, bool strict_adherence)
{
// Visual info was previously forced.
if( _vinfo != NULL )
return _vinfo;
if( _visual_id != 0 )
{
VisualInfo temp;
long mask = VisualIDMask;
int n;
temp.visualid = _visual_id;
_vinfo = XGetVisualInfo( dpy, mask, &temp, &n );
if( _vinfo != NULL || _strictAdherence )
return _vinfo;
}
if( _visual_attributes.size() == 0 )
setSimpleConfiguration();
vector<VisualAttribute>::const_iterator p;
vector<int>va;
for( p = _visual_attributes.begin(); p != _visual_attributes.end(); p++ )
{
applyAttribute(*p, va);
}
va.push_back(0);
if( _strictAdherence )
{
_vinfo = glXChooseVisual( dpy, screen, &(va.front()) );
}
else
{
p = _visual_attributes.end() - 1;
while( _vinfo == NULL && va.size() > 0)
{
_vinfo = glXChooseVisual( dpy, screen, &(va.front()) );
if( _vinfo == NULL && va.size() > 0 )
{
// should we report an message that we're relaxing constraints here?
// std::cout << "Popping attributes"<<std::endl;
va.pop_back(); // Pop the NULL terminator
if( (*p).hasParameter() && va.size() >= 2 )
{
va.pop_back();
va.pop_back();
}
else
va.pop_back();
va.push_back(0); // Push a new NULL terminator
if( p == _visual_attributes.begin() )
break;
p --;
}
}
}
if( _vinfo != 0L )
_visual_id = _vinfo->visualid;
else
_visual_id = 0;
return _vinfo;
}
#endif
#ifdef _WIN32_IMPLEMENTATION
#include "WGLExtensions.h"
void VisualChooser::applyAttribute(const VisualAttribute &va, std::vector<int> &attribs)
{
if (va.attribute() == UseGL)
{
attribs.push_back(WGL_SUPPORT_OPENGL_ARB);
attribs.push_back(1);
attribs.push_back(WGL_ACCELERATION_ARB);
attribs.push_back(WGL_FULL_ACCELERATION_ARB);
return;
}
if (va.attribute() == DoubleBuffer)
{
attribs.push_back(WGL_DOUBLE_BUFFER_ARB);
attribs.push_back(1);
attribs.push_back(WGL_SWAP_METHOD_ARB);
attribs.push_back(WGL_SWAP_EXCHANGE_ARB);
return;
}
// please note that *all* WGL attributes must have a parameter!
// to keep compatibility we'll explicitely set a boolean
// parameter value where needed.
std::pair<int, int> attr = std::make_pair(static_cast<int>(va.attribute()), va.parameter());
switch (va.attribute())
{
case Level: return;
case BufferSize: attr.first = WGL_COLOR_BITS_ARB; break;
case RGBA: attr.first = WGL_PIXEL_TYPE_ARB; attr.second = WGL_TYPE_RGBA_ARB; break;
case Stereo: attr.first = WGL_STEREO_ARB; attr.second = 1; break;
case AuxBuffers: attr.first = WGL_AUX_BUFFERS_ARB; break;
case RedSize: attr.first = WGL_RED_BITS_ARB; break;
case GreenSize: attr.first = WGL_GREEN_BITS_ARB; break;
case BlueSize: attr.first = WGL_BLUE_BITS_ARB; break;
case AlphaSize: attr.first = WGL_ALPHA_BITS_ARB; break;
case DepthSize: attr.first = WGL_DEPTH_BITS_ARB; break;
case StencilSize: attr.first = WGL_STENCIL_BITS_ARB; break;
case AccumRedSize: attr.first = WGL_ACCUM_RED_BITS_ARB; break;
case AccumGreenSize: attr.first = WGL_ACCUM_GREEN_BITS_ARB; break;
case AccumBlueSize: attr.first = WGL_ACCUM_BLUE_BITS_ARB; break;
case AccumAlphaSize: attr.first = WGL_ACCUM_ALPHA_BITS_ARB; break;
#if defined(WGL_SAMPLE_BUFFERS_ARB) && defined (WGL_SAMPLES_ARB)
case SampleBuffers: attr.first = WGL_SAMPLE_BUFFERS_ARB; break;
case Samples: attr.first = WGL_SAMPLES_ARB; break;
#endif
default: ;
}
attribs.push_back(attr.first);
attribs.push_back(attr.second);
}
VisualInfo *VisualChooser::choose( Display *dpy, int screen, bool strict_adherence)
{
if (_vinfo)
return _vinfo;
if (_visual_attributes.empty())
setSimpleConfiguration();
int vid;
bool failed = false;
WGLExtensions *ext = WGLExtensions::instance();
if (ext && ext->isSupported(WGLExtensions::ARB_pixel_format))
{
do
{
std::vector<int> attribs;
for (std::vector<VisualAttribute>::const_iterator i=_visual_attributes.begin(); i!=_visual_attributes.end(); ++i)
applyAttribute(*i, attribs);
attribs.push_back(0);
unsigned int num_formats;
failed = !ext->wglChoosePixelFormat(*dpy, &attribs.front(), 0, 1, &vid, &num_formats) || num_formats == 0;
if (failed)
{
// **** DRIVER BUG? It seems that some ATI cards don't support
// **** the WGL_SWAP_METHOD_ARB attribute. Now we try to remove
// **** it from the attribute list and choose a pixel format again.
for (std::vector<int>::iterator k=attribs.begin(); k!=attribs.end(); ++k)
{
if (*k == WGL_SWAP_METHOD_ARB)
{
// attribute come in sequential attribute,paramter pairs
// as WGL specifications so we need to delete two entries
attribs.erase(k,k+2);
break;
}
}
failed = !ext->wglChoosePixelFormat(*dpy, &attribs.front(), 0, 1, &vid, &num_formats) || num_formats == 0;
}
if (failed)
{
if (strict_adherence || _visual_attributes.empty())
break;
std::cerr << "Producer::VisualChooser: the requested visual is not available, trying to relax attributes..." << std::endl;
_visual_attributes.pop_back();
}
} while (failed);
}
if (failed || !ext || !ext->isSupported(WGLExtensions::ARB_pixel_format))
{
std::cerr << "Producer::VisualChooser: unable to setup a valid visual with WGL extensions, switching to compatibility mode" << std::endl;
failed = false;
do
{
PIXELFORMATDESCRIPTOR pfd;
ZeroMemory(&pfd, sizeof(pfd));
pfd.nSize = sizeof(pfd);
pfd.nVersion = 1;
pfd.dwFlags = PFD_DRAW_TO_WINDOW;
pfd.iLayerType = PFD_MAIN_PLANE;
for (std::vector<VisualAttribute>::const_iterator i=_visual_attributes.begin(); i!=_visual_attributes.end(); ++i)
{
if (i->attribute() == UseGL) pfd.dwFlags |= PFD_SUPPORT_OPENGL;
if (i->attribute() == DoubleBuffer) pfd.dwFlags |= PFD_DOUBLEBUFFER | PFD_SWAP_EXCHANGE;
if (i->attribute() == Stereo) pfd.dwFlags |= PFD_STEREO;
if (i->attribute() == RGBA) pfd.iPixelType = PFD_TYPE_RGBA;
if (i->attribute() == BufferSize) pfd.cColorBits = i->parameter();
if (i->attribute() == RedSize) pfd.cRedBits = i->parameter();
if (i->attribute() == GreenSize) pfd.cGreenBits = i->parameter();
if (i->attribute() == BlueSize) pfd.cBlueBits = i->parameter();
if (i->attribute() == AlphaSize) pfd.cAlphaBits = i->parameter();
if (i->attribute() == AccumRedSize) pfd.cAccumRedBits = i->parameter();
if (i->attribute() == AccumGreenSize) pfd.cAccumGreenBits = i->parameter();
if (i->attribute() == AccumBlueSize) pfd.cAccumBlueBits = i->parameter();
if (i->attribute() == AccumAlphaSize) pfd.cAccumAlphaBits = i->parameter();
if (i->attribute() == DepthSize) pfd.cDepthBits = i->parameter();
if (i->attribute() == StencilSize) pfd.cStencilBits = i->parameter();
if (i->attribute() == AuxBuffers) pfd.cAuxBuffers = i->parameter();
}
pfd.cAccumBits = pfd.cAccumRedBits + pfd.cAccumGreenBits + pfd.cAccumBlueBits + pfd.cAccumAlphaBits;
vid = ChoosePixelFormat(*dpy, &pfd);
if ( vid != 0 )
{
// Is this additional check neccessary ?
// Did anyone encountered a situation where
// ChoosePixelFormat returned PXIELFORMAT worse than required ?
_visual_id = static_cast<unsigned int>(vid);
VisualInfo pfd;
DescribePixelFormat(*dpy, _visual_id, sizeof(PIXELFORMATDESCRIPTOR), &pfd);
bool boolOK = true;
for (std::vector<VisualAttribute>::const_iterator i=_visual_attributes.begin(); i!=_visual_attributes.end(); ++i)
{
if (i->attribute() == UseGL) boolOK &= !!( pfd.dwFlags & PFD_SUPPORT_OPENGL );
if (i->attribute() == DoubleBuffer) boolOK &= !!( pfd.dwFlags & ( PFD_DOUBLEBUFFER | PFD_SWAP_EXCHANGE ) );
if (i->attribute() == Stereo) boolOK &= !!( pfd.dwFlags & PFD_STEREO );
if (i->attribute() == RGBA) boolOK &= pfd.iPixelType == PFD_TYPE_RGBA;
if (i->attribute() == BufferSize) boolOK &= pfd.cColorBits >= i->parameter();
if (i->attribute() == RedSize) boolOK &= pfd.cRedBits >= i->parameter();
if (i->attribute() == GreenSize) boolOK &= pfd.cGreenBits >= i->parameter();
if (i->attribute() == BlueSize) boolOK &= pfd.cBlueBits >= i->parameter();
if (i->attribute() == AlphaSize) boolOK &= pfd.cAlphaBits >= i->parameter();
if (i->attribute() == AccumRedSize) boolOK &= pfd.cAccumRedBits >= i->parameter();
if (i->attribute() == AccumGreenSize) boolOK &= pfd.cAccumGreenBits >= i->parameter();
if (i->attribute() == AccumBlueSize) boolOK &= pfd.cAccumBlueBits >= i->parameter();
if (i->attribute() == AccumAlphaSize) boolOK &= pfd.cAccumAlphaBits >= i->parameter();
if (i->attribute() == DepthSize) boolOK &= pfd.cDepthBits >= i->parameter();
if (i->attribute() == StencilSize) boolOK &= pfd.cStencilBits >= i->parameter();
if (i->attribute() == AuxBuffers) boolOK &= pfd.cAuxBuffers >= i->parameter();
}
if ( !boolOK )
vid = 0;
}
if( vid == 0 )
{
failed = true;
if (strict_adherence || _visual_attributes.empty())
break;
std::cerr << "Producer::VisualChooser: the requested visual is not available, trying to relax attributes..." << std::endl;
_visual_attributes.pop_back();
}
} while (failed);
}
if (failed)
{
std::cerr << "Producer::VisualChooser: could not choose the pixel format" << std::endl;
return 0;
}
_visual_id = static_cast<unsigned int>(vid);
// we set _vinfo for compatibility, but it's going to be unused
// because the pixel format is usually chosen by visual ID rather
// than by descriptor.
_vinfo = new VisualInfo;
DescribePixelFormat(*dpy, _visual_id, sizeof(PIXELFORMATDESCRIPTOR), _vinfo);
return _vinfo;
}
#endif
#if 0
unsigned int VisualChooser::getVisualID() const
{
return 0;
}
bool VisualChooser::getStrictAdherence()
{
return _strictAdherence;
}
void VisualChooser::setStrictAdherence(bool strictAdherence)
{
_strictAdherence = strictAdherence;
}
#endif
bool VisualChooser::isDoubleBuffer() const
{
for (std::vector<VisualAttribute>::const_iterator i=_visual_attributes.begin(); i!=_visual_attributes.end(); ++i)
if (i->attribute() == DoubleBuffer)
return true;
return false;
}

View File

@@ -0,0 +1,207 @@
/* -*-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.
*/
#ifndef OSGPRODUCER_VISUAL_CHOOSER
#define OSGPRODUCER_VISUAL_CHOOSER 1
#include <vector>
#include <osg/Referenced>
namespace osgProducer {
class VisualChooser : public osg::Referenced
{
public :
VisualChooser( void );
enum AttributeName {
UseGL,
BufferSize,
Level,
RGBA,
DoubleBuffer,
Stereo,
AuxBuffers,
RedSize,
GreenSize,
BlueSize,
AlphaSize,
DepthSize,
StencilSize,
AccumRedSize,
AccumGreenSize,
AccumBlueSize,
AccumAlphaSize,
Samples,
SampleBuffers
};
#if 0
//-------------------------------------------------------------------------
// Explicitely set the visual info pointer. This will override the use of
// glXChooseVisual(). Useful for functions requiring a VisualChooser
// argument, but not a XVisualInfo.
void setVisual( VisualInfo *vinfo );
#endif
//-------------------------------------------------------------------------
// Chooses a minimal set of parameters
void setSimpleConfiguration(bool doublebuffer = true);
//-------------------------------------------------------------------------
// Clear the list of parameters
void clear() ;
//-------------------------------------------------------------------------
// Generic method for adding an attribute without a parameter
// (e.g DoubleBuffer )
void addAttribute( AttributeName attribute );
//-------------------------------------------------------------------------
// Generic method for adding an attribute with a parameter
// (e.g DepthSize, 1 )
void addAttribute( AttributeName attribute, int parameter );
//-------------------------------------------------------------------------
// Generic method for adding an attribute without a parameter
// (e.g DoubleBuffer )
void addExtendedAttribute( unsigned int attribute );
//-------------------------------------------------------------------------
// Generic method for adding an extended attribute with a parameter
// (e.g DepthSize, 1 )
void addExtendedAttribute( unsigned int attribute, int parameter );
//-------------------------------------------------------------------------
// The following method returns whether double buffering is being used
bool isDoubleBuffer() const;
//-------------------------------------------------------------------------
// The following methods set attributes explicitely
//
void setBufferSize( unsigned int size );
void setLevel( int level );
void useRGBA();
void useDoubleBuffer();
void useStereo();
void setAuxBuffers( unsigned int num );
void setRedSize( unsigned int size );
void setGreenSize( unsigned int size );
void setBlueSize( unsigned int size );
void setAlphaSize( unsigned int size );
void setDepthSize( unsigned int size );
void setStencilSize( unsigned int size );
void setAccumRedSize( unsigned int size );
void setAccumGreenSize( unsigned int size );
void setAccumBlueSize( unsigned int size );
void setAccumAlphaSize( unsigned int size );
void setSampleBuffers( unsigned int size );
void setSamples( unsigned int size );
void setVisualID( unsigned int id );
#if 0
//-------------------------------------------------------------------------
// Chooses visual based on previously selected attributes and parameters
// dpy = Conection to Xserver as returned by XOpenDisplay()
// screen = XServer screen (Could be DefaultScreen(dpy))
// strict_adherence = If true, return NULL visual info if the set of
// parameters is not matched verbatim. If set to
// false, choose() will attempt to find a visual that
// matches as much of the attribute list as possible
//
// Important Note : An attribute is removed from the end
// of the list before each retry, implying that the
// attribute list should be specified in priority order,
// most important attriutes first.
//
VisualInfo *choose( Display *dpy, int screen, bool strict_adherence=false);
unsigned int getVisualID() const;
bool getStrictAdherence();
void setStrictAdherence(bool);
#endif
protected:
~VisualChooser(void);
public :
struct VisualAttribute
{
unsigned int _attribute;
bool _has_parameter;
int _parameter;
bool _is_extension;
VisualAttribute( AttributeName attribute, int parameter ) :
_attribute(attribute),
_has_parameter(true),
_parameter(parameter),
_is_extension(false) {}
VisualAttribute( AttributeName attribute ) :
_attribute(attribute),
_has_parameter(false),
_parameter(0),
_is_extension(false) {}
VisualAttribute( unsigned int attribute, int parameter ) :
_attribute(attribute),
_has_parameter(true),
_parameter(parameter),
_is_extension(true) {}
VisualAttribute( unsigned int attribute ) :
_attribute(attribute),
_has_parameter(false),
_parameter(0),
_is_extension(true) {}
unsigned int attribute() const { return _attribute; }
bool hasParameter() const { return _has_parameter; }
int parameter() const { return _parameter; }
bool isExtension() const { return _is_extension; }
};
void applyAttribute(const VisualAttribute &va, std::vector<int> &attribs);
void resetVisualInfo();
std::vector <VisualAttribute> _visual_attributes;
// VisualInfo *_vinfo;
unsigned int _visual_id;
bool _strictAdherence;
};
}
#endif