Added support for controlling the frequency of checking for OpenGL errors

via:

        enum CheckForGLErrors
        {
            /** NEVER_CHECK_GL_ERRORS hints that OpenGL need not be checked for, this
                is the fastest option since checking for errors does incurr a small overhead.*/
            NEVER_CHECK_GL_ERRORS,
            /** ONCE_PER_FRAME means that OpenGl errors will be checked for once per
                frame, the overhead is still small, but at least OpenGL errors that are occurring
                will be caught, the reporting isn't fine grained enough for debugging purposes.*/
            ONCE_PER_FRAME,
            /** ONCE_PER_ATTRIBUTE means that OpenGL errors will be checked for after
                every attribute is applied, allow errors to be directly associated with
                particular operations which makes debugging much easier.*/
            ONCE_PER_ATTRIBUTE
        };

        /** Set whether and how often OpenGL errors should be checked for.*/
        void setCheckForGLErrors(CheckForGLErrors check) { _checkGLErrors = check; }

        /** Get whether and how often OpenGL errors should be checked for.*/
        CheckForGLErrors getCheckForGLErrors() const { return _checkGLErrors; }
This commit is contained in:
Robert Osfield 2005-04-29 20:56:20 +00:00
parent 0ff98ceb59
commit 7117ff4bd3
3 changed files with 39 additions and 16 deletions

View File

@ -708,8 +708,26 @@ class OSG_EXPORT State : public Referenced
* if true steps should be taken to complete rendering early.*/ * if true steps should be taken to complete rendering early.*/
bool getAbortRendering() const { return _abortRenderingPtr!=0?(*_abortRenderingPtr):false; } bool getAbortRendering() const { return _abortRenderingPtr!=0?(*_abortRenderingPtr):false; }
void setReportGLErrors(bool flag) { _reportGLErrors = flag; } enum CheckForGLErrors
bool getReportGLErrors() const { return _reportGLErrors; } {
/** NEVER_CHECK_GL_ERRORS hints that OpenGL need not be checked for, this
is the fastest option since checking for errors does incurr a small overhead.*/
NEVER_CHECK_GL_ERRORS,
/** ONCE_PER_FRAME means that OpenGl errors will be checked for once per
frame, the overhead is still small, but at least OpenGL errors that are occurring
will be caught, the reporting isn't fine grained enough for debugging purposes.*/
ONCE_PER_FRAME,
/** ONCE_PER_ATTRIBUTE means that OpenGL errors will be checked for after
every attribute is applied, allow errors to be directly associated with
particular operations which makes debugging much easier.*/
ONCE_PER_ATTRIBUTE
};
/** Set whether and how often OpenGL errors should be checked for.*/
void setCheckForGLErrors(CheckForGLErrors check) { _checkGLErrors = check; }
/** Get whether and how often OpenGL errors should be checked for.*/
CheckForGLErrors getCheckForGLErrors() const { return _checkGLErrors; }
bool checkGLErrors(const char* str) const; bool checkGLErrors(const char* str) const;
bool checkGLErrors(StateAttribute::GLMode mode) const; bool checkGLErrors(StateAttribute::GLMode mode) const;
@ -732,7 +750,7 @@ class OSG_EXPORT State : public Referenced
ref_ptr<DisplaySettings> _displaySettings; ref_ptr<DisplaySettings> _displaySettings;
bool* _abortRenderingPtr; bool* _abortRenderingPtr;
bool _reportGLErrors; CheckForGLErrors _checkGLErrors;
struct ModeStack struct ModeStack
{ {
@ -827,7 +845,7 @@ class OSG_EXPORT State : public Referenced
if (enabled) glEnable(mode); if (enabled) glEnable(mode);
else glDisable(mode); else glDisable(mode);
if (_reportGLErrors) checkGLErrors(mode); if (_checkGLErrors==ONCE_PER_ATTRIBUTE) checkGLErrors(mode);
return true; return true;
} }
@ -846,7 +864,7 @@ class OSG_EXPORT State : public Referenced
as.last_applied_attribute = attribute; as.last_applied_attribute = attribute;
attribute->apply(*this); attribute->apply(*this);
if (_reportGLErrors) checkGLErrors(attribute); if (_checkGLErrors==ONCE_PER_ATTRIBUTE) checkGLErrors(attribute);
return true; return true;
} }
@ -862,7 +880,7 @@ class OSG_EXPORT State : public Referenced
if (as.global_default_attribute.valid()) if (as.global_default_attribute.valid())
{ {
as.global_default_attribute->apply(*this); as.global_default_attribute->apply(*this);
if (_reportGLErrors) checkGLErrors(as.global_default_attribute.get()); if (_checkGLErrors==ONCE_PER_ATTRIBUTE) checkGLErrors(as.global_default_attribute.get());
} }
return true; return true;
} }

View File

@ -28,7 +28,7 @@ State::State()
_modelView = _identity; _modelView = _identity;
_abortRenderingPtr = false; _abortRenderingPtr = false;
_reportGLErrors = false; _checkGLErrors = ONCE_PER_FRAME;
_currentActiveTextureUnit=0; _currentActiveTextureUnit=0;
_currentClientActiveTextureUnit=0; _currentClientActiveTextureUnit=0;
@ -247,7 +247,7 @@ void State::captureCurrentState(StateSet& stateset) const
void State::apply(const StateSet* dstate) void State::apply(const StateSet* dstate)
{ {
if (_reportGLErrors) checkGLErrors("start of State::apply(StateSet*)"); if (_checkGLErrors==ONCE_PER_ATTRIBUTE) checkGLErrors("start of State::apply(StateSet*)");
// equivilant to: // equivilant to:
//pushStateSet(dstate); //pushStateSet(dstate);
@ -312,13 +312,13 @@ void State::apply(const StateSet* dstate)
apply(); apply();
} }
if (_reportGLErrors) checkGLErrors("end of State::apply(StateSet*)"); if (_checkGLErrors==ONCE_PER_ATTRIBUTE) checkGLErrors("end of State::apply(StateSet*)");
} }
void State::apply() void State::apply()
{ {
if (_reportGLErrors) checkGLErrors("start of State::apply()"); if (_checkGLErrors==ONCE_PER_ATTRIBUTE) checkGLErrors("start of State::apply()");
// go through all active OpenGL modes, enabling/disable where // go through all active OpenGL modes, enabling/disable where
// appropriate. // appropriate.
@ -355,7 +355,7 @@ void State::apply()
} }
} }
if (_reportGLErrors) checkGLErrors("end of State::apply()"); if (_checkGLErrors==ONCE_PER_ATTRIBUTE) checkGLErrors("end of State::apply()");
} }
void State::haveAppliedMode(StateAttribute::GLMode mode,StateAttribute::GLModeValue value) void State::haveAppliedMode(StateAttribute::GLMode mode,StateAttribute::GLModeValue value)

View File

@ -938,12 +938,17 @@ void SceneView::draw()
// re apply the defalt OGL state. // re apply the defalt OGL state.
_state->popAllStateSets(); _state->popAllStateSets();
GLenum errorNo = glGetError(); if (_state->getCheckForGLErrors()!=osg::State::NEVER_CHECK_GL_ERRORS)
if (errorNo!=GL_NO_ERROR)
{ {
osg::notify(WARN)<<"Warning: detected OpenGL error '"<<gluErrorString(errorNo)<<"'"<< std::endl; GLenum errorNo = glGetError();
// go into debug mode of OGL errors. if (errorNo!=GL_NO_ERROR)
_state->setReportGLErrors(true); {
osg::notify(WARN)<<"Warning: detected OpenGL error '"<<gluErrorString(errorNo)<<"'"<< std::endl;
// go into debug mode of OGL error in a fine grained way to help
// track down OpenGL errors.
_state->setCheckForGLErrors(osg::State::ONCE_PER_ATTRIBUTE);
}
} }
} }