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

commonMain.ru.casperix.opengl.renderer.texture.GLTexture2DArray.kt Maven / Gradle / Ivy

There is a newer version: 1.3.0
Show newest version
package ru.casperix.opengl.renderer.texture

import io.github.oshai.kotlinlogging.KotlinLogging
import ru.casperix.opengl.core.*
import ru.casperix.opengl.renderer.texture.GLTexture.Companion.asGLMagFilter
import ru.casperix.opengl.renderer.texture.GLTexture.Companion.asGLMinFilter
import ru.casperix.opengl.renderer.texture.GLTexture.Companion.asGLWrap
import ru.casperix.renderer.material.Texture2DArray
import ru.casperix.renderer.pixel_map.PixelMap

class GLTexture2DArray(val texture: Texture2DArray) : GLTexture {
    val logger = KotlinLogging.logger { }
    val handle = GLTextureHandlerProvider.next()

//	constructor(colorProvider: ColorCube) : this(colorProvider.minX, colorProvider.maxX, colorProvider.minY, colorProvider.maxY, colorProvider.minZ, colorProvider.maxZ)

    class PixelMap3D(val bytes: UByteArray, val width: Int, val height: Int, val depth: Int)

    init {
        glBindTexture(GL_TEXTURE_2D_ARRAY, handle)
        texture.config.apply {
            glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_S, asGLWrap(uWrap))
            glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_T, asGLWrap(vWrap))
            glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_R, asGLWrap(wWrap))
            glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, asGLMinFilter(minFilter, useMipMap))
            glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, asGLMagFilter(magFilter, useMipMap))
        }
        texture.apply {
            val bytes = toMap3D(maps)
            loadData(bytes, maps.size)
        }
        if (texture.config.useMipMap) {
            glGenerateMipmap(GL_TEXTURE_2D_ARRAY)
        }
        glBindTexture(GL_TEXTURE_2D_ARRAY, 0)
        logger.debug { "Texture created: ${toShortString()}"  }
    }


    override fun dispose() {
        glDeleteTexture(handle)

        logger.debug { "Texture disposed: ${toShortString()}"  }
    }

    private fun toShortString(): String {
        return "id: $handle; size: ${texture.maps.first().width}x${texture.maps.first().height}x${texture.maps.size}"
    }

    private fun toMap3D(maps: List): PixelMap3D {
        if (maps.isEmpty()) return PixelMap3D(UByteArray(0), 0, 0, 0)

        val first = maps.first()

        val size = first.byteArray.data.size
        val output = UByteArray(size * maps.size)

        maps.forEachIndexed { index, next ->
            if (next.pixelCodec != first.pixelCodec) {
                throw Exception("Expected all codec is: ${first.pixelCodec}. But actual codec is ${next.pixelCodec}")
            }
            if (next.byteArray.data.size != size) {
                throw Exception("Expected all size is: $size. But actual size is ${next.byteArray.data.size} for '${next.name}'")
            }
            next.byteArray.data.copyInto(output, index * size)
        }

        return PixelMap3D(output, first.width, first.height, maps.size)
    }

    private fun loadData(map: PixelMap3D, layerAmount: Int) {
        glTexImage3D(
            GL_TEXTURE_2D_ARRAY,
            0,
            GL_RGBA,
            map.width,
            map.height,
            layerAmount,
            0,
            GL_RGBA,
            GL_UNSIGNED_BYTE,
            map.bytes.toByteArray()
        )
    }

    override fun bind(channel: Int) {
        glActiveTexture(GL_TEXTURE0 + channel)
        glBindTexture(GL_TEXTURE_2D_ARRAY, handle)
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy