背景
我有一个开发汽车控制系统的程序,它使用TCL脚本语言和OpenGL的组合来额外渲染汽车行驶的行为。
我正在做的是为它实施OculusRift支持,到目前为止已经设法解决了sesor部分,右键单击汽车行驶的窗口我可以将它发送到眼裂谷。到目前为止看起来像这样: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
现在我的问题:
我确实在stackoverflow上发布了This帖子但未能理解:/
答案 0 :(得分:0)
这样的事情会成为可能吗?
是的。但它可能不是最佳解决方案,因为将数据复制回cpu内存并对其进行处理很可能对实时应用程序来说不够快。
有人能指出我正确的方向吗?即我可以使用一些gl函数吗?
如果你真的想这样做,你首先要将图像渲染到帧缓冲区(或者更好地说是附加到帧缓冲区的纹理)。然后可以通过相关帖子(glGetTexImage)中找到的函数将此纹理复制到cpu内存中。还有其他选项,如像素缓冲区可能会更快(see here)
更快的解决方案
所有这些方法都要求您将数据从gpu mem复制到cpu mem,在那里进行处理并将所有内容复制回来。这需要在gpu和cpu之间进行大量同步,另外处理cpu上的图像会很慢。
根据可用的OpenGL功能,您可以使用方法在gpu上执行整个图像处理。最简单的可能是使用着色器:
在该方法中,也不需要第二窗口,因为后处理的四边形可以在第一窗口中显示。有关gpu上的后期处理的更多信息,您可以查看here。