2012-09-30 79 views
7

FBOを使用したオフスクリーンレンダリング(WSなしのコンソール環境)を行いたいと思います。 私はOpenGLコンテキストを作成する必要があることを知っているし、すべての操作のための少なくともダミー窓、したがって、私は次の初期化をした:I場合FBOレンダリングのためのOpenGL 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; 

初期のこのタイプは、ターゲットシステム上で動作しますが、何かをFBOに描画し、それを読み込んだ後(getReadPixels)は常に黒い画像しか取得しません。 X11の上に同じコードを試しましたが、エラーが発生したeglCreateWindowSurface呼び出しでエラーが発生しました:EGL_BAD_NATIVE_WINDOWは動作しますが、この呼び出しに実際のX11windowネイティブウィンドウハンドラを渡すと動作します(このケースでは、画像も)

FBOレンダリングにはどのようなサーフェスを使用する必要がありますか? または何が間違っていますか?

残りの描画コード: // initおよびstart 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

溶液は、(エラー処理なし)下記た:eglSurfaceとeglContext間の1つが最初に作成されるべきである

#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

? – chengpei

+1

最初の実装で何が問題なのか説明できますか?私は違いを見ることができません。 –

関連する問題