gpt4 book ai didi

linux - 没有 GUI 的 OpenGL

转载 作者:可可西里 更新时间:2023-11-01 11:51:22 30 4
gpt4 key购买 nike

假设我运行的是 Linux,但没有安装桌面环境。我启动了我的系统,我所拥有的只是我的 shell。

是否可以编译使用OpenGL库或直接使用GPU驱动程序绘制到屏幕的程序?

据我所知,我总是需要某种桌面环境来为我提供一个可以在上面绘图的窗口。为了保持它 简单比方说我只想在屏幕中间绘制一个简单的二维形状,例如三角形。

如果可能的话,我该怎么做,我在哪里可以阅读更多关于该主题的信息?如果我能够直接在我的终端上绘图,这是否意味着我能够在具有桌面环境的系统上运行我的应用程序并且仍然能够看到我的三角形?

最佳答案

Is it possible to compile a program that uses the OpenGL libraries or directly uses the GPU driver to draw to the screen?

是的。通过 EGL API,这已经正式化,并且与 NVidia GPU 及其专有驱动程序配合得最好。 NVidia 在他们的开发博客上对此进行了描述 https://devblogs.nvidia.com/egl-eye-opengl-visualization-without-x-server/

主要步骤是:

为 PBuffer 创建 OpenGL 上下文

#include <EGL/egl.h>

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
};

static const int pbufferWidth = 9;
static const int pbufferHeight = 9;

static const EGLint pbufferAttribs[] = {
EGL_WIDTH, pbufferWidth,
EGL_HEIGHT, pbufferHeight,
EGL_NONE,
};

int main(int argc, char *argv[])
{
// 1. Initialize EGL
EGLDisplay eglDpy = eglGetDisplay(EGL_DEFAULT_DISPLAY);

EGLint major, minor;

eglInitialize(eglDpy, &major, &minor);

// 2. Select an appropriate configuration
EGLint numConfigs;
EGLConfig eglCfg;

eglChooseConfig(eglDpy, configAttribs, &eglCfg, 1, &numConfigs);

// 3. Create a surface
EGLSurface eglSurf = eglCreatePbufferSurface(eglDpy, eglCfg,
pbufferAttribs);

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

// 5. Create a context and make it current
EGLContext eglCtx = eglCreateContext(eglDpy, eglCfg, EGL_NO_CONTEXT,
NULL);

eglMakeCurrent(eglDpy, eglSurf, eglSurf, eglCtx);

// from now on use your OpenGL context

// 6. Terminate EGL when finished
eglTerminate(eglDpy);
return 0;
}

然后像往常一样继续休息。或者您甚至可以完全放弃 PBuffer,只使用 OpenGL 管理资源,即渲染到帧缓冲区对象。为此,您可以省略创建表面并仅使上下文成为当前上下文。

这是一个使用 EGL 的例子,没有显示,没有 EGL 表面,有 OpenGL 管理的帧缓冲区。

#include <GL/glew.h>
#include <GL/glut.h>
#include <EGL/egl.h>

#include <unistd.h>
#include <stdlib.h>
#include <assert.h>
#include <sys/mman.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

#include <math.h>
#include <stdio.h>

using namespace std;

namespace render
{
int width, height;
float aspect;

void init();
void display();

int const fbo_width = 512;
int const fbo_height = 512;

GLuint fb, color, depth;

void *dumpbuf;
int dumpbuf_fd;
};

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
};

int main(int argc, char *argv[])
{
// 1. Initialize EGL
EGLDisplay eglDpy = eglGetDisplay(EGL_DEFAULT_DISPLAY);

EGLint major, minor;
eglInitialize(eglDpy, &major, &minor);

// 2. Select an appropriate configuration
EGLint numConfigs;
EGLConfig eglCfg;

eglChooseConfig(eglDpy, configAttribs, &eglCfg, 1, &numConfigs);

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

// 3. Create a context and make it current
EGLContext eglCtx = eglCreateContext(eglDpy, eglCfg, EGL_NO_CONTEXT,
NULL);

eglMakeCurrent(eglDpy, EGL_NO_SURFACE, EGL_NO_SURFACE, eglCtx);

glewInit();
// from now on use your OpenGL context
render::init();
render::display();

// 4. Terminate EGL when finished
eglTerminate(eglDpy);
return 0;
}

void CHECK_FRAMEBUFFER_STATUS()
{
GLenum status;
status = glCheckFramebufferStatus(GL_DRAW_FRAMEBUFFER);
switch(status) {
case GL_FRAMEBUFFER_COMPLETE:
break;

case GL_FRAMEBUFFER_UNSUPPORTED:
/* choose different formats */
break;

default:
/* programming error; will fail on all hardware */
throw "Framebuffer Error";
}
}

namespace render
{
float const light_dir[]={1,1,1,0};
float const light_color[]={1,0.95,0.9,1};

void init()
{
glGenFramebuffers(1, &fb);
glGenTextures(1, &color);
glGenRenderbuffers(1, &depth);

glBindFramebuffer(GL_FRAMEBUFFER, fb);

glBindTexture(GL_TEXTURE_2D, color);
glTexImage2D( GL_TEXTURE_2D,
0,
GL_RGB8,
fbo_width, fbo_height,
0,
GL_RGBA,
GL_UNSIGNED_BYTE,
NULL);

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, color, 0);

glBindRenderbuffer(GL_RENDERBUFFER, depth);
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24, fbo_width, fbo_height);
glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depth);

GLint red_bits, green_bits, blue_bits, alpha_bits;

glGetIntegerv(GL_RED_BITS, &red_bits);
glGetIntegerv(GL_GREEN_BITS, &green_bits);
glGetIntegerv(GL_BLUE_BITS, &blue_bits);
glGetIntegerv(GL_ALPHA_BITS, &alpha_bits);

fprintf(stderr, "FBO format R%dG%dB%dA%d\n",
(int)red_bits,
(int)green_bits,
(int)blue_bits,
(int)alpha_bits );

CHECK_FRAMEBUFFER_STATUS();

dumpbuf_fd = open("/tmp/fbodump.rgb", O_CREAT|O_SYNC|O_RDWR, S_IRUSR|S_IWUSR);
assert(-1 != dumpbuf_fd);
dumpbuf = malloc(fbo_width*fbo_height*3);
assert(dumpbuf);
}

void render()
{
static float a=0, b=0, c=0;

glBindTexture(GL_TEXTURE_2D, 0);
glEnable(GL_TEXTURE_2D);
glBindFramebuffer(GL_FRAMEBUFFER, fb);

glViewport(0,0,fbo_width, fbo_height);

glClearColor(0,0,0,0);
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );

glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(-1, 1, -1, 1, -1, 1);

glMatrixMode(GL_MODELVIEW);
glLoadIdentity();

glBegin(GL_TRIANGLES);
glColor3f(1,0,0);
glVertex3f(1,0,0);

glColor3f(0,1,0);
glVertex3f(0,1,0);

glColor3f(0,0,1);
glVertex3f(0,0,1);
glEnd();

glReadBuffer(GL_COLOR_ATTACHMENT0);
glReadPixels(0,0,fbo_width,fbo_height,GL_RGB,GL_UNSIGNED_BYTE,dumpbuf);
lseek(dumpbuf_fd, SEEK_SET, 0);
write(dumpbuf_fd, dumpbuf, fbo_width*fbo_height*3);
}
}

关于linux - 没有 GUI 的 OpenGL,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53381218/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com