66 Commits

Author SHA1 Message Date
874b2b59f7 Merge branch 'main' of yibble.dev:bulmanator/ld58 2025-10-07 14:14:51 +01:00
dbff261805 Merge branch 'main' of yibble.dev:bulmanator/ld58 2025-10-07 14:09:59 +01:00
8363560fd2 fix: make it compile 2025-10-06 23:13:46 +01:00
31863b0d31 fix: import 2025-10-06 23:09:53 +01:00
7f77d7ad52 npc and bandit dressup, bits of UI added, WIP NPC interaction 2025-10-06 23:08:15 +01:00
df2c02a6a9 VERY hacky positional audio 2025-10-06 22:17:41 +01:00
f18d9d2b0e feat: made hitboxes area dependent 2025-10-06 21:57:06 +01:00
59f643b72c Added audio playback
Playing music
2025-10-06 21:54:48 +01:00
c01a6be4e5 feat: Initial prop placement 2025-10-06 21:35:32 +01:00
f93b543924 chore: fix \n 2025-10-06 21:30:13 +01:00
72a86ddb41 Merge remote-tracking branch 'origin' 2025-10-06 21:19:44 +01:00
680d375b8c feat: Added portals 2025-10-06 21:07:55 +01:00
87d3c9087e Merge branch 'debug'
Fixed some warnings
2025-10-06 19:52:28 +01:00
0c33944721 Merge branch 'debug/world_change' of yibble.dev:bulmanator/ld58 into debug 2025-10-06 19:38:14 +01:00
c1fb705f68 Fixed level saving and loading 2025-10-06 19:36:41 +01:00
be49003a8d Merge remote-tracking branch 'origin' 2025-10-06 19:32:12 +01:00
7b7f088116 fix: save/load 2025-10-06 19:27:45 +01:00
d9957eead1 feat: Nav mesh generation 2025-10-06 18:23:47 +01:00
cb10bd10b6 Merge branch 'main' of yibble.dev:bulmanator/ld58 2025-10-06 17:55:32 +01:00
a6577f520b Fixed ???
Some files have been renamed
2025-10-06 17:49:08 +01:00
d54b4df4c2 player health 2025-10-06 17:45:58 +01:00
fcc7adfb22 added badman shooting and reloading 2025-10-06 17:30:49 +01:00
c4cf8f532b feat: World loading that's broken 2025-10-06 16:35:22 +01:00
8a360df98a feat: Hitbox drawing 2025-10-06 14:50:32 +01:00
3a84947750 feat: Basic level editing 2025-10-06 14:26:00 +01:00
3e527f473b feat: Fix loading 2025-10-06 11:31:35 +01:00
ab8301f475 feat (BROKEN): Save world code 2025-10-06 01:49:10 +01:00
08cbfaeb71 Merge remote-tracking branch 'origin' 2025-10-06 01:12:08 +01:00
2f52bb3097 feat: save world written 2025-10-06 01:10:44 +01:00
a9612b2d57 Fixed some warnings
Moved global width/height
2025-10-06 01:01:28 +01:00
139b14ed71 Merge branch 'main' of yibble.dev:bulmanator/ld58 2025-10-06 00:57:13 +01:00
c721839dfa Added animations
Added new assets for the player
Added lookups for assets
Initial sound testing
Re-enabled temp world drawing
2025-10-06 00:52:16 +01:00
24e9b472c3 use slab aabb for gunshots 2025-10-06 00:48:41 +01:00
b09bdc6209 map tiles 2025-10-06 00:38:10 +01:00
64a84e3a8d feat: different rooms added
feat: shooting bandit added
2025-10-05 23:36:50 +01:00
319bb441ed feat: Added basic shooting 2025-10-05 22:35:34 +01:00
3eb8683ce3 Merge branch 'main' of yibble.dev:bulmanator/ld58 2025-10-05 21:19:14 +01:00
eb3c81cd04 Added unproject
Broken and buggy font stuff
Fixed some typos
Fixed draw rect not using dim properly
2025-10-05 21:11:18 +01:00
635e7b1c1e feat: Initial bandit roaming 2025-10-05 21:05:29 +01:00
b8f47b8f61 feat: added npc poi for custom npcs 2025-10-05 18:28:58 +01:00
e20e537e97 feat: Player controller 2025-10-05 18:05:01 +01:00
98095c907f chore: removed nav printf 2025-10-05 16:53:56 +01:00
8dc0ac1d3e Merge remote-tracking branch 'origin' 2025-10-05 16:51:59 +01:00
222575b318 feat: People go walkies 2025-10-05 16:49:18 +01:00
9a46a802e0 add ignore 2025-10-05 16:12:23 +01:00
628a6c5ade raycast fin 2025-10-05 16:12:23 +01:00
c8dfcd857e raycast start 2025-10-05 16:11:47 +01:00
394366480b feat: Random npc walkabouts 2025-10-05 15:32:57 +01:00
8f148b6894 Merge remote-tracking branch 'origin' 2025-10-05 15:22:09 +01:00
7306c8fba4 chore: struct reorg 2025-10-05 15:21:23 +01:00
5cabf845b6 Added random number generator
Fixed typo in calculate camera
Removed some warning
2025-10-05 15:17:37 +01:00
1d70f3ae20 feat: Add player breaks 2025-10-05 14:47:54 +01:00
5d48ed9c19 Merge remote-tracking branch 'origin' 2025-10-05 14:46:04 +01:00
1f97d81133 feat: initial bandit and more npc tweaks 2025-10-05 14:42:19 +01:00
1757fc4b96 Added rect draw api
Added some new maths types
Updated shaders to use new D_Rect structure
Added rect buffers to frames
Misc cleanup
2025-10-05 14:27:05 +01:00
3b8c50a361 Added camera
Moved some math types
Added some more vector types
Did the camera matrix calulations
Updated shaders to take push constants
2025-10-05 02:40:59 +01:00
2c67896cf2 Made navmesh compile on Windows
Small updates to remove warnings
Testing nonuniform descriptor access in shader
2025-10-05 01:31:39 +01:00
175f4da59b chore: Fix printf 2025-10-05 00:31:52 +01:00
50efa6d8c0 Merge remote-tracking branch 'origin' 2025-10-05 00:30:33 +01:00
ab96fa3eeb feat: Basic NPC wandering 2025-10-05 00:25:37 +01:00
55c1adba40 Added system path stuff on Windows
Fixed typo in image loading
2025-10-05 00:24:51 +01:00
dd316664f6 Added filesystem stuff on Linux
More includes for Linux
Update build script to copy assets and compile shaders
Added base code directory as include path
Added FS_SystemPath
Made asset loading work directory agnostic
2025-10-04 23:46:13 +01:00
e4c1bc0a1c Merge branch 'main' of yibble.dev:bulmanator/ld58
Fixed conflicts
Added "code" directory for include to make it easier to include core
headers
Stopped warnings (probably cl specific)
2025-10-04 21:58:14 +01:00
187359f747 Drawing a textured quad
Added new assets
Loaded all texture assets into game state
Loaded the basic pipeline
Setup a hard-coded quad to test drawing
Created a very jank vertex struct
Added ReadEntireFile for filesystem
Added getting file size from file handle
Added a descriptor pool to each in flight frame
Changed Vk_BufferCreate to handle multiple uses
Added shader building to the windows.bat build script
2025-10-04 21:42:04 +01:00
b1a805cea8 Added image loading
Added some string functions and macros
Added path listing on windows
Added assets
2025-10-04 17:24:30 +01:00
7d55b16c8e Filesystem stuff on Windows
Minor image acquire/present refactor
Unsigned integer limits
Fixed typo in arena push/push copy macro
2025-10-04 11:52:39 +01:00
136 changed files with 4598 additions and 160 deletions

1
.gitignore vendored
View File

@@ -1,3 +1,4 @@
build/
code/compile_commands.json
code/.cache
.vscode

BIN
assets/barrel.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 590 B

BIN
assets/can.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 168 B

BIN
assets/candle.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 176 B

BIN
assets/clock.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 584 B

BIN
assets/heart.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 289 B

BIN
assets/house.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

BIN
assets/house_int.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 KiB

BIN
assets/hunter.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 730 B

BIN
assets/log_pile.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 519 B

BIN
assets/nightstand.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 244 B

BIN
assets/npc_00.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 801 B

BIN
assets/npc_back_base_0.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 650 B

BIN
assets/npc_back_base_1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 677 B

BIN
assets/npc_back_face_1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 232 B

BIN
assets/npc_back_face_2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 204 B

BIN
assets/npc_back_hair_1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 483 B

BIN
assets/npc_back_hair_2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 395 B

BIN
assets/npc_back_hair_3.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 243 B

BIN
assets/npc_back_hat_1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 319 B

BIN
assets/npc_back_hat_2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 298 B

BIN
assets/npc_back_shirt_0.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 560 B

BIN
assets/npc_back_shirt_1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 521 B

BIN
assets/npc_back_shoes_0.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 274 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 337 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 325 B

BIN
assets/npc_front_base_0.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 732 B

BIN
assets/npc_front_base_1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 737 B

BIN
assets/npc_front_eyes_0.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 232 B

BIN
assets/npc_front_eyes_1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 207 B

BIN
assets/npc_front_eyes_2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 217 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 127 B

BIN
assets/npc_front_face_1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 227 B

BIN
assets/npc_front_face_2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 186 B

BIN
assets/npc_front_face_3.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 157 B

BIN
assets/npc_front_face_4.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 191 B

BIN
assets/npc_front_hair_1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 393 B

BIN
assets/npc_front_hair_2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 334 B

BIN
assets/npc_front_hair_3.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 191 B

BIN
assets/npc_front_hat_1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 326 B

BIN
assets/npc_front_hat_2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 300 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 528 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 479 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 273 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 361 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 354 B

BIN
assets/npc_side_base_0.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 636 B

BIN
assets/npc_side_base_1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 639 B

BIN
assets/npc_side_eyes_0.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 199 B

BIN
assets/npc_side_eyes_1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 191 B

BIN
assets/npc_side_eyes_2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 176 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 124 B

BIN
assets/npc_side_face_1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 257 B

BIN
assets/npc_side_face_2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 242 B

BIN
assets/npc_side_face_3.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 135 B

BIN
assets/npc_side_face_4.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 133 B

BIN
assets/npc_side_hair_1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 346 B

BIN
assets/npc_side_hair_2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 329 B

BIN
assets/npc_side_hair_3.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 235 B

BIN
assets/npc_side_hat_1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 321 B

BIN
assets/npc_side_hat_2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 328 B

BIN
assets/npc_side_shirt_0.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 448 B

BIN
assets/npc_side_shirt_1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 403 B

BIN
assets/npc_side_shoes_0.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 259 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 421 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 393 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 409 B

BIN
assets/outside_ambience.wav Normal file

Binary file not shown.

BIN
assets/path_corner.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 520 B

BIN
assets/path_middle.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 483 B

BIN
assets/path_middle_edge.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 453 B

BIN
assets/pool_table.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 846 B

BIN
assets/poster.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

BIN
assets/rug0.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 634 B

BIN
assets/rug1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

BIN
assets/saloon_ext.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.0 KiB

BIN
assets/saloon_int.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.2 KiB

BIN
assets/saloon_outside.wav Normal file

Binary file not shown.

BIN
assets/skull.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 555 B

BIN
assets/table.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1012 B

BIN
assets/tile_detail_0.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 208 B

BIN
assets/tile_detail_1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 329 B

BIN
assets/tile_detail_2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 358 B

BIN
assets/tile_detail_3.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 351 B

BIN
assets/tile_detail_4.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 223 B

BIN
assets/tile_detail_5.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 368 B

BIN
assets/tile_detail_6.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 317 B

BIN
assets/tile_dirt_0.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 462 B

BIN
assets/tile_dirt_1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 494 B

View File

@@ -1,7 +1,7 @@
#if !defined(LD_CORE_ARENA_H_)
#define LD_CORE_ARENA_H_
#define AlignUp(x, a) (((x) + ~((a) - 1)) & ~((a) - 1))
#define AlignUp(x, a) (((x) + ((a) - 1)) & ~((a) - 1))
#define AlignDown(x, a) (((x)) & ~((a) - 1))
#define KB(x) ((U64) (x) << 10)
@@ -64,8 +64,8 @@ function void *_M_ArenaPush(M_Arena *arena, U64 esize, M_ArenaPushOpts *opts)
function void *_M_ArenaPushCopy(M_Arena *arena, void *src, U64 esize, M_ArenaPushOpts *opts);
#define M_ArenaAlloc(limit, ...) _M_ArenaAlloc(limit, &(M_ArenaOpts) { .initial = MB(1), .increment = KB(64), ##__VA_ARGS__ })
#define M_ArenaPush(arena, T, ...) (T *) _M_ArenaPush(arena, sizeof(T), &(M_ArenaOpts) { .count = 1, .align = Alignof(T), ##__VA_ARGS__ })
#define M_ArenaPushCopy(arena, T, src, ...) (T *) _M_ArenaPush(arena, src, sizeof(T), &(M_ArenaOpts) { .count = 1, .align = Alignof(T), ##__VA_ARGS__ })
#define M_ArenaPush(arena, T, ...) (T *) _M_ArenaPush(arena, sizeof(T), &(M_ArenaPushOpts) { .count = 1, .align = Alignof(T), ##__VA_ARGS__ })
#define M_ArenaPushCopy(arena, T, src, ...) (T *) _M_ArenaPush(arena, src, sizeof(T), &(M_ArenaPushOpts) { .count = 1, .align = Alignof(T), ##__VA_ARGS__ })
function void M_ArenaReset(M_Arena *arena);
function void M_ArenaRelease(M_Arena *arena);

View File

@@ -1 +1,3 @@
#include "impl/arena.c"
#include "impl/string.c"
#include "impl/math.c"

View File

@@ -5,5 +5,7 @@
#include "platform.h"
#include "macros.h"
#include "arena.h"
#include "string.h"
#include "math.h"
#endif // LD_CORE_CORE_H_

238
code/core/impl/math.c Normal file
View File

@@ -0,0 +1,238 @@
#include <math.h>
V2f V2F(F32 x, F32 y) {
V2f result = { x, y };
return result;
}
function V2f V2f_Scale(V2f x, F32 scale) {
return V2F(x.x * scale, x.y * scale);
}
V2f NormaliseV2F(V2f x) {
F32 magnitude = sqrtf((x.x * x.x) + (x.y * x.y));
if(magnitude > 0.0){
F32 inverse = 1.0f/magnitude;
return V2F(x.x*inverse, x.y*inverse);
}
return x;
}
V3f V3F(F32 x, F32 y, F32 z) {
V3f result = { x, y, z };
return result;
}
V4f V4F(F32 x, F32 y, F32 z, F32 w) {
V4f result = { x, y, z, w };
return result;
}
R2f R2F(V2f min, V2f max) {
R2f result = { min, max };
return result;
}
V3f V3f_Neg(V3f x) {
V3f result = { -x.x, -x.y, -x.z };
return result;
}
V3f V3f_Scale(V3f x, F32 s) {
V3f result = { s * x.x, s * x.y, s * x.z };
return result;
}
V3f V3f_Sub(V3f a, V3f b) {
V3f result = { a.x - b.x, a.y - b.y, a.z - b.z };
return result;
}
F32 V2f_Dot(V2f a, V2f b) {
F32 result = (a.x * b.x) + (a.y * b.y);
return result;
}
F32 V3f_Dot(V3f a, V3f b) {
F32 result = (a.x * b.x) + (a.y * b.y) + (a.z * b.z);
return result;
}
F32 V4f_Dot(V4f a, V4f b) {
F32 result = (a.x * b.x) + (a.y * b.y) + (a.z * b.z) + (a.w * b.w);
return result;
}
Mat4x4F M4x4F_Rows(V3f x, V3f y, V3f z) {
Mat4x4F result = {
x.x, x.y, x.z, 0,
y.x, y.y, y.z, 0,
z.x, z.y, z.z, 0,
0, 0, 0, 1
};
return result;
}
Mat4x4F M4x4F_Columns(V3f x, V3f y, V3f z) {
Mat4x4F result = {
x.x, y.x, z.x, 0,
x.y, y.y, z.y, 0,
x.z, y.z, z.z, 0,
0, 0, 0, 1
};
return result;
}
Mat4x4F M4x4F_Mul(Mat4x4F a, Mat4x4F b) {
Mat4x4F result;
for (U32 r = 0; r < 4; ++r) {
for (U32 c = 0; c < 4; ++c) {
result.m[r][c] =
(a.m[r][0] * b.m[0][c]) + (a.m[r][1] * b.m[1][c]) +
(a.m[r][2] * b.m[2][c]) + (a.m[r][3] * b.m[3][c]);
}
}
return result;
}
V4f M4x4F_VMul4(Mat4x4F m, V4f v) {
V4f result;
result.x = V4f_Dot(m.r[0], v);
result.y = V4f_Dot(m.r[1], v);
result.z = V4f_Dot(m.r[2], v);
result.w = V4f_Dot(m.r[3], v);
return result;
}
V3f M4x4F_VMul3(Mat4x4F m, V3f v) {
V4f tx;
tx.xyz = v;
tx.w = 1.0f;
V3f result = M4x4F_VMul4(m, tx).xyz;
return result;
}
Mat4x4FInv M4x4F_Perspective(F32 fov, F32 aspect, F32 nearp, F32 farp) {
F32 focal_length = 1.0f / tanf(0.5f * (PI_F32 * (fov / 360.0f)));
F32 a = focal_length;
F32 b = focal_length * aspect;
F32 c = -(nearp + farp) / (farp - nearp);
F32 d = -(2.0f * nearp * farp) / (farp - nearp);
Mat4x4FInv result = {
// fwd
{
a, 0, 0, 0,
0, b, 0, 0,
0, 0, c, d,
0, 0, -1, 0
},
// inv
{
(1 / a), 0, 0, 0,
0, (1 / b), 0, 0,
0, 0, 0, -1,
0, 0, (1/ d), (c / d)
}
};
return result;
}
Mat4x4FInv M4x4F_CameraView(V3f x, V3f y, V3f z, V3f p) {
Mat4x4FInv result;
// Construct orthonomal basis from axes
//
result.fwd = M4x4F_Rows(x, y, z);
V3f txp = V3f_Neg(M4x4F_VMul3(result.fwd, p));
// Translate by txp
//
result.fwd.r[0].w += txp.x;
result.fwd.r[1].w += txp.y;
result.fwd.r[2].w += txp.z;
// Calculate inverse axes
//
V3f ix = V3f_Scale(x, 1.0f / V3f_Dot(x, x));
V3f iy = V3f_Scale(y, 1.0f / V3f_Dot(y, y));
V3f iz = V3f_Scale(z, 1.0f / V3f_Dot(z, z));
// Calculate inverse position
//
V3f ip;
ip.x = (txp.x * ix.x) + (txp.y * iy.x) + (txp.z * iz.x);
ip.y = (txp.x * ix.y) + (txp.y * iy.y) + (txp.z * iz.y);
ip.z = (txp.x * ix.z) + (txp.y * iy.z) + (txp.z * iz.z);
result.inv = M4x4F_Columns(ix, iy, iz);
// Translate by ip
//
result.inv.r[0].w -= ip.x;
result.inv.r[1].w -= ip.y;
result.inv.r[2].w -= ip.z;
return result;
}
// Random
Random Random_Seed(U64 seed) {
Random result = { seed };
return result;
}
U64 Random_Next(Random *rnd) {
U64 result = rnd->state;
result ^= (result << 13);
result ^= (result >> 7);
result ^= (result << 17);
rnd->state = result;
return result;
}
F32 Random_F32(Random *rnd, F32 min, F32 max) {
F32 result = min + (Random_Unilateral(rnd) * (max - min));
return result;
}
F64 Random_F64(Random *rnd, F64 min, F64 max) {
F64 result = min + (Random_Unilateral(rnd) * (max - min));
return result;
}
U32 Random_U32(Random *rnd, U32 min, U32 max) {
U32 result = min + (U32) (Random_Unilateral(rnd) * (max - min));
return result;
}
F32 Random_Unilateral(Random *rnd) {
F32 result = Random_Next(rnd) / (F32) U64_MAX;
return result;
}
F32 Random_Bilateral(Random *rnd) {
F32 result = -1.0f + (2.0f * Random_Unilateral(rnd));
return result;
}
V2f V2f_Clip(V2f screen_xy, V2f screen_size) {
V2f result;
result.x = ((screen_xy.x / screen_size.w) * 2.0f) - 1.0f;
result.y = ((screen_xy.y / screen_size.h) * 2.0f) - 1.0f;
return result;
}

164
code/core/impl/string.c Normal file
View File

@@ -0,0 +1,164 @@
Str8 Str8_Wrap(S64 count, U8 *data) {
Str8 result;
result.data = data;
result.count = count;
return result;
}
Str8 Str8_WrapRange(U8 *start, U8 *end) {
Str8 result;
result.data = start;
result.count = cast(S64) (end - start);
return result;
}
internal S64 Str8_CountZ(U8 *data) {
S64 result = 0;
while (data[result] != 0) { result += 1; }
return result;
}
Str8 Str8_WrapZ(U8 *data) {
Str8 result;
result.data = data;
result.count = Str8_CountZ(data);
return result;
}
#define FNV_OFFSET_BIAS ((U64) 0xCBF29CE484222325)
#define FNV_PRIME ((U64) 0x100000001B3)
U64 Str8_Hash(Str8 v) {
U64 result = FNV_OFFSET_BIAS;
for (S64 it = 0; it < v.count; ++it) {
result ^= v.data[it];
result *= FNV_PRIME;
}
return result;
}
Str8 Str8_Copy(M_Arena *arena, Str8 s) {
Str8 result;
result.count = s.count;
result.data = M_ArenaPush(arena, U8, .count = s.count + 1);
M_CopySize(result.data, s.data, s.count);
return result;
}
Str8 Str8_Format(M_Arena *arena, const char *format, ...) {
va_list args;
va_start(args, format);
Str8 result = Str8_FormatArgs(arena, format, args);
va_end(args);
return result;
}
internal S64 Str8_ProcessFormat(Str8 out, const char *format, va_list args) {
S64 result = vsnprintf((char *) out.data, (int) out.count, format, args);
return result;
}
Str8 Str8_FormatArgs(M_Arena *arena, const char *format, va_list args) {
Str8 result;
va_list copy;
va_copy(copy, args);
U64 offset = M_ArenaOffset(arena);
result.count = KB(1);
result.data = M_ArenaPush(arena, U8, .count = result.count);
S64 needed = Str8_ProcessFormat(result, format, args);
if (needed >= result.count) {
M_ArenaPop(arena, offset);
result.count = needed;
result.data = M_ArenaPush(arena, U8, .count = result.count + 1);
Str8_ProcessFormat(result, format, copy);
}
else {
U64 size = result.count - needed - 1;
M_ArenaPopSize(arena, size);
result.count = needed;
}
return result;
}
B32 Str8_Equal(Str8 a, Str8 b, Str8_EqualFlags flags) {
B32 result = (a.count == b.count);
if (result) {
B32 ignore_case = (flags & STR8_EQUAL_IGNORE_CASE) != 0;
for (S64 it = 0; it < a.count; ++it) {
U8 ac = ignore_case ? Chr_ToLowercase(a.data[it]) : a.data[it];
U8 bc = ignore_case ? Chr_ToLowercase(b.data[it]) : b.data[it];
if (ac != bc) {
result = false;
break;
}
}
}
return result;
}
Str8 Str8_Prefix(Str8 s, S64 count) {
Str8 result;
result.data = s.data;
result.count = Min(s.count, count);
return result;
}
Str8 Str8_Suffix(Str8 s, S64 count) {
Str8 result;
result.count = Min(s.count, count);
result.data = s.data + (s.count - result.count);
return result;
}
Str8 Str8_RemoveAfterLast(Str8 s, U8 c) {
Str8 result;
result.data = s.data;
result.count = s.count;
for (S64 it = s.count - 1; it >= 0; --it) {
if (result.data[it] == c) {
result.count = it;
break;
}
}
return result;
}
B32 Str8_EndsWith(Str8 s, Str8 suffix) {
B32 result = Str8_Equal(Str8_Suffix(s, suffix.count), suffix, 0);
return result;
}
U8 Chr_ToUppercase(U8 c) {
U8 result = (c >= 'a' && c <= 'z') ? (c - ('a' - 'A')) : c;
return result;
}
U8 Chr_ToLowercase(U8 c) {
U8 result = (c >= 'A' && c <= 'Z') ? (c + ('a' - 'A')) : c;
return result;
}

View File

@@ -4,6 +4,7 @@
#include <assert.h>
#define Assert(exp) assert(exp)
#define StaticAssert(exp) static_assert(exp, #exp)
#define ArraySize(x) (sizeof(x) / sizeof((x)[0]))
#define Min(a, b) ((a) < (b) ? (a) : (b))
@@ -34,6 +35,13 @@
#define SLL_PushN(h, n, next) ((n)->next = (h), (h) = (n))
#define SLL_PopN(h, next) (((h) != 0) ? (h) = (h)->next : 0)
#define SLL_Enqueue(h, t, n) SLL_EnqueueN(h, t, n, next)
#define SLL_EnqueueFront(h, t, n) SLL_EnqueueFrontN(h, t, n, next)
#define SLL_Dequeue(h, t) SLL_DequeueN(h, t, next)
#define SLL_Push(h, n) SLL_PushN(h, n, next)
#define SLL_Pop(h) (((h) != 0) ? (h) = (h)->next : 0)
#define function static
#define internal static
#define global_var static
@@ -45,14 +53,4 @@
#define thread_var __thread
#endif
#define S(x) Str8_Wrap(sizeof(x) - sizeof(*(x)), (U8 *) (x))
Str8 Str8_Wrap(S64 count, U8 *data) {
Str8 result;
result.data = data;
result.count = count;
return result;
}
#define Sv(x) (int) (x).count, (x).data
#endif // LD_CORE_MACROS_H_

153
code/core/math.h Normal file
View File

@@ -0,0 +1,153 @@
#if !defined(LD_CORE_MATH_H_)
#define LD_CORE_MATH_H_
#define PI_F32 (3.14159265358979323846264338f)
#define TAU_F32 (2.0f * PI_F32)
#define Abs(x) (((x) < 0 ? -(x) : (x)))
typedef struct Random Random;
struct Random {
U64 state;
};
typedef union V2f V2f;
union V2f {
struct {
F32 x, y;
};
struct {
F32 u, v;
};
struct {
F32 w, h;
};
F32 e[2];
};
typedef union V2i V2i;
union V2i {
struct {
U32 x, y;
};
struct {
U32 w, h;
};
U32 e[2];
};
typedef union V3f V3f;
union V3f {
struct {
F32 x, y, z;
};
struct {
F32 r, g, b;
};
struct {
F32 w, h, d;
};
struct {
V2f xy;
F32 _z;
};
F32 e[3];
};
typedef union V4f V4f;
union V4f {
struct {
F32 x, y, z, w;
};
struct {
F32 r, g, b, a;
};
struct {
V3f xyz;
F32 _w;
};
F32 e[4];
};
typedef union Mat4x4F Mat4x4F;
union Mat4x4F {
F32 m[4][4];
F32 e[16];
V4f r[4];
};
typedef struct Mat4x4FInv Mat4x4FInv;
struct Mat4x4FInv {
Mat4x4F fwd;
Mat4x4F inv;
};
typedef struct R2f R2f;
struct R2f {
V2f min;
V2f max;
};
typedef struct R3f R3f;
struct R3f {
V3f min;
V3f max;
};
function V2f V2F(F32 x, F32 y);
function V3f V3F(F32 x, F32 y, F32 z);
function V4f V4F(F32 x, F32 y, F32 z, F32 w);
function R2f R2F(V2f min, V2f max);
function V2f V2f_Scale(V2f x, F32 s);
function V3f V3f_Neg(V3f x);
function V3f V3f_Scale(V3f x, F32 s);
function V3f V3f_Sub(V3f a, V3f b);
function F32 V2f_Dot(V2f a, V2f b);
function F32 V3f_Dot(V3f a, V3f b);
function F32 V4f_Dot(V4f a, V4f b);
function Mat4x4F M4x4F_Rows(V3f x, V3f y, V3f z);
function Mat4x4F M4x4F_Columns(V3f x, V3f y, V3f z);
function V4f M4x4F_VMul4(Mat4x4F m, V4f v);
function V3f M4x4F_VMul3(Mat4x4F m, V3f v);
function Mat4x4FInv M4x4F_Perspective(F32 fov, F32 aspect, F32 nearp, F32 farp);
function Mat4x4FInv M4x4F_CameraView(V3f x, V3f y, V3f z, V3f p);
function V2f NormaliseV2F(V2f x);
function V2f V2f_Scale(V2f x, F32 scale);
// Random
function Random Random_Seed(U64 seed);
function U64 Random_Next(Random *rnd);
function F32 Random_F32(Random *rnd, F32 min, F32 max);
function F64 Random_F64(Random *rnd, F64 min, F64 max);
function U32 Random_U32(Random *rnd, U32 min, U32 max);
function F32 Random_Unilateral(Random *rnd);
function F32 Random_Bilateral(Random *rnd);
V2f V2f_Clip(V2f screen_xy, V2f screen_size);
#endif // LD_CORE_MATH_H_

View File

@@ -68,11 +68,17 @@
#if OS_WINDOWS
#define WIN32_LEAN_AND_MEAN 1
#include <windows.h>
#include <shlobj_core.h>
#pragma warning(disable : 4201)
#elif OS_LINUX
#include <sys/types.h>
#include <dlfcn.h>
#include <sys/mman.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <errno.h>
#include <dirent.h>
#endif
#endif // LD_CORE_PLATFORM_H_

39
code/core/string.h Normal file
View File

@@ -0,0 +1,39 @@
#if !defined(LD_CORE_STRING_H_)
#define LD_CORE_STRING_H_
#define S(x) Str8_Wrap(sizeof(x) - sizeof(*(x)), (U8 *) (x))
#define Sz(x) Str8_WrapZ((U8 *) (x))
#define Sl(x) { sizeof(x) - sizeof(*(x)), (U8 *) (x) }
#define Sv(x) (int) (x).count, (x).data
#define Sf(arena, fmt, ...) Str8_Format(arena, fmt, ##__VA_ARGS__)
function Str8 Str8_Wrap(S64 count, U8 *data);
function Str8 Str8_WrapRange(U8 *start, U8 *end);
function Str8 Str8_WrapZ(U8 *data);
function U64 Str8_Hash(Str8 v);
function Str8 Str8_Copy(M_Arena *arena, Str8 s);
function Str8 Str8_Format(M_Arena *arena, const char *format, ...);
function Str8 Str8_FormatArgs(M_Arena *arena, const char *format, va_list args);
typedef U32 Str8_EqualFlags;
enum {
STR8_EQUAL_IGNORE_CASE = (1 << 0)
};
function B32 Str8_Equal(Str8 a, Str8 b, Str8_EqualFlags flags);
function Str8 Str8_Prefix(Str8 s, S64 count);
function Str8 Str8_Suffix(Str8 s, S64 count);
function Str8 Str8_RemoveAfterLast(Str8 s, U8 c);
function B32 Str8_EndsWith(Str8 s, Str8 suffix);
function U8 Chr_ToUppercase(U8 c);
function U8 Chr_ToLowercase(U8 c);
#endif // LD_CORE_STRING_H_

View File

@@ -29,16 +29,12 @@ struct Str8 {
U8 *data;
};
typedef struct V2f V2f;
struct V2f {
F32 x;
F32 y;
};
#define U8_MAX ((U8) -1)
#define U16_MAX ((U16) -1)
#define U32_MAX ((U32) -1)
#define U64_MAX ((U64) -1)
typedef struct V2i V2i;
struct V2i {
U32 x;
U32 y;
};
#define F32_MAX ((F32) 3.40282346638528859811704183484516925e+038F)
#define F64_MAX ((F64) 1.79769313486231570814527423731704357e+308L)
#endif // LD_CORE_TYPES_H_

379
code/draw/core.c Normal file
View File

@@ -0,0 +1,379 @@
U32 D_ImageHandle(D_Context *draw, Str8 name) {
U32 result = 0;
U64 hash = Str8_Hash(name);
U64 index = hash & (D_ASSET_HASH_COUNT - 1);
D_AssetHash *lookup = draw->lookup[index];
while (lookup != 0) {
if (lookup->hash == hash && Str8_Equal(lookup->value, name, 0)) {
result = lookup->id;
break;
}
lookup = lookup->next;
}
return result;
}
void D_AnimationInit(D_Animation *a, U32 id, U32 rows, U32 cols, F32 time) {
a->id = id;
a->rows = rows;
a->cols = cols;
a->time = 0;
a->frame_time = time;
a->frame = V2F(1.0f / (F32) cols, 1.0f / (F32) rows);
a->index = 0;
}
R2f D_AnimationFrame(D_Animation *a) {
R2f result = { 0 };
U32 row = a->index / a->cols;
U32 col = a->index % a->cols;
result.min = V2F(a->frame.w * col, a->frame.h * row);
result.max = V2F(result.min.x + a->frame.w, result.min.y + a->frame.h);
return result;
}
void D_AnimationUpdate(D_Animation *a, F32 dt) {
a->time += dt;
if (a->time >= a->frame_time) {
a->time = 0;
a->index += 1;
if (a->index >= (a->rows * a->cols)) { a->index = 0; }
}
}
void D_Begin(D_Context *draw, Vk_Frame *frame, U32 max_rects) {
Vk_Buffer *rbo = &frame->rbo;
draw->rbo = rbo;
draw->n_rects = 0;
draw->max_rects = max_rects;
draw->rects = rbo->data;
}
void D_End(D_Context *draw, Vk_Frame *frame) {
VkCommandBuffer cmd = frame->cmd;
Vk_Pipeline *basic = &draw->pipelines[0];
// We can probably stop doing this at some point
VkDescriptorSet set;
VkDescriptorSetAllocateInfo alloc_info = { 0 };
alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
alloc_info.descriptorPool = frame->descriptors;
alloc_info.descriptorSetCount = 1;
alloc_info.pSetLayouts = &basic->layout.set;
vk.AllocateDescriptorSets(vk.device, &alloc_info, &set);
// 'update' the descriptor sets for binding
M_TempScope(0, 0) {
VkWriteDescriptorSet writes[2] = { 0 };
VkDescriptorBufferInfo rbo_info = { 0 };
rbo_info.buffer = draw->rbo->handle;
rbo_info.offset = 0;
rbo_info.range = VK_WHOLE_SIZE;
U32 total = draw->n_images + draw->n_fonts;
VkDescriptorImageInfo *image_info = M_ArenaPush(temp.arena, VkDescriptorImageInfo, .count = total);
for (U32 it = 0; it < draw->n_images; ++it) {
image_info[it].imageView = draw->images[it].image.view;
image_info[it].sampler = vk.sampler;
image_info[it].imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
}
U32 idx = draw->n_images;
for (D_Font *it = draw->fonts; it != 0; it = it->next) {
image_info[idx].imageView = it->image.view;
image_info[idx].sampler = vk.sampler; // @Todo: probably want linear filtering on fonts
image_info[idx].imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
idx += 1;
}
writes[0].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
writes[0].dstSet = set;
writes[0].dstBinding = 0;
writes[0].descriptorCount = 1;
writes[0].descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
writes[0].pBufferInfo = &rbo_info;
writes[1].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
writes[1].dstSet = set;
writes[1].dstBinding = 1;
writes[1].descriptorCount = total;
writes[1].descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
writes[1].pImageInfo = image_info;
vk.UpdateDescriptorSets(vk.device, ArraySize(writes), writes, 0, 0);
}
vk.CmdBindPipeline(cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, basic->handle);
vk.CmdBindDescriptorSets(cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, basic->layout.pipeline, 0, 1, &set, 0, 0);
vk.CmdPushConstants(cmd, basic->layout.pipeline, VK_SHADER_STAGE_VERTEX_BIT, 0, sizeof(Mat4x4F), &draw->camera->proj.fwd);
VkViewport viewport = { 0, 0, (F32) draw->window_width, (F32) draw->window_height, 0.0f, 1.0f };
VkRect2D scissor = { 0, 0, draw->window_width, draw->window_height };
vk.CmdSetViewport(cmd, 0, 1, &viewport);
vk.CmdSetScissor(cmd, 0, 1, &scissor);
vk.CmdDraw(cmd, 6, draw->n_rects, 0, 0);
}
internal U32 V4f_UnormColour(V4f c) {
// @Todo: SRGB handling
U32 result =
((U8) (255.0f * c.a)) << 24 |
((U8) (255.0f * c.r)) << 16 |
((U8) (255.0f * c.g)) << 8 |
((U8) (255.0f * c.b)) << 0;
return result;
}
void _D_Rect(D_Context *draw, D_RectOpts *opts) {
if (draw->n_rects < draw->max_rects) {
D_Rect *rect = &draw->rects[draw->n_rects];
rect->texture = opts->texture;
F32 w, h;
rect->x = opts->p.x;
rect->y = opts->p.y;
rect->uv[0] = opts->uv.min.x;
rect->uv[1] = opts->uv.min.y;
rect->uv[2] = opts->uv.max.x;
rect->uv[3] = opts->uv.max.y;
rect->angle = opts->angle;
if (opts->flags & D_RECT_PER_VERTEX_COLOUR) {
rect->c[0] = V4f_UnormColour(opts->vtxc[0]);
rect->c[1] = V4f_UnormColour(opts->vtxc[1]);
rect->c[2] = V4f_UnormColour(opts->vtxc[2]);
rect->c[3] = V4f_UnormColour(opts->vtxc[3]);
}
else {
U32 unorm = V4f_UnormColour(opts->c);
rect->c[0] = unorm;
rect->c[1] = unorm;
rect->c[2] = unorm;
rect->c[3] = unorm;
}
if (opts->flags & D_RECT_IGNORE_ASPECT) {
w = opts->dim.w;
h = opts->dim.h;
}
else {
Vk_Image *image = 0;
if (opts->texture >= draw->n_images) {
// @hack: first font texture
//
image = &draw->fonts->image;
}
else {
image = &draw->images[opts->texture].image;
}
F32 width = cast(F32) image->width;
F32 height = cast(F32) image->height;
if (opts->flags & D_RECT_UV_ASPECT) {
width *= (opts->uv.max.x - opts->uv.min.x);
height *= (opts->uv.max.y - opts->uv.min.y);
}
F32 aspect_w = (width > height) ? 1.0f : (width / height);
F32 aspect_h = (width > height) ? (height / width) : 1.0f;
w = opts->scale * aspect_w;
h = opts->scale * aspect_h;
}
if (opts->flags & D_RECT_FLIP_X) { w *= -1.0f; }
if (opts->flags & D_RECT_FLIP_Y) { h *= -1.0f; }
rect->w = w;
rect->h = h;
draw->n_rects += 1;
}
}
void D_Text(D_Context *draw, D_Font *font, Str8 text, F32 x, F32 y) {
F32 xoff = x;
// @Todo: control scale
F32 scale = 1.0f / (font->ascent - font->descent);
for (S64 it = 0; it < text.count; ++it) {
if (text.data[it] >= ' ' && text.data[it] <= '~') {
D_Glyph *glyph = &font->glyphs[text.data[it] - ' '];
F32 image_scale = scale * Max(glyph->dim.w, glyph->dim.h);
F32 advance = scale * glyph->advance;
V2f offset = V2f_Scale(glyph->offset, scale);
D_Rect(draw, xoff + offset.x, y + offset.y, .texture = font->id, .uv = glyph->box, .scale = image_scale, .flags = D_RECT_UV_ASPECT);
xoff += advance;
}
}
}
void D_FontLoad(D_Context *draw, Str8 name, F32 size) {
M_TempScope(0, 0) {
(void) draw;
Str8 exe_path = FS_SystemPath(temp.arena, FS_SYSTEM_PATH_EXE);
Str8 path = Sf(temp.arena, "%.*s/assets/%.*s.ttf", Sv(exe_path), Sv(name));
Str8 font_data = FS_ReadEntireFile(temp.arena, path);
stbtt_fontinfo info = { 0 };
stbtt_InitFont(&info, font_data.data, 0);
F32 scale = stbtt_ScaleForPixelHeight(&info, 256);
U32 w = 512;
U32 h = 512;
U8 *pixels = M_ArenaPush(temp.arena, U8, .count = (w * h));
stbtt_pack_context pack = { 0 };
stbtt_PackBegin(&pack, pixels, w, h, 0, 1, 0);
U32 count = '~' - ' ';
stbtt_packedchar *packed = M_ArenaPush(temp.arena, stbtt_packedchar, .count = count);
stbtt_PackFontRange(&pack, font_data.data, 0, size, ' ', count, packed);
D_Font *font = M_ArenaPush(draw->arena, D_Font);
S32 asc, desc, line;
stbtt_GetFontVMetrics(&info, &asc, &desc, &line);
font->line_advance = cast(F32) (scale * line);
font->ascent = cast(F32) (scale * asc);
font->descent = cast(F32) (scale * desc);
font->glyphs = M_ArenaPush(draw->arena, D_Glyph, .count = count);
for (U32 it = 0; it < count; ++it) {
D_Glyph *glyph = &font->glyphs[it];
stbtt_packedchar *chr = &packed[it];
S32 left, width;
stbtt_GetCodepointHMetrics(&info, ' ' + it, &width, &left);
glyph->box.min = V2F(chr->x0 / (F32) w, chr->y0 / (F32) h);
glyph->box.max = V2F(chr->x1 / (F32) w, chr->y1 / (F32) h);
glyph->advance = chr->xadvance;
glyph->dim.w = cast(F32) (chr->x1 - chr->x0);
glyph->dim.h = cast(F32) (chr->y1 - chr->y0);
glyph->offset.x = (0.5f * glyph->dim.w) + chr->xoff;
glyph->offset.y = (0.5f * glyph->dim.h) + chr->yoff;
}
Vk_Buffer *staging = &draw->staging;
U32 *px = (U32 *) staging->data;
for (U32 y = 0; y < h; ++y) {
for (U32 x = 0; x < w; ++x) {
*px++ = 0x0 | ((U32) pixels[(y * w) + x] << 24);
}
}
Vk_CommandBuffer *cmds = Vk_CommandBufferPush();
font->id = draw->n_images + draw->n_fonts;
font->image.width = w;
font->image.height = h;
font->image.format = VK_FORMAT_R8G8B8A8_SRGB;
font->image.usage = VK_IMAGE_USAGE_SAMPLED_BIT;
Vk_ImageCreate(&font->image);
VkBufferImageCopy copy = { 0 };
copy.bufferOffset = 0;
copy.bufferRowLength = 0;
copy.bufferImageHeight = 0;
copy.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
copy.imageSubresource.mipLevel = 0;
copy.imageSubresource.baseArrayLayer = 0;
copy.imageSubresource.layerCount = 1;
copy.imageExtent.width = w;
copy.imageExtent.height = h;
copy.imageExtent.depth = 1;
VkImageMemoryBarrier2 transfer = { 0 };
VkImageMemoryBarrier2 shader_read = { 0 };
transfer.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER_2;
transfer.srcStageMask = VK_PIPELINE_STAGE_2_NONE;
transfer.srcAccessMask = VK_ACCESS_2_NONE;
transfer.dstStageMask = VK_PIPELINE_STAGE_2_TRANSFER_BIT;
transfer.dstAccessMask = VK_ACCESS_2_TRANSFER_WRITE_BIT;
transfer.oldLayout = VK_IMAGE_LAYOUT_UNDEFINED;
transfer.newLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
transfer.image = font->image.handle;
transfer.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
transfer.subresourceRange.layerCount = 1;
transfer.subresourceRange.levelCount = 1;
shader_read.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER_2;
shader_read.srcStageMask = VK_PIPELINE_STAGE_2_TRANSFER_BIT;
shader_read.srcAccessMask = VK_ACCESS_2_TRANSFER_WRITE_BIT;
shader_read.dstStageMask = VK_PIPELINE_STAGE_2_FRAGMENT_SHADER_BIT;
shader_read.dstAccessMask = VK_ACCESS_2_SHADER_SAMPLED_READ_BIT;
shader_read.oldLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
shader_read.newLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
shader_read.image = font->image.handle;
shader_read.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
shader_read.subresourceRange.layerCount = 1;
shader_read.subresourceRange.levelCount = 1;
VkDependencyInfo dep = { 0 };
dep.sType = VK_STRUCTURE_TYPE_DEPENDENCY_INFO;
dep.imageMemoryBarrierCount = 1;
dep.pImageMemoryBarriers = &transfer;
vk.CmdPipelineBarrier2(cmds->handle, &dep);
vk.CmdCopyBufferToImage(cmds->handle, staging->handle, font->image.handle, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &copy);
dep.pImageMemoryBarriers = &shader_read;
vk.CmdPipelineBarrier2(cmds->handle, &dep);
Vk_CommandBufferSubmit(cmds, true);
SLL_PushN(draw->fonts, font, next);
draw->n_fonts += 1;
}
}

Some files were not shown because too many files have changed in this diff Show More