2013-08-29 6 views
1

내 상황은 이와 같습니다. 나는 그 내용이 바뀌 었는지 아닌지를 그룹화 한 코드를 썼다. (다시 그리기가 모든 윈도우와 모든 자식을 다시 크기 조정 한 후에 성공적으로 수행되었다.) 조건이 충족 될 경우 glXSwapBuffers가 창과 모든 자식을 호출합니다. 내 목표는 깜박임 현상이있는 크기 조정 시스템을 허용하는 것이 었습니다. 자식 창은 타일 방식으로 배열되어 있으며 겹치지 않습니다. 그들 사이에 기능이 작동하는 것처럼 보였다. 그러나 내 문제는 부모와 함께 발생합니다. 크기 조정 중 때때로 내용이 깜박입니다. 지금까지, 이것이 내가 구현 한 것입니다.glXSwapbuffers가 스왑되지 않은 것처럼 보입니다 (?)

  1. ConfigureNotify 또는 Expose와 같은 모든 이벤트는 필요에 따라 이미 압축되어 있습니다.
  2. 창 background_pixmap이 없음으로 설정됩니다.
  3. Expose 이벤트가 생성 될 때마다 창 배경 콘텐트가 손실된다는 것을 이해하십시오. 다시 그릴 때마다 완료된 다시 그리기 복사본을 항상 할당 된 버퍼에 보관합니다. (pixmap 또는 fbo는 아니지만 지금은 충분합니다.)

glXSwapBuffers()를 호출 할 때마다 내 논리가 같습니다.

void window_swap(Window *win) { 
    Window *child; 
    if (win) { 
     for (child=win->child; child; child=child->next) 
      window_swap(child); 

     if (isValidForSwap(win)) { 
      glXMakeCurrent(dpy, win->drawable, win->ctx); 
      glDrawBuffer(GL_BACK); 
      RedrawWindowFromBuffer(win, win->backing_store); 
      glXSwapBuffers(dpy, win->drawable); 
     } 
    } 
} 

어느 쪽을 사용해야합니까? 콘텐츠는 항상 스왑하기 전에 복원됩니다. 안타깝게도 구현에는 그렇게 나타나지 않았습니다. 위의 코드에서 버퍼에 있어야 할 내용을 다음과 같이 출력하여 디버깅 목적에 맞게 조정합니다.

void window_swap(Window *win) { 
    if (win) { 
     if (isValidForSwap(win)) { 

      glXMakeCurrent(dpy, win->drawable, win->ctx); 

      glDrawBuffer(GL_BACK); 
      OutputWindowBuffer("back.jpg", GL_BACK); 
      RedrawWindowFromBuffer(win, win->backing_store); 

      glXSwapBuffers(dpy, win->drawable); 

      glDrawBuffer(GL_BACK); 
      glClearColor(1.0, 1.0, 1.0, 1.0); 
      glClear(GL_COLOR_BUFFER_BIT); 

      OutputWindowBuffer("front_after.jpg", GL_FRONT); 
      OutputWindowBuffer("back_after.jpg", GL_BACK); 
     } 
    } 
} 

OutputWindowBuffer 함수() 화상으로서 버퍼 콘텐츠 후 출력 읽어 표준 glReadPixel()를 사용한다. 읽을 버퍼는 함수에 전달 된 매개 변수에 의해 결정됩니다. 출력 그림을 통해 알게 된 것은 이것입니다.

  1. RedrawWindowFromBuffer() 이후의 백 버퍼의 사진 출력이 예상 한 것입니다.
  2. 스왑 후 백 버퍼의 그림 출력은 예상대로 지워진 색으로 채워집니다. 따라서, glReadPixel은 Intel 시스템에 대한 발견 된 버그가 한 번 제안 된 것처럼 Front 버퍼에 호출되었을 때 실행이 지연 될 수 있습니다.
  3. 스왑 후 전면 버퍼의 그림 출력은 주로 검은 색 아티팩트를 표시합니다 (내 그림의 색은 각 그림을 그리기 전에 항상 다른 색으로 지워짐).

왜 버퍼를 바꾸는 것이 버퍼를 바꾸는 것처럼 보이지 않는 것 같은 다른 그럴듯한 설명이 있습니까? 깜박임없는 크기 조정을 구현할 때 고려해야 할 다른 경로가 있습니까? 나는 WinGravity의 사용을 제안하는 기사를 읽었지만 나는 아직 그것을 이해하지 못하고있다.

답변

0

윈도우에 배경 pixmap이 설정되어있는 경우 실제 OpenGL 그리기가 시작되기 전에 모든 크기 조정 단계마다 채워집니다. 이것이 깜박임의 한 원인입니다. 다른 문제는 glXSwapBuffers가 수직 리 트레이스와 동기화되지 않는다는 것입니다. glXSwapInterval을 사용하여이를 설정할 수 있습니다.

깜박임없는 크기 조정을 위해해야 ​​할 두 가지 작업 : 배경이없는 pixmap을 설정하고 glXSwapBuffers가 수직 귀선 (스왑 간격 1)과 동기화되도록 설정합니다.

+0

배경 pixmap이 이미 None으로 설정되어 있으므로 수직 리트 렉션 설정을 시도해 볼 수 있습니다.현재 구현되고 있는지 여부를 확인하는 방법이 있습니까? 어떤 이는 운전자가 결정할 때까지 달려 있다고 말했습니다. 어떤 사람들은 OpenGL 환경을 설정했다. 그리고 glXSwapInterval이있다. 한 번 수직 리트 렉션을 허용하기 위해 NVDia 설정을 확인했지만 창이 계속 깜박이기 때문에 실제로 작동하는지 여부는 확실하지 않습니다. – null

+0

@ S.Aymerich : 진실은 당신이 심각하게 과장되어 있다고 생각합니다. 간단하고 심하게 보관하십시오 : 창에 그리기를 마치면 glXSwapBuffers를 호출하십시오. 어쨌든 다시 그리기해야하며 성능에 대해 걱정하지 마십시오. – datenwolf

+0

그것이 어떻게 한 번 완료되었는지, @ datenwolf. 슬픈 사실은 어떤 크기 조정 이벤트 (형제 또는 그 부모 중 하나에서)가 수행 될 때 자식 윈도우가 크게 표시된다는 것입니다. – null

관련 문제