More clean up for synch with 0.8.42

This commit is contained in:
Don BURNS
2001-09-19 21:19:47 +00:00
parent 2462c6273c
commit 7e81f6cfa6
292 changed files with 39673 additions and 0 deletions

98
src/osg/ClipPlane.cpp Normal file
View File

@@ -0,0 +1,98 @@
#include <osg/ClipPlane>
#include <osg/Notify>
using namespace osg;
ClipPlane::ClipPlane()
{
_clipPlane = new double[4];
_clipPlane[0] = 0.0;
_clipPlane[1] = 0.0;
_clipPlane[2] = 0.0;
_clipPlane[3] = 0.0;
_clipPlaneNum = 0;
}
ClipPlane::~ClipPlane()
{
delete _clipPlane;
}
void ClipPlane::setClipPlane(const Vec4& plane)
{
_clipPlane[0] = plane[0];
_clipPlane[1] = plane[1];
_clipPlane[2] = plane[2];
_clipPlane[3] = plane[3];
}
void ClipPlane::setClipPlane(const Plane& plane)
{
_clipPlane[0] = plane[0];
_clipPlane[1] = plane[1];
_clipPlane[2] = plane[2];
_clipPlane[3] = plane[3];
}
void ClipPlane::setClipPlane(const double* plane)
{
if (plane)
{
_clipPlane[0] = plane[0];
_clipPlane[1] = plane[1];
_clipPlane[2] = plane[2];
_clipPlane[3] = plane[3];
}
else
{
notify(WARN)<<"Warning: ClipPlane::setClipPlane() passed NULL plane array, ignoring operation."<<endl;
}
}
void ClipPlane::getClipPlane(Vec4& plane) const
{
plane[0] = (float)_clipPlane[0];
plane[1] = (float)_clipPlane[1];
plane[2] = (float)_clipPlane[2];
plane[3] = (float)_clipPlane[3];
}
void ClipPlane::getClipPlane(Plane& plane) const
{
plane[0] = _clipPlane[0];
plane[1] = _clipPlane[1];
plane[2] = _clipPlane[2];
plane[3] = _clipPlane[3];
}
void ClipPlane::getClipPlane(double* plane) const
{
if (plane)
{
plane[0] = _clipPlane[0];
plane[1] = _clipPlane[1];
plane[2] = _clipPlane[2];
plane[3] = _clipPlane[3];
}
else
{
notify(WARN)<<"Warning: ClipPlane::getClipPlane() passed NULL plane array, ignoring operation."<<endl;
}
}
void ClipPlane::setClipPlaneNum(const unsigned int num)
{
_clipPlaneNum = num;
}
const unsigned int ClipPlane::getClipPlaneNum() const
{
return _clipPlaneNum;
}
void ClipPlane::apply(State&) const
{
glClipPlane((GLenum)(GL_CLIP_PLANE0+_clipPlaneNum),_clipPlane);
}

23
src/osg/ColorMask.cpp Normal file
View File

@@ -0,0 +1,23 @@
#include <osg/ColorMask>
using namespace osg;
ColorMask::ColorMask()
{
// set up same defaults as glColorMask.
_red = true;
_green = true;
_blue = true;
_alpha = true;
}
ColorMask::~ColorMask()
{
}
void ColorMask::apply(State&) const
{
glColorMask((GLboolean)_red,(GLboolean)_green,(GLboolean)_blue,(GLboolean)_alpha);
}

25
src/osg/Depth.cpp Normal file
View File

@@ -0,0 +1,25 @@
#include <osg/Depth>
using namespace osg;
Depth::Depth()
{
_func = LESS;
_depthWriteMask = true;
_zNear = 0.0;
_zFar = 1.0;
}
Depth::~Depth()
{
}
void Depth::apply(State&) const
{
glDepthFunc((GLenum)_func);
glDepthMask((GLboolean)_depthWriteMask);
glDepthRange(_zNear,_zFar);
}

159
src/osg/Drawable.cpp Normal file
View File

@@ -0,0 +1,159 @@
#include <stdio.h>
#include <math.h>
#include <float.h>
#include <osg/Drawable>
#include <osg/State>
#include <osg/Notify>
using namespace osg;
Drawable::DeletedDisplayListCache Drawable::s_deletedDisplayListCache;
Drawable::Drawable()
{
_bbox_computed = false;
// Note, if your are defining a subclass from drawable which is
// dynamically updated then you should set both the following to
// to false in your constructor. This will prevent any display
// lists from being automatically created and safeguard the
// dynamic updating of data.
_supportsDisplayList = true;
_useDisplayList = true;
}
Drawable::~Drawable()
{
dirtyDisplayList();
}
void Drawable::compile(State& state)
{
if (!_useDisplayList) return;
// get the contextID (user defined ID of 0 upwards) for the
// current OpenGL context.
uint contextID = state.getContextID();
// fill in array if required.
while (_globjList.size()<=contextID) _globjList.push_back(0);
// get the globj for the current contextID.
uint& globj = _globjList[contextID];
// call the globj if already set otherwise comple and execute.
if( globj != 0 )
{
glDeleteLists( globj, 1 );
}
if (_dstate.valid())
{
_dstate->compile(state);
}
globj = glGenLists( 1 );
glNewList( globj, GL_COMPILE );
drawImmediateMode(state);
glEndList();
}
void Drawable::setSupportsDisplayList(const bool flag)
{
// if value unchanged simply return.
if (_supportsDisplayList==flag) return;
// if previously set to true then need to check about display lists.
if (_supportsDisplayList)
{
if (_useDisplayList)
{
// used to support display lists and display lists switched
// on so now delete them and turn useDisplayList off.
dirtyDisplayList();
_useDisplayList = false;
}
}
// set with new value.
_supportsDisplayList=flag;
}
void Drawable::setUseDisplayList(const bool flag)
{
// if value unchanged simply return.
if (_useDisplayList==flag) return;
// if was previously set to true, remove display list.
if (_useDisplayList)
{
dirtyDisplayList();
}
if (_supportsDisplayList)
{
// set with new value.
_useDisplayList = flag;
}
else // does not support display lists.
{
if (flag)
{
notify(WARN)<<"Warning: attempt to setUseDisplayList(true) on a drawable with does not support display lists."<<endl;
}
else
{
// set with new value.
_useDisplayList = false;
}
}
}
void Drawable::dirtyDisplayList()
{
for(uint i=0;i<_globjList.size();++i)
{
if (_globjList[i] != 0)
{
Drawable::deleteDisplayList(i,_globjList[i]);
_globjList[i] = 0;
}
}
}
void Drawable::deleteDisplayList(uint contextID,uint globj)
{
if (globj!=0)
{
// insert the globj into the cache for the appropriate context.
s_deletedDisplayListCache[contextID].insert(globj);
}
}
/** flush all the cached display list which need to be deleted
* in the OpenGL context related to contextID.*/
void Drawable::flushDeletedDisplayLists(uint contextID)
{
DeletedDisplayListCache::iterator citr = s_deletedDisplayListCache.find(contextID);
if (citr!=s_deletedDisplayListCache.end())
{
std::set<uint>& displayListSet = citr->second;
for(std::set<uint>::iterator gitr=displayListSet.begin();
gitr!=displayListSet.end();
++gitr)
{
glDeleteLists(*gitr,1);
}
s_deletedDisplayListCache.erase(citr);
}
}

19
src/osg/FrontFace.cpp Normal file
View File

@@ -0,0 +1,19 @@
#include "osg/GL"
#include "osg/FrontFace"
using namespace osg;
FrontFace::FrontFace()
{
_mode = COUNTER_CLOCKWISE;
}
FrontFace::~FrontFace()
{
}
void FrontFace::apply(State&) const
{
glFrontFace((GLenum)_mode);
}

74
src/osg/GLExtensions.cpp Normal file
View File

@@ -0,0 +1,74 @@
#ifdef _WIN32
#include <windows.h>
#elif !defined macintosh
#include <dlfcn.h>
#endif
#include "osg/GL"
#include "osg/GLExtensions"
#include "osg/Notify"
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <string>
#include <vector>
#include <set>
const bool osg::isGLExtensionSupported(const char *extension)
{
typedef std::set<std::string> ExtensionSet;
static ExtensionSet s_extensionSet;
static const char* s_extensions = NULL;
if (s_extensions==NULL)
{
// get the extension list from OpenGL.
s_extensions = (const char*)glGetString(GL_EXTENSIONS);
if (s_extensions==NULL) return false;
// insert the ' ' delimiated extensions words into the extensionSet.
const char *startOfWord = s_extensions;
const char *endOfWord;
while ((endOfWord = strchr(startOfWord,' '))!=NULL)
{
s_extensionSet.insert(std::string(startOfWord,endOfWord));
startOfWord = endOfWord+1;
}
if (*startOfWord!=0) s_extensionSet.insert(std::string(startOfWord));
osg::notify(INFO)<<"OpenGL extensions supported by installed OpenGL drivers are:"<<endl;
for(ExtensionSet::iterator itr=s_extensionSet.begin();
itr!=s_extensionSet.end();
++itr)
{
osg::notify(INFO)<<" "<<*itr<<endl;
}
}
// true if extension found in extensionSet.
bool result = s_extensionSet.find(extension)!=s_extensionSet.end();
if (result) osg::notify(INFO)<<"OpenGL extension '"<<extension<<"' is supported."<<endl;
else osg::notify(INFO)<<"OpenGL extension '"<<extension<<"' is not supported."<<endl;
return result;
}
void* osg::getGLExtensionFuncPtr(const char *funcName)
{
#if defined(_WIN32)
return wglGetProcAddress(funcName);
#elif defined(macintosh)
return NULL;
#else
static void *lib = dlopen("libGL.so", RTLD_LAZY);
if (lib)
return dlsym(lib, funcName);
else
return NULL;
#endif
}

64
src/osg/Impostor.cpp Normal file
View File

@@ -0,0 +1,64 @@
#include "osg/Impostor"
#include <algorithm>
using namespace osg;
Impostor::Impostor()
{
_impostorThreshold = -1.0f;
}
ImpostorSprite* Impostor::findBestImpostorSprite(const osg::Vec3& currLocalEyePoint)
{
float min_distance2 = FLT_MAX;
ImpostorSprite* impostorSprite = NULL;
for(ImpostorSpriteList::iterator itr=_impostorSpriteList.begin();
itr!=_impostorSpriteList.end();
++itr)
{
float distance2 = (currLocalEyePoint-(*itr)->getStoredLocalEyePoint()).length2();
if (distance2<min_distance2)
{
min_distance2 = distance2;
impostorSprite = itr->get();
}
}
return impostorSprite;
}
void Impostor::addImpostorSprite(ImpostorSprite* is)
{
if (is && is->getParent()!=this)
{
// add it to my impostor list first, so it remains referenced
// when its reference in the previous_owner is removed.
_impostorSpriteList.push_back(is);
if (is->getParent())
{
Impostor* previous_owner = is->getParent();
ImpostorSpriteList& isl = previous_owner->_impostorSpriteList;
// find and erase reference to is.
for(ImpostorSpriteList::iterator itr=isl.begin();
itr!=isl.end();
++itr)
{
if ((*itr)==is)
{
isl.erase(itr);
break;
}
}
}
is->setParent(this);
}
}
const bool Impostor::computeBound() const
{
return LOD::computeBound();
}

273
src/osg/ImpostorSprite.cpp Normal file
View File

@@ -0,0 +1,273 @@
#if defined(_MSC_VER)
#pragma warning( disable : 4786 )
#endif
#include <stdio.h>
#include <math.h>
#include <float.h>
#include <osg/ImpostorSprite>
#include <osg/Texture>
#include <osg/TexEnv>
#include <osg/AlphaFunc>
#include <osg/Notify>
using namespace osg;
ImpostorSprite::ImpostorSprite()
{
// don't use display list since we will be updating the geometry.
_useDisplayList = false;
_parent = NULL;
_ism = NULL;
_previous = NULL;
_next = NULL;
_texture = NULL;
_s = 0;
_t = 0;
}
ImpostorSprite::~ImpostorSprite()
{
if (_ism)
{
_ism->remove(this);
}
}
const float ImpostorSprite::calcPixelError(const Camera& camera,const int* viewport,const osg::Matrix* matrix) const
{
// find the maximum screen space pixel error between the control coords and the quad coners.
float max_error_sqrd = 0.0f;
for(int i=0;i<4;++i)
{
Vec3 projected_coord;
Vec3 projected_control;
if (matrix)
{
// project the coords of the quad into screen space.
camera.project(_coords[i]*(*matrix),viewport,projected_coord);
// project the controls coords into screen space.
camera.project(_controlcoords[i]*(*matrix),viewport,projected_control);
}
else
{
// project the coords of the quad into screen space.
camera.project(_coords[i],viewport,projected_coord);
// project the controls coords into screen space.
camera.project(_controlcoords[i],viewport,projected_control);
}
float dx = (projected_coord.x()-projected_control.x());
float dy = (projected_coord.y()-projected_control.y());
float error_sqrd = dx*dx+dy*dy;
if (error_sqrd > max_error_sqrd) max_error_sqrd = error_sqrd;
}
return sqrtf(max_error_sqrd);
}
void ImpostorSprite::drawImmediateMode(State&)
{
// when the tex env is set to REPLACE, and the
// texture is set up correctly the color has no effect.
glColor4f( 1.0f, 1.0f, 1.0f, 1.0f );
glBegin( GL_QUADS );
glTexCoord2fv( (GLfloat *)&_texcoords[0] );
glVertex3fv( (GLfloat *)&_coords[0] );
glTexCoord2fv( (GLfloat *)&_texcoords[1] );
glVertex3fv( (GLfloat *)&_coords[1] );
glTexCoord2fv( (GLfloat *)&_texcoords[2] );
glVertex3fv( (GLfloat *)&_coords[2] );
glTexCoord2fv( (GLfloat *)&_texcoords[3] );
glVertex3fv( (GLfloat *)&_coords[3] );
glEnd();
}
const bool ImpostorSprite::computeBound() const
{
_bbox.init();
_bbox.expandBy(_coords[0]);
_bbox.expandBy(_coords[1]);
_bbox.expandBy(_coords[2]);
_bbox.expandBy(_coords[3]);
_bbox_computed=true;
if (!_bbox.isValid())
{
cout << "******* ImpostorSprite::computeBound() problem"<<endl;
cout << "******* = "<<_coords[0]<<endl;
cout << "******* = "<<_coords[1]<<endl;
cout << "******* = "<<_coords[2]<<endl;
cout << "******* = "<<_coords[3]<<endl;
}
return true;
}
void ImpostorSprite::setTexture(Texture* tex,int s,int t)
{
_texture = tex;
_s = s;
_t = t;
}
///////////////////////////////////////////////////////////////////////////
// Helper class for managing the reuse of ImpostorSprite resources.
///////////////////////////////////////////////////////////////////////////
ImpostorSpriteManager::ImpostorSpriteManager()
{
_first = NULL;
_last = NULL;
}
ImpostorSpriteManager::~ImpostorSpriteManager()
{
while (_first)
{
ImpostorSprite* next = _first->_next;
_first->_ism = NULL;
_first->_previous = NULL;
_first->_next = NULL;
_first = next;
}
}
void ImpostorSpriteManager::push_back(ImpostorSprite* is)
{
if (is==NULL || is==_last) return;
// remove entry for exisiting position in linked list
// if it is already inserted.
if (is->_previous)
{
(is->_previous)->_next = is->_next;
}
if (is->_next)
{
(is->_next)->_previous = is->_previous;
}
if (_first==is) _first = is->_next;
if (empty())
{
_first = is;
_last = is;
is->_ism = this;
is->_previous = NULL;
is->_next = NULL;
}
else
{
// now add the element into the list.
ImpostorSprite* previous_last = _last;
previous_last->_next = is;
_last = is;
_last->_ism = this;
_last->_previous = previous_last;
_last->_next = NULL;
}
}
void ImpostorSpriteManager::remove(ImpostorSprite* is)
{
if (is==NULL) return;
// remove entry for exisiting position in linked list
// if it is already inserted.
if (is->_previous)
{
(is->_previous)->_next = is->_next;
}
if (is->_next)
{
(is->_next)->_previous = is->_previous;
}
if (_first==is) _first = is->_next;
if (_last==is) _last = is->_previous;
}
ImpostorSprite* ImpostorSpriteManager::createOrReuseImpostorSprite(int s,int t,int frameNumber)
{
if (!empty())
{
// search for a valid impostor to reuse.
ImpostorSprite* curr = _first;
while (curr)
{
if (curr->getLastFrameUsed()<=frameNumber &&
curr->s()==s &&
curr->t()==t)
{
push_back(curr);
return curr;
}
else
{
curr = curr->_next;
}
}
}
// creating new impostor sprite.
StateSet* stateset = new StateSet;
stateset->setMode(GL_CULL_FACE,osg::StateAttribute::OFF);
stateset->setMode(GL_LIGHTING,osg::StateAttribute::OFF);
stateset->setMode(GL_BLEND,osg::StateAttribute::ON);
Texture* texture = new Texture;
stateset->setAttributeAndModes(texture,StateAttribute::ON);
TexEnv* texenv = new TexEnv;
texenv->setMode(TexEnv::REPLACE);
stateset->setAttribute(texenv);
AlphaFunc* alphafunc = new osg::AlphaFunc;
alphafunc->setFunction( AlphaFunc::GREATER, 0.000f );
stateset->setAttributeAndModes( alphafunc, StateAttribute::ON );
// stateset->setMode( GL_ALPHA_TEST, StateAttribute::OFF );
ImpostorSprite* is = new ImpostorSprite;
is->setStateSet(stateset);
is->setTexture(texture,s,t);
push_back(is);
return is;
}

287
src/osg/LineSegment.cpp Normal file
View File

@@ -0,0 +1,287 @@
#include "osg/LineSegment"
using namespace osg;
const bool LineSegment::intersectAndClip(Vec3& s,Vec3& e,const BoundingBox& bb)
{
// compate s and e against the xMin to xMax range of bb.
if (s.x()<=e.x())
{
// trivial reject of segment wholely outside.
if (e.x()<bb.xMin()) return false;
if (s.x()>bb.xMax()) return false;
if (s.x()<bb.xMin())
{
// clip s to xMin.
s = s+(e-s)*(bb.xMin()-s.x())/(e.x()-s.x());
}
if (e.x()>bb.xMax())
{
// clip e to xMax.
e = s+(e-s)*(bb.xMax()-s.x())/(e.x()-s.x());
}
}
else
{
if (s.x()<bb.xMin()) return false;
if (e.x()>bb.xMax()) return false;
if (e.x()<bb.xMin())
{
// clip s to xMin.
e = s+(e-s)*(bb.xMin()-s.x())/(e.x()-s.x());
}
if (s.x()>bb.xMax())
{
// clip e to xMax.
s = s+(e-s)*(bb.xMax()-s.x())/(e.x()-s.x());
}
}
// compate s and e against the yMin to yMax range of bb.
if (s.y()<=e.y())
{
// trivial reject of segment wholely outside.
if (e.y()<bb.yMin()) return false;
if (s.y()>bb.yMax()) return false;
if (s.y()<bb.yMin())
{
// clip s to yMin.
s = s+(e-s)*(bb.yMin()-s.y())/(e.y()-s.y());
}
if (e.y()>bb.yMax())
{
// clip e to yMax.
e = s+(e-s)*(bb.yMax()-s.y())/(e.y()-s.y());
}
}
else
{
if (s.y()<bb.yMin()) return false;
if (e.y()>bb.yMax()) return false;
if (e.y()<bb.yMin())
{
// clip s to yMin.
e = s+(e-s)*(bb.yMin()-s.y())/(e.y()-s.y());
}
if (s.y()>bb.yMax())
{
// clip e to yMax.
s = s+(e-s)*(bb.yMax()-s.y())/(e.y()-s.y());
}
}
// compate s and e against the zMin to zMax range of bb.
if (s.z()<=e.z())
{
// trivial reject of segment wholely outside.
if (e.z()<bb.zMin()) return false;
if (s.z()>bb.zMax()) return false;
if (s.z()<bb.zMin())
{
// clip s to zMin.
s = s+(e-s)*(bb.zMin()-s.z())/(e.z()-s.z());
}
if (e.z()>bb.zMax())
{
// clip e to zMax.
e = s+(e-s)*(bb.zMax()-s.z())/(e.z()-s.z());
}
}
else
{
if (s.z()<bb.zMin()) return false;
if (e.z()>bb.zMax()) return false;
if (e.z()<bb.zMin())
{
// clip s to zMin.
e = s+(e-s)*(bb.zMin()-s.z())/(e.z()-s.z());
}
if (s.z()>bb.zMax())
{
// clip e to zMax.
s = s+(e-s)*(bb.zMax()-s.z())/(e.z()-s.z());
}
}
return true;
}
const bool LineSegment::intersect(const BoundingBox& bb) const
{
if (!bb.isValid()) return false;
Vec3 s=_s,e=_e;
return intersectAndClip(s,e,bb);
}
const bool LineSegment::intersect(const BoundingBox& bb,float& r1,float& r2) const
{
if (!bb.isValid()) return false;
Vec3 s=_s,e=_e;
bool result = intersectAndClip(s,e,bb);
if (result)
{
float len = (_e-_s).length();
if (len>0.0f)
{
float inv_len = 1.0f/len;
r1 = (s-_s).length()*inv_len;
r2 = (e-_e).length()*inv_len;
}
else
{
r1 = 0.0f;
r2 = 0.0f;
}
}
return result;
}
const bool LineSegment::intersect(const BoundingSphere& bs,float& r1,float& r2) const
{
Vec3 sm = _s-bs._center;
float c = sm.length2()-bs._radius*bs._radius;
Vec3 se = _e-_s;
float a = se.length2();
float b = sm*se*2.0f;
float d = b*b-4.0f*a*c;
if (d<0.0f) return false;
d = sqrtf(d);
float div = 1.0f/(2.0f*a);
r1 = (-b-d)*div;
r2 = (-b+d)*div;
if (r1<=0.0f && r2<=0.0f) return false;
if (r1>=1.0f && r2>=1.0f) return false;
return true;
}
const bool LineSegment::intersect(const BoundingSphere& bs) const
{
Vec3 sm = _s-bs._center;
float c = sm.length2()-bs._radius*bs._radius;
if (c<0.0f) return true;
Vec3 se = _e-_s;
float a = se.length2();
float b = (sm*se)*2.0f;
float d = b*b-4.0f*a*c;
if (d<0.0f) return false;
d = sqrtf(d);
float div = 1.0f/(2.0f*a);
float r1 = (-b-d)*div;
float r2 = (-b+d)*div;
if (r1<=0.0f && r2<=0.0f) return false;
if (r1>=1.0f && r2>=1.0f) return false;
return true;
}
const bool LineSegment::intersect(const Vec3& v1,const Vec3& v2,const Vec3& v3,float& r)
{
if (v1==v2 || v2==v3 || v1==v3) return false;
Vec3 vse = _e-_s;
Vec3 v12 = v2-v1;
Vec3 n12 = v12^vse;
float ds12 = (_s-v1)*n12;
float d312 = (v3-v1)*n12;
if (d312>=0.0f)
{
if (ds12<0.0f) return false;
if (ds12>d312) return false;
}
else // d312 < 0
{
if (ds12>0.0f) return false;
if (ds12<d312) return false;
}
Vec3 v23 = v3-v2;
Vec3 n23 = v23^vse;
float ds23 = (_s-v2)*n23;
float d123 = (v1-v2)*n23;
if (d123>=0.0f)
{
if (ds23<0.0f) return false;
if (ds23>d123) return false;
}
else // d123 < 0
{
if (ds23>0.0f) return false;
if (ds23<d123) return false;
}
Vec3 v31 = v1-v3;
Vec3 n31 = v31^vse;
float ds31 = (_s-v3)*n31;
float d231 = (v2-v3)*n31;
if (d231>=0.0f)
{
if (ds31<0.0f) return false;
if (ds31>d231) return false;
}
else // d231 < 0
{
if (ds31>0.0f) return false;
if (ds31<d231) return false;
}
float r3 = ds12/d312;
float r1 = ds23/d123;
float r2 = ds31/d231;
// float rt = r1+r2+r3;
Vec3 in = v1*r1+v2*r2+v3*r3;
float length = vse.length();
vse /= length;
float d = (in-_s)*vse;
if (d<0.0f) return false;
if (d>length) return false;
r = d/length;
return true;
}

0
src/osg/Makedepend Normal file
View File

68
src/osg/PolygonMode.cpp Normal file
View File

@@ -0,0 +1,68 @@
#include "osg/GL"
#include "osg/PolygonMode"
#include "osg/Notify"
using namespace osg;
PolygonMode::PolygonMode()
{
_frontAndBack = true;
_modeFront = FILL;
_modeBack = FILL;
}
PolygonMode::~PolygonMode()
{
}
void PolygonMode::setMode(const Face face,const Mode mode)
{
switch(face)
{
case(FRONT):
_frontAndBack = false;
_modeFront = mode;
break;
case(BACK):
_frontAndBack = false;
_modeBack = mode;
break;
case(FRONT_AND_BACK):
_frontAndBack = true;
_modeFront = mode;
_modeBack = mode;
break;
}
}
const PolygonMode::Mode PolygonMode::getMode(const Face face) const
{
switch(face)
{
case(FRONT):
return _modeFront;
break;
case(BACK):
return _modeBack;
break;
case(FRONT_AND_BACK):
return _modeFront;
}
notify(WARN)<<"Warning : invalid Face passed to PolygonMode::getMode(Face face)"<<endl;
return _modeFront;
}
void PolygonMode::apply(State&) const
{
if (_frontAndBack)
{
glPolygonMode(GL_FRONT_AND_BACK,(GLenum)_modeFront);
}
else
{
glPolygonMode(GL_FRONT,(GLenum)_modeFront);
glPolygonMode(GL_BACK,(GLenum)_modeBack);
}
}

488
src/osg/State.cpp Normal file
View File

@@ -0,0 +1,488 @@
#include <osg/State>
#include <osg/Notify>
#include <GL/glu.h>
using namespace osg;
State::State()
{
_contextID = 0;
_frameNumber = 0;
_fineGrainedErrorDetection = true;
}
State::~State()
{
}
void State::reset()
{
_modeMap.clear();
_attributeMap.clear();
_drawStateStack.clear();
}
void State::pushStateSet(const StateSet* dstate)
{
_drawStateStack.push_back(dstate);
if (dstate)
{
// iterator through all OpenGL modes in incomming StateSet
// for each GLMode entry push it to the back of the appropriate
// mode stack, taking into consideration current override status.
const StateSet::ModeList& ds_modeList = dstate->getModeList();
for(StateSet::ModeList::const_iterator mitr=ds_modeList.begin();
mitr!=ds_modeList.end();
++mitr)
{
// get the mode stack for incomming GLmode {mitr->first}.
ModeStack& ms = _modeMap[mitr->first];
if (ms.valueVec.empty())
{
// first pair so simply push incomming pair to back.
ms.valueVec.push_back(mitr->second);
}
else if (ms.valueVec.back() & StateAttribute::OVERRIDE) // check the existing override flag
{
// push existing back since override keeps the previoius value.
ms.valueVec.push_back(ms.valueVec.back());
}
else
{
// no override on so simply push incomming pair to back.
ms.valueVec.push_back(mitr->second);
}
ms.changed = true;
}
// iterator through all StateAttribute's in incomming StateSet
// for each Type entry push it to the back of the appropriate
// attribute stack, taking into consideration current override status.
const StateSet::AttributeList& ds_attributeList = dstate->getAttributeList();
for(StateSet::AttributeList::const_iterator aitr=ds_attributeList.begin();
aitr!=ds_attributeList.end();
++aitr)
{
// get the attribute stack for incomming type {aitr->first}.
AttributeStack& as = _attributeMap[aitr->first];
if (as.attributeVec.empty())
{
// first pair so simply push incomming pair to back.
as.attributeVec.push_back(
AttributePair(aitr->second.first.get(),aitr->second.second));
}
else if (as.attributeVec.back().second & StateAttribute::OVERRIDE) // check the existing override flag
{
// push existing back since override keeps the previoius value.
as.attributeVec.push_back(as.attributeVec.back());
}
else
{
// no override on so simply push incomming pair to back.
as.attributeVec.push_back(
AttributePair(aitr->second.first.get(),aitr->second.second));
}
as.changed = true;
}
}
}
void State::popStateSet()
{
if (_drawStateStack.empty()) return;
const StateSet* dstate = _drawStateStack.back().get();
if (dstate)
{
// iterator through all OpenGL modes in incomming StateSet
// for each GLMode entry pop_back of the appropriate
// mode stack.
const StateSet::ModeList& ds_modeList = dstate->getModeList();
for(StateSet::ModeList::const_iterator mitr=ds_modeList.begin();
mitr!=ds_modeList.end();
++mitr)
{
// get the mode stack for incomming GLmode {mitr->first}.
ModeStack& ms = _modeMap[mitr->first];
if (!ms.valueVec.empty())
{
ms.valueVec.pop_back();
}
ms.changed = true;
}
// iterator through all StateAttribute's in incomming StateSet
// for each Type entry pop_back of the appropriate
// attribute stack.
const StateSet::AttributeList& ds_attributeList = dstate->getAttributeList();
for(StateSet::AttributeList::const_iterator aitr=ds_attributeList.begin();
aitr!=ds_attributeList.end();
++aitr)
{
// get the attribute stack for incomming type {aitr->first}.
AttributeStack& as = _attributeMap[aitr->first];
if (!as.attributeVec.empty())
{
as.attributeVec.pop_back();
}
as.changed = true;
}
}
// remove the top draw state from the stack.
_drawStateStack.pop_back();
}
void State::apply(const StateSet* dstate)
{
// equivilant to:
//pushStateSet(dstate);
//apply();
//popStateSet();
if (dstate)
{
// first handle mode changes.
{
const StateSet::ModeList& ds_modeList = dstate->getModeList();
StateSet::ModeList::const_iterator ds_mitr = ds_modeList.begin();
ModeMap::iterator this_mitr=_modeMap.begin();
while (this_mitr!=_modeMap.end() && ds_mitr!=ds_modeList.end())
{
if (this_mitr->first<ds_mitr->first)
{
// note GLMode = this_mitr->first
ModeStack& ms = this_mitr->second;
if (ms.changed)
{
ms.changed = false;
if (!ms.valueVec.empty())
{
bool new_value = ms.valueVec.back() & StateAttribute::ON;
apply_mode(this_mitr->first,new_value,ms);
}
else
{
// assume default of disabled.
apply_mode(this_mitr->first,false,ms);
}
}
++this_mitr;
}
else if (ds_mitr->first<this_mitr->first)
{
// ds_mitr->first is a new mode, therefore
// need to insert a new mode entry for ds_mistr->first.
ModeStack& ms = _modeMap[ds_mitr->first];
bool new_value = ds_mitr->second & StateAttribute::ON;
apply_mode(ds_mitr->first,new_value,ms);
// will need to disable this mode on next apply so set it to changed.
ms.changed = true;
++ds_mitr;
}
else
{
// this_mitr & ds_mitr refer to the same mode, check the overide
// if any otherwise just apply the incomming mode.
ModeStack& ms = this_mitr->second;
if (!ms.valueVec.empty() && ms.valueVec.back() & StateAttribute::OVERRIDE)
{
// override is on, there just treat as a normal apply on modes.
if (ms.changed)
{
ms.changed = false;
bool new_value = ms.valueVec.back() & StateAttribute::ON;
apply_mode(this_mitr->first,new_value,ms);
}
}
else
{
// no override on or no previous entry, therefore consider incomming mode.
bool new_value = ds_mitr->second & StateAttribute::ON;
if (apply_mode(ds_mitr->first,new_value,ms))
{
ms.changed = true;
}
}
++this_mitr;
++ds_mitr;
}
}
// iterator over the remaining state modes to apply any previous changes.
for(;
this_mitr!=_modeMap.end();
++this_mitr)
{
// note GLMode = this_mitr->first
ModeStack& ms = this_mitr->second;
if (ms.changed)
{
ms.changed = false;
if (!ms.valueVec.empty())
{
bool new_value = ms.valueVec.back() & StateAttribute::ON;
apply_mode(this_mitr->first,new_value,ms);
}
else
{
// assume default of disabled.
apply_mode(this_mitr->first,false,ms);
}
}
}
// iterator over the remaining incomming modes to apply any new mode.
for(;
ds_mitr!=ds_modeList.end();
++ds_mitr)
{
ModeStack& ms = _modeMap[ds_mitr->first];
bool new_value = ds_mitr->second & StateAttribute::ON;
apply_mode(ds_mitr->first,new_value,ms);
// will need to disable this mode on next apply so set it to changed.
ms.changed = true;
}
}
// now handle attribute changes
{
const StateSet::AttributeList& ds_attributeList = dstate->getAttributeList();
StateSet::AttributeList::const_iterator ds_aitr=ds_attributeList.begin();
AttributeMap::iterator this_aitr=_attributeMap.begin();
while (this_aitr!=_attributeMap.end() && ds_aitr!=ds_attributeList.end())
{
if (this_aitr->first<ds_aitr->first)
{
// note attribute type = this_aitr->first
AttributeStack& as = this_aitr->second;
if (as.changed)
{
as.changed = false;
if (!as.attributeVec.empty())
{
const StateAttribute* new_attr = as.attributeVec.back().first;
apply_attribute(new_attr,as);
}
else
{
// this is really an error state, in theory we *should* have a
// global state attribute set for all types.
//notify(WARN)<<" No global StateAttribute set for type"<<(int)aitr->first<<endl;
}
}
++this_aitr;
}
else if (ds_aitr->first<this_aitr->first)
{
// ds_mitr->first is a new attribute, therefore
// need to insert a new attribute entry for ds_aistr->first.
AttributeStack& as = _attributeMap[ds_aitr->first];
const StateAttribute* new_attr = ds_aitr->second.first.get();
apply_attribute(new_attr,as);
// will need to disable this mode on next apply so set it to changed.
as.changed = true;
++ds_aitr;
}
else
{
// this_mitr & ds_mitr refer to the same mode, check the overide
// if any otherwise just apply the incomming mode.
AttributeStack& as = this_aitr->second;
if (!as.attributeVec.empty() && as.attributeVec.back().second)
{
// override is os, there just treat as a normal apply on modes.
if (as.changed)
{
as.changed = false;
const StateAttribute* new_attr = as.attributeVec.back().first;
apply_attribute(new_attr,as);
}
}
else
{
// no override on or no previous entry, therefore consider incomming mode.
const StateAttribute* new_attr = ds_aitr->second.first.get();
if (apply_attribute(new_attr,as))
{
as.changed = true;
}
}
++this_aitr;
++ds_aitr;
}
}
// iterator over the remaining state modes to apply any previous changes.
for(;
this_aitr!=_attributeMap.end();
++this_aitr)
{
// note attribute type = this_aitr->first
AttributeStack& as = this_aitr->second;
if (as.changed)
{
as.changed = false;
if (!as.attributeVec.empty())
{
const StateAttribute* new_attr = as.attributeVec.back().first;
apply_attribute(new_attr,as);
}
else
{
// this is really an error state, in theory we *should* have a
// global state attribute set for all types.
//notify(WARN)<<" No global StateAttribute set for type"<<(int)aitr->first<<endl;
}
}
}
// iterator over the remaining incomming modes to apply any new mode.
for(;
ds_aitr!=ds_attributeList.end();
++ds_aitr)
{
// ds_mitr->first is a new attribute, therefore
// need to insert a new attribute entry for ds_aistr->first.
AttributeStack& as = _attributeMap[ds_aitr->first];
const StateAttribute* new_attr = ds_aitr->second.first.get();
apply_attribute(new_attr,as);
// will need to update this attribute on next apply so set it to changed.
as.changed = true;
}
}
}
else
{
// no incomming stateset, so simply apply state.
apply();
}
}
void State::apply()
{
// go through all active OpenGL modes, enabling/disable where
// appropriate.
for(ModeMap::iterator mitr=_modeMap.begin();
mitr!=_modeMap.end();
++mitr)
{
// note GLMode = mitr->first
ModeStack& ms = mitr->second;
if (ms.changed)
{
ms.changed = false;
if (!ms.valueVec.empty())
{
bool new_value = ms.valueVec.back() & StateAttribute::ON;
apply_mode(mitr->first,new_value,ms);
}
else
{
// assume default of disabled.
apply_mode(mitr->first,false,ms);
}
}
}
// go through all active StateAttribute's, applying where appropriate.
for(AttributeMap::iterator aitr=_attributeMap.begin();
aitr!=_attributeMap.end();
++aitr)
{
AttributeStack& as = aitr->second;
if (as.changed)
{
as.changed = false;
if (!as.attributeVec.empty())
{
const StateAttribute* new_attr = as.attributeVec.back().first;
apply_attribute(new_attr,as);
}
else
{
// this is really an error state, in theory we *should* have a
// global state attribute set for all types.
//notify(WARN)<<" No global StateAttribute set for type"<<(int)aitr->first<<endl;
}
}
}
}
/** mode has been set externally, update state to reflect this setting.*/
void State::have_applied(const StateAttribute::GLMode mode,const StateAttribute::GLModeValue value)
{
ModeStack& ms = _modeMap[mode];
ms.last_applied_value = value & StateAttribute::ON;
// will need to disable this mode on next apply so set it to changed.
ms.changed = true;
}
/** attribute has been applied externally, update state to reflect this setting.*/
void State::have_applied(const StateAttribute* attribute)
{
if (attribute)
{
AttributeStack& as = _attributeMap[attribute->getType()];
as.last_applied_attribute = attribute;
// will need to update this attribute on next apply so set it to changed.
as.changed = true;
}
}

208
src/osg/StateSet.cpp Normal file
View File

@@ -0,0 +1,208 @@
#include <stdio.h>
#include <osg/StateSet>
#include <osg/State>
#include <osg/Notify>
#include <osg/AlphaFunc>
#include <osg/Material>
#include <osg/CullFace>
#include <osg/FrontFace>
#include <osg/PolygonMode>
#include <osg/Transparency>
using namespace osg;
StateSet::StateSet()
{
_renderingHint = DEFAULT_BIN;
setRendingBinToInherit();
}
StateSet::~StateSet()
{
// note, all attached state attributes will be automatically
// unreferenced by ref_ptr<> and therefore there is no need to
// delete the memory manually.
}
void StateSet::setGlobalDefaults()
{
_renderingHint = DEFAULT_BIN;
setRendingBinToInherit();
setMode(GL_LIGHTING,StateAttribute::OFF);
setMode(GL_FOG,StateAttribute::OFF);
setMode(GL_POINT_SMOOTH,StateAttribute::OFF);
setMode(GL_TEXTURE_2D,StateAttribute::OFF);
setMode(GL_TEXTURE_GEN_S,StateAttribute::OFF);
setMode(GL_TEXTURE_GEN_T,StateAttribute::OFF);
setMode(GL_TEXTURE_GEN_R,StateAttribute::OFF);
setMode(GL_TEXTURE_GEN_Q,StateAttribute::OFF);
setAttributeAndModes(new AlphaFunc,StateAttribute::OFF);
setAttributeAndModes(new CullFace,StateAttribute::ON);
setAttributeAndModes(new FrontFace,StateAttribute::ON);
Material *material = new Material;
material->setColorMode(Material::AMBIENT_AND_DIFFUSE);
setAttributeAndModes(material,StateAttribute::ON);
setAttributeAndModes(new PolygonMode,StateAttribute::OFF);
setAttributeAndModes(new Transparency,StateAttribute::OFF);
}
void StateSet::setAllToInherit()
{
_renderingHint = DEFAULT_BIN;
setRendingBinToInherit();
_modeList.clear();
_attributeList.clear();
}
void StateSet::setMode(const StateAttribute::GLMode mode, const StateAttribute::GLModeValue value)
{
if ((value&StateAttribute::INHERIT)) setModeToInherit(mode);
else _modeList[mode] = value;
}
void StateSet::setModeToInherit(const StateAttribute::GLMode mode)
{
ModeList::iterator itr = _modeList.find(mode);
if (itr!=_modeList.end())
{
_modeList.erase(itr);
}
}
const StateAttribute::GLModeValue StateSet::getMode(const StateAttribute::GLMode mode) const
{
ModeList::const_iterator itr = _modeList.find(mode);
if (itr!=_modeList.end())
{
return itr->second;
}
else
return StateAttribute::INHERIT;
}
void StateSet::setAttribute(StateAttribute *attribute, const StateAttribute::OverrideValue value)
{
if (attribute)
{
if ((value&StateAttribute::INHERIT)) setAttributeToInherit(attribute->getType());
else _attributeList[attribute->getType()] = RefAttributePair(attribute,value&StateAttribute::OVERRIDE);
}
}
void StateSet::setAttributeAndModes(StateAttribute *attribute, const StateAttribute::GLModeValue value)
{
if (attribute)
{
_attributeList[attribute->getType()] = RefAttributePair(attribute,value&StateAttribute::OVERRIDE);
attribute->setStateSetModes(*this,value);
}
}
void StateSet::setAttributeToInherit(const StateAttribute::Type type)
{
AttributeList::iterator itr = _attributeList.find(type);
if (itr!=_attributeList.end())
{
itr->second.first->setStateSetModes(*this,StateAttribute::INHERIT);
_attributeList.erase(itr);
}
}
const StateAttribute* StateSet::getAttribute(const StateAttribute::Type type) const
{
AttributeList::const_iterator itr = _attributeList.find(type);
if (itr!=_attributeList.end())
{
return itr->second.first.get();
}
else
return NULL;
}
const StateSet::RefAttributePair* StateSet::getAttributePair(const StateAttribute::Type type) const
{
AttributeList::const_iterator itr = _attributeList.find(type);
if (itr!=_attributeList.end())
{
return &(itr->second);
}
else
return NULL;
}
void StateSet::compile(State& state) const
{
for(AttributeList::const_iterator itr = _attributeList.begin();
itr!=_attributeList.end();
++itr)
{
itr->second.first->compile(state);
}
}
const StateSet::ModeVector StateSet::getModeVector() const
{
ModeVector vec;
for (ModeList::const_iterator itr = _modeList.begin();
itr!=_modeList.end();
++itr)
{
vec.push_back(*itr);
}
return vec;
}
const StateSet::AttributeVector StateSet::getAttributeVector() const
{
AttributeVector vec;
for (AttributeList::const_iterator itr = _attributeList.begin();
itr!=_attributeList.end();
++itr)
{
vec.push_back(itr->second.first.get());
}
return vec;
}
void StateSet::setRenderingHint(const int hint)
{
_renderingHint = hint;
// temporary hack to get new render bins working.
if (_renderingHint==TRANSPARENT_BIN)
{
_binMode = USE_RENDERBIN_DETAILS;
_binNum = 1;
_binName = "DepthSortedBin";
// _binName = "RenderBin";
}
}
void StateSet::setRenderBinDetails(const int binNum,const std::string& binName,const RenderBinMode mode)
{
_binMode = mode;
_binNum = binNum;
_binName = binName;
}
void StateSet::setRendingBinToInherit()
{
_binMode = INHERIT_RENDERBIN_DETAILS;
_binNum = 0;
_binName = "";
}

32
src/osg/Stencil.cpp Normal file
View File

@@ -0,0 +1,32 @@
#include <osg/Stencil>
using namespace osg;
Stencil::Stencil()
{
// set up same defaults as glStencilFunc.
_func = ALWAYS;
_funcRef = 0;
_funcMask = ~0;
// set up same defaults as glStencilOp.
_sfail = KEEP;
_zfail = KEEP;
_zpass = KEEP;
// set up same defaults as glStencilMask.
_writeMask = ~0;
}
Stencil::~Stencil()
{
}
void Stencil::apply(State&) const
{
glStencilFunc((GLenum)_func,_funcRef,_funcMask);
glStencilOp((GLenum)_sfail,(GLenum)_zfail,(GLenum)_zpass);
glStencilMask(_writeMask);
}

87
src/osg/Transform.cpp Normal file
View File

@@ -0,0 +1,87 @@
#include "osg/Transform"
using namespace osg;
Transform::Transform()
{
_matrix = new osg::Matrix();
_matrix->makeIdent();
}
Transform::Transform(const Matrix& mat )
{
(*_matrix) = mat;
}
Transform::~Transform()
{
}
void Transform::setMatrix(const Matrix& mat )
{
(*_matrix) = mat;
dirtyBound();
}
void Transform::preMult( const Matrix& mat )
{
_matrix->preMult( mat );
dirtyBound();
}
void Transform::preScale( const float sx, const float sy, const float sz )
{
_matrix->preScale( sx, sy, sz );
dirtyBound();
}
void Transform::preTranslate( const float tx, const float ty, const float tz )
{
_matrix->preTrans( tx, ty, tz );
dirtyBound();
}
void Transform::preRotate( const float deg, const float x, const float y, const float z )
{
_matrix->preRot( deg, x, y, z );
dirtyBound();
}
const bool Transform::computeBound() const
{
if (!Group::computeBound()) return false;
Vec3 xdash = _bsphere._center;
xdash.x() += _bsphere._radius;
xdash = xdash*(*_matrix);
Vec3 ydash = _bsphere._center;
ydash.y() += _bsphere._radius;
ydash = ydash*(*_matrix);
Vec3 zdash = _bsphere._center;
zdash.y() += _bsphere._radius;
zdash = zdash*(*_matrix);
_bsphere._center = _bsphere._center*(*_matrix);
xdash -= _bsphere._center;
float len_xdash = xdash.length();
ydash -= _bsphere._center;
float len_ydash = ydash.length();
zdash -= _bsphere._center;
float len_zdash = zdash.length();
_bsphere._radius = len_xdash;
if (_bsphere._radius<len_ydash) _bsphere._radius = len_ydash;
if (_bsphere._radius<len_zdash) _bsphere._radius = len_zdash;
return true;
}