Changed Texture so that is use lazy updating on texture paramters (Filter/Wrap)

mode by using a _texParamtersDirty flag in combination with an
applyTexParamters(State&) method which does the paramters setting in one
tidy bundle.  This new implementations replaces the CompileFlags submitted
yesterday.

Simplified NodeCallback by remove osg::NodeCallback::Requirements as they
are no longer needed.

Fixed comments in Drawable.

Put guards around cosf definations so that they are only used under Win32/Mac.

Fixed warning in CullVisitor.
This commit is contained in:
Robert Osfield
2002-03-14 16:01:21 +00:00
parent 3a4efd335a
commit e80496d5db
7 changed files with 139 additions and 164 deletions

View File

@@ -43,7 +43,7 @@ Texture::Texture()
_borderColor.set(0.0, 0.0, 0.0, 0.0);//OpenGL default
_compile_flags = COMPILE_ALL;
_texParamtersDirty = true;
}
@@ -121,11 +121,12 @@ void Texture::setWrap(const WrapParameter which, const WrapMode wrap)
{
switch( which )
{
case WRAP_S : _wrap_s = wrap; break;
case WRAP_T : _wrap_t = wrap; break;
case WRAP_R : _wrap_r = wrap; break;
case WRAP_S : _wrap_s = wrap; _texParamtersDirty = true; break;
case WRAP_T : _wrap_t = wrap; _texParamtersDirty = true; break;
case WRAP_R : _wrap_r = wrap; _texParamtersDirty = true; break;
default : notify(WARN)<<"Error: invalid 'which' passed Texture::setWrap("<<(unsigned int)which<<","<<(unsigned int)wrap<<")"<<std::endl; break;
}
}
@@ -145,8 +146,8 @@ void Texture::setFilter(const FilterParameter which, const FilterMode filter)
{
switch( which )
{
case MIN_FILTER : _min_filter = filter; break;
case MAG_FILTER : _mag_filter = filter; break;
case MIN_FILTER : _min_filter = filter; _texParamtersDirty = true; break;
case MAG_FILTER : _mag_filter = filter; _texParamtersDirty = true; break;
default : notify(WARN)<<"Error: invalid 'which' passed Texture::setFilter("<<(unsigned int)which<<","<<(unsigned int)filter<<")"<<std::endl; break;
}
}
@@ -193,14 +194,7 @@ void Texture::apply(State& state) const
if (_subloadMode == OFF)
{
glBindTexture( GL_TEXTURE_2D, handle );
if( !(_compile_flags & COMPILE_MIN_FILTER) )
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, _min_filter);
if( !(_compile_flags & COMPILE_MAG_FILTER) )
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, _mag_filter);
if( !(_compile_flags & COMPILE_WRAP_S) )
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, _wrap_s );
if( !(_compile_flags & COMPILE_WRAP_T) )
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, _wrap_t );
if (_texParamtersDirty) applyTexParameters(state);
}
else if (_image.valid() && _image->data())
{
@@ -210,6 +204,7 @@ void Texture::apply(State& state) const
(_subloadMode == IF_DIRTY && modifiedTag != _image->getModifiedTag()))
{
glBindTexture( GL_TEXTURE_2D, handle );
if (_texParamtersDirty) applyTexParameters(state);
glTexSubImage2D(GL_TEXTURE_2D, 0,
_subloadOffsX, _subloadOffsY,
_image->s(), _image->t(),
@@ -243,25 +238,8 @@ void Texture::compile(State& state) const
}
void Texture::applyImmediateMode(State& state) const
void Texture::applyTexParameters(State&) const
{
// if we don't have a valid image we can't create a texture!
if (!_image.valid() || !_image->data())
return;
// get the contextID (user defined ID of 0 upwards) for the
// current OpenGL context.
const uint contextID = state.getContextID();
// update the modified tag to show that it is upto date.
getModifiedTag(contextID) = _image->getModifiedTag();
if (_subloadMode == OFF)
_image->ensureDimensionsArePowerOfTwo();
glPixelStorei(GL_UNPACK_ALIGNMENT,_image->packing());
WrapMode ws = _wrap_s, wt = _wrap_t;
// GL_IBM_texture_mirrored_repeat, fall-back REPEAT
@@ -287,9 +265,9 @@ void Texture::applyImmediateMode(State& state) const
static bool s_borderClampSupported = isGLExtensionSupported("GL_ARB_texture_border_clamp");
if(!s_borderClampSupported)
{
if(ws == CLAMP_TO_BORDER_ARB)
if(ws == CLAMP_TO_BORDER)
ws = CLAMP;
if(wt == CLAMP_TO_BORDER_ARB)
if(wt == CLAMP_TO_BORDER)
wt = CLAMP;
}
@@ -328,6 +306,30 @@ void Texture::applyImmediateMode(State& state) const
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, _mag_filter);
}
_texParamtersDirty=false;
}
void Texture::applyImmediateMode(State& state) const
{
// if we don't have a valid image we can't create a texture!
if (!_image.valid() || !_image->data())
return;
// get the contextID (user defined ID of 0 upwards) for the
// current OpenGL context.
const uint contextID = state.getContextID();
// update the modified tag to show that it is upto date.
getModifiedTag(contextID) = _image->getModifiedTag();
if (_subloadMode == OFF)
_image->ensureDimensionsArePowerOfTwo();
glPixelStorei(GL_UNPACK_ALIGNMENT,_image->packing());
applyTexParameters(state);
static bool s_ARB_Compression = isGLExtensionSupported("GL_ARB_texture_compression");
static bool s_S3TC_Compression = isGLExtensionSupported("GL_EXT_texture_compression_s3tc");
@@ -549,10 +551,7 @@ void Texture::copyTexImage2D(State& state, int x, int y, int width, int height )
glGenTextures( 1, &handle );
glBindTexture( GL_TEXTURE_2D, handle );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, _wrap_s );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, _wrap_t );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, _min_filter );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, _mag_filter );
applyTexParameters(state);
glCopyTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, x, y, width, height, 0 );
@@ -579,10 +578,7 @@ void Texture::copyTexSubImage2D(State& state, int xoffset, int yoffset, int x, i
{
// we have a valid image
glBindTexture( GL_TEXTURE_2D, handle );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, _wrap_s );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, _wrap_t );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, _min_filter );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, _mag_filter );
applyTexParameters(state);
glCopyTexSubImage2D( GL_TEXTURE_2D, 0, xoffset,yoffset, x, y, width, height);
/* Redundant, delete later */

View File

@@ -174,6 +174,7 @@ bool Texture_matchWrapStr(const char* str,Texture::WrapMode& wrap)
{
if (strcmp(str,"CLAMP")==0) wrap = Texture::CLAMP;
else if (strcmp(str,"CLAMP_TO_EDGE")==0) wrap = Texture::CLAMP_TO_EDGE;
else if (strcmp(str,"CLAMP_TO_BORDER")==0) wrap = Texture::CLAMP_TO_BORDER;
else if (strcmp(str,"REPEAT")==0) wrap = Texture::REPEAT;
else if (strcmp(str,"MIRROR")==0) wrap = Texture::MIRROR;
else return false;
@@ -187,6 +188,7 @@ const char* Texture_getWrapStr(Texture::WrapMode wrap)
{
case(Texture::CLAMP): return "CLAMP";
case(Texture::CLAMP_TO_EDGE): return "CLAMP_TO_EDGE";
case(Texture::CLAMP_TO_BORDER): return "CLAMP_TO_BORDER";
case(Texture::REPEAT): return "REPEAT";
case(Texture::MIRROR): return "MIRROR";
}

View File

@@ -228,19 +228,19 @@ void TriangleViewFrustumIntersect::intersect_triangle(const osg::Vec3& vert1, co
v3 = vert3;
}
//construct positions of truncated clipping volume corners
/*
/*
osg::Vec3 UpLeft(_eye + _LeftUp * _current_near);
osg::Vec3 DownLeft(_eye + _LeftDown*_current_near);
osg::Vec3 UpRight(_eye + _RightUp*_current_near);
osg::Vec3 DownRight(_eye + _RightDown*_current_near);
*/
osg::Vec3 UpLeft(_eye + _LeftUp);
*/
osg::Vec3 UpLeft(_eye + _LeftUp);
osg::Vec3 DownLeft(_eye + _LeftDown);
osg::Vec3 UpRight(_eye + _RightUp);
osg::Vec3 DownRight(_eye + _RightDown);
//construct truncation "back plane"
osg::Plane back_plane(DownLeft, DownRight, UpRight);//CCW, to have normal where it should be
@@ -624,18 +624,17 @@ void CullVisitor::calcClippingDirections() const
osg::Vec3 t_up = _camera->getUpVector();
osg::Vec3 t_side = _camera->getSideVector();
double t_VFOV_2 = osg::DegreesToRadians(_camera->calc_fovy() * 0.5);//half of vertical FOV in radians
double pitch_up_angle = atan(_camera->top()/_camera->zNear());
double pitch_up_angle = atan(_camera->top()/_camera->zNear());
//we need to pitch up the cameras up vector for angle that is half fovy,
// osg::Vec3 pitched_up_up = t_up * osg::Matrix::rotate(t_VFOV_2, t_side.x(), t_side.y(), t_side.z());
osg::Vec3 pitched_up_up = t_up * osg::Matrix::rotate(pitch_up_angle, t_side.x(), t_side.y(), t_side.z());
osg::Vec3 pitched_up_up = t_up * osg::Matrix::rotate(pitch_up_angle, t_side.x(), t_side.y(), t_side.z());
//we need also pitched down cameras up vector
// osg::Vec3 pitched_down_up = t_up * osg::Matrix::rotate(-t_VFOV_2, t_side.x(), t_side.y(), t_side.z());
double pitch_down_angle = atan(_camera->bottom()/_camera->zNear());
// osg::Vec3 pitched_down_up = t_up * osg::Matrix::rotate(-t_VFOV_2, t_side.x(), t_side.y(), t_side.z());
osg::Vec3 pitched_down_up = t_up * osg::Matrix::rotate(pitch_down_angle, t_side.x(), t_side.y(), t_side.z());
double pitch_down_angle = atan(_camera->bottom()/_camera->zNear());
// osg::Vec3 pitched_down_up = t_up * osg::Matrix::rotate(-t_VFOV_2, t_side.x(), t_side.y(), t_side.z());
osg::Vec3 pitched_down_up = t_up * osg::Matrix::rotate(pitch_down_angle, t_side.x(), t_side.y(), t_side.z());
//we need either left and right or up and down planes of clipping volume (their normals better said)
@@ -721,33 +720,33 @@ void CullVisitor::updateCalculatedNearFar(osg::Drawable* pDrawable)
current_near = _calculated_zfar * current_near;
else current_near = 10000.0;//something must be put
double mult_factor;
if(_calculated_znear != FLT_MAX)//just in case this is the very first entry (i.e. the first bounding box contained eyePoint of camera
double mult_factor;
if(_calculated_znear != FLT_MAX)//just in case this is the very first entry (i.e. the first bounding box contained eyePoint of camera
mult_factor = _calculated_znear * current_near;//this is side of triangle ...
else if(_calculated_zfar != -FLT_MAX)
mult_factor = _calculated_zfar * current_near;
else mult_factor = 10000.0;//something must be put
double LUdistance = _LeftUp*lookVector;
LUdistance = mult_factor / LUdistance;
double LUdistance = _LeftUp*lookVector;
LUdistance = mult_factor / LUdistance;
double LDdistance = _LeftDown*lookVector;
LDdistance = mult_factor / LDdistance;
double LDdistance = _LeftDown*lookVector;
LDdistance = mult_factor / LDdistance;
double RUdistance = _RightUp*lookVector;
RUdistance = mult_factor / RUdistance;
double RUdistance = _RightUp*lookVector;
RUdistance = mult_factor / RUdistance;
double RDdistance = _RightDown*lookVector;
RDdistance = mult_factor / RDdistance;
double RDdistance = _RightDown*lookVector;
RDdistance = mult_factor / RDdistance;
//construct functor: needs clipping volume, matrix, and current near, while some members for speed are kept in CullVisitor since
//they need be calculated only once per frame
/*
/*
TriangleViewFrustumIntersect ti(_cvs->_clippingVolume,
_cvs->_matrix.get(), current_near, eyePoint,
_LeftUp,_LeftDown,_RightUp,_RightDown);
*/
TriangleViewFrustumIntersect ti(_cvs->_clippingVolume,
*/
TriangleViewFrustumIntersect ti(_cvs->_clippingVolume,
_cvs->_matrix.get(), eyePoint,
_LeftUp*LUdistance,_LeftDown*LDdistance,_RightUp*RUdistance,_RightDown*RDdistance);
@@ -886,7 +885,7 @@ void CullVisitor::apply(Geode& node)
if (!node.getCullingActive()) mode = 0;
else if (node.getNumChildrenWithCullingDisabled()==0 &&
isCulled(node.getBound(),mode)) return;
isCulled(node.getBound(),mode)) return;
// push the node's state.
StateSet* node_state = node.getStateSet();
@@ -898,19 +897,19 @@ void CullVisitor::apply(Geode& node)
Drawable* drawable = node.getDrawable(i);
const BoundingBox &bb =drawable->getBound();
if( drawable->getCullCallback() )
{
if( drawable->getCullCallback()->cull( this, drawable ) == true )
continue;
}
else
{
if( drawable->getCullCallback() )
{
if( drawable->getCullCallback()->cull( this, drawable ) == true )
continue;
}
else
{
if (isCulled(bb,mode)) continue;
}
}
//SandB change:
// updateCalculatedNearFar(bb);
// updateCalculatedNearFar(bb);
if(_detailedCulling)
{
updateCalculatedNearFar(drawable);
@@ -923,7 +922,7 @@ void CullVisitor::apply(Geode& node)
// push the geoset's state on the geostate stack.
StateSet* stateset = drawable->getStateSet();
bool isTransparent = stateset && stateset->getRenderingHint()==osg::StateSet::TRANSPARENT_BIN;
if (isTransparent)
{