【问题标题】:Using OpenGL ES 2.0 FrameBuffer (FBO) and Stencil in android Native code (ndk)在 android Native 代码 (ndk) 中使用 OpenGL ES 2.0 FrameBuffer (FBO) 和 Stencil
【发布时间】:2011-08-25 00:25:41
【问题描述】:

我正在尝试使用 NDK (r5b) 生成一个帧缓冲区对象并在本机 android 应用程序中使用模板。目标设备运行 froyo 2.2,支持 OpenGL ES 2.0。

所以,我一直在我的 c++ 本机库中编写大量 gl 代码,除此之外没有遇到任何问题。我似乎无法让它工作。

这是用于创建帧缓冲区的代码片段。完整性很好,但屏幕仍然完全黑。就像我正在创建的 fbo 并没有真正绑定到由应用程序的 Java 部分创建的 gl 表面。我的应用程序代码的其余部分都很好,如果我删除了 fbo 创建和绑定,一切都可以正常工作,除了我没有我的应用程序需要的模板工作。

    GLint backingWidth = 1024;
      GLint backingHeight = 1024;


    //Create the FrameBuffer and binds it
    glGenFramebuffers(1, &_defaultFramebuffer);
    checkGlError("glGenFramebuffers");
    glBindFramebuffer(GL_FRAMEBUFFER, _defaultFramebuffer);
    checkGlError("glBindFramebuffer");

    //Create the RenderBuffer for offscreen rendering // Color
    glGenRenderbuffers(1, &_colorRenderbuffer);
    checkGlError("glGenRenderbuffers color");
    glBindRenderbuffer(GL_RENDERBUFFER, _colorRenderbuffer);
    checkGlError("glBindRenderbuffer color");
    glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA4, backingWidth, backingHeight);
    checkGlError("glRenderbufferStorage color");

    //Create the RenderBuffer for offscreen rendering // Depth
    glGenRenderbuffers(1, &_depthRenderbuffer);
    checkGlError("glGenRenderbuffers depth");
    glBindRenderbuffer(GL_RENDERBUFFER, _depthRenderbuffer);
    checkGlError("glBindRenderbuffer depth");
    glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, backingWidth, backingHeight);
    checkGlError("glRenderbufferStorage depth");

    //Create the RenderBuffer for offscreen rendering // Stencil
    glGenRenderbuffers(1, &_stencilRenderbuffer);
    checkGlError("glGenRenderbuffers stencil");
    glBindRenderbuffer(GL_RENDERBUFFER, _stencilRenderbuffer);
    checkGlError("glBindRenderbuffer stencil");
    glRenderbufferStorage(GL_RENDERBUFFER, GL_STENCIL_INDEX8, backingWidth, backingHeight);
    checkGlError("glRenderbufferStorage stencil");

    // bind renderbuffers to framebuffer object
    glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, _depthRenderbuffer);
    checkGlError("glFramebufferRenderbuffer depth");
    glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, _colorRenderbuffer);
    checkGlError("glFramebufferRenderbuffer color");
    glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, _stencilRenderbuffer);
    checkGlError("glFramebufferRenderbuffer stencil");

//Test for FrameBuffer completeness
    GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
    checkGlError("glCheckFramebufferStatus");
    switch (status)
    {
    case GL_FRAMEBUFFER_COMPLETE: LOGI("\n\n\nFLIPBOOM : FBO complete  GL_FRAMEBUFFER_COMPLETE %x\n\n\n", status);break;

    case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT: LOGI("\n\n\nFLIPBOOM : FBO GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT  %x\n\n\n", status);break;

    case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT: LOGI("\n\n\nFLIPBOOM : FBO FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT  %x\n\n\n", status);break;

    case GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS: LOGI("\n\n\nFLIPBOOM : FBO FRAMEBUFFER_INCOMPLETE_DIMENSIONS  %x\n\n\n", status);break;

    case GL_FRAMEBUFFER_UNSUPPORTED: LOGI("\n\n\nFLIPBOOM : FBO GL_FRAMEBUFFER_UNSUPPORTED  %x\n\n\n", status);break;

    default : LOGI("\n\n\nFLIPBOOM : failed to make complete framebuffer object %x\n\n\n", status);
    }

我也尝试过渲染到 2D 纹理而不是渲染缓冲区...也没有用。

那么,有什么办法可以解决这个问题吗?我这里有什么问题吗?如果有人有任何想法,请让我知道....花了太多时间查找这个问题...呵呵;)

提前致谢!

干杯!


编辑:

好的,我已设法使模板缓冲区正常工作,但 FBO 无法正常工作。我认为android不完全支持OpenGL ES 2.0(顺便说一句,这里使用r5b)。我认为方法存根已定义,但未完全实现。或者创建的 GlSurfaceView 没有与 FBO 正确链接。

至于模板缓冲区,我不得不这样做

glEnable(GL_DEPTH_TEST);

并删除 glDepthMask 的使用,以便它们正常工作。

【问题讨论】:

    标签: android android-ndk framebuffer stencil-buffer stencils


    【解决方案1】:

    @ Zennichimaro,关于模板缓冲区的使用!

    初始化期间:

    glBindFramebuffer(GL_FRAMEBUFFER, 0);
    glEnable(GL_DEPTH_TEST);
    

    渲染过程中:

    glViewport(0, 0, GetViewWidth(), GetViewHeight());
    checkGlError("glViewport");
    
    if (_firstRenderDone == false)
    {
        glClearDepthf( 0.9f );
        glDepthMask( GL_TRUE );
        glClear( GL_DEPTH_BUFFER_BIT );
        glDepthMask( GL_FALSE );
        _firstRenderDone = true;
    }
    
    glClearColor(M_channelToFloat(_backgroundColor.r),
                   M_channelToFloat(_backgroundColor.g),
                   M_channelToFloat(_backgroundColor.b),
                   M_channelToFloat(_backgroundColor.a));
    checkGlError("glClearColor");
    glClearStencil( 0 );
    checkGlError("glClearStencil");
    glClear( GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT );
    checkGlError("glClear");
    
    _stencilLayer = 1;
    
    //use our custom shaders
    if( _program )
    {
        glUseProgram(_program);
    
    
        if( transformMatrix3x3 != NULL )
        {
            glUniformMatrix3fv( _uniforms[OGL_UNIFORM_TRANSFORM], 1, false, transformMatrix3x3 );
        }
    
         // reset the shading.
        glUniform1f( _uniforms[ OGL_UNIFORM_SHADE ], 0.0f );
    }
    
    
    //Do the actual drawing (Triangle Slip)
     if( object )
      {
         _isRender = true;
        object->OglDraw(this);
        _isRender = false;
      }
    

    当我需要使用模板时,我会根据需要使用以下方法:

    void GlEs2Renderer::StencilStartMask()
    {
    if (!USE_STENCIL)   //For debugging purpose
        return;
    
    
    glEnable(GL_STENCIL_TEST);
    
    //Turn off writing to the Color Buffer and Depth Buffer
    //We want to draw to the Stencil Buffer only
    glColorMask( GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE );
    
    //Set 1 into the stencil buffer
    glStencilFunc( GL_ALWAYS, NewStencilLayer(), 0xFFFFFFFF );
    glStencilOp( GL_ZERO, GL_ZERO, GL_REPLACE );
    }
    
    void GlEs2Renderer::StencilUseMask()
    {
    if (!USE_STENCIL)   //For debugging purpose
            return;
    
    //Turn back on Color Buffer and Depth Buffer
    glColorMask( GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE );
    
    //Only write to the Stencil Buffer where 1 is set
    glStencilFunc( GL_EQUAL, StencilLayer(), 0xFFFFFFFF);
    
    //Keep the content of the Stencil Buffer
    glStencilOp( GL_KEEP, GL_KEEP, GL_KEEP );
    }
    
    void GlEs2Renderer::StencilOverlayMask()
    {
    if (!USE_STENCIL)   //For debugging purpose
            return;
    
    //Turn back on Color Buffer and Depth Buffer
    glColorMask( GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE );
    glDepthMask(true);
    
    //Only write to the Stencil Buffer where 1 is set
    glStencilFunc( GL_EQUAL, StencilLayer(), 0xFFFFFFFF);
    
    //Keep the content of the Stencil Buffer and increase when z passed
    glStencilOp(GL_KEEP, GL_KEEP, GL_INCR);
    }
    

    最后,我使用双通道技术在模板内部进行绘图...这是一个示例:

    glVertexAttribPointer(OGL_ATTRIB_VERTEX, 2, GL_FLOAT, 0, 0, _triangles);
    glEnableVertexAttribArray(OGL_ATTRIB_VERTEX);
    glVertexAttribPointer(OGL_ATTRIB_COLOR, 4, GL_UNSIGNED_BYTE, 1, 0, _colors);
    glEnableVertexAttribArray(OGL_ATTRIB_COLOR);
    
    glContext->StencilStartMask();
    glDrawArrays(GL_TRIANGLE_STRIP, 0, _nPoints);
    
    glContext->StencilUseMask();;
    glDrawArrays(GL_TRIANGLE_STRIP, 0, _nPoints);
    
    glContext->StencilEndMask();
    

    我的代码相当复杂,所以很难只发布与模具相关的内容,但我希望它会有所帮助;)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-01-24
      • 2016-08-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-09-14
      • 1970-01-01
      相关资源
      最近更新 更多