2013-08-29 2 views
1

Моя ситуация такая. Я написал код, который проверял группу окон, если их контент может быть заменен или нет (это все перерисовка успешно выполняется в указанном окне и всех его дочерних элементах после события повторного калибровки). Если условия будут выполнены, я выполнил вызов glXSwapBuffers для указанного окна и всех его дочерних элементов. Моя цель состояла в том, чтобы разрешить систему мерцания-освобождения после изменения. Детские окна были расположены в виде плитки и не перекрывались. Между ними функция работала. Однако мой вопрос возникает с родителем. Когда-то во время повторной калибровки его содержимое мерцает. Пока это то, что я реализовал.glXSwapbuffers, похоже, не были заменены (?)

  1. Все события, такие как ConfigureNotify или Expose, уже сжимаются по мере необходимости.
  2. Окно background_pixmap установлено как None.
  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 может отставать в своем исполнении, когда он был вызван для Front-буфера, поскольку некоторая обнаруженная ошибка в системе Intel, казалось, предлагала один раз.
  3. Выход изображения переднего буфера после свопа показывает главным образом черные артефакты (цвет каждого окна всегда очищается до другого цвета перед каждым рисунком).

Есть ли другие правдоподобные объяснения относительно того, почему замена буфера, по-видимому, не заменяет буфер? Есть ли другие маршруты, которые я должен изучать, чтобы реализовать обновление без мерцания? Я прочитал статью, предлагающую использовать WinGravity, но, боюсь, я пока этого не понимаю.

ответ

0

Если в ваших окнах установлена ​​фоновая картинка, то на каждом шаге изменения размера они заполняются этим, прежде чем начнется перерисовка OpenGL. Это один из источников мерцания. Другая проблема заключается в том, что glXSwapBuffers не синхронизируются с вертикальным обратным каналом. Вы можете установить это с помощью glXSwapInterval.

Итак, две вещи, которые нужно сделать для изменения размера без мерцания: установите нулевую фонограмму и включите glXSwapBuffers, синхронизированный с вертикальным обратным проходом (интервал обмена 1).

+0

Фоновая pixmap уже установлена ​​в None, поэтому я думаю, что я могу попробовать установить вертикальный обратный путь.Есть ли способ проверить, выполняется ли это в настоящее время или нет? Некоторые сказали, что это зависит от того, какой водитель решит. Некоторые говорили, чтобы установить среду opengl, а затем, конечно, есть glXSwapInterval. Я однажды проверил настройку NVDia, чтобы разрешить вертикальную обратную передачу, но я не уверен, действительно ли это работает или нет, поскольку окно все еще продолжает мерцать. – null

+0

@ S.Aymerich: По правде говоря, я думаю, что вы сильно преувеличиваете вещи. Держите его простым и напряженным: просто вызовите glXSwapBuffers, как только вы закончите рисовать в окно. Вы все равно должны перерисовываться, не беспокойтесь о производительности. – datenwolf

+0

Вот как это было сделано один раз, @ datenwolf. Печальный факт заключается в том, что отображение дочерних окон, когда выполняется какое-либо событие изменения размера (либо его родных братьев, либо его родителей), сильно страдает. – null

Смежные вопросы