我想在我的OpenGL ES 2
上使用Raspberry
绘制一个矩形,其RGB像素值将存储在内存中的缓冲区中,以便通过CPU进行进一步处理。
换句话说,这是路径:RAM中的RGB缓冲区 - > GPU上的纹理 - >画 - >回到RAM。最后,通过阅读以下简单程序,我想要做的事情应该是清楚的。
我试图通过EGLImage
创建eglCreateImageKHR
上下文来实现此目的,但程序失败并显示错误0x501
(来自GLCHK
宏的断言) :
#include <bcm_host.h>
#include <GLES2/gl2.h>
#include <GLES2/gl2ext.h>
#include <EGL/egl.h>
#include <iostream>
#include <stdexcept>
#include <cassert>
#include <system_error>
#include <memory>
/* Uncomment to enable extra GL error checking */
#define CHECK_GL_ERRORS
#if defined(CHECK_GL_ERRORS)
#define GLCHK(X) \
do { \
GLenum err = GL_NO_ERROR; \
X; \
while ((err = glGetError())) \
{ \
std::cout << "GL error " << err << " in file " << __FILE__<< ", line " << __LINE__ << ' '; \
assert(err == GL_NO_ERROR); \
exit(err); \
} \
} \
while(0)
#else
#define GLCHK(X) X
#endif /* CHECK_GL_ERRORS */
void demo() {
EGLDisplay eglDisplay = 0;
EGLConfig eglConfigWindow = 0;
EGLSurface eglSurfacePbuffer = 0;
EGLContext eglContext = 0;
const EGLint attribListWindow[] = {
EGL_SURFACE_TYPE, EGL_PBUFFER_BIT,
EGL_RED_SIZE, 8,
EGL_GREEN_SIZE, 8,
EGL_BLUE_SIZE, 8,
EGL_ALPHA_SIZE, 8,
EGL_DEPTH_SIZE, 16,
EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
EGL_NONE
};
const EGLint srfPbufferAttr[] = {
EGL_WIDTH, 640,
EGL_HEIGHT, 480,
EGL_NONE
};
const EGLint context_attribs[] = {
EGL_CONTEXT_CLIENT_VERSION, 1,
EGL_NONE
};
EGLint iMajorVersion, iMinorVersion;
int iConfigs;
eglDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);
if (eglDisplay == EGL_NO_DISPLAY)
throw std::runtime_error {"error eglGetDisaply()"};
auto result = eglInitialize(eglDisplay, &iMajorVersion, &iMinorVersion);
if (result == EGL_FALSE)
throw std::runtime_error {"error eglInitialize()"};
//result = eglChooseConfig(eglDisplay, attribListPbuffer, &eglConfigWindow, 1, &iConfigs);
result = eglChooseConfig(eglDisplay, attribListWindow, &eglConfigWindow, 1, &iConfigs);
if (result == EGL_FALSE)
throw std::system_error(result, std::generic_category(), "Error setting configuration for the given display: check your settings");
auto context = eglContext = eglCreateContext(eglDisplay, eglConfigWindow, EGL_NO_CONTEXT, context_attribs);
if (context == EGL_NO_CONTEXT)
throw std::runtime_error{"error eglCreateContext()"};
eglSurfacePbuffer = eglCreatePbufferSurface(eglDisplay, eglConfigWindow, srfPbufferAttr);
if (eglSurfacePbuffer == EGL_NO_SURFACE)
throw std::runtime_error{"error CreatePbufferSurface(). " + std::to_string(eglGetError())};
eglMakeCurrent(eglDisplay, eglSurfacePbuffer, eglSurfacePbuffer, eglContext);
GLuint texture; // Name for the preview texture
EGLImageKHR egl_image = EGL_NO_IMAGE_KHR; // The current preview EGL image
glClearColor(0x11, 0x22, 0x33, 0); // random color
glClearDepthf(1);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
const int bytes_per_pixel = 4;
unsigned char buffer[640 * 480 * bytes_per_pixel] = {}; // 0x77 to see if it will be changed somehow
GLCHK(glBindTexture(GL_TEXTURE_EXTERNAL_OES, texture));
egl_image = eglCreateImageKHR(eglDisplay, EGL_NO_CONTEXT, EGL_IMAGE_BRCM_MULTIMEDIA, (EGLClientBuffer) buffer, NULL);
GLCHK(glEGLImageTargetTexture2DOES(GL_TEXTURE_EXTERNAL_OES, &egl_image));
glReadPixels(0, 0, 640, 480, GL_RGBA, GL_UNSIGNED_BYTE, buffer);
if (glGetError() != GL_NO_ERROR)
throw std::runtime_error{"error glReadPixels():" + std::to_string(eglGetError())};
eglSwapBuffers(eglDisplay, eglSurfacePbuffer);
// print the buffer pixel values, should be different from 0x00
for (auto x : buffer)
std::cout << std::hex << int(x) << ' ';
// Terminate
/* Delete OES textures */
glDeleteTextures(1, &texture);
eglDestroyImageKHR(eglDisplay, egl_image);
egl_image = EGL_NO_IMAGE_KHR;
/* Terminate EGL */
eglMakeCurrent(eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
eglDestroyContext(eglDisplay, context);
eglDestroySurface(eglDisplay, eglSurfacePbuffer);
eglTerminate(eglDisplay);
}
int main() {
atexit(bcm_host_deinit);
bcm_host_init();
demo();
}
答案 0 :(得分:0)
代码中的一些问题。您正在请求ES 1.0上下文,而代码中的其他内容以及您的问题表明您计划使用ES 2.0:
const EGLint context_attribs[] = {
EGL_CONTEXT_CLIENT_VERSION, 1,
EGL_NONE
};
ES 2.0需要客户端版本2.
最直接的问题是您使用未初始化的texture
变量:
GLuint texture; // Name for the preview texture
...
GLCHK(glBindTexture(GL_TEXTURE_EXTERNAL_OES, texture));
这两个语句之间没有设置 texture
。您需要glGenTextures(1, &texture)
来创建有效的纹理ID。