私の目的は、ここの Android OpenGL ES チュートリアルからの形状作成を一般化することです : http://developer.android.com/training/graphics/opengl/shapes.html
val squareCoords = Array( -0.5f, 0.5f, 0.0f, // top left
-0.5f, -0.5f, 0.0f, // bottom left
0.5f, -0.5f, 0.0f, // bottom right
0.5f, 0.5f, 0.0f ) // top right
val vertexBuffer = ByteBuffer.allocateDirect(
// (# of coordinate values * 4 bytes per float)
squareCoords.length * 4)
.order(ByteOrder.nativeOrder())
.asFloatBuffer()
.put(squareCoords)
.position(0)
そのため、float サイズはハードコーディングされています。しかし、私もいくつかの短い配列を持っています:
val drawOrder = Array[Short] ( 0, 1, 2, 0, 2, 3 )
val drawListBuffer = ByteBuffer.allocateDirect(
// (# of coordinate values * 2 bytes per short)
drawOrder.length * 2)
.order(ByteOrder.nativeOrder())
.asShortBuffer()
drawListBuffer.put(drawOrder)
drawListBuffer.position(0)
コードは似ていますが、課題の部分は、この場合、適切なメソッド asFloatBuffer()/asShortBuffer() を選択し、適切なプリミティブ値を使用することです。
この問題を解決するために、次のコードを書きました。
import scala.reflect.runtime.universe._
implicit class SByteBuffer[T <: AnyVal : TypeTag] (coords: Array[T]) {
private val length = coords.length
def buffer(): Buffer = {
def allocateBb(mod: Int) = {
ByteBuffer.allocateDirect(length * mod)
.order(ByteOrder.nativeOrder())
}
val buffer = typeOf[T] match {
case t if t =:= typeOf[Float] => allocateBb(4).asFloatBuffer().put(coords.asInstanceOf[Array[Float]])
case t if t =:= typeOf[Short] => allocateBb(2).asShortBuffer().put(coords.asInstanceOf[Array[Short]])
}
buffer.position(0)
}
}
val squareCoords = Array( -0.5f, 0.5f, 0.0f, // top left
-0.5f, -0.5f, 0.0f, // bottom left
0.5f, -0.5f, 0.0f, // bottom right
0.5f, 0.5f, 0.0f ) // top right
val vertexBuffer = squareCoords.buffer()
しかし、複雑すぎるようで、コードの繰り返しがあります。このコードをリファクタリングしてより簡潔に見えるようにし、実行時の型チェックをなくす方法についてアドバイスをいただけますか?