背景
我有一个用于开发汽车控制系统的程序,它使用 TCL 脚本语言和 OpenGL 的组合来额外渲染汽车在道路上行驶的行为。
我正在做的是实现对它的 OculusRift 支持,到目前为止已经设法解决了传感器部分,通过右键单击汽车正在行驶的窗口,我可以将它发送到 oculus rift。到目前为止,它看起来像这样:Youtube-Video
该程序的视觉部分已经有很多功能,包括调整 FOV、鱼眼镜头、相机方向、车内视图等选项。
在查看了软件文件夹后,我发现了一个 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 popmatrix
dict 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
现在我的问题:
- 这样的事情可能吗?
- 有人能指出我正确的方向吗?即我可以使用的一些 gl 函数?
- 也许 Direct3D 也可以?
我确实在 stackoverflow 上阅读了这篇文章,但未能理解:/