Mercurial > games > semicongine
diff src/zamikongine/shader.nim @ 32:9edca5dc4e93
add: working implementation of uniforms
author | Sam <sam@basx.dev> |
---|---|
date | Sat, 14 Jan 2023 23:34:50 +0700 |
parents | b1b05d4efb52 |
children | 94c38e4b5782 |
line wrap: on
line diff
--- a/src/zamikongine/shader.nim Sat Jan 14 14:15:50 2023 +0700 +++ b/src/zamikongine/shader.nim Sat Jan 14 23:34:50 2023 +0700 @@ -5,14 +5,16 @@ import ./vulkan_helpers +import ./glsl_helpers import ./vulkan import ./vertex +import ./descriptor import ./math/vector type AllowedUniformType = SomeNumber|Vec UniformSlot *[T:AllowedUniformType] = object - ShaderProgram*[Uniforms] = object + ShaderProgram*[VertexType, Uniforms] = object entryPoint*: string programType*: VkShaderStageFlagBits shader*: VkPipelineShaderStageCreateInfo @@ -58,7 +60,7 @@ ) i += 4 -proc initShaderProgram*[T](device: VkDevice, programType: static VkShaderStageFlagBits, shader: static string, entryPoint: static string="main"): ShaderProgram[T] = +proc initShaderProgram*[VertexType, Uniforms](device: VkDevice, programType: static VkShaderStageFlagBits, shader: static string, entryPoint: static string="main"): ShaderProgram[VertexType, Uniforms] = result.entryPoint = entryPoint result.programType = programType @@ -79,31 +81,63 @@ pName: cstring(result.entryPoint), # entry point for shader ) -func generateVertexShaderCode*[VertexType](entryPoint, positionAttrName, colorAttrName: static string): string {.compileTime.} = +func generateVertexShaderCode*[VertexType, Uniforms]( + shaderBody: static string = "", + entryPoint: static string = "main", + glslVersion: static string = "450" +): string {.compileTime.} = var lines: seq[string] - lines.add "#version 450" - # lines.add "layout(binding = 0) uniform UniformBufferObject { float dt; } ubo;" - lines.add generateGLSLDeclarations[VertexType]() + lines.add "#version " & glslVersion + lines.add "layout(row_major) uniform;" + lines.add generateGLSLUniformDeclarations[Uniforms]() + lines.add generateGLSLVertexDeclarations[VertexType]() lines.add "layout(location = 0) out vec3 fragColor;" lines.add "void " & entryPoint & "() {" + var hasPosition = 0 + var hasColor = 0 for name, value in VertexType().fieldPairs: - when typeof(value) is VertexAttribute and name == positionAttrName: - # lines.add " vec2 tmp = " & name & " * ubo.dt;" - lines.add " vec2 tmp = " & name & ";" - lines.add " gl_Position = vec4(tmp, 0.0, 1.0);" - when typeof(value) is VertexAttribute and name == colorAttrName: - lines.add " fragColor = " & name & ";" + when typeof(value) is PositionAttribute: + let glsltype = getGLSLType[getAttributeType(value)]() + lines.add &" {glsltype} in_position = " & name & ";" + if getAttributeType(value) is Vec2: + lines.add " vec4 out_position = vec4(in_position, 0.0, 1.0);" + elif getAttributeType(value) is Vec3: + lines.add " vec4 out_position = vec4(in_position, 1.0);" + elif getAttributeType(value) is Vec4: + lines.add " vec4 out_position = in_position;" + hasPosition += 1 + when typeof(value) is ColorAttribute: + let glsltype = getGLSLType[getAttributeType(value)]() + lines.add &" {glsltype} in_color = " & name & ";" + lines.add &" {glsltype} out_color = in_color;"; + hasColor += 1 + + lines.add shaderBody + lines.add " gl_Position = out_position;" + lines.add " fragColor = out_color;" lines.add "}" + if hasPosition != 1: + raise newException(Exception, fmt"VertexType needs to have exactly one attribute of type PositionAttribute (has {hasPosition})") + if hasColor != 1: + raise newException(Exception, fmt"VertexType needs to have exactly one attribute of type ColorAttribute (has {hasColor})") return lines.join("\n") -func generateFragmentShaderCode*[VertexType](entryPoint: static string): string {.compileTime.} = +func generateFragmentShaderCode*[VertexType]( + shaderBody: static string = "", + entryPoint: static string = "main", + glslVersion: static string = "450" +): string {.compileTime.} = var lines: seq[string] - lines.add "#version 450" + lines.add "#version " & glslVersion + lines.add "layout(row_major) uniform;" lines.add "layout(location = 0) in vec3 fragColor;" lines.add "layout(location = 0) out vec4 outColor;" lines.add "void " & entryPoint & "() {" - lines.add " outColor = vec4(fragColor, 1.0);" + lines.add " vec3 in_color = fragColor;" + lines.add " vec3 out_color = in_color;" + lines.add shaderBody + lines.add " outColor = vec4(out_color, 1.0);" lines.add "}" return lines.join("\n")