OpenGL
Как избежать лишних операций очистки Z-буфера
Большинству кадров в OpenGL предшествует операция glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT), которая одновременно очищает цветовой буфер кадра, и Z-буфер. Однако при больших разрешениях время очистки может составить до нескольких миллисекунд. Эту задержку очень желательно было бы сократить, поскольку она напрямую влияет на число кадров в секунду. Ускорения можно достичь, пожертвовав 1 (одним) битом точности.
На профессиональных картах, где разрядность Z составляет 32 бита, это можно проделать безболезненно. Тем более, что при размере окна 640x480 для очистки 32-битного Z-буфера нужно заполнить 600 (!) Кб памяти перед каждым кадром.
На недорогих изделиях типа Permedia2 (16-битный буфер), выигрыш в скорости будет меньше (при том же разрешении Z-буфер занимает 300 Кб), а качество изображения заметно ухудшится.
Технология следующая: в начале работы программы мы устанавливаем glDepthRange(0.0,1.0), то есть полностью задействуем Z-буфер. Затем очищаем его вызовом glClear(GL_DEPTH_BUFFER_BIT); Дополнительно вводим переменную Even=1 (четный кадр).
Перед каждым четным кадром (если Even=1) идет код:
glDepthRange(0.0,0.499999); glDepthFunc(GL_LESS);
Перед каждым нечетным (если Even=0):
glDepthRange(1.0,0.5); glDepthFunc(GL_GREATER);
После каждого кадра инвертируем переменную: Even=! Even.
В результате, четные кадры используют первую половину возможных значений Z-буфера, а нечетные - вторую. Поэтому в четных кадрах новое значение Z будет всегда меньше того, которое уже находится в буфере. В нечетных, наоборот, новое значение всегда больше ранее записанного. Поэтому для правильной работы перед каждым кадром необходимо инвертировать функцию glDepthFunc.
Метод применяется в играх GLQuake и Quake II. Переключается с консоли командой GL_ZTRICK с числовым параметром 1 или 0.