basic model rendering completed
This commit is contained in:
parent
2dd274742d
commit
b4ba1f491b
BIN
assets/models/cube.m3d
Normal file
BIN
assets/models/cube.m3d
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
assets/shaders/pbr.frag.spv
Normal file
BIN
assets/shaders/pbr.frag.spv
Normal file
Binary file not shown.
BIN
assets/shaders/pbr.vert.spv
Normal file
BIN
assets/shaders/pbr.vert.spv
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -7,11 +7,6 @@ import r = renderer;
|
||||
import util;
|
||||
import core.simd;
|
||||
|
||||
struct Floats
|
||||
{
|
||||
f32 r = 0.0, g = 0.0, b = 0.0, a = 0.0;
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
p.Window window = p.CreateWindow("Video Game", 1920, 1080);
|
||||
|
||||
@ -6,6 +6,7 @@ import alloc;
|
||||
import vulkan;
|
||||
import vulkan : Destroy, Init, Draw, DrawIndexed, Bind, BindUIBuffers, BeginRender, SetUniform, PrepCompute, Dispatch, FinishFrame, BeginFrame;
|
||||
import assets;
|
||||
import std.math.traits : isNaN;
|
||||
import u = util;
|
||||
import p = platform;
|
||||
|
||||
@ -28,6 +29,8 @@ enum Format : VkFormat
|
||||
RG_F32 = VK_FORMAT_R32G32_SFLOAT,
|
||||
RGB_F32 = VK_FORMAT_R32G32B32_SFLOAT,
|
||||
RGBA_F32 = VK_FORMAT_R32G32B32A32_SFLOAT,
|
||||
RGBA_UINT = VK_FORMAT_B8G8R8A8_UINT,
|
||||
RGBA_UNORM = VK_FORMAT_R8G8B8A8_UNORM,
|
||||
}
|
||||
|
||||
alias FMT = Format;
|
||||
@ -74,6 +77,7 @@ struct Renderer
|
||||
u32[] ui_index_buf;
|
||||
u32 ui_count;
|
||||
|
||||
Pipeline pbr_pipeline;
|
||||
Pipeline triangle_pipeline;
|
||||
Pipeline compute_pipeline;
|
||||
Pipeline ui_pipeline;
|
||||
@ -173,6 +177,19 @@ Init(p.Window* window)
|
||||
],
|
||||
};
|
||||
|
||||
GfxPipelineInfo pbr_info = {
|
||||
vertex_shader: "shaders/pbr.vert",
|
||||
frag_shader: "shaders/pbr.frag",
|
||||
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 },
|
||||
],
|
||||
};
|
||||
|
||||
rd.pbr_pipeline = BuildGfxPipeline(&rd, &pbr_info);
|
||||
rd.triangle_pipeline = BuildGfxPipeline(&rd, &triangle_info);
|
||||
rd.ui_pipeline = BuildGfxPipeline(&rd, &ui_info);
|
||||
rd.compute_pipeline = BuildCompPipeline(&rd, "shaders/gradient.comp");
|
||||
@ -207,18 +224,144 @@ Cycle(Renderer* rd)
|
||||
|
||||
BindUIBuffers(rd);
|
||||
|
||||
DrawIndexed(rd, 6, rd.ui_count);
|
||||
DrawIndexed(rd, 6, rd.ui_count, 0);
|
||||
|
||||
Bind(rd, &rd.triangle_pipeline);
|
||||
|
||||
Draw(rd, 3, 1);
|
||||
|
||||
Bind(rd, &rd.pbr_pipeline);
|
||||
|
||||
DrawModel(rd, &rd.yoder);
|
||||
|
||||
success = FinishFrame(rd);
|
||||
}
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
pragma(inline): void
|
||||
DrawModel(Renderer* rd, Model* model)
|
||||
{
|
||||
BindBuffers(&rd.vk, &model.index_buffer, &model.vertex_buffer);
|
||||
|
||||
foreach(i, part; model.parts)
|
||||
{
|
||||
DrawIndexed(rd, part.length, 1, part.offset);
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
debug
|
||||
{
|
||||
assert(dst.x == src.x && dst.y == src.y && dst.z == src.z && dst.w == src.w, "Vertex copy failed");
|
||||
assert(!isNaN(dst.x) && !isNaN(dst.y) && !isNaN(dst.z) && !isNaN(dst.w), "Vertex contains NaN");
|
||||
}
|
||||
}
|
||||
|
||||
pragma(inline): bool
|
||||
BeginFrame(Renderer* rd)
|
||||
{
|
||||
return BeginFrame(&rd.vk);
|
||||
}
|
||||
|
||||
pragma(inline): bool
|
||||
FinishFrame(Renderer* rd)
|
||||
{
|
||||
return FinishFrame(&rd.vk);
|
||||
}
|
||||
|
||||
pragma(inline): void
|
||||
Dispatch(Renderer* rd)
|
||||
{
|
||||
Dispatch(&rd.vk);
|
||||
}
|
||||
|
||||
pragma(inline): void
|
||||
PrepCompute(Renderer* rd)
|
||||
{
|
||||
PrepCompute(&rd.vk);
|
||||
}
|
||||
|
||||
pragma(inline): void
|
||||
SetUniform(Renderer* rd, GlobalUniforms* uniforms)
|
||||
{
|
||||
SetUniform(&rd.vk, uniforms);
|
||||
}
|
||||
|
||||
pragma(inline): void
|
||||
BeginRender(Renderer* rd)
|
||||
{
|
||||
BeginRender(&rd.vk);
|
||||
}
|
||||
|
||||
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
|
||||
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): Pipeline
|
||||
BuildGfxPipeline(Renderer* rd, GfxPipelineInfo* info)
|
||||
{
|
||||
return CreateGraphicsPipeline(&rd.vk, info);
|
||||
}
|
||||
|
||||
pragma(inline): Pipeline
|
||||
BuildCompPipeline(Renderer* rd, string compute)
|
||||
{
|
||||
return CreateComputePipeline(&rd.vk, compute);
|
||||
}
|
||||
|
||||
Model
|
||||
LoadModel(Renderer* rd, string name)
|
||||
{
|
||||
@ -298,7 +441,7 @@ LoadModel(Renderer* rd, string name)
|
||||
{
|
||||
if (last == u64.max)
|
||||
{
|
||||
model.parts[index].mat = mat_lookup[m3d.face[i].materialid];
|
||||
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;
|
||||
}
|
||||
@ -369,111 +512,6 @@ LoadModel(Renderer* rd, string name)
|
||||
return model;
|
||||
}
|
||||
|
||||
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): bool
|
||||
BeginFrame(Renderer* rd)
|
||||
{
|
||||
return BeginFrame(&rd.vk);
|
||||
}
|
||||
|
||||
pragma(inline): bool
|
||||
FinishFrame(Renderer* rd)
|
||||
{
|
||||
return FinishFrame(&rd.vk);
|
||||
}
|
||||
|
||||
pragma(inline): void
|
||||
Dispatch(Renderer* rd)
|
||||
{
|
||||
Dispatch(&rd.vk);
|
||||
}
|
||||
|
||||
pragma(inline): void
|
||||
PrepCompute(Renderer* rd)
|
||||
{
|
||||
PrepCompute(&rd.vk);
|
||||
}
|
||||
|
||||
pragma(inline): void
|
||||
SetUniform(Renderer* rd, GlobalUniforms* uniforms)
|
||||
{
|
||||
SetUniform(&rd.vk, uniforms);
|
||||
}
|
||||
|
||||
pragma(inline): void
|
||||
BeginRender(Renderer* rd)
|
||||
{
|
||||
BeginRender(&rd.vk);
|
||||
}
|
||||
|
||||
pragma(inline): void
|
||||
BindUIBuffers(Renderer* rd)
|
||||
{
|
||||
BindUIBuffers(&rd.vk);
|
||||
}
|
||||
|
||||
pragma(inline): void
|
||||
DrawIndexed(Renderer* rd, u32 index_count, u32 instance_count)
|
||||
{
|
||||
DrawIndexed(&rd.vk, index_count, instance_count);
|
||||
}
|
||||
|
||||
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
|
||||
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): Pipeline
|
||||
BuildGfxPipeline(Renderer* rd, GfxPipelineInfo* info)
|
||||
{
|
||||
return CreateGraphicsPipeline(&rd.vk, info);
|
||||
}
|
||||
|
||||
pragma(inline): Pipeline
|
||||
BuildCompPipeline(Renderer* rd, string compute)
|
||||
{
|
||||
return CreateComputePipeline(&rd.vk, compute);
|
||||
}
|
||||
|
||||
void
|
||||
Destroy(Renderer* rd)
|
||||
{
|
||||
|
||||
@ -316,6 +316,15 @@ BindUIBuffers(Vulkan* vk)
|
||||
vkCmdBindVertexBuffers(vk.cmds[vk.frame_index], 0, 1, &vk.ui_vert_buf.buffer, &offset);
|
||||
}
|
||||
|
||||
void
|
||||
BindBuffers(Vulkan* vk, Buffer* index_buffer, Buffer* vertex_buffer)
|
||||
{
|
||||
VkDeviceSize offset = 0;
|
||||
|
||||
vkCmdBindIndexBuffer(vk.cmds[vk.frame_index], index_buffer.buffer, 0, VK_INDEX_TYPE_UINT32);
|
||||
vkCmdBindVertexBuffers(vk.cmds[vk.frame_index], 0, 1, &vertex_buffer.buffer, &offset);
|
||||
}
|
||||
|
||||
MappedBuffer!(T)
|
||||
CreateMappedBuffer(T)(Vulkan* vk, BufferType type, u64 count)
|
||||
{
|
||||
@ -541,9 +550,9 @@ Draw(Vulkan* vk, u32 index_count, u32 instance_count)
|
||||
}
|
||||
|
||||
void
|
||||
DrawIndexed(Vulkan* vk, u32 index_count, u32 instance_count)
|
||||
DrawIndexed(Vulkan* vk, u32 index_count, u32 instance_count, u32 index_offset)
|
||||
{
|
||||
vkCmdDrawIndexed(vk.cmds[vk.frame_index], index_count, instance_count, 0, 0, 0);
|
||||
vkCmdDrawIndexed(vk.cmds[vk.frame_index], index_count, instance_count, index_offset, 0, 0);
|
||||
}
|
||||
|
||||
bool
|
||||
|
||||
@ -11,16 +11,19 @@ enum AssetType : u32
|
||||
alias AT = AssetType;
|
||||
|
||||
static immutable string[] MODEL_FILES = [
|
||||
"models/cube.m3d",
|
||||
"models/test_char.m3d",
|
||||
"models/yoda.m3d",
|
||||
];
|
||||
|
||||
static immutable string[] MODEL_NAMES = [
|
||||
"models/cube",
|
||||
"models/test_char",
|
||||
"models/yoda",
|
||||
];
|
||||
|
||||
static immutable u64[] MODEL_HASHES = [
|
||||
16487010975852376380,
|
||||
13826959199295087925,
|
||||
4559395153940738542,
|
||||
];
|
||||
@ -28,25 +31,31 @@ static immutable u64[] MODEL_HASHES = [
|
||||
static immutable string[] SHADER_FILES = [
|
||||
"shaders/gui.frag.spv",
|
||||
"shaders/triangle.vert.spv",
|
||||
"shaders/pbr.frag.spv",
|
||||
"shaders/gui.vert.spv",
|
||||
"shaders/gradient.comp.spv",
|
||||
"shaders/triangle.frag.spv",
|
||||
"shaders/pbr.vert.spv",
|
||||
];
|
||||
|
||||
static immutable string[] SHADER_NAMES = [
|
||||
"shaders/gui.frag",
|
||||
"shaders/triangle.vert",
|
||||
"shaders/pbr.frag",
|
||||
"shaders/gui.vert",
|
||||
"shaders/gradient.comp",
|
||||
"shaders/triangle.frag",
|
||||
"shaders/pbr.vert",
|
||||
];
|
||||
|
||||
static immutable u64[] SHADER_HASHES = [
|
||||
15780387719315455808,
|
||||
8769314645675479020,
|
||||
2230071466542309169,
|
||||
14797956403837654625,
|
||||
16130483095684998267,
|
||||
6282520872716708711,
|
||||
8518761701216801634,
|
||||
];
|
||||
|
||||
static immutable string[] TEXTURE_FILES = [
|
||||
|
||||
@ -1,6 +1,5 @@
|
||||
#version 460
|
||||
|
||||
#extension GL_EXT_buffer_reference : require
|
||||
#extension GL_GOOGLE_include_directive : require
|
||||
|
||||
#include "structures.layout"
|
||||
|
||||
@ -1,6 +1,5 @@
|
||||
#version 460
|
||||
|
||||
#extension GL_EXT_buffer_reference : require
|
||||
#extension GL_GOOGLE_include_directive : require
|
||||
#extension GL_EXT_nonuniform_qualifier : require
|
||||
|
||||
|
||||
@ -1,6 +1,5 @@
|
||||
#version 460
|
||||
|
||||
#extension GL_EXT_buffer_reference : require
|
||||
#extension GL_GOOGLE_include_directive : require
|
||||
#extension GL_EXT_nonuniform_qualifier : require
|
||||
|
||||
|
||||
16
src/shaders/pbr.frag.glsl
Normal file
16
src/shaders/pbr.frag.glsl
Normal file
@ -0,0 +1,16 @@
|
||||
#version 460
|
||||
|
||||
#extension GL_GOOGLE_include_directive : require
|
||||
#extension GL_EXT_nonuniform_qualifier : require
|
||||
|
||||
#include "structures.layout"
|
||||
|
||||
layout (location = 0) in vec4 in_col;
|
||||
layout (location = 1) in vec2 in_uv;
|
||||
|
||||
layout (location = 0) out vec4 FragColor;
|
||||
|
||||
void main()
|
||||
{
|
||||
FragColor = in_col;
|
||||
}
|
||||
20
src/shaders/pbr.vert.glsl
Normal file
20
src/shaders/pbr.vert.glsl
Normal file
@ -0,0 +1,20 @@
|
||||
#version 460
|
||||
|
||||
#extension GL_GOOGLE_include_directive : require
|
||||
#extension GL_EXT_nonuniform_qualifier : require
|
||||
|
||||
#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) out vec4 out_col;
|
||||
layout (location = 1) out vec2 out_uv;
|
||||
|
||||
void main()
|
||||
{
|
||||
gl_Position = in_pos;
|
||||
out_col = in_col;
|
||||
}
|
||||
@ -1,6 +1,5 @@
|
||||
#version 460
|
||||
|
||||
#extension GL_EXT_buffer_reference : require
|
||||
#extension GL_GOOGLE_include_directive : require
|
||||
#extension GL_EXT_nonuniform_qualifier : require
|
||||
|
||||
|
||||
@ -1,6 +1,5 @@
|
||||
#version 460
|
||||
|
||||
#extension GL_EXT_buffer_reference : require
|
||||
#extension GL_GOOGLE_include_directive : require
|
||||
#extension GL_EXT_nonuniform_qualifier : require
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user