Raspberry
에 OpenGL ES 2
을 사용하여 나중에 CPU를 통해 추가 처리를 위해 메모리에있는 버퍼에 RGB 픽셀 값이 저장되는 사각형을 그립니다.OpenGL을 사용하여 시스템 RAM에 텍스처 그리기 및 매핑
즉, 이것은 RAM의 RGB 버퍼 -> GPU의 텍스처 -> 그리기 -> RAM으로 되돌아가는 경로입니다. 결국, 다음과 같은 간단한 프로그램을 읽음으로써 내가하고 싶은 일이 분명 해져야합니다.
나는 기본적으로 eglCreateImageKHR
통해 EGLImage
컨텍스트를 생성하여이 작업을 수행하려고 노력하지만, 프로그램합니다 (GLCHK
매크로에서 주장에서) 오류 0x501
실패 : 코드에서 문제
#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();
}