Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/193.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/jquery/73.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
Android GLSurfaceView内部片段在重新启动时未呈现_Android_Opengl Es_Android Fragments_Glsurfaceview - Fatal编程技术网

Android GLSurfaceView内部片段在重新启动时未呈现

Android GLSurfaceView内部片段在重新启动时未呈现,android,opengl-es,android-fragments,glsurfaceview,Android,Opengl Es,Android Fragments,Glsurfaceview,我使用GLSurfaceView.Renderer按预期设置和渲染了GLSurfaceView.Renderer。我的应用程序使用android支持包中的片段。当我导航到一个新片段时,surfaceDestroyed被调用,但当我通过backbackback返回片段时,GLSurfaceView将不会呈现,对requestRender的调用不会导致onDraw调用 我知道我需要在surface视图上调用onResume和onPause,我是从宿主片段执行此操作的,但它似乎无法解决问题。关于hti

我使用
GLSurfaceView.Renderer
按预期设置和渲染了
GLSurfaceView.Renderer。我的应用程序使用android支持包中的片段。当我导航到一个新片段时,
surfaceDestroyed
被调用,但当我通过backbackback返回片段时,
GLSurfaceView
将不会呈现,对
requestRender
的调用不会导致
onDraw
调用

我知道我需要在surface视图上调用
onResume
onPause
,我是从宿主片段执行此操作的,但它似乎无法解决问题。关于htis方法的所有示例都涉及活动,这可能是问题所在吗?如果是这样,如何在片段中使用
GLSurfaceView

非常感谢任何见解,我很高兴发布代码,但对我来说,这似乎更像是一个一般性问题


感谢

我不处理片段,但如果glsurface被破坏,可能需要再次创建OpenGLRenderer的实例并重新分配给glsurface,当更改方向并重新创建所有屏幕时,此代码在活动中对我有效,在这种情况下,我必须再次设置布局的contentview以重置GLSURFACHEVIEW:

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(); 

我不是OpenGL的专家,但我已经为片段和它们的生命周期奋斗了很多。我建议您为片段设置
onCreateView
,告诉渲染器重新开始绘制,如果不起作用,请尝试从片段的
onResume
开始绘制。在片段中绘制
GL
曲面时,不需要从活动级别执行任何操作

以下是我如何在片段中设置GLSurfaceView:

onCreateView() {
    glSurfaceView = new GLSurfaceView(getActivity());
   ...
}

onPause() {
    if (glSurfaceView != null) { glSurfaceView.onPause(); }
    ...
}

onResume() {
    if (glSurfaceView != null) { glSurfaceView.onResume(); }
    ...
}
}


所以,类似于你在活动中所做的。这在我的用例中起作用,所以看起来它们是在片段中工作的。如果不知道您的代码是什么样子,很难说得更多。

我知道现在已经太迟了,但它可能对其他人有用 这是我的答案,因为我已经实现了它,它在模拟器和设备中都运行良好。我已经使用了fragment和supportV4。希望您会喜欢它

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;
}
}

在使用glsurfaceview的片段时,需要了解一些事情。这会有点棘手,但请和我在一起。当您导航到一个新片段时,ondestroyview会自动使用glsurfaceview对您的片段调用,这会破坏您的视图(您在oncreateview中创建并返回的glsurfaceview)

因此,当您导航到一个新片段,然后在Pause、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。确保在绘制资源之前,在onsurfacecreated中、ondrawframe中重新加载上次使用的资源

@Override
public void onCreate(Bundle savedInstanceState) 
{
    super.onCreate(savedInstanceState);

    shader = new Shader(this); 

    Log.d("Fragment", "OnCreate"); 

}
当涉及到暂停和恢复片段时,在大多数情况下,当您动态替换片段并将其添加到backbackback时,这会自动处理,因此只需将surface.onpause()和surface.onResume()放在正确的位置,就可以了


为了让事情变得非常清楚,请尝试在围绕片段生命周期和glsurfaceview渲染器的方法中放置log语句,这样您将能够看到发生了什么和没有发生什么

这是一个很好的问题,我也在寻找答案(如果找到解决方案,我会更新)。我没有尝试在片段中使用GLSURFACHEVIEW,但根据我在互联网上使用基于活动的示例的经验,这些示例大多不完整或过时。我认为主要的问题是您需要在onPause中查看所有OpenGL资源(纹理、着色器、VBOs IIRC),然后在onResume中重新创建它们。我最近会检查我的旧代码。你试过把你的代码放到活动中吗?@Blackhex代码在活动中运行得很好,当我决定将其移动到片段中时,我遇到了问题。我对OpenGL没有太多经验,所以如果你能为我指出暂停时释放所有资源的正确方向,我会尝试一下。对于onResume()中的每个glCreateShader()、glCreateProgram()、glGetTextures()、glGenBuffers()和glGenFramebuffers(),应该有glDeleteShader()glDeleteProgram()、glDeleteTextures(),glDeleteBuffers()和glDeleteFrameb