Some Error In User Opengl Draw Object

Hello,

When I use the opengl primitives in opencascade based application, according to ViewerTest_OpenGlCommands.cxx file, Below is a snippet of the code.

He did draw what I wanted, but it was blocked by two triangle primitives , and I could see the following elements from the gap, such as the coordinate axis and the elements I drew, and an error occurred at the same time."FBO blitting has failed".

what should I do? Thanks a lot.

//Header
class UserDrawObj : public AIS_InteractiveObject
{
public:
UserDrawObj();

// Called by VUserDrawElement
void Render(const Handle(OpenGl_Workspace)& theWorkspace) const;
private:
NodeGroup* m_pRoot = nullptr
};

//Cpp
void UserDrawObj::Render(const Handle(OpenGl_Workspace)& theWorkspace) const
{
Handle(OpenGl_Context) aCtx = theWorkspace->GetGlContext();
aCtx->BindProgram(Handle(OpenGl_ShaderProgram)());
aCtx->ShaderManager()->PushState(Handle(OpenGl_ShaderProgram)());

if (nullptr != m_pRoot)
{
m_pRoot->display();
}
}

Error:
FBO blitting has failed [# 1280]
Please check your graphics driver settings or try updating driver.
MSAA settings should not be overridden by driver!

Kirill Gavrilov's picture

What does the following code?

m_pRoot->display();

mei zhen's picture

Hi Kirill, thank you very much for your reply.

The main work done in "Display" is the drawing work of Opengl. Previously, it was drawn directly in QOpenGLWidget, and the display can run normally. Now I want to migrate to OCC, and the above problem occurs.

Problems have been found, mainly
glPolygonMode(GL_FRONT, GL_LINE);
glPolygonMode(GL_BACK, GL_FILL);
When I comment this code, it can be displayed normally.

Will this affect the drawing of Occ?

Kirill Gavrilov's picture

OpenGL context has a global state shared between OCCT renderer and your application. When important state modifications remain hidden to one of the sides, bad things may happen. The main steps to avoid such issues:

  • Try using OCCT API to manage OpenGL state instead of direct calls to low-level OpenGL functions. For example, glPolygonMode() wrapper is defined by OpenGl_Context::SetPolygonMode(). Not all OpenGL features are wrapped in this way though (for instance, OpenGl_Context::SetPolygonMode() may only set the same polygon mode to both sides, GL_FRONT_AND_BACK).
  • Try to avoid using obsolete and deprecated functionality like glPolygonMode() altogether.
  • At the beginning of application-side rendering, make sure to set or reset OpenGL states critical to the following code.
  • At the end of application-side rendering, make sure to revert OpenGL state modifications that have been done using non-OCCT API.

So that in particular case, at the end of you custom OpenGL rendering code you may revert glPolygonMode() state to OCCT state:

void VUserDrawObj::Render(const Handle(OpenGl_Workspace)& theWorkspace) const
{
  const Handle(OpenGl_Context)& aCtx = theWorkspace->GetGlContext();
  // reset state to OCCT defaults;
  // could be useful if custom OpenGL code doesn't use OpenGl_Aspects
  theWorkspace->ResetAppliedAspect();

  // backup active state
  const Standard_Integer aPolygonModeBack = aCtx->PolygonMode();

  // custom state changes and drawing
  glPolygonMode (GL_FRONT, GL_LINE);
  glPolygonMode (GL_BACK, GL_FILL);
  ...

  // revert state
  glPolygonMode (GL_FRONT_AND_BACK, (GLenum )aPolygonModeBack);
}

Note that OpenGl_Context caches many OpenGL states to reduce overall amount of low-level OpenGL calls, which could reduce performance otherwise.