Mercurial > games > semicongine
comparison 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 |
comparison
equal
deleted
inserted
replaced
| 31:0996104ad066 | 32:9edca5dc4e93 |
|---|---|
| 3 import std/tables | 3 import std/tables |
| 4 import std/compilesettings | 4 import std/compilesettings |
| 5 | 5 |
| 6 | 6 |
| 7 import ./vulkan_helpers | 7 import ./vulkan_helpers |
| 8 import ./glsl_helpers | |
| 8 import ./vulkan | 9 import ./vulkan |
| 9 import ./vertex | 10 import ./vertex |
| 11 import ./descriptor | |
| 10 import ./math/vector | 12 import ./math/vector |
| 11 | 13 |
| 12 type | 14 type |
| 13 AllowedUniformType = SomeNumber|Vec | 15 AllowedUniformType = SomeNumber|Vec |
| 14 UniformSlot *[T:AllowedUniformType] = object | 16 UniformSlot *[T:AllowedUniformType] = object |
| 15 ShaderProgram*[Uniforms] = object | 17 ShaderProgram*[VertexType, Uniforms] = object |
| 16 entryPoint*: string | 18 entryPoint*: string |
| 17 programType*: VkShaderStageFlagBits | 19 programType*: VkShaderStageFlagBits |
| 18 shader*: VkPipelineShaderStageCreateInfo | 20 shader*: VkPipelineShaderStageCreateInfo |
| 19 uniforms*: Uniforms | 21 uniforms*: Uniforms |
| 20 | 22 |
| 56 (uint32(shaderbinary[i + 2]) shl 16) or | 58 (uint32(shaderbinary[i + 2]) shl 16) or |
| 57 (uint32(shaderbinary[i + 3]) shl 24) | 59 (uint32(shaderbinary[i + 3]) shl 24) |
| 58 ) | 60 ) |
| 59 i += 4 | 61 i += 4 |
| 60 | 62 |
| 61 proc initShaderProgram*[T](device: VkDevice, programType: static VkShaderStageFlagBits, shader: static string, entryPoint: static string="main"): ShaderProgram[T] = | 63 proc initShaderProgram*[VertexType, Uniforms](device: VkDevice, programType: static VkShaderStageFlagBits, shader: static string, entryPoint: static string="main"): ShaderProgram[VertexType, Uniforms] = |
| 62 result.entryPoint = entryPoint | 64 result.entryPoint = entryPoint |
| 63 result.programType = programType | 65 result.programType = programType |
| 64 | 66 |
| 65 const constcode = compileGLSLToSPIRV(programType, shader, entryPoint) | 67 const constcode = compileGLSLToSPIRV(programType, shader, entryPoint) |
| 66 var code = constcode | 68 var code = constcode |
| 77 stage: programType, | 79 stage: programType, |
| 78 module: shaderModule, | 80 module: shaderModule, |
| 79 pName: cstring(result.entryPoint), # entry point for shader | 81 pName: cstring(result.entryPoint), # entry point for shader |
| 80 ) | 82 ) |
| 81 | 83 |
| 82 func generateVertexShaderCode*[VertexType](entryPoint, positionAttrName, colorAttrName: static string): string {.compileTime.} = | 84 func generateVertexShaderCode*[VertexType, Uniforms]( |
| 85 shaderBody: static string = "", | |
| 86 entryPoint: static string = "main", | |
| 87 glslVersion: static string = "450" | |
| 88 ): string {.compileTime.} = | |
| 83 var lines: seq[string] | 89 var lines: seq[string] |
| 84 lines.add "#version 450" | 90 lines.add "#version " & glslVersion |
| 85 # lines.add "layout(binding = 0) uniform UniformBufferObject { float dt; } ubo;" | 91 lines.add "layout(row_major) uniform;" |
| 86 lines.add generateGLSLDeclarations[VertexType]() | 92 lines.add generateGLSLUniformDeclarations[Uniforms]() |
| 93 lines.add generateGLSLVertexDeclarations[VertexType]() | |
| 87 lines.add "layout(location = 0) out vec3 fragColor;" | 94 lines.add "layout(location = 0) out vec3 fragColor;" |
| 88 lines.add "void " & entryPoint & "() {" | 95 lines.add "void " & entryPoint & "() {" |
| 89 | 96 |
| 97 var hasPosition = 0 | |
| 98 var hasColor = 0 | |
| 90 for name, value in VertexType().fieldPairs: | 99 for name, value in VertexType().fieldPairs: |
| 91 when typeof(value) is VertexAttribute and name == positionAttrName: | 100 when typeof(value) is PositionAttribute: |
| 92 # lines.add " vec2 tmp = " & name & " * ubo.dt;" | 101 let glsltype = getGLSLType[getAttributeType(value)]() |
| 93 lines.add " vec2 tmp = " & name & ";" | 102 lines.add &" {glsltype} in_position = " & name & ";" |
| 94 lines.add " gl_Position = vec4(tmp, 0.0, 1.0);" | 103 if getAttributeType(value) is Vec2: |
| 95 when typeof(value) is VertexAttribute and name == colorAttrName: | 104 lines.add " vec4 out_position = vec4(in_position, 0.0, 1.0);" |
| 96 lines.add " fragColor = " & name & ";" | 105 elif getAttributeType(value) is Vec3: |
| 106 lines.add " vec4 out_position = vec4(in_position, 1.0);" | |
| 107 elif getAttributeType(value) is Vec4: | |
| 108 lines.add " vec4 out_position = in_position;" | |
| 109 hasPosition += 1 | |
| 110 when typeof(value) is ColorAttribute: | |
| 111 let glsltype = getGLSLType[getAttributeType(value)]() | |
| 112 lines.add &" {glsltype} in_color = " & name & ";" | |
| 113 lines.add &" {glsltype} out_color = in_color;"; | |
| 114 hasColor += 1 | |
| 115 | |
| 116 lines.add shaderBody | |
| 117 lines.add " gl_Position = out_position;" | |
| 118 lines.add " fragColor = out_color;" | |
| 97 lines.add "}" | 119 lines.add "}" |
| 120 if hasPosition != 1: | |
| 121 raise newException(Exception, fmt"VertexType needs to have exactly one attribute of type PositionAttribute (has {hasPosition})") | |
| 122 if hasColor != 1: | |
| 123 raise newException(Exception, fmt"VertexType needs to have exactly one attribute of type ColorAttribute (has {hasColor})") | |
| 98 return lines.join("\n") | 124 return lines.join("\n") |
| 99 | 125 |
| 100 func generateFragmentShaderCode*[VertexType](entryPoint: static string): string {.compileTime.} = | 126 func generateFragmentShaderCode*[VertexType]( |
| 127 shaderBody: static string = "", | |
| 128 entryPoint: static string = "main", | |
| 129 glslVersion: static string = "450" | |
| 130 ): string {.compileTime.} = | |
| 101 var lines: seq[string] | 131 var lines: seq[string] |
| 102 lines.add "#version 450" | 132 lines.add "#version " & glslVersion |
| 133 lines.add "layout(row_major) uniform;" | |
| 103 lines.add "layout(location = 0) in vec3 fragColor;" | 134 lines.add "layout(location = 0) in vec3 fragColor;" |
| 104 lines.add "layout(location = 0) out vec4 outColor;" | 135 lines.add "layout(location = 0) out vec4 outColor;" |
| 105 lines.add "void " & entryPoint & "() {" | 136 lines.add "void " & entryPoint & "() {" |
| 106 lines.add " outColor = vec4(fragColor, 1.0);" | 137 lines.add " vec3 in_color = fragColor;" |
| 138 lines.add " vec3 out_color = in_color;" | |
| 139 lines.add shaderBody | |
| 140 lines.add " outColor = vec4(out_color, 1.0);" | |
| 107 lines.add "}" | 141 lines.add "}" |
| 108 | 142 |
| 109 return lines.join("\n") | 143 return lines.join("\n") |
