1

我正在开发一个使用 OpenGL ES 的应用程序,并且我试图在启动应用程序逻辑之前将纹理加载到内存中。我尝试了一些解决方案,但都没有成功。

我的活动 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

自第二个线程调用 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();
    }
}

接下来将代码添加onCreateActivity

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 回答