mirror of
https://github.com/curioustorvald/Terrarum.git
synced 2026-06-11 02:54:04 +09:00
268 lines
8.7 KiB
Kotlin
268 lines
8.7 KiB
Kotlin
package net.torvald.terrarum.tests
|
|
|
|
import com.badlogic.gdx.Gdx
|
|
import com.badlogic.gdx.Input
|
|
import com.badlogic.gdx.InputAdapter
|
|
import com.badlogic.gdx.ScreenAdapter
|
|
import com.badlogic.gdx.backends.lwjgl.LwjglApplication
|
|
import com.badlogic.gdx.backends.lwjgl.LwjglApplicationConfiguration
|
|
import com.badlogic.gdx.graphics.Color
|
|
import com.badlogic.gdx.graphics.OrthographicCamera
|
|
import com.badlogic.gdx.graphics.Pixmap
|
|
import com.badlogic.gdx.graphics.Texture
|
|
import com.badlogic.gdx.graphics.g2d.SpriteBatch
|
|
import com.badlogic.gdx.graphics.glutils.ShaderProgram
|
|
import com.sudoplay.joise.Joise
|
|
import com.sudoplay.joise.module.ModuleBasisFunction
|
|
import com.sudoplay.joise.module.ModuleFractal
|
|
import com.sudoplay.joise.module.ModuleScaleDomain
|
|
import com.sudoplay.joise.module.ModuleScaleOffset
|
|
import net.torvald.random.HQRNG
|
|
import net.torvald.terrarum.AppLoader
|
|
import net.torvald.terrarum.AppLoader.printdbg
|
|
import net.torvald.terrarum.Terrarum
|
|
import net.torvald.terrarum.concurrent.BlockingThreadPool
|
|
import net.torvald.terrarum.concurrent.RunnableFun
|
|
import net.torvald.terrarum.concurrent.ParallelUtils.sliceEvenly
|
|
import net.torvald.terrarum.concurrent.ThreadParallel
|
|
import net.torvald.terrarum.inUse
|
|
import net.torvald.terrarum.modulebasegame.Ingame
|
|
import net.torvald.terrarum.roundInt
|
|
import kotlin.math.absoluteValue
|
|
import kotlin.system.measureNanoTime
|
|
import kotlin.system.measureTimeMillis
|
|
|
|
/**
|
|
* Created by minjaesong on 2018-12-14.
|
|
*/
|
|
class NoiseGenerator : ScreenAdapter() {
|
|
|
|
lateinit var batch: SpriteBatch
|
|
lateinit var camera: OrthographicCamera
|
|
lateinit var pixmap: Pixmap
|
|
lateinit var texture: Texture
|
|
private val IMAGE_SIZE = 1024
|
|
private val IMAGE_SIZEF = IMAGE_SIZE.toFloat()
|
|
private val IMAGE_SIZED = IMAGE_SIZE.toDouble()
|
|
private val RNG = HQRNG()
|
|
|
|
override fun show() {
|
|
Gdx.input.inputProcessor = NoiseGeneratorController(this)
|
|
|
|
batch = SpriteBatch()
|
|
camera = OrthographicCamera(AppLoader.appConfig.width.toFloat(), AppLoader.appConfig.height.toFloat())
|
|
|
|
camera.setToOrtho(true, AppLoader.appConfig.width.toFloat(), AppLoader.appConfig.height.toFloat())
|
|
camera.update()
|
|
Gdx.gl20.glViewport(0, 0, AppLoader.appConfig.width, AppLoader.appConfig.height)
|
|
|
|
pixmap = Pixmap(IMAGE_SIZE, IMAGE_SIZE, Pixmap.Format.RGBA8888)
|
|
texture = Texture(1, 1, Pixmap.Format.RGBA8888)
|
|
|
|
batch.projectionMatrix = camera.combined
|
|
|
|
println("Test runs: ${testSets.size * samplingCount}")
|
|
println("Warmup runs: $warmupTries")
|
|
}
|
|
|
|
var regenerate = true
|
|
|
|
private var pixelsInSingleJob = (IMAGE_SIZE * IMAGE_SIZE) / 16 // CHANGE THIS VALUE HERE
|
|
|
|
private val jobsCount: Int
|
|
get() = (IMAGE_SIZE * IMAGE_SIZE) / pixelsInSingleJob
|
|
private val rawPixelsList: List<IntRange>
|
|
get() = (0 until IMAGE_SIZE * IMAGE_SIZE).sliceEvenly(jobsCount)
|
|
private fun makeGenFun(seed: Long, index: Int) = { //i: Int ->
|
|
val module = ModuleFractal()
|
|
module.setType(ModuleFractal.FractalType.BILLOW)
|
|
module.setAllSourceBasisTypes(ModuleBasisFunction.BasisType.GRADIENT)
|
|
module.setAllSourceInterpolationTypes(ModuleBasisFunction.InterpolationType.QUINTIC)
|
|
module.setNumOctaves(10)
|
|
module.setFrequency(8.0)
|
|
module.seed = seed
|
|
|
|
val moduleScale = ModuleScaleOffset()
|
|
moduleScale.setSource(module)
|
|
moduleScale.setScale(0.5)
|
|
moduleScale.setOffset(0.0)
|
|
|
|
val noiseModule = Joise(moduleScale)
|
|
|
|
for (c in rawPixelsList[index]) {
|
|
val x = c % IMAGE_SIZE
|
|
val y = c / IMAGE_SIZE
|
|
val uvX = x / IMAGE_SIZED
|
|
val uvY = y / IMAGE_SIZED
|
|
|
|
val noiseValue = noiseModule.get(uvX, uvY).absoluteValue
|
|
val rgb = (noiseValue * 255.0).roundInt()
|
|
|
|
pixmap.drawPixel(x, y, (rgb shl 24) or (rgb shl 16) or (rgb shl 8) or 0xFF)
|
|
}
|
|
}
|
|
|
|
private var timerStart = 0L
|
|
private var timerFired = false
|
|
|
|
override fun render(delta: Float) {
|
|
Gdx.graphics.setTitle(Ingame.getCanonicalTitle())
|
|
|
|
|
|
updateTestGovernor(delta)
|
|
|
|
|
|
// regen
|
|
if (timerFired && BlockingThreadPool.allFinished()) {
|
|
timerFired = false
|
|
|
|
totalTestsDone += 1
|
|
}
|
|
|
|
if (regenerate && BlockingThreadPool.allFinished()) {
|
|
//printdbg(this, "Reticulating splines...")
|
|
|
|
regenerate = false
|
|
// don't join while rendering noise
|
|
|
|
timerStart = System.currentTimeMillis()
|
|
timerFired = true
|
|
|
|
val seed = RNG.nextLong()
|
|
val jobs = List(jobsCount) { makeGenFun(seed, it) }
|
|
BlockingThreadPool.setTasks(jobs, "")
|
|
BlockingThreadPool.startAllWaitForDie()
|
|
}
|
|
|
|
|
|
// render
|
|
texture.dispose()
|
|
texture = Texture(pixmap)
|
|
|
|
batch.inUse {
|
|
batch.color = Color.WHITE
|
|
batch.draw(texture, 0f, 0f)
|
|
|
|
batch.color = Color.CYAN
|
|
Terrarum.fontGame.draw(batch, "Tests: $totalTestsDone / ${testSets.size * samplingCount}", 10f, 10f)
|
|
}
|
|
|
|
}
|
|
|
|
//private val testSets = listOf(1, 2, 3, 4, 6, 8, 12, 16, 24, 32, 48, 64, 96, 128, 192, 256, 384, 512, 768, 1024, 1536, 2048, 3072, 4096, 6144, 8192)//, 12288, 16384, 24576, 32768, 49152, 65536)
|
|
private val testSets = listOf(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16)
|
|
private val samplingCount = 20
|
|
private var totalTestsDone = 0
|
|
private val rawTimerRecords = ArrayList<Long>()
|
|
|
|
private var warmupDone = false
|
|
private val warmupTries = (testSets.size * samplingCount) / 4
|
|
private var constructOnce = false
|
|
|
|
private val timeWhenTestBegun = System.currentTimeMillis()
|
|
|
|
private var wholeJobTimer = 0L
|
|
|
|
private fun updateTestGovernor(delta: Float) {
|
|
// cut the warm-up {
|
|
if (!warmupDone && totalTestsDone >= warmupTries) {
|
|
println("######## WARMUP DONE, THE TEST BEGINS HERE ########")
|
|
totalTestsDone = 0
|
|
//rawTimerRecords.clear()
|
|
warmupDone = true
|
|
}
|
|
|
|
|
|
// time to end the test
|
|
if (totalTestsDone == testSets.size * samplingCount) {
|
|
println("Test completed:")
|
|
println("Total tests done = $totalTestsDone")
|
|
|
|
// print a table
|
|
println("Timer raw:")
|
|
rawTimerRecords.forEachIndexed { index, l ->
|
|
if (index < rawTimerRecords.size - testSets.size) {
|
|
println("* $l")
|
|
}
|
|
else {
|
|
println("$l")
|
|
}
|
|
}
|
|
|
|
// k thx bye
|
|
val timeWasted = (System.currentTimeMillis() - timeWhenTestBegun) / 1000
|
|
println("Total testing time: " +
|
|
"${timeWasted.div(60).toString().padStart(2, '0')}:" +
|
|
"${timeWasted.rem(60).toString().padStart(2, '0')}")
|
|
|
|
System.exit(0)
|
|
}
|
|
// time to construct a new test
|
|
if (totalTestsDone % samplingCount == 0 && BlockingThreadPool.allFinished()) {
|
|
pixelsInSingleJob = (IMAGE_SIZE * IMAGE_SIZE) / testSets[totalTestsDone / samplingCount]
|
|
|
|
|
|
if (!constructOnce) {
|
|
if (warmupDone)
|
|
println("Preparing test for ${testSets[totalTestsDone / samplingCount]} task sets")
|
|
else
|
|
println("This is warm-up, task sets: $${testSets[totalTestsDone / samplingCount]}")
|
|
|
|
val endTime = System.currentTimeMillis()
|
|
rawTimerRecords.add(endTime - wholeJobTimer)
|
|
println("> Timer end: $endTime")
|
|
wholeJobTimer = endTime
|
|
println("> Timer start: $wholeJobTimer")
|
|
|
|
constructOnce = true
|
|
}
|
|
}
|
|
|
|
// auto-press SPACE
|
|
if (BlockingThreadPool.allFinished()) {
|
|
regenerate = true
|
|
constructOnce = false
|
|
}
|
|
}
|
|
|
|
override fun pause() {
|
|
super.pause()
|
|
}
|
|
|
|
override fun resume() {
|
|
super.resume()
|
|
}
|
|
|
|
override fun resize(width: Int, height: Int) {
|
|
super.resize(width, height)
|
|
}
|
|
|
|
override fun dispose() {
|
|
pixmap.dispose()
|
|
texture.dispose()
|
|
}
|
|
}
|
|
|
|
class NoiseGeneratorController(val host: NoiseGenerator) : InputAdapter() {
|
|
override fun keyDown(keycode: Int): Boolean {
|
|
if (keycode == Input.Keys.SPACE) {
|
|
host.regenerate = true
|
|
}
|
|
return true
|
|
}
|
|
}
|
|
|
|
fun main(args: Array<String>) {
|
|
ShaderProgram.pedantic = false
|
|
|
|
val appConfig = LwjglApplicationConfiguration()
|
|
appConfig.vSyncEnabled = false
|
|
appConfig.resizable = false//true;
|
|
appConfig.width = 1024
|
|
appConfig.height = 1024
|
|
appConfig.backgroundFPS = 9999
|
|
appConfig.foregroundFPS = 9999
|
|
appConfig.forceExit = false
|
|
|
|
LwjglApplication(AppLoader(appConfig, NoiseGenerator()), appConfig)
|
|
} |