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

commonMain.korlibs.graphics.AGProgramWithUniform.kt Maven / Gradle / Ivy

There is a newer version: 4.0.10
Show newest version
package korlibs.graphics

import korlibs.datastructure.*
import korlibs.datastructure.iterators.*
import korlibs.graphics.shader.*

class AGProgramWithUniforms(val program: Program, val bufferCache: BufferCache = BufferCache()) {
    // Holder to reuse AGRichUniformBlockData and buffers between several programs
    class BufferCache {
        private val uniformBlocks = FastIdentityMap>()

        fun reset() {
            uniformBlocks.fastForEach { key, value -> value.reset() }
        }

        fun uploadUpdatedBuffers() {
            uniformBlocks.fastForEach { key, value -> value.upload() }
        }

        operator fun  get(block: T): UniformBlockBuffer =
            uniformBlocks.getOrPut(block) { UniformBlockBuffer(block) } as UniformBlockBuffer
    }

    val uniformLayouts = program.typedUniforms.map { it.block }.distinct()
    val maxLocation = uniformLayouts.maxOfOrNull { it.fixedLocation + 1 } ?: 0

    val uniformsBlocks = Array(maxLocation) { null }.also {
        for (layout in uniformLayouts) it[layout.fixedLocation] = layout
    }
    val uniformsBlocksData = Array?>(uniformsBlocks.size) {
        uniformsBlocks[it]?.let { bufferCache[it] }
    }
    private val agUniformBlockDatas: Array?> = Array(uniformsBlocks.size) { uniformsBlocksData[it]?.block?.let { UniformBlockBuffer(it) } }
    private val agBuffers = Array(uniformsBlocks.size) { uniformsBlocksData[it]?.agBuffer }
    private val agBufferIndices = IntArray(uniformsBlocks.size) { 0 }

    fun reset() {
        agUniformBlockDatas.fastForEach { it?.reset() }
    }

    fun createRef(): UniformBlocksBuffersRef {
        for (n in agBufferIndices.indices) agBufferIndices[n] = uniformsBlocksData[n]?.currentIndex ?: -1
        return UniformBlocksBuffersRef(agUniformBlockDatas, agBuffers, agBufferIndices.copyOf())
    }

    operator fun  get(block: T): UniformBlockBuffer {
        val rblock = uniformsBlocks.getOrNull(block.fixedLocation)
            ?: error("Can't find block '$block'")
        if (rblock !== block) error("Block $block not used in program")
        return uniformsBlocksData[block.fixedLocation]!! as UniformBlockBuffer
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy