2012-09-30 19 views
7

के लिए ओपनजीएल ES2.0 ऑफस्क्रीन संदर्भ एफबीओ के साथ मैं ऑफस्क्रीन प्रतिपादन (बिना किसी डब्ल्यूएस के कंसोल पर्यावरण में) करना चाहता हूं। मुझे पता है कि यह एक ओपन संदर्भ बनाने के लिए आवश्यक है, और कम से कम किसी भी ऑपरेशन के लिए एक डमी खिड़की, इसलिए मैं निम्नलिखित आरंभ किया:एफबीओ प्रतिपादन

// Step 1 - Get the default display. 
eglDisplay = eglGetDisplay((EGLNativeDisplayType)0); 

// Step 2 - Initialize EGL. 
EGLint iMajorVersion, iMinorVersion; 
if (!eglInitialize(eglDisplay, &iMajorVersion, &iMinorVersion)) 
{ 
    printf("Error: eglInitialize() failed.\n"); 
    goto cleanup; 
} 

// Step 3 - Make OpenGL ES the current API. 
eglBindAPI(EGL_OPENGL_ES_API); 
if (!TestEGLError("eglBindAPI")) 
{ 
    goto cleanup; 
} 

// 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; 
if (!eglChooseConfig(eglDisplay, pi32ConfigAttribs, &eglConfig, 1, &iConfigs) || (iConfigs != 1)) 
{ 
    printf("Error: eglChooseConfig() failed.\n"); 
    goto cleanup; 
} 

// Step 6 - Create a surface to draw to. 
EGLSurface eglSurface; 
eglSurface = eglCreateWindowSurface(eglDisplay, eglConfig, (EGLNativeWindowType)NULL, NULL); 
if (!TestEGLError("eglCreateWindowSurface")) goto cleanup; 

// Step 7 - Create a context. 
eglContext = eglCreateContext(eglDisplay, eglConfig, NULL, ai32ContextAttribs); 
if (!TestEGLError("eglCreateContext")) goto cleanup; 

// Step 8 - Bind the context to the current thread 
eglMakeCurrent(eglDisplay, eglSurface, eglSurface, eglContext); 
if (!TestEGLError("eglMakeCurrent")) goto cleanup; 

आरंभीकरण के इस प्रकार के लक्ष्य सिस्टम पर काम करता है, लेकिन अगर मैं एफबीओ में कुछ खींचें, और इसे वापस पढ़ने के बाद (getReadPixels) हमेशा एक काला छवि प्राप्त करें। मैंने X11 से ऊपर एक ही कोड का प्रयास किया है, जहां यह (पहले से) त्रुटि के साथ eglCreateWindowSurface कॉल पर विफल रहता है: EGL_BAD_NATIVE_WINDOW वर्क्स, लेकिन यह काम करता है अगर मैं इस कॉल को वास्तविक X11window देशी विंडो हैंडलर (इस मामले में मैं मान्य प्रस्तुत कर सकता हूं छवि भी)

कृपया मुझे स्पष्टीकरण दें कि मुझे एफबीओ प्रतिपादन के लिए किस प्रकार की सतह का उपयोग करने की आवश्यकता है ?? या मैं गलत क्या करूँ ??

शेष ड्राइंग कोड: // init और opengl es shanders शुरू करें Shaders_Init();

{ 
    // create a framebuffer object 
    glGenFramebuffers(1, &fboId); 
    glBindFramebuffer(GL_FRAMEBUFFER, fboId); 

    // create a texture object 
    GLuint textureId; 
    glGenTextures(1, &textureId); 
    glBindTexture(GL_TEXTURE_2D, textureId); 
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); //GL_LINEAR_MIPMAP_LINEAR 
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); 
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 
    //glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP_HINT, GL_TRUE); // automatic mipmap 
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, renderBufferWidth, renderBufferHeight, 0, 
        GL_RGB, GL_UNSIGNED_BYTE, 0); 
    //glBindTexture(GL_TEXTURE_2D, 0); 


    // attach the texture to FBO color attachment point 
    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, 
          GL_TEXTURE_2D, textureId, 0); 

    // 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"); 
    } 
} 





// Sets the clear color. 
// The colours are passed per channel (red,green,blue,alpha) as float values from 0.0 to 1.0 
glClearColor(0.6f, 0.8f, 1.0f, 1.0f); // clear blue 

// We're going to draw a triangle to the screen so create a vertex buffer object for our triangle 
{ 
    // Interleaved vertex data 
    GLfloat afVertices[] = { -0.4f,-0.4f,0.0f, // Position 
          0.4f ,-0.4f,0.0f, 
          0.0f ,0.4f ,0.0f}; 
    // Generate the vertex buffer object (VBO) 
    glGenBuffers(1, &ui32Vbo); 

    // Bind the VBO so we can fill it with data 
    glBindBuffer(GL_ARRAY_BUFFER, ui32Vbo); 

    // Set the buffer's data 
    unsigned int uiSize = 3 * (sizeof(GLfloat) * 3); // Calc afVertices size (3 vertices * stride (3 GLfloats per vertex)) 
    glBufferData(GL_ARRAY_BUFFER, uiSize, afVertices, GL_STATIC_DRAW); 
} 

// Draw a triangle 
{ 
    glClear(GL_COLOR_BUFFER_BIT); 
    if (!TestEGLError("glClear")) goto cleanup; 



    // First gets the location of that variable in the shader using its name 
    int i32Location = glGetUniformLocation(uiProgramObject, "myPMVMatrix"); 

    // Then passes the matrix to that variable 
    glUniformMatrix4fv(i32Location, 1, GL_FALSE, pfIdentity); 

    /* 
     Enable the custom vertex attribute at index VERTEX_ARRAY. 
     We previously binded that index to the variable in our shader "vec4 MyVertex;" 
    */ 
    glEnableVertexAttribArray(VERTEX_ARRAY); 

    // Sets the vertex data to this attribute index 
    glVertexAttribPointer(VERTEX_ARRAY, 3, GL_FLOAT, GL_FALSE, 0, 0); 

    /* 
     Draws a non-indexed triangle array from the pointers previously given. 
     This function allows the use of other primitive types : triangle strips, lines, ... 
     For indexed geometry, use the function glDrawElements() with an index list. 
    */ 
    glDrawArrays(GL_TRIANGLES, 0, 3); 
    if (!TestEGLError("glDrawArrays")) goto cleanup; 

     // get the image data 
     long imageSize = x * y * 3; 
     unsigned char *data = new unsigned char[imageSize]; 
     glReadPixels(0,0,x,y,GL_RGB,GL_UNSIGNED_BYTE,data); 

अग्रिम धन्यवाद !!!!! सादर, गेज़ा

उत्तर

2

समाधान किया गया था निम्नलिखित (त्रुटि हैंडलिंग के बिना):

#ifdef CONTEXT_ES20 
    EGLint ai32ContextAttribs[] = { EGL_CONTEXT_CLIENT_VERSION, 2, 
                  EGL_NONE }; 
    #endif 

// Step 1 - Get the default display. 
    eglDisplay = eglGetDisplay((EGLNativeDisplayType)0); 

// Step 2 - Initialize EGL. 
    eglInitialize(eglDisplay, 0, 0); 

    #ifdef CONTEXT_ES20 
// 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; 
    #else 
    EGLint pi32ConfigAttribs[3]; 
    pi32ConfigAttribs[0] = EGL_SURFACE_TYPE; 
    pi32ConfigAttribs[1] = EGL_WINDOW_BIT; 
    pi32ConfigAttribs[2] = EGL_NONE; 
    #endif 

// Step 5 - Find a config that matches all requirements. 
    int iConfigs; 
    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 = eglCreateWindowSurface(eglDisplay, eglConfig, 
             (EGLNativeWindowType)NULL, NULL); 

// Step 7 - Create a context. 
    #ifdef CONTEXT_ES20 
    eglContext = eglCreateContext(eglDisplay, eglConfig, NULL, 
                ai32ContextAttribs); 
    #else 
    eglContext = eglCreateContext(eglDisplay, eglConfig, NULL, NULL); 
    #endif 

// Step 8 - Bind the context to the current thread 
    eglMakeCurrent(eglDisplay, eglSurface, eglSurface, eglContext); 
+0

जो eglSurface और eglContext के बीच एक पहले बनाने की जानी चाहिए? – chengpei

+1

क्या आप समझा सकते हैं कि आपके पहले कार्यान्वयन में क्या गलत है? मुझे कोई अंतर नहीं दिख रहा है। –

संबंधित मुद्दे