commonMain.ru.casperix.opengl.renderer.texture.GLTexture2D.kt Maven / Gradle / Ivy
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.Texture2D
class GLTexture2D(val texture: Texture2D) : GLTexture {
private val logger = KotlinLogging.logger { }
private val handle = GLTextureHandlerProvider.next()
private var isDisposed = false
val isPowerOf2 get() = isPowerOf2(texture.map.width) && isPowerOf2(texture.map.height)
init {
glBindTexture(GL_TEXTURE_2D, handle)
upload()
texture.config.apply {
val actualMipMap = useMipMap && isPowerOf2
if (useMipMap != actualMipMap) {
logger.warn { "Mip-map not allowed for rectangle texture ${texture.map.name} (${texture.map.dimension}) " }
}
if (actualMipMap) {
glGenerateMipmap(GL_TEXTURE_2D)
}
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, asGLWrap(uWrap))
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, asGLWrap(vWrap))
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, asGLMinFilter(minFilter, actualMipMap))
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, asGLMagFilter(magFilter, actualMipMap))
}
logger.debug { "Texture created: ${toShortString()}" }
}
override fun dispose() {
glDeleteTexture(handle)
isDisposed = true
logger.debug { "Texture disposed: ${toShortString()}" }
}
private fun toShortString(): String {
return "id: $handle; size: ${texture.map.width}x${texture.map.height}"
}
private fun upload() {
val image = texture.map
val data = image.byteArray.data
val bytesPerPixel = image.pixelCodec.bytesPerPixel
val openGlFormat = when (bytesPerPixel) {
3 -> GL_RGB8
4 -> GL_RGBA8
else -> throw Exception("Unsupported bytesPerPixel: $bytesPerPixel")
}
val dataFormat = when (bytesPerPixel) {
3 -> GL_RGB
4 -> GL_RGBA
else -> throw Exception("Unsupported bytesPerPixel: $bytesPerPixel")
}
glTexImage2D(
GL_TEXTURE_2D,
0,
openGlFormat,
image.width,
image.height,
0,
dataFormat,
GL_UNSIGNED_BYTE,
data.asByteArray()
)
}
override fun bind(channel: Int) {
glActiveTexture(GL_TEXTURE0 + channel)
glBindTexture(GL_TEXTURE_2D, handle)
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy