我正在开发一个使用 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();
}
}
接下来将代码添加到Activity
的onCreate
中:
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/