[英]Trying to add GLSurfaceView to a layout programmatically
Ok, Just some background... I have a fully functioning game that uses the canvas to draw, and I'm in the process of trying to learn and convert the drawing over to OpenGL ES 1.0. 好吧,只是一些背景......我有一个功能齐全的游戏,使用画布绘制,我正在尝试学习并将绘图转换为OpenGL ES 1.0。 (to keep compatibility.) (为了保持兼容性。)
What I've been trying to do, Is figure out a way to incorporate the GLSurfaceView and Renderer into the program so that I can switch the drawing over piece by piece. 我一直试图做的是,找出一种方法将GLSurfaceView和Renderer合并到程序中,这样我就可以逐个切换绘图。 (There are a lot of sprites and I have needs to update often, so I don't want it to take me a month to release the next update.) (有很多精灵,我需要经常更新,所以我不想让它花一个月时间来发布下一次更新。)
It has been suggested that I Use the GLSurfaceView on top of the current SurfaceView, and i'm getting there but I've hit a snag. 有人建议我在当前的SurfaceView上使用GLSurfaceView,但是我到了那里但是我遇到了麻烦。
I'm basically using the LunarLander example and trying to add on a simple OpenGL renderer that draws a texture on a square and renders it. 我基本上使用的是LunarLander示例,并尝试添加一个简单的OpenGL渲染器,在一个正方形上绘制纹理并渲染它。 The goal would be to draw the square on top of the canvas. 目标是在画布上绘制正方形。
Here is the relevant code in the Activity: 以下是活动中的相关代码:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.lunar_layout);
LinearLayout detailListView = (LinearLayout) findViewById(R.id.dets); // Find the layout where you want to add button
Button button = new Button(this);
button.setLayoutParams(new LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,ViewGroup.LayoutParams.WRAP_CONTENT));
detailListView.addView(button);//add view to add
mGLSV = new BasicGLSurfaceView(this);
mGLSV.setLayoutParams(new LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,ViewGroup.LayoutParams.WRAP_CONTENT));
detailListView.addView(mGLSV);
//clipped
The lunar_layout file looks like this: lunar_layout文件如下所示:
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:ads="http://schemas.android.com/apk/lib/com.google.ads"
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.example.android.lunarlander.LunarView
android:id="@+id/lunar"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
<LinearLayout
android:id="@+id/dets"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:layout_marginLeft="0dp"
android:layout_marginTop="50dp"
android:orientation="vertical" >
<com.google.ads.AdView
android:id="@+id/adView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
ads:adSize="BANNER"
ads:adUnitId="a14ecf8f2d9ef49"
ads:loadAdOnCreate="true" >
</com.google.ads.AdView>
</LinearLayout>
<RelativeLayout
android:id="@+id/relLayout"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<TextView
android:id="@+id/text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:gravity="center_horizontal"
android:text="@string/lunar_layout_text_text"
android:textColor="#88ffffff"
android:textSize="24sp"
android:visibility="visible" />
</RelativeLayout>
</FrameLayout>
Pretty Simple, I'm trying to use that LinearLayout to add things on top of the Surface View. 非常简单,我正在尝试使用LinearLayout在Surface View上添加内容。 Notice I also add a scratch Button, just to check the concept works. 注意我还添加了一个临时按钮,只是为了检查概念的工作原理。 What I end up with is the canvas, and the button showing up correctly, but no sign of the GLSurfaceView. 我最终得到的是画布,按钮显示正确,但没有GLSurfaceView的迹象。 What am I doing wrong? 我究竟做错了什么?
I'd suggest you have your BasicGLSurfaceView already added to your framelayout in XML, and use findViewById(R.id.basicGLSurfaceView1)
to get a hold of it, rather than trying to create it programatically: 我建议您已将BasicGLSurfaceView添加到XML中的framelayout中,并使用findViewById(R.id.basicGLSurfaceView1)
来获取它,而不是尝试以编程方式创建它:
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:ads="http://schemas.android.com/apk/lib/com.google.ads"
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.example.android.lunarlander.BasicGLSurfaceView
android:id="@+id/glSurfaceView1"
android:layout_width="match_parent"
android:layout_height="match_parent">
</com.example.android.lunarlander.BasicGLSurfaceView>
<com.example.android.lunarlander.LunarView
android:id="@+id/lunar"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
<LinearLayout
android:id="@+id/dets"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:layout_marginLeft="0dp"
android:layout_marginTop="50dp"
android:orientation="vertical" >
<com.google.ads.AdView
android:id="@+id/adView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
ads:adSize="BANNER"
ads:adUnitId="a14ecf8f2d9ef49"
ads:loadAdOnCreate="true" >
</com.google.ads.AdView>
</LinearLayout>
<RelativeLayout
android:id="@+id/relLayout"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<TextView
android:id="@+id/text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:gravity="center_horizontal"
android:text="@string/lunar_layout_text_text"
android:textColor="#88ffffff"
android:textSize="24sp"
android:visibility="visible" />
</RelativeLayout>
</FrameLayout>
You need to tell the GLSurfaceView to start rendering. 您需要告诉GLSurfaceView开始渲染。 You have to call (or even override) GLSurfaceView.start()
in your GLSurfaceView. 您必须在 GLSurfaceView.start()
调用(或甚至覆盖) GLSurfaceView.start()
。 Alternatively, setRenderer is public, so if you call mGLSV.setRenderer(myRenderer);
或者,setRenderer是公共的,所以如果你调用 mGLSV.setRenderer(myRenderer);
in your Activity where myRenderer is an instance of MyRenderer implements GLSurfaceView.Renderer
then it should automatically start the rendering without you having to touch start()
在您的Activity中,myRenderer是MyRenderer的一个实例, MyRenderer implements GLSurfaceView.Renderer
然后它应该自动启动渲染,而不必触摸start()
EDIT: Actually, start()
is called when the view is laid out (ie when you setContentView()
or add it to whatever layout you set as content view), not when setRenderer is called 编辑:实际上,在布局视图时调用start()
(即当你setContentView()
或将它添加到你设置为内容视图的任何布局时),而不是在调用setRenderer时
It sounds back-to-front but implementing Renderer is for if you just want to render something in the standard android/opengl-es way, whilst extending GLSurfaceView is if you actually want to get under the hood and edit the way android renders. 它听起来是前置的,但实现Renderer是为了你想要以标准的android / opengl-es方式呈现某些东西,同时扩展GLSurfaceView就是你真的想深入了解并编辑android呈现的方式。 In fact, I would recommend not extending GLSurfaceView at all but doing as much as possible in your GLSurfaceView.Renderer. 事实上,我建议不要在GLSurfaceView.Renderer中尽可能地扩展GLSurfaceView。 I have programmed my entire 3D game without extending GLSurfaceView. 我编写了我的整个3D游戏而没有扩展GLSurfaceView。 My code looks like this: 我的代码看起来像这样:
public class stackoverflowTest extends Activity {
MyGLSurfaceView glSurface;
MyRenderer myRenderer;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
myRenderer = new MyRenderer();
//Get hold of our GLSurfaceView
glSurface = (MyGLSurfaceView) findViewById(R.id.graphics_glsurfaceview1);
// optional
glSurface.setEGLConfigChooser(true);
glSurface.setRenderer(myRenderer);
//Set the renderer. setRenderer will call start() and start the GL thread, which then calls onSurfaceCreated, onDraw etc in the Renderer
}
@Override
public void onPause(){
super.onPause();
glSurface.onPause();
}
@Override
public void onResume() {
super.onResume();
glSurface.onResume();
}
}
}
Renderer: 渲染:
public class MyRenderer implements Renderer {
@Override
public void onDrawFrame(GL10 gl) {
// openGL drawing code goes here
}
@Override
public void onSurfaceChanged(GL10 gl, int width, int height) {
// etc
}
@Override
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
// etc
}
}
GLSurfaceView: GLSurfaceView:
public class MyGLSurfaceView extends GLSurfaceView {
public MyGLSurfaceView(Context context) {
super(context);
}
public MyGLSurfaceView(Context context, AttributeSet attribs) {
super(context, attribs);
}
@Override
public void onPause(){
super.onPause();
}
@Override
public void onResume(){
super.onResume();
}
}
If you can stand upgrading to android 2.1 (opengl-es 1.1) you can use point-sprites rather than rendering textured quads or whatever 如果你可以升级到android 2.1(opengl-es 1.1)你可以使用点精灵而不是渲染纹理四边形或其他
Figured it out myself. 自己搞清楚了。 Even though SurfaceView is a subclass of View, the way SurfaceView displays through the window is kinda funny, Basically The canvas actually goes through the surfaceview but is behind it in Z order. 即使SurfaceView是View的子类,SurfaceView在窗口中显示的方式也很有趣,基本上画布实际上是通过surfaceview但是在Z顺序后面。 Because of this Multiple surface views have to be ordered using surfaceview.setZOrderOnTop(true); 因此,必须使用surfaceview.setZOrderOnTop(true)来排序多个表面视图;
Now I just have to worry about making the GLSurfaceView Transparent. 现在我只需要担心GLSurfaceView透明化。
Taken from min3d, this should work on making the GLSurfaceView transparent 从min3d开始,这应该可以使GLSurfaceView透明化
_glSurfaceView.setEGLConfigChooser(8,8,8,8, 16, 0);
_glSurfaceView.getHolder().setFormat(PixelFormat.TRANSLUCENT);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.