Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/324.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java OpenGL模具(剪辑实体)_Java_Android_Opengl Es_Opengl Es 2.0_Andengine - Fatal编程技术网

Java OpenGL模具(剪辑实体)

Java OpenGL模具(剪辑实体),java,android,opengl-es,opengl-es-2.0,andengine,Java,Android,Opengl Es,Opengl Es 2.0,Andengine,我正在尝试使用精灵作为剪辑实体。这意味着我希望剪裁它的所有子实体,以便只有子实体中与剪裁实体(父实体)重叠的部分可见 我正在尝试使用OpenGL模具函数来实现这一点。在我的模拟器上我让它工作了,但在我的安卓手机上却没有。我做错了什么 GLES20.glEnable(GLES20.GL_STENCIL_TEST); GLES20.glClearStencil(0); GLES20.glStencilMask(1); GLES20.glClear(GLES20.GL_STENCIL_BUFFER_

我正在尝试使用精灵作为剪辑实体。这意味着我希望剪裁它的所有子实体,以便只有子实体中与剪裁实体(父实体)重叠的部分可见

我正在尝试使用OpenGL模具函数来实现这一点。在我的模拟器上我让它工作了,但在我的安卓手机上却没有。我做错了什么

GLES20.glEnable(GLES20.GL_STENCIL_TEST);
GLES20.glClearStencil(0);
GLES20.glStencilMask(1);

GLES20.glClear(GLES20.GL_STENCIL_BUFFER_BIT);

// pre draw
GLES20.glStencilFunc(GLES20.GL_NEVER, 1, 1);
GLES20.glStencilOp(GLES20.GL_REPLACE, GLES20.GL_KEEP, GLES20.GL_KEEP);

// draw clip-entity (this) (sprite)
this.draw();

// post draw
GLES20.glStencilFunc(GLES20.GL_LESS, 2, 1);
GLES20.glStencilOp(GLES20.GL_KEEP, GLES20.GL_KEEP, GLES20.GL_KEEP);

// draw children of clip-entity (this) which should now be clipped
this.drawChildren();

GLES20.glDisable(GLES20.GL_STENCIL_TEST);

使用模具缓冲区进行描述听起来是个不错的方法

您需要确保使用模具缓冲区请求帧缓冲区配置。在Android上使用
GLSurfaceView
时,这是通过重载的
setEGLConfigChooser()
方法之一完成的。最简单的形式是对红色、绿色、蓝色、Alpha、深度和模板有一点深度的形式。如果您还需要深度缓冲区,可以尝试以下组合以获得模具配置:

setEGLConfigChooser(8, 8, 8, 8, 24, 8);
setEGLConfigChooser(8, 8, 8, 8, 16, 8);
setEGLConfigChooser(8, 8, 8, 0, 24, 8);
setEGLConfigChooser(8, 8, 8, 0, 16, 8);
setEGLConfigChooser(5, 6, 5, 0, 24, 8);
setEGLConfigChooser(5, 6, 5, 0, 16, 8);
为了更彻底,您还可以使用
setEGLConfigChooser()
覆盖来注册自己的
EGLConfigChooser
实现。使用它,您可以枚举配置,并实现自己的逻辑来选择最符合您需要的配置

要验证是否确实有模具缓冲区,可以使用:

GLint stencilBits = 0;
glGetIntegerv(GL_STENCIL_BITS, &stencilBits);
我认为模具支持是标准的,但按照我阅读ES 2.0规范的方式,它不是必需的:

此外,实现或上下文可能不提供深度或模具缓冲区。但是,OpenGL ES实现必须至少支持一个具有深度位深度的配置

我相信至少相对较新的GPU支持模具。如果你在尝试了以上所有方法后,不得不在一个确实不提供模板的GPU上实现这一点,事情就会变得更加困难。对于您绘制的示例,您可以通过一个矩形进行剪裁,当然,这可以通过使用剪刀形矩形来完成。但我相信你只是用它来说明

根据实际渲染中使用深度缓冲区的程度,可以使用深度缓冲区进行一些操作。例如,它可以如下所示:

glClearDepthf(0.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glDisable(GL_DEPTH_TEST);
// draw clip entity
glEnable(GL_DEPTH_TEST);
// draw children

这样做的缺点是,您需要禁用部分图形的深度测试,如果该图形需要深度测试才能正确渲染,这可能是完全不可接受的。

您是否检查了在设备上运行时是否存在模具缓冲区?是的,请检查
setEGLConfigChooser()
call,并确保您请求了模具缓冲区。当您请求深度缓冲区时,某些设备会自动为您提供模具缓冲区,因为深度/模具通常组合在同一缓冲区中。但并非所有设备都是如此。非常感谢你们的快速回答!我真的很感谢你的帮助。我已经调用view.setEGLConfigChooser(8,8,8,8,16,0);在onSetContentView中,但遗憾的是没有成功。还有其他想法吗?顺便说一句:我应该基本上避免使用OpenGL模具,还是这是实现我想要的稳定方法?该
setEGLConfigChooser()
重载的最后一个参数是
stencilSize
。使用8作为最后一个参数的值。谢谢您回复我!我现在称之为.mRenderSurfaceView.setEGLConfigChooser(8,8,8,16,8);但它还是不起作用?使用模板是个好主意吗它们在大多数设备上都能正常工作吗?谢谢你的帮助。谢谢你,你好,雷托。非常感谢您的详细回答!真有趣。我还认为所有使用ES 2.0的设备都支持模具,很高兴知道我错了。是的,你是对的,我不能用剪刀,因为我也想旋转“剪辑矩形”。然而,我似乎必须找到另一种解决办法,以避免在一些不支持模具的设备上出现错误行为。谢谢你的时间和努力!祝你今天愉快