Я пишу библиотеку 3D-графики как часть моего проекта, и я нахожусь в точке, где все работает, но не достаточно хорошо.
В частности, моя главная головная боль заключается в том, что мойскорость заполнения пикселя составляет ужасно медленно - я даже не могу управлять 30 кадрами в секунду при рисовании треугольника, который охватывает половину окна 800x600 на моей целевой машине (которая по общему признанию является более старым компьютером, но это должно бытьв состоянии управлять этим ...)
Я запустил gprof на своем исполняемом файле, и я получаю следующие интересные строки:
% cumulative self self total
time seconds seconds calls ms/call ms/call name
43.51 9.50 9.50 vSwap
34.86 17.11 7.61 179944 0.04 0.04 grInterpolateHLine
13.99 20.17 3.06 grClearDepthBuffer
<snip>
0.76 21.78 0.17 624 0.27 12.46 grScanlineFill
Функция vSwap
- это моя функция подкачки двойного буфера, и она также выполняет всечинг, поэтому для меня имеет смысл, что тестовая программа будет проводить там большую часть своего времени.grScanlineFill
- это моя функция рисования треугольника, которая создает список ребер и затем вызывает grInterpolateHLine
для фактического заполнения треугольника.
Мой движок в настоящее время использует Z-буфер для выполнения скрытой очистки поверхности.Если мы сбрасываем со счетов (предполагаемые) издержки vsynch, то оказывается, что тестовая программа тратит примерно 85% своего времени либо на очистку буфера глубины, либо на запись пикселей в соответствии со значениями в буфере глубины.Моя функция очистки буфера глубины сама по себе проста: скопируйте максимальное значение с плавающей точкой в каждый элемент.Функция grInterpolateHLine
:
void grInterpolateHLine(int x1, int x2, int y, float z, float zstep, int colour) {
for(; x1 <= x2; x1 ++, z += zstep) {
if(z < grDepthBuffer[x1 + y*VIDEO_WIDTH]) {
vSetPixel(x1, y, colour);
grDepthBuffer[x1 + y*VIDEO_WIDTH] = z;
}
}
}
Я действительно не понимаю, как это можно улучшить, особенно учитывая, что vSetPixel
- это макрос.
Весь мой запас идей дляоптимизация была сведена к одному:
- Использовать буфер глубины целых чисел / фиксированной точки.
Проблема, с которой я столкнулся с буферами глубины целочисленных значений / фиксированной точкив том, что интерполяция может быть очень раздражающей, и у меня на самом деле нет библиотеки чисел с фиксированной точкой еще.Есть еще какие-нибудь мысли?Любой совет будет наиболее ценным.