In Chapter 7, 360-Degree Gallery, we explained the need for worker threads to offload processing from the render thread. In this project, we'll add threading to the ModelObject
constructor where we read and parse the model files:
public ModelObject(final int objFile) { super(); extentsMin = new Vector3(Float.MAX_VALUE, Float.MAX_VALUE, Float.MAX_VALUE); extentsMax = new Vector3(Float.MIN_VALUE, Float.MIN_VALUE, Float.MIN_VALUE); SolidColorLightingMaterial.setupProgram(); enabled = false; new Thread(new Runnable() { @Override public void run() { InputStream inputStream = RenderBox.instance.mainActivity.getResources().openRawResource(objFile); if (inputStream == null) return; // error createMaterial(); enabled = true; float scalar = normalScalar(); transform.setLocalScale(scalar, scalar, scalar); } }).start(); }
We have to declare the file handle, objFile
, as final
to be able to access it from within the inner class. You may have also noticed that we added a call to the material's setup
program before starting the thread to ensure that it's properly set up in time and avoid crashing the app. This avoids the need to call createMaterial
within a queueEvent
procedure, since the shader compiler makes use of the graphics context. Similarly, we disable the object until it has completed loading its data. Finally, since the load is asynchronous, it's necessary to set the scale at the end of this procedure. Our previous method set the scale in setup()
, which now completes before the model is done loading.