다시 시작할 때 조각 내부의 GLSurfaceView가 렌더링되지 않음
나는 한 GLSurfaceView
설정하고를 사용하여 예상대로 렌더링 GLSurfaceView.Renderer
. 내 앱은 Android 지원 패키지의 조각을 사용합니다. 새 조각으로 이동하면 surfaceDestroyed
호출되지만 백 스택을 통해 조각으로 돌아 오면 GLSurfaceView
렌더링되지 않고 호출이 호출 requestRender
되지 않습니다 onDraw
.
내가 호출 할 필요가 있음을 알고 onResume
및 onPause
표면보기에 내가 호스팅 조각에서이 일을하고 있지만,이 문제를 해결하지 않는 것 같습니다. htis 방법에 대한 모든 예는 활동을 참조합니다. 이것이 문제가 될 수 있습니까? 그렇다면 GLSurfaceView
조각 내부를 어떻게 사용합니까?
어떤 통찰력이라도 대단히 감사합니다. 코드를 게시하게되어 기쁩니다. 그러나 그것은 나에게 일반적인 질문 인 것 같습니다.
감사
조각에 GLSurfaceView를 설정하는 방법은 다음과 같습니다.
onCreateView() {
glSurfaceView = new GLSurfaceView(getActivity());
...
}
onPause() {
if (glSurfaceView != null) { glSurfaceView.onPause(); }
...
}
onResume() {
if (glSurfaceView != null) { glSurfaceView.onResume(); }
...
}
}
따라서 활동에서하는 것과 유사합니다. 이것은 내 사용 사례에서 작동하므로 조각으로 작동하는 것처럼 보입니다. 코드가 어떻게 생겼는지 모른 채 더 많은 것을 말하기는 어렵습니다.
너무 늦었지만 다른 사람들에게 유용 할 수 있습니다 이것은 이미 구현했으며 에뮬레이터와 장치 모두에서 잘 작동하므로 내 대답입니다. 조각 및 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와 함께 조각을 사용할 때 알아야 할 몇 가지 사항입니다. 조금 까다로워 지지만 나와 함께하십시오. 새 조각으로 이동하면 glsurfaceview가있는 조각에서 ondestroyview가 자동으로 호출되어 뷰 (oncreateview에서 생성하고 반환 한 glsurfaceview)를 파괴합니다.
따라서 새 조각으로 이동하면 onpause, 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 );
}
You don't want to create your rendering class (shader) in oncreateview unless you want your rendering class to 'start over' every time you come back to your fragment with the glsurfaceview. Instead create your rendering class in your Fragments onCreate, that way if you have things set up then you will start right where you left since simply setting the renderer will provide you with the surface which will cause the onsurfacecreated, onsurfacechanged, and ondrawframe to be invoked automatically. Make sure you reload whatever resources you were last using in onsurfacecreated, on in the ondrawframe prior to drawing them.
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
shader = new Shader(this);
Log.d("Fragment", "OnCreate");
}
when it comes to pausing and resuming your fragment, then in most cases this is automatically handled when you dynamically replace a fragment and add it to the backstack, so just simply put surface.onpause() and surface.onResume() in the right spots and you are good to go.
To make things crystal clear try putting log statements in the methods revolving around the fragment lifecycle and glsurfaceview renderer and you will be able to see what is and isn't happening.
I not work with fragments but if the glsurface was destroyed, perhaps have to create an instance again of the OpenGLRenderer and reassing to the glsurface, this code work for me in activities when change orientation and recreate all the screen, in this case I have to set the contentview of layout again for reset the glsurfaceview:
view.onPause();
setContentView(R.layout.slidegl);
view = (GLSurfaceView) this.findViewById(R.id.glSurface);
renderer = new OpenGLRenderer();
view.setRenderer(renderer);
view.onResume();
If you wan´t restart and setup all content of view try creating a new object of GLSurface:
this.view = new GLSurfaceView();
Im not an expert with OpenGL
ES
, but I have fought my way around fragments and their lifecycle enough. What I suggest you do is set onCreateView
for your fragment, tell the renderer to start drawing again, and if that doesn't work try doing it from the onResume
from the fragment. There should be no need to do anything from the activity level when it comes to the drawing of the GL
surface in the fragment.
'development' 카테고리의 다른 글
런타임에 결정된 대형 구조체 유형을 반환하는 IMP 함수를 구현하는 방법은 무엇입니까? (0) | 2020.12.09 |
---|---|
Cassandra 서버에서 java.lang.AssertionError : DecoratedKey (…)! = DecoratedKey 발생 (0) | 2020.12.09 |
내 구조체 배열이 왜 그렇게 많은 메모리를 차지합니까? (0) | 2020.12.09 |
취소 후 이벤트 전파를 계속하는 방법은 무엇입니까? (0) | 2020.12.09 |
올바른 Protobuf 콘텐츠 유형은 무엇입니까? (0) | 2020.12.09 |