我正在尝试使用OpenGL来帮助将Kinect深度图输入处理为图像。目前,我们正在使用Kinect作为基本的运动传感器,该程序会统计有多少人经过,并在每次检测到新的人时截屏。
问题是我需要让这个程序在不访问显示器的情况下运行。我们希望通过SSH远程运行它,而来自其他服务的网络流量对于X11转发来说将是一个好主意。在运行程序的机器上附加一个显示器是一种可能性,但出于能源消耗的原因,我们希望避免这样做。
该程序确实为OpenGL生成了2D纹理对象,通常只是在读取像素并使用FreeImage将其输出到.PNG文件之前使用GLUT来渲染它。我遇到的问题是,一旦删除了GLUT函数调用,所有打印到.PNG文件中的内容都是黑盒。
我在Kinect上使用的是OpenNI和NITE驱动。编程语言是C++,由于目标设备的硬件限制,我需要使用Ubuntu10.04。
我尝试过使用OSMesa或FrameBuffer对象,但我是一个完全的OpenGL新手,所以我还没有让OSMesa正确地呈现GLUT函数,并且我的编译器在GL/glext.h或GL/gl.h中找不到任何OpenGL FrameBuffer函数。
我知道纹理可以从图像文件读取到程序中,而我想要输出的只是一个2-D纹理。在这种情况下,有没有一种方法可以跳过令人头疼的屏幕外渲染,直接将纹理打印到图像文件中,而不需要首先使用OpenGL进行渲染?
发布于 2011-12-09 16:19:04
OSMesa库既不是GLUT的临时替代品,也不能协同工作。如果你只需要屏幕外的渲染部分而不需要交互,你必须自己实现一个简单的事件循环。
例如:
/* init OSMesa */
OSMesaContext mContext;
void *mBuffer;
size_t mWidth;
size_t mHeight;
// Create RGBA context and specify Z, stencil, accum sizes
mContext = OSMesaCreateContextExt( OSMESA_RGBA, 16, 0, 0, NULL );
OSMesaMakeCurrent(mContext, mBuffer, GL_UNSIGNED_BYTE, mWidth, mHeight);在这段代码之后,您可以使用普通的OpenGL调用来呈现,并且在glFinish()调用之后,可以通过mBuffer指针访问结果。
在您的事件循环中,您可以调用常规的onDisplay、onIdle等回调函数。
发布于 2011-12-09 01:44:01
我们想通过SSH远程运行它,来自其他服务的网络流量太大了,X11转发不是一个好主意。
如果转发X11并在该显示器上创建OpenGL上下文,则无论是否有可见的窗口,OpenGL流量都将通过网络。因此,您实际需要做的(如果您想使用GPU加速OpenGL)是在远程机器上启动X服务器,并使其保持活动的VT (即,X服务器必须是“拥有”显示器的程序)。那么您的程序只能与这台X服务器建立连接。但这需要使用Xlib。不久前,真菌写了一个简约的Xlib示例,我对它进行了一点扩展,以便它使用FBConfigs,您可以在这里找到它:https://github.com/datenwolf/codesamples/blob/master/samples/OpenGL/x11argb_opengl/x11argb_opengl.c
在您的情况下,应渲染到FBO或PBuffer。永远不要使用可见的窗口帧缓冲区来渲染要存储的内容!如果你创建了一个OpenGL窗口,就像我链接的代码一样,使用一个FBO。创建GLX PBuffer与创建GLX窗口没有什么不同,只是它不在屏幕上。
诀窍是,不要使用默认的X显示( SSH转发),而是使用到本地X Server的单独连接。关键是这条线
Xdisplay = XOpenDisplay(NULL);您可以将连接传递到本地服务器,而不是NULL。要做到这一点,您还需要(手动)在OpenGL呈现服务器上添加一个扩展验证条目,或者禁用扩展验证。
发布于 2011-12-09 01:16:30
可以使用glGetTexImage从OpenGL读回纹理。
https://stackoverflow.com/questions/8434633
复制相似问题