Merge remote-tracking branch 'origin'
This commit is contained in:
@@ -11,7 +11,7 @@ struct AABB {
|
||||
};
|
||||
|
||||
|
||||
function bool AABB_Collide(AABB a, AABB b);
|
||||
function bool AABB_Point(AABB a, V2f v);
|
||||
function bool AABB_Collide(AABB a, AABB b);
|
||||
function bool AABB_Point(AABB a, V2f v);
|
||||
|
||||
#endif // LD_GAME_AABB_H_
|
||||
|
||||
198
code/game/core.c
Normal file
198
code/game/core.c
Normal file
@@ -0,0 +1,198 @@
|
||||
void G_ImagesLoad(G_State *game) {
|
||||
M_TempScope(0, 0) {
|
||||
Str8 exe_path = FS_SystemPath(temp.arena, FS_SYSTEM_PATH_EXE);
|
||||
Str8 path = Sf(temp.arena, "%.*s/assets", Sv(exe_path));
|
||||
|
||||
FS_List assets = FS_PathList(temp.arena, path);
|
||||
|
||||
Vk_Buffer staging = { 0 };
|
||||
staging.size = MB(256);
|
||||
staging.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT;
|
||||
staging.host_visible = true;
|
||||
|
||||
Vk_BufferCreate(&staging);
|
||||
|
||||
U8 *base = staging.data;
|
||||
U64 offset = 0;
|
||||
|
||||
Vk_CommandBuffer *cmds = Vk_CommandBufferPush();
|
||||
|
||||
for (FS_Entry *it = assets.first; it != 0; it = it->next) {
|
||||
if (Str8_EndsWith(it->basename, S("png"))) {
|
||||
game->n_images += 1;
|
||||
}
|
||||
}
|
||||
|
||||
VkBufferImageCopy copy = { 0 };
|
||||
game->images = M_ArenaPush(game->arena, G_Image, .count = game->n_images);
|
||||
game->n_images = 0;
|
||||
|
||||
// Image upload is sbi_load -> copy to staging -> upload to gpu texture
|
||||
|
||||
for (FS_Entry *it = assets.first; it != 0; it = it->next) {
|
||||
if (Str8_EndsWith(it->basename, S("png"))) {
|
||||
S32 w, h, c;
|
||||
stbi_uc *data = stbi_load((const char *) it->path.data, &w, &h, &c, 4);
|
||||
|
||||
if (data) {
|
||||
G_Image *image = &game->images[game->n_images];
|
||||
|
||||
U64 image_sz = 4 * w * h;
|
||||
|
||||
M_CopySize(base, data, image_sz);
|
||||
|
||||
copy.bufferOffset = offset;
|
||||
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;
|
||||
|
||||
base += image_sz;
|
||||
offset += image_sz;
|
||||
|
||||
Assert(offset <= staging.size);
|
||||
|
||||
game->n_images += 1;
|
||||
|
||||
image->name = Str8_Copy(game->arena, Str8_RemoveAfterLast(it->basename, '.'));
|
||||
|
||||
printf("[Info] :: Loaded %.*s from %.*s\n", Sv(image->name), Sv(it->basename));
|
||||
|
||||
image->image.width = w;
|
||||
image->image.height = h;
|
||||
|
||||
image->image.format = VK_FORMAT_R8G8B8A8_SRGB;
|
||||
image->image.usage = VK_IMAGE_USAGE_SAMPLED_BIT;
|
||||
|
||||
Vk_ImageCreate(&image->image);
|
||||
|
||||
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 = image->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 = image->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, image->image.handle, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, ©);
|
||||
|
||||
dep.pImageMemoryBarriers = &shader_read;
|
||||
|
||||
vk.CmdPipelineBarrier2(cmds->handle, &dep);
|
||||
|
||||
stbi_image_free(data);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Vk_CommandBufferSubmit(cmds, true /* wait */);
|
||||
}
|
||||
}
|
||||
|
||||
void G_PipelinesLoad(G_State *game) {
|
||||
game->pipelines = M_ArenaPush(game->arena, Vk_Pipeline, .count = 1);
|
||||
|
||||
Vk_Pipeline *basic = &game->pipelines[0];
|
||||
|
||||
VkShaderModule vshader = 0, fshader = 0;
|
||||
M_TempScope(0, 0) {
|
||||
Str8 exe_path = FS_SystemPath(temp.arena, FS_SYSTEM_PATH_EXE);
|
||||
Str8 vshader_code = FS_ReadEntireFile(temp.arena, Sf(temp.arena, "%.*s/assets/shaders/basic.vert.spv", Sv(exe_path)));
|
||||
Str8 fshader_code = FS_ReadEntireFile(temp.arena, Sf(temp.arena, "%.*s/assets/shaders/basic.frag.spv", Sv(exe_path)));
|
||||
|
||||
VkShaderModuleCreateInfo create_info = { 0 };
|
||||
create_info.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO;
|
||||
create_info.pCode = (U32 *) vshader_code.data;
|
||||
create_info.codeSize = vshader_code.count;
|
||||
|
||||
vk.CreateShaderModule(vk.device, &create_info, 0, &vshader);
|
||||
|
||||
create_info.pCode = (U32 *) fshader_code.data;
|
||||
create_info.codeSize = fshader_code.count;
|
||||
|
||||
vk.CreateShaderModule(vk.device, &create_info, 0, &fshader);
|
||||
}
|
||||
|
||||
// Create pipeline layout, its insane what you have to do for this because the ALREADY KNOW
|
||||
// all of this information
|
||||
{
|
||||
VkDescriptorSetLayoutBinding bindings[2] = { 0 };
|
||||
|
||||
bindings[0].binding = 0;
|
||||
bindings[0].descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
|
||||
bindings[0].descriptorCount = 1;
|
||||
bindings[0].stageFlags = VK_SHADER_STAGE_VERTEX_BIT;
|
||||
|
||||
bindings[1].binding = 1;
|
||||
bindings[1].descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
|
||||
bindings[1].descriptorCount = 1;
|
||||
bindings[1].stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT;
|
||||
|
||||
VkDescriptorSetLayoutCreateInfo set_info = { 0 };
|
||||
set_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
|
||||
set_info.bindingCount = 2;
|
||||
set_info.pBindings = bindings;
|
||||
|
||||
vk.CreateDescriptorSetLayout(vk.device, &set_info, 0, &basic->layout.set);
|
||||
|
||||
VkPipelineLayoutCreateInfo layout_create = { 0 };
|
||||
layout_create.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
|
||||
layout_create.setLayoutCount = 1;
|
||||
layout_create.pSetLayouts = &basic->layout.set;
|
||||
|
||||
vk.CreatePipelineLayout(vk.device, &layout_create, 0, &basic->layout.pipeline);
|
||||
}
|
||||
|
||||
basic->targets.items[0] = vk.swapchain.format.format;
|
||||
basic->targets.count = 1;
|
||||
|
||||
basic->shaders.count = 2;
|
||||
|
||||
basic->shaders.items[0].stage = VK_SHADER_STAGE_VERTEX_BIT;
|
||||
basic->shaders.items[0].handle = vshader;
|
||||
|
||||
basic->shaders.items[1].stage = VK_SHADER_STAGE_FRAGMENT_BIT;
|
||||
basic->shaders.items[1].handle = fshader;
|
||||
|
||||
Vk_PipelineCreate(basic);
|
||||
}
|
||||
|
||||
#include "impl/aabb.c"
|
||||
#include "impl/nav.c"
|
||||
#include "impl/player.c"
|
||||
40
code/game/core.h
Normal file
40
code/game/core.h
Normal file
@@ -0,0 +1,40 @@
|
||||
#if !defined(LD_GAME_CORE_H_)
|
||||
#define LD_GAME_CORE_H_
|
||||
|
||||
typedef struct G_Vertex G_Vertex;
|
||||
struct G_Vertex {
|
||||
F32 x, y, z, w;
|
||||
F32 u, v;
|
||||
U32 c;
|
||||
U32 pad;
|
||||
};
|
||||
|
||||
typedef struct G_Image G_Image;
|
||||
struct G_Image {
|
||||
Str8 name;
|
||||
Vk_Image image;
|
||||
};
|
||||
|
||||
typedef struct G_State G_State;
|
||||
struct G_State {
|
||||
M_Arena *arena;
|
||||
|
||||
U32 n_images;
|
||||
G_Image *images;
|
||||
|
||||
U32 n_pipelines;
|
||||
Vk_Pipeline *pipelines;
|
||||
|
||||
Vk_Buffer vbo;
|
||||
};
|
||||
|
||||
function void G_ImagesLoad(G_State *game);
|
||||
function void G_PipelinesLoad(G_State *game);
|
||||
|
||||
#include "aabb.h"
|
||||
#include "player.h"
|
||||
#include "nav.h"
|
||||
#include "npc.h"
|
||||
#include "world.h"
|
||||
|
||||
#endif // LD_GAME_CORE_H_
|
||||
@@ -1,5 +1,5 @@
|
||||
#include "../aabb.h"
|
||||
#include "../types.h"
|
||||
#include "game/aabb.h"
|
||||
#include "core/types.h"
|
||||
|
||||
bool AABB_Collide(AABB a, AABB b) {
|
||||
bool collision_x = a.pos.x + a.size.x >= b.pos.x && b.pos.x + b.size.x >= a.pos.x;
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#include "../nav.h"
|
||||
#include "../../core/types.h"
|
||||
#include "game/nav.h"
|
||||
#include "core/types.h"
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#define MAX_UNFINISHED 128
|
||||
@@ -14,16 +15,16 @@ struct navSearchNodeState{
|
||||
|
||||
typedef struct navSearchState navSearchState;
|
||||
struct navSearchState{
|
||||
navSearchNodeState nodeStates[NAV_MAX_NODES];
|
||||
navSearchNodeState nodeStates[NAV_MAX_NODES];
|
||||
};
|
||||
|
||||
navSearchState initState(U32 start, U32 meshSize) {
|
||||
navSearchState state = {};
|
||||
for(int i = 0; i < meshSize; i++) {
|
||||
for(U32 i = 0; i < meshSize; i++) {
|
||||
state.nodeStates[i].visited = false;
|
||||
state.nodeStates[i].addedToUnvisited = false;
|
||||
// underflow to the max :)
|
||||
state.nodeStates[i].distance = -1;
|
||||
// underflow to the max :)
|
||||
state.nodeStates[i].distance = U64_MAX;
|
||||
state.nodeStates[i].shortest = 0;
|
||||
}
|
||||
state.nodeStates[start].distance = 0;
|
||||
@@ -31,10 +32,10 @@ navSearchState initState(U32 start, U32 meshSize) {
|
||||
}
|
||||
|
||||
U32 getLowestState(U32 unfinishedIndexes[128], U32 unfinishedCount, navSearchState state, U32 *offset) {
|
||||
U32 lowest = -1;
|
||||
U32 lowestI = -1;
|
||||
U32 lowest = U32_MAX;
|
||||
U32 lowestI = U32_MAX;
|
||||
bool startFound = false;
|
||||
for(int i = *offset; i < unfinishedCount; i++) {
|
||||
for(U32 i = *offset; i < unfinishedCount; i++) {
|
||||
navSearchNodeState checkNode = state.nodeStates[unfinishedIndexes[i]];
|
||||
if(checkNode.visited) {
|
||||
if(!startFound) {
|
||||
@@ -44,7 +45,7 @@ U32 getLowestState(U32 unfinishedIndexes[128], U32 unfinishedCount, navSearchSta
|
||||
}
|
||||
startFound = true;
|
||||
if (lowest > checkNode.distance) {
|
||||
lowest = checkNode.distance;
|
||||
lowest = cast(U32) checkNode.distance;
|
||||
lowestI = unfinishedIndexes[i];
|
||||
}
|
||||
}
|
||||
@@ -60,7 +61,7 @@ NavPath Nav_Path(NavMesh mesh, U32 start, U32 end) {
|
||||
// the unfinished nodes, so when checking for a lowest
|
||||
// if I find the first N items have been checked, I'll mark
|
||||
// an offset to skip the first N items.
|
||||
U32 unfinishedOffset = 0;
|
||||
U32 unfinishedOffset = 0;
|
||||
U32 lowestNodeIndex = start;
|
||||
bool found = false;
|
||||
while(!found) {
|
||||
@@ -68,11 +69,11 @@ NavPath Nav_Path(NavMesh mesh, U32 start, U32 end) {
|
||||
NavConnection connection = mesh.nodes[lowestNodeIndex].connections[connectionI];
|
||||
navSearchNodeState *testNode = &state.nodeStates[connection.NodeIndex];
|
||||
if(testNode->visited) {continue;}
|
||||
U32 distance = state.nodeStates[lowestNodeIndex].distance + connection.Cost;
|
||||
distance += mesh.nodes[end].pos.x - mesh.nodes[connection.NodeIndex].pos.x;
|
||||
distance += mesh.nodes[end].pos.y - mesh.nodes[connection.NodeIndex].pos.y;
|
||||
U32 distance = cast(U32) (state.nodeStates[lowestNodeIndex].distance + connection.Cost);
|
||||
distance += cast(U32) (mesh.nodes[end].pos.x - mesh.nodes[connection.NodeIndex].pos.x);
|
||||
distance += cast(U32) (mesh.nodes[end].pos.y - mesh.nodes[connection.NodeIndex].pos.y);
|
||||
if(testNode->distance > distance) {
|
||||
testNode->distance = distance;
|
||||
testNode->distance = distance;
|
||||
testNode->shortest = lowestNodeIndex;
|
||||
}
|
||||
if(!testNode->addedToUnvisited) {
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
#include "../npc.h"
|
||||
#include "../world.h"
|
||||
#include "../../core/types.h"
|
||||
#include "nav.c"
|
||||
#include <stdio.h>
|
||||
|
||||
void updateNPC(F32 delta, NPC *npc, World *world) {
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
#if !defined(LD_GAME_NAV_H_)
|
||||
#define LD_GAME_NAV_H_
|
||||
|
||||
#include "../core/types.h"
|
||||
#include "../core/macros.h"
|
||||
#include "core/types.h"
|
||||
#include "core/macros.h"
|
||||
|
||||
#define NAV_MAX_PATH 1024
|
||||
#define NAV_MAX_CONNECTIONS 8
|
||||
|
||||
@@ -1,7 +1,11 @@
|
||||
#if !defined(LD_GAME_PLAYER_H_)
|
||||
#define LD_GAME_PLAYER_H_
|
||||
|
||||
#include "../core/types.h"
|
||||
#include <SDL3/SDL_events.h>
|
||||
#include "../core/macros.h"
|
||||
|
||||
#include <SDL3/SDL_events.h>
|
||||
|
||||
typedef struct Player Player;
|
||||
struct Player
|
||||
{
|
||||
@@ -9,3 +13,5 @@ struct Player
|
||||
};
|
||||
|
||||
function void PlayerUpdate(SDL_Event *event, Player *player);
|
||||
|
||||
#endif // LD_GAME_PLAYER_H_
|
||||
|
||||
Reference in New Issue
Block a user