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

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

The newest version!
package ru.casperix.opengl.renderer

import ru.casperix.opengl.renderer.exp.TileMapMaterial
import ru.casperix.opengl.renderer.generated.Resources
import ru.casperix.opengl.core.misc.ShaderFactory
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 shaderMap = 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 {
        return shaderMap.getOrPut(ShaderKey(vertexAttributes, material)) {
            val attributes = if (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,
                )
            } else if (material is TileMapMaterial) {
                ShaderAttributes(
                    hasMaterialTileMap = true,
                    hasMaterialTileGird = material.gird,
                    hasMaterialNormal = true,
                    hasMaterialTextureArray = true,
                )
            } else {
                ShaderAttributes()
            }
            createSimpleShader(attributes)
        }
    }

    private fun createSimpleShader(shaderAttributes: ShaderAttributes): ShaderController = shaderAttributes.run {
        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