1

OpenGL ES を使用するアプリケーションで作業しており、アプリケーション ロジックを開始する前にテクスチャをメモリにロードしようとしています。私はいくつかの解決策を試しましたが、成功しませんでした。

私のActivity Oncreateコード。私の活動:

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

        // Create a GLSurfaceView instance and set it
        // as the ContentView for this Activity.
        view = new GLSurfaceView(this);

        // Initiate the game renderer
        renderer = new AppRenderer(this);

        view.setRenderer(renderer);
        // Only render when we tell it to
        view.setRenderMode(GLSurfaceView.RENDERMODE_WHEN_DIRTY);

        // Set the custom renderer as our view
        setContentView(view);

        startApplication();
    }

上記のコードはバグを処理します。AppRenderers の onsurfacechanged 関数でテクスチャを読み込みます。問題は、startApplication() が onsurfacechanged の前に実行されることです。これにより、startapplication() の実行時にバインドされたテクスチャがロードされず、代わりに白が表示されます。

opengles が独自のスレッドで実行されることは知っています。

そこで、以下の非同期タスクとフラグの例を使用しようとしました。

public class loadTextureTask extends AsyncTask<Void, Void, Boolean> {
    @Override
    protected Boolean doInBackground(Void... params) {
        textureLoad = renderer.getTextureLoaded();
        while (textureLoad == false) {
            textureLoad = renderer.getTextureLoaded();
        }
        startApplication();
    }
}

その後、oncreate の「startApplication()」をこの非同期タスクの開始に置き換えたので、テクスチャがいつロードされたかを確認できます。

    loadTextureTask = new loadTextureTask();
    loadTextureTask.execute((Void) null);

これにより、次のエラー「threadid=14: thread exiting with uncaught exception (group=0x40de82a0)」が発生し、この非同期タスクが存在しない場合にロードする場合に比べて、このメソッドでテクスチャをロードするのに約 20 倍の時間がかかります。 ..

私が達成しようとしているのは、テクスチャがロードされた後に startApplication() メソッドを実行することです。

注: 私のテクスチャはすべて 2 のべき乗です。

どんな助けでも大歓迎です!前もって感謝します。

4

1 に答える 1

0

2 番目のスレッドが renderer.getTextureLoaded(); を呼び出すため、20 倍の時間がかかります。何度も何度も、これは多くの CPU を使用します...したがって、次のようにすることができます。

インターフェイスを作成します。

interface ITextureLoaddedListener {
    void done();
}

AppRenderer追加 ( ) variant I.:

ITextureLoaddedListener _listener = null;
public void setTextureLoaddedListener(ITextureLoaddedListener listener) {
    _listener = listener;
}

または ( variant II.)AppRendererコンストラクタで追加

public AppRenderer(Context ctx, ITextureLoaddedListener listener){
    _listener = listener;
    //rest of old code
    LoadTexturesAsync(); 
}

両方のバージョンに次を追加します。

public void LoadTexturesAsync() {
    new AsyncTask<Void,Void, Void>(){
        @Override
        protected Void doInBackground(Void... params) 
        {
            //do your loading texture stuff here
            return null;
        }
        @Override
        protected void onPostExecute(Void result) {
            if(_listener!=null){
                _listener.done();
            }
        }

    }.execute();
}

次に、実装と実装を次のようにしActivityますITextureLoaddedListener

public YourActivity extends Activity implments ITextureLoaddedListener{
    //....
    //rest of YourActivity code
    //....

    @Override
    protected void done()
    {
        startApplication();
    }
}

次にonCreateofにコードを追加しますActivity:

renderer = new AppRenderer(this); //or (for II.) renderer = new AppRenderer(this, this); 
renderer.setTextureLoaddedListener(this); //(for I.) no need for this if you choose II. variant
renderer.LoadTexturesAsync();//(for I.) no need for this if you choose II. variant
view.setRenderer(renderer);

この場所ではまだリスナーを設定していないため、I. variantコンストラクターで LoadTexturesAsync を呼び出すべきではありません。AppRenderer

于 2013-05-20T12:59:16.637 に答える