diff --git a/assets/shaders/gradient.comp.spv b/assets/shaders/gradient.comp.spv index 1d9f82a..18575bc 100644 Binary files a/assets/shaders/gradient.comp.spv and b/assets/shaders/gradient.comp.spv differ diff --git a/assets/shaders/gui.frag.spv b/assets/shaders/gui.frag.spv index c490d3e..8a6d970 100644 Binary files a/assets/shaders/gui.frag.spv and b/assets/shaders/gui.frag.spv differ diff --git a/assets/shaders/gui.vert.spv b/assets/shaders/gui.vert.spv index 39374c1..5e968bf 100644 Binary files a/assets/shaders/gui.vert.spv and b/assets/shaders/gui.vert.spv differ diff --git a/assets/shaders/pbr.frag.spv b/assets/shaders/pbr.frag.spv index 5d4e833..4f0dc63 100644 Binary files a/assets/shaders/pbr.frag.spv and b/assets/shaders/pbr.frag.spv differ diff --git a/assets/shaders/pbr.vert.spv b/assets/shaders/pbr.vert.spv index c369eaa..09f5990 100644 Binary files a/assets/shaders/pbr.vert.spv and b/assets/shaders/pbr.vert.spv differ diff --git a/assets/shaders/triangle.frag.spv b/assets/shaders/triangle.frag.spv index 1dd2a8e..821a69b 100644 Binary files a/assets/shaders/triangle.frag.spv and b/assets/shaders/triangle.frag.spv differ diff --git a/assets/shaders/triangle.vert.spv b/assets/shaders/triangle.vert.spv index 97265db..1524706 100644 Binary files a/assets/shaders/triangle.vert.spv and b/assets/shaders/triangle.vert.spv differ diff --git a/src/gears/game.d b/src/gears/game.d index b99caf5..21e2a74 100644 --- a/src/gears/game.d +++ b/src/gears/game.d @@ -89,6 +89,10 @@ InitGame(PlatformWindow* window) g.model = LoadModel(&g.rd, "models/Tree01.m3d"); + SetClearColor(&g.rd, Vec4(0.3, 0.5, 0.9, 1.0)); + + ClearColorEnabled(&g.rd, true); + return g; } @@ -169,13 +173,14 @@ Destroy(Game* g) Destroy(&g.rd, &g.triangle_pipeline); Destroy(&g.rd, &g.ui_pipeline); Destroy(&g.rd, &g.compute_pipeline); + Destroy(&g.rd, &g.model); Destroy(&g.rd); } struct Camera { Vec3 velocity = Vec3(0.0); - Vec3 pos = Vec3(0.0, 0.0, 5.0); + Vec3 pos = Vec3(0.0, 0.0, 2.0); f32 pitch = 0.0; f32 yaw = 0.0; } @@ -183,8 +188,6 @@ struct Camera pragma(inline): void HandleInputs(Camera* cam, Inputs* inputs) { - Logf("%.04f %.04f", cam.pitch, cam.yaw); - foreach(i; 0 .. inputs.count) { InputEvent event = inputs.events[i]; diff --git a/src/gears/renderer.d b/src/gears/renderer.d index 338d205..e089c93 100644 --- a/src/gears/renderer.d +++ b/src/gears/renderer.d @@ -4,7 +4,7 @@ import assets; import util; import alloc; import vulkan; -import vulkan : Destroy, Init, Draw, DrawIndexed, Bind, BindUIBuffers, BeginRender, SetUniform, PrepComputeDrawImage, Dispatch, FinishFrame, BeginFrame, WaitIdle, PushConstants, BindBuffers; +import vulkan : Destroy, Init, Draw, DrawIndexed, Bind, BindUIBuffers, BeginRender, SetUniform, PrepComputeDrawImage, Dispatch, FinishFrame, BeginFrame, WaitIdle, PushConstants, BindBuffers, SetClearColor; import assets; import std.math.traits : isNaN; import util : Logf; @@ -345,6 +345,7 @@ LoadModel(Renderer* rd, string name) u32[] tex_lookup = AllocArray!(u32)(&rd.temp_arena, m3d.numtexture); model.textures = AllocArray!(ImageView)(&rd.arena, m3d.numtexture); + Logf("numtexture %s", m3d.numtexture); foreach(i; 0 .. m3d.numtexture) { u32 w = m3d.texture[i].w; u32 h = m3d.texture[i].h; u32 ch = m3d.texture[i].f; @@ -359,6 +360,7 @@ LoadModel(Renderer* rd, string name) Material[] mats = AllocArray!(Material)(&rd.temp_arena, m3d.nummaterial); u32[] mat_lookup = AllocArray!(u32)(&rd.temp_arena, m3d.nummaterial); model.materials = AllocArray!(Buffer)(&rd.arena, m3d.nummaterial); + Logf("nummaterial %s", m3d.nummaterial); foreach(i; 0 .. m3d.nummaterial) { const(char)[] mat_name = m3d.material[i].name[0 .. strlen(m3d.material[i].name)]; @@ -371,6 +373,7 @@ LoadModel(Renderer* rd, string name) case m3dp_Ka: ConvertColor(&mats[i].ambient, m3d.material[i].prop[j].value.color); break; case m3dp_Ks: ConvertColor(&mats[i].specular, m3d.material[i].prop[j].value.color); break; case m3dp_Ns: mats[i].shininess = m3d.material[i].prop[j].value.fnum; break; + case m3dp_d: mats[i].alpha = m3d.material[i].prop[j].value.fnum; break; case m3dp_map_Kd: { mats[i].albedo_texture = tex_lookup[m3d.material[i].prop[j].value.textureid]; @@ -386,7 +389,13 @@ LoadModel(Renderer* rd, string name) mats[i].specular_texture = tex_lookup[m3d.material[i].prop[j].value.textureid]; mats[i].specular_has_texture = true; } break; - default: break; + case m3dp_map_D: + { + Logf("alpha %s", i); + mats[i].alpha_texture = tex_lookup[m3d.material[i].prop[j].value.textureid]; + mats[i].alpha_has_texture = true; + } break; + default: Logf("Unsupported property: %s", M3DPropToStr(m3d.material[i].prop[j].type)); break; } } @@ -525,6 +534,46 @@ LoadModel(Renderer* rd, string name) return model; } +string +M3DPropToStr(u8 type) +{ + string result = "Unknown"; + switch(type) + { + case m3dp_Kd: result = "Diffuse"; break; + case m3dp_Ka: result = "Ambient"; break; + case m3dp_Ks: result = "Specular Color"; break; + case m3dp_Ns: result = "Specular Exponent"; break; + case m3dp_Ke: result = "Emissive"; break; + case m3dp_Tf: result = "Transmission"; break; + case m3dp_Km: result = "Bump Strength"; break; + case m3dp_d: result = "Alpha"; break; + case m3dp_il: result = "Illumination"; break; + case m3dp_Pr: result = "Roughness"; break; + case m3dp_Pm: result = "Metallic"; break; + case m3dp_Ps: result = "Sheen"; break; + case m3dp_Ni: result = "Refraction"; break; + case m3dp_Nt: result = "Face Thickness"; break; + case m3dp_map_Kd: result = "Diffuse Texture"; break; + case m3dp_map_Ka: result = "Ambient Texture"; break; + case m3dp_map_Ks: result = "Specular Texture"; break; + case m3dp_map_Ns: result = "Specular Exponent Texture"; break; + case m3dp_map_Ke: result = "Emissive Texture"; break; + case m3dp_map_Tf: result = "Transmission Texture"; break; + case m3dp_map_Km: result = "Bump Map"; break; + case m3dp_map_D: result = "Alpha Map"; break; + case m3dp_map_N: result = "Normal Map"; break; + case m3dp_map_Pr: result = "Roughness Map"; break; + case m3dp_map_Pm: result = "Metallic Map"; break; + case m3dp_map_Ps: result = "Sheen Map"; break; + case m3dp_map_Ni: result = "Refraction Map"; break; + case m3dp_map_Nt: result = "Thickness Map"; break; + default: break; + } + + return result; +} + pragma(inline): void CopyVertex(Vec3* dst, m3dv_t* src) { @@ -557,3 +606,31 @@ PrintShader(Renderer* rd, Pipeline* pipeline, VkShaderStageFlagBits stage) PrintShaderDisassembly(&rd.vk, pipeline, stage); } +void +SetClearColor(Renderer* rd, Vec4 color) +{ + SetClearColor(&rd.vk, color); +} + +void +ClearColorEnabled(Renderer* rd, bool enabled) +{ + rd.vk.enable_clear_color = enabled; +} + +void +Destroy(Renderer* rd, Model* model) +{ + Destroy(&rd.vk, &model.vertex_buffer); + Destroy(&rd.vk, &model.index_buffer); + + foreach(i, mat; model.materials) + { + Destroy(&rd.vk, model.materials.ptr + i); + } + + foreach(i, view; model.textures) + { + Destroy(model.textures.ptr + i, rd.vk.device, rd.vk.vma); + } +} diff --git a/src/gears/vulkan.d b/src/gears/vulkan.d index f3ced11..9d673bc 100644 --- a/src/gears/vulkan.d +++ b/src/gears/vulkan.d @@ -93,6 +93,7 @@ enum StepInitialized : u32 Swapchain, DrawImages, Descriptors, + Pipelines, } alias SI = StepInitialized; @@ -220,6 +221,9 @@ struct Vulkan VkPipeline last_comp_pipeline; bool compute_pass_started; + bool enable_clear_color; + VkClearColorValue clear_color; + alias queues this; } @@ -294,6 +298,8 @@ Init(PlatformWindow* window, u64 permanent_mem, u64 frame_mem) bool InitConversionPipeline(Vulkan* vk) { + Push(vk, SI.Pipelines); + VkDescriptorBindingFlags[] binding_flags; binding_flags[] = VK_DESCRIPTOR_BINDING_UPDATE_AFTER_BIND_BIT; @@ -432,6 +438,7 @@ InitBuffers(Vulkan* vk) Push(vk, SI.Buffers); vk.global_buf = CreateMappedBuffer!(GlobalUniforms)(vk, BT.Uniform, 1); + vk.shader_buf = CreateMappedBuffer!(ShaderUniforms)(vk, BT.Uniform, 1); u64 transfer_size = MB(64); vk.transfer_buf = CreateMappedBuffer!(u8)(vk, BT.Staging, transfer_size); @@ -540,8 +547,11 @@ BeginRender(Vulkan* vk) sType: VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO, imageView: vk.draw_image.view, imageLayout: vk.draw_image.layout, - loadOp: VK_ATTACHMENT_LOAD_OP_CLEAR, // CLEAR instead of LOAD if wanting to clear colors, also clearColor value (or whatever) + loadOp: (vk.enable_clear_color ? VK_ATTACHMENT_LOAD_OP_CLEAR : VK_ATTACHMENT_LOAD_OP_LOAD), // CLEAR instead of LOAD if wanting to clear colors, also clearColor value (or whatever) storeOp: VK_ATTACHMENT_STORE_OP_STORE, + clearValue: { + color: vk.clear_color, + }, }; VkRenderingAttachmentInfo depth_attach = { @@ -569,6 +579,15 @@ BeginRender(Vulkan* vk) vkCmdBeginRendering(vk.cmds[vk.frame_index], &render_info); } +void +SetClearColor(Vulkan* vk, Vec4 color) +{ + vk.clear_color.float32[0] = color.r; + vk.clear_color.float32[1] = color.g; + vk.clear_color.float32[2] = color.b; + vk.clear_color.float32[3] = color.a; +} + void PrepComputeDrawImage(Vulkan* vk) { @@ -1321,7 +1340,13 @@ CreateGraphicsPipeline(Vulkan* vk, GfxPipelineInfo* build_info) VkPipelineColorBlendAttachmentState blend_state = { colorWriteMask: VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT, - blendEnable: VK_FALSE, + blendEnable: VK_TRUE, + srcColorBlendFactor: VK_BLEND_FACTOR_SRC_ALPHA, + dstColorBlendFactor: VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA, + colorBlendOp: VK_BLEND_OP_ADD, + srcAlphaBlendFactor: VK_BLEND_FACTOR_SRC_ALPHA, + dstAlphaBlendFactor: VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA, + alphaBlendOp: VK_BLEND_OP_ADD, }; VkPipelineColorBlendStateCreateInfo blend_info = { @@ -1558,6 +1583,13 @@ Destroy(Vulkan* vk) break; case SI.Buffers: Destroy(vk, &vk.transfer_buf); + Destroy(vk, &vk.ui_vert_buf); + Destroy(vk, &vk.ui_index_buf); + Destroy(vk, &vk.global_buf); + Destroy(vk, &vk.shader_buf); + break; + case SI.Pipelines: + DestroyPipelines(vk); break; default: break; @@ -1565,6 +1597,35 @@ Destroy(Vulkan* vk) } } +void +DestroyPipelines(Vulkan* vk) +{ + if (vk.conv_pipeline_layout) + { + vkDestroyPipelineLayout(vk.device, vk.conv_pipeline_layout, null); + } + + if (vk.conv_desc_layout) + { + vkDestroyDescriptorSetLayout(vk.device, vk.conv_desc_layout, null); + } + + if (vk.r_to_rgba_pipeline.handle) + { + vkDestroyPipeline(vk.device, vk.r_to_rgba_pipeline.handle, null); + } + + if (vk.rg_to_rgba_pipeline.handle) + { + vkDestroyPipeline(vk.device, vk.rg_to_rgba_pipeline.handle, null); + } + + if (vk.rgb_to_rgba_pipeline.handle) + { + vkDestroyPipeline(vk.device, vk.rgb_to_rgba_pipeline.handle, null); + } +} + void Destroy(T)(Vulkan* vk, MappedBuffer!(T)* buf) { @@ -2789,6 +2850,21 @@ DestroyFS(Vulkan* vk) vkDestroyCommandPool(vk.device, vk.imm_pool, null); } + if (vk.comp_cmd) + { + vkFreeCommandBuffers(vk.device, vk.comp_cmd_pool, 1, &vk.comp_cmd); + } + + if (vk.comp_cmd_pool) + { + vkDestroyCommandPool(vk.device, vk.comp_cmd_pool, null); + } + + if (vk.comp_fence) + { + vkDestroyFence(vk.device, vk.comp_fence, null); + } + foreach(sem; vk.submit_sems) { if (sem) diff --git a/src/shaders/pbr.frag.glsl b/src/shaders/pbr.frag.glsl index 75542f5..d1170ed 100644 --- a/src/shaders/pbr.frag.glsl +++ b/src/shaders/pbr.frag.glsl @@ -30,5 +30,14 @@ void main() vec4 col = Materials[nonuniformEXT(PC.mat_id)].diffuse; vec4 tex_col = texture(sampler2D(Textures[nonuniformEXT(Materials[nonuniformEXT(PC.mat_id)].albedo_texture)], SamplerNearest), FragData.uv); - FragColor = CalculateDirectionalLight(col, tex_col, G.light_color, G.light_direction, FragData.normal); + vec4 out_col = CalculateDirectionalLight(col, tex_col, G.light_color, G.light_direction, FragData.normal); + out_col.a = Materials[nonuniformEXT(PC.mat_id)].alpha; + + if (Materials[nonuniformEXT(PC.mat_id)].alpha_has_texture) + { + vec4 alpha_col = texture(sampler2D(Textures[nonuniformEXT(Materials[nonuniformEXT(PC.mat_id)].alpha_texture)], SamplerNearest), FragData.uv); + out_col.a = alpha_col.a; + } + + FragColor = out_col; } diff --git a/src/shaders/structures.layout b/src/shaders/structures.layout index 5def1fa..ca31899 100644 --- a/src/shaders/structures.layout +++ b/src/shaders/structures.layout @@ -29,10 +29,13 @@ layout (set = 2, binding = 0) uniform Material { uint albedo_texture; uint ambient_texture; uint specular_texture; + uint alpha_texture; bool albedo_has_texture; bool ambient_has_texture; bool specular_has_texture; + bool alpha_has_texture; float shininess; + float alpha; } Materials[]; layout (push_constant) uniform Constants { diff --git a/src/shared/assets.d b/src/shared/assets.d index 574aab6..0148607 100644 --- a/src/shared/assets.d +++ b/src/shared/assets.d @@ -73,10 +73,13 @@ struct Material u32 albedo_texture; u32 ambient_texture; u32 specular_texture; + u32 alpha_texture; b32 albedo_has_texture; b32 ambient_has_texture; b32 specular_has_texture; + b32 alpha_has_texture; f32 shininess = 0.0; + f32 alpha = 0.0; } struct TextureInfo