2012-05-16 2 views
23

많은 자식 OpenGL 창이있는 wxWidgets 응용 프로그램이 있습니다. 내 자신의 GL 캔버스 클래스, wx 하나를 사용하고 있습니다. 창은 OpenGL 컨텍스트를 공유합니다. wxwidgets가 실제로 여기 관련이 있다고 생각하지 않습니다.OpenGL 깜박임/손상된 윈도우 크기 조정 및 DWM 활성화

OpenGL 윈도우는 탭 컨트롤 내에 포함 된 서로의 형제 인 윈도우의 하위입니다. MDI 스타일 인터페이스의 일종이지만 MDI 윈도우가 아닙니다. 각각 개별적으로 크기를 조정할 수 있습니다. Aero가 활성화되어 있고 DWM이 활성화되어 있지 않으면 모두 작동합니다.

임의의 창 (심지어 OpenGL도 아닌)의 크기를 조정하면 OpenGL 이외의 지점에서 화면에 어떤 쓰레기가 있었는지에 관계없이 모든 OpenGL 창이 때때로 깜박입니다. 이것은 Aero가 활성화 된 경우에만 발생합니다.

저는 DWM이 실제로 드로잉 표면의 백킹 스토어에있는 OpenGL 내용을 가지고 있지 않고 창을 제대로 그리지 않았 음을 확신합니다.

나는이 문제를 해결하기 위해 많은 노력을 기울였습니다. 해결책이 있지만 아주 좋지는 않습니다. glReadPixels을 사용하여 프레임 버퍼를 DIB로 읽은 다음 내 onPaint 루틴의 DC로 블리치하는 작업이 포함됩니다. 이 해결 방법은 DWM이 활성화되어있는 경우에만 활성화되지만 성능을 약간 손상시킬 수 있으므로이 작업을 수행하지 않아도됩니다 (그러나 가능한 시스템에서는 그리 좋지 않습니다 - 장면은 비교적 단순한 3 차원 그래프입니다). 또한 GDI와 OpenGL을 혼합하는 것은 권장되지 않지만 놀랍게도이 방법이 효과적입니다. 나는 지금 그걸로 살 수 있지만 오히려 가질 필요가 없다. 어쨌든 자식 윈도우의 스크린 샷을 찍고 싶다면 WM_PRINT에서이 작업을 수행해야합니다. 그 방법은 보이지 않습니다.

누가 더 좋은 해결책을 알고 있습니까? 누가 물어 전에

나는 확실히 다음을 수행하십시오

  • 창 클래스는 CS_OWNDC
  • WM_ERASEBACKGROUND는 아무것도하지 않고 TRUE를 반환 있습니다.
  • 이중 버퍼링을 사용할 수 있습니다.
  • Windows에는 WS_CLIPSIBLINGS 및 WS_CLIPCHILDREN 창 스타일이 있습니다.
  • 내 resize 이벤트 핸들러에서 즉시 창을 다시 그립니다. 픽셀 형식 설명자에 PFD_SUPPORT_COMPOSITION 설정

    • :
    • 내가 해봤

    .

  • 페인트 처리기에서 wxPaintDC를 사용하지 않고 :: ValidateRect (hwnd, NULL)을 대신 호출하십시오.
  • WM_NCPAINT 처리하고 이전과 버퍼 스왑 후 glFlush 및/또는 glFinish 호출 페인트 이벤트
  • 의 클라이언트 영역을 제외한 DWM의 API
  • 를 통해 클라이언트 영역을
  • 비활성화 NC 페인트를 제외하고.
  • 모든 페인트 이벤트 (테스트)에서 창을 무효화 - 여전히 깜박임!
  • 공유 GL 컨텍스트를 사용하지 않습니다.
  • 이중 버퍼링을 비활성화합니다.

이 DWM을 사용하지 GL_FRONT_AND_BACK에 기록

  • 를 선택할 수 없습니다.

    그리고 OpenGL 대신 Direct3D를 사용하는 경우에도 이것이 문제가된다는 것을 알고 있습니다. 테스트 해보지는 않았지만 많은 작업을 나타냅니다.

  • +0

    나는 MFC 컨트롤이 때때로 GL 창에서 유물을 그릴 떠나하여 MFC MDI 응용 프로그램 및 OpenGL, 유사한 문제가있다. 이는 Aero가 활성화 된 경우에만 발생합니다. 마찬가지로 만족스러운 해결책을 찾지 못했습니다. – mcmcc

    +0

    glReadPixels에서 읽은 OpenGL 컨텐트가있는 창으로 블리 팅하면 문제가 해결되지만 더 멋진 방법이 있어야합니다. – Pete

    답변

    0

    흠, 어쩌면 당신은 같은 문제에 부딪 혔을 것입니다 : "새로운"MFC 을 사용하고 있다면 탭과 윈도우 스플리터가있는 응용 프로그램이 만들어집니다.

    스플리터에는이 동작을 유발하는 일부 로직이 있습니다 (이 경우 투명 윈도우와 어도비 플록 주위에 XOR 줄을 그리는 것으로 추측됩니다). 스플리터를 제거하여 문제가 해결되었는지 확인하십시오 ( ). 분리 기능이 필요한 경우 - 다른 분리기를 사용하십시오.

    또한 탭을 사용하면 동일한 문제 (제거/교체)가있는 창을 도킹하고 다시 분할 할 수 있습니다.

    행운을 빌어 요, 이고르

    +0

    wxWidgets 앱이 없거나 mcmcc의 댓글에 응답하고 있습니까? 궁극적 인 문제는 DWM이 다른 스레드에서 합성된다는 것입니다. – Pete

    +0

    Paint 메서드에서 모든 OpenGL 호출을 바꾸어 동일한 문제를 해결했습니다. 월요일까지 내 코드에 액세스 할 필요가 없으므로 지금은 더 자세한 정보를 제공 할 수 없습니다 ... 적어도 VCL을 사용하지만 동일한 문제가 있기 때문에 동일한 솔루션이 될 수 있습니다! – Maypeur

    2

    이는 롱샷이지만, 나는 정확히 같은 문제를 자신을 단지 해결 .

    우리가 OpenGL 창을 둘러싼 캡션이없는 그룹 상자의 윤곽선을 소유자가 그리기 때문에 (즉, 작은 경계선을 만들기 위해) 사용자의 사례를 설명하지 않을 수 있기 때문에 긴 사진 부분이 나타납니다. 우리가 무엇을 발견

    문제가이이었다 원인 :

    우리는 그룹 상자의 윤곽을 그릴 수의 (a HOLLOW_BRUSH 포함) RoundRect() 호출을 사용했다. MoveToEx() 및 LineTo() 호출을 변경하여 줄이 그려 지도록하고 그룹 상자에서 수행하지 않으면 GDI가 예기치 않게 컨트롤의 전체 내용을 다시 칠하지 못하게합니다. 무효화 논리에 차이가있을 수 있습니다 (또는 의도 한 속이 빈 브러시를로드하는 데 버그가 있음). 아직 조사 중입니다.

    -Noel는