Фон
У меня есть программа для разработки систем управления автомобилем, которая использует комбинацию языка сценариев TCL и OpenGL для дополнительной визуализации поведения автомобиля на дороге.
Что я делаю, так это реализую поддержку OculusRift, и до сих пор мне удалось решить сесорную часть, и, щелкнув правой кнопкой мыши по окну, в котором движется автомобиль, я могу отправить его в Oculus Rift. Пока это выглядит так: YouTube видео
Визуальная часть программы уже имеет множество функций и включает в себя такие параметры, как настройка поля зрения, объектив «рыбий глаз», ориентация камеры, вид изнутри автомобиля и т. Д.
Осмотрев папку с программным обеспечением, я нашел файл TCL со следующими строками:
// ... cut here
gl pushmatrix
gl loadidentity
gl translate $x $y $z
gl rotate $xrot 1 0 0
gl rotate $yrot 0 1 0
gl rotate $zrot 0 0 1
gl translate $offx $offy $offz
lassign [lrange [OGL get modelviewmatrix] 12 14] tx ty tz
gl popmatrixdict set ::View($view) CameraMode FixedToBodyA
dict set ::View($view) xrot $xrot
dict set ::View($view) yrot $yrot
dict set ::View($view) zrot [expr $zrot + $zrot_eyeAngle]
dict set ::View($view) dist $conf(dist)
dict set ::View($view) VPtOffset_x $tx
dict set ::View($view) VPtOffset_y $ty
dict set ::View($view) VPtOffset_z $tz
dict set ::View($view) FieldOfView $conf(fov)
dict set ::View($view) AspectRatio $conf(AspectRatio)
return;
}
Я не нашел ни одной строки, которая обрабатывает сам рендеринг, но «gl» -команд было достаточно, чтобы я понял, что этот TCL-файл запускается непосредственно при подключении к процессу рендеринга. Поэтому я расширил вышеупомянутое с этим:
// load a self written DLL that wraps OVR functionality (Github link bellow)
# now run tclovrGetData() from the loaded DLL to get sensor data
set data [tclovrGetData]
// data = x y z xrot yrot zrot
gl pushmatrix
gl loadidentity
gl translate $x $y $z
gl rotate $xrot 1 0 0
...
Как вы можете видеть на видео, на мониторе он выглядит хорошо, но, как мы знаем, линзы Rift вносят искажения (которые были для меня незначительными) и довольно некоторую хроматическую аберрацию.
Моя идея
То, что я хочу, это захватить это «изображение / текстуру / рамку» на экране в видео каждые 10-20 мс (я все еще новичок в терминологии) и выполнить некоторую фильтрацию цвета на нем (я хочу посмотреть, смогу ли я уменьшить Хроматическая аберрация). Затем, возможно (чтобы сделать все независимым), создайте новое окно с измененным изображением и отправьте его в Rift. По сути, получите изображение в необходимом «формате», чтобы можно было выполнять на нем вычисления.
Моя идея состояла в том, чтобы (поскольку мы привязаны к процессу рендеринга) добавить несколько дополнительных строк в вышеупомянутый файл TCL, которые вызывают дополнительные функции внутри моей DLL, которые могут выполнять следующие действия:
// Begin Oculus rendering loop
//1. get frame that is currently being rendered (in this process)
//2. copy this frame to memory
//3. perform some operations (color filtering) on this frame in memory
//4. send this frame to a new window
Теперь мой вопрос:
Я читал это публиковать в stackoverflow, но не смог понять: /
Возможно ли что-то подобное?
Да, это так. Но это может быть не лучшим решением, поскольку копирование данных обратно в память процессора и их обработка там, скорее всего, будет недостаточно быстрым для приложений реального времени.
Может ли кто-нибудь указать мне правильное направление? То есть некоторые функции GL я мог бы использовать?
Если вы действительно хотите это сделать, сначала вы должны визуализировать ваше изображение в буфере кадров (или, лучше сказать, в текстуре, прикрепленной к буферу кадров). Затем эту текстуру можно скопировать в память процессора с помощью функций, которые вы уже нашли в соответствующем сообщении (glGetTexImage). Есть также другие варианты, такие как пиксельные буферы, которые могут быть немного быстрее (посмотреть здесь)
Более быстрое решение
Все эти подходы требуют, чтобы вы скопировали данные из gpu mem в cpu mem, обработали их там и скопировали все обратно. Это требует большой синхронизации между процессором и процессором, и, кроме того, обработка изображения на процессоре будет медленной.
В зависимости от доступных функций OpenGL, которые вы можете использовать, существуют методы для полной обработки изображений в графическом процессоре. Проще всего использовать шейдер:
В этом методе также нет необходимости во втором окне, поскольку обработанный квад может быть отображен в первом окне. Подробнее о постобработке на GPU вы можете посмотреть Вот.