Try create image-viewer use Kotlin & lib: Filament, i follow c++ example cpp & material image.mat, convert to Kotlin but it doesn't work
My code: Mesh:
private fun createMesh() {
val intSize = 4
val floatSize = 4
val shortSize = 2
val vertexSize = 4 * floatSize
// Define a vertex and a function to put a vertex in a ByteBuffer
data class Vertex(val x: Float, val y: Float, val z: Float, val w: Float)
fun ByteBuffer.put(v: Vertex): ByteBuffer {
putFloat(v.x)
putFloat(v.y)
putFloat(v.z)
putFloat(v.w)
return this
}
val vertexCount = 3
val vertexData = ByteBuffer.allocate(vertexCount * vertexSize)
// It is important to respect the native byte order
.order(ByteOrder.nativeOrder())
.put(Vertex(-1.0f, -1.0f, 1.0f, 1.0f))
.put(Vertex(3.0f, -1.0f, 1.0f, 1.0f))
.put(Vertex(-1.0f, 3.0f, 1.0f, 1.0f))
// Make sure the cursor is pointing in the right place in the byte buffer
.flip()
vertexBuffer = VertexBuffer.Builder()
.bufferCount(1)
.vertexCount(vertexCount)
.attribute(VertexAttribute.POSITION, 0, AttributeType.FLOAT4, 0, vertexSize)
.build(engine)
vertexBuffer.setBufferAt(engine, 0, vertexData)
val indexData = ByteBuffer.allocate(3 * shortSize)
.order(ByteOrder.nativeOrder())
.putShort(0)
.putShort(1)
.putShort(2)
.flip()
indexBuffer = IndexBuffer.Builder()
.indexCount(3)
.bufferType(IndexBuffer.Builder.IndexType.USHORT)
.build(engine)
indexBuffer.setBuffer(engine, indexData)
}
Load Material
private fun loadMaterial() {
readUncompressedAsset("materials/image.filamat").let {
val texture = loadTexture(engine, resources, R.drawable.bg, TextureType.COLOR)
material = Material.Builder().payload(it, it.remaining()).build(engine)
val sampler = TextureSampler()
sampler.magFilter = TextureSampler.MagFilter.LINEAR
sampler.minFilter = TextureSampler.MinFilter.LINEAR_MIPMAP_LINEAR
sampler.wrapModeS = TextureSampler.WrapMode.REPEAT
sampler.wrapModeT = TextureSampler.WrapMode.REPEAT
material.setDefaultParameter("image", texture, sampler)
material.setDefaultParameter("transform", MaterialInstance.FloatElement.MAT3, Mat3().toFloatArray(), 0, 9)
material.setDefaultParameter("showImage", 1)
material.setDefaultParameter("backgroundColor", MaterialInstance.FloatElement.FLOAT3, Float3(0f, 0f ,0f), 3)
}
}
renderable
renderable = EntityManager.get().create()
RenderableManager.Builder(1)
.boundingBox(Box(0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1f))
.material(0, material.defaultInstance)
.geometry(0, PrimitiveType.TRIANGLES, vertexBuffer, indexBuffer, 0, 3)
.culling(false)
.build(engine, renderable)
scene.addEntity(renderable)
That always crash with error:
showImage uniform not exist
If i try change image.mat always show image and don't require background color, apps not crash but dont render anything.
image.mat after change:
material {
name : Image,
parameters :
[
{
type : sampler2d,
name : image
}
],
variables : [ imageUV ],
vertexDomain : device,
depthWrite : false,
shadingModel : unlit,
variantFilter : [ skinning, shadowReceiver, vsm ],
culling: none
}
vertex {
void materialVertex(inout MaterialVertexInputs material) {
material.imageUV.st = getPosition().st * 0.5 + 0.5;
}
}
fragment {
void material(inout MaterialInputs material) {
prepareMaterial(material);
vec4 bg = vec4(0.0, 0.0, 0.0, 1.0);
highp vec2 uv = vec3(saturate(variable_imageUV.st), 1.0).st;
uv.t = 1.0 - uv.t;
vec4 color = max(texture(materialParams_image, uv.st), 0.0);
color.rgb *= color.a;
// Manual, pre-multiplied srcOver with opaque destination optimization
material.baseColor.rgb = color.rgb + bg.rgb * (1.0 - color.a);
}
}
I dont know why it crash while showImage exist ? while i change image.mat, it can run but why didn't render anything ?