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

commonMain.ru.casperix.opengl.renderer.impl.MaterialBinder.kt Maven / Gradle / Ivy

There is a newer version: 0.11.1
Show newest version
package ru.casperix.opengl.renderer.impl

import ru.casperix.opengl.core.*
import ru.casperix.opengl.renderer.exp.TileMapMaterial
import ru.casperix.opengl.renderer.TextureConfig
import ru.casperix.opengl.renderer.TextureProvider
import ru.casperix.opengl.renderer.shader.ShaderController
import ru.casperix.opengl.renderer.shader.ShaderUniform
import ru.casperix.opengl.renderer.texture.GLTexture
import ru.casperix.renderer.material.Material
import ru.casperix.renderer.material.SimpleMaterial

@ExperimentalUnsignedTypes
class MaterialBinder(config: TextureConfig) {
    private val textureBinder = TextureProvider()
    private var textureLayers = Array(80) { null }

    data class TextureLayer(val texture: GLTexture, val shader: ShaderUniform)

    fun setupMaterialAttributes(controller: ShaderController, material: Material) {
        (material as? SimpleMaterial)?.apply {
            color?.let {
                controller.uMaterialColor?.set(it.toColor4f())
            }
            albedoMap?.let {
                setTexture(controller.uAlbedoTexture, 0, textureBinder.getTexture(it))
            }

            normalMap?.let {
                setTexture(controller.uNormalTexture, 1, textureBinder.getTexture(it))
            }

            specularMap?.let {
                setTexture(controller.uSpecularTexture, 2, textureBinder.getTexture(it))
            }
        }
        (material as? TileMapMaterial)?.apply {
            textureArray.let {
                setTexture(controller.uTextureArray, 0, textureBinder.getTexture(it))
            }
            tileMap.let {
                setTexture(controller.uTileMapTexture, 1, textureBinder.getTexture(it))
            }
            controller.uTexScale?.set(texScale)
            controller.uTileSmoothMode?.set(smooth.ordinal)
        }

    }

    private fun setTexture(textureLocation: ShaderUniform?, textureChannel: Int, texture: GLTexture) {
        if (textureLocation == null) {
            return
        }
        if (textureChannel < 0 || textureChannel >= 80) {
            throw Error("Texture layer must be positive and smaller than 80")
        }

        val layer = TextureLayer(texture, textureLocation)

        if (textureLayers[textureChannel] == layer) return
        textureLayers[textureChannel] = layer

        textureLocation.set(textureChannel, texture)
    }

    fun unbind() {
        textureLayers.forEachIndexed { channel, textureLayer ->
            if (textureLayer != null) {
                glActiveTexture(GL_TEXTURE0 + channel)
                glBindTexture(GL_TEXTURE_2D, 0)
                glBindTexture(GL_TEXTURE_2D_ARRAY, 0)
                glBindTexture(GL_TEXTURE_CUBE_MAP, 0)
                textureLayers[channel] = null
            }
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy