Android OpenGL ES 透明背景
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2034822/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Android OpenGL ES Transparent Background
提问by mattbasta
I'm building an Android app that takes advantage of OpenGL. As it stands, the background for the GLSurfaceView
is dynamically generated by my code and loaded in as a texture and drawn with glDrawTexfOES
. Which is "ok", but I can simply display the image much more smoothly to its own surface (without OpenGL). Is there any way that I can make the background of a GLSurfaceView
transparent? I've heard some rumors that this can be done with setEGLConfigChooser
, but I haven't found any confirmation. Ultimately, I'd like to take a surface which I'm drawing to and put the GLSurfaceView
over it to achieve a layered effect.
我正在构建一个利用 OpenGL 的 Android 应用程序。就目前而言, 的背景GLSurfaceView
由我的代码动态生成并作为纹理加载并使用glDrawTexfOES
. 这是“好的”,但我可以简单地将图像更平滑地显示到它自己的表面(没有 OpenGL)。有什么办法可以使背景GLSurfaceView
透明?我听说过一些传言说这可以用 来完成setEGLConfigChooser
,但我还没有找到任何确认。最终,我想取一个我正在绘制的表面并将其GLSurfaceView
放在上面以实现分层效果。
I know this is a tricky and is quite possibly infeasible, but any input is appreciated. Thanks in advance.
我知道这是一个棘手的问题,而且很可能是不可行的,但任何输入都值得赞赏。提前致谢。
回答by mattbasta
Just some simple changes that I did to get this to work.
我只是做了一些简单的改变来让它发挥作用。
On my GLSurfaceView.Renderer
:
在我的GLSurfaceView.Renderer
:
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
gl.glDisable(GL10.GL_DITHER);
gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT,
GL10.GL_FASTEST);
gl.glClearColor(0,0,0,0);
gl.glEnable(GL10.GL_CULL_FACE);
gl.glShadeModel(GL10.GL_SMOOTH);
gl.glEnable(GL10.GL_DEPTH_TEST);
}
On my GLSurfaceView
:
在我的GLSurfaceView
:
setEGLConfigChooser(8, 8, 8, 8, 16, 0);
getHolder().setFormat(PixelFormat.TRANSLUCENT);
回答by Napalm
Your GLSurfaceView
also requires setZOrderOnTop(true);
您GLSurfaceView
还需要setZOrderOnTop(true);
回答by Michael Biermann
I use my own GLSurfaceView class to display charts (transparent background / overlay). My extended GLSurfaceView is embed via XML into a popover window.
我使用自己的 GLSurfaceView 类来显示图表(透明背景/叠加)。我的扩展 GLSurfaceView 通过 XML 嵌入到弹出窗口中。
<com.dsignmatters.iq_fitfunlite.GLPieChartView
android:id="@+id/gameprogress_chart"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
...
As part of the activity I added this code:
作为活动的一部分,我添加了以下代码:
mGamesuccessPieChart = (GLSurfaceView) gameprogressView.findViewById(R.id.gameprogress_chart);
mGamesuccessPieChart.setZOrderOnTop(true);
Last but not least my GLSurfaceView looks like this:
最后但并非最不重要的是我的 GLSurfaceView 看起来像这样:
public class GLPieChartView extends GLSurfaceView {
public GLPieChartView(Context context) {
super(context);
initGL();
}
public GLPieChartView(Context context, AttributeSet attrs) {
super(context, attrs);
initGL();
}
void initGL() {
setEGLContextClientVersion(2);
setEGLConfigChooser(8,8,8,8,16,0);
setRenderer(new GLPieChartRenderer());
setRenderMode(GLSurfaceView.RENDERMODE_WHEN_DIRTY);
getHolder().setFormat(PixelFormat.TRANSLUCENT);
}
}
My renderer class GLPieChartRenderer
does not call glClearColor
at all.
我的渲染器类GLPieChartRenderer
根本不调用glClearColor
。
回答by Kiran
Code sample at the end is for enabling transparency with GLSurfaceView
. But before using transparency with GLSurfaceView
, consider the following negative points.
最后的代码示例是使用GLSurfaceView
. 但是在将透明度与 一起使用之前GLSurfaceView
,请考虑以下负面因素。
- Enabling transparency requires that you use
setZOrderOnTop
onGLSurfaceView
. That will prevent you from placing any other views ( e.g.TextView
) on top of your transparentGLSurfaceView
. Even Navigation drawers cannot slide above the transparentGLSurfaceView
( ignoring tricks). Transparent or not,GLSurfaceView
can only exist above or below other android views and not in between them. - Transparency requires that you use
setEGLConfigChooser
andsetFormat
as in below example. That means, you cannot get what would have been default format chosen by system which would have been the best for that particular device. More importantly, you will need to ensure that the device has the supported format and chose alternatives if expected format isn't present as in this gsoc example.
- 启用透明度要求您使用
setZOrderOnTop
onGLSurfaceView
。这将阻止您将任何其他视图(例如TextView
)放在透明的顶部GLSurfaceView
。即使导航抽屉也不能在透明上方滑动GLSurfaceView
(忽略技巧)。透明与否,GLSurfaceView
只能存在于其他 android 视图的上方或下方,不能存在于它们之间。 - 透明度要求您使用
setEGLConfigChooser
和setFormat
,如下例所示。这意味着,您无法获得系统选择的最适合该特定设备的默认格式。更重要的是,您需要确保设备具有受支持的格式,并在此 gsoc示例中不存在预期格式时选择替代格式。
Other options to transparency.
透明度的其他选项。
- Running
Tracer
for opengl in Android, will show that, background images for activities are drawn as opengl textures. So instead of makingGLSurfaceView
transparent, if possible, you can as well render your background as an opengl texture in GLSurfaceView. - Also, alpha channel or transparency on the surface is not pre requirement for alpha blending in opengl. Both are independent.
TextureView
(trick) is good alternative if your opengl component is to be embedded between other views. This breakoutgame is a very good example forGLSurfaceView
2d drawing in Android.
Tracer
在 Android 中运行opengl,将显示活动的背景图像绘制为 opengl 纹理。因此GLSurfaceView
,如果可能的话,您可以将背景渲染为 GLSurfaceView 中的 opengl 纹理,而不是透明。- 此外,表面上的 alpha 通道或透明度不是 opengl 中 alpha 混合的先决条件。两者都是独立的。
TextureView
如果您的 opengl 组件要嵌入在其他视图之间,则(技巧) 是不错的选择。这个突破性游戏是GLSurfaceView
在 Android 中进行2d 绘图的一个很好的例子。
Below sample with layout xml and code for transparent GLSurfaceView
with background.
下面的示例带有布局 xml 和透明GLSurfaceView
背景代码。
Layout xml file with
green
color background<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MainActivity" android:background="#00FFFF"> <android.opengl.GLSurfaceView android:id="@+id/mySurfaceView" android:layout_width="wrap_content" android:layout_height="wrap_content"/> </RelativeLayout>
MainActivity.java file. Change
ALPHA
variable from 0.0 to 1.0 to see surface colorred
mixing with background activity colorgreen
package com.example.transparentsurfaceview; import android.app.Activity; import android.graphics.PixelFormat; import android.opengl.GLES20; import android.opengl.GLSurfaceView; import android.os.Bundle; import javax.microedition.khronos.egl.EGLConfig; import javax.microedition.khronos.opengles.GL10; public class MainActivity extends Activity { private GLSurfaceView mSurfaceView; private static float ALPHA = 0.5f; private static float RED = 1.0f; private static float GREEN = 0.0f; private static float BLUE = 0.0f; protected void onCreate( Bundle savedInstanceState ) { super.onCreate( savedInstanceState ); setContentView( R.layout.activity_main ); mSurfaceView = (GLSurfaceView)findViewById( R.id.mySurfaceView ); mSurfaceView.setEGLContextClientVersion( 2 ); mSurfaceView.setZOrderOnTop( true ); mSurfaceView.setEGLConfigChooser( 8, 8, 8, 8, 16, 0 ); mSurfaceView.getHolder().setFormat( PixelFormat.RGBA_8888 ); mSurfaceView.setRenderer( new GLSurfaceView.Renderer() { public void onSurfaceCreated( GL10 gl10, EGLConfig eglConfig ) { GLES20.glClearColor( RED, GREEN, BLUE, ALPHA ); } public void onSurfaceChanged( GL10 gl10, int i, int i2 ) {} public void onDrawFrame( GL10 gl10 ) { GLES20.glClear( GLES20.GL_COLOR_BUFFER_BIT ); } }); } }
具有
green
彩色背景的布局 xml 文件<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MainActivity" android:background="#00FFFF"> <android.opengl.GLSurfaceView android:id="@+id/mySurfaceView" android:layout_width="wrap_content" android:layout_height="wrap_content"/> </RelativeLayout>
MainActivity.java 文件。将
ALPHA
变量从 0.0更改为 1.0 以查看表面颜色red
与背景活动颜色的混合green
package com.example.transparentsurfaceview; import android.app.Activity; import android.graphics.PixelFormat; import android.opengl.GLES20; import android.opengl.GLSurfaceView; import android.os.Bundle; import javax.microedition.khronos.egl.EGLConfig; import javax.microedition.khronos.opengles.GL10; public class MainActivity extends Activity { private GLSurfaceView mSurfaceView; private static float ALPHA = 0.5f; private static float RED = 1.0f; private static float GREEN = 0.0f; private static float BLUE = 0.0f; protected void onCreate( Bundle savedInstanceState ) { super.onCreate( savedInstanceState ); setContentView( R.layout.activity_main ); mSurfaceView = (GLSurfaceView)findViewById( R.id.mySurfaceView ); mSurfaceView.setEGLContextClientVersion( 2 ); mSurfaceView.setZOrderOnTop( true ); mSurfaceView.setEGLConfigChooser( 8, 8, 8, 8, 16, 0 ); mSurfaceView.getHolder().setFormat( PixelFormat.RGBA_8888 ); mSurfaceView.setRenderer( new GLSurfaceView.Renderer() { public void onSurfaceCreated( GL10 gl10, EGLConfig eglConfig ) { GLES20.glClearColor( RED, GREEN, BLUE, ALPHA ); } public void onSurfaceChanged( GL10 gl10, int i, int i2 ) {} public void onDrawFrame( GL10 gl10 ) { GLES20.glClear( GLES20.GL_COLOR_BUFFER_BIT ); } }); } }
回答by bismack163
you should make sure the activity background is transparent!
你应该确保活动背景是透明的!
If the activity's background is opaque, say white by default, then even when the content view (the glsurfaceview) is translucent, it will display the activity's white background as its background.
如果活动的背景是不透明的,默认情况下为白色,那么即使内容视图(glsurfaceview)是半透明的,它也会显示活动的白色背景作为其背景。
You can set the activity background transparency in the Android.manifest where it is declared, see the official API demo TranslucentGLSurfaceViewActivity for help
可以在Android.manifest中设置activity的背景透明度,帮助查看官方API演示TranslucentGLSurfaceViewActivity