All Downloads are FREE. Search and download functionalities are using the official Maven repository.

commonMain.earth.worldwind.draw.DrawableStarField.kt Maven / Gradle / Ivy

package earth.worldwind.draw

import earth.worldwind.geom.Matrix4
import earth.worldwind.layer.starfield.StarFieldProgram
import earth.worldwind.render.Texture
import earth.worldwind.render.buffer.FloatBufferObject
import earth.worldwind.util.Logger
import earth.worldwind.util.Pool
import earth.worldwind.util.kgl.GL_ALIASED_POINT_SIZE_RANGE
import earth.worldwind.util.kgl.GL_FLOAT
import earth.worldwind.util.kgl.GL_POINTS
import kotlin.jvm.JvmStatic

open class DrawableStarField protected constructor(): Drawable {
    val matrix = Matrix4()
    var julianDate = 0.0
    var minMagnitude = 0.0f
    var maxMagnitude = 0.0f
    var numStars = 0
    var isShowSun = false
    var sunSize = 0.0f
    var sunTexture: Texture? = null
    var starsPositionsBuffer: FloatBufferObject? = null
    var sunPositionsBuffer: FloatBufferObject? = null
    var program: StarFieldProgram? = null
    private var pool: Pool? = null

    companion object {
        var maxGlPointSize = 0f

        @JvmStatic
        fun obtain(pool: Pool): DrawableStarField {
            val instance = pool.acquire() ?: DrawableStarField()
            instance.pool = pool
            return instance
        }
    }

    override fun recycle() {
        starsPositionsBuffer = null
        sunPositionsBuffer = null
        sunTexture = null
        program = null
        pool?.release(this)
        pool = null
    }

    override fun draw(dc: DrawContext) {
        val program = program ?: return // program unspecified
        if (!program.useProgram(dc)) return // program failed to build
        try {
            dc.gl.depthMask(false)
            drawStars(dc, program, starsPositionsBuffer)
            if (isShowSun) drawSun(dc, program, sunPositionsBuffer, sunTexture)
        } finally {
            dc.gl.depthMask(true)
        }
    }

    protected open fun drawStars(dc: DrawContext, program: StarFieldProgram, buffer: FloatBufferObject?) {
        if (buffer?.bindBuffer(dc) != true) return
        dc.gl.vertexAttribPointer(0, 4, GL_FLOAT, false, 0, 0)
        // This subtraction does not work properly on the GPU due to precision loss. It must be done on the CPU.
        program.loadModelviewProjection(matrix)
        program.loadNumDays((julianDate - 2451545.0).toFloat())
        program.loadMagnitudeRange(minMagnitude, maxMagnitude)
        program.loadTextureEnabled(false)
        dc.gl.drawArrays(GL_POINTS, 0, numStars)
    }

    protected open fun drawSun(
        dc: DrawContext, program: StarFieldProgram, sunBuffer: FloatBufferObject?, sunTexture: Texture?
    ) {
        if (maxGlPointSize == 0f) maxGlPointSize = dc.gl.getParameterfv(GL_ALIASED_POINT_SIZE_RANGE)[1]

        if (sunSize > maxGlPointSize) {
            Logger.log(Logger.WARN, "StarFieldLayer - sunSize is to big, max size allowed is: $maxGlPointSize")
        }

        if (sunBuffer?.bindBuffer(dc) != true) return
        if (sunTexture?.bindTexture(dc) != true) return
        dc.gl.vertexAttribPointer(0, 4, GL_FLOAT, false, 0, 0)
        program.loadTextureEnabled(true)
        dc.gl.drawArrays(GL_POINTS, 0, 1)
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy