add alpha to shaders, fix vulkan cleanup

This commit is contained in:
matthew 2025-08-04 11:05:47 +10:00
parent 282f78baae
commit 0081887f19
13 changed files with 179 additions and 8 deletions

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -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];

View File

@ -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);
}
}

View File

@ -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)

View File

@ -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;
}

View File

@ -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 {

View File

@ -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