60

GLSurfaceView使用して、期待どおりにセットアップとレンダリングを行いましたGLSurfaceView.Renderer。私のアプリは、Android サポート パッケージのフラグメントを使用します。新しいフラグメントに移動するsurfaceDestroyedと呼び出されますが、バックスタックを介してフラグメントに戻るとGLSurfaceViewレンダリングされず、呼び出しが呼び出されrequestRenderませんonDraw

私は表面ビューで呼び出す必要があることを認識しておりonResumeonPauseホスティングフラグメントからこれを行っていますが、問題は解決していないようです。htis メソッドに関するすべての例はアクティビティを参照していますが、これが問題になる可能性はありますか? もしそうならGLSurfaceView、フラグメント内でどのように使用しますか。

コードを投稿できてうれしいですが、私にとっては一般的な質問のようです。

ありがとう

4

5 に答える 5

4

GLSurfaceViewをフラグメントで設定する方法は次のとおりです。

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

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

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

}

つまり、アクティビティで行うのと同じです。これは私のユースケースで機能するので、フラグメントで機能するようです。あなたのコードがどのように見えるかを知らずにこれ以上言うのは難しいです。

于 2013-02-22T01:08:20.410 に答える
4

遅すぎることはわかっていますが、他の人にとっては役立つかもしれません。これは私の答えです。すでに実装しており、エミュレーターとデバイスの両方でうまく機能します。

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;
}
}
于 2013-03-21T13:26:00.537 に答える
3

glsurfaceview でフラグメントを使用する場合、いくつかのことを理解する必要があります。少しトリッキーになりますが、私と一緒にいてください。新しいフラグメントに移動すると、glsurfaceview を使用して ondestroyview がフラグメントで自動的に呼び出され、ビュー (作成して oncreateview で返された glsurfaceview) が破棄されます。

そのため、新しいフラグメントに移動すると、onpause、onstop、ondestroyview が自動的に呼び出されます。何もしなくてもかまいません。glsurfaceview を使用してそのフラグメントに戻ると、oncreateview、onactivitycreated、onstart、および onresume が自動的に呼び出されます。ユーザーの作業は必要ありません。

あなたの質問の鍵は、Android 開発者の Web サイトで見つけることができるフラグメントのライフサイクルを理解し、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 );
}

glsurfaceview でフラグメントに戻るたびにレンダリング クラスを「最初からやり直す」場合を除き、oncreateview でレンダリング クラス (シェーダー) を作成する必要はありません。代わりに Fragments onCreate でレンダリング クラスを作成します。設定が完了している場合は、レンダラーを設定するだけで onsurfacecreated、onsurfacechanged、および ondrawframe が呼び出されるサーフェスが提供されるため、左の場所から開始できます。自動的。onsurfacecreated で最後に使用していたリソースを、描画する前に ondrawframe で必ず再読み込みしてください。

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

    shader = new Shader(this); 

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

}

フラグメントの一時停止と再開に関しては、ほとんどの場合、フラグメントを動的に置き換えてバックスタックに追加すると自動的に処理されるため、適切な場所に surface.onpause() と surface.onResume() を配置するだけですそして、あなたは行ってもいいです。

物事を明確にするために、フラグメントのライフサイクルと glsurfaceview レンダラーを中心に展開するメソッドにログ ステートメントを入れてみてください。何が起こっていて、何が起こっていないかを確認できます。

于 2014-08-03T18:24:08.807 に答える
1

私は の専門家ではありませんが、OpenGL ESフラグメントとそのライフサイクルについて十分に戦ってきました。私がお勧めするのはonCreateView、フラグメントに設定し、レンダラーに再度描画を開始するように指示することです。それがうまくいかない場合はonResume、フラグメントから実行してみてください。GLフラグメント内のサーフェスの描画に関しては、アクティビティ レベルから何もする必要はありません。

于 2013-01-20T16:27:09.060 に答える
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(); 
于 2012-09-26T09:38:42.860 に答える