split renderer into game and vulkan files
This commit is contained in:
parent
290fa0d19d
commit
31b0bb79d4
416
src/gears/game.d
416
src/gears/game.d
@ -1,8 +1,8 @@
|
|||||||
import aliases;
|
import aliases;
|
||||||
import includes;
|
import includes;
|
||||||
import renderer : Destroy;
|
import vulkan : Destroy;
|
||||||
import renderer;
|
|
||||||
import vulkan;
|
import vulkan;
|
||||||
|
import assets;
|
||||||
import util;
|
import util;
|
||||||
import alloc;
|
import alloc;
|
||||||
import platform;
|
import platform;
|
||||||
@ -12,9 +12,51 @@ import std.algorithm.sorting;
|
|||||||
|
|
||||||
f32 g_DELTA;
|
f32 g_DELTA;
|
||||||
|
|
||||||
|
struct UIVertex
|
||||||
|
{
|
||||||
|
Vec2 p0;
|
||||||
|
Vec2 p1;
|
||||||
|
Vec4 col;
|
||||||
|
u32 texture;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Vertex
|
||||||
|
{
|
||||||
|
Vec4 color;
|
||||||
|
Vec4 tangent;
|
||||||
|
Vec3 pos;
|
||||||
|
Vec3 normal;
|
||||||
|
Vec2 uv;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct MeshPart
|
||||||
|
{
|
||||||
|
u32 mat;
|
||||||
|
u32 offset;
|
||||||
|
u32 length;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Model
|
||||||
|
{
|
||||||
|
Vec3 pos = Vec3(0.0);
|
||||||
|
Buffer vertex_buffer;
|
||||||
|
Buffer index_buffer;
|
||||||
|
MeshPart[] parts;
|
||||||
|
|
||||||
|
string name;
|
||||||
|
|
||||||
|
Buffer[] materials;
|
||||||
|
ImageView[] textures;
|
||||||
|
|
||||||
|
Vec3[] positions;
|
||||||
|
u32[] pos_indices;
|
||||||
|
u32[] indices;
|
||||||
|
}
|
||||||
|
|
||||||
struct Game
|
struct Game
|
||||||
{
|
{
|
||||||
Renderer rd;
|
Renderer rd;
|
||||||
|
Arena arena;
|
||||||
Arena frame_arena;
|
Arena frame_arena;
|
||||||
|
|
||||||
PlatformWindow* window;
|
PlatformWindow* window;
|
||||||
@ -25,6 +67,10 @@ struct Game
|
|||||||
Pipeline ui_pipeline;
|
Pipeline ui_pipeline;
|
||||||
Pipeline oit_pipeline;
|
Pipeline oit_pipeline;
|
||||||
|
|
||||||
|
UIVertex[] ui_vertex_buf;
|
||||||
|
u32[] ui_index_buf;
|
||||||
|
u32 ui_count;
|
||||||
|
|
||||||
ImageView draw_image, depth_image;
|
ImageView draw_image, depth_image;
|
||||||
ImageView aux_image;
|
ImageView aux_image;
|
||||||
|
|
||||||
@ -48,7 +94,8 @@ Game
|
|||||||
InitGame(PlatformWindow* window)
|
InitGame(PlatformWindow* window)
|
||||||
{
|
{
|
||||||
Game g = {
|
Game g = {
|
||||||
rd: InitRenderer(window),
|
rd: InitRenderer(window, MB(24), MB(32)),
|
||||||
|
arena: CreateArena(MB(32)),
|
||||||
frame_arena: CreateArena(MB(16)),
|
frame_arena: CreateArena(MB(16)),
|
||||||
window: window,
|
window: window,
|
||||||
timer: CreateTimer(),
|
timer: CreateTimer(),
|
||||||
@ -59,11 +106,11 @@ InitGame(PlatformWindow* window)
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
Extent ext = GetExtent(&g.rd);
|
UVec2 ext = GetExtent(&g.rd);
|
||||||
|
|
||||||
CreateImageView(&g.rd, &g.draw_image, ext.w, ext.h, GetDrawImageFormat(&g.rd), IU.Draw, false);
|
CreateImageView(&g.rd, &g.draw_image, ext.x, ext.y, GetDrawImageFormat(&g.rd), IU.Draw, false);
|
||||||
CreateImageView(&g.rd, &g.depth_image, ext.w, ext.h, FMT.D_SF32, IU.Depth, true);
|
CreateImageView(&g.rd, &g.depth_image, ext.x, ext.y, FMT.D_SF32, IU.Depth, true);
|
||||||
CreateImageView(&g.rd, &g.aux_image, ext.w, ext.h, FMT.R_U32, IU.Storage);
|
CreateImageView(&g.rd, &g.aux_image, ext.x, ext.y, FMT.R_U32, IU.Storage);
|
||||||
|
|
||||||
GfxPipelineInfo triangle_info = {
|
GfxPipelineInfo triangle_info = {
|
||||||
vertex_shader: "shaders/triangle.vert.spv",
|
vertex_shader: "shaders/triangle.vert.spv",
|
||||||
@ -113,28 +160,24 @@ InitGame(PlatformWindow* window)
|
|||||||
shader: "shaders/gradient.comp.spv",
|
shader: "shaders/gradient.comp.spv",
|
||||||
};
|
};
|
||||||
|
|
||||||
g.pbr_pipeline = BuildGfxPipeline(&g.rd, &pbr_info);
|
g.pbr_pipeline = CreateGraphicsPipeline(&g.rd, &pbr_info);
|
||||||
g.triangle_pipeline = BuildGfxPipeline(&g.rd, &triangle_info);
|
g.triangle_pipeline = CreateGraphicsPipeline(&g.rd, &triangle_info);
|
||||||
g.ui_pipeline = BuildGfxPipeline(&g.rd, &ui_info);
|
g.ui_pipeline = CreateGraphicsPipeline(&g.rd, &ui_info);
|
||||||
g.oit_pipeline = BuildGfxPipeline(&g.rd, &oit_info);
|
g.oit_pipeline = CreateGraphicsPipeline(&g.rd, &oit_info);
|
||||||
g.compute_pipeline = BuildCompPipeline(&g.rd, &gradient_info);
|
g.compute_pipeline = CreateComputePipeline(&g.rd, &gradient_info);
|
||||||
|
|
||||||
PrintShader(&g.rd, &g.pbr_pipeline, VK_SHADER_STAGE_VERTEX_BIT);
|
g.rock = LoadModel(&g, "models/BigRock01.m3d");
|
||||||
|
g.tree = LoadModel(&g, "models/Tree01.m3d");
|
||||||
g.rock = LoadModel(&g.rd, "models/BigRock01.m3d");
|
g.magic_rock = LoadModel(&g, "models/MagicRock01.m3d");
|
||||||
g.tree = LoadModel(&g.rd, "models/Tree01.m3d");
|
g.log = LoadModel(&g, "models/Log01.m3d");
|
||||||
g.magic_rock = LoadModel(&g.rd, "models/MagicRock01.m3d");
|
g.stump = LoadModel(&g, "models/Stump01.m3d");
|
||||||
g.log = LoadModel(&g.rd, "models/Log01.m3d");
|
|
||||||
g.stump = LoadModel(&g.rd, "models/Stump01.m3d");
|
|
||||||
|
|
||||||
SetClearColor(&g.rd, Vec4(0.3, 0.5, 0.9, 1.0));
|
|
||||||
|
|
||||||
ClearColorEnabled(&g.rd, true);
|
|
||||||
|
|
||||||
assert(g.aux_image.view != null);
|
assert(g.aux_image.view != null);
|
||||||
|
|
||||||
UpdateAuxImage(&g.rd, &g.aux_image);
|
UpdateAuxImage(&g.rd, &g.aux_image);
|
||||||
|
|
||||||
|
Reset(&g.frame_arena);
|
||||||
|
|
||||||
return g;
|
return g;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -221,7 +264,7 @@ Cycle(Game* g)
|
|||||||
|
|
||||||
BeginFrame(&g.rd);
|
BeginFrame(&g.rd);
|
||||||
|
|
||||||
PrepAuxImage(&g.rd.vk, &g.aux_image);
|
PrepAuxImage(&g.rd, &g.aux_image);
|
||||||
|
|
||||||
Bind(&g.rd, &g.compute_pipeline);
|
Bind(&g.rd, &g.compute_pipeline);
|
||||||
|
|
||||||
@ -229,7 +272,7 @@ Cycle(Game* g)
|
|||||||
|
|
||||||
ImageBarrier(&g.rd);
|
ImageBarrier(&g.rd);
|
||||||
|
|
||||||
Extent ext = GetExtent(&g.rd);
|
UVec2 ext = GetExtent(&g.rd);
|
||||||
f32 aspect = (cast(f32)ext.x) / (cast(f32)ext.y);
|
f32 aspect = (cast(f32)ext.x) / (cast(f32)ext.y);
|
||||||
Mat4 projection = Perspective(90.0, aspect, 10000.0, 0.1);
|
Mat4 projection = Perspective(90.0, aspect, 10000.0, 0.1);
|
||||||
|
|
||||||
@ -280,7 +323,7 @@ Cycle(Game* g)
|
|||||||
|
|
||||||
//FinishRendering(&g.rd);
|
//FinishRendering(&g.rd);
|
||||||
|
|
||||||
Submit(&g.rd, &g.draw_image);
|
SubmitAndPresent(&g.rd, &g.draw_image);
|
||||||
}
|
}
|
||||||
|
|
||||||
pragma(inline): void
|
pragma(inline): void
|
||||||
@ -320,6 +363,23 @@ Destroy(Game* g)
|
|||||||
Destroy(&g.rd);
|
Destroy(&g.rd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Destroy(Renderer* rd, Model* model)
|
||||||
|
{
|
||||||
|
Destroy(rd, &model.vertex_buffer);
|
||||||
|
Destroy(rd, &model.index_buffer);
|
||||||
|
|
||||||
|
foreach(i, mat; model.materials)
|
||||||
|
{
|
||||||
|
Destroy(rd, model.materials.ptr + i);
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach(i, view; model.textures)
|
||||||
|
{
|
||||||
|
Destroy(rd, model.textures.ptr + i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
struct Camera
|
struct Camera
|
||||||
{
|
{
|
||||||
Vec3 velocity = Vec3(0.0);
|
Vec3 velocity = Vec3(0.0);
|
||||||
@ -402,3 +462,307 @@ Sort(Game* g, Vec3 pos, Model* model)
|
|||||||
|
|
||||||
UpdateIndexBuffer(&g.rd, model);
|
UpdateIndexBuffer(&g.rd, model);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
DrawRect(Game* g, f32 p0_x, f32 p0_y, f32 p1_x, f32 p1_y, Vec4 col)
|
||||||
|
{
|
||||||
|
g.ui_vertex_buf[g.ui_count].p0.x = p0_x;
|
||||||
|
g.ui_vertex_buf[g.ui_count].p0.y = p0_y;
|
||||||
|
g.ui_vertex_buf[g.ui_count].p1.x = p1_x;
|
||||||
|
g.ui_vertex_buf[g.ui_count].p1.y = p1_y;
|
||||||
|
g.ui_vertex_buf[g.ui_count].col = col;
|
||||||
|
|
||||||
|
u32 index_count = g.ui_count * 6;
|
||||||
|
|
||||||
|
g.ui_index_buf[index_count+0] = index_count+0;
|
||||||
|
g.ui_index_buf[index_count+1] = index_count+1;
|
||||||
|
g.ui_index_buf[index_count+2] = index_count+2;
|
||||||
|
g.ui_index_buf[index_count+3] = index_count+1;
|
||||||
|
g.ui_index_buf[index_count+4] = index_count+2;
|
||||||
|
g.ui_index_buf[index_count+5] = index_count+3;
|
||||||
|
|
||||||
|
g.ui_count += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
Model
|
||||||
|
LoadModel(Game* g, string name)
|
||||||
|
{
|
||||||
|
AssetInfo info = GetAssetInfo(name);
|
||||||
|
|
||||||
|
u8[] data = LoadAssetData(&g.frame_arena, name);
|
||||||
|
Model model = {
|
||||||
|
name: name,
|
||||||
|
};
|
||||||
|
|
||||||
|
m3d_t* m3d = m3d_load(data.ptr, null, null, null);
|
||||||
|
scope(exit) m3d_free(m3d);
|
||||||
|
|
||||||
|
u32[] tex_lookup = AllocArray!(u32)(&g.frame_arena, m3d.numtexture);
|
||||||
|
model.textures = AllocArray!(ImageView)(&g.arena, 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;
|
||||||
|
u8[] tex_data = m3d.texture[i].d[0 .. w * h * ch];
|
||||||
|
|
||||||
|
const(char)[] tex_name = m3d.texture[i].name[0 .. strlen(m3d.texture[i].name)];
|
||||||
|
CreateImageView(&g.rd, &model.textures[i], w, h, ch, tex_data);
|
||||||
|
|
||||||
|
tex_lookup[i] = Pop(&g.rd, DT.SampledImage);
|
||||||
|
}
|
||||||
|
|
||||||
|
Material[] mats = AllocArray!(Material)(&g.frame_arena, m3d.nummaterial);
|
||||||
|
u32[] mat_lookup = AllocArray!(u32)(&g.frame_arena, m3d.nummaterial);
|
||||||
|
model.materials = AllocArray!(Buffer)(&g.arena, m3d.nummaterial);
|
||||||
|
foreach(i; 0 .. m3d.nummaterial)
|
||||||
|
{
|
||||||
|
const(char)[] mat_name = m3d.material[i].name[0 .. strlen(m3d.material[i].name)];
|
||||||
|
|
||||||
|
foreach(j; 0 .. m3d.material[i].numprop)
|
||||||
|
{
|
||||||
|
switch (m3d.material[i].prop[j].type)
|
||||||
|
{
|
||||||
|
case m3dp_Kd: ConvertColor(&mats[i].albedo, m3d.material[i].prop[j].value.color); break;
|
||||||
|
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];
|
||||||
|
mats[i].albedo_has_texture = true;
|
||||||
|
} break;
|
||||||
|
case m3dp_map_Ka:
|
||||||
|
{
|
||||||
|
mats[i].ambient_texture = tex_lookup[m3d.material[i].prop[j].value.textureid];
|
||||||
|
mats[i].ambient_has_texture = true;
|
||||||
|
} break;
|
||||||
|
case m3dp_map_Ks:
|
||||||
|
{
|
||||||
|
mats[i].specular_texture = tex_lookup[m3d.material[i].prop[j].value.textureid];
|
||||||
|
mats[i].specular_has_texture = true;
|
||||||
|
} break;
|
||||||
|
case m3dp_map_D:
|
||||||
|
{
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
CreateBuffer(&g.rd, &model.materials[i], BT.Uniform, Material.sizeof, false);
|
||||||
|
assert(Transfer(&g.rd, &model.materials[i], &mats[i]), "LoadModel failure: Transfer error when transferring material");
|
||||||
|
|
||||||
|
mat_lookup[i] = Pop(&g.rd, DT.Material);
|
||||||
|
}
|
||||||
|
|
||||||
|
u32 mesh_count = 0;
|
||||||
|
u64 last = u64.max;
|
||||||
|
foreach(i; 0 .. m3d.numface)
|
||||||
|
{
|
||||||
|
if (m3d.face[i].materialid != last)
|
||||||
|
{
|
||||||
|
last = m3d.face[i].materialid;
|
||||||
|
mesh_count += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
model.parts = AllocArray!(MeshPart)(&g.arena, mesh_count);
|
||||||
|
last = u64.max;
|
||||||
|
u32 index = 0;
|
||||||
|
foreach(i; 0 .. m3d.numface)
|
||||||
|
{
|
||||||
|
if (last == u64.max)
|
||||||
|
{
|
||||||
|
model.parts[index].mat = (m3d.face[i].materialid != u32.max) ? mat_lookup[m3d.face[i].materialid] : 0;
|
||||||
|
model.parts[index].offset = 0;
|
||||||
|
last = m3d.face[i].materialid;
|
||||||
|
}
|
||||||
|
else if (m3d.face[i].materialid != last)
|
||||||
|
{
|
||||||
|
u32 vertex_index = i * 3;
|
||||||
|
|
||||||
|
model.parts[index].length = vertex_index - model.parts[index].offset;
|
||||||
|
index += 1;
|
||||||
|
|
||||||
|
model.parts[index].mat = mat_lookup[m3d.face[i].materialid];
|
||||||
|
model.parts[index].offset = vertex_index;
|
||||||
|
last = m3d.face[i].materialid;
|
||||||
|
}
|
||||||
|
else if (i == m3d.numface-1)
|
||||||
|
{
|
||||||
|
u32 vertex_index = i * 3;
|
||||||
|
model.parts[index].length = vertex_index+3 - model.parts[index].offset;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
m3dv_t* vertex;
|
||||||
|
|
||||||
|
u32[] indices = AllocArray!(u32)(&g.arena, m3d.numface * 3);
|
||||||
|
Vertex[] vertices = AllocArray!(Vertex)(&g.frame_arena, m3d.numface * 3);
|
||||||
|
Vec3[] positions = AllocArray!(Vec3)(&g.arena, m3d.numface);
|
||||||
|
u32[] pos_indices = AllocArray!(u32)(&g.arena, m3d.numface);
|
||||||
|
|
||||||
|
foreach(i; 0 .. m3d.numface)
|
||||||
|
{
|
||||||
|
u32 vi = (i * 3);
|
||||||
|
u32 i0 = vi+0;
|
||||||
|
u32 i1 = vi+1;
|
||||||
|
u32 i2 = vi+2;
|
||||||
|
|
||||||
|
CopyVertex(&vertices[i0].pos, &m3d.vertex[m3d.face[i].vertex[0]]);
|
||||||
|
CopyVertex(&vertices[i1].pos, &m3d.vertex[m3d.face[i].vertex[1]]);
|
||||||
|
CopyVertex(&vertices[i2].pos, &m3d.vertex[m3d.face[i].vertex[2]]);
|
||||||
|
|
||||||
|
CopyVertex(&vertices[i0].normal, &m3d.vertex[m3d.face[i].normal[0]]);
|
||||||
|
CopyVertex(&vertices[i1].normal, &m3d.vertex[m3d.face[i].normal[1]]);
|
||||||
|
CopyVertex(&vertices[i2].normal, &m3d.vertex[m3d.face[i].normal[2]]);
|
||||||
|
|
||||||
|
ConvertColor(&vertices[i0].color, m3d.vertex[m3d.face[i].vertex[0]].color);
|
||||||
|
ConvertColor(&vertices[i1].color, m3d.vertex[m3d.face[i].vertex[1]].color);
|
||||||
|
ConvertColor(&vertices[i2].color, m3d.vertex[m3d.face[i].vertex[2]].color);
|
||||||
|
|
||||||
|
if (m3d.numtmap)
|
||||||
|
{
|
||||||
|
vertices[i0].uv.x = m3d.tmap[m3d.face[i].texcoord[0]].u;
|
||||||
|
vertices[i0].uv.y = m3d.tmap[m3d.face[i].texcoord[0]].v;
|
||||||
|
|
||||||
|
vertices[i1].uv.x = m3d.tmap[m3d.face[i].texcoord[1]].u;
|
||||||
|
vertices[i1].uv.y = m3d.tmap[m3d.face[i].texcoord[1]].v;
|
||||||
|
|
||||||
|
vertices[i2].uv.x = m3d.tmap[m3d.face[i].texcoord[2]].u;
|
||||||
|
vertices[i2].uv.y = m3d.tmap[m3d.face[i].texcoord[2]].v;
|
||||||
|
}
|
||||||
|
|
||||||
|
indices[i0] = i0;
|
||||||
|
indices[i1] = i1;
|
||||||
|
indices[i2] = i2;
|
||||||
|
|
||||||
|
Vec3 center = (vertices[i0].pos + vertices[i1].pos + vertices[i2].pos) / 3.0;
|
||||||
|
|
||||||
|
positions[i] = center;
|
||||||
|
pos_indices[i] = i;
|
||||||
|
}
|
||||||
|
|
||||||
|
for(u64 i = 0; i < indices.length; i += 3)
|
||||||
|
{
|
||||||
|
u32 i0 = indices[i+0];
|
||||||
|
u32 i1 = indices[i+1];
|
||||||
|
u32 i2 = indices[i+2];
|
||||||
|
|
||||||
|
Vec3 edge1 = vertices[i1].pos - vertices[i0].pos;
|
||||||
|
Vec3 edge2 = vertices[i2].pos - vertices[i0].pos;
|
||||||
|
|
||||||
|
Vec2 delta_uv1 = vertices[i1].uv - vertices[i0].uv;
|
||||||
|
Vec2 delta_uv2 = vertices[i2].uv - vertices[i0].uv;
|
||||||
|
|
||||||
|
f32 dividend = delta_uv1.x * delta_uv2.y - delta_uv2.x * delta_uv1.y;
|
||||||
|
f32 fc = 1.0 / dividend;
|
||||||
|
|
||||||
|
Vec3 tangent = Vec3(
|
||||||
|
fc * (delta_uv2.y * edge1.x - delta_uv1.y * edge2.x),
|
||||||
|
fc * (delta_uv2.y * edge1.y - delta_uv1.y * edge2.y),
|
||||||
|
fc * (delta_uv2.y * edge1.z - delta_uv1.y * edge2.z)
|
||||||
|
);
|
||||||
|
|
||||||
|
Normalize(&tangent);
|
||||||
|
|
||||||
|
f32 handedness = ((delta_uv1.y * delta_uv2.x - delta_uv2.y * delta_uv1.x) < 0.0) ? -1.0 : 1.0;
|
||||||
|
|
||||||
|
Vec3 t = tangent * handedness;
|
||||||
|
|
||||||
|
vertices[i0].tangent = Vec4(t, handedness);
|
||||||
|
vertices[i1].tangent = Vec4(t, handedness);
|
||||||
|
vertices[i2].tangent = Vec4(t, handedness);
|
||||||
|
}
|
||||||
|
|
||||||
|
assert(vertices.length > 0 && indices.length > 0, "Error loading model");
|
||||||
|
|
||||||
|
CreateBuffer(&g.rd, &model.vertex_buffer, BT.Vertex, vertices.length * Vertex.sizeof, false);
|
||||||
|
CreateBuffer(&g.rd, &model.index_buffer, BT.Index, indices.length * u32.sizeof, false);
|
||||||
|
|
||||||
|
assert(Transfer(&g.rd, &model.vertex_buffer, vertices), "LoadModel failure: Unable to transfer vertex buffer");
|
||||||
|
assert(Transfer(&g.rd, &model.index_buffer, indices), "LoadModel failure: Unable to transfer index buffer");
|
||||||
|
|
||||||
|
WriteDescriptors(&g.rd, DT.Material, model.materials, mat_lookup);
|
||||||
|
WriteDescriptors(&g.rd, DT.SampledImage, model.textures, tex_lookup);
|
||||||
|
|
||||||
|
model.positions = positions;
|
||||||
|
model.indices = indices;
|
||||||
|
model.pos_indices = pos_indices;
|
||||||
|
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
dst.x = src.x;
|
||||||
|
dst.y = src.y;
|
||||||
|
dst.z = src.z;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ReadModel(Game* g, string name)
|
||||||
|
{
|
||||||
|
AssetInfo info = GetAssetInfo(name);
|
||||||
|
|
||||||
|
u8[] data = LoadAssetData(&g.frame_arena, name);
|
||||||
|
|
||||||
|
m3d_t* m3d = m3d_load(data.ptr, null, null, null);
|
||||||
|
|
||||||
|
foreach(i; 0 .. m3d.numtexture)
|
||||||
|
{
|
||||||
|
const(char)[] tex_name = m3d.texture[i].name[0 .. strlen(m3d.texture[i].name)];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m3d.numtexture == 0)
|
||||||
|
{
|
||||||
|
Log("No textures in model");
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach(i; 0 .. m3d.nummaterial)
|
||||||
|
{
|
||||||
|
const(char)[] mat_name = m3d.material[i].name[0 .. strlen(m3d.material[i].name)];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@ -1,766 +0,0 @@
|
|||||||
import aliases;
|
|
||||||
import includes;
|
|
||||||
import assets;
|
|
||||||
import util;
|
|
||||||
import alloc;
|
|
||||||
import vulkan;
|
|
||||||
import vulkan : Destroy, Init, Draw, DrawIndexed, Bind, BindUIBuffers, BeginRendering, SetUniform, PrepComputeDrawImage, Dispatch, SubmitAndPresent, BeginFrame, WaitIdle, PushConstants, BindBuffers, SetClearColor, ImageBarrier, CreateImageView, GetDrawImageFormat, FinishRendering, UpdateAuxImage, ClearColor, SubmitAndPresent;
|
|
||||||
import assets;
|
|
||||||
import std.math.traits : isNaN;
|
|
||||||
import util : Logf;
|
|
||||||
import util;
|
|
||||||
import platform;
|
|
||||||
import math;
|
|
||||||
|
|
||||||
alias Shader = VkShaderModule;
|
|
||||||
alias Pipeline = PipelineHandle;
|
|
||||||
alias Attribute = VkVertexInputAttributeDescription;
|
|
||||||
alias SpecEntry = VkSpecializationMapEntry;
|
|
||||||
|
|
||||||
enum InputRate : int
|
|
||||||
{
|
|
||||||
Vertex = VK_VERTEX_INPUT_RATE_VERTEX,
|
|
||||||
Instance = VK_VERTEX_INPUT_RATE_INSTANCE,
|
|
||||||
}
|
|
||||||
|
|
||||||
alias IR = InputRate;
|
|
||||||
|
|
||||||
enum ImageUsage : VkImageUsageFlagBits
|
|
||||||
{
|
|
||||||
None = cast(VkImageUsageFlagBits)0,
|
|
||||||
Draw = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT |
|
|
||||||
VK_IMAGE_USAGE_STORAGE_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT,
|
|
||||||
Depth = VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT,
|
|
||||||
Texture = VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT,
|
|
||||||
Convert = VK_IMAGE_USAGE_STORAGE_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT,
|
|
||||||
Storage = VK_IMAGE_USAGE_STORAGE_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT,
|
|
||||||
Swapchain = VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT,
|
|
||||||
}
|
|
||||||
|
|
||||||
alias IU = ImageUsage;
|
|
||||||
|
|
||||||
enum Format : VkFormat
|
|
||||||
{
|
|
||||||
UINT = VK_FORMAT_R32_UINT,
|
|
||||||
R_F32 = VK_FORMAT_R32_SFLOAT,
|
|
||||||
RG_F32 = VK_FORMAT_R32G32_SFLOAT,
|
|
||||||
RGB_F32 = VK_FORMAT_R32G32B32_SFLOAT,
|
|
||||||
RGBA_F32 = VK_FORMAT_R32G32B32A32_SFLOAT,
|
|
||||||
RGBA_UINT = VK_FORMAT_B8G8R8A8_UINT,
|
|
||||||
R_U32 = VK_FORMAT_R32_UINT,
|
|
||||||
RG_U32 = VK_FORMAT_R32G32_UINT,
|
|
||||||
RGBA_UNORM = VK_FORMAT_R8G8B8A8_UNORM,
|
|
||||||
RGBA_SRGB = VK_FORMAT_R8G8B8A8_SRGB,
|
|
||||||
D_SF32 = VK_FORMAT_D32_SFLOAT,
|
|
||||||
}
|
|
||||||
|
|
||||||
alias FMT = Format;
|
|
||||||
|
|
||||||
enum BufferType : VkBufferUsageFlagBits
|
|
||||||
{
|
|
||||||
None = cast(VkBufferUsageFlagBits)0,
|
|
||||||
Vertex = VK_BUFFER_USAGE_VERTEX_BUFFER_BIT,
|
|
||||||
Index = VK_BUFFER_USAGE_INDEX_BUFFER_BIT,
|
|
||||||
Uniform = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT,
|
|
||||||
Storage = VK_BUFFER_USAGE_STORAGE_BUFFER_BIT,
|
|
||||||
Staging = VK_BUFFER_USAGE_TRANSFER_SRC_BIT,
|
|
||||||
BufferView = VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT | VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT,
|
|
||||||
}
|
|
||||||
|
|
||||||
alias BT = BufferType;
|
|
||||||
|
|
||||||
enum ImageLayout : VkImageLayout
|
|
||||||
{
|
|
||||||
Undefined = VK_IMAGE_LAYOUT_UNDEFINED,
|
|
||||||
General = VK_IMAGE_LAYOUT_GENERAL,
|
|
||||||
ColorAttach = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
|
|
||||||
}
|
|
||||||
|
|
||||||
struct GlobalUniforms
|
|
||||||
{
|
|
||||||
Mat4 view_matrix = Mat4Identity();
|
|
||||||
Mat4 projection_matrix = Mat4Identity();
|
|
||||||
Mat4 projection_view = Mat4Identity();
|
|
||||||
Vec4 light_color;
|
|
||||||
Vec4 ambient_color;
|
|
||||||
Vec3 light_direction;
|
|
||||||
f32 padding;
|
|
||||||
Vec2 res;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct ShaderUniforms
|
|
||||||
{
|
|
||||||
f32 placeholder;
|
|
||||||
}
|
|
||||||
|
|
||||||
enum PipelineType : int
|
|
||||||
{
|
|
||||||
Graphics,
|
|
||||||
Compute,
|
|
||||||
}
|
|
||||||
|
|
||||||
alias PT = PipelineType;
|
|
||||||
|
|
||||||
struct Specialization
|
|
||||||
{
|
|
||||||
u64 size;
|
|
||||||
SpecEntry[] entries;
|
|
||||||
void* data;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct GfxPipelineInfo
|
|
||||||
{
|
|
||||||
string vertex_shader;
|
|
||||||
string frag_shader;
|
|
||||||
InputRate input_rate;
|
|
||||||
u32 input_rate_stride;
|
|
||||||
Attribute[] vertex_attributes;
|
|
||||||
Specialization vert_spec;
|
|
||||||
Specialization frag_spec;
|
|
||||||
ImageView* draw_image;
|
|
||||||
ImageView* depth_image;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct CompPipelineInfo
|
|
||||||
{
|
|
||||||
string shader;
|
|
||||||
Specialization spec;
|
|
||||||
VkPipelineLayout *layout;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct PushConst
|
|
||||||
{
|
|
||||||
Mat4 model_matrix;
|
|
||||||
u32 mat_id;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct Extent
|
|
||||||
{
|
|
||||||
u32 x;
|
|
||||||
u32 y;
|
|
||||||
alias x w;
|
|
||||||
alias y h;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct UIVertex
|
|
||||||
{
|
|
||||||
Vec2 p0;
|
|
||||||
Vec2 p1;
|
|
||||||
Vec4 col;
|
|
||||||
u32 texture;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct Vertex
|
|
||||||
{
|
|
||||||
Vec4 color;
|
|
||||||
Vec4 tangent;
|
|
||||||
Vec3 pos;
|
|
||||||
Vec3 normal;
|
|
||||||
Vec2 uv;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct MeshPart
|
|
||||||
{
|
|
||||||
u32 mat;
|
|
||||||
u32 offset;
|
|
||||||
u32 length;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct Model
|
|
||||||
{
|
|
||||||
Vec3 pos = Vec3(0.0);
|
|
||||||
Buffer vertex_buffer;
|
|
||||||
Buffer index_buffer;
|
|
||||||
MeshPart[] parts;
|
|
||||||
|
|
||||||
string name;
|
|
||||||
|
|
||||||
Buffer[] materials;
|
|
||||||
ImageView[] textures;
|
|
||||||
|
|
||||||
Vec3[] positions;
|
|
||||||
u32[] pos_indices;
|
|
||||||
u32[] indices;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct Image
|
|
||||||
{
|
|
||||||
VkImage image;
|
|
||||||
VmaAllocation alloc;
|
|
||||||
Format format;
|
|
||||||
VkImageLayout layout;
|
|
||||||
u32 w;
|
|
||||||
u32 h;
|
|
||||||
bool depth_image;
|
|
||||||
ImageUsage usage;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct BufferView
|
|
||||||
{
|
|
||||||
Buffer base;
|
|
||||||
VkBufferView view;
|
|
||||||
|
|
||||||
alias base this;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct ImageView
|
|
||||||
{
|
|
||||||
Image base;
|
|
||||||
VkImageView view;
|
|
||||||
|
|
||||||
alias base this;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct Buffer
|
|
||||||
{
|
|
||||||
VkBuffer buffer;
|
|
||||||
VmaAllocation alloc;
|
|
||||||
u64 size;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct Renderer
|
|
||||||
{
|
|
||||||
Arena arena;
|
|
||||||
Arena temp_arena;
|
|
||||||
|
|
||||||
Vulkan vk;
|
|
||||||
PlatformWindow* window;
|
|
||||||
|
|
||||||
UIVertex[] ui_vertex_buf;
|
|
||||||
u32[] ui_index_buf;
|
|
||||||
u32 ui_count;
|
|
||||||
}
|
|
||||||
|
|
||||||
Renderer
|
|
||||||
InitRenderer(PlatformWindow* window)
|
|
||||||
{
|
|
||||||
Result!(Vulkan) vk_result = Init(window, MB(24), MB(32));
|
|
||||||
assert(vk_result.ok, "Init failure: Unable to initialize Vulkan");
|
|
||||||
|
|
||||||
Renderer rd = {
|
|
||||||
arena: CreateArena(MB(16)),
|
|
||||||
temp_arena: CreateArena(MB(16)),
|
|
||||||
vk: vk_result.value,
|
|
||||||
window: window,
|
|
||||||
ui_vertex_buf: GetUIVertexBuffer(&vk_result.value),
|
|
||||||
ui_index_buf: GetUIIndexBuffer(&vk_result.value),
|
|
||||||
};
|
|
||||||
|
|
||||||
return rd;
|
|
||||||
}
|
|
||||||
|
|
||||||
pragma(inline): Extent
|
|
||||||
GetExtent(Renderer* rd)
|
|
||||||
{
|
|
||||||
return Extent(rd.vk.swapchain_extent.width, rd.vk.swapchain_extent.height);
|
|
||||||
}
|
|
||||||
|
|
||||||
pragma(inline): f32
|
|
||||||
GetAspect(Renderer* rd)
|
|
||||||
{
|
|
||||||
return cast(f32)(rd.vk.swapchain_extent.width) / cast(f32)(rd.vk.swapchain_extent.height);
|
|
||||||
}
|
|
||||||
|
|
||||||
pragma(inline): void
|
|
||||||
BeginFrame(Renderer* rd)
|
|
||||||
{
|
|
||||||
rd.ui_count = 0;
|
|
||||||
BeginFrame(&rd.vk);
|
|
||||||
}
|
|
||||||
|
|
||||||
pragma(inline): void
|
|
||||||
DrawUI(Renderer* rd)
|
|
||||||
{
|
|
||||||
DrawIndexed(rd, 6, rd.ui_count, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
pragma(inline): void
|
|
||||||
Dispatch(Renderer* rd)
|
|
||||||
{
|
|
||||||
Dispatch(&rd.vk);
|
|
||||||
}
|
|
||||||
|
|
||||||
pragma(inline): void
|
|
||||||
PrepComputeDrawImage(Renderer* rd)
|
|
||||||
{
|
|
||||||
PrepComputeDrawImage(&rd.vk);
|
|
||||||
}
|
|
||||||
|
|
||||||
pragma(inline): void
|
|
||||||
SetUniform(Renderer* rd, GlobalUniforms* uniforms)
|
|
||||||
{
|
|
||||||
SetUniform(&rd.vk, uniforms);
|
|
||||||
}
|
|
||||||
|
|
||||||
pragma(inline): void
|
|
||||||
BeginRendering(Renderer* rd, ImageView* draw_image, ImageView* depth_image)
|
|
||||||
{
|
|
||||||
BeginRendering(&rd.vk, draw_image, depth_image);
|
|
||||||
}
|
|
||||||
|
|
||||||
pragma(inline): void
|
|
||||||
BindUIBuffers(Renderer* rd)
|
|
||||||
{
|
|
||||||
BindUIBuffers(&rd.vk);
|
|
||||||
}
|
|
||||||
|
|
||||||
pragma(inline): void
|
|
||||||
DrawIndexed(Renderer* rd, u32 index_count, u32 instance_count, u32 index_offset)
|
|
||||||
{
|
|
||||||
DrawIndexed(&rd.vk, index_count, instance_count, index_offset);
|
|
||||||
}
|
|
||||||
|
|
||||||
pragma(inline): void
|
|
||||||
Draw(Renderer* rd, u32 index_count, u32 instance_count)
|
|
||||||
{
|
|
||||||
Draw(&rd.vk, index_count, instance_count);
|
|
||||||
}
|
|
||||||
|
|
||||||
pragma(inline): void
|
|
||||||
Bind(Renderer* rd, Pipeline* pipeline)
|
|
||||||
{
|
|
||||||
Bind(&rd.vk, pipeline);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
UpdateIndexBuffer(Renderer* rd, Model* model)
|
|
||||||
{
|
|
||||||
assert(Transfer(&rd.vk, &model.index_buffer, model.indices), "UpdateIndexBuffer failure");
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
DrawRect(Renderer* rd, f32 p0_x, f32 p0_y, f32 p1_x, f32 p1_y, Vec4 col)
|
|
||||||
{
|
|
||||||
rd.ui_vertex_buf[rd.ui_count].p0.x = p0_x;
|
|
||||||
rd.ui_vertex_buf[rd.ui_count].p0.y = p0_y;
|
|
||||||
rd.ui_vertex_buf[rd.ui_count].p1.x = p1_x;
|
|
||||||
rd.ui_vertex_buf[rd.ui_count].p1.y = p1_y;
|
|
||||||
rd.ui_vertex_buf[rd.ui_count].col = col;
|
|
||||||
|
|
||||||
u32 index_count = rd.ui_count * 6;
|
|
||||||
|
|
||||||
rd.ui_index_buf[index_count+0] = index_count+0;
|
|
||||||
rd.ui_index_buf[index_count+1] = index_count+1;
|
|
||||||
rd.ui_index_buf[index_count+2] = index_count+2;
|
|
||||||
rd.ui_index_buf[index_count+3] = index_count+1;
|
|
||||||
rd.ui_index_buf[index_count+4] = index_count+2;
|
|
||||||
rd.ui_index_buf[index_count+5] = index_count+3;
|
|
||||||
|
|
||||||
rd.ui_count += 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
pragma(inline): void
|
|
||||||
BindBuffers(Renderer* rd, Buffer* index_buffer, Buffer* vertex_buffer)
|
|
||||||
{
|
|
||||||
BindBuffers(&rd.vk, index_buffer, vertex_buffer);
|
|
||||||
}
|
|
||||||
|
|
||||||
pragma(inline): void
|
|
||||||
PushConstants(Renderer* rd, PushConst* pc)
|
|
||||||
{
|
|
||||||
PushConstants(&rd.vk, pc);
|
|
||||||
}
|
|
||||||
|
|
||||||
pragma(inline): Pipeline
|
|
||||||
BuildGfxPipeline(Renderer* rd, GfxPipelineInfo* info)
|
|
||||||
{
|
|
||||||
return CreateGraphicsPipeline(&rd.vk, info);
|
|
||||||
}
|
|
||||||
|
|
||||||
pragma(inline): Pipeline
|
|
||||||
BuildCompPipeline(Renderer* rd, CompPipelineInfo* comp_info)
|
|
||||||
{
|
|
||||||
return CreateComputePipeline(&rd.vk, comp_info);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
ReadModel(Renderer* rd, string name)
|
|
||||||
{
|
|
||||||
AssetInfo info = GetAssetInfo(name);
|
|
||||||
|
|
||||||
u8[] data = LoadAssetData(&rd.temp_arena, name);
|
|
||||||
|
|
||||||
m3d_t* m3d = m3d_load(data.ptr, null, null, null);
|
|
||||||
|
|
||||||
foreach(i; 0 .. m3d.numtexture)
|
|
||||||
{
|
|
||||||
const(char)[] tex_name = m3d.texture[i].name[0 .. strlen(m3d.texture[i].name)];
|
|
||||||
}
|
|
||||||
|
|
||||||
if (m3d.numtexture == 0)
|
|
||||||
{
|
|
||||||
Log("No textures in model");
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach(i; 0 .. m3d.nummaterial)
|
|
||||||
{
|
|
||||||
const(char)[] mat_name = m3d.material[i].name[0 .. strlen(m3d.material[i].name)];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Model
|
|
||||||
LoadModel(Renderer* rd, string name)
|
|
||||||
{
|
|
||||||
AssetInfo info = GetAssetInfo(name);
|
|
||||||
|
|
||||||
u8[] data = LoadAssetData(&rd.temp_arena, name);
|
|
||||||
Model model = {
|
|
||||||
name: name,
|
|
||||||
};
|
|
||||||
|
|
||||||
m3d_t* m3d = m3d_load(data.ptr, null, null, null);
|
|
||||||
scope(exit) m3d_free(m3d);
|
|
||||||
|
|
||||||
u32[] tex_lookup = AllocArray!(u32)(&rd.temp_arena, m3d.numtexture);
|
|
||||||
model.textures = AllocArray!(ImageView)(&rd.arena, 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;
|
|
||||||
u8[] tex_data = m3d.texture[i].d[0 .. w * h * ch];
|
|
||||||
|
|
||||||
const(char)[] tex_name = m3d.texture[i].name[0 .. strlen(m3d.texture[i].name)];
|
|
||||||
CreateImageView(&rd.vk, &model.textures[i], w, h, ch, tex_data);
|
|
||||||
|
|
||||||
tex_lookup[i] = Pop(&rd.vk, DT.SampledImage);
|
|
||||||
}
|
|
||||||
|
|
||||||
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);
|
|
||||||
foreach(i; 0 .. m3d.nummaterial)
|
|
||||||
{
|
|
||||||
const(char)[] mat_name = m3d.material[i].name[0 .. strlen(m3d.material[i].name)];
|
|
||||||
|
|
||||||
foreach(j; 0 .. m3d.material[i].numprop)
|
|
||||||
{
|
|
||||||
switch (m3d.material[i].prop[j].type)
|
|
||||||
{
|
|
||||||
case m3dp_Kd: ConvertColor(&mats[i].albedo, m3d.material[i].prop[j].value.color); break;
|
|
||||||
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];
|
|
||||||
mats[i].albedo_has_texture = true;
|
|
||||||
} break;
|
|
||||||
case m3dp_map_Ka:
|
|
||||||
{
|
|
||||||
mats[i].ambient_texture = tex_lookup[m3d.material[i].prop[j].value.textureid];
|
|
||||||
mats[i].ambient_has_texture = true;
|
|
||||||
} break;
|
|
||||||
case m3dp_map_Ks:
|
|
||||||
{
|
|
||||||
mats[i].specular_texture = tex_lookup[m3d.material[i].prop[j].value.textureid];
|
|
||||||
mats[i].specular_has_texture = true;
|
|
||||||
} break;
|
|
||||||
case m3dp_map_D:
|
|
||||||
{
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
CreateBuffer(&rd.vk, &model.materials[i], BT.Uniform, Material.sizeof, false);
|
|
||||||
assert(Transfer(&rd.vk, &model.materials[i], &mats[i]), "LoadModel failure: Transfer error when transferring material");
|
|
||||||
|
|
||||||
mat_lookup[i] = Pop(&rd.vk, DT.Material);
|
|
||||||
}
|
|
||||||
|
|
||||||
u32 mesh_count = 0;
|
|
||||||
u64 last = u64.max;
|
|
||||||
foreach(i; 0 .. m3d.numface)
|
|
||||||
{
|
|
||||||
if (m3d.face[i].materialid != last)
|
|
||||||
{
|
|
||||||
last = m3d.face[i].materialid;
|
|
||||||
mesh_count += 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
model.parts = AllocArray!(MeshPart)(&rd.arena, mesh_count);
|
|
||||||
last = u64.max;
|
|
||||||
u32 index = 0;
|
|
||||||
foreach(i; 0 .. m3d.numface)
|
|
||||||
{
|
|
||||||
if (last == u64.max)
|
|
||||||
{
|
|
||||||
model.parts[index].mat = (m3d.face[i].materialid != u32.max) ? mat_lookup[m3d.face[i].materialid] : 0;
|
|
||||||
model.parts[index].offset = 0;
|
|
||||||
last = m3d.face[i].materialid;
|
|
||||||
}
|
|
||||||
else if (m3d.face[i].materialid != last)
|
|
||||||
{
|
|
||||||
u32 vertex_index = i * 3;
|
|
||||||
|
|
||||||
model.parts[index].length = vertex_index - model.parts[index].offset;
|
|
||||||
index += 1;
|
|
||||||
|
|
||||||
model.parts[index].mat = mat_lookup[m3d.face[i].materialid];
|
|
||||||
model.parts[index].offset = vertex_index;
|
|
||||||
last = m3d.face[i].materialid;
|
|
||||||
}
|
|
||||||
else if (i == m3d.numface-1)
|
|
||||||
{
|
|
||||||
u32 vertex_index = i * 3;
|
|
||||||
model.parts[index].length = vertex_index+3 - model.parts[index].offset;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
m3dv_t* vertex;
|
|
||||||
|
|
||||||
u32[] indices = AllocArray!(u32)(&rd.arena, m3d.numface * 3);
|
|
||||||
Vertex[] vertices = AllocArray!(Vertex)(&rd.temp_arena, m3d.numface * 3);
|
|
||||||
Vec3[] positions = AllocArray!(Vec3)(&rd.arena, m3d.numface);
|
|
||||||
u32[] pos_indices = AllocArray!(u32)(&rd.arena, m3d.numface);
|
|
||||||
|
|
||||||
foreach(i; 0 .. m3d.numface)
|
|
||||||
{
|
|
||||||
u32 vi = (i * 3);
|
|
||||||
u32 i0 = vi+0;
|
|
||||||
u32 i1 = vi+1;
|
|
||||||
u32 i2 = vi+2;
|
|
||||||
|
|
||||||
CopyVertex(&vertices[i0].pos, &m3d.vertex[m3d.face[i].vertex[0]]);
|
|
||||||
CopyVertex(&vertices[i1].pos, &m3d.vertex[m3d.face[i].vertex[1]]);
|
|
||||||
CopyVertex(&vertices[i2].pos, &m3d.vertex[m3d.face[i].vertex[2]]);
|
|
||||||
|
|
||||||
CopyVertex(&vertices[i0].normal, &m3d.vertex[m3d.face[i].normal[0]]);
|
|
||||||
CopyVertex(&vertices[i1].normal, &m3d.vertex[m3d.face[i].normal[1]]);
|
|
||||||
CopyVertex(&vertices[i2].normal, &m3d.vertex[m3d.face[i].normal[2]]);
|
|
||||||
|
|
||||||
ConvertColor(&vertices[i0].color, m3d.vertex[m3d.face[i].vertex[0]].color);
|
|
||||||
ConvertColor(&vertices[i1].color, m3d.vertex[m3d.face[i].vertex[1]].color);
|
|
||||||
ConvertColor(&vertices[i2].color, m3d.vertex[m3d.face[i].vertex[2]].color);
|
|
||||||
|
|
||||||
if (m3d.numtmap)
|
|
||||||
{
|
|
||||||
vertices[i0].uv.x = m3d.tmap[m3d.face[i].texcoord[0]].u;
|
|
||||||
vertices[i0].uv.y = m3d.tmap[m3d.face[i].texcoord[0]].v;
|
|
||||||
|
|
||||||
vertices[i1].uv.x = m3d.tmap[m3d.face[i].texcoord[1]].u;
|
|
||||||
vertices[i1].uv.y = m3d.tmap[m3d.face[i].texcoord[1]].v;
|
|
||||||
|
|
||||||
vertices[i2].uv.x = m3d.tmap[m3d.face[i].texcoord[2]].u;
|
|
||||||
vertices[i2].uv.y = m3d.tmap[m3d.face[i].texcoord[2]].v;
|
|
||||||
}
|
|
||||||
|
|
||||||
indices[i0] = i0;
|
|
||||||
indices[i1] = i1;
|
|
||||||
indices[i2] = i2;
|
|
||||||
|
|
||||||
Vec3 center = (vertices[i0].pos + vertices[i1].pos + vertices[i2].pos) / 3.0;
|
|
||||||
|
|
||||||
positions[i] = center;
|
|
||||||
pos_indices[i] = i;
|
|
||||||
}
|
|
||||||
|
|
||||||
for(u64 i = 0; i < indices.length; i += 3)
|
|
||||||
{
|
|
||||||
u32 i0 = indices[i+0];
|
|
||||||
u32 i1 = indices[i+1];
|
|
||||||
u32 i2 = indices[i+2];
|
|
||||||
|
|
||||||
Vec3 edge1 = vertices[i1].pos - vertices[i0].pos;
|
|
||||||
Vec3 edge2 = vertices[i2].pos - vertices[i0].pos;
|
|
||||||
|
|
||||||
Vec2 delta_uv1 = vertices[i1].uv - vertices[i0].uv;
|
|
||||||
Vec2 delta_uv2 = vertices[i2].uv - vertices[i0].uv;
|
|
||||||
|
|
||||||
f32 dividend = delta_uv1.x * delta_uv2.y - delta_uv2.x * delta_uv1.y;
|
|
||||||
f32 fc = 1.0 / dividend;
|
|
||||||
|
|
||||||
Vec3 tangent = Vec3(
|
|
||||||
fc * (delta_uv2.y * edge1.x - delta_uv1.y * edge2.x),
|
|
||||||
fc * (delta_uv2.y * edge1.y - delta_uv1.y * edge2.y),
|
|
||||||
fc * (delta_uv2.y * edge1.z - delta_uv1.y * edge2.z)
|
|
||||||
);
|
|
||||||
|
|
||||||
Normalize(&tangent);
|
|
||||||
|
|
||||||
f32 handedness = ((delta_uv1.y * delta_uv2.x - delta_uv2.y * delta_uv1.x) < 0.0) ? -1.0 : 1.0;
|
|
||||||
|
|
||||||
Vec3 t = tangent * handedness;
|
|
||||||
|
|
||||||
vertices[i0].tangent = Vec4(t, handedness);
|
|
||||||
vertices[i1].tangent = Vec4(t, handedness);
|
|
||||||
vertices[i2].tangent = Vec4(t, handedness);
|
|
||||||
}
|
|
||||||
|
|
||||||
assert(vertices.length > 0 && indices.length > 0, "Error loading model");
|
|
||||||
|
|
||||||
CreateBuffer(&rd.vk, &model.vertex_buffer, BT.Vertex, vertices.length * Vertex.sizeof, false);
|
|
||||||
CreateBuffer(&rd.vk, &model.index_buffer, BT.Index, indices.length * u32.sizeof, false);
|
|
||||||
|
|
||||||
assert(Transfer(&rd.vk, &model.vertex_buffer, vertices), "LoadModel failure: Unable to transfer vertex buffer");
|
|
||||||
assert(Transfer(&rd.vk, &model.index_buffer, indices), "LoadModel failure: Unable to transfer index buffer");
|
|
||||||
|
|
||||||
WriteDescriptors(&rd.vk, DT.Material, model.materials, mat_lookup);
|
|
||||||
WriteDescriptors(&rd.vk, DT.SampledImage, model.textures, tex_lookup);
|
|
||||||
|
|
||||||
model.positions = positions;
|
|
||||||
model.indices = indices;
|
|
||||||
model.pos_indices = pos_indices;
|
|
||||||
|
|
||||||
Reset(&rd.temp_arena);
|
|
||||||
|
|
||||||
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)
|
|
||||||
{
|
|
||||||
dst.x = src.x;
|
|
||||||
dst.y = src.y;
|
|
||||||
dst.z = src.z;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
Destroy(Renderer* rd)
|
|
||||||
{
|
|
||||||
Destroy(&rd.vk);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
Destroy(Renderer* rd, Pipeline* pipeline)
|
|
||||||
{
|
|
||||||
Destroy(&rd.vk, pipeline);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
WaitIdle(Renderer* rd)
|
|
||||||
{
|
|
||||||
WaitIdle(&rd.vk);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
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
|
|
||||||
ImageBarrier(Renderer* rd)
|
|
||||||
{
|
|
||||||
ImageBarrier(&rd.vk);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
CreateImageView(Renderer* rd, ImageView* view, u32 w, u32 h, Format format, ImageUsage usage, bool depth_image = false)
|
|
||||||
{
|
|
||||||
CreateImageView(&rd.vk, view, w, h, format, usage, depth_image);
|
|
||||||
}
|
|
||||||
|
|
||||||
Format
|
|
||||||
GetDrawImageFormat(Renderer* rd)
|
|
||||||
{
|
|
||||||
return cast(Format)GetDrawImageFormat(&rd.vk);
|
|
||||||
}
|
|
||||||
|
|
||||||
pragma(inline): void
|
|
||||||
ResizeDrawImageIfNeeded(Renderer* rd, ImageView* view)
|
|
||||||
{
|
|
||||||
Extent ext = GetExtent(rd);
|
|
||||||
|
|
||||||
if (view.w != ext.w || view.h != ext.h)
|
|
||||||
{
|
|
||||||
Destroy(view, rd.vk.device, rd.vk.vma);
|
|
||||||
CreateImageView(&rd.vk, view, ext.w, ext.h, view.format, view.usage, view.depth_image);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
FinishRendering(Renderer* rd)
|
|
||||||
{
|
|
||||||
FinishRendering(&rd.vk);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
Submit(Renderer* rd, ImageView* view)
|
|
||||||
{
|
|
||||||
SubmitAndPresent(&rd.vk, view);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
UpdateAuxImage(Renderer* rd, ImageView* view)
|
|
||||||
{
|
|
||||||
UpdateAuxImage(&rd.vk, view);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
ClearColor(Renderer* rd, ImageView* view, Vec4 color)
|
|
||||||
{
|
|
||||||
ClearColor(&rd.vk, view, color);
|
|
||||||
}
|
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -10,10 +10,13 @@ import util;
|
|||||||
import alloc;
|
import alloc;
|
||||||
import platform;
|
import platform;
|
||||||
import assets;
|
import assets;
|
||||||
import renderer;
|
import game;
|
||||||
import std.math.rounding : Ceil = ceil;
|
import std.math.rounding : Ceil = ceil;
|
||||||
import math;
|
import math;
|
||||||
|
|
||||||
|
alias InitRenderer = Init;
|
||||||
|
alias Renderer = Vulkan;
|
||||||
|
|
||||||
bool g_VLAYER_SUPPORT = false;
|
bool g_VLAYER_SUPPORT = false;
|
||||||
bool g_DEBUG_PRINTF = false;
|
bool g_DEBUG_PRINTF = false;
|
||||||
|
|
||||||
@ -77,6 +80,163 @@ const VkFormat[] VK_IMAGE_FORMATS = [
|
|||||||
VK_FORMAT_R8G8B8A8_UNORM,
|
VK_FORMAT_R8G8B8A8_UNORM,
|
||||||
];
|
];
|
||||||
|
|
||||||
|
alias Shader = VkShaderModule;
|
||||||
|
alias Pipeline = PipelineHandle;
|
||||||
|
alias Attribute = VkVertexInputAttributeDescription;
|
||||||
|
alias SpecEntry = VkSpecializationMapEntry;
|
||||||
|
|
||||||
|
enum InputRate : int
|
||||||
|
{
|
||||||
|
Vertex = VK_VERTEX_INPUT_RATE_VERTEX,
|
||||||
|
Instance = VK_VERTEX_INPUT_RATE_INSTANCE,
|
||||||
|
}
|
||||||
|
|
||||||
|
alias IR = InputRate;
|
||||||
|
|
||||||
|
enum ImageUsage : VkImageUsageFlagBits
|
||||||
|
{
|
||||||
|
None = cast(VkImageUsageFlagBits)0,
|
||||||
|
Draw = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT |
|
||||||
|
VK_IMAGE_USAGE_STORAGE_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT,
|
||||||
|
Depth = VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT,
|
||||||
|
Texture = VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT,
|
||||||
|
Convert = VK_IMAGE_USAGE_STORAGE_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT,
|
||||||
|
Storage = VK_IMAGE_USAGE_STORAGE_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT,
|
||||||
|
Swapchain = VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT,
|
||||||
|
}
|
||||||
|
|
||||||
|
alias IU = ImageUsage;
|
||||||
|
|
||||||
|
enum Format : VkFormat
|
||||||
|
{
|
||||||
|
UINT = VK_FORMAT_R32_UINT,
|
||||||
|
R_F32 = VK_FORMAT_R32_SFLOAT,
|
||||||
|
RG_F32 = VK_FORMAT_R32G32_SFLOAT,
|
||||||
|
RGB_F32 = VK_FORMAT_R32G32B32_SFLOAT,
|
||||||
|
RGBA_F32 = VK_FORMAT_R32G32B32A32_SFLOAT,
|
||||||
|
RGBA_UINT = VK_FORMAT_B8G8R8A8_UINT,
|
||||||
|
R_U32 = VK_FORMAT_R32_UINT,
|
||||||
|
RG_U32 = VK_FORMAT_R32G32_UINT,
|
||||||
|
RGBA_UNORM = VK_FORMAT_R8G8B8A8_UNORM,
|
||||||
|
RGBA_SRGB = VK_FORMAT_R8G8B8A8_SRGB,
|
||||||
|
D_SF32 = VK_FORMAT_D32_SFLOAT,
|
||||||
|
}
|
||||||
|
|
||||||
|
alias FMT = Format;
|
||||||
|
|
||||||
|
enum BufferType : VkBufferUsageFlagBits
|
||||||
|
{
|
||||||
|
None = cast(VkBufferUsageFlagBits)0,
|
||||||
|
Vertex = VK_BUFFER_USAGE_VERTEX_BUFFER_BIT,
|
||||||
|
Index = VK_BUFFER_USAGE_INDEX_BUFFER_BIT,
|
||||||
|
Uniform = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT,
|
||||||
|
Storage = VK_BUFFER_USAGE_STORAGE_BUFFER_BIT,
|
||||||
|
Staging = VK_BUFFER_USAGE_TRANSFER_SRC_BIT,
|
||||||
|
BufferView = VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT | VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT,
|
||||||
|
}
|
||||||
|
|
||||||
|
alias BT = BufferType;
|
||||||
|
|
||||||
|
enum ImageLayout : VkImageLayout
|
||||||
|
{
|
||||||
|
Undefined = VK_IMAGE_LAYOUT_UNDEFINED,
|
||||||
|
General = VK_IMAGE_LAYOUT_GENERAL,
|
||||||
|
ColorAttach = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
|
||||||
|
}
|
||||||
|
|
||||||
|
struct GlobalUniforms
|
||||||
|
{
|
||||||
|
Mat4 view_matrix = Mat4Identity();
|
||||||
|
Mat4 projection_matrix = Mat4Identity();
|
||||||
|
Mat4 projection_view = Mat4Identity();
|
||||||
|
Vec4 light_color;
|
||||||
|
Vec4 ambient_color;
|
||||||
|
Vec3 light_direction;
|
||||||
|
f32 padding;
|
||||||
|
Vec2 res;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Image
|
||||||
|
{
|
||||||
|
VkImage image;
|
||||||
|
VmaAllocation alloc;
|
||||||
|
Format format;
|
||||||
|
VkImageLayout layout;
|
||||||
|
u32 w;
|
||||||
|
u32 h;
|
||||||
|
bool depth_image;
|
||||||
|
ImageUsage usage;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct BufferView
|
||||||
|
{
|
||||||
|
Buffer base;
|
||||||
|
VkBufferView view;
|
||||||
|
|
||||||
|
alias base this;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct ImageView
|
||||||
|
{
|
||||||
|
Image base;
|
||||||
|
VkImageView view;
|
||||||
|
|
||||||
|
alias base this;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Buffer
|
||||||
|
{
|
||||||
|
VkBuffer buffer;
|
||||||
|
VmaAllocation alloc;
|
||||||
|
u64 size;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct ShaderUniforms
|
||||||
|
{
|
||||||
|
f32 placeholder;
|
||||||
|
}
|
||||||
|
|
||||||
|
enum PipelineType : int
|
||||||
|
{
|
||||||
|
Graphics,
|
||||||
|
Compute,
|
||||||
|
}
|
||||||
|
|
||||||
|
alias PT = PipelineType;
|
||||||
|
|
||||||
|
struct Specialization
|
||||||
|
{
|
||||||
|
u64 size;
|
||||||
|
SpecEntry[] entries;
|
||||||
|
void* data;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct GfxPipelineInfo
|
||||||
|
{
|
||||||
|
string vertex_shader;
|
||||||
|
string frag_shader;
|
||||||
|
InputRate input_rate;
|
||||||
|
u32 input_rate_stride;
|
||||||
|
Attribute[] vertex_attributes;
|
||||||
|
Specialization vert_spec;
|
||||||
|
Specialization frag_spec;
|
||||||
|
ImageView* draw_image;
|
||||||
|
ImageView* depth_image;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct CompPipelineInfo
|
||||||
|
{
|
||||||
|
string shader;
|
||||||
|
Specialization spec;
|
||||||
|
VkPipelineLayout *layout;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct PushConst
|
||||||
|
{
|
||||||
|
Mat4 model_matrix;
|
||||||
|
u32 mat_id;
|
||||||
|
}
|
||||||
|
|
||||||
enum StepInitialized : u32
|
enum StepInitialized : u32
|
||||||
{
|
{
|
||||||
Renderer = 1,
|
Renderer = 1,
|
||||||
@ -196,9 +356,6 @@ struct Vulkan
|
|||||||
VkPipeline last_comp_pipeline;
|
VkPipeline last_comp_pipeline;
|
||||||
bool compute_pass_started;
|
bool compute_pass_started;
|
||||||
|
|
||||||
bool enable_clear_color;
|
|
||||||
VkClearColorValue clear_color;
|
|
||||||
|
|
||||||
BufferView a_buffer_view;
|
BufferView a_buffer_view;
|
||||||
ImageView aux_image;
|
ImageView aux_image;
|
||||||
|
|
||||||
@ -224,7 +381,7 @@ struct QueueInfo
|
|||||||
bool single_queue;
|
bool single_queue;
|
||||||
}
|
}
|
||||||
|
|
||||||
Result!(Vulkan)
|
Vulkan
|
||||||
Init(PlatformWindow* window, u64 permanent_mem, u64 frame_mem)
|
Init(PlatformWindow* window, u64 permanent_mem, u64 frame_mem)
|
||||||
{
|
{
|
||||||
bool success = true;
|
bool success = true;
|
||||||
@ -260,17 +417,9 @@ Init(PlatformWindow* window, u64 permanent_mem, u64 frame_mem)
|
|||||||
if (success) InitBuffers(&vk);
|
if (success) InitBuffers(&vk);
|
||||||
if (success) success = InitConversionPipeline(&vk);
|
if (success) success = InitConversionPipeline(&vk);
|
||||||
|
|
||||||
Result!(Vulkan) result = {
|
assert(success, "Error initializing vulkan");
|
||||||
ok: success,
|
|
||||||
value: vk,
|
|
||||||
};
|
|
||||||
|
|
||||||
if (!success)
|
return vk;
|
||||||
{
|
|
||||||
Logf("error initializing vulkan");
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
@ -410,6 +559,12 @@ CreateBuffer(Vulkan* vk, Buffer* buf, BufferType type, u64 size, bool host_visib
|
|||||||
buf.size = size;
|
buf.size = size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
UpdateIndexBuffer(Vulkan* vk, Model* model)
|
||||||
|
{
|
||||||
|
assert(Transfer(vk, &model.index_buffer, model.indices), "UpdateIndexBuffer failure");
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
InitBuffers(Vulkan* vk)
|
InitBuffers(Vulkan* vk)
|
||||||
{
|
{
|
||||||
@ -525,11 +680,8 @@ BeginRendering(Vulkan* vk, ImageView* draw_image, ImageView* depth_image)
|
|||||||
sType: VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO,
|
sType: VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO,
|
||||||
imageView: draw_image.view,
|
imageView: draw_image.view,
|
||||||
imageLayout: draw_image.layout,
|
imageLayout: draw_image.layout,
|
||||||
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)
|
loadOp: VK_ATTACHMENT_LOAD_OP_CLEAR, // CLEAR instead of LOAD if wanting to clear colors, also clearColor value (or whatever)
|
||||||
storeOp: VK_ATTACHMENT_STORE_OP_STORE,
|
storeOp: VK_ATTACHMENT_STORE_OP_STORE,
|
||||||
clearValue: {
|
|
||||||
color: vk.clear_color,
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
|
|
||||||
VkRenderingAttachmentInfo depth_attach = {
|
VkRenderingAttachmentInfo depth_attach = {
|
||||||
@ -557,13 +709,28 @@ BeginRendering(Vulkan* vk, ImageView* draw_image, ImageView* depth_image)
|
|||||||
vkCmdBeginRendering(vk.cmds[vk.frame_index], &render_info);
|
vkCmdBeginRendering(vk.cmds[vk.frame_index], &render_info);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
pragma(inline): void
|
||||||
SetClearColor(Vulkan* vk, Vec4 color)
|
ResizeDrawImageIfNeeded(Vulkan* vk, ImageView* view)
|
||||||
{
|
{
|
||||||
vk.clear_color.float32[0] = color.r;
|
UVec2 ext = GetExtent(vk);
|
||||||
vk.clear_color.float32[1] = color.g;
|
|
||||||
vk.clear_color.float32[2] = color.b;
|
if (view.w != ext.x || view.h != ext.y)
|
||||||
vk.clear_color.float32[3] = color.a;
|
{
|
||||||
|
Destroy(vk, view);
|
||||||
|
CreateImageView(vk, view, ext.x, ext.y, view.format, view.usage, view.depth_image);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pragma(inline): UVec2
|
||||||
|
GetExtent(Vulkan* vk)
|
||||||
|
{
|
||||||
|
return UVec2(vk.swapchain_extent.width, vk.swapchain_extent.height);
|
||||||
|
}
|
||||||
|
|
||||||
|
pragma(inline): f32
|
||||||
|
GetAspect(Vulkan* vk)
|
||||||
|
{
|
||||||
|
return cast(f32)(vk.swapchain_extent.width) / cast(f32)(vk.swapchain_extent.height);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -812,7 +979,7 @@ CreateImageView(Vulkan* vk, ImageView* view, u32 w, u32 h, u32 ch, u8[] data)
|
|||||||
vkQueueWaitIdle(vk.tfer_queue);
|
vkQueueWaitIdle(vk.tfer_queue);
|
||||||
|
|
||||||
Destroy(vk, &buf);
|
Destroy(vk, &buf);
|
||||||
Destroy(&conv_view, vk.device, vk.vma);
|
Destroy(vk, &conv_view);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1626,7 +1793,8 @@ Destroy(Vulkan* vk)
|
|||||||
Destroy(vk.swapchain, vk.present_images, vk.device);
|
Destroy(vk.swapchain, vk.present_images, vk.device);
|
||||||
break;
|
break;
|
||||||
case SI.DrawImages:
|
case SI.DrawImages:
|
||||||
Destroy(&vk.draw_image, &vk.depth_image, vk.device, vk.vma);
|
Destroy(vk, &vk.draw_image);
|
||||||
|
Destroy(vk, &vk.depth_image);
|
||||||
break;
|
break;
|
||||||
case SI.Descriptors:
|
case SI.Descriptors:
|
||||||
Destroy(vk.desc_pool, vk.desc_layouts, vk.pipeline_layout, vk.nearest_sampler, vk.device);
|
Destroy(vk.desc_pool, vk.desc_layouts, vk.pipeline_layout, vk.nearest_sampler, vk.device);
|
||||||
@ -2242,7 +2410,7 @@ InitFrameStructures(Vulkan* vk)
|
|||||||
return success;
|
return success;
|
||||||
}
|
}
|
||||||
|
|
||||||
VkFormat
|
Format
|
||||||
GetDrawImageFormat(Vulkan* vk)
|
GetDrawImageFormat(Vulkan* vk)
|
||||||
{
|
{
|
||||||
VkFormat selected_format;
|
VkFormat selected_format;
|
||||||
@ -2270,7 +2438,7 @@ GetDrawImageFormat(Vulkan* vk)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return selected_format;
|
return cast(Format)selected_format;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
@ -2414,7 +2582,8 @@ RecreateSwapchain(Vulkan* vk)
|
|||||||
vkDeviceWaitIdle(vk.device);
|
vkDeviceWaitIdle(vk.device);
|
||||||
|
|
||||||
Destroy(vk.swapchain, vk.present_images, vk.device);
|
Destroy(vk.swapchain, vk.present_images, vk.device);
|
||||||
Destroy(&vk.draw_image, &vk.depth_image, vk.device, vk.vma);
|
Destroy(vk, &vk.draw_image);
|
||||||
|
Destroy(vk, &vk.depth_image);
|
||||||
|
|
||||||
CreateSwapchain(vk);
|
CreateSwapchain(vk);
|
||||||
CreateDrawImages(vk);
|
CreateDrawImages(vk);
|
||||||
@ -2851,16 +3020,16 @@ Destroy(VkSwapchainKHR swapchain, ImageView[] views, VkDevice device)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
Destroy(ImageView* view, VkDevice device, VmaAllocator vma)
|
Destroy(Vulkan* vk, ImageView* view)
|
||||||
{
|
{
|
||||||
if (view.view)
|
if (view.view)
|
||||||
{
|
{
|
||||||
vkDestroyImageView(device, view.view, null);
|
vkDestroyImageView(vk.device, view.view, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (view.image)
|
if (view.image)
|
||||||
{
|
{
|
||||||
vmaDestroyImage(vma, view.image, view.alloc);
|
vmaDestroyImage(vk.vma, view.image, view.alloc);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2891,13 +3060,6 @@ Destroy(VkDescriptorPool pool, VkDescriptorSetLayout[] layouts, VkPipelineLayout
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
Destroy(ImageView* draw, ImageView* depth, VkDevice device, VmaAllocator vma)
|
|
||||||
{
|
|
||||||
Destroy(draw, device, vma);
|
|
||||||
Destroy(depth, device, vma);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
DestroyFS(Vulkan* vk)
|
DestroyFS(Vulkan* vk)
|
||||||
{
|
{
|
||||||
|
|||||||
@ -35,6 +35,8 @@ alias Vec2 = Vector!(f32, 2);
|
|||||||
alias Vec3 = Vector!(f32, 3);
|
alias Vec3 = Vector!(f32, 3);
|
||||||
alias Vec4 = Vector!(f32, 4);
|
alias Vec4 = Vector!(f32, 4);
|
||||||
|
|
||||||
|
alias UVec2 = Vector!(u32, 2);
|
||||||
|
|
||||||
alias Mat2 = Matrix!(f32, 2);
|
alias Mat2 = Matrix!(f32, 2);
|
||||||
alias Mat3 = Matrix!(f32, 3);
|
alias Mat3 = Matrix!(f32, 3);
|
||||||
alias Mat4 = Matrix!(f32, 4);
|
alias Mat4 = Matrix!(f32, 4);
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user