More clean up for synch with 0.8.42
This commit is contained in:
98
src/osg/ClipPlane.cpp
Normal file
98
src/osg/ClipPlane.cpp
Normal 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
23
src/osg/ColorMask.cpp
Normal 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
25
src/osg/Depth.cpp
Normal 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
159
src/osg/Drawable.cpp
Normal 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
19
src/osg/FrontFace.cpp
Normal 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
74
src/osg/GLExtensions.cpp
Normal 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
64
src/osg/Impostor.cpp
Normal 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
273
src/osg/ImpostorSprite.cpp
Normal 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
287
src/osg/LineSegment.cpp
Normal 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
0
src/osg/Makedepend
Normal file
68
src/osg/PolygonMode.cpp
Normal file
68
src/osg/PolygonMode.cpp
Normal 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
488
src/osg/State.cpp
Normal 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
208
src/osg/StateSet.cpp
Normal 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
32
src/osg/Stencil.cpp
Normal 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
87
src/osg/Transform.cpp
Normal 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;
|
||||
}
|
||||
Reference in New Issue
Block a user