2014-05-21 3 views
0

RaspberryOpenGL 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(); 
} 

답변

0

커플.

const EGLint context_attribs[] = { 
    EGL_CONTEXT_CLIENT_VERSION, 1, 
    EGL_NONE 
}; 

당신은 ES 2.0 클라이언트 버전이 필요합니다 코드, 그리고 귀하의 질문에 다른 모든 것들, 당신은 ES 2.0을 사용하도록 계획하고 제안하는 동안, ES 1.0 컨텍스트를 요청하고 있습니다.

가장 직접적인 문제

당신이 texture 변수 초기화를 사용하는 것입니다 :

GLuint texture;       // Name for the preview texture 
... 
GLCHK(glBindTexture(GL_TEXTURE_EXTERNAL_OES, texture)); 

texture이 두 문 사이에 설정되어 있지 않습니다. 유효한 텍스처 ID를 만들려면 glGenTextures(1, &texture)이 필요합니다.

관련 문제