Android OpenGL ES模具缓冲区在特定设备上不工作

Android OpenGL ES模具缓冲区在特定设备上不工作,android,opengl-es,stencil-buffer,Android,Opengl Es,Stencil Buffer,我正在使用OpenGLES2.0,并使用一个模具缓冲区。下面是我制作的一个简单模具缓冲区演示的代码。模版只能在一台设备上正常工作 设备如下: Android 4.2.2、PowerVR SGX 544MP(GPU)、Allwinner A10平板电脑。(模具缓冲区在此设备上工作正常) Android 4.1.2,Adreno 225(GPU),Galaxy S III手机。(模具缓冲区不工作,一些模具的鬼影图像很少闪烁 Android 4.2.2、Mali-400MP(GPU)、Rockchip

我正在使用OpenGLES2.0,并使用一个模具缓冲区。下面是我制作的一个简单模具缓冲区演示的代码。模版只能在一台设备上正常工作

设备如下:

Android 4.2.2、PowerVR SGX 544MP(GPU)、Allwinner A10平板电脑。(模具缓冲区在此设备上工作正常)

Android 4.1.2,Adreno 225(GPU),Galaxy S III手机。(模具缓冲区不工作,一些模具的鬼影图像很少闪烁

Android 4.2.2、Mali-400MP(GPU)、Rockchip rk30sdk平板电脑。(在初始测试中,模具缓冲区不工作,经过多次更改后,现在似乎工作正常,状态有问题。在op模具缓冲区中修复的具体更改目前未知)

同样是最新的。APK给出了上述结果

来自“Play Store”的应用程序“OpenGL 3D Showcase”已在所有三台设备上运行,“Showcase”#18“模具缓冲阴影”[OGL 1.1]工作正常,没有错误消息。该应用程序随附源代码,并已审核无效

下面是我的模具代码:

public void onDrawFrame(GL10 glUnused) {
    // Clear the rendering surface.
     glClear( GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT );

    multiplyMM(viewProjectionMatrix, 0, projectionMatrix, 0, viewMatrix, 0);

    invertM(invertedViewProjectionMatrix, 0, viewProjectionMatrix, 0);

    //Start using the stencil
    glEnable( GL_STENCIL_TEST );
    //Disable rendering to the color buffer
    glColorMask( false, false, false, false );


   //Place a 1 where rendered
   glStencilFunc( GL_ALWAYS, 1, 1 );

   //Replace where rendered
   glStencilOp( GL_REPLACE, GL_REPLACE, GL_REPLACE );

   glDisable(GL_DEPTH_TEST); 

   glStencilMask(0xFF);//value used when writing to stencil buffer      

    // draw stencil triangle
    rotateObjectInScene(0.0f, 0.0f, 0.0f);//x,y,z Object is rottated one full rotation ever 3 seconds within
    colorProgram.useProgram();
    colorProgram.setUniforms(modelViewProjectionMatrix, 0f, 0f, 1f);
    DemoTriangleStencilObj.bindData(colorProgram);
    DemoTriangleStencilObj.draw();

    //Reenable color
    glColorMask( true, true, true, true );
    //Where a 1 was not rendered
    glStencilFunc( GL_EQUAL, 1, 1 );//GL_EQUAL GL_NOTEQUAL
    //Keep the pixel
    glStencilOp( GL_KEEP, GL_KEEP, GL_KEEP );

    glStencilMask(0x00);//disable writing to stencil buffer by setting value used to 0.

    positionObjectInScene1(0.0f, 0.0f, 0.0f);//leave image/object fixed in center of screen
    textureProgram1.useProgram();
    textureProgram1.setUniforms(modelViewProjectionMatrix, texture_opengl);
    openglImageDemoObj.bindData(textureProgram1);
    openglImagerectanDemoObj.draw();

    //Finished using stencil
    glDisable( GL_STENCIL_TEST );

}
初始化:

初始化2:

已尝试所有已注释的“setEGLConfigChooser”调用

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    //Remove title bar
    this.requestWindowFeature(Window.FEATURE_NO_TITLE);
    //Remove notification bar
    this.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
    //setContentView(R.layout.activity_fist_open_glproject_aactivity);
    glSurfaceView = new GLSurfaceView(this);
    final TheSurfaceRenderer theSurfaceRenderer = new TheSurfaceRenderer(this);

    this.getApplicationContext();
    final ActivityManager activityManager =
            (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
    final ConfigurationInfo configurationInfo =
            activityManager.getDeviceConfigurationInfo();
    //final boolean supportsEs2 = false;//configurationInfo.reqGlEsVersion >= 0x20000;
    final boolean supportsEs2 = configurationInfo.reqGlEsVersion >= 0x20000;

    if (supportsEs2) {
        // Request an OpenGL ES 2.0 compatible context.
        glSurfaceView.setEGLContextClientVersion(2);

        //glSurfaceView.setEGLConfigChooser(8, 8, 8, 8, 16, 0);//when use emulator, may be needed.
        glSurfaceView.setEGLConfigChooser(new MultiSampleConfigChooser());
        //glSurfaceView.setEGLConfigChooser(8, 8, 8, 8, 16, 8);
        //glSurfaceView.setEGLConfigChooser(5,6,5,0,24,8);
        //glSurfaceView.setEGLConfigChooser(5,6,5,0,16,8);
        //glSurfaceView.setEGLConfigChooser(5,6,5,8,16,8);

        // Assign our renderer.
        //glSurfaceView.setRenderer(new AirHockeyRenderer(this));
        glSurfaceView.setRenderer(theSurfaceRenderer);
        rendererSet = true;
        //Toast.makeText(this, "Renderer started", Toast.LENGTH_LONG).show();
    } else {
        Toast.makeText(this, "This device does not support OpenGL ES 2.0.",
        Toast.LENGTH_LONG).show();
        return;
    }

    setContentView(glSurfaceView);
}

有没有跟踪问题的想法?我可能在其他任何地方得到帮助?(如果需要,可以联系制造商/Android/Google让我到任何地方吗?

在您提供的代码中,设置glStencilMask(0xFF),然后再设置glStencilMask(0x00).OpenGL是一个状态机,因此无论您上次设置什么,都是当前值——即使在清除时也是如此。默认的模具掩码值是255,因此您的glClear在第一帧上工作。但在这之后,模具掩码为0(因为您是这样设置的),因此模具缓冲区不会被清除。请在函数顶部执行此操作:

public void onDrawFrame(GL10 glUnused) {
    // Clear the rendering surface.
    glStencilMask(0xFF);
    glClear( GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT );
    ...
}

glStencilMask函数设置写入掩码--清除是一种写入操作,因此通常应在清除时将所有模具位设置为可写入。

有关这方面的任何消息?在某些设备上有类似的闪烁问题。
public void onDrawFrame(GL10 glUnused) {
    // Clear the rendering surface.
    glStencilMask(0xFF);
    glClear( GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT );
    ...
}