java - Android OpenGLES 在 GLThread 中加载纹理然后告诉 UI 线程运行一个方法

标签 java android opengl-es

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

我的 Activity Oncreate 代码。 我的 Activity :

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() 运行时绑定(bind)的纹理不加载并显示白色。

我确实知道 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: 线程因未捕获的异常而退出 (group=0x40de82a0) “并且使用此方法加载纹理需要花费大约 20 倍的时间(如果该异步任务不存在,则加载时间会增加 20 倍)。

我想要完成的是在纹理加载后运行 startApplication() 方法。

注意:我的纹理都是 2 的幂。

任何帮助将不胜感激!预先感谢您。

最佳答案

自第二个线程调用 renderer.getTextureLoaded() 以来,它花费了 20 倍的时间;一次又一次,这会占用大量 CPU...所以你可以这样做:

创建接口(interface):

interface ITextureLoaddedListener {
    void done();
}

AppRenderer中添加(变体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();
    }
}

接下来将代码添加到ActivityonCreate中:

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。变体您不应该在AppRenderer的构造函数中调用LoadTexturesAsync,因为在这个地方您还没有设置监听器。

关于java - Android OpenGLES 在 GLThread 中加载纹理然后告诉 UI 线程运行一个方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16647031/

相关文章:

java - 使用 Spring 在 Tomcat 启动期间委托(delegate)处理

java - 使用扫描仪或正则表达式java分割字符串

java - 我可以使用哪些技术来帮助更好地理解离散数学中的概念是如何在编程中使用的?

android - 构建 Android 总是为每个构建下载依赖项

android - 如何在 Firebase Event Analytics 中查看 Bundle 参数

android - ListActivtiy 中的自定义标题栏按钮

visual-studio - OpenGL ES-寻找预编译 header 时文件意外结束

java - 位置 2 处出现意外字符 (") JSON 解析器 (Java)

iOS GLSL 球谐着色器。如何使用 iOS GPU 进行 Raycast

android - 是否可以使用 Z 坐标使 Android 游戏在多种屏​​幕尺寸上兼容?