Androidネイティブコード(NDK)のOpenGL ES 2.0 FrameBuffer(FBO)とステンシルの使用
-
13-11-2019 - |
質問
FramBufferオブジェクトを生成し、NDK(R5b)を使用してネイティブのAndroidアプリケーション内でステンシルを使用しようとしています。ターゲットデバイスは、OpenGL ES 2.0をサポートするFroyo 2.2を実行しています。
だから、私は私のC ++ネイティブのlibsで多くの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);
}
.
RenderBufferの代わりに2Dテクスチャにレンダリングしようとしました...
だから、私がこれを修正できる方法はありますか?私はここで何か悪いものを得ていますか?誰かがいかなるアイデアも持っていれば、知っています....この問題を見上げて過ごす時間を過ごしています... hehe;)
事前にありがとう!
歓声!
編集:
OK、ステンシルバッファーの作業を行うことを管理しますが、FBOは動作していません。 OpenGL ES 2.0はAndroidで完全にサポートされていないと思います(ここではR5Bを使用してください)。メソッドスタブが定義されていますが、完全には実装されていません。または作成されたGlSurfaceViewがFBOSと正しくリンクされません。
ステンシルバッファーは、をしなければなりませんでした
glEnable(GL_DEPTH_TEST);
.
とgldepthmaskの使用法を正しく機能させるために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);
}
.
そして最後に私はステンシルの中を描くためにダブルパス技術をしています...ここは例です:
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();
.
私のコードはかなり複雑ですので、ステンシルに関連するものだけを投稿するのは難しいですが、それが手助けすることを願っています;)