我使用GLSurfaceView
按预期设置GLSurfaceView.Renderer
。我的应用程序使用Android支持包中的片段。当我导航到一个新的片段surfaceDestroyed
被调用但是当我通过后台返回到片段时GLSurfaceView
将不会呈现,对requestRender
的调用不会导致{{1}调用。
我知道我需要在表面视图上调用onDraw
和onResume
,而我正在从托管片段执行此操作,但它似乎无法解决问题。关于htis方法的所有例子都参考了活动,这可能是问题吗?如果是这样,你如何在片段中使用onPause
。
非常感谢任何见解,我很乐意发布代码,但这似乎对我来说更像一般性问题,
由于
答案 0 :(得分:4)
以下是我在片段中设置GLSurfaceView的方法:
onCreateView() {
glSurfaceView = new GLSurfaceView(getActivity());
...
}
onPause() {
if (glSurfaceView != null) { glSurfaceView.onPause(); }
...
}
onResume() {
if (glSurfaceView != null) { glSurfaceView.onResume(); }
...
}
}
所以,类似于你在活动中所做的事情。这在我的用例中有效,所以看起来它们确实在碎片中工作。如果不知道你的代码是什么样的话,很难说更多。
答案 1 :(得分:4)
我知道为时已晚,但对其他人可能有用 这是我的答案,因为我已经实现了它,它在模拟器和设备中都运行良好。我有使用片段和支持VB。希望你喜欢它。
import android.opengl.GLSurfaceView;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import com.example.opengles20.glsurfaceview.GlSurfaceViewClass;
import com.example.opengles20.renderer.RendererClass;
public class MYGlclass extends Fragment {
private GlSurfaceViewClass mGLView;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
if (container == null) {
return null;
}
View view=inflater.inflate(R.layout.main, container, false);
mGLView=(GlSurfaceViewClasss)view.findViewById(R.id.gl_surface_view);
mGLView.setEGLContextClientVersion(2);
RendererClass rendererclass=new RendererClass(getActivity());
mGLView.setRenderer(rendererclass);
mGLView.setRenderMode(GLSurfaceView.RENDERMODE_WHEN_DIRTY);
return view;
}
}
答案 2 :(得分:3)
使用带有glsurfaceview的片段时需要注意的几件事情。这有点棘手,但留在我身边。导航到新片段时,会自动使用glsurfaceview调用ondestroyview片段,这会破坏您的视图(您在oncreateview中创建并返回的glsurfaceview)。
因此,当您导航到新片段然后暂停时,onstop会自动调用ondestroyview,而无需您做任何工作。当你用glsurfaceview回到那个片段然后oncreateview,onactivitycreated,onstart和onresume被自动调用,你不需要做任何工作。
你的问题的关键是理解片段生命周期,可以在android开发者网站上找到,并了解glsurfaceview如何运作。
现在,使用glsurfaceview,您必须使用onsurfacecreated,onsurfacechanged和ondrawframe来实现渲染器。导航到另一个片段,然后使用glsurfaceview返回到你的片段将导致onsurfacecreated被再次调用,因为你的glsurfaceview在ondestroyview中被销毁,你的上下文已经丢失,你需要重新加载gl线程上的所有资源。
最后,从您的问题看,未调用ondrawframe,这可能是由于您没有重新创建视图,设置渲染器以及从oncreateview返回视图。
所以在oncreateview中你需要这样的东西
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle
savedInstanceState)
{
View mView = inflater.inflate(R.layout.fragment_layout, null);
surface = (GLSurfaceView) mView.findViewById (R.id.glsurfaceview);
surface.setEGLContextClientVersion(2);
//return your view here
return mView;
}
@Override
public void onActivityCreated(Bundle mState)
{
super.onActivityCreated(mState);
//setting your renderer here causes onSurfaceCreated to be called
//if you set your renderer here then you have a context to load resources
surface.setRenderer( shader );
}
您不想在oncreateview中创建渲染类(着色器),除非您希望渲染类重新开始。每次你用glsurfaceview回到你的片段。而是在Fragments onCreate中创建渲染类,这样如果你设置了东西,那么你将从你离开的地方开始,因为只需设置渲染器就会为你提供表面,这将导致onsurfacecreated,onsurfacechanged和ondrawframe被调用自动。确保在绘制之前重新加载上次使用的onsurface创建的任何资源。
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
shader = new Shader(this);
Log.d("Fragment", "OnCreate");
}
当暂停和恢复你的片段时,在大多数情况下,当动态替换片段并将其添加到backstack时,会自动处理,所以只需将surface.onpause()和surface.onResume()放入正确的地方,你很高兴。
为了使事情变得清晰,尝试将日志语句放在围绕片段生命周期和glsurfaceview渲染器的方法中,您将能够看到什么是和不发生。
答案 3 :(得分:1)
我不使用片段但是如果glsurface被破坏了,也许必须再次创建OpenGLRenderer的实例并重新放入glsurface,这个代码在我改变方向并重新创建所有屏幕的活动中适用于我,在这种情况下我必须再次设置布局的内容视图以重置glsurfaceview:
view.onPause();
setContentView(R.layout.slidegl);
view = (GLSurfaceView) this.findViewById(R.id.glSurface);
renderer = new OpenGLRenderer();
view.setRenderer(renderer);
view.onResume();
如果您不想重新启动并设置所有视图内容,请尝试创建GLSurface的新对象:
this.view = new GLSurfaceView();
答案 4 :(得分:1)
我不是OpenGL
ES
的专家,但我已经对片段及其生命周期进行了充分的思考。我建议你做的是为你的片段设置onCreateView
,告诉渲染器再次开始绘制,如果这不起作用,请尝试从片段中的onResume
开始。在片段中绘制GL
曲面时,不需要从活动级别做任何事情。