Archived issue #0027543

Samples - flickering when view is resized in MFC samples

CommunityOCCT:Samplesclosed12 public notes

Search issues

Description

When using the MFC samples, e.g. Viewer3d, there is a flickering when the view is resized.
When using Draw, there is no flickering.

The flickering looks as if the scene is first cleared in White and then drawn again in dark grey.

The Problem occurs in all OCC versions (I didn't try earlier than 6.7.1).

I don't know if this has to be so or if it is a problem of my graphics card.

OpenGL info:
  GLvendor    = 'ATI Technologies Inc.'
  GLdevice    = 'ATI FirePro V5800 (FireGL) Graphics Adapter'
  GLversion   = '4.5.13399 Compatibility Profile Context FireGL 15.200.1062.1004'
  GLSLversion = '4.40'

Steps to reproduce

Start Viewer3d MFC sample and resize the view / window.

Public activity

12 archived notes

Participants are labeled by their role within this record.

01Commenter 2
> When using the MFC samples, e.g. Viewer3d, there is a flickering when the view is resized.
> When using Draw, there is no flickering.
In this case, I suppose this should be considered as issue of samples (there is dedicated category), not Viewer3d (which does nothing more than redrawing view on resize).
02Commenter 3
Branch [archived branch] has been created by Commenter 2.

[revision removed]


Detailed log of new commits:

Author: Commenter 2
Date: Sat Jul 30 19:07:34 2016 +0300

    0027543: Samples - flickering when view is resized in MFC samples
    
    Define proper window class for OpenGL window within
    overridden method CView::PreCreateWindow().
03Commenter 2
Patch is ready for review.
04Commenter 4
Branch CR27543 reviewed without remarks, please test MFC samples.
05Commenter 1
Viewer3d
Flickering during resize of the shape does not observed.
But behavior of rectangle selection regarding others samples is very inarticulate and flickering is present.

06Commenter 2
Please provide more details - which MFC samples exactly suffers from issue / and is it regression or not.
As far as I can see, not all MFC samples have been updated to use AIS_RubberBand in scope of #0025338.
But I suppose this is dedicated issue anyway.

07Commenter 1
I speak about sample Viewer3d only. And it is not regression.
But from my point of view for this sample such behavior is unacceptableю
08Commenter 2
Viewer3d does not use OCC_BaseView::drawRectangle().
We should register dedicated bug for fixing rubber-band issue.
09Commenter 3
Branch [archived branch] has been deleted by Participant.

[revision removed]
10Author
I tested it with 7.1.0 beta. It works well.

Could you still explain a bit what was the reason for this behaviour and how you solved it as we experience similar effects in our Delphi application using OCC via CSharp-wrapper.
11Commenter 2
The patch specifies parameters for defining window class:
cs.lpszClass = ::AfxRegisterWndClass(CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS | CS_OWNDC, ::LoadCursor(NULL, IDC_ARROW), NULL, NULL);

Before the patch, window class with default parameters has been created implicitly by MFC, which are suboptimal for creating OpenGL context.

The flags CS_HREDRAW and CS_VREDRAW requires that window content should be redrawn during window resize (e.g. to generate WM_PAINT event on resize or something like that).

The flag CS_OWNDC specifies that window should have own unique device context - without this flag system can use the same context for several windows at ones, so that reducing memory usage. Since Vista+ the behavior has been changed (since window composition is performed independently for each window), but this flag still has some effect. So, for OpenGL it is still preferred to set this flag.

In C#/WinForms window class parameters can be specified by sub-classing UserControl and overriding method ::CreateParams():
  //! Define the WinForms control for using as OpenGL window for OCCT 3D Viewer.
  public partial class OpenGl_ViewControl : UserControl
  {
    public OpenGl_ViewControl()
    {
      if (DesignMode) return; // avoid calling native code within Designer

      SetStyle (ControlStyles.AllPaintingInWmPaint | ControlStyles.Opaque | ControlStyles.ResizeRedraw | ControlStyles.UserPaint, true);
      SetStyle (ControlStyles.OptimizedDoubleBuffer, false);
      InitializeComponent();
    }

    //! Request own device context.
    protected override CreateParams CreateParams
    {
      get
      {
        if (DesignMode) return base.CreateParams;

        const int VREDRAW = 0x00000001;
        const int HREDRAW = 0x00000002;
        const int OWNDC   = 0x00000020;
        CreateParams aParams = base.CreateParams;
        aParams.ClassStyle |= VREDRAW | HREDRAW | OWNDC;
        return aParams;
      }
    }


You can search web for discussions about WinAPI window class parameters for OpenGL windows for more details.

12Author
I'm unsure whether CS_HREDRAW and CS_VREDRAW are really necessary.

If CS_HREDRAW and CS_VREDRAW are defined, always a resize and a paint message are created when the window is resized and in the paint event handler you can redraw the view.

If they are not defined, only a resize message is created.
But if you call view.MustBeResized(); in the resize event handler, then it also redraws the view and then CS_HREDRAW and CS_VREDRAW wouldn't be necessary.

But maybe it is more safe to always create a paint message if the view is resized.


In Delphi, you can change the window class style by overriding the CreateParams method:

procedure TOCCPanel.CreateParams(var Params: TCreateParams);
begin
  inherited;

  Params.WindowClass.style := Params.WindowClass.style or CS_HREDRAW or CS_VREDRAW or CS_OWNDC;
end;

In our application, there was another reason for the flickering:
We used a panel for drawing the OpenGL view and there were other controls on top of this panel. When the window was resized all the controls were realigned which caused the background of the panel to be drawn. The drawing of the background is now avoided by:

procedure TOCCPanel.WMEraseBkgnd(var Message: TWMEraseBkgnd);
begin
  message.Result:=-1;
end;

Related records