in app/src/main/java/com/facebook/sample/rendering/SampleGLTFRenderer.java [75:146]
private ArrayList<GLTFRenderObject> CreateGLTFRenderObjects(SampleGLTFReader.GLTFScene gltfScene) {
ArrayList<GLTFRenderObject> renderObjects = new ArrayList<>();
// Note in real glTF nodes can have children. Here we're only loading top level siblings for the sample.
for (int i = 0; i < gltfScene.meshes.size(); ++i) {
SampleGLTFReader.GLTFScene.Mesh mesh = gltfScene.meshes.get(i);
// Add each primitive into the render object list.
for (int j = 0; j < mesh.primitives.size(); ++j) {
GLTFRenderObject renderObject = new GLTFRenderObject();
SampleGLTFReader.GLTFScene.Primitive primitive = mesh.primitives.get(j);
// Find which accessor contains the data for this attribute
int accessorIdx = primitive.attributes.get("POSITION");
SampleGLTFReader.GLTFScene.Accessor accessor = gltfScene.accessors.get(accessorIdx);
SampleGLTFReader.GLTFScene.BufferView bufferView = gltfScene.bufferViews.get(accessor.bufferView);
SampleGLTFReader.GLTFScene.Buffer buffer = gltfScene.buffers.get(bufferView.buffer);
// Load vertex data embedded in JSON
if (accessor.componentType == SampleGLTFReader.COMPONENT_TYPE_FLOAT) {
renderObject.vertices = buffer.data.asFloatBuffer();
renderObject.vertexByteLength = bufferView.byteLength;
renderObject.vertexByteOffset = bufferView.byteOffset;
renderObject.vertices.position(bufferView.byteOffset / BYTES_PER_FLOAT);
} else {
// Not needed for our example.
// Would need to initialize the correct Buffer type given the componentType.
Log.e(TAG, "Not implemented");
}
// Load index data embedded in JSON
int indicesAccessor = primitive.indices;
accessor = gltfScene.accessors.get(indicesAccessor);
bufferView = gltfScene.bufferViews.get(accessor.bufferView);
buffer = gltfScene.buffers.get(bufferView.buffer);
if (bufferView.target == SampleGLTFReader.TARGET_ELEMENT_ARRAY_BUFFER) {
renderObject.indices = buffer.data.asShortBuffer();
renderObject.indexByteLength = bufferView.byteLength;
renderObject.indexByteOffset = bufferView.byteOffset;
renderObject.indices.position(bufferView.byteOffset / BYTES_PER_SHORT);
} else {
Log.e(TAG, "Index buffer is invalid");
}
// Prepare and upload GPU data.
int[] buffers = new int[2];
GLES20.glGenBuffers(2, buffers, 0);
renderObject.vertexBufferId = buffers[0];
renderObject.indexBufferId = buffers[1];
// Upload vertex buffer to GPU
renderObject.vertices.position(renderObject.vertexByteOffset / BYTES_PER_FLOAT);
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, renderObject.vertexBufferId);
GLES20.glBufferData(GLES20.GL_ARRAY_BUFFER, renderObject.vertexByteLength, renderObject.vertices, GLES20.GL_STATIC_DRAW);
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, 0);
// Upload index buffer to GPU
renderObject.indices.position(renderObject.indexByteOffset / BYTES_PER_SHORT);
GLES20.glBindBuffer(GLES20.GL_ELEMENT_ARRAY_BUFFER, renderObject.indexBufferId);
GLES20.glBufferData(
GLES20.GL_ELEMENT_ARRAY_BUFFER, renderObject.indexByteLength, renderObject.indices, GLES20.GL_STATIC_DRAW);
GLES20.glBindBuffer(GLES20.GL_ELEMENT_ARRAY_BUFFER, 0);
GLHelpers.checkGlError("glTF buffer load");
renderObjects.add(renderObject);
}
}
return renderObjects;
}