Files
kotlin-fork/idea/testData/perfTest/native/OpenGLES/src/main/App.kt
T

236 lines
9.2 KiB
Kotlin
Vendored

/*
* Copyright 2010-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
* that can be found in the license/LICENSE.txt file.
*/
@file:Suppress("PackageDirectoryMismatch", "RemoveRedundantCallsOfConversionMethods", "unused", "CanBeParameter")
package perfTestPackage1 // this package is mandatory
import kotlinx.cinterop.FloatVar
import kotlinx.cinterop.allocArray
import kotlinx.cinterop.cValuesOf
import kotlinx.cinterop.memScoped
import kotlinx.cinterop.set
import kotlinx.cinterop.toCValues
import platform.gles.GL_COLOR_BUFFER_BIT
import platform.gles.GL_CULL_FACE
import platform.gles.GL_CW
import platform.gles.GL_DEPTH_BUFFER_BIT
import platform.gles.GL_DEPTH_TEST
import platform.gles.GL_DIFFUSE
import platform.gles.GL_DITHER
import platform.gles.GL_FASTEST
import platform.gles.GL_FLOAT
import platform.gles.GL_FRONT_AND_BACK
import platform.gles.GL_LIGHT0
import platform.gles.GL_LIGHTING
import platform.gles.GL_MODELVIEW
import platform.gles.GL_NORMAL_ARRAY
import platform.gles.GL_PERSPECTIVE_CORRECTION_HINT
import platform.gles.GL_POSITION
import platform.gles.GL_PROJECTION
import platform.gles.GL_SHININESS
import platform.gles.GL_SMOOTH
import platform.gles.GL_SPECULAR
import platform.gles.GL_TEXTURE_2D
import platform.gles.GL_TEXTURE_COORD_ARRAY
import platform.gles.GL_TRIANGLES
import platform.gles.GL_UNSIGNED_BYTE
import platform.gles.GL_VERTEX_ARRAY
import platform.gles.glClear
import platform.gles.glClearColor
import platform.gles.glDisable
import platform.gles.glDrawElements
import platform.gles.glEnable
import platform.gles.glEnableClientState
import platform.gles.glFrontFace
import platform.gles.glFrustumf
import platform.gles.glHint
import platform.gles.glLightfv
import platform.gles.glLoadIdentity
import platform.gles.glMaterialf
import platform.gles.glMaterialfv
import platform.gles.glMatrixMode
import platform.gles.glMultMatrixf
import platform.gles.glNormalPointer
import platform.gles.glPopMatrix
import platform.gles.glPushMatrix
import platform.gles.glShadeModel
import platform.gles.glTexCoordPointer
import platform.gles.glTranslatef
import platform.gles.glVertexPointer
import platform.gles.glViewport
import platform.posix.sqrtf
private const val WIDTH = 600
private const val HEIGHT = 800
private const val SCALE = 1.25f
fun main() = memScoped {
glDisable(GL_DITHER)
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST)
glClearColor(0.0f, 0.0f, 0.0f, 0.0f)
glEnable(GL_CULL_FACE)
glShadeModel(GL_SMOOTH)
glEnable(GL_DEPTH_TEST)
glViewport(0, 0, WIDTH, HEIGHT)
val ratio = WIDTH.toFloat() / HEIGHT
glMatrixMode(GL_PROJECTION)
glLoadIdentity()
glFrustumf(-ratio, ratio, -1.0f, 1.0f, 1.0f, 10.0f)
glMatrixMode(GL_MODELVIEW)
glTranslatef(0.0f, 0.0f, -2.0f)
glLightfv(GL_LIGHT0, GL_POSITION, cValuesOf(1.25f, 1.25f, -2.0f, 0.0f))
glEnable(GL_LIGHTING)
glEnable(GL_LIGHT0)
glEnable(GL_TEXTURE_2D)
glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, cValuesOf(0.0f, 1.0f, 1.0f, 1.0f))
glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, cValuesOf(0.3f, 0.3f, 0.3f, 1.0f))
glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 30.0f)
glPushMatrix()
glMatrixMode(GL_MODELVIEW)
val matrix = allocArray<FloatVar>(16)
for (i in 0..3)
for (j in 0..3)
matrix[i * 4 + j] = if (i == j) 1.0f else 0.0f
glMultMatrixf(matrix)
glClear((GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT).toUInt())
glEnableClientState(GL_VERTEX_ARRAY)
glEnableClientState(GL_NORMAL_ARRAY)
glEnableClientState(GL_TEXTURE_COORD_ARRAY)
val polygon = RegularPolyhedra.Dodecahedron
val vertices = mutableListOf<Float>()
val texCoords = mutableListOf<Float>()
val triangles = mutableListOf<Byte>()
val normals = mutableListOf<Float>()
val texturePoints = arrayOf(Vector2(0.0f, 0.2f), Vector2(0.0f, 0.8f), Vector2(0.6f, 1.0f), Vector2(1.0f, 0.5f), Vector2(0.8f, 0.0f))
for (face in polygon.faces) {
val u = polygon.vertices[face[2].toInt()] - polygon.vertices[face[1].toInt()]
val v = polygon.vertices[face[0].toInt()] - polygon.vertices[face[1].toInt()]
val normal = u.crossProduct(v).normalized()
val copiedFace = ByteArray(face.size)
for (j in face.indices) {
copiedFace[j] = (vertices.size / 4).toByte()
polygon.vertices[face[j].toInt()].copyCoordinatesTo(vertices)
vertices.add(SCALE)
normal.copyCoordinatesTo(normals)
texturePoints[j].copyCoordinatesTo(texCoords)
}
for (j in 1..face.size - 2) {
triangles.add(copiedFace[0])
triangles.add(copiedFace[j])
triangles.add(copiedFace[j + 1])
}
}
glFrontFace(GL_CW)
glVertexPointer(4, GL_FLOAT, 0, vertices.toFloatArray().toCValues().ptr)
glTexCoordPointer(2, GL_FLOAT, 0, texCoords.toFloatArray().toCValues().ptr)
glNormalPointer(GL_FLOAT, 0, normals.toFloatArray().toCValues().ptr)
glDrawElements(GL_TRIANGLES, triangles.size, GL_UNSIGNED_BYTE, triangles.toByteArray().toCValues().ptr)
glPopMatrix()
}
private class Vector2(val x: Float, val y: Float) {
val length by lazy { sqrtf(x * x + y * y) }
fun normalized(): Vector2 {
val len = length
return Vector2(x / len, y / len)
}
fun copyCoordinatesTo(arr: MutableList<Float>) {
arr.add(x)
arr.add(y)
}
operator fun minus(other: Vector2) = Vector2(x - other.x, y - other.y)
operator fun plus(other: Vector2) = Vector2(x + other.x, y + other.y)
operator fun times(other: Float) = Vector2(x * other, y * other)
operator fun div(other: Float) = Vector2(x / other, y / other)
companion object {
val Zero = Vector2(0.0f, 0.0f)
}
}
private class Vector3(val x: Float, val y: Float, val z: Float) {
val length by lazy { sqrtf(x * x + y * y + z * z) }
fun crossProduct(other: Vector3): Vector3 =
Vector3(y * other.z - z * other.y, z * other.x - x * other.z, x * other.y - y * other.x)
fun normalized(): Vector3 {
val len = length
return Vector3(x / len, y / len, z / len)
}
fun copyCoordinatesTo(arr: MutableList<Float>) {
arr.add(x)
arr.add(y)
arr.add(z)
}
operator fun minus(other: Vector3) = Vector3(x - other.x, y - other.y, z - other.z)
operator fun plus(other: Vector3) = Vector3(x + other.x, y + other.y, z + other.z)
}
private const val Zero = 0.0f
private const val DodeA = 0.93417235896f // (Sqrt(5) + 1) / (2 * Sqrt(3))
private const val DodeB = 0.35682208977f // (Sqrt(5) - 1) / (2 * Sqrt(3))
private const val DodeC = 0.57735026919f // 1 / Sqrt(3)
private const val IcosA = 0.52573111212f // Sqrt(5 - Sqrt(5)) / Sqrt(10)
private const val IcosB = 0.85065080835f // Sqrt(5 + Sqrt(5)) / Sqrt(10)
private enum class RegularPolyhedra(val vertices: Array<Vector3>, val faces: Array<ByteArray>) {
Dodecahedron(
arrayOf(
Vector3(-DodeA, Zero, DodeB), Vector3(-DodeA, Zero, -DodeB), Vector3(DodeA, Zero, -DodeB),
Vector3(DodeA, Zero, DodeB), Vector3(DodeB, -DodeA, Zero), Vector3(-DodeB, -DodeA, Zero),
Vector3(-DodeB, DodeA, Zero), Vector3(DodeB, DodeA, Zero), Vector3(Zero, DodeB, -DodeA),
Vector3(Zero, -DodeB, -DodeA), Vector3(Zero, -DodeB, DodeA), Vector3(Zero, DodeB, DodeA),
Vector3(-DodeC, -DodeC, DodeC), Vector3(-DodeC, -DodeC, -DodeC), Vector3(DodeC, -DodeC, -DodeC),
Vector3(DodeC, -DodeC, DodeC), Vector3(-DodeC, DodeC, DodeC), Vector3(-DodeC, DodeC, -DodeC),
Vector3(DodeC, DodeC, -DodeC), Vector3(DodeC, DodeC, DodeC)
),
arrayOf(
byteArrayOf(0, 12, 10, 11, 16), byteArrayOf(1, 17, 8, 9, 13), byteArrayOf(2, 14, 9, 8, 18),
byteArrayOf(3, 19, 11, 10, 15), byteArrayOf(4, 14, 2, 3, 15), byteArrayOf(5, 12, 0, 1, 13),
byteArrayOf(6, 17, 1, 0, 16), byteArrayOf(7, 19, 3, 2, 18), byteArrayOf(8, 17, 6, 7, 18),
byteArrayOf(9, 14, 4, 5, 13), byteArrayOf(10, 12, 5, 4, 15), byteArrayOf(11, 19, 7, 6, 16)
)),
Icosahedron(
arrayOf(
Vector3(-IcosA, Zero, IcosB), Vector3(IcosA, Zero, IcosB), Vector3(-IcosA, Zero, -IcosB),
Vector3(IcosA, Zero, -IcosB), Vector3(Zero, IcosB, IcosA), Vector3(Zero, IcosB, -IcosA),
Vector3(Zero, -IcosB, IcosA), Vector3(Zero, -IcosB, -IcosA), Vector3(IcosB, IcosA, Zero),
Vector3(-IcosB, IcosA, Zero), Vector3(IcosB, -IcosA, Zero), Vector3(-IcosB, -IcosA, Zero)
),
arrayOf(
byteArrayOf(1, 4, 0), byteArrayOf(4, 9, 0), byteArrayOf(4, 5, 9), byteArrayOf(8, 5, 4),
byteArrayOf(1, 8, 4), byteArrayOf(1, 10, 8), byteArrayOf(10, 3, 8), byteArrayOf(8, 3, 5),
byteArrayOf(3, 2, 5), byteArrayOf(3, 7, 2), byteArrayOf(3, 10, 7), byteArrayOf(10, 6, 7),
byteArrayOf(6, 11, 7), byteArrayOf(6, 0, 11), byteArrayOf(6, 1, 0), byteArrayOf(10, 1, 6),
byteArrayOf(11, 0, 9), byteArrayOf(2, 11, 9), byteArrayOf(5, 2, 9), byteArrayOf(11, 2, 7)
)
);
val verticesPerFace get() = faces[0].size
}