work on basic rendering
This commit is contained in:
parent
77ce53d4f1
commit
119f5f069c
Binary file not shown.
Binary file not shown.
@ -1 +1 @@
|
|||||||
Subproject commit 1b4d9979765ca8a1c1f45ddf8420edc93d1b79dc
|
Subproject commit d46741a48033b5136fa189c1b80a574986e68f64
|
||||||
@ -8,17 +8,20 @@ const u32 UNI_MAX = 50;
|
|||||||
struct GameState
|
struct GameState
|
||||||
{
|
{
|
||||||
RenderState rds;
|
RenderState rds;
|
||||||
|
u64 frame;
|
||||||
|
u64 frame_idx;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct RenderState
|
struct RenderState
|
||||||
{
|
{
|
||||||
Renderer rd;
|
Renderer rd;
|
||||||
Arena[2] frame_arenas;
|
Arena[2] frame_arenas;
|
||||||
|
Arena perm_arena;
|
||||||
|
|
||||||
PushConst pc;
|
PushConst pc;
|
||||||
ShaderGlobals globals;
|
ShaderGlobals globals;
|
||||||
|
|
||||||
Pipeline pipeline_pbr;
|
Pipeline[PID.Max] pipelines;
|
||||||
DescSetLayout desc_layout_globals;
|
DescSetLayout desc_layout_globals;
|
||||||
DescSetLayout desc_layout_resources;
|
DescSetLayout desc_layout_resources;
|
||||||
DescSet[2] desc_set_globals;
|
DescSet[2] desc_set_globals;
|
||||||
@ -38,6 +41,68 @@ struct ShaderGlobals
|
|||||||
f32 alpha = 0.0;
|
f32 alpha = 0.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct Model
|
||||||
|
{
|
||||||
|
Buffer v_buf;
|
||||||
|
Buffer i_buf;
|
||||||
|
Buffer s_buf;
|
||||||
|
ModelState state;
|
||||||
|
ModelRenderInfo info;
|
||||||
|
Vertex[] v;
|
||||||
|
u32[] idx;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct ModelRenderInfo
|
||||||
|
{
|
||||||
|
PushConst pc;
|
||||||
|
PipelineID pid;
|
||||||
|
|
||||||
|
alias pc this;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct ModelState
|
||||||
|
{
|
||||||
|
Mat4 matrix;
|
||||||
|
}
|
||||||
|
|
||||||
|
enum PBRMod : u32
|
||||||
|
{
|
||||||
|
AlbedoValue = 0x0001,
|
||||||
|
AmbientValue = 0x0002,
|
||||||
|
SpecularValue = 0x0004,
|
||||||
|
AlphaValue = 0x0008,
|
||||||
|
AlbedoTexture = 0x0010,
|
||||||
|
AmbientTexture = 0x0020,
|
||||||
|
SpecularTexture = 0x0040,
|
||||||
|
AlphaTexture = 0x0080,
|
||||||
|
}
|
||||||
|
|
||||||
|
enum PipelineID : u32
|
||||||
|
{
|
||||||
|
None,
|
||||||
|
PBRVVVV,
|
||||||
|
PBRTVVV,
|
||||||
|
PBRVTVV,
|
||||||
|
PBRVVTV,
|
||||||
|
PBRVVVT,
|
||||||
|
PBRTTVV,
|
||||||
|
PBRTVTV,
|
||||||
|
PBRTVVT,
|
||||||
|
PBRVTTV,
|
||||||
|
PBRVTVT,
|
||||||
|
PBRVVTT,
|
||||||
|
PBRVTTT,
|
||||||
|
PBRTVTT,
|
||||||
|
PBRTTVT,
|
||||||
|
PBRTTTV,
|
||||||
|
PBRTTTT,
|
||||||
|
Max,
|
||||||
|
}
|
||||||
|
|
||||||
|
alias PID = PipelineID;
|
||||||
|
|
||||||
|
const PID[] PBR_PIPELINES = [PID.PBRVVVV, PID.PBRTVVV, PID.PBRVTVV, PID.PBRVVTV, PID.PBRVVVT, PID.PBRTTVV, PID.PBRTVTV, PID.PBRTVVT, PID.PBRVTTV, PID.PBRVTVT, PID.PBRVVTT, PID.PBRTTTV, PID.PBRTTVT, PID.PBRTVTT, PID.PBRVTTT, PID.PBRTTTT];
|
||||||
|
|
||||||
struct PushConst
|
struct PushConst
|
||||||
{
|
{
|
||||||
union
|
union
|
||||||
@ -72,6 +137,8 @@ struct Vertex
|
|||||||
Vec2 uv;
|
Vec2 uv;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Model g_box;
|
||||||
|
|
||||||
GameState
|
GameState
|
||||||
InitGame(PlatformWindow* window)
|
InitGame(PlatformWindow* window)
|
||||||
{
|
{
|
||||||
@ -81,6 +148,34 @@ InitGame(PlatformWindow* window)
|
|||||||
return g;
|
return g;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
RunCycle(GameState* g)
|
||||||
|
{
|
||||||
|
g.frame_idx = g.frame % 2;
|
||||||
|
|
||||||
|
Reset(&g.rds.frame_arenas[g.frame_idx]);
|
||||||
|
|
||||||
|
Renderer* rd = &g.rds.rd;
|
||||||
|
|
||||||
|
BeginFrame(rd);
|
||||||
|
|
||||||
|
BeginRendering(rd);
|
||||||
|
|
||||||
|
PushConstants(rd, g.rds.pipelines[g_box.info.pid], &g_box.info.pc);
|
||||||
|
|
||||||
|
Bind(rd, g.rds.pipelines[g_box.info.pid], [g.rds.desc_set_globals[g.frame_idx], g.rds.desc_set_resources[g.frame_idx]]);
|
||||||
|
|
||||||
|
BindBuffers(rd, &g_box.i_buf, &g_box.v_buf);
|
||||||
|
|
||||||
|
DrawIndexed(rd, cast(u32)g_box.idx.length, 1, 0);
|
||||||
|
|
||||||
|
FinishRendering(rd);
|
||||||
|
|
||||||
|
SubmitAndPresent(rd);
|
||||||
|
|
||||||
|
g.frame += 1;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
Init(RenderState* rds, PlatformWindow* window)
|
Init(RenderState* rds, PlatformWindow* window)
|
||||||
{
|
{
|
||||||
@ -113,6 +208,7 @@ Init(RenderState* rds, PlatformWindow* window)
|
|||||||
];
|
];
|
||||||
|
|
||||||
rds.rd = InitRenderer(handles, MB(24), MB(32));
|
rds.rd = InitRenderer(handles, MB(24), MB(32));
|
||||||
|
rds.perm_arena = CreateArena(MB(4));
|
||||||
rds.frame_arenas = [
|
rds.frame_arenas = [
|
||||||
CreateArena(MB(4)),
|
CreateArena(MB(4)),
|
||||||
CreateArena(MB(4)),
|
CreateArena(MB(4)),
|
||||||
@ -129,6 +225,19 @@ Init(RenderState* rds, PlatformWindow* window)
|
|||||||
rds.desc_set_resources[i] = AllocDescSet(&rds.rd, rds.desc_layout_resources);
|
rds.desc_set_resources[i] = AllocDescSet(&rds.rd, rds.desc_layout_resources);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
u32[4] spec_data;
|
||||||
|
|
||||||
|
Specialization spec = {
|
||||||
|
data: spec_data.ptr,
|
||||||
|
size: u32.sizeof * spec_data.length,
|
||||||
|
entries: [
|
||||||
|
{ constantID: 0, size: u32.sizeof, offset: u32.sizeof*0 },
|
||||||
|
{ constantID: 1, size: u32.sizeof, offset: u32.sizeof*1 },
|
||||||
|
{ constantID: 2, size: u32.sizeof, offset: u32.sizeof*2 },
|
||||||
|
{ constantID: 3, size: u32.sizeof, offset: u32.sizeof*3 },
|
||||||
|
],
|
||||||
|
};
|
||||||
|
|
||||||
GfxPipelineInfo pbr_info = {
|
GfxPipelineInfo pbr_info = {
|
||||||
vertex_shader: LoadAssetData(&rds.frame_arenas[0], "shaders/pbr.vert.spv"),
|
vertex_shader: LoadAssetData(&rds.frame_arenas[0], "shaders/pbr.vert.spv"),
|
||||||
frag_shader: LoadAssetData(&rds.frame_arenas[0], "shaders/pbr.frag.spv"),
|
frag_shader: LoadAssetData(&rds.frame_arenas[0], "shaders/pbr.frag.spv"),
|
||||||
@ -136,10 +245,21 @@ Init(RenderState* rds, PlatformWindow* window)
|
|||||||
input_rate_stride: Vertex.sizeof,
|
input_rate_stride: Vertex.sizeof,
|
||||||
layout: rds.pipeline_layout_pbr,
|
layout: rds.pipeline_layout_pbr,
|
||||||
vertex_attributes: attributes,
|
vertex_attributes: attributes,
|
||||||
|
vert_spec: spec,
|
||||||
|
frag_spec: spec,
|
||||||
};
|
};
|
||||||
|
|
||||||
bool result = CreateGraphicsPipeline(&rds.rd, &rds.pipeline_pbr, &pbr_info);
|
foreach(pid; PBR_PIPELINES)
|
||||||
|
{
|
||||||
|
u32 mod = PIDToPBR(pid);
|
||||||
|
spec_data[0] = mod & PBRMod.AlbedoTexture;
|
||||||
|
spec_data[1] = mod & PBRMod.AmbientTexture;
|
||||||
|
spec_data[2] = mod & PBRMod.SpecularTexture;
|
||||||
|
spec_data[3] = mod & PBRMod.AlphaTexture;
|
||||||
|
|
||||||
|
bool result = CreateGraphicsPipeline(&rds.rd, &rds.pipelines[pid], &pbr_info);
|
||||||
assert(result);
|
assert(result);
|
||||||
|
}
|
||||||
|
|
||||||
const u64 tex_size = 32*32*4;
|
const u64 tex_size = 32*32*4;
|
||||||
u8[tex_size] placeholder_tex;
|
u8[tex_size] placeholder_tex;
|
||||||
@ -160,4 +280,140 @@ Init(RenderState* rds, PlatformWindow* window)
|
|||||||
CreateImageView(&rds.rd, &rds.placeholder_tex, 32, 32, 4, placeholder_tex);
|
CreateImageView(&rds.rd, &rds.placeholder_tex, 32, 32, 4, placeholder_tex);
|
||||||
|
|
||||||
CreateBuffer(&rds.rd, &rds.globals_buffer, BT.Uniform, ShaderGlobals.sizeof, false);
|
CreateBuffer(&rds.rd, &rds.globals_buffer, BT.Uniform, ShaderGlobals.sizeof, false);
|
||||||
|
bool transfer = Transfer(&rds.rd, &rds.globals_buffer, &rds.globals);
|
||||||
|
|
||||||
|
assert(transfer);
|
||||||
|
|
||||||
|
g_box = MakeBox(rds, 6.0, 6.0, Vec4(0.3, 0.4, 0.8, 1.0));
|
||||||
|
|
||||||
|
CreateBuffer(&rds.rd, &g_box.v_buf, BT.Vertex, g_box.v.length * Vertex.sizeof, false);
|
||||||
|
CreateBuffer(&rds.rd, &g_box.i_buf, BT.Index, g_box.idx.length * u32.sizeof, false);
|
||||||
|
CreateBuffer(&rds.rd, &g_box.s_buf, BT.Uniform, ModelState.sizeof, false);
|
||||||
|
|
||||||
|
transfer = Transfer(&rds.rd, &g_box.v_buf, g_box.v);
|
||||||
|
transfer &= Transfer(&rds.rd, &g_box.i_buf, g_box.idx);
|
||||||
|
transfer &= Transfer(&rds.rd, &g_box.s_buf, &g_box.state);
|
||||||
|
|
||||||
|
assert(transfer);
|
||||||
|
|
||||||
|
Write(&rds.rd, rds.desc_set_globals[0], &rds.globals_buffer, 0, DT.Uniform);
|
||||||
|
Write(&rds.rd, rds.desc_set_globals[1], &rds.globals_buffer, 0, DT.Uniform);
|
||||||
|
|
||||||
|
Write(&rds.rd, rds.desc_set_resources[0], &g_box.s_buf, 2, 0, DT.Uniform);
|
||||||
|
Write(&rds.rd, rds.desc_set_resources[1], &g_box.s_buf, 2, 0, DT.Uniform);
|
||||||
|
}
|
||||||
|
|
||||||
|
PipelineID
|
||||||
|
PBRToPID(u32 mod)
|
||||||
|
{
|
||||||
|
switch(mod)
|
||||||
|
{
|
||||||
|
case GetPBRMod(false, false, false, false): return PID.PBRVVVV;
|
||||||
|
case GetPBRMod(true , false, false, false): return PID.PBRTVVV;
|
||||||
|
case GetPBRMod(false, true , false, false): return PID.PBRVTVV;
|
||||||
|
case GetPBRMod(false, false, true , false): return PID.PBRVVTV;
|
||||||
|
case GetPBRMod(false, false, false, true ): return PID.PBRVVVT;
|
||||||
|
case GetPBRMod(true , true , false, false): return PID.PBRTTVV;
|
||||||
|
case GetPBRMod(true , false, true , false): return PID.PBRTVTV;
|
||||||
|
case GetPBRMod(true , false, false, true ): return PID.PBRTVVT;
|
||||||
|
case GetPBRMod(false, true , true , false): return PID.PBRVTTV;
|
||||||
|
case GetPBRMod(false, true , false, true ): return PID.PBRVTVT;
|
||||||
|
case GetPBRMod(false, false, true , true ): return PID.PBRVVTT;
|
||||||
|
case GetPBRMod(false, true , true , true ): return PID.PBRVTTT;
|
||||||
|
case GetPBRMod(true , false, true , true ): return PID.PBRTVTT;
|
||||||
|
case GetPBRMod(true , true , false, true ): return PID.PBRTTVT;
|
||||||
|
case GetPBRMod(true , true , true , false): return PID.PBRTTTV;
|
||||||
|
case GetPBRMod(true , true , true , true ): return PID.PBRTTTT;
|
||||||
|
default: return PID.None;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
u32
|
||||||
|
PIDToPBR(PipelineID pid)
|
||||||
|
{
|
||||||
|
switch(pid) with(PID)
|
||||||
|
{
|
||||||
|
case PBRVVVV: return GetPBRMod(false, false, false, false);
|
||||||
|
case PBRTVVV: return GetPBRMod(true , false, false, false);
|
||||||
|
case PBRVTVV: return GetPBRMod(false, true , false, false);
|
||||||
|
case PBRVVTV: return GetPBRMod(false, false, true , false);
|
||||||
|
case PBRVVVT: return GetPBRMod(false, false, false, true );
|
||||||
|
case PBRTTVV: return GetPBRMod(true , true , false, false);
|
||||||
|
case PBRTVTV: return GetPBRMod(true , false, true , false);
|
||||||
|
case PBRTVVT: return GetPBRMod(true , false, false, true );
|
||||||
|
case PBRVTTV: return GetPBRMod(false, true , true , false);
|
||||||
|
case PBRVTVT: return GetPBRMod(false, true , false, true );
|
||||||
|
case PBRVVTT: return GetPBRMod(false, false, true , true );
|
||||||
|
case PBRTTTV: return GetPBRMod(true , true , true , false);
|
||||||
|
case PBRTTVT: return GetPBRMod(true , true , false, true );
|
||||||
|
case PBRTVTT: return GetPBRMod(true , false, true , true );
|
||||||
|
case PBRVTTT: return GetPBRMod(false, true , true , true );
|
||||||
|
case PBRTTTT: return GetPBRMod(true , true , true , true );
|
||||||
|
default: return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static u32
|
||||||
|
GetPBRMod(bool albedo = false, bool ambient = false, bool specular = false, bool alpha = false)
|
||||||
|
{
|
||||||
|
with(PBRMod)
|
||||||
|
{
|
||||||
|
return
|
||||||
|
(albedo ? AlbedoTexture : AlbedoValue) |
|
||||||
|
(ambient ? AmbientTexture : AmbientValue) |
|
||||||
|
(specular ? SpecularTexture : SpecularValue) |
|
||||||
|
(alpha ? AlphaTexture : AlphaValue);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Model
|
||||||
|
MakeBox(RenderState* rds, f32 width, f32 height, Vec4 col)
|
||||||
|
{
|
||||||
|
Model box = {
|
||||||
|
v: Alloc!(Vertex)(&rds.perm_arena, 8),
|
||||||
|
idx: Alloc!(u32)(&rds.perm_arena, 36),
|
||||||
|
info: {
|
||||||
|
pid: PID.PBRVVVV,
|
||||||
|
},
|
||||||
|
state: {
|
||||||
|
matrix: Mat4Identity(),
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
const Vec3[8] positions = [
|
||||||
|
Vec3(-1.0, 0.0, -1.0), Vec3(+1.0, 0.0, -1.0), Vec3(+1.0, 1.0, -1.0), Vec3(-1.0, 1.0, -1.0),
|
||||||
|
Vec3(-1.0, 0.0, +1.0), Vec3(+1.0, 0.0, +1.0), Vec3(+1.0, 1.0, +1.0), Vec3(-1.0, 1.0, +1.0),
|
||||||
|
];
|
||||||
|
|
||||||
|
const u32[36] indices = [
|
||||||
|
0, 1, 3, 3, 1, 2,
|
||||||
|
1, 5, 2, 2, 5, 6,
|
||||||
|
5, 4, 6, 6, 4, 7,
|
||||||
|
4, 0, 7, 7, 0, 3,
|
||||||
|
3, 2, 7, 7, 2, 6,
|
||||||
|
4, 5, 0, 0, 5, 1,
|
||||||
|
];
|
||||||
|
|
||||||
|
f32 half_width = width/2.0;
|
||||||
|
|
||||||
|
Vec3 pos = Vec3(half_width, height, half_width);
|
||||||
|
for(u64 i = 0; i < positions.length; i += 1)
|
||||||
|
{
|
||||||
|
box.v[i].pos = pos * positions[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
box.idx[] = indices[];
|
||||||
|
|
||||||
|
return box;
|
||||||
|
}
|
||||||
|
|
||||||
|
unittest
|
||||||
|
{
|
||||||
|
with(PBRMod) with(PID)
|
||||||
|
{
|
||||||
|
foreach(pid; PBR_PIPELINES)
|
||||||
|
{
|
||||||
|
assert(PBRToPID(PIDToPBR(pid)) == pid);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -10,5 +10,16 @@ void main(string[] argv)
|
|||||||
PlatformWindow window = CreateWindow("Video Game", 1920, 1080);
|
PlatformWindow window = CreateWindow("Video Game", 1920, 1080);
|
||||||
|
|
||||||
GameState g = InitGame(&window);
|
GameState g = InitGame(&window);
|
||||||
|
|
||||||
|
for(;;)
|
||||||
|
{
|
||||||
|
Inputs* inputs = GetEvents(&window);
|
||||||
|
if(window.close)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
RunCycle(&g);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -5,12 +5,14 @@
|
|||||||
#include "structures.layout"
|
#include "structures.layout"
|
||||||
|
|
||||||
layout (location = 0) in struct FragDataIn {
|
layout (location = 0) in struct FragDataIn {
|
||||||
|
vec4 col;
|
||||||
vec3 normal;
|
vec3 normal;
|
||||||
vec2 uv;
|
vec2 uv;
|
||||||
} FragData;
|
} FragData;
|
||||||
|
|
||||||
layout (location = 0, index = 0) out vec4 FragColor;
|
layout (location = 0, index = 0) out vec4 FragColor;
|
||||||
|
|
||||||
|
/*
|
||||||
vec4 CalculateDirectionalLight(vec4 diff_col, vec4 diff_samp, vec4 light_col, vec3 dir, vec3 normal)
|
vec4 CalculateDirectionalLight(vec4 diff_col, vec4 diff_samp, vec4 light_col, vec3 dir, vec3 normal)
|
||||||
{
|
{
|
||||||
float diffuse_factor = max(dot(normal, -dir), 0.0);
|
float diffuse_factor = max(dot(normal, -dir), 0.0);
|
||||||
@ -36,9 +38,13 @@ vec4 UnPreMultLinearToSRGB(vec4 col)
|
|||||||
col.b = UnPreMultLinearToSRGB(col.x);
|
col.b = UnPreMultLinearToSRGB(col.x);
|
||||||
return col;
|
return col;
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
|
FragColor = FragData.col;
|
||||||
|
|
||||||
|
/*
|
||||||
ivec2 coord = ivec2(gl_FragCoord.xy);
|
ivec2 coord = ivec2(gl_FragCoord.xy);
|
||||||
int store_mask = 0;
|
int store_mask = 0;
|
||||||
int view_size = int(G.res.x) * int(G.res.y);
|
int view_size = int(G.res.x) * int(G.res.y);
|
||||||
@ -75,4 +81,5 @@ void main()
|
|||||||
{
|
{
|
||||||
FragColor = vec4(0.0); //vec4(out_col.rgb * out_col.a, out_col.a); // Change to vec4(0.0) to disable tail blending
|
FragColor = vec4(0.0); //vec4(out_col.rgb * out_col.a, out_col.a); // Change to vec4(0.0) to disable tail blending
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|||||||
@ -34,6 +34,7 @@ layout (location = 3) in vec3 in_normal;
|
|||||||
layout (location = 4) in vec2 in_uv;
|
layout (location = 4) in vec2 in_uv;
|
||||||
|
|
||||||
layout (location = 0) out struct FragDataOut {
|
layout (location = 0) out struct FragDataOut {
|
||||||
|
vec4 col;
|
||||||
vec3 normal;
|
vec3 normal;
|
||||||
vec2 uv;
|
vec2 uv;
|
||||||
} FragData;
|
} FragData;
|
||||||
@ -51,4 +52,5 @@ void main()
|
|||||||
|
|
||||||
FragData.uv = in_uv;
|
FragData.uv = in_uv;
|
||||||
FragData.normal = mat3(ModelMatrix) * in_normal;
|
FragData.normal = mat3(ModelMatrix) * in_normal;
|
||||||
|
FragData.col = in_col;
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user