Ubuntu 上没有 X Server 无法使用 EGL
Unable to use EGL without X Server on Ubuntu
我想在 Ubuntu 16.04 上打开没有 X 服务器的 OpenGL 上下文。使用 nvidia 390.48 驱动程序。我可以使用 https://devblogs.nvidia.com/egl-eye-opengl-visualization-without-x-server/ 上的官方文档重现结果。
我现在想创建一个帧缓冲区对象。
的代码
#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
有没有人有解决此问题的想法或创建帧缓冲区对象的替代方法?
根据 NVIDIA's blog,您需要 link libOpenGL.so 而不是 libGL.so。
g++ tinyegl.cc -o tinyegl -lEGL /usr/lib/nvidia-390/libOpenGL.so
我不确定,但是“-lOpenGL”不工作。
所以,需要使用 /usr/lib/{nvidia-driver-path}/libOpenGL.so
我想在 Ubuntu 16.04 上打开没有 X 服务器的 OpenGL 上下文。使用 nvidia 390.48 驱动程序。我可以使用 https://devblogs.nvidia.com/egl-eye-opengl-visualization-without-x-server/ 上的官方文档重现结果。
我现在想创建一个帧缓冲区对象。
的代码#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
有没有人有解决此问题的想法或创建帧缓冲区对象的替代方法?
根据 NVIDIA's blog,您需要 link libOpenGL.so 而不是 libGL.so。
g++ tinyegl.cc -o tinyegl -lEGL /usr/lib/nvidia-390/libOpenGL.so
我不确定,但是“-lOpenGL”不工作。 所以,需要使用 /usr/lib/{nvidia-driver-path}/libOpenGL.so