diff --git a/assets/shaders/pbr.vert.spv b/assets/shaders/pbr.vert.spv index 3330c72..5f2ca88 100644 Binary files a/assets/shaders/pbr.vert.spv and b/assets/shaders/pbr.vert.spv differ diff --git a/src/gears/game.d b/src/gears/game.d index 50e8994..f019bd4 100644 --- a/src/gears/game.d +++ b/src/gears/game.d @@ -68,9 +68,10 @@ InitGame(PlatformWindow* window) input_rate_stride: Vertex.sizeof, vertex_attributes: [ { binding: 0, location: 0, format: FMT.RGBA_F32, offset: 0 }, - { binding: 0, location: 1, format: FMT.RGBA_F32, offset: Vertex.n.offsetof }, - { binding: 0, location: 2, format: FMT.RG_F32, offset: Vertex.uv.offsetof }, - { binding: 0, location: 3, format: FMT.RGBA_UNORM, offset: Vertex.col.offsetof }, + { binding: 0, location: 1, format: FMT.RGBA_F32, offset: Vertex.tangent.offsetof }, + { binding: 0, location: 2, format: FMT.RGB_F32, offset: Vertex.pos.offsetof }, + { binding: 0, location: 3, format: FMT.RGB_F32, offset: Vertex.normal.offsetof }, + { binding: 0, location: 4, format: FMT.RG_F32, offset: Vertex.uv.offsetof }, ], }; diff --git a/src/gears/main.d b/src/gears/main.d index d434556..c786d77 100644 --- a/src/gears/main.d +++ b/src/gears/main.d @@ -7,6 +7,7 @@ import game; import util; import core.simd; import math; +import core.stdc.string : memcpy; // TODO: // 1. Remove bindless (informed to be perf death) @@ -24,7 +25,12 @@ void main(string[] argv) while (true) { HandleEvents(&window); - if (window.close) break; + if (window.close) + { + Logf("quitting"); + break; + } + Cycle(&g); } diff --git a/src/gears/renderer.d b/src/gears/renderer.d index a8a30a7..59e3230 100644 --- a/src/gears/renderer.d +++ b/src/gears/renderer.d @@ -118,20 +118,6 @@ struct Renderer PushConst push_const; } -extern(C) struct Material -{ - Vec4 ambient; - Vec4 albedo; - Vec4 specular; - u32 albedo_texture; - u32 ambient_texture; - u32 specular_texture; - b32 albedo_has_texture; - b32 ambient_has_texture; - b32 specular_has_texture; - f32 shininess = 0.0; -} - struct Extent { u32 x; @@ -148,10 +134,11 @@ struct UIVertex struct Vertex { - Vec4 pos; - Vec4 n; + Vec4 color; + Vec4 tangent; + Vec3 pos; + Vec3 normal; Vec2 uv; - u32 col; } struct MeshPart @@ -214,18 +201,6 @@ GetExtent(Renderer* rd) return Extent(rd.vk.swapchain_extent.width, rd.vk.swapchain_extent.height); } -pragma(inline): void -CopyVertex(Vec4* dst, m3dv_t* src) -{ - asm - { - mov R8, src; - mov R9, dst; - movups XMM0, src.x.offsetof[R8]; - movups dst.x.offsetof[R9], XMM0; - } -} - pragma(inline): void BeginFrame(Renderer* rd) { @@ -465,34 +440,37 @@ LoadModel(Renderer* rd, string name) foreach(i; 0 .. m3d.numface) { u32 vi = (i * 3); + u32 i0 = vi+0; + u32 i1 = vi+1; + u32 i2 = vi+2; - CopyVertex(&vertices[vi+0].pos, &m3d.vertex[m3d.face[i].vertex[0]]); - CopyVertex(&vertices[vi+1].pos, &m3d.vertex[m3d.face[i].vertex[1]]); - CopyVertex(&vertices[vi+2].pos, &m3d.vertex[m3d.face[i].vertex[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[vi+0].n, &m3d.vertex[m3d.face[i].vertex[0]]); - CopyVertex(&vertices[vi+1].n, &m3d.vertex[m3d.face[i].vertex[1]]); - CopyVertex(&vertices[vi+2].n, &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]]); - vertices[vi+0].col = m3d.vertex[m3d.face[i].vertex[0]].color; - vertices[vi+1].col = m3d.vertex[m3d.face[i].vertex[1]].color; - vertices[vi+2].col = m3d.vertex[m3d.face[i].vertex[2]].color; + 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[vi+0].uv.x = m3d.tmap[m3d.face[i].texcoord[0]].u; - vertices[vi+0].uv.y = m3d.tmap[m3d.face[i].texcoord[0]].v; + 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[vi+1].uv.x = m3d.tmap[m3d.face[i].texcoord[1]].u; - vertices[vi+1].uv.y = m3d.tmap[m3d.face[i].texcoord[1]].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[vi+2].uv.x = m3d.tmap[m3d.face[i].texcoord[2]].u; - vertices[vi+2].uv.y = m3d.tmap[m3d.face[i].texcoord[2]].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[vi+0] = vi+0; - indices[vi+1] = vi+1; - indices[vi+2] = vi+2; + indices[i0] = i0; + indices[i1] = i1; + indices[i2] = i2; } assert(vertices.length > 0 && indices.length > 0, "Error loading model"); @@ -511,6 +489,14 @@ LoadModel(Renderer* rd, string name) return model; } +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) { diff --git a/src/gears/vulkan.d b/src/gears/vulkan.d index b3a1566..b935e6c 100644 --- a/src/gears/vulkan.d +++ b/src/gears/vulkan.d @@ -283,6 +283,11 @@ Init(PlatformWindow* window, u64 permanent_mem, u64 frame_mem) value: vk, }; + if (!success) + { + Logf("error initializing vulkan"); + } + return result; } diff --git a/src/packer/packer.d b/src/packer/packer.d index 0408b7b..b2d893f 100644 --- a/src/packer/packer.d +++ b/src/packer/packer.d @@ -172,7 +172,7 @@ TestFile() } } -u32 +static u32 MagicValue(string str) { assert(str.length == 4, "Magic value must 4 characters"); @@ -192,3 +192,60 @@ InitHeader(u64 asset_count) return header; } +static ModelHeader +InitModelHeader() +{ + ModelHeader header = { + magic: MagicValue("stgm"), + model_version: MODEL_VERSION, + }; + + return header; +} + +ModelData +ConvertModel(u8[] data) +{ + assert(data.size > 4, "Model data too small for a magic number"); + + u32 magic = *cast(u32*)(data.ptr); + + ModelData model; + switch (magic) + { + case MagicValue("3DMO"): + { + model = ConvertM3D(data); + } break; + case MagicValue("glTF"): + { + model = ConvertGLTF(data); + } break; + default: + { + assert(false, "Unsupported model type"); + } break; + } + + return model; +} + +ModelData +ConvertGLTF(u8[] data) +{ + ModelData model; + + assert(false, "Not yet supported"); + + return model; +} + +ModelData +ConvertM3D(u8[] data) +{ + ModelData model; + + return model; +} + + diff --git a/src/shaders/pbr.vert.glsl b/src/shaders/pbr.vert.glsl index 83b793f..1e37a61 100644 --- a/src/shaders/pbr.vert.glsl +++ b/src/shaders/pbr.vert.glsl @@ -5,10 +5,11 @@ #include "structures.layout" -layout (location = 0) in vec4 in_pos; -layout (location = 1) in vec4 in_normal; -layout (location = 2) in vec2 in_uv; -layout (location = 3) in vec4 in_col; +layout (location = 0) in vec4 in_col; +layout (location = 1) in vec4 in_tangent; +layout (location = 2) in vec3 in_pos; +layout (location = 3) in vec3 in_normal; +layout (location = 4) in vec2 in_uv; layout (location = 0) out vec4 out_col; layout (location = 1) out vec2 out_uv; @@ -22,7 +23,7 @@ mat4 y_matrix = mat4( void main() { - gl_Position = G.projection_matrix * G.view_matrix * PC.model_matrix * vec4(in_pos.rgb, 1.0); + gl_Position = G.projection_matrix * G.view_matrix * PC.model_matrix * vec4(in_pos, 1.0); vec4 col = Materials[nonuniformEXT(PC.mat_id)].diffuse; diff --git a/src/shared/aliases.d b/src/shared/aliases.d index 13d3428..f3e7345 100644 --- a/src/shared/aliases.d +++ b/src/shared/aliases.d @@ -29,6 +29,8 @@ alias b32 = uint; alias intptr = intptr_t; alias uintptr = uintptr_t; +alias usize = size_t; + alias Vec2 = Vector!(f32, 2); alias Vec3 = Vector!(f32, 3); alias Vec4 = Vector!(f32, 4); diff --git a/src/shared/assets.d b/src/shared/assets.d index 5ae66b3..574aab6 100644 --- a/src/shared/assets.d +++ b/src/shared/assets.d @@ -14,6 +14,7 @@ AssetInfo[] Asset_Info; u8[][] Asset_Data; const u32 FILE_VERSION = 2; +const u32 MODEL_VERSION = 1; enum AssetType : u32 { @@ -33,6 +34,64 @@ struct FileHeader u64 asset_info_offset; } +struct ModelHeader +{ + u32 magic; + u32 model_version; + u64 vertex_count; + u64 vertex_offset; + u64 index_count; + u64 index_offset; + u64 material_count; + u64 material_offset; + u64 texture_count; + u64 texture_offset; +} + +struct Vertex +{ + Vec4 color; + Vec4 tangent; + Vec3 pos; + Vec3 normal; + Vec2 uv; +} + +struct ModelData +{ + Vertex[] vertices; + u32[] indices; + Material[] materials; + TextureInfo[] textures; +} + +struct Material +{ + Vec4 ambient; + Vec4 albedo; + Vec4 specular; + u32 albedo_texture; + u32 ambient_texture; + u32 specular_texture; + b32 albedo_has_texture; + b32 ambient_has_texture; + b32 specular_has_texture; + f32 shininess = 0.0; +} + +struct TextureInfo +{ + string name; + u32 id; +} + +struct TextureHeader +{ + u64 str_length; + u64 str_offset; + u32 texture_id; +} + struct ModelMeta { u64 index_count; diff --git a/src/shared/util.d b/src/shared/util.d index 4db439f..ecbb50a 100644 --- a/src/shared/util.d +++ b/src/shared/util.d @@ -558,3 +558,69 @@ GenerateLoop(string format_string, int N)() nothrow pure @safe return result; } +void +MemCpy(void* dst_p, void* src_p, u64 length) +{ + u8* dst = cast(u8*)dst_p; + u8* src = cast(u8*)src_p; + + u64 remaining = length; + if (remaining >= 64) + { + for(u64 i = 0; i < length; i += 64) + { + asm + { + mov R8, src; + mov R9, dst; + + add R8, i; + movdqu XMM0, [R8+00]; + movdqu XMM1, [R8+16]; + movdqu XMM2, [R8+32]; + movdqu XMM3, [R8+48]; + + add R9, i; + movdqu [R9+00], XMM0; + movups [R9+16], XMM1; + movups [R9+32], XMM2; + movups [R9+48], XMM3; + + sub remaining, 64; + } + } + } + + if (remaining >= 32) + { + for(u64 i = remaining; i < length; i += 32) + { + asm + { + mov R8, src; + mov R9, dst; + + add R8, i; + movdqu XMM0, [R8+00]; + movdqu XMM1, [R8+16]; + + add R9, i; + movdqu [R9+00], XMM0; + movdqu [R9+16], XMM1; + + sub remaining, 32; + } + } + } + + for(u64 i = remaining; i < length; i += 1) + { + dst[i] = src[i]; + } +} + +void +MemSet(void* dst, char ch, usize length) +{ + +}