some work on camera (wip)
This commit is contained in:
parent
fd03759f57
commit
e429cee207
Binary file not shown.
170
src/gears/game.d
Normal file
170
src/gears/game.d
Normal file
@ -0,0 +1,170 @@
|
||||
import aliases;
|
||||
import includes;
|
||||
import renderer : Destroy;
|
||||
import renderer;
|
||||
import util;
|
||||
import platform;
|
||||
import dplug.math;
|
||||
|
||||
struct Camera
|
||||
{
|
||||
f32 speed = 3.0;
|
||||
Vec3 pos = Vec3(0.0, 0.0, 3.0);
|
||||
Vec3 front = Vec3(0.0, 0.0, -1.0);
|
||||
Vec3 up = Vec3(0.0, 1.0, 0.0);
|
||||
}
|
||||
|
||||
struct Game
|
||||
{
|
||||
Renderer rd;
|
||||
|
||||
PlatformWindow* window;
|
||||
|
||||
Pipeline pbr_pipeline;
|
||||
Pipeline triangle_pipeline;
|
||||
Pipeline compute_pipeline;
|
||||
Pipeline ui_pipeline;
|
||||
|
||||
GlobalUniforms globals;
|
||||
|
||||
f32 delta;
|
||||
Timer timer;
|
||||
|
||||
Camera camera;
|
||||
|
||||
Model model;
|
||||
}
|
||||
|
||||
Game
|
||||
InitGame(PlatformWindow* window)
|
||||
{
|
||||
Game g = {
|
||||
rd: InitRenderer(window),
|
||||
window: window,
|
||||
timer: CreateTimer(),
|
||||
};
|
||||
|
||||
GfxPipelineInfo triangle_info = {
|
||||
vertex_shader: "shaders/triangle.vert.spv",
|
||||
frag_shader: "shaders/triangle.frag.spv",
|
||||
};
|
||||
|
||||
GfxPipelineInfo ui_info = {
|
||||
vertex_shader: "shaders/gui.vert.spv",
|
||||
frag_shader: "shaders/gui.frag.spv",
|
||||
input_rate: IR.Instance,
|
||||
input_rate_stride: UIVertex.sizeof,
|
||||
vertex_attributes: [
|
||||
{ binding: 0, location: 0, format: FMT.RG_F32, offset: 0 },
|
||||
{ binding: 0, location: 1, format: FMT.RG_F32, offset: UIVertex.p1.offsetof },
|
||||
{ binding: 0, location: 2, format: FMT.RGBA_F32, offset: UIVertex.col.offsetof },
|
||||
{ binding: 0, location: 3, format: FMT.UINT, offset: UIVertex.texture.offsetof },
|
||||
],
|
||||
};
|
||||
|
||||
GfxPipelineInfo pbr_info = {
|
||||
vertex_shader: "shaders/pbr.vert.spv",
|
||||
frag_shader: "shaders/pbr.frag.spv",
|
||||
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 },
|
||||
],
|
||||
};
|
||||
|
||||
CompPipelineInfo gradient_info = {
|
||||
shader: "shaders/gradient.comp.spv",
|
||||
};
|
||||
|
||||
g.pbr_pipeline = BuildGfxPipeline(&g.rd, &pbr_info);
|
||||
g.triangle_pipeline = BuildGfxPipeline(&g.rd, &triangle_info);
|
||||
g.ui_pipeline = BuildGfxPipeline(&g.rd, &ui_info);
|
||||
g.compute_pipeline = BuildCompPipeline(&g.rd, &gradient_info);
|
||||
|
||||
g.model = LoadModel(&g.rd, "models/yoda.m3d");
|
||||
|
||||
return g;
|
||||
}
|
||||
|
||||
void
|
||||
Update(Game* g, Camera* cam)
|
||||
{
|
||||
f32 speed = cam.speed * g.delta;
|
||||
|
||||
foreach(i; 0 .. g.window.input_count)
|
||||
{
|
||||
switch(g.window.inputs[i].key)
|
||||
{
|
||||
case KBI.W:
|
||||
{
|
||||
cam.pos += speed * cam.front;
|
||||
} break;
|
||||
case KBI.A:
|
||||
{
|
||||
cam.pos -= speed * cam.front;
|
||||
} break;
|
||||
case KBI.S:
|
||||
{
|
||||
cam.pos -= cross(cam.front, cam.up).normalized() * speed;
|
||||
} break;
|
||||
case KBI.D:
|
||||
{
|
||||
cam.pos += cross(cam.front, cam.up).normalized() * speed;
|
||||
} break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Cycle(Game* g)
|
||||
{
|
||||
g.delta = DeltaTime(&g.timer);
|
||||
|
||||
Update(g, &g.camera);
|
||||
|
||||
g.globals.projection_matrix = Mat4.identity;
|
||||
g.globals.view_matrix = Mat4.lookAt(g.camera.pos, g.camera.pos + g.camera.front, g.camera.up);
|
||||
|
||||
BeginFrame(&g.rd);
|
||||
|
||||
Bind(&g.rd, &g.compute_pipeline);
|
||||
|
||||
SetUniform(&g.rd, &g.globals);
|
||||
|
||||
DrawRect(&g.rd, 150.0, 300.0, 500.0, 700.0, Vec4(0.0, 0.0, 1.0, 1.0));
|
||||
|
||||
PrepComputeDrawImage(&g.rd);
|
||||
|
||||
Dispatch(&g.rd);
|
||||
|
||||
BeginRender(&g.rd);
|
||||
|
||||
Bind(&g.rd, &g.ui_pipeline);
|
||||
|
||||
BindUIBuffers(&g.rd);
|
||||
|
||||
DrawUI(&g.rd);
|
||||
|
||||
Bind(&g.rd, &g.triangle_pipeline);
|
||||
|
||||
Draw(&g.rd, 3, 1);
|
||||
|
||||
Bind(&g.rd, &g.pbr_pipeline);
|
||||
|
||||
DrawModel(&g.rd, &g.model);
|
||||
|
||||
FinishFrame(&g.rd);
|
||||
}
|
||||
|
||||
void
|
||||
Destroy(Game* g)
|
||||
{
|
||||
Destroy(&g.rd, &g.pbr_pipeline);
|
||||
Destroy(&g.rd, &g.triangle_pipeline);
|
||||
Destroy(&g.rd, &g.ui_pipeline);
|
||||
Destroy(&g.rd, &g.compute_pipeline);
|
||||
Destroy(&g.rd);
|
||||
}
|
||||
@ -2,43 +2,24 @@ public import includes;
|
||||
import std.stdio;
|
||||
import aliases;
|
||||
import core.memory;
|
||||
import p = platform;
|
||||
import r = renderer;
|
||||
import platform;
|
||||
import game;
|
||||
import util;
|
||||
import core.simd;
|
||||
|
||||
void main()
|
||||
{
|
||||
p.Window window = p.CreateWindow("Video Game", 1920, 1080);
|
||||
PlatformWindow window = CreateWindow("Video Game", 1920, 1080);
|
||||
|
||||
r.Renderer rd = r.Init(&window);
|
||||
scope(exit) r.Destroy(&rd);
|
||||
|
||||
u64 os_freq = OSTimeFreq();
|
||||
u64 cpu_start = RDTSC();
|
||||
u64 os_start = OSTime();
|
||||
u64 os_end = 0;
|
||||
u64 os_elapsed = 0;
|
||||
|
||||
while (os_elapsed < os_freq)
|
||||
{
|
||||
os_end = OSTime();
|
||||
os_elapsed = os_end - os_start;
|
||||
}
|
||||
|
||||
u64 cpu_end = RDTSC();
|
||||
u64 cpu_elapsed = cpu_end - cpu_start;
|
||||
|
||||
writefln(" OS Timer: %s -> %s = %s elapsed", os_start, os_end, os_elapsed);
|
||||
writefln("OS Seconds: %.4f", cast(f64)(os_elapsed)/cast(f64)(os_freq));
|
||||
writefln(" CPU Timer: %s -> %s = %s elapsed", cpu_start, cpu_end, cpu_elapsed);
|
||||
Game g = InitGame(&window);
|
||||
scope(exit) Destroy(&g);
|
||||
|
||||
while (true)
|
||||
{
|
||||
p.HandleEvents(&window);
|
||||
HandleEvents(&window);
|
||||
if (window.close) break;
|
||||
|
||||
r.Cycle(&rd);
|
||||
Cycle(&g);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -3,11 +3,40 @@ import includes;
|
||||
import std.stdio;
|
||||
import core.memory;
|
||||
|
||||
enum KeyboardInput
|
||||
{
|
||||
None,
|
||||
A, B, C, D, E, F, G, H, I, J, K, L, M,
|
||||
N, O, P, Q, R, S, T, U, V, W, X, Y, Z,
|
||||
Zero, One, Two, Three, Four, Five, Six, Seven, Eight, Nine,
|
||||
Num0, Num1, Num2, Num3, Num4, Num5, Num6, Num7, Num8, Num9,
|
||||
NumLock, NumSlash, NumStar, NumMinus, NumPlus, NumEnter, NumPeriod,
|
||||
Insert, Delete, Home, End, PageUp, PageDown,
|
||||
PrintScreen, ScrollLock, Pause,
|
||||
Comma, Period, BackSlash, Backspace, ForwardSlash, Minus, Plus,
|
||||
F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12,
|
||||
Up, Down, Left, Right,
|
||||
LeftCtrl, LeftAlt, LeftShift, LeftSuper,
|
||||
Tab, CapsLock,
|
||||
RightCtrl, RightAlt, RightSuper, RightShift,
|
||||
Enter, Space,
|
||||
Tilde, Esc,
|
||||
Semicolon, Quote, LeftBrace, RightBrace,
|
||||
};
|
||||
|
||||
alias KBI = KeyboardInput;
|
||||
|
||||
version(linux)
|
||||
{
|
||||
import core.sys.posix.dlfcn;
|
||||
|
||||
struct Window
|
||||
struct InputEvent
|
||||
{
|
||||
KeyboardInput key;
|
||||
bool pressed;
|
||||
}
|
||||
|
||||
struct PlatformWindow
|
||||
{
|
||||
Display *display;
|
||||
xcb_connection_t *conn;
|
||||
@ -17,6 +46,8 @@ struct Window
|
||||
u16 w;
|
||||
u16 h;
|
||||
bool close;
|
||||
InputEvent[10] inputs;
|
||||
u32 input_count;
|
||||
};
|
||||
|
||||
struct Library
|
||||
@ -29,15 +60,15 @@ struct Function
|
||||
void* ptr;
|
||||
};
|
||||
|
||||
void CheckErr(Window *window, xcb_void_cookie_t *cookie, xcb_generic_error_t *err, string msg)
|
||||
void CheckErr(PlatformWindow *window, xcb_void_cookie_t *cookie, xcb_generic_error_t *err, string msg)
|
||||
{
|
||||
assert(err == null, msg);
|
||||
pureFree(err);
|
||||
};
|
||||
|
||||
Window CreateWindow(string name, u16 width, u16 height)
|
||||
PlatformWindow CreateWindow(string name, u16 width, u16 height)
|
||||
{
|
||||
Window window = {
|
||||
PlatformWindow window = {
|
||||
w: width,
|
||||
h: height,
|
||||
};
|
||||
@ -147,7 +178,7 @@ Window CreateWindow(string name, u16 width, u16 height)
|
||||
};
|
||||
|
||||
void
|
||||
HandleEvents(Window* window)
|
||||
HandleEvents(PlatformWindow* window)
|
||||
{
|
||||
xcb_generic_event_t* e;
|
||||
|
||||
@ -172,6 +203,29 @@ HandleEvents(Window* window)
|
||||
window.close = true;
|
||||
}
|
||||
} break;
|
||||
case XCB_KEY_RELEASE:
|
||||
case XCB_KEY_PRESS:
|
||||
{
|
||||
// TODO: definitely definitely need to rework this whole thing
|
||||
if (window.input_count == window.inputs.length)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
xcb_key_press_event_t* keyboard_event = cast(xcb_key_press_event_t*)e;
|
||||
|
||||
bool pressed = e.response_type == XCB_KEY_PRESS;
|
||||
xcb_keycode_t code = keyboard_event.detail;
|
||||
KeySym key_sym = XkbKeycodeToKeysym(window.display, cast(KeyCode)code, 0, 0);
|
||||
KBI input = ConvertInput(key_sym);
|
||||
|
||||
if (input != KBI.None)
|
||||
{
|
||||
window.inputs[window.input_count].key = input;
|
||||
window.inputs[window.input_count].pressed = pressed;
|
||||
window.input_count += 1;
|
||||
}
|
||||
} break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@ -202,6 +256,143 @@ Function LoadFunction(Library lib, string name)
|
||||
return fn;
|
||||
};
|
||||
|
||||
KeyboardInput
|
||||
ConvertInput(u64 x_key)
|
||||
{
|
||||
switch (x_key)
|
||||
{
|
||||
case XK_BackSpace: return KBI.Backspace;
|
||||
case XK_Return: return KBI.Enter;
|
||||
case XK_Tab: return KBI.Tab;
|
||||
case XK_Pause: return KBI.Pause;
|
||||
case XK_Caps_Lock: return KBI.CapsLock;
|
||||
case XK_Escape: return KBI.Esc;
|
||||
case XK_space: return KBI.Space;
|
||||
case XK_Prior: return KBI.PageUp;
|
||||
case XK_Next: return KBI.PageDown;
|
||||
case XK_End: return KBI.End;
|
||||
case XK_Home: return KBI.Home;
|
||||
case XK_Left: return KBI.Left;
|
||||
case XK_Up: return KBI.Up;
|
||||
case XK_Right: return KBI.Right;
|
||||
case XK_Down: return KBI.Down;
|
||||
case XK_Print: return KBI.PrintScreen;
|
||||
case XK_Insert: return KBI.Insert;
|
||||
case XK_Delete: return KBI.Delete;
|
||||
case XK_Meta_L:
|
||||
case XK_Super_L: return KBI.LeftSuper;
|
||||
case XK_Meta_R:
|
||||
case XK_Super_R: return KBI.RightSuper;
|
||||
case XK_KP_0: return KBI.Num0;
|
||||
case XK_KP_1: return KBI.Num1;
|
||||
case XK_KP_2: return KBI.Num2;
|
||||
case XK_KP_3: return KBI.Num3;
|
||||
case XK_KP_4: return KBI.Num4;
|
||||
case XK_KP_5: return KBI.Num5;
|
||||
case XK_KP_6: return KBI.Num6;
|
||||
case XK_KP_7: return KBI.Num7;
|
||||
case XK_KP_8: return KBI.Num8;
|
||||
case XK_KP_9: return KBI.Num9;
|
||||
case XK_multiply: return KBI.NumStar;
|
||||
case XK_KP_Subtract: return KBI.NumMinus;
|
||||
case XK_KP_Decimal: return KBI.NumPeriod;
|
||||
case XK_KP_Divide: return KBI.NumSlash;
|
||||
case XK_KP_Add: return KBI.NumPlus;
|
||||
case XK_F1: return KBI.F1;
|
||||
case XK_F2: return KBI.F2;
|
||||
case XK_F3: return KBI.F3;
|
||||
case XK_F4: return KBI.F4;
|
||||
case XK_F5: return KBI.F5;
|
||||
case XK_F6: return KBI.F6;
|
||||
case XK_F7: return KBI.F7;
|
||||
case XK_F8: return KBI.F8;
|
||||
case XK_F9: return KBI.F9;
|
||||
case XK_F10: return KBI.F10;
|
||||
case XK_F11: return KBI.F11;
|
||||
case XK_F12: return KBI.F12;
|
||||
case XK_Num_Lock: return KBI.NumLock;
|
||||
case XK_Scroll_Lock: return KBI.ScrollLock;
|
||||
case XK_Shift_L: return KBI.LeftShift;
|
||||
case XK_Shift_R: return KBI.RightShift;
|
||||
case XK_Control_L: return KBI.LeftCtrl;
|
||||
case XK_Control_R: return KBI.RightCtrl;
|
||||
case XK_Alt_L: return KBI.LeftAlt;
|
||||
case XK_Alt_R: return KBI.RightAlt;
|
||||
case XK_semicolon: return KBI.Semicolon;
|
||||
case XK_bracketleft: return KBI.LeftBrace;
|
||||
case XK_bracketright: return KBI.RightBrace;
|
||||
case XK_plus: return KBI.Plus;
|
||||
case XK_comma: return KBI.Comma;
|
||||
case XK_minus: return KBI.Minus;
|
||||
case XK_backslash: return KBI.BackSlash;
|
||||
case XK_slash: return KBI.ForwardSlash;
|
||||
case XK_grave: return KBI.Tilde;
|
||||
case XK_0: return KBI.Zero;
|
||||
case XK_1: return KBI.One;
|
||||
case XK_2: return KBI.Two;
|
||||
case XK_3: return KBI.Three;
|
||||
case XK_4: return KBI.Four;
|
||||
case XK_5: return KBI.Five;
|
||||
case XK_6: return KBI.Six;
|
||||
case XK_7: return KBI.Seven;
|
||||
case XK_8: return KBI.Eight;
|
||||
case XK_9: return KBI.Nine;
|
||||
case XK_a:
|
||||
case XK_A: return KBI.A;
|
||||
case XK_b:
|
||||
case XK_B: return KBI.B;
|
||||
case XK_c:
|
||||
case XK_C: return KBI.C;
|
||||
case XK_d:
|
||||
case XK_D: return KBI.D;
|
||||
case XK_e:
|
||||
case XK_E: return KBI.E;
|
||||
case XK_f:
|
||||
case XK_F: return KBI.F;
|
||||
case XK_g:
|
||||
case XK_G: return KBI.G;
|
||||
case XK_h:
|
||||
case XK_H: return KBI.H;
|
||||
case XK_i:
|
||||
case XK_I: return KBI.I;
|
||||
case XK_j:
|
||||
case XK_J: return KBI.J;
|
||||
case XK_k:
|
||||
case XK_K: return KBI.K;
|
||||
case XK_l:
|
||||
case XK_L: return KBI.L;
|
||||
case XK_m:
|
||||
case XK_M: return KBI.M;
|
||||
case XK_n:
|
||||
case XK_N: return KBI.N;
|
||||
case XK_o:
|
||||
case XK_O: return KBI.O;
|
||||
case XK_p:
|
||||
case XK_P: return KBI.P;
|
||||
case XK_q:
|
||||
case XK_Q: return KBI.Q;
|
||||
case XK_r:
|
||||
case XK_R: return KBI.R;
|
||||
case XK_s:
|
||||
case XK_S: return KBI.S;
|
||||
case XK_t:
|
||||
case XK_T: return KBI.T;
|
||||
case XK_u:
|
||||
case XK_U: return KBI.U;
|
||||
case XK_v:
|
||||
case XK_V: return KBI.V;
|
||||
case XK_w:
|
||||
case XK_W: return KBI.W;
|
||||
case XK_x:
|
||||
case XK_X: return KBI.X;
|
||||
case XK_y:
|
||||
case XK_Y: return KBI.Y;
|
||||
case XK_z:
|
||||
case XK_Z: return KBI.Z;
|
||||
default: return KBI.None;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
version(Windows)
|
||||
|
||||
@ -8,7 +8,7 @@ import vulkan : Destroy, Init, Draw, DrawIndexed, Bind, BindUIBuffers, BeginRend
|
||||
import assets;
|
||||
import std.math.traits : isNaN;
|
||||
import u = util : Logf;
|
||||
import p = platform;
|
||||
import platform;
|
||||
|
||||
alias Shader = VkShaderModule;
|
||||
alias Pipeline = PipelineHandle;
|
||||
@ -51,8 +51,8 @@ alias BT = BufferType;
|
||||
|
||||
struct GlobalUniforms
|
||||
{
|
||||
Mat4 view_matrix;
|
||||
Mat4 projection_matrix;
|
||||
Mat4 view_matrix = Mat4.identity;
|
||||
Mat4 projection_matrix = Mat4.identity;
|
||||
Vec2 res;
|
||||
}
|
||||
|
||||
@ -106,30 +106,13 @@ struct Renderer
|
||||
Arena temp_arena;
|
||||
|
||||
Vulkan vk;
|
||||
p.Window* window;
|
||||
PlatformWindow* window;
|
||||
|
||||
GlobalUniforms globals;
|
||||
UIVertex[] ui_vertex_buf;
|
||||
u32[] ui_index_buf;
|
||||
u32 ui_count;
|
||||
|
||||
Pipeline pbr_pipeline;
|
||||
Pipeline triangle_pipeline;
|
||||
Pipeline compute_pipeline;
|
||||
Pipeline ui_pipeline;
|
||||
|
||||
PushConst push_const;
|
||||
|
||||
Vec3 camera_pos = Vec3(0.0);
|
||||
|
||||
Model model;
|
||||
}
|
||||
|
||||
struct Camera
|
||||
{
|
||||
Vec3 pos = Vec3(0.0, 0.0, 3.0);
|
||||
Vec3 front = Vec3(0.0, 0.0, -1.0);
|
||||
Vec3 up = Vec3(0.0, 1.0, 0.0);
|
||||
}
|
||||
|
||||
extern(C) struct Material
|
||||
@ -182,7 +165,7 @@ struct Model
|
||||
}
|
||||
|
||||
Renderer
|
||||
Init(p.Window* window)
|
||||
InitRenderer(PlatformWindow* window)
|
||||
{
|
||||
u.Result!(Vulkan) vk_result = Init(window, u.MB(24), u.MB(32));
|
||||
assert(vk_result.ok, "Init failure: Unable to initialize Vulkan");
|
||||
@ -196,95 +179,15 @@ Init(p.Window* window)
|
||||
ui_index_buf: GetUIIndexBuffer(&vk_result.value),
|
||||
};
|
||||
|
||||
GfxPipelineInfo triangle_info = {
|
||||
vertex_shader: "shaders/triangle.vert.spv",
|
||||
frag_shader: "shaders/triangle.frag.spv",
|
||||
};
|
||||
|
||||
GfxPipelineInfo ui_info = {
|
||||
vertex_shader: "shaders/gui.vert.spv",
|
||||
frag_shader: "shaders/gui.frag.spv",
|
||||
input_rate: IR.Instance,
|
||||
input_rate_stride: UIVertex.sizeof,
|
||||
vertex_attributes: [
|
||||
{ binding: 0, location: 0, format: FMT.RG_F32, offset: 0 },
|
||||
{ binding: 0, location: 1, format: FMT.RG_F32, offset: UIVertex.p1.offsetof },
|
||||
{ binding: 0, location: 2, format: FMT.RGBA_F32, offset: UIVertex.col.offsetof },
|
||||
{ binding: 0, location: 3, format: FMT.UINT, offset: UIVertex.texture.offsetof },
|
||||
],
|
||||
};
|
||||
|
||||
GfxPipelineInfo pbr_info = {
|
||||
vertex_shader: "shaders/pbr.vert.spv",
|
||||
frag_shader: "shaders/pbr.frag.spv",
|
||||
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 },
|
||||
],
|
||||
};
|
||||
|
||||
CompPipelineInfo gradient_info = {
|
||||
shader: "shaders/gradient.comp.spv",
|
||||
};
|
||||
|
||||
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, &gradient_info);
|
||||
|
||||
rd.model = LoadModel(&rd, "models/yoda.m3d");
|
||||
|
||||
ReadModel(&rd, "models/yoda.m3d");
|
||||
|
||||
return rd;
|
||||
}
|
||||
|
||||
void
|
||||
Cycle(Renderer* rd)
|
||||
{
|
||||
rd.ui_count = 0;
|
||||
|
||||
rd.globals.view_matrix = Mat4(1.0);
|
||||
|
||||
BeginFrame(rd);
|
||||
|
||||
Bind(rd, &rd.compute_pipeline);
|
||||
|
||||
SetUniform(rd, &rd.globals);
|
||||
|
||||
//DrawRect(rd, 150.0, 300.0, 500.0, 700.0, Vec4(0.0, 0.0, 1.0, 1.0));
|
||||
|
||||
PrepComputeDrawImage(rd);
|
||||
|
||||
Dispatch(rd);
|
||||
|
||||
BeginRender(rd);
|
||||
|
||||
Bind(rd, &rd.ui_pipeline);
|
||||
|
||||
BindUIBuffers(rd);
|
||||
|
||||
DrawIndexed(rd, 6, rd.ui_count, 0);
|
||||
|
||||
Bind(rd, &rd.triangle_pipeline);
|
||||
|
||||
//Draw(rd, 3, 1);
|
||||
|
||||
Bind(rd, &rd.pbr_pipeline);
|
||||
|
||||
DrawModel(rd, &rd.model);
|
||||
|
||||
FinishFrame(rd);
|
||||
}
|
||||
|
||||
pragma(inline): void
|
||||
DrawModel(Renderer* rd, Model* model)
|
||||
{
|
||||
BindBuffers(&rd.vk, &model.index_buffer, &model.vertex_buffer);
|
||||
|
||||
rd.push_const.model_matrix = Mat4.identity;
|
||||
foreach(i, part; model.parts)
|
||||
{
|
||||
rd.push_const.mat_id = part.mat;
|
||||
@ -308,9 +211,16 @@ CopyVertex(Vec4* dst, m3dv_t* src)
|
||||
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
|
||||
FinishFrame(Renderer* rd)
|
||||
{
|
||||
@ -410,7 +320,6 @@ ReadModel(Renderer* rd, string name)
|
||||
foreach(i; 0 .. m3d.numtexture)
|
||||
{
|
||||
const(char)[] tex_name = m3d.texture[i].name[0 .. strlen(m3d.texture[i].name)];
|
||||
Logf("texture name: %r", tex_name);
|
||||
}
|
||||
|
||||
if (m3d.numtexture == 0)
|
||||
@ -421,7 +330,6 @@ ReadModel(Renderer* rd, string name)
|
||||
foreach(i; 0 .. m3d.nummaterial)
|
||||
{
|
||||
const(char)[] mat_name = m3d.material[i].name[0 .. strlen(m3d.material[i].name)];
|
||||
Logf("material name: %r", mat_name);
|
||||
}
|
||||
}
|
||||
|
||||
@ -445,8 +353,6 @@ LoadModel(Renderer* rd, string name)
|
||||
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];
|
||||
|
||||
Logf("w: %s h: %s ch: %s", 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);
|
||||
|
||||
@ -483,7 +389,7 @@ LoadModel(Renderer* rd, string name)
|
||||
mats[i].specular_texture = tex_lookup[m3d.material[i].prop[j].value.textureid];
|
||||
mats[i].specular_has_texture = true;
|
||||
} break;
|
||||
default: Logf("Unimplemented: %s", m3d.material[i].prop[j].type); break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -588,9 +494,11 @@ LoadModel(Renderer* rd, string name)
|
||||
void
|
||||
Destroy(Renderer* rd)
|
||||
{
|
||||
Destroy(&rd.vk, rd.triangle_pipeline);
|
||||
Destroy(&rd.vk, rd.compute_pipeline);
|
||||
Destroy(&rd.vk);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Destroy(Renderer* rd, Pipeline* pipeline)
|
||||
{
|
||||
Destroy(&rd.vk, pipeline);
|
||||
}
|
||||
|
||||
@ -7,7 +7,7 @@ import core.stdc.string : strcmp, memcpy;
|
||||
import std.format : sformat;
|
||||
import u = util : HashTable, Result, Logf, Log, MB, Delete;
|
||||
import alloc;
|
||||
import p = platform;
|
||||
import platform;
|
||||
import ap = assets;
|
||||
import renderer;
|
||||
import std.math.rounding : Ceil = ceil;
|
||||
@ -140,7 +140,7 @@ struct Vulkan
|
||||
|
||||
u.SLList!(SI) cleanup_list;
|
||||
|
||||
p.Window* window;
|
||||
PlatformWindow* window;
|
||||
|
||||
VkDebugUtilsMessengerEXT dbg_msg;
|
||||
VkInstance instance;
|
||||
@ -226,7 +226,7 @@ struct QueueInfo
|
||||
};
|
||||
|
||||
u.Result!(Vulkan)
|
||||
Init(p.Window* window, u64 permanent_mem, u64 frame_mem)
|
||||
Init(PlatformWindow* window, u64 permanent_mem, u64 frame_mem)
|
||||
{
|
||||
bool success = true;
|
||||
|
||||
@ -716,8 +716,6 @@ CreateImageView(Vulkan* vk, ImageView* view, u32 w, u32 h, u32 ch, u8[] data)
|
||||
{
|
||||
CreateImageView(vk, view, w, h);
|
||||
|
||||
Logf("w: %s h: %s ch: %s", w, h, ch);
|
||||
|
||||
if (ch == 4)
|
||||
{
|
||||
assert(Transfer(vk, view, data, w, h), "CreateImageView failure: Image Transfer error");
|
||||
@ -1457,6 +1455,7 @@ SetUniform(Vulkan* vk, GlobalUniforms* globals)
|
||||
{
|
||||
globals.res.x = vk.swapchain_extent.width;
|
||||
globals.res.y = vk.swapchain_extent.height;
|
||||
globals.projection_matrix = Mat4.perspective(1.57, cast(f32)(globals.res.y) / cast(f32)(globals.res.y), 0.1, 100.0);
|
||||
|
||||
vk.global_buf.data[0] = *globals;
|
||||
|
||||
@ -1484,7 +1483,7 @@ Destroy(Vulkan* vk, Shader shader)
|
||||
}
|
||||
|
||||
void
|
||||
Destroy(Vulkan* vk, Pipeline pipeline)
|
||||
Destroy(Vulkan* vk, Pipeline* pipeline)
|
||||
{
|
||||
vkDestroyPipeline(vk.device, pipeline.handle, null);
|
||||
}
|
||||
@ -1731,34 +1730,41 @@ InitDescriptors(Vulkan* vk)
|
||||
sampler: vk.nearest_sampler,
|
||||
};
|
||||
|
||||
VkDescriptorImageInfo draw_image_info = {
|
||||
imageView: vk.draw_image.view,
|
||||
imageLayout: VK_IMAGE_LAYOUT_GENERAL,
|
||||
};
|
||||
|
||||
VkWriteDescriptorSet[] writes = [
|
||||
{
|
||||
VkWriteDescriptorSet write = {
|
||||
sType: VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
|
||||
dstSet: vk.desc_sets[DT.Shared],
|
||||
dstBinding: 3,
|
||||
descriptorCount: 1,
|
||||
descriptorType: VK_DESCRIPTOR_TYPE_SAMPLER,
|
||||
pImageInfo: &sampler_info,
|
||||
},
|
||||
{
|
||||
};
|
||||
|
||||
vkUpdateDescriptorSets(vk.device, 1, &write, 0, null);
|
||||
|
||||
WriteDrawImageDesc(vk);
|
||||
}
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
void
|
||||
WriteDrawImageDesc(Vulkan* vk)
|
||||
{
|
||||
VkDescriptorImageInfo draw_image_info = {
|
||||
imageView: vk.draw_image.view,
|
||||
imageLayout: VK_IMAGE_LAYOUT_GENERAL,
|
||||
};
|
||||
|
||||
VkWriteDescriptorSet write = {
|
||||
sType: VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
|
||||
dstSet: vk.desc_sets[DT.Shared],
|
||||
dstBinding: 2,
|
||||
descriptorCount: 1,
|
||||
descriptorType: VK_DESCRIPTOR_TYPE_STORAGE_IMAGE,
|
||||
pImageInfo: &draw_image_info,
|
||||
},
|
||||
];
|
||||
};
|
||||
|
||||
vkUpdateDescriptorSets(vk.device, cast(u32)writes.length, writes.ptr, 0, null);
|
||||
}
|
||||
|
||||
return success;
|
||||
vkUpdateDescriptorSets(vk.device, 1, &write, 0, null);
|
||||
}
|
||||
|
||||
void
|
||||
@ -2258,8 +2264,11 @@ RecreateSwapchain(Vulkan* vk)
|
||||
vkDeviceWaitIdle(vk.device);
|
||||
|
||||
Destroy(vk.swapchain, vk.present_images, vk.device);
|
||||
Destroy(&vk.draw_image, &vk.depth_image, vk.device, vk.vma);
|
||||
|
||||
CreateSwapchain(vk);
|
||||
CreateDrawImages(vk);
|
||||
WriteDrawImageDesc(vk);
|
||||
}
|
||||
|
||||
bool
|
||||
|
||||
@ -22,7 +22,7 @@ mat4 y_matrix = mat4(
|
||||
|
||||
void main()
|
||||
{
|
||||
gl_Position = in_pos * y_matrix;
|
||||
gl_Position = G.projection_matrix * G.view_matrix * PC.model_matrix * in_pos;
|
||||
|
||||
vec4 col = Materials[nonuniformEXT(PC.mat_id)].diffuse;
|
||||
|
||||
|
||||
@ -411,3 +411,111 @@ OSTime()
|
||||
|
||||
return time;
|
||||
}
|
||||
|
||||
// TODO: probably needs improvement/testing
|
||||
struct IntervalTimer
|
||||
{
|
||||
u64 cpu_freq;
|
||||
u64 interval;
|
||||
u64 prev;
|
||||
}
|
||||
|
||||
IntervalTimer
|
||||
CreateTimer(u64 fps)
|
||||
{
|
||||
IntervalTimer timer;
|
||||
|
||||
u64 ms_to_wait = 50;
|
||||
|
||||
u64 os_freq = OSTimeFreq();
|
||||
u64 cpu_start = RDTSC();
|
||||
u64 os_start = OSTime();
|
||||
u64 os_end = 0;
|
||||
u64 os_elapsed = 0;
|
||||
|
||||
u64 os_wait_time = os_freq * ms_to_wait / 1000;
|
||||
|
||||
while (os_elapsed < os_wait_time)
|
||||
{
|
||||
os_end = OSTime();
|
||||
os_elapsed = os_end - os_start;
|
||||
}
|
||||
|
||||
u64 cpu_end = RDTSC();
|
||||
u64 cpu_elapsed = cpu_end - cpu_start;
|
||||
u64 cpu_freq = 0;
|
||||
if (os_elapsed)
|
||||
{
|
||||
cpu_freq = os_freq * cpu_elapsed / os_elapsed;
|
||||
}
|
||||
|
||||
timer.cpu_freq = cpu_freq;
|
||||
timer.interval = cpu_freq/(fps+1);
|
||||
timer.prev = RDTSC();
|
||||
|
||||
return timer;
|
||||
}
|
||||
|
||||
pragma(inline): bool
|
||||
CheckTimer(IntervalTimer* t)
|
||||
{
|
||||
bool result = false;
|
||||
u64 time = RDTSC();
|
||||
if (time - t.prev > t.interval)
|
||||
{
|
||||
result = true;
|
||||
t.prev = time;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
struct Timer
|
||||
{
|
||||
u64 cpu_freq;
|
||||
u64 prev;
|
||||
}
|
||||
|
||||
Timer
|
||||
CreateTimer()
|
||||
{
|
||||
u64 ms_to_wait = 50;
|
||||
|
||||
u64 os_freq = OSTimeFreq();
|
||||
u64 cpu_start = RDTSC();
|
||||
u64 os_start = OSTime();
|
||||
u64 os_end = 0;
|
||||
u64 os_elapsed = 0;
|
||||
|
||||
u64 os_wait_time = os_freq * ms_to_wait / 1000;
|
||||
|
||||
while (os_elapsed < os_wait_time)
|
||||
{
|
||||
os_end = OSTime();
|
||||
os_elapsed = os_end - os_start;
|
||||
}
|
||||
|
||||
u64 cpu_end = RDTSC();
|
||||
u64 cpu_elapsed = cpu_end - cpu_start;
|
||||
u64 cpu_freq = 0;
|
||||
if (os_elapsed)
|
||||
{
|
||||
cpu_freq = os_freq * cpu_elapsed / os_elapsed;
|
||||
}
|
||||
|
||||
Timer timer = {
|
||||
cpu_freq: cpu_freq,
|
||||
prev: RDTSC(),
|
||||
};
|
||||
|
||||
return timer;
|
||||
}
|
||||
|
||||
pragma(inline): f32
|
||||
DeltaTime(Timer* t)
|
||||
{
|
||||
u64 time = RDTSC();
|
||||
u64 step = time - t.prev;
|
||||
t.prev = time;
|
||||
return cast(f32)(step) / cast(f32)(t.cpu_freq);
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user