При выбранном нами подходе камере дается задание провести трассировку луча, для чего необходимо добавить к существующему классу Camera следующий метод:
void Camera :: raytrace(Scene& sen, int blockSize):
Для трассировки луча в камеру передается сцена. В переменной blockSize следует описать размер блока пикселов. Из глаза камеры испускается луч, проходящий через каждый угол пиксела на сцену, и определяется цвет света, возвращающегося обратно вдоль этого луча. Затем пиксел рисуется этим цветом.
14.5. Организация трассировщика луча в приложении Для текущего рисования пиксела мы будем использовать OpenGL; ниже показано, как функция raytraceO задает матрицу моделирования-вида и проекционную матрицу так, чтобы рисовать непосредственно на экране. Поэтому функция displayO в главном цикле имеет очень простой вид: требуется только очистить экран и дать команду объекту cam класса Camera провести трассировку луча. Можно использовать следующий псевдокод:
void display(void) {
gl Cl ear(GL_COLOR_BUFFER_BIT) : // clear the screen // очищаем экран
cam.raytrace(scn. blockSize); // ray trace the scene // производим трассировку луча на сцене
}
Даже небольшое изменение данного подхода может привести к большим отличиям при разработке вашего трассировщика луча. В нашем распоряжении уже имеется инструмент, рисующий SDL-сцену с помощью функций OpenGL, поэтому полезно непосредственно перед каждой трассировкой луча делать «эскиз» («preview») сцены. Такой эскиз позволит нам быстро убедиться в том, что камера нацелена правильно, а объекты находятся в нужных местах. В процессе трассировки эскиз сцены закрашивается, пиксел за пикселом, «истинными» цветами, которые эти пикселы получают в соответствии с трассировкой луча. Если все сделано правильно, то объекты после трассировки в точности совпадут с этими же объектами на эскизе. Любые ошибки трассировщика луча становятся очевидными.
Для рисования эскиза сцены достаточно дополнить функцию displayO следующим кодом:
void display(void) {