在Ubuntu上无法在没有X Server的情况下使用EGL

时间:2018-04-16 02:55:25

标签: opengl xserver egl

我想在Ubuntu 16.04上打开没有X Server的OpenGL上下文。使用nvidia 390.48驱动程序。我可以使用https://devblogs.nvidia.com/egl-eye-opengl-visualization-without-x-server/上的官方文档重现结果。

我现在想要创建一个帧缓冲对象。

我尝试使用以下代码改编自https://github.com/parallel-forall/code-samples/blob/master/posts/egl_OpenGl_without_Xserver/tinyegl.cc

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <iostream>

#ifdef USE_EGL_GET_DISPLAY
#include <EGL/egl.h>
#else
#define EGL_EGLEXT_PROTOTYPES
#include <EGL/egl.h>
#include <EGL/eglext.h>
#endif

#ifdef USE_EGL_SURFACE
#include <GL/gl.h>
#else
#define GL_GLEXT_PROTOTYPES
#include <GL/gl.h>
#include <GL/glext.h>
#endif

//ID for FBO and RBO
unsigned int FboID[1], RboID[1];

static const int pbufferWidth = 9, pbufferHeight = 9;

int main(int argc, char *argv[])
{

EGLDisplay display;
EGLContext context;

// 1. Initialize EGL
display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
if (display == EGL_NO_DISPLAY) {
        fprintf(stderr, "Error! Failed to eglGetDisplay\n");
        return false;
}
EGLint major, minor;
EGLBoolean eglStatus = eglInitialize(display, &major, &minor);
if (eglStatus == EGL_FALSE) {
        fprintf(stderr, "Error! Failed to eglInitialize\n");
        return false;
}
fprintf(stderr, "EGL Version %d . %d\n", major, minor);

// 2. Choose config
static const EGLint configAttribs[] = {
        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
};
EGLint numConfigs;
EGLConfig eglCfg;
eglStatus = eglChooseConfig(display, configAttribs, &eglCfg, 1, &numConfigs);
if (eglStatus == EGL_FALSE) {
        fprintf(stderr, "Error! Failed to eglChooseConfig\n");
        return false;
}
// 3. Create surface
const EGLint pbufferAttribs[] = {
        EGL_WIDTH, pbufferWidth,
        EGL_HEIGHT, pbufferHeight,
        EGL_NONE
};
EGLSurface surface = eglCreatePbufferSurface(display, eglCfg, pbufferAttribs);
if (surface == EGL_NO_SURFACE) {
        fprintf(stderr, "Error! Failed to eglCreatePbufferSurface\n");
        return false;
}
// 4. Bind API(OpenGL)
eglStatus = eglBindAPI(EGL_OPENGL_API);
if (eglStatus == EGL_FALSE) {
        fprintf(stderr, "Error! Failed to eglBindAPI\n");
        return false;
}
// 5.Create context and make it current
context = eglCreateContext(display, eglCfg, EGL_NO_CONTEXT, NULL);
if (context == EGL_NO_CONTEXT) {
        fprintf(stderr, "Error! Failed to eglCreateContext\n");
        return false;
}
eglStatus = eglMakeCurrent(display, surface, surface, context);
if (eglStatus == EGL_FALSE) {
        fprintf(stderr, "Error! Failed to eglMakeCurrent\n");
        return false;
}
// manually create the OpenGL buffers and textures: A  framebuffer object with associated
// texture and depth buffers.
// create a 2D texture as the color buffer
GLuint texId;
glGenTextures(1, &texId);
glBindTexture(GL_TEXTURE_2D,  texId);
glTexImage2D(GL_TEXTURE_2D, 0,  GL_RGBA8,  pbufferWidth, pbufferHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
glBindTexture(GL_TEXTURE_2D, 0);    

// create a renderbuffer for storing the depth component
GLuint rbId;
glGenRenderbuffers(1, &rbId);
glBindRenderbuffer(GL_RENDERBUFFER, rbId);
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, pbufferWidth, pbufferHeight);
glBindRenderbuffer(GL_RENDERBUFFER, 0);

// create the framebuffer and attach the texture (color buffer) and the renderbuffer (depth buffer)
GLuint fbId;
glGenFramebuffers(1, &fbId);
glBindFramebuffer(GL_FRAMEBUFFER, fbId);    

glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texId, 0);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rbId);

GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
if (status != GL_FRAMEBUFFER_COMPLETE) {
            fprintf(stderr, "Error! status = %d\n", status);
}

eglTerminate(display);
return 0;
}

但似乎GL_FRAMEBUFFER的状态并未转为“完成”

编译命令:

g++ main.cc -lEGL  -lGL

是否有人想知道这个或替代方法来创建帧缓冲区对象?

1 个答案:

答案 0 :(得分:0)

根据NVIDIA's blog,您需要链接libOpenGL.so而不是libGL.so。

g++ tinyegl.cc -o tinyegl -lEGL /usr/lib/nvidia-390/libOpenGL.so

我不确定,但是&#34; -lOpenGL&#34;不管用。 所以,需要使用/ usr / lib / {nvidia-driver-path} /libOpenGL.so