基于linux系统的OpenGL环境(二)

OpenGL函数文档

远程显示设备

  继续上一篇,使用EGL创建surface之后,就可以进行编译和执行了

# 编译链接
gcc -o example example.c -lEGL
# 执行
./example

如果程序马上执行结束,就是属于正常的,如果程序卡在那里不动也没有结束,就说明还有问题,可能是在寻找显示设备DISPLAY,但是寻找不到就卡在那里。EGL创建的surface会绑定到一个默认显示设备上,而linux中可以通过设置DISPLAY变量来指定显示设备,同时也可以将显示设备设置为一个远程显示器,这样可以通过远程网络进行显示。

# 在~/.bashrc文件中设置DISPLAY
export DISPLAY=IP:0.0
# 之后执行source ~/.bashrc

这样可以在windows上远程显示出来,这里可以使用putty和Xming软件进行远程显示,这样操作完成之后,程序就应该可以正常执行了。
  除了使用Xming还可以使用VNCserver来进行远程显示

yum install tigervnc-server
yum install tigervnc
# 设置密码
vncserver

然后在windows端安装vncviewer或者tightvnc,就可以远程连接登录linux系统了,vncserver桌面删除命令如下所示。

# 删除桌面
vncserver kill :1

  但是需要注意的是,这种远程显示是直接发送绘图指令的,常规的绘图指令比如打开一个桌面或者软件界面,都是没有问题的。但是如果要操纵更加复杂的底层绘图指令,比如使用opengl的freeglut库的glut函数来创建窗口或者缓存等,会调用基于X11的GLX库,但是windows的窗口系统没有GLX库,那么程序就会运行失败。

在多个显卡中指定显示设备

  如果linux系统上有多个显卡,可以指定某个显卡为显示设备

#define EGL_EGLEXT_PROTOTYPES
#include <EGL/egl.h>
#include <EGL/eglext.h>

main()
{
  static const int MAX_DEVICES = 4;
  EGLDeviceEXT eglDevs[MAX_DEVICES];
  EGLint numDevices;

  PFNEGLQUERYDEVICESEXTPROC eglQueryDevicesEXT =
    (PFNEGLQUERYDEVICESEXTPROC)
    eglGetProcAddress("eglQueryDevicesEXT");

  eglQueryDevicesEXT(MAX_DEVICES, eglDevs, &numDevices);

  printf(“Detected %d devices\n”, numDevices);

  PFNEGLGETPLATFORMDISPLAYEXTPROC eglGetPlatformDisplayEXT =
    (PFNEGLGETPLATFORMDISPLAYEXTPROC)
    eglGetProcAddress("eglGetPlatformDisplayEXT");

  eglDpy = eglGetPlatformDisplayEXT(EGL_PLATFORM_DEVICE_EXT, 
                                    eglDevs[0], 0);

  // ...
}

创建窗口

  使用EGL创建一个窗口的简单流程是

eglGetDisplay()
eglInitialize()
eglChooseConfig()
eglCreateWindowSurface()
eglCreatePBufferSurface()
eglCreatePixmapSurface()
# draw with GL
eglSwapBuffers()

  其中第一种是可以直接显示在屏幕上的surface类型,

EGLSurface eglCreateWindowSurface()

而另外两种surface类型则不会直接显示在屏幕上,分别是

eglCreatePBufferSurface()
eglCreatePixmapSurface()

  通过查询函数文档,知道其调用方式是

EGLSurface eglCreateWindowSurface(	EGLDisplay display,
									EGLConfig config,
								 	NativeWindowType native_window,
								 	EGLint const * attrib_list);

管理你自己的OpenGL资源

  在之前的例子中,使用EGL创建Pbuffer Surface,并用EGL管理所有的Buffer,这个类似于窗口中默认的Framebuffer。也可以你自己管理OpenGL资源,这时就要跳过函数eglCreatePbufferSurface(),之后要出创建OpenGL Context,并且要通过一个函数绑定

eglMakeCurrent(eglDpy, EGL_NO_SURFACE, EGL_NO_SURFACE, eglCtx);

之后就要自己创建一个Frame Buffer Object (FBO),然后绑定纹理和渲染缓存,这点是很有用的,可以避免从EGL Surface拷贝数据到CUDA/OpenGL加速缓存。

上一篇:Android:如何以编程方式找出设备的精确像素长宽比?


下一篇:Linux-docker如何映射主机分区?