gpt4 book ai didi

android - 在 android native 代码 (ndk) 中使用 OpenGL ES 2.0 FrameBuffer (FBO) 和 Stencil

转载 作者:塔克拉玛干 更新时间:2023-11-02 22:59:12 26 4
gpt4 key购买 nike

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

所以,我一直在我的 c++ native 库中编写大量 gl 代码,除此之外没有解决任何问题。我似乎无法让它发挥作用。

这是创建帧缓冲区的代码 fragment 。完整性都很好,但屏幕仍然完全黑色。这就像我正在创建的 fbo 并没有真正绑定(bind)到由应用程序的 Java 部分创建的 gl 表面。我的应用程序代码的其余部分都很好,如果我删除 fbo 创建和绑定(bind),一切都运行良好,除了我没有我的应用程序所需的模板。

    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)。我认为方法 stub 已定义,但未完全实现。或者创建的 GlSurfaceView 没有与 FBO 正确链接。

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

glEnable(GL_DEPTH_TEST);

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

最佳答案

@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);
}

最后,我使用双 channel 技术在模板内部绘制...这是一个示例:

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

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

关于android - 在 android native 代码 (ndk) 中使用 OpenGL ES 2.0 FrameBuffer (FBO) 和 Stencil,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5993634/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com