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

commonMain.ru.casperix.opengl.renderer.ShaderProvider.kt Maven / Gradle / Ivy

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

import io.github.oshai.kotlinlogging.KotlinLogging
import ru.casperix.opengl.core.misc.ShaderFactory
import ru.casperix.opengl.renderer.exp.TileMapMaterial
import ru.casperix.opengl.renderer.generated.Resources
import ru.casperix.opengl.renderer.impl.ShaderAttributes
import ru.casperix.opengl.renderer.shader.ShaderBuffer
import ru.casperix.opengl.renderer.shader.ShaderController
import ru.casperix.renderer.material.Material
import ru.casperix.renderer.material.SimpleMaterial
import ru.casperix.renderer.vector.vertex.ColorFormat
import ru.casperix.renderer.vector.vertex.VertexAttributes

@ExperimentalUnsignedTypes
class ShaderProvider(val config: OpenGlRendererConfig) {
    private val logger = KotlinLogging.logger { }

    private val attributesByVertexAndMaterial = mutableMapOf()
    private val shaderByAttributes = mutableMapOf()

    private val simpleShader = ShaderReference(Resources.shader2d_vert, Resources.shader2d_frag)

    class ShaderReference(val vertexShaderSource: String, val fragmentShaderSource: String)

    data class ShaderKey(val attributes: VertexAttributes, val material: Material)

    fun getOrCreate(
        vertexAttributes: VertexAttributes,
        material: Material
    ): ShaderController {
//        val shaderAttributes = attributesByVertexAndMaterial.getOrPut(ShaderKey(vertexAttributes, material)) {
//            createShaderAttributes(vertexAttributes, material)
//        }
        val shaderAttributes = createShaderAttributes(vertexAttributes, material)

        return shaderByAttributes.getOrPut(shaderAttributes) {
            createSimpleShader(shaderAttributes)
        }
    }

    private fun createShaderAttributes(vertexAttributes: VertexAttributes, material: Material): ShaderAttributes {
        return when (material) {
            is SimpleMaterial -> {
                ShaderAttributes(
                    hasMaterialColor = material.color != null,
                    hasMaterialAlbedoMap = material.albedoMap != null,
                    hasMaterialNormal = material.normalMap != null,
                    hasMaterialNormalMap = material.normalMap != null,
                    hasVertexColor3 = vertexAttributes.color == ColorFormat.BGR || vertexAttributes.color == ColorFormat.RGB,
                    hasVertexColor4 = vertexAttributes.color == ColorFormat.BGRA || vertexAttributes.color == ColorFormat.RGBA,
                )
            }

            is TileMapMaterial -> {
                ShaderAttributes(
                    hasMaterialTileMap = true,
                    hasMaterialTileGird = material.gird,
                    hasMaterialNormal = true,
                    hasMaterialTextureArray = true,
                )
            }

            else -> {
                ShaderAttributes()
            }
        }
    }

    private fun createSimpleShader(shaderAttributes: ShaderAttributes): ShaderController = shaderAttributes.run {
        logger.info { "createShader with $shaderAttributes" }

        val shaderDefines = mutableSetOf()

        if (config.discardAlpha) {
            shaderDefines += "CONFIG_DISCARD_ALPHA"
        }
        if (config.gammaCorrection) {
            shaderDefines += "CONFIG_GAMMA_CORRECTION"
        }
        if (hasMaterialColor) {
            shaderDefines += "MATERIAL_COLOR"
        }
        if (hasMaterialAlbedoMap) {
            shaderDefines += "MATERIAL_ALBEDO_MAP"
        }
        if (hasMaterialTileMap) {
            shaderDefines += "MATERIAL_TILE_MAP"
        }
        if (hasMaterialTileGird) {
            shaderDefines += "MATERIAL_TILE_GIRD"
        }
        if (hasMaterialTextureArray) {
            shaderDefines += "MATERIAL_TEXTURE_ARRAY"
        }
        if (hasMaterialNormal) {
            shaderDefines += "MATERIAL_NORMAL"
        }
        if (hasMaterialNormalMap) {
            shaderDefines += "MATERIAL_NORMAL_MAP"
        }
        if (hasMaterialSpecularMap) {
            shaderDefines += "MATERIAL_SPECULAR_MAP"
        }
        if (hasMaterialAlbedoMap || hasMaterialNormalMap || hasMaterialSpecularMap || hasMaterialTextureArray) {
            shaderDefines += "VERTEX_TEXTURE_COORD"
        }
        if (hasVertexColor) {
            shaderDefines += "VERTEX_COLOR"
        }
        if (hasVertexColor3) {
            shaderDefines += "VERTEX_COLOR3"
        }
        if (hasVertexColor4) {
            shaderDefines += "VERTEX_COLOR4"
        }

        val vertexShader = ShaderFactory.setup(simpleShader.vertexShaderSource, shaderDefines)
        val fragmentShader = ShaderFactory.setup(simpleShader.fragmentShaderSource, shaderDefines)

        val buffer = ShaderBuffer(vertexShader, fragmentShader, null)
        return ShaderController(buffer, this)

    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy