Skip to content

Commit

Permalink
Add TextureLoader.loadImageTexture()
Browse files Browse the repository at this point in the history
  • Loading branch information
ThomasGorisse committed Jun 24, 2022
1 parent 8c62a47 commit f724780
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 28 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -239,7 +239,7 @@ class PlaneRenderer(private val lifecycle: ArSceneLifecycle) : ArSceneLifecycleO
}

private suspend fun loadPlaneMaterial() {
val texture = TextureLoader.loadTexture(
val texture = TextureLoader.loadImageTexture(
sceneView.context,
lifecycle,
"sceneview/textures/plane_renderer.png",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,48 +3,72 @@ package io.github.sceneview.texture
import android.content.Context
import android.graphics.BitmapFactory
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.coroutineScope
import com.google.android.filament.Texture
import com.google.android.filament.android.TextureHelper
import io.github.sceneview.Filament
import io.github.sceneview.utils.useFileBufferNotNull
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
import java.nio.ByteBuffer

/**
* Based on the [com.google.android.filament.textured.loadTexture]
*/
object TextureLoader {

suspend fun loadTexture(
suspend fun loadImageTexture(
context: Context,
lifecycle: Lifecycle,
textureFileLocation: String,
type: TextureType
imageFileLocation: String,
type: TextureType = TextureType.COLOR
): Texture? =
context.useFileBufferNotNull(textureFileLocation) { buffer ->
val bitmap = BitmapFactory.decodeByteArray(
buffer.array(),
0,
buffer.capacity(),
BitmapFactory.Options().apply {
// Color is the only type of texture we want to pre-multiply with the alpha
// channel. Pre-multiplication is the default behavior, so we need to turn it
// off here
inPremultiplied = type == TextureType.COLOR
})
Texture.Builder()
.width(bitmap.width)
.height(bitmap.height)
.sampler(Texture.Sampler.SAMPLER_2D)
.format(internalFormat(type))
// This tells Filament to figure out the number of mip levels
.levels(0xff)
.build(lifecycle).apply {
// TextureHelper offers a method that skips the copy of the bitmap into a
// ByteBuffer
TextureHelper.setBitmap(Filament.engine, this, 0, bitmap)
generateMipmaps(Filament.engine)
}
context.useFileBufferNotNull(imageFileLocation) { buffer ->
withContext(Dispatchers.Main) {
createImageTexture(lifecycle, buffer, type)
}
}

fun loadImageTextureAsync(
context: Context,
lifecycle: Lifecycle,
imageFileLocation: String,
type: TextureType = TextureType.COLOR,
result: (Texture?) -> Unit
) = lifecycle.coroutineScope.launchWhenCreated {
result(loadImageTexture(context, lifecycle, imageFileLocation, type))
}

fun createImageTexture(
lifecycle: Lifecycle? = null,
imageBuffer: ByteBuffer,
type: TextureType = TextureType.COLOR,
): Texture {
val bitmap = BitmapFactory.decodeByteArray(
imageBuffer.array(),
0,
imageBuffer.capacity(),
BitmapFactory.Options().apply {
// Color is the only type of texture we want to pre-multiply with the alpha
// channel. Pre-multiplication is the default behavior, so we need to turn it
// off here
inPremultiplied = type == TextureType.COLOR
})
return Texture.Builder()
.width(bitmap.width)
.height(bitmap.height)
.sampler(Texture.Sampler.SAMPLER_2D)
.format(internalFormat(type))
// This tells Filament to figure out the number of mip levels
.levels(0xff)
.build(lifecycle).apply {
// TextureHelper offers a method that skips the copy of the bitmap into a
// ByteBuffer
TextureHelper.setBitmap(Filament.engine, this, 0, bitmap)
generateMipmaps(Filament.engine)
}
}

private fun internalFormat(type: TextureType) = when (type) {
TextureType.COLOR -> Texture.InternalFormat.SRGB8_A8
TextureType.NORMAL -> Texture.InternalFormat.RGBA8
Expand Down

0 comments on commit f724780

Please sign in to comment.