- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我对egl pbuffer 表面非常困惑。在我看来,pbuffer 表面是一个独立于平台的表面,就像 windows 表面或 pixmap 表面一样。绘制到该表面的事物虽然不可见,但应该能够被读回。
这个问题的答案似乎证实了我的理解:
Difference from eglCreatePbufferSurface and eglCreatePixmapSurface with OpenGL ES(EGL)
但是,我的实验表明,除了使用 pbuffer 表面之外,我还需要创建一个 fbo 缓冲区。
这段代码似乎对我有用,它创建了一个 pbuffer 表面,然后创建了一个 fbo。
#include <GLES2/gl2.h>
#include <EGL/egl.h>
int main(int argc, char *argv[])
{
EGLint ai32ContextAttribs[] = { EGL_CONTEXT_CLIENT_VERSION, 2,
EGL_NONE };
// Step 1 - Get the default display.
EGLDisplay eglDisplay = eglGetDisplay((EGLNativeDisplayType)0);
// Step 2 - Initialize EGL.
eglInitialize(eglDisplay, 0, 0);
// Step 3 - Make OpenGL ES the current API.
eglBindAPI(EGL_OPENGL_ES_API);
// Step 4 - Specify the required configuration attributes.
EGLint pi32ConfigAttribs[5];
pi32ConfigAttribs[0] = EGL_SURFACE_TYPE;
pi32ConfigAttribs[1] = EGL_WINDOW_BIT;
pi32ConfigAttribs[2] = EGL_RENDERABLE_TYPE;
pi32ConfigAttribs[3] = EGL_OPENGL_ES2_BIT;
pi32ConfigAttribs[4] = EGL_NONE;
// Step 5 - Find a config that matches all requirements.
int iConfigs;
EGLConfig eglConfig;
eglChooseConfig(eglDisplay, pi32ConfigAttribs, &eglConfig, 1, &iConfigs);
if (iConfigs != 1)
{
printf("Error: eglChooseConfig(): config not found.\n");
exit(-1);
}
// Step 6 - Create a surface to draw to.
EGLSurface eglSurface;
eglSurface = eglCreatePbufferSurface(eglDisplay, eglConfig, NULL);
// Step 7 - Create a context.
EGLContext eglContext;
eglContext = eglCreateContext(eglDisplay, eglConfig, NULL, ai32ContextAttribs);
// Step 8 - Bind the context to the current thread
eglMakeCurrent(eglDisplay, eglSurface, eglSurface, eglContext);
GLuint fboId = 0;
GLuint renderBufferWidth = 1920;
GLuint renderBufferHeight = 1080;
// Step 9 - create a framebuffer object
glGenFramebuffers(1, &fboId);
glBindFramebuffer(GL_FRAMEBUFFER, fboId);
GLuint renderBuffer;
glGenRenderbuffers(1, &renderBuffer);
glBindRenderbuffer(GL_RENDERBUFFER, renderBuffer);
glRenderbufferStorage(GL_RENDERBUFFER, GL_RGB565, renderBufferWidth, renderBufferHeight);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, renderBuffer);
GLuint depthRenderbuffer;
glGenRenderbuffers(1, &depthRenderbuffer);
glBindRenderbuffer(GL_RENDERBUFFER, depthRenderbuffer);
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, renderBufferWidth, renderBufferHeight);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depthRenderbuffer);
// Step 10 - check FBO status
GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
if(status != GL_FRAMEBUFFER_COMPLETE)
{
printf("Problem with OpenGL framebuffer after specifying color render buffer: \n%x\n", status);
}
else
{
printf("FBO creation succedded\n");
}
int size = 4 * renderBufferHeight * renderBufferWidth;
unsigned char *data2 = new unsigned char[size];
// Step 11 - clear the screen in Red and read it back
glClearColor(1.0,0.0,0.0,1.0);
glClear(GL_COLOR_BUFFER_BIT);
eglSwapBuffers( eglDisplay, eglSurface);
glReadPixels(0,0,renderBufferWidth,renderBufferHeight,GL_RGBA, GL_UNSIGNED_BYTE, data2);
... save data2 to image ...
}
但是,如果我删除 fbo,并尝试直接绘制到 pbuffer,则在调用 glClear() 函数后我会立即看到段错误:
#include <GLES2/gl2.h>
#include <EGL/egl.h>
int main(int argc, char *argv[])
{
EGLint ai32ContextAttribs[] = { EGL_CONTEXT_CLIENT_VERSION, 2,
EGL_NONE };
// Step 1 - Get the default display.
EGLDisplay eglDisplay = eglGetDisplay((EGLNativeDisplayType)0);
// Step 2 - Initialize EGL.
eglInitialize(eglDisplay, 0, 0);
// Step 3 - Make OpenGL ES the current API.
eglBindAPI(EGL_OPENGL_ES_API);
// Step 4 - Specify the required configuration attributes.
EGLint pi32ConfigAttribs[5];
pi32ConfigAttribs[0] = EGL_SURFACE_TYPE;
pi32ConfigAttribs[1] = EGL_WINDOW_BIT;
pi32ConfigAttribs[2] = EGL_RENDERABLE_TYPE;
pi32ConfigAttribs[3] = EGL_OPENGL_ES2_BIT;
pi32ConfigAttribs[4] = EGL_NONE;
// Step 5 - Find a config that matches all requirements.
int iConfigs;
EGLConfig eglConfig;
eglChooseConfig(eglDisplay, pi32ConfigAttribs, &eglConfig, 1, &iConfigs);
if (iConfigs != 1)
{
printf("Error: eglChooseConfig(): config not found.\n");
exit(-1);
}
// Step 6 - Create a surface to draw to.
EGLSurface eglSurface;
eglSurface = eglCreatePbufferSurface(eglDisplay, eglConfig, NULL);
// Step 7 - Create a context.
EGLContext eglContext;
eglContext = eglCreateContext(eglDisplay, eglConfig, NULL, ai32ContextAttribs);
// Step 8 - Bind the context to the current thread
eglMakeCurrent(eglDisplay, eglSurface, eglSurface, eglContext);
int size = 4 * renderBufferHeight * renderBufferWidth;
unsigned char *data2 = new unsigned char[size];
// Step 11 - clear the screen in Red and read it back
glClearColor(1.0,0.0,0.0,1.0);
glClear(GL_COLOR_BUFFER_BIT);
eglSwapBuffers( eglDisplay, eglSurface);
glReadPixels(0,0,renderBufferWidth,renderBufferHeight,GL_RGBA, GL_UNSIGNED_BYTE, data2);
... save data2 to image ...
}
我的环境是带有 intel Graphics/mesa 的 ubuntu 14。
你知道为什么我看到段错误吗? (我检查了eglcontext,似乎创建成功。)您能确认pbuffer surface需要fbo吗?
编辑:正如 Reto 所指出的,我的问题是因为缺少属性。
设置这些属性后,我能够在 opengl es 2 上下文中正常工作。但是,我仍然对桌面 opengl 上下文存在问题。
使用桌面 opengl 上下文,我只能得到透明图像,而不是读回红色图像。这是我当前的代码:
#include <QCoreApplication>
#include <QDebug>
#include <QImage>
#include <GL/gl.h>
#include <EGL/egl.h>
#include <QElapsedTimer>
int main(int argc, char *argv[])
{
// Step 1 - Get the default display.
EGLDisplay eglDisplay = eglGetDisplay((EGLNativeDisplayType)0);
// Step 2 - Initialize EGL.
eglInitialize(eglDisplay, 0, 0);
// Step 3 - Make OpenGL ES the current API.
eglBindAPI(EGL_OPENGL_API);
// Step 4 - Specify the required configuration attributes.
EGLint pi32ConfigAttribs[5];
pi32ConfigAttribs[0] = EGL_SURFACE_TYPE;
pi32ConfigAttribs[1] = EGL_PBUFFER_BIT;
pi32ConfigAttribs[2] = EGL_RENDERABLE_TYPE;
pi32ConfigAttribs[3] = EGL_OPENGL_BIT;
pi32ConfigAttribs[4] = EGL_CONFORMANT;
pi32ConfigAttribs[5] = EGL_OPENGL_BIT;
pi32ConfigAttribs[6] = EGL_COLOR_BUFFER_TYPE;
pi32ConfigAttribs[7] = EGL_RGB_BUFFER;
pi32ConfigAttribs[8] = EGL_LUMINANCE_SIZE;
pi32ConfigAttribs[9] = 0;
pi32ConfigAttribs[10] = EGL_RED_SIZE;
pi32ConfigAttribs[11] = 8;
pi32ConfigAttribs[12] = EGL_GREEN_SIZE;
pi32ConfigAttribs[13] = 8;
pi32ConfigAttribs[14] = EGL_BLUE_SIZE;
pi32ConfigAttribs[15] = 8;
pi32ConfigAttribs[16] = EGL_ALPHA_SIZE;
pi32ConfigAttribs[17] = 8;
pi32ConfigAttribs[18] = EGL_DEPTH_SIZE;
pi32ConfigAttribs[19] = 8;
pi32ConfigAttribs[20] = EGL_LEVEL;
pi32ConfigAttribs[21] = 0;
pi32ConfigAttribs[22] = EGL_BUFFER_SIZE;
pi32ConfigAttribs[23] = 24;
pi32ConfigAttribs[24] = EGL_NONE;
// Step 5 - Find a config that matches all requirements.
int iConfigs;
EGLConfig eglConfig;
eglChooseConfig(eglDisplay, pi32ConfigAttribs, &eglConfig, 1, &iConfigs);
qDebug() << "egl error" << eglGetError();
if (iConfigs != 1)
{
printf("Error: eglChooseConfig(): config not found.\n");
exit(-1);
}
EGLint pbufferAttribs[5];
pbufferAttribs[0] = EGL_WIDTH;
pbufferAttribs[1] = 1920;
pbufferAttribs[2] = EGL_HEIGHT;
pbufferAttribs[3] = 1080;
pbufferAttribs[4] = EGL_NONE;
// Step 6 - Create a surface to draw to.
EGLSurface eglSurface;
eglSurface = eglCreatePbufferSurface(eglDisplay, eglConfig, pbufferAttribs);
qDebug() << "egl error" << eglGetError();
if (eglSurface == EGL_NO_SURFACE)
{
qDebug() << "surface issue";
}
// Step 7 - Create a context.
EGLContext eglContext;
eglContext = eglCreateContext(eglDisplay, eglConfig, NULL, NULL);
qDebug() << "egl error" << eglGetError();
if (eglContext == EGL_NO_CONTEXT)
{
qDebug() << "context issue";
}
// Step 8 - Bind the context to the current thread
bool result = eglMakeCurrent(eglDisplay, eglSurface, eglSurface, eglContext);
if (!result)
{
qDebug() << "make current error" << eglGetError();
}
qDebug() << "egl error" << eglGetError();
GLuint renderBufferWidth = 1920;
GLuint renderBufferHeight = 1080;
QElapsedTimer benchmarkTimer;
int size = 4 * renderBufferHeight * renderBufferWidth;
unsigned char *data2 = new unsigned char[size];
int i = 0;
benchmarkTimer.start();
while(i<1000)
{
glClearColor(1.0,0.0,0.0,1.0);
glClear(GL_COLOR_BUFFER_BIT);
eglSwapBuffers( eglDisplay, eglSurface);
glReadPixels(0,0,renderBufferWidth,renderBufferHeight,GL_RGBA, GL_UNSIGNED_BYTE, data2);
++i;
}
qDebug() << "fps" << 1000.0*1000.0/benchmarkTimer.elapsed();
QImage saveImage(data2, renderBufferWidth, renderBufferHeight, QImage::Format_RGBA8888_Premultiplied);
saveImage.save("haha.png");
QCoreApplication a(argc, argv);
qDebug() << "done";
return a.exec();
}
最佳答案
这段代码有几个问题:
配置属性中指定的 EGL_SURFACE_TYPE
错误:
pi32ConfigAttribs[0] = EGL_SURFACE_TYPE;
pi32ConfigAttribs[1] = EGL_WINDOW_BIT;
要渲染到 PBuffer,需要使用匹配的值:
pi32ConfigAttribs[0] = EGL_SURFACE_TYPE;
pi32ConfigAttribs[1] = EGL_PBUFFER_BIT;
未指定 PBuffer 的大小。而man page表明在不指定大小的情况下创建 PBuffer 是合法的,宽度和高度的默认值为 0。我无法想象当尝试渲染到大小为 0 乘以 0 的表面时会发生什么好事。要指定大小:
EGLint pbufferAttribs[5];
pbufferAttribs[0] = EGL_WIDTH;
pbufferAttribs[1] = DesiredWidthOfPBuffer;
pbufferAttribs[2] = EGL_HEIGHT;
pbufferAttribs[3] = DesiredHeightOfPBuffer;
pbufferAttribs[4] = EGL_NONE;
eglSurface = eglCreatePbufferSurface(eglDisplay, eglConfig, pbufferAttribs);
我对这个问题的回答包含为两个不同版本的 EGL 创建上下文和 PBuffer 表面的完整代码:GLES10.glGetIntegerv returns 0 in Lollipop only 。该代码使用 Java 绑定(bind),但应该很容易适应。
关于opengl-es - eGL 离屏渲染中的 pbuffer 与 fbo,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28817777/
我已经编译了 SDL 2.0 源代码。 首先,我在控制台上推荐了 'cmake ../-G "MinGW Makefiles"。 其次,我赞扬了“制造”。但发生错误。 fatal error: EGL
我正在用 opengl 和 java/android 做一些工作。我在 C++ 中有一些代码,并且正在使用 JNI 在两者之间进行交互。我得到结果: D/App ( 2966): eglGet
我正在尝试通过指定 eglfs 平台在没有 X Server 的情况下运行 hellogl_es2 Qt 示例: ./hellogl_es2 -platform eglfs EGL Error : C
版本情况如下 CUDA版本:10.2 tensorrt版本:8.0.1.6 JetPack版本:32.6.1 deepstream版本:6.0 官网的系统版本适配图如下: 通过对比发现:我的版本是没有
我想实现一个生成图像的opengl应用程序,并通过网页查看图像。 该应用程序旨在运行在没有显示器、没有 x 窗口但具有 gpu 的 linux 服务器上。 我知道 egl 可以使用 pixmap 或
考虑到上下文句柄从 main() 传递给线程的函数,是否允许从 main() 创建 egl 上下文并从另一个线程渲染? 最佳答案 是的,肯定是。 首先,您需要在一个线程中创建一个上下文: EGL
关闭。这个问题不满足Stack Overflow guidelines .它目前不接受答案。 想改善这个问题吗?更新问题,使其成为 on-topic对于堆栈溢出。 5年前关闭。 Improve thi
我正在尝试在 Ubuntu Trusty 系统上使用 g++ 4.9.1 链接一个非常简单的 GLES2 和 EGL 程序。我正在使用台面库。 我收到 EGL 函数的链接器错误: test.cpp:(
EGL 看起来是有史以来记录最差的 Khronos 项目,我确实找不到关于这个项目的任何具体信息,但它看起来很有希望,最后有一个标准化的 GLUT/FreeGlut 替代方案。 我的观点是,假设我想要
我有一个包含两个 Activity 的 Android 项目。一个是我的主要 Activity ,使用从 native 代码更新的 GLSurfaceView。另一个是 PurchaseActivit
setPreserveEGLContextOnPause Android 函数的文档说明如下: “...如果设置为 true,那么当 GLSurfaceView 暂停时,EGL 上下文可能会被保留..
对于那些处理过 EGL(精英游戏阶梯)锦标赛和阶梯脚本的人...我在弄清楚如何为我制作的自定义模组添加新的组权限时遇到了问题。我创建了一种新型的“一般规则”模组,我想存储权限,如下所示: case "
我在少数设备上遇到以下崩溃,代码在少数设备上运行良好。我不明白是哪部分代码造成了这次崩溃。几天前它工作正常,突然间我看到了这次崩溃。谁能告诉我是什么导致了这次崩溃。请帮助我 堆栈轨迹如下: java.
看起来 EGL 将成为将“GUI 窗口”连接到图形服务器的下一个最流行的标准,我的问题是:有一个 GUI 框架,可能是在 C++ 中,它能够在EGL 的顶部? 出于不同的原因,我将 GTK、QT、Wx
目前我转换 eglGetError() 结果的函数如下所示: std::string eglErrorString(EGLint error) { switch(error) {
我在 Cloudbees 上设置了一个 Jenkins Job,我可以在那里成功地 checkout 和编译我的 Android 项目。现在我想在 android 模拟器中运行一些 JUnit 测试并
在 OpenGL ES 中,我可以使用扩展名为 GL_EXT_sRGB 的 OpenGL ES 3.0 或 OpenGL ES 2.0 创建 sRGB 渲染缓冲区。我创建了一个内部格式为 GL_SRG
任何人都可以向我解释什么是 EGL 以及它的作用吗? 我如何在 Linux 上将 EGL 与 OpenGL-ES 结合使用? EGL 是硬件和操作系统之间的一层吗? 最佳答案 EGL是独立于窗口系统的
此代码在没有抗锯齿 (samples=0) 时呈现彩色三角形。但是,当我打开抗锯齿 (samples=1...32) 时,它无法呈现任何内容。如何使其与抗锯齿一起使用?也许我无法直接从多重采样 fbo
我正在尝试对我正在解决的问题进行服务器端渲染。 EGL 提供了一种无需窗口系统即可定义 OpenGL 上下文的方法。我已经能够在笔记本电脑上使用 EGL 成功地离屏渲染,但是当我尝试在 digital
我是一名优秀的程序员,十分优秀!