Linux下3D离屏渲染(可通过ssh操作)

网上有好多3D渲染的例子,包括IOS、Android以及带Linux、windows上带窗口的。linux下真正离屏渲染的例子少之又少,我这里说的离屏是不依赖X Server,即ssh即可运行,当然渲染得到的图片要保存下来,否则没有意义。

回顾

我之前进行openGL渲染使用的是glew、glfw库,其中有以下这样一段代码:

	GLFWwindow* window;
    TextureHelper texHelper;
    //window
    if (!glfwInit())
    {
        std::cout << "Error::GLFW could not initialize GLFW!" << std::endl;
        return false;
    }
    glfwWindowHint(GLFW_RESIZABLE, GL_FALSE);
    
    window = glfwCreateWindow(windowWidth, windowHeight, "demo", NULL, NULL);
    if (!window)
    {
        std::cout << "Error::GLFW could not create window!" << std::endl;
        glfwTerminate();
        return false;
    }
    glfwMakeContextCurrent(window);
    
    glewExperimental = GL_TRUE;
    if(glewInit()!=GLEW_OK)
    {
        std::cout<<"Error::GLEW init failed!"<<std::endl;
        glfwTerminate();
        return false;
    }

下面接着就可以添加自己的渲染代码了,在连着屏幕的电脑上可正常运行。但问题是我用ssh远程操作时,在不构建X Server时,总会爆出 “Error::GLFW could not create window!”。Google后才明白glfw的主要作用是构建渲染所需的上下文,而glfw是依赖X Server的,也就是我们不能用glfw,但要创建一个上下文。

正题

找了好久终于找到了它,EGL库,接下来直接上代码。

#include <stdio.h>
#include <string.h>
#include <EGL/egl.h>

using namespace std;

class CreateContext {

private:
    const EGLint configAttribs[13] = {
            EGL_SURFACE_TYPE, EGL_PBUFFER_BIT,
            EGL_BLUE_SIZE, 8,
            EGL_GREEN_SIZE, 8,
            EGL_RED_SIZE, 8,
            EGL_DEPTH_SIZE, 8,
            EGL_RENDERABLE_TYPE, EGL_OPENGL_BIT,
            EGL_NONE
    };
    const int pbufferWidth = 9;
    const int pbufferHeight = 9;
    const EGLint pbufferAttribs[5] = {
          EGL_WIDTH, pbufferWidth,
          EGL_HEIGHT, pbufferHeight,
          EGL_NONE,
    };
    
public:

    struct context {
        EGLDisplay display;
        EGLContext gl_context;
        EGLSurface surface;
    }ctx;

    bool setup_context(context& ctx)
    {
        // 1. Initialize EGL
        ctx.display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
        EGLint major, minor;
        eglInitialize(ctx.display, &major, &minor);

        // 2. Select an appropriate configuration
        EGLint numConfigs;
        EGLConfig eglCfg;
        eglChooseConfig(ctx.display, configAttribs, &eglCfg, 1, &numConfigs);

        // 3. Create a surface
        ctx.surface = eglCreatePbufferSurface(ctx.display, eglCfg, pbufferAttribs);

        // 4. Bind the API
        eglBindAPI(EGL_OPENGL_API);

        // 5. Create a context and make it current
        ctx.gl_context = eglCreateContext(ctx.display, eglCfg, EGL_NO_CONTEXT, NULL);
        if (ctx.gl_context == EGL_NO_CONTEXT)
            return false;

        if (!eglMakeCurrent(ctx.display, ctx.surface, ctx.surface, ctx.gl_context))
            return false;

        return true;
    }

    void cleanup(context& ctx)
    {
        eglDestroySurface(ctx.display, ctx.surface);
        eglDestroyContext(ctx.display, ctx.gl_context);
        eglTerminate(ctx.display);
    }
};

仅需要EGL库,作用就是创建上下文以便接下来的渲染。需要注意的是,这里仅代替了glfwInit(),在编写渲染代码之前,还需要glewInit()。

至于渲染并截图,网上有很多例子,也可以参考: IOS opengl离屏渲染并截图,有些函数名字不太一样,需要稍做改动。

  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值