From b83078553e8db053c2925e3dd32bd4b8830ba95f Mon Sep 17 00:00:00 2001 From: kotofyt Date: Wed, 28 May 2025 14:36:57 +0300 Subject: [PATCH] added mesh rendering --- .gitmodules | 3 + build.c | 14 +- engine/__build.c | 34 +- engine/baseentity.cpp | 7 + engine/brush.cpp | 18 +- engine/cl_light.cpp | 60 ++- engine/cl_worldspawn.cpp | 2 +- engine/client.cpp | 1 + engine/engine.cpp | 15 +- engine/filesystem.cpp | 2 +- engine/server.cpp | 10 +- engine/sv_light.cpp | 16 +- engine/sv_worldspawn.cpp | 1 + engine/vk_brush.cpp | 137 ++----- engine/vk_helper.h | 68 ++-- engine/vk_mesh.cpp | 354 ++++++++++++++++++ engine/vk_postprocessing.cpp | 0 engine/vk_shading.cpp | 0 engine/vk_video.cpp | 63 +++- engine/vk_videolinux.cpp | 20 +- engine/vk_videosdl.cpp | 424 ++++++++++++++++++++++ external/SDL | 1 + fpc/build.sh | 0 fpc/main.cpp | 0 funnyassets/__build.c | 7 +- funnyassets/_rtt/gfx/mesh_frag.spv | Bin 0 -> 1396 bytes funnyassets/_rtt/gfx/mesh_vert.spv | Bin 0 -> 2776 bytes funnyassets/_rtt/maps/test_map.fmap | Bin 6290 -> 6290 bytes funnyassets/gfx_shaders/mesh_frag.slang | 23 ++ funnyassets/gfx_shaders/mesh_shared.slang | 15 + funnyassets/gfx_shaders/mesh_vert.slang | 24 ++ funnyassets/maps/test_map.fmap | Bin 6290 -> 6290 bytes funnyassets/raw_maps/dust.map | 186 +++++----- game/client/__build.c | 35 ++ game/client/baseplayer.cpp | 32 ++ game/{ => server}/__build.c | 13 +- game/{ => server}/baseplayer.cpp | 0 game/{ => server}/game.cpp | 3 +- launcher/launcher.cpp | 10 +- public/baseentity.h | 17 +- public/console.h | 4 +- public/engine.h | 5 +- public/filesystem.h | 1 + public/level.h | 2 +- public/physics_gen.h | 2 + public/rendering.h | 68 +++- public/tier0/platform.h | 11 + public/tier1/utlvector.h | 2 +- rapier/__build.c | 10 +- rapier/px.rs | 13 +- src/main.rs | 3 - tier0/__build.c | 9 +- tier0/platform.cpp | 54 ++- 53 files changed, 1436 insertions(+), 363 deletions(-) create mode 100644 engine/client.cpp create mode 100644 engine/vk_mesh.cpp create mode 100644 engine/vk_postprocessing.cpp create mode 100644 engine/vk_shading.cpp create mode 100644 engine/vk_videosdl.cpp create mode 160000 external/SDL create mode 100644 fpc/build.sh create mode 100644 fpc/main.cpp create mode 100644 funnyassets/_rtt/gfx/mesh_frag.spv create mode 100644 funnyassets/_rtt/gfx/mesh_vert.spv create mode 100644 funnyassets/gfx_shaders/mesh_frag.slang create mode 100644 funnyassets/gfx_shaders/mesh_shared.slang create mode 100644 funnyassets/gfx_shaders/mesh_vert.slang create mode 100644 game/client/__build.c create mode 100644 game/client/baseplayer.cpp rename game/{ => server}/__build.c (79%) rename game/{ => server}/baseplayer.cpp (100%) rename game/{ => server}/game.cpp (71%) delete mode 100644 src/main.rs diff --git a/.gitmodules b/.gitmodules index b8e4e86..abcc806 100644 --- a/.gitmodules +++ b/.gitmodules @@ -10,3 +10,6 @@ [submodule "external/stb"] path = external/stb url = https://github.com/nothings/stb.git +[submodule "external/SDL"] + path = external/SDL + url = https://github.com/libsdl-org/SDL.git diff --git a/build.c b/build.c index 2605791..aafbd1a 100644 --- a/build.c +++ b/build.c @@ -18,15 +18,15 @@ char* include_dirs[] = { #include "fgui/__build.c" #include "rapier/__build.c" #include "engine/__build.c" -#include "game/__build.c" +#include "game/server/__build.c" +#include "game/client/__build.c" #include "launcher/__build.c" #include "funnyassets/__build.c" -int build(struct build_data b) { - if (!step("trace")) - trace = 1; +int build(struct build_data b) { + trace = 1; makedir("build/"GAME_NAME"/game/" GAME_NAME); makedir("build/"GAME_NAME"/game/" GAME_NAME "/bin"); makedir("build/"GAME_NAME"/game/bin/"); @@ -38,8 +38,12 @@ int build(struct build_data b) { launcher_build(b); server_build(b); + client_build(b); - assets_build(b); + if (step("noassets")) + { + assets_build(b); + } mv("build", "tools"); if (step("run")!=STEP_FAILED) diff --git a/engine/__build.c b/engine/__build.c index f0573d9..5dddadd 100644 --- a/engine/__build.c +++ b/engine/__build.c @@ -1,9 +1,13 @@ +#include "god/build.h" #include "god/c.h" #include "god/ld.h" #include "god/utils.h" +char *engine_lib; +char *engine_implib; void engine_build(struct build_data b) { + char *szVideoFile = "engine/vk_videosdl.cpp"; char* files[] = { "engine/console.cpp", "engine/filesystem.cpp", @@ -11,12 +15,12 @@ void engine_build(struct build_data b) "engine/engine.cpp", /* rendering */ - "engine/vk_videolinux.cpp", "engine/vk_video.cpp", "engine/vk_brush.cpp", + "engine/vk_mesh.cpp", + szVideoFile, - /* entities */ - + /* entities */ "engine/baseentity.cpp", "engine/level.cpp", "engine/brush.cpp", @@ -30,9 +34,6 @@ void engine_build(struct build_data b) "engine/cl_light.cpp", NULL, }; - char *rustFiles[] = { - "engine/rust/physics.rs" - }; struct project p = { @@ -40,7 +41,6 @@ void engine_build(struct build_data b) .files = files, .name = "engine", }; - struct project o = C_compile(p, (struct C_settings){ .generation_flags = C_GENERATION_FLAGS_PIC, .compile_flags = C_COMPILE_FLAGS_WALL, @@ -49,16 +49,28 @@ void engine_build(struct build_data b) add_item(&o.files, tier1_lib); add_item(&o.files, rapierLib); + char *szVulkan = (char*)1; + char *szws2 = (char*)1; + if (b.kernel==BUILD_KERNEL_WINDOWS) + { + szVulkan="vulkan-1"; + szws2="ws2_32"; + } + if (b.kernel==BUILD_KERNEL_LINUX) + { + szVulkan="vulkan"; + } + char* libs[] = { "c", - "vulkan", - "X11", + "SDL3", + szVulkan, NULL, }; - char* dll = ld_link_project(o, (struct link_settings){ + engine_lib = ld_link_project(o, (struct link_settings){ .type = LINK_TYPE_DYNAMIC, .libs = libs, }); - mv("build/"GAME_NAME"/game/bin",dll); + mv("build/"GAME_NAME"/game/bin",engine_lib); } diff --git a/engine/baseentity.cpp b/engine/baseentity.cpp index 4fe2a78..b2eb5e9 100644 --- a/engine/baseentity.cpp +++ b/engine/baseentity.cpp @@ -1,8 +1,15 @@ #include "baseentity.h" +#include "cglm/mat4.h" +#include "tier0/platform.h" CUtlSelfReferencingVector g_entities; CUtlVector g_RegisteredEntities; +CBaseEntity::CBaseEntity() +{ + glm_mat4_identity(m_matrix); +}; + CEntityRegistry::CEntityRegistry(const char *szName, const char *szClass, EntityRegistryFn pfn) : m_szName(szName), m_szClass(szClass), m_pfn(pfn), m_pClientfn(0) { diff --git a/engine/brush.cpp b/engine/brush.cpp index 778a43b..afd72bd 100644 --- a/engine/brush.cpp +++ b/engine/brush.cpp @@ -22,22 +22,20 @@ void CBrushEntity::Spawn() for (auto tri: m_mesh) { V_memcpy(&triangles[i],tri.location,36); - i+=1; + i+=3; } - V_printf("indicides %i\n",indicies.GetSize()); - V_printf("vertices %i\n",triangles.GetSize()); - px_collider_params params = {}; - params.friction = 0; + params.friction = 0.6; m_collider = px_trimesh((Point*)triangles.GetMemory(), triangles.GetSize(), (uint32_t(*)[3])indicies.GetMemory(), indicies.GetSize()/3 ,params); + //m_collider = px_box(4, 10, 1, params); px_matrix mat = {}; mat.m[0] = 1; - mat.m[4] = 1; - mat.m[9] = 1; + mat.m[5] = 1; + mat.m[10] = 1; mat.m[15] = 1; px_rigidbody_params param = {}; param.gravity_scale = 1; - m_body = px_staticbody(px, m_collider, mat); + px_fixedbody(px, m_collider); }; void CBrushEntity::Destroy() @@ -67,7 +65,7 @@ void C_BrushEntity::Spawn() pAlbedo = ITextureManager::LoadTexture("gfx/bricks.png"); CBrushEntity* pBrushEntity = (CBrushEntity*)pEntity; uint32_t numVertices = 15*pBrushEntity->m_mesh.GetSize(); - vertexBuffer = IBrushRenderer::CreateVertexBuffer(numVertices*4); + vertexBuffer = IRenderer::CreateVertexBuffer(numVertices*4); Vertex_t *pTriangles = (Vertex_t*)vertexBuffer->Map(); uint32_t i = 0; for (auto &triangle: pBrushEntity->m_mesh) @@ -103,7 +101,7 @@ void C_BrushEntity::Destroy() void C_BrushEntity::Think( float fDelta ) { material.m.albedo = ITextureManager::GetTexture(pAlbedo); - IBrushRenderer::SetMaterial(&material); + IRenderer::SetMaterial(&material); mesh->Draw(); }; diff --git a/engine/cl_light.cpp b/engine/cl_light.cpp index b6dfc2d..490a116 100644 --- a/engine/cl_light.cpp +++ b/engine/cl_light.cpp @@ -1,5 +1,5 @@ #include "baseentity.h" - +#include "rendering.h" class C_Light: public C_BaseEntity { @@ -7,7 +7,9 @@ public: virtual void Precache ( void ) override; virtual void Spawn( void ) override; virtual void Destroy( void ) override; - virtual void Think( float fDelta ) override; + virtual void Think( float fDelta ) override; + IVertexBuffer *vertexBuffer; + IMesh *mesh; }; void C_Light::Precache() @@ -17,6 +19,56 @@ void C_Light::Precache() void C_Light::Spawn() { + float cubeVertices[] = { + -0.5f, -0.5f, 0.5f, 0.0f, 0.0f, + 0.5f, -0.5f, 0.5f, 1.0f, 0.0f, + 0.5f, 0.5f, 0.5f, 1.0f, 1.0f, + 0.5f, 0.5f, 0.5f, 1.0f, 1.0f, + -0.5f, 0.5f, 0.5f, 0.0f, 1.0f, + -0.5f, -0.5f, 0.5f, 0.0f, 0.0f, + + -0.5f, -0.5f, -0.5f, 1.0f, 0.0f, + -0.5f, 0.5f, -0.5f, 1.0f, 1.0f, + 0.5f, 0.5f, -0.5f, 0.0f, 1.0f, + 0.5f, 0.5f, -0.5f, 0.0f, 1.0f, + 0.5f, -0.5f, -0.5f, 0.0f, 0.0f, + -0.5f, -0.5f, -0.5f, 1.0f, 0.0f, + + -0.5f, 0.5f, 0.5f, 1.0f, 0.0f, + -0.5f, 0.5f, -0.5f, 1.0f, 1.0f, + -0.5f, -0.5f, -0.5f, 0.0f, 1.0f, + -0.5f, -0.5f, -0.5f, 0.0f, 1.0f, + -0.5f, -0.5f, 0.5f, 0.0f, 0.0f, + -0.5f, 0.5f, 0.5f, 1.0f, 0.0f, + + 0.5f, 0.5f, 0.5f, 1.0f, 0.0f, + 0.5f, -0.5f, -0.5f, 0.0f, 1.0f, + 0.5f, 0.5f, -0.5f, 1.0f, 1.0f, + 0.5f, -0.5f, -0.5f, 0.0f, 1.0f, + 0.5f, 0.5f, 0.5f, 1.0f, 0.0f, + 0.5f, -0.5f, 0.5f, 0.0f, 0.0f, + + -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, + -0.5f, 0.5f, 0.5f, 0.0f, 0.0f, + 0.5f, 0.5f, 0.5f, 1.0f, 0.0f, + 0.5f, 0.5f, 0.5f, 1.0f, 0.0f, + 0.5f, 0.5f, -0.5f, 1.0f, 1.0f, + -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, + + -0.5f, -0.5f, -0.5f, 1.0f, 1.0f, + 0.5f, -0.5f, -0.5f, 0.0f, 1.0f, + 0.5f, -0.5f, 0.5f, 0.0f, 0.0f, + 0.5f, -0.5f, 0.5f, 0.0f, 0.0f, + -0.5f, -0.5f, 0.5f, 1.0f, 0.0f, + -0.5f, -0.5f, -0.5f, 1.0f, 1.0f, + }; + vertexBuffer = IRenderer::CreateVertexBuffer(sizeof(cubeVertices)); + void *pTriangles = vertexBuffer->Map(); + V_memcpy(pTriangles, cubeVertices, sizeof(cubeVertices)); + vertexBuffer->Unmap(); + + mesh = IMeshRenderer::CreateMesh(); + mesh->SetVertexBuffer(vertexBuffer); }; void C_Light::Destroy() @@ -25,7 +77,9 @@ void C_Light::Destroy() } void C_Light::Think( float fDelta ) { - + IRenderer::SetMaterial(0); + mesh->SetMatrix(pEntity->m_matrix); + mesh->Draw(); }; LINK_CLIENT_ENTITY(C_Light, CLight) diff --git a/engine/cl_worldspawn.cpp b/engine/cl_worldspawn.cpp index d3be7db..2daff5b 100644 --- a/engine/cl_worldspawn.cpp +++ b/engine/cl_worldspawn.cpp @@ -13,7 +13,7 @@ public: void C_WorldSpawn::Precache() { - + C_BrushEntity::Precache(); } void C_WorldSpawn::Spawn() diff --git a/engine/client.cpp b/engine/client.cpp new file mode 100644 index 0000000..f679c0d --- /dev/null +++ b/engine/client.cpp @@ -0,0 +1 @@ +#include "client.h" diff --git a/engine/engine.cpp b/engine/engine.cpp index 1181fa0..1e60137 100644 --- a/engine/engine.cpp +++ b/engine/engine.cpp @@ -8,13 +8,12 @@ #include "baseentity.h" #include "server.h" #include "physics.h" - -#ifdef __linux #include "signal.h" -#endif double fPrev = 0; double fCurrent = 0; + +funnyphysics *px; //----------------------------------------------------------------------------- // Purpose: Engine entry point //----------------------------------------------------------------------------- @@ -49,7 +48,6 @@ void IEngine_Signal(int sig) _exit(0); }; -funnyphysics *px; void IEngine::Init() { @@ -83,15 +81,6 @@ void IEngine::Shutdown() { }; -void IIEngine::PrecacheModel( const char *psz ) -{ - -} -void IIEngine::PrecacheSound( const char *psz ) -{ - -} - CBaseEntity *IIEngine::SpawnEntity( const char *szName ) { diff --git a/engine/filesystem.cpp b/engine/filesystem.cpp index fa7feed..d827eb0 100644 --- a/engine/filesystem.cpp +++ b/engine/filesystem.cpp @@ -88,7 +88,7 @@ bool IFileSystem::LoadPackFile( const char *szFilename ) unsigned long long nNumFiles = 0; PackDirectory_t *pDirs = NULL; - FILE* f = V_fopen(szFilename, "r"); + FILE* f = V_fopen(szFilename, "rb"); if (!f) Plat_FatalErrorFunc("Failed to open %s",szFilename); V_fread(&header,1,sizeof(header),f); diff --git a/engine/server.cpp b/engine/server.cpp index 563f285..289fa9e 100644 --- a/engine/server.cpp +++ b/engine/server.cpp @@ -5,19 +5,23 @@ #include "physics.h" void *g_serverdll; +ConVar g_tickrate("tickrate","64",FCVAR_PROTECTED); +float g_fAccumulator = 0; void IServer::LoadGame( const char *psz ) { +#ifdef __WIN32__ + g_serverdll = Plat_LoadLibrary(CUtlString("%s/bin/server.dll", psz)); +#endif +#ifdef __linux__ g_serverdll = Plat_LoadLibrary(CUtlString("%s/bin/libserver.so", psz)); +#endif void (*GameLoadfn)() = (void(*)())Plat_GetProc(g_serverdll, "IGame_Load"); if (!GameLoadfn) Plat_FatalErrorFunc("IGame_Load not found in libserver.so\n"); GameLoadfn(); }; -ConVar g_tickrate("tickrate","64",FCVAR_PROTECTED); -float g_fAccumulator = 0; - void IServer::Think( float fDelta ) { g_fAccumulator += fDelta; diff --git a/engine/sv_light.cpp b/engine/sv_light.cpp index 4ff1527..6eecd8b 100644 --- a/engine/sv_light.cpp +++ b/engine/sv_light.cpp @@ -23,15 +23,16 @@ void CLight::Precache() void CLight::Spawn() { px_collider_params params = {}; - params.friction = 0; - col = px_box(1, 1, 1, params); + params.friction = 0.7; + col = px_box(0.5,0.5,0.5, params); px_matrix mat = {}; mat.m[0] = 1; - mat.m[4] = 1; - mat.m[9] = 1; + mat.m[5] = 1; + mat.m[10] = 1; mat.m[15] = 1; - mat.m[3]=-10; mat.m[11]=10; + mat.m[7]=-4; + mat.m[3]=12; px_rigidbody_params param = {}; param.gravity_scale = 1; m_body=px_rigidbody(px, col, mat, param); @@ -43,8 +44,9 @@ void CLight::Destroy() } void CLight::Think( float fDelta ) { - px_vec3 pos = px_getposition(px, m_body); - V_printf("%p %f %f %f\n",col, pos.m[0], pos.m[1], pos.m[2]); + px_matrix pos = px_getmatrix(px, m_body); + V_memcpy(m_matrix, pos.m, 64); + V_printf("%p %f %f %f\n",col, pos.m[12], pos.m[13], pos.m[14]); }; DECLARE_ENTITY(light, CLight) diff --git a/engine/sv_worldspawn.cpp b/engine/sv_worldspawn.cpp index 8517429..b144328 100644 --- a/engine/sv_worldspawn.cpp +++ b/engine/sv_worldspawn.cpp @@ -17,6 +17,7 @@ void CWorldSpawn::Precache() void CWorldSpawn::Spawn() { + V_printf("Cool\n"); CBrushEntity::Spawn(); }; diff --git a/engine/vk_brush.cpp b/engine/vk_brush.cpp index 42c6f67..75f260f 100644 --- a/engine/vk_brush.cpp +++ b/engine/vk_brush.cpp @@ -4,48 +4,27 @@ #include "vk_helper.h" #include "vulkan/vulkan_core.h" -extern VkSampler g_invalidTextureSampler; + +vk_tripipeline_t g_brushPipeline = {}; + +VkDescriptorPool g_brushDescriptorPool; +VkDescriptorSet g_brushDescriptorSet; + +VkSampler g_brushSampler; + + abstract_class CBrush: public IBrush { public: - void SetPosition( vec3 position ) override; - void SetRotationEuler( vec3 angle ) override; - void SetRotationQuat( vec4 quaternion) override; - void SetMatrix( mat3 matrix ) override; - void SetScale( vec3 scale ) override; - void SetVertexBuffer( IVertexBuffer *pBuffer ) override; void SetIndexBuffer( IIndexBuffer *pBuffer ) override; void Draw() override; - IMaterial *m_pMaterial = NULL; + Material_t m_material; CVertexBuffer *m_pVertexBuffer = NULL; CIndexBuffer *m_pIndexBuffer = NULL; }; -void CBrush::SetPosition( vec3 position ) -{ - -} - -void CBrush::SetRotationEuler( vec3 angle ) -{ - -} - -void CBrush::SetRotationQuat( vec4 quaternion) -{ - -} - -void CBrush::SetMatrix( mat3 matrix ) -{ - -} - -void CBrush::SetScale( vec3 scale ) -{ - -} +CUtlVector g_drawnBrushes; void CBrush::SetVertexBuffer( IVertexBuffer *pBuffer ) @@ -58,34 +37,15 @@ void CBrush::SetIndexBuffer( IIndexBuffer *pBuffer ) m_pIndexBuffer = (CIndexBuffer*)pBuffer; } -CUtlVector g_drawnMeshes; -IMaterial *g_pDefaultMaterial; -IMaterial *g_pCurrentMaterial; - void CBrush::Draw() { - g_drawnMeshes.AppendTail(*this); + if (!g_pCurrentMaterial) + m_material = {}; + else + m_material = g_pCurrentMaterial->m; + g_drawnBrushes.AppendTail(*this); } -abstract_class CMaterial: public IMaterial -{ -}; - -extern CUtlVector g_textures; - -vk_tripipeline_t g_brushPipeline = {}; -vk_image2d_t meshdepth; -vk_image2d_t meshcolor; -extern bool g_bConfigNotify; - -VkDescriptorPool g_brushDescriptorPool; -VkDescriptorSet g_brushDescriptorSet; -vk_buffer_t g_brushProjection; -struct MeshProjection { - mat4 projection; -} *g_brushProject; - -VkSampler g_brushSampler; void IBrushRenderer::Init() { @@ -111,9 +71,6 @@ void IBrushRenderer::Init() shaders[1].Destroy(); shaders[0].Destroy(); - meshdepth.Create(1280, 720, VK_FORMAT_D32_SFLOAT, VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT); - meshcolor.Create(1280, 720, VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT); - CUtlVector pools; for (auto &binding: bindings) { @@ -137,8 +94,6 @@ void IBrushRenderer::Init() allocInfo.pSetLayouts = &g_brushPipeline.m_descriptorSetLayout; vkAllocateDescriptorSets(g_vkDevice, &allocInfo, &g_brushDescriptorSet); - g_brushProjection.Create(64, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT); - g_brushProject = (MeshProjection*)g_brushProjection.Map(0, 64); VkPhysicalDeviceProperties properties{}; vkGetPhysicalDeviceProperties(g_vkPhysicalDevice, &properties); @@ -164,17 +119,6 @@ void IBrushRenderer::Init() void IBrushRenderer::Frame( float fDelta ) { - glm_mat4_identity(g_brushProject->projection); - glm_perspective(glm_rad(90),(float)g_nWindowWidth/g_nWindowHeight, 0.01, 100, g_brushProject->projection); - glm_rotate(g_brushProject->projection, glm_rad(90), (vec4){1,0,0,0}); - glm_scale(g_brushProject->projection, (vec4){1,-1,1,1}); - glm_rotate(g_brushProject->projection, glm_rad(-90), (vec4){0,0,1,0}); - if (g_bConfigNotify) - { - meshdepth.Destroy(); - meshdepth.Create(g_nWindowWidth, g_nWindowHeight, VK_FORMAT_D32_SFLOAT, VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT); - } - CUtlVector writes(2); for (auto &write: writes) @@ -186,9 +130,9 @@ void IBrushRenderer::Frame( float fDelta ) } VkDescriptorBufferInfo bufferInfo = {}; - bufferInfo.buffer = g_brushProjection.m_buffer; + bufferInfo.buffer = g_cameraProperties.m_buffer; bufferInfo.offset = 0; - bufferInfo.range = g_brushProjection.m_nSize; + bufferInfo.range = g_cameraProperties.m_nSize; writes[0].dstBinding = 0; writes[0].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; writes[0].descriptorCount = 1; @@ -237,7 +181,7 @@ void IBrushRenderer::Frame( float fDelta ) }; VkRenderingAttachmentInfo depthAttachment = { .sType = VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO, - .imageView = meshdepth.m_imageView, + .imageView = g_meshdepth.m_imageView, .imageLayout = VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL, .loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR, .storeOp = VK_ATTACHMENT_STORE_OP_STORE, @@ -317,14 +261,10 @@ void IBrushRenderer::Frame( float fDelta ) vkCmdBindPipeline(g_vkCommandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, g_brushPipeline.m_pipeline); vkCmdBindDescriptorSets(g_vkCommandBuffer,VK_PIPELINE_BIND_POINT_GRAPHICS, g_brushPipeline.m_layout, 0, 1, &g_brushDescriptorSet, 0, NULL); - for (auto &mesh: g_drawnMeshes) + for (auto &mesh: g_drawnBrushes) { VkDeviceSize offset = 0; - uint32_t textureID = 0; - if (g_pCurrentMaterial == 0) - textureID = 0; - else - textureID = ((CMaterial*)g_pCurrentMaterial)->m.albedo; + uint32_t textureID = mesh.m_material.albedo; vkCmdPushConstants(g_vkCommandBuffer, g_brushPipeline.m_layout, VK_SHADER_STAGE_ALL, 0, 4, &textureID); vkCmdBindVertexBuffers(g_vkCommandBuffer, 0, 1, &mesh.m_pVertexBuffer->m_buffer.m_buffer, &offset); if (mesh.m_pIndexBuffer) @@ -349,7 +289,7 @@ void IBrushRenderer::Frame( float fDelta ) .srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, .dstAccessMask = 0, .oldLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, - .newLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR, + .newLayout = VK_IMAGE_LAYOUT_GENERAL, .image = g_swapchainImage, .subresourceRange = {VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1} }; @@ -358,23 +298,10 @@ void IBrushRenderer::Frame( float fDelta ) VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, 0, 0, NULL, 0, NULL, 1, &barrier); - g_drawnMeshes = CUtlVector(); + g_drawnBrushes = CUtlVector(); } -IVertexBuffer *IBrushRenderer::CreateVertexBuffer( uint32_t uSize ) -{ - CVertexBuffer *pBuffer = new CVertexBuffer(); - pBuffer->m_buffer.Create(uSize, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT); - return pBuffer; -} - -IIndexBuffer *IBrushRenderer::CreateIndexBuffer( uint32_t uSize ) -{ - CIndexBuffer *pBuffer = new CIndexBuffer(); - pBuffer->m_buffer.Create(uSize, VK_BUFFER_USAGE_INDEX_BUFFER_BIT | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT); - return pBuffer; -} IBrush *IBrushRenderer::CreateMesh() { @@ -387,21 +314,3 @@ void IBrushRenderer::Destroy( IBrush *pModel ) } -IMaterial *IBrushRenderer::LoadMaterial( const char *szMaterial ) -{ - FileHandle_t file = IFileSystem::Open(szMaterial, IFILE_READ); - CMaterial *pMaterial = new CMaterial; - if (!file) - { - return g_pDefaultMaterial; - } - - IFileSystem::Close(file); -} - -void IBrushRenderer::SetMaterial( IMaterial *pMaterial ) -{ - g_pCurrentMaterial = pMaterial; -} - - diff --git a/engine/vk_helper.h b/engine/vk_helper.h index 597a773..b20b5ee 100644 --- a/engine/vk_helper.h +++ b/engine/vk_helper.h @@ -5,11 +5,7 @@ #include "console.h" #include "tier1/commandline.h" -#include "X11/X.h" -#include "X11/Xlib.h" #include "vulkan/vulkan.h" -#include "vulkan/vulkan_core.h" -#include "vulkan/vulkan_xlib.h" #define VULKAN_RENDERING_IMPL #include "vk_video.h" @@ -21,31 +17,6 @@ #include "cglm/affine.h" #include "cglm/cglm.h" -extern Display* g_xdisplay; -extern int g_xscreen; -extern Window g_xroot; -extern Window g_xwin; - -extern VkInstance g_vkInstance; -extern VkPhysicalDevice g_vkPhysicalDevice; -extern VkDevice g_vkDevice; -extern uint32_t g_drawfamily; -extern VkQueue g_drawQueue; -extern uint32_t g_presentfamily; -extern VkQueue g_presentQueue; -extern VmaAllocator g_allocator; - -extern VkSurfaceKHR g_surface; -extern VkSwapchainKHR g_swapchain; - -extern VkCommandPool g_vkCommandPool; -extern VkCommandBuffer g_vkCommandBuffer; -extern VkImageView g_swapchainImageView; -extern VkImage g_swapchainImage; - -extern uint32_t g_nWindowWidth; -extern uint32_t g_nWindowHeight; - class CVertexBuffer: public IVertexBuffer { public: @@ -70,3 +41,42 @@ class CTexture: public ITexture public: vk_image2d_t image; }; + + + +extern VkInstance g_vkInstance; +extern VkPhysicalDevice g_vkPhysicalDevice; +extern VkDevice g_vkDevice; +extern uint32_t g_drawfamily; +extern VkQueue g_drawQueue; +extern uint32_t g_presentfamily; +extern VkQueue g_presentQueue; +extern VmaAllocator g_allocator; + +extern VkSurfaceKHR g_surface; +extern VkSwapchainKHR g_swapchain; + +extern VkCommandPool g_vkCommandPool; +extern VkCommandBuffer g_vkCommandBuffer; +extern VkImageView g_swapchainImageView; +extern VkImage g_swapchainImage; + +extern bool g_bConfigNotify; +extern uint32_t g_nWindowWidth; +extern uint32_t g_nWindowHeight; + +extern VkSampler g_invalidTextureSampler; +extern IMaterial *g_pDefaultMaterial; +extern IMaterial *g_pCurrentMaterial; + +extern CUtlVector g_textures; + +struct CameraProjection { + mat4 viewprojection; +}; + +extern vk_buffer_t g_cameraProperties; +extern CameraProjection *g_cameraDataMap; + +extern vk_image2d_t g_meshdepth; +extern vk_image2d_t g_meshcolor; diff --git a/engine/vk_mesh.cpp b/engine/vk_mesh.cpp new file mode 100644 index 0000000..dc23cd8 --- /dev/null +++ b/engine/vk_mesh.cpp @@ -0,0 +1,354 @@ +#include "cglm/mat4.h" +#include "filesystem.h" +#include "rendering.h" +#include "tier1/utlvector.h" +#include "vk_helper.h" +#include "vulkan/vulkan_core.h" + + +vk_tripipeline_t g_meshPipeline = {}; + +VkDescriptorPool g_meshDescriptorPool; +VkDescriptorSet g_meshDescriptorSet; + +VkSampler g_meshSampler; + + +abstract_class CMesh: public IMesh +{ +public: + CMesh(); + void SetPosition( vec3 position ) override; + void SetRotationEuler( vec3 angle ) override; + void SetRotationQuat( vec4 quaternion) override; + void SetMatrix( mat4 matrix ) override; + void SetScale( vec3 scale ) override; + + void SetVertexBuffer( IVertexBuffer *pBuffer ) override; + void SetIndexBuffer( IIndexBuffer *pBuffer ) override; + void Draw() override; + + Material_t m_material; + CVertexBuffer *m_pVertexBuffer = NULL; + CIndexBuffer *m_pIndexBuffer = NULL; + mat4 m_matrix; +}; + +CMesh::CMesh() +{ + glm_mat4_identity(m_matrix); +}; + +void CMesh::SetPosition( vec3 position ) +{ + m_matrix[0][3] = position[0]; + m_matrix[1][3] = position[1]; + m_matrix[2][3] = position[2]; +} + +void CMesh::SetRotationEuler( vec3 angle ) +{ + +} + +void CMesh::SetRotationQuat( vec4 quaternion) +{ + +} + +void CMesh::SetMatrix( mat4 matrix ) +{ + memcpy(m_matrix,matrix,64); +} + +void CMesh::SetScale( vec3 scale ) +{ + +} + +void CMesh::SetVertexBuffer( IVertexBuffer *pBuffer ) +{ + m_pVertexBuffer = (CVertexBuffer*)pBuffer; +} + +void CMesh::SetIndexBuffer( IIndexBuffer *pBuffer ) +{ + m_pIndexBuffer = (CIndexBuffer*)pBuffer; +} + +CUtlVector g_drawnMeshes; + +void CMesh::Draw() +{ + if (!g_pCurrentMaterial) + m_material = {}; + else + m_material = g_pCurrentMaterial->m; + g_drawnMeshes.AppendTail(*this); +} + +void IMeshRenderer::Init() +{ + CUtlVector shaders(2); + for (auto &shader: shaders) + { + shader.m_shaderModule = NULL; + } + shaders[0].Create("gfx/mesh_vert.spv", VK_SHADER_STAGE_VERTEX_BIT); + shaders[1].Create("gfx/mesh_frag.spv", VK_SHADER_STAGE_FRAGMENT_BIT); + CUtlVector bindings(2); + bindings[0] = {}; + bindings[0].binding = 0; + bindings[0].stageFlags = VK_SHADER_STAGE_VERTEX_BIT; + bindings[0].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; + bindings[0].descriptorCount = 1; + bindings[1] = {}; + bindings[1].binding = 1; + bindings[1].stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT; + bindings[1].descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; + bindings[1].descriptorCount = 1024; + g_meshPipeline.Create(shaders, bindings, 76); + shaders[1].Destroy(); + shaders[0].Destroy(); + + CUtlVector pools; + for (auto &binding: bindings) + { + VkDescriptorPoolSize dps = {}; + dps.type = binding.descriptorType; + dps.descriptorCount = binding.descriptorCount; + pools.AppendTail(dps); + } + + VkDescriptorPoolCreateInfo poolInfo = {}; + poolInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO; + poolInfo.poolSizeCount = pools.GetSize(); + poolInfo.pPoolSizes = pools.GetData(); + poolInfo.maxSets = 1; + vkCreateDescriptorPool(g_vkDevice, &poolInfo, NULL, &g_meshDescriptorPool); + + VkDescriptorSetAllocateInfo allocInfo = {}; + allocInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO; + allocInfo.descriptorPool = g_meshDescriptorPool; + allocInfo.descriptorSetCount = 1; + allocInfo.pSetLayouts = &g_meshPipeline.m_descriptorSetLayout; + vkAllocateDescriptorSets(g_vkDevice, &allocInfo, &g_meshDescriptorSet); + + + VkPhysicalDeviceProperties properties{}; + vkGetPhysicalDeviceProperties(g_vkPhysicalDevice, &properties); + VkSamplerCreateInfo samplerInfo{}; + samplerInfo.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO; + samplerInfo.magFilter = VK_FILTER_LINEAR; + samplerInfo.minFilter = VK_FILTER_LINEAR; + samplerInfo.addressModeU = VK_SAMPLER_ADDRESS_MODE_REPEAT; + samplerInfo.addressModeV = VK_SAMPLER_ADDRESS_MODE_REPEAT; + samplerInfo.addressModeW = VK_SAMPLER_ADDRESS_MODE_REPEAT; + samplerInfo.anisotropyEnable = VK_FALSE; + samplerInfo.maxAnisotropy = properties.limits.maxSamplerAnisotropy; + samplerInfo.borderColor = VK_BORDER_COLOR_INT_OPAQUE_BLACK; + samplerInfo.unnormalizedCoordinates = VK_FALSE; + samplerInfo.compareEnable = VK_FALSE; + samplerInfo.compareOp = VK_COMPARE_OP_ALWAYS; + samplerInfo.mipmapMode = VK_SAMPLER_MIPMAP_MODE_LINEAR; + samplerInfo.mipLodBias = 0.0f; + samplerInfo.minLod = 0.0f; + samplerInfo.maxLod = 0.0f; + vkCreateSampler(g_vkDevice, &samplerInfo, nullptr, &g_meshSampler); +} + +void IMeshRenderer::Frame( float fDelta ) +{ + CUtlVector writes(2); + for (auto &write: writes) + { + write = {}; + write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; + write.dstSet = g_meshDescriptorSet; + write.dstArrayElement = 0; + } + + VkDescriptorBufferInfo bufferInfo = {}; + bufferInfo.buffer = g_cameraProperties.m_buffer; + bufferInfo.offset = 0; + bufferInfo.range = g_cameraProperties.m_nSize; + writes[0].dstBinding = 0; + writes[0].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; + writes[0].descriptorCount = 1; + writes[0].pBufferInfo = &bufferInfo; + + CUtlVector textures; + textures.Reserve(g_textures.GetSize()); + for (ITexture *t: g_textures) + { + CTexture *texture = (CTexture*)t; + VkDescriptorImageInfo image = {}; + image.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; + image.imageView = texture->image.m_imageView; + image.sampler = g_meshSampler; + textures.AppendTail(image); + }; + textures[0].sampler = g_invalidTextureSampler; + writes[1].dstBinding = 1; + writes[1].descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; + writes[1].descriptorCount = textures.GetSize(); + writes[1].pImageInfo = textures.GetData(); + vkUpdateDescriptorSets(g_vkDevice, writes.GetSize(), writes.GetData(), 0, NULL); + + + VkImageMemoryBarrier barrier = { + .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, + .srcAccessMask = 0, + .dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, + .oldLayout = VK_IMAGE_LAYOUT_GENERAL, + .newLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, + .image = g_swapchainImage, + .subresourceRange = {VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1} + }; + vkCmdPipelineBarrier(g_vkCommandBuffer, + VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, + VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, + 0, 0, NULL, 0, NULL, 1, &barrier); + + VkRenderingAttachmentInfo colorAttachment = { + .sType = VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO, + .imageView = g_swapchainImageView, + .imageLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, + .loadOp = VK_ATTACHMENT_LOAD_OP_LOAD, + .storeOp = VK_ATTACHMENT_STORE_OP_STORE, + }; + VkRenderingAttachmentInfo depthAttachment = { + .sType = VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO, + .imageView = g_meshdepth.m_imageView, + .imageLayout = VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL, + .loadOp = VK_ATTACHMENT_LOAD_OP_LOAD, + .storeOp = VK_ATTACHMENT_STORE_OP_STORE, + }; + + VkRenderingInfo renderInfo = { + .sType = VK_STRUCTURE_TYPE_RENDERING_INFO, + .renderArea = {{0, 0}, {g_nWindowWidth, g_nWindowHeight}}, + .layerCount = 1, + .colorAttachmentCount = 1, + .pColorAttachments = &colorAttachment, + .pDepthAttachment = &depthAttachment, + }; + vkCmdBeginRendering(g_vkCommandBuffer, &renderInfo); + + vkCmdSetRasterizerDiscardEnable(g_vkCommandBuffer, VK_FALSE); + vkCmdSetDepthBiasEnable(g_vkCommandBuffer, VK_FALSE); + _vkCmdSetPolygonModeEXT(g_vkCommandBuffer, VK_POLYGON_MODE_FILL); + vkCmdSetCullMode(g_vkCommandBuffer, VK_CULL_MODE_BACK_BIT); + vkCmdSetFrontFace(g_vkCommandBuffer, VK_FRONT_FACE_COUNTER_CLOCKWISE); + + vkCmdSetDepthTestEnable(g_vkCommandBuffer, VK_TRUE); + vkCmdSetDepthWriteEnable(g_vkCommandBuffer, VK_TRUE); + vkCmdSetDepthCompareOp(g_vkCommandBuffer, VK_COMPARE_OP_LESS); + vkCmdSetStencilTestEnable(g_vkCommandBuffer, VK_FALSE); + + _vkCmdSetRasterizationSamplesEXT(g_vkCommandBuffer, VK_SAMPLE_COUNT_1_BIT); + VkSampleMask sampleMask = 0xFFFFFFFF; + _vkCmdSetSampleMaskEXT(g_vkCommandBuffer, VK_SAMPLE_COUNT_1_BIT, &sampleMask); + _vkCmdSetAlphaToCoverageEnableEXT(g_vkCommandBuffer, VK_FALSE); + + VkViewport viewport = {0, 0, (float)g_nWindowWidth, (float)g_nWindowHeight, 0.0f, 1.0f}; + VkRect2D scissor = {{0, 0}, {g_nWindowWidth, g_nWindowHeight}}; + vkCmdSetViewportWithCount(g_vkCommandBuffer, 1, &viewport); + vkCmdSetScissorWithCount(g_vkCommandBuffer, 1, &scissor); + + vkCmdSetPrimitiveTopology(g_vkCommandBuffer, VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST); + vkCmdSetPrimitiveRestartEnable(g_vkCommandBuffer, VK_FALSE); + + VkVertexInputBindingDescription2EXT binding = { + .sType = VK_STRUCTURE_TYPE_VERTEX_INPUT_BINDING_DESCRIPTION_2_EXT, + .binding = 0, + .stride = 20, + .inputRate = VK_VERTEX_INPUT_RATE_VERTEX, + .divisor = 1, + }; + VkVertexInputAttributeDescription2EXT attributes[2] = { + { + VK_STRUCTURE_TYPE_VERTEX_INPUT_ATTRIBUTE_DESCRIPTION_2_EXT, + NULL, + 0, 0, + VK_FORMAT_R32G32B32_SFLOAT, + 0 + }, + { + VK_STRUCTURE_TYPE_VERTEX_INPUT_ATTRIBUTE_DESCRIPTION_2_EXT, + NULL, + 1, 0, + VK_FORMAT_R32G32_SFLOAT, + 12 + } + }; + _vkCmdSetVertexInputEXT(g_vkCommandBuffer, 1, &binding, 2, attributes); + + VkBool32 blendEnable = VK_FALSE; + VkColorBlendEquationEXT blendEquation = { + VK_BLEND_FACTOR_SRC_ALPHA, VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA, VK_BLEND_OP_ADD, + VK_BLEND_FACTOR_ONE, VK_BLEND_FACTOR_ZERO, VK_BLEND_OP_ADD + }; + VkColorComponentFlags writeMask = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | + VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT; + + _vkCmdSetColorBlendEnableEXT(g_vkCommandBuffer, 0, 1, &blendEnable); + _vkCmdSetColorBlendEquationEXT(g_vkCommandBuffer, 0, 1, &blendEquation); + _vkCmdSetColorWriteMaskEXT(g_vkCommandBuffer, 0, 1, &writeMask); + + vkCmdBindPipeline(g_vkCommandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, g_meshPipeline.m_pipeline); + vkCmdBindDescriptorSets(g_vkCommandBuffer,VK_PIPELINE_BIND_POINT_GRAPHICS, g_meshPipeline.m_layout, 0, 1, &g_meshDescriptorSet, 0, NULL); + for (auto &mesh: g_drawnMeshes) + { + VkDeviceSize offset = 0; + uint32_t textureID = mesh.m_material.albedo; + vkCmdPushConstants(g_vkCommandBuffer, g_meshPipeline.m_layout, VK_SHADER_STAGE_ALL, 0, 64, mesh.m_matrix); + vkCmdPushConstants(g_vkCommandBuffer, g_meshPipeline.m_layout, VK_SHADER_STAGE_ALL, 64, 4, &textureID); + vkCmdBindVertexBuffers(g_vkCommandBuffer, 0, 1, &mesh.m_pVertexBuffer->m_buffer.m_buffer, &offset); + if (mesh.m_pIndexBuffer) + { + vkCmdBindIndexBuffer( + g_vkCommandBuffer, + mesh.m_pIndexBuffer->m_buffer.m_buffer, + 0, + VK_INDEX_TYPE_UINT32 + ); + vkCmdDrawIndexed(g_vkCommandBuffer, mesh.m_pIndexBuffer->m_buffer.m_nSize/4, 1, 0, 0, 0); + } + else + { + vkCmdDraw(g_vkCommandBuffer, mesh.m_pVertexBuffer->m_buffer.m_nSize/12,1,0,0); + } + } + vkCmdEndRendering(g_vkCommandBuffer); + + barrier = { + .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, + .srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, + .dstAccessMask = 0, + .oldLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, + .newLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR, + .image = g_swapchainImage, + .subresourceRange = {VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1} + }; + + vkCmdPipelineBarrier(g_vkCommandBuffer, + VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, + VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, + 0, 0, NULL, 0, NULL, 1, &barrier); + g_drawnMeshes = CUtlVector(); + +} + + +IMesh *IMeshRenderer::CreateMesh() +{ + CMesh *mesh = new CMesh; + return mesh; +} + +void IMeshRenderer::Destroy( IBrush *pModel ) +{ + +} + diff --git a/engine/vk_postprocessing.cpp b/engine/vk_postprocessing.cpp new file mode 100644 index 0000000..e69de29 diff --git a/engine/vk_shading.cpp b/engine/vk_shading.cpp new file mode 100644 index 0000000..e69de29 diff --git a/engine/vk_video.cpp b/engine/vk_video.cpp index 77ea595..695d401 100644 --- a/engine/vk_video.cpp +++ b/engine/vk_video.cpp @@ -11,6 +11,15 @@ VkSampler g_invalidTextureSampler; +vk_buffer_t g_cameraProperties; +CameraProjection *g_cameraDataMap; + +IMaterial *g_pDefaultMaterial; +IMaterial *g_pCurrentMaterial; + +vk_image2d_t g_meshdepth; +vk_image2d_t g_meshcolor; + void IVulkan::Init() { char invalidTexture[1024] = {}; @@ -43,13 +52,33 @@ void IVulkan::Init() samplerInfo.minLod = 0.0f; samplerInfo.maxLod = 0.0f; vkCreateSampler(g_vkDevice, &samplerInfo, nullptr, &g_invalidTextureSampler); - IBrushRenderer::Init(); + + g_cameraProperties.Create(sizeof(CameraProjection), VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT); + g_cameraDataMap = (CameraProjection*)g_cameraProperties.Map(0, 64); + g_meshdepth.Create(1280, 720, VK_FORMAT_D32_SFLOAT, VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT); + g_meshcolor.Create(1280, 720, VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT); + + IBrushRenderer::Init(); + IMeshRenderer::Init(); }; void IVulkan::Frame() { + glm_mat4_identity(g_cameraDataMap->viewprojection); + glm_perspective(glm_rad(90),(float)g_nWindowWidth/g_nWindowHeight, 0.01, 100, g_cameraDataMap->viewprojection); + glm_rotate(g_cameraDataMap->viewprojection, glm_rad(90), (vec4){1,0,0,0}); + glm_scale(g_cameraDataMap->viewprojection, (vec4){1,-1,1,1}); + glm_rotate(g_cameraDataMap->viewprojection, glm_rad(90), (vec4){0,0,1,0}); + + if (g_bConfigNotify) + { + g_meshdepth.Destroy(); + g_meshdepth.Create(g_nWindowWidth, g_nWindowHeight, VK_FORMAT_D32_SFLOAT, VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT); + } + IBrushRenderer::Frame(0); + IMeshRenderer::Frame(0); }; void vk_shader_t::Create( const char *szPath, VkShaderStageFlagBits shaderStage ) @@ -472,3 +501,35 @@ ITexture *ITextureManager::LoadTexture( const char *szName ) pTexture->szName = szName; return pTexture; }; + +IMaterial *IRenderer::LoadMaterial( const char *szMaterial ) +{ + FileHandle_t file = IFileSystem::Open(szMaterial, IFILE_READ); + IMaterial *pMaterial = new IMaterial; + if (!file) + { + return g_pDefaultMaterial; + } + + IFileSystem::Close(file); +} + +void IRenderer::SetMaterial( IMaterial *pMaterial ) +{ + g_pCurrentMaterial = pMaterial; +} + +IVertexBuffer *IRenderer::CreateVertexBuffer( uint32_t uSize ) +{ + CVertexBuffer *pBuffer = new CVertexBuffer(); + pBuffer->m_buffer.Create(uSize, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT); + return pBuffer; +} + +IIndexBuffer *IRenderer::CreateIndexBuffer( uint32_t uSize ) +{ + CIndexBuffer *pBuffer = new CIndexBuffer(); + pBuffer->m_buffer.Create(uSize, VK_BUFFER_USAGE_INDEX_BUFFER_BIT | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT); + return pBuffer; +} + diff --git a/engine/vk_videolinux.cpp b/engine/vk_videolinux.cpp index c8674d6..d1d52ef 100644 --- a/engine/vk_videolinux.cpp +++ b/engine/vk_videolinux.cpp @@ -38,6 +38,7 @@ ConVar vulkan_gpu("vk_gpu", "0", FCVAR_ARCHIVE); VkCommandPool g_vkCommandPool; + /* more efficient */ CUtlVector g_commandBuffers; VkCommandBuffer g_vkCommandBuffer; @@ -49,11 +50,18 @@ VkImage g_swapchainImage; uint32_t g_nNumSwapchainImages = 0; +#define VK_DEVICE_FUNCTION(name) PFN_##name _##name +#include "vk_external_functions.cpp" +#undef VK_DEVICE_FUNCTION + +char g_bConfigNotify = 0; +uint32_t g_nWindowWidth = 1280; +uint32_t g_nWindowHeight = 720; + void IVideo_SwapchainInit() { /* swapchain */ - VkXlibSurfaceCreateInfoKHR surfaceCreateInfo = {}; surfaceCreateInfo.sType = VK_STRUCTURE_TYPE_XLIB_SURFACE_CREATE_INFO_KHR; surfaceCreateInfo.dpy = g_xdisplay; @@ -176,16 +184,13 @@ void IVideo_SwapchainDestroy() } }; -#define VK_DEVICE_FUNCTION(name) PFN_##name _##name -#include "vk_external_functions.cpp" -#undef VK_DEVICE_FUNCTION - void IVideo::Init() { g_xdisplay = XOpenDisplay(NULL); g_xscreen = DefaultScreen(g_xdisplay); g_xroot = RootWindow(g_xdisplay, g_xscreen); g_xwin = XCreateSimpleWindow(g_xdisplay, g_xroot, 0, 0, 1280, 720, 0, 0, 0); + XSelectInput(g_xdisplay, g_xwin, StructureNotifyMask); vulkan_gpu.SetValue(ICommandLine::ParamValue("-gpu")); @@ -338,7 +343,6 @@ void IVideo::Init() #undef VK_DEVICE_FUNCTION IVideo_SwapchainInit(); - XMapWindow(g_xdisplay, g_xwin); XFlush(g_xdisplay); @@ -346,10 +350,6 @@ void IVideo::Init() } -char g_bConfigNotify = 0; -uint32_t g_nWindowWidth = 1280; -uint32_t g_nWindowHeight = 720; - void IVideo_HandleX11() { XEvent event; diff --git a/engine/vk_videosdl.cpp b/engine/vk_videosdl.cpp new file mode 100644 index 0000000..7b89978 --- /dev/null +++ b/engine/vk_videosdl.cpp @@ -0,0 +1,424 @@ +#include "rendering.h" +#include "tier0/platform.h" +#include "tier1/utlvector.h" +#include "console.h" +#include "tier1/commandline.h" + +#include "vulkan/vulkan.h" +#include "SDL3/SDL.h" +#define SDL_MAIN_HANDLED +#include "SDL3/SDL_main.h" +#include "SDL3/SDL_vulkan.h" +#include "SDL3/SDL_events.h" + +#define VULKAN_RENDERING_IMPL +#include "vk_video.h" + +#define VMA_VULKAN_VERSION 1004000 +#define VMA_IMPLEMENTATION +#include "vk_mem_alloc.h" + +SDL_Window *g_window; + +VkInstance g_vkInstance = NULL; +VkPhysicalDevice g_vkPhysicalDevice = NULL; +VkDevice g_vkDevice = NULL; +uint32_t g_drawfamily = 0; +VkQueue g_drawQueue; +uint32_t g_presentfamily = 0; +VkQueue g_presentQueue; +VmaAllocator g_allocator = NULL; + +VkSurfaceKHR g_surface; +VkSwapchainKHR g_swapchain; + +ConVar vulkan_gpu("vk_gpu", "0", FCVAR_ARCHIVE); + + +VkCommandPool g_vkCommandPool; + +/* more efficient */ +CUtlVector g_commandBuffers; +VkCommandBuffer g_vkCommandBuffer; +CUtlVector g_frameData; +CUtlVector g_swapchainImages; +CUtlVector g_swapchainImageViews; +VkImageView g_swapchainImageView; +VkImage g_swapchainImage; + +uint32_t g_nNumSwapchainImages = 0; + +#define VK_DEVICE_FUNCTION(name) PFN_##name _##name +#include "vk_external_functions.cpp" +#undef VK_DEVICE_FUNCTION + +char g_bConfigNotify = 0; +uint32_t g_nWindowWidth = 1280; +uint32_t g_nWindowHeight = 720; + + +void IVideo_SwapchainInit() +{ + + /* swapchain */ + SDL_Vulkan_CreateSurface(g_window, g_vkInstance, NULL, &g_surface); + + VkSurfaceCapabilitiesKHR surfaceCapatibilities = {}; + + vkGetPhysicalDeviceSurfaceCapabilitiesKHR(g_vkPhysicalDevice, g_surface, &surfaceCapatibilities); + + const VkFormat preferedSurfaceFormats[] = { + VK_FORMAT_R8G8B8A8_UNORM, + VK_FORMAT_B8G8R8A8_UNORM, + }; + + uint32_t numSurfaceFormats = 0; + vkGetPhysicalDeviceSurfaceFormatsKHR(g_vkPhysicalDevice, g_surface, &numSurfaceFormats, NULL); + CUtlVector surfaceFormats(numSurfaceFormats); + vkGetPhysicalDeviceSurfaceFormatsKHR(g_vkPhysicalDevice, g_surface, &numSurfaceFormats, surfaceFormats.GetData()); + + VkSurfaceFormatKHR selectedFormat = surfaceFormats[0]; + for (auto &format: surfaceFormats) + { + for (int i = 0; i < sizeof(preferedSurfaceFormats)/sizeof(VkFormat); i++) + { + selectedFormat = surfaceFormats[i]; + } + } + + uint32_t numSurfacePresentModes = 0; + vkGetPhysicalDeviceSurfacePresentModesKHR(g_vkPhysicalDevice, g_surface, &numSurfacePresentModes, NULL); + CUtlVector surfacePresentModes(numSurfacePresentModes); + vkGetPhysicalDeviceSurfacePresentModesKHR(g_vkPhysicalDevice, g_surface, &numSurfacePresentModes, surfacePresentModes.GetData()); + + VkSwapchainCreateInfoKHR swapchainCreateInfo = {}; + swapchainCreateInfo.sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR; + swapchainCreateInfo.surface = g_surface; + swapchainCreateInfo.imageFormat = selectedFormat.format; + swapchainCreateInfo.imageColorSpace = selectedFormat.colorSpace; + swapchainCreateInfo.presentMode = VK_PRESENT_MODE_IMMEDIATE_KHR; + swapchainCreateInfo.imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT; + swapchainCreateInfo.preTransform = surfaceCapatibilities.currentTransform; + swapchainCreateInfo.compositeAlpha = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR; + swapchainCreateInfo.imageArrayLayers = 1; + swapchainCreateInfo.imageExtent = surfaceCapatibilities.minImageExtent; + swapchainCreateInfo.minImageCount = surfaceCapatibilities.minImageCount; + vkCreateSwapchainKHR(g_vkDevice, &swapchainCreateInfo, NULL, &g_swapchain); + + vkGetSwapchainImagesKHR(g_vkDevice, g_swapchain, &g_nNumSwapchainImages, NULL); + g_swapchainImages = CUtlVector(g_nNumSwapchainImages); + g_swapchainImageViews = CUtlVector(g_nNumSwapchainImages); + g_commandBuffers = CUtlVector(g_nNumSwapchainImages); + g_frameData = CUtlVector(g_nNumSwapchainImages); + vkGetSwapchainImagesKHR(g_vkDevice, g_swapchain, &g_nNumSwapchainImages, g_swapchainImages.GetData()); + + for (int i = 0; i < g_nNumSwapchainImages; i++) + { + VkImageViewCreateInfo createInfo = {}; + createInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO; + createInfo.image = g_swapchainImages[i]; + createInfo.viewType = VK_IMAGE_VIEW_TYPE_2D; + createInfo.format = selectedFormat.format; + createInfo.components.r = VK_COMPONENT_SWIZZLE_IDENTITY; + createInfo.components.g = VK_COMPONENT_SWIZZLE_IDENTITY; + createInfo.components.b = VK_COMPONENT_SWIZZLE_IDENTITY; + createInfo.components.a = VK_COMPONENT_SWIZZLE_IDENTITY; + createInfo.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; + createInfo.subresourceRange.baseMipLevel = 0; + createInfo.subresourceRange.levelCount = 1; + createInfo.subresourceRange.baseArrayLayer = 0; + createInfo.subresourceRange.layerCount = 1; + + vkCreateImageView(g_vkDevice, &createInfo, NULL, &g_swapchainImageViews[i]); + } + + + /* command buffers */ + VkCommandPoolCreateInfo commandPoolCreateInfo = {}; + commandPoolCreateInfo.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO; + commandPoolCreateInfo.queueFamilyIndex = g_drawfamily; + commandPoolCreateInfo.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT; + vkCreateCommandPool(g_vkDevice, &commandPoolCreateInfo, NULL, &g_vkCommandPool); + + VkCommandBufferAllocateInfo commandBufferAllocInfo = {}; + commandBufferAllocInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO; + commandBufferAllocInfo.commandPool = g_vkCommandPool; + commandBufferAllocInfo.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY; + commandBufferAllocInfo.commandBufferCount = g_nNumSwapchainImages; + vkAllocateCommandBuffers(g_vkDevice, &commandBufferAllocInfo, g_commandBuffers.GetData()); + + /* sync */ + + VkFenceCreateInfo fenceCreateInfo = {}; + fenceCreateInfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO; + fenceCreateInfo.flags = VK_FENCE_CREATE_SIGNALED_BIT; + + VkSemaphoreCreateInfo semaphoreCreateInfo = {}; + semaphoreCreateInfo.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO; + + for (int i = 0; i < g_nNumSwapchainImages; i++) + { + vkCreateFence(g_vkDevice,&fenceCreateInfo, NULL, &g_frameData[i].fence); + vkCreateSemaphore(g_vkDevice, &semaphoreCreateInfo, NULL, &g_frameData[i].draw); + vkCreateSemaphore(g_vkDevice, &semaphoreCreateInfo, NULL, &g_frameData[i].present); + } + +}; + +void IVideo_SwapchainDestroy() +{ + vkDestroySwapchainKHR(g_vkDevice, g_swapchain, NULL); + vkDestroySurfaceKHR(g_vkInstance, g_surface, NULL); + for (int i = 0; i < g_nNumSwapchainImages; i++) + { + vkDestroyImageView(g_vkDevice, g_swapchainImageViews[i], NULL); + vkDestroySemaphore(g_vkDevice, g_frameData[i].draw, NULL); + vkDestroySemaphore(g_vkDevice, g_frameData[i].present, NULL); + vkDestroyFence(g_vkDevice, g_frameData[i].fence, NULL); + } +}; + +void IVideo::Init() +{ + SDL_Init(SDL_INIT_VIDEO | SDL_INIT_EVENTS); + g_window = SDL_CreateWindow("rtt", 1280, 720, SDL_WINDOW_VULKAN); + + unsigned int nExtensionCount = 0; + const char* const* szExtensions = SDL_Vulkan_GetInstanceExtensions(&nExtensionCount); + + vulkan_gpu.SetValue(ICommandLine::ParamValue("-gpu")); + VkResult r = VK_SUCCESS; + uint32_t i = 0; + + /* Instance */ + VkApplicationInfo applicationInfo = {}; + applicationInfo.apiVersion = VK_API_VERSION_1_4; + + VkInstanceCreateInfo instanceCreateInfo = {}; + instanceCreateInfo.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO; + instanceCreateInfo.pApplicationInfo = &applicationInfo; + + instanceCreateInfo.enabledExtensionCount = nExtensionCount; + instanceCreateInfo.ppEnabledExtensionNames = szExtensions; + r = vkCreateInstance(&instanceCreateInfo, NULL, &g_vkInstance); + if ( r != VK_SUCCESS ) + Plat_FatalErrorFunc("Failed to create VkInstance!"); + + + /* Physical Devices */ + uint32_t nNumPhysicalDevices = 0; + vkEnumeratePhysicalDevices(g_vkInstance, &nNumPhysicalDevices, NULL); + if ( nNumPhysicalDevices == 0 ) + Plat_FatalErrorFunc("No GPU drivers available!"); + CUtlVector PhysicalDevices(nNumPhysicalDevices); + + vkEnumeratePhysicalDevices(g_vkInstance, &nNumPhysicalDevices, PhysicalDevices.GetData()); + + /* enumerate them for the user */ + for (auto &device: PhysicalDevices) + { + VkPhysicalDeviceProperties Properties = {}; + vkGetPhysicalDeviceProperties(device, &Properties); + V_printf("GPU%i available: %s\n", i, Properties.deviceName); + i++; + } + + /* select one in vk_gpu */ + g_vkPhysicalDevice = PhysicalDevices[vulkan_gpu.GetInt()]; + VkPhysicalDeviceProperties Properties = {}; + vkGetPhysicalDeviceProperties(g_vkPhysicalDevice, &Properties); + V_printf("Using %s\n", Properties.deviceName); + + /* queue family */ + uint32_t nNumQueueFamilies = 0; + vkGetPhysicalDeviceQueueFamilyProperties(g_vkPhysicalDevice, &nNumQueueFamilies, NULL); + CUtlVector queueFamilyProperties(nNumQueueFamilies); + vkGetPhysicalDeviceQueueFamilyProperties(g_vkPhysicalDevice, &nNumQueueFamilies, queueFamilyProperties.GetData()); + + i = 0; + for (auto &family: queueFamilyProperties) + { + if (family.queueFlags & VK_QUEUE_GRAPHICS_BIT) + { + g_drawfamily = i; + g_presentfamily = i; + } + i++; + } + + /* create device */ + float queuePriority = 1.0f; + VkDeviceQueueCreateInfo queueCreateInfo = {}; + queueCreateInfo.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO; + queueCreateInfo.queueFamilyIndex = g_drawfamily; + queueCreateInfo.queueCount = 1; + queueCreateInfo.pQueuePriorities = &queuePriority; + + VkPhysicalDeviceVertexInputDynamicStateFeaturesEXT pdvidsfe = { + .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VERTEX_INPUT_DYNAMIC_STATE_FEATURES_EXT, + .vertexInputDynamicState = VK_TRUE, + }; + + VkPhysicalDeviceExtendedDynamicState3FeaturesEXT pdeds3fe = { + .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTENDED_DYNAMIC_STATE_3_FEATURES_EXT, + .pNext = &pdvidsfe, + .extendedDynamicState3DepthClampEnable = VK_TRUE, + .extendedDynamicState3PolygonMode = VK_TRUE, + .extendedDynamicState3RasterizationSamples = VK_TRUE, + .extendedDynamicState3SampleMask = VK_TRUE, + .extendedDynamicState3AlphaToCoverageEnable = VK_TRUE, + .extendedDynamicState3LogicOpEnable = VK_TRUE, + .extendedDynamicState3ColorBlendEnable = VK_TRUE, + .extendedDynamicState3ColorBlendEquation = VK_TRUE, + .extendedDynamicState3ColorWriteMask = VK_TRUE, + }; + + VkPhysicalDeviceExtendedDynamicState2FeaturesEXT pdeds2fe = { + .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTENDED_DYNAMIC_STATE_2_FEATURES_EXT, + .pNext = &pdeds3fe, + .extendedDynamicState2LogicOp = VK_TRUE, + .extendedDynamicState2PatchControlPoints = VK_TRUE, + }; + + VkPhysicalDeviceVulkan13Features pdv13f = { + .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_3_FEATURES, + .pNext = &pdeds2fe, + .dynamicRendering = VK_TRUE, + }; + VkPhysicalDeviceVulkan12Features pdv12f = { + .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_FEATURES, + .pNext = &pdv13f, + .runtimeDescriptorArray = VK_TRUE, + .bufferDeviceAddress = VK_TRUE, + }; + VkPhysicalDeviceVulkan11Features pdv11f = { + .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_1_FEATURES, + .pNext = &pdv12f, + }; + + const char *szEnabledGPUExtensions[] = { + VK_KHR_SWAPCHAIN_EXTENSION_NAME, + VK_EXT_VERTEX_INPUT_DYNAMIC_STATE_EXTENSION_NAME, + VK_EXT_EXTENDED_DYNAMIC_STATE_3_EXTENSION_NAME, + }; + VkDeviceCreateInfo deviceCreateInfo = {}; + deviceCreateInfo.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO; + deviceCreateInfo.pQueueCreateInfos = &queueCreateInfo; + deviceCreateInfo.queueCreateInfoCount = 1; + deviceCreateInfo.enabledExtensionCount = sizeof(szEnabledGPUExtensions)/(sizeof(const char*)); + deviceCreateInfo.ppEnabledExtensionNames = szEnabledGPUExtensions; + deviceCreateInfo.pNext = &pdv11f; + + r = vkCreateDevice(g_vkPhysicalDevice, &deviceCreateInfo, NULL, &g_vkDevice); + if ( r != VK_SUCCESS ) + Plat_FatalErrorFunc("Failed to create VkDevice!"); + vkGetDeviceQueue(g_vkDevice, g_drawfamily, 0, &g_drawQueue); + vkGetDeviceQueue(g_vkDevice, g_presentfamily, 0, &g_presentQueue); + + VmaVulkanFunctions vulkanFunctions = {}; + vulkanFunctions.vkGetInstanceProcAddr = &vkGetInstanceProcAddr; + vulkanFunctions.vkGetDeviceProcAddr = &vkGetDeviceProcAddr; + + VmaAllocatorCreateInfo allocatorCreateInfo = {}; + allocatorCreateInfo.flags = VMA_ALLOCATOR_CREATE_BUFFER_DEVICE_ADDRESS_BIT; + allocatorCreateInfo.vulkanApiVersion = VK_API_VERSION_1_4; + allocatorCreateInfo.physicalDevice = g_vkPhysicalDevice; + allocatorCreateInfo.device = g_vkDevice; + allocatorCreateInfo.instance = g_vkInstance; + vmaCreateAllocator(&allocatorCreateInfo, &g_allocator); + + #define VK_DEVICE_FUNCTION(name) _##name = (PFN_##name)vkGetDeviceProcAddr(g_vkDevice, #name) + #include "vk_external_functions.cpp" + #undef VK_DEVICE_FUNCTION + + IVideo_SwapchainInit(); + + IVulkan::Init(); + +} + +void IVideo_HandleEvents() +{ + SDL_Event event; + while (SDL_PollEvent(&event)) + { + switch (event.type) + { + case SDL_EVENT_WINDOW_RESIZED: + g_nWindowWidth = event.window.data1; + g_nWindowHeight = event.window.data2; + g_bConfigNotify = 2; + } + }; +}; + + +void IVideo::Frame( float fDelta ) +{ + static uint32_t s_frameID = 0; + IVideo_HandleEvents(); + + vk_framedata_t frame = g_frameData[s_frameID]; + vkDeviceWaitIdle(g_vkDevice); + + vkWaitForFences(g_vkDevice, 1, &frame.fence, VK_TRUE, UINT64_MAX); + + uint32_t imageIndex = 0; + VkResult r = vkAcquireNextImageKHR(g_vkDevice, g_swapchain, UINT64_MAX, frame.draw, VK_NULL_HANDLE, &imageIndex); + if (r == VK_ERROR_OUT_OF_DATE_KHR || r == VK_SUBOPTIMAL_KHR || g_bConfigNotify == 2) + { + g_bConfigNotify=1; + vkDeviceWaitIdle(g_vkDevice); + IVideo_SwapchainDestroy(); + IVideo_SwapchainInit(); + return; + } + vk_framedata_t frameindex = g_frameData[imageIndex]; + + vkResetFences(g_vkDevice, 1, &frame.fence); + + g_vkCommandBuffer = g_commandBuffers[s_frameID]; + g_swapchainImageView = g_swapchainImageViews[imageIndex]; + g_swapchainImage = g_swapchainImages[imageIndex]; + vkResetCommandBuffer(g_vkCommandBuffer, 0); + + VkCommandBufferBeginInfo beginInfo = {}; + beginInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO; + vkBeginCommandBuffer(g_vkCommandBuffer, &beginInfo); + IVulkan::Frame(); + vkEndCommandBuffer(g_vkCommandBuffer); + + VkPipelineStageFlags waitStages[] = {VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT}; + VkSubmitInfo submitInfo = {}; + submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; + submitInfo.waitSemaphoreCount = 1; + submitInfo.pWaitSemaphores = &frame.draw; + submitInfo.pWaitDstStageMask = waitStages; + submitInfo.commandBufferCount = 1; + submitInfo.pCommandBuffers = &g_vkCommandBuffer; + submitInfo.signalSemaphoreCount = 1; + submitInfo.pSignalSemaphores = &frameindex.present; + + vkQueueSubmit(g_drawQueue, 1, &submitInfo, frame.fence); + + VkPresentInfoKHR presentInfo = {}; + presentInfo.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR; + presentInfo.waitSemaphoreCount = 1; + presentInfo.pWaitSemaphores = &frameindex.present; + presentInfo.swapchainCount = 1; + presentInfo.pSwapchains = &g_swapchain; + presentInfo.pImageIndices = &imageIndex; + + + r = vkQueuePresentKHR(g_presentQueue, &presentInfo); + if (r == VK_ERROR_OUT_OF_DATE_KHR || r == VK_SUBOPTIMAL_KHR) + { + vkDeviceWaitIdle(g_vkDevice); + IVideo_SwapchainDestroy(); + IVideo_SwapchainInit(); + return; + } + + g_bConfigNotify = 0; + s_frameID=(s_frameID+1)%g_nNumSwapchainImages; +}; diff --git a/external/SDL b/external/SDL new file mode 160000 index 0000000..b512735 --- /dev/null +++ b/external/SDL @@ -0,0 +1 @@ +Subproject commit b51273512b8eaf6c42986335fefb4235a444e505 diff --git a/fpc/build.sh b/fpc/build.sh new file mode 100644 index 0000000..e69de29 diff --git a/fpc/main.cpp b/fpc/main.cpp new file mode 100644 index 0000000..e69de29 diff --git a/funnyassets/__build.c b/funnyassets/__build.c index b5ce5a1..3bdbdf8 100644 --- a/funnyassets/__build.c +++ b/funnyassets/__build.c @@ -1,3 +1,4 @@ +#include "god/build.h" #include "god/slang.h" #include "god/utils.h" #include "god/common.h" @@ -13,7 +14,7 @@ void build_shader(char *name, enum slang_stage stage) mv(string_clone("funnyassets/_rtt/gfx/%s.spv",name),file); }; -void makepak(char *name) +void makepak(struct build_data b, char *name) { struct run_project rp = run_new("python"); run_add_arg(&rp, "tools/makepak64.py"); @@ -28,9 +29,11 @@ void assets_build(struct build_data b) makedir("funnyassets/_rtt/gfx"); build_shader("brush_frag", SLANG_STAGE_FRAGMENT); build_shader("brush_vert", SLANG_STAGE_VERTEX); + build_shader("mesh_frag", SLANG_STAGE_FRAGMENT); + build_shader("mesh_vert", SLANG_STAGE_VERTEX); mv("funnyassets/_rtt/","funnyassets/maps"); mv("funnyassets/_rtt/","funnyassets/gfx"); mv("funnyassets/_rtt/","funnyassets/textures"); mv("funnyassets/_rtt/","funnyassets/materials"); - makepak("rtt"); + makepak(b, "rtt"); } diff --git a/funnyassets/_rtt/gfx/mesh_frag.spv b/funnyassets/_rtt/gfx/mesh_frag.spv new file mode 100644 index 0000000000000000000000000000000000000000..060bbd107ba4a7e9308b7d04e270e9fbc3bda124 GIT binary patch literal 1396 zcmZ9M+iMd+6vj`JZrXb3#o888Luy|HK?H*c;*F|l)zs8he9~n!Ya2;+%kD(tn}3ym zn=gXjZ#PpUXE{4_zH^;#HmTQk7A%^x+h+DzimX}9eqXKDIoZorFLCxOwq)~KYtoS$ zq&Qwn*QFn%OVU-v<6n^0^<30SZlnkQAUzxVyW=0)3b~}mEbcm=4<<)G%iT#5e;a1b zwbN zz0PrFbHgu5KihvnOo-SP&t5i2eb41?bUp%k z_>r$+KJ6nh1aHYq9&vC5uRfXhah??gH7VmJ;LskXa1gz@ACTC60bz5E-!g6x-9<(f0rs#NiLTgxbvX zNLszNI~a4F};&>#9uLcKPL1Ih)!?!dlWT#Zw!b8CtUGLk>9pWv%%6 z&NuX4(b|#{b7yM97ycW1!y!3fP4$99Fml(lwxmc?9pDH*cu;cS0Uz^R(aJr6g?{=u zmV$pnJN(37)2^eHd6|zh1;IwHtA543*-h=?7n@r91W3TJ-;`G6hl`$UYIBFo!v08V z_UkF}$J*iJ{EuYAC9}~Ro3rqZgJIK;`$VwG=l-biK-I|$X8`*n3!WeA&HeD7LapbD zg@;Wk_2GvYIN6edA1VfpKTR=elgAm~N|^&6dGOJdf`3#e&T}xu=!v}3>EPo~iVsD? Y%stg6@4b{5czU9faXzrWihL;j2NADz5C8xG literal 0 HcmV?d00001 diff --git a/funnyassets/_rtt/gfx/mesh_vert.spv b/funnyassets/_rtt/gfx/mesh_vert.spv new file mode 100644 index 0000000000000000000000000000000000000000..73c788a9e9e0a5d23773f739781b3a89f1bd5924 GIT binary patch literal 2776 zcma)+TW?fV6vuZvowkMo0ufNL7I`5dArKp5LX??SXi3Bj;R8$#bbul4oaW3als9QY zpH%RE1H{{dkKRyF0Tlu93-My&|98$>ot-|pCu`PP|GjQ|tu<5W-!T-bePL$^;U5ua zL+B5E;_E`C(2>`NHHF--@42MiL3vtqK(r)U7OfL)5LNWS8oz27Ebw+`ej(pIpLW}M zJC%1;A8bo};fzEfBVmhp^Kg=9?Zu;cnk6S&%@ea}l8-NrHz(8C!^!D1>*h0i$M*z9 zt`_$A&LnvPC&p&+qp#Lqn`$Dv6vDQp_=oM_-p1J6aCr@=+-L9@2XM*ZLGHZA>42PPq1D!lO*GSu)yy($N3HWi( zIqvmIu7;sv)~!{3*b$TYuexipC%ZM;Y8cQ)_4Z~;I=eC|;-Iq&=)4botN5VkanZCQ zuos*iC6i61m>Y4qXXc#V{Xnsw+e^5J$vmGk9iIu4-3N@>a8_f~1y&Qe9l606gku%M zrp2kTCXOBV$Q+N&JC~%FzpV1z^wImW$$p31i(gdPo6VBx%a~}3{D;KR2TUI}ot)eg zn|taSlfG7*w}7M5Uv&JQkiN0NOKg|vn}l&(e^N5}w&|NWQ3KehvM?twWM+a+o~OjA z2@HLk>81TZcvd=bh>P!pIB}?HQhZFr8P#j*;@pEf;Zu{&9r2mTW1^br2TkXmchHlw zq7Yu+kNtT`^oSbJFPKhW_DQF2>};Ru^o^Z$o%gX{{UYqi&wnE|pc8*dL=JS~FPr{? zc7r(hab~g=+bNpghoa0wv!pPwmd-jJ2oZ~tElnfT04a znR(DJ-a|gW`&%+|p>KCY??2`X)&YZ8^ zy$8p~pM8Gcfx*qjn28q-j_yBnVBf@;>35gmUq^4NG1jfiTCKfzvnd){@dQQT7i4zr}++x-C=wBU$Ljo z&t$OC3ylyN5Ii6el)?hJ4uUebdqlLoHE+8Yzp_XAXYJEH*Sy7bL=40~#rf$xLd!K{ z0gD45vB^O+LS#BSL{JKw97G}y8MA=(^zr!&;baCNMJ8ak{5`AdqDqECRUse+GC|}P zJGou)->sQcN$`)|hka6E5d$VShEpR%=CH9|h@g~7jtHyHZ=>^meuuj-k~E zNO7GY(gN2W5upp512CE3DT1=la>k-AGy+m)s2&Sl$Z3JM#vWlov%s&u*=bd?rwEZ< zy4V_fga}GuRgdVMF||2nYPBpr9JxC?6;_p&MrheZ*QtEIY6PUXRtO|dCKW=qDmIfrU?Nl+HG9~JPI;Fm=cLxsLk0|yZWNtGxv417es^t58kB+ zNP%oZaA!Gxy|mmxO!?>XfBu08iwEMPXRmpy+Dx1$f?fbE2udGzh~$~7Gr~0x@|1t~ z-f#SKWbKxZy}jXV(j!t%`UzI6?TvN8lHyYgHmM6iXqhfEjexYFI^i&%7y9K$djtu3 zf{$l<6T_Jz*dw}MGy)w;uM|SwY$Sy6g0Co$VAQ~(z~KdKB|>CC5KRQ7u*oZmjen|T zSTjZ%0Vxn_Uf|5!P0MtcH3CvxCkS0mjXmNEKVwgz&CnaLLz5>Z7FCEG?^v#D{p?5( zkOG+?bO?1uxXv>aG+&j1yUiTwDQ;& zK!gJZ1a^lPEvG;8UchdM2wnuVAh0_TKq`cUlZiw|xDH9hs9}9HC6x}RGJOz8fuIx? z*L5%Su*1$Wa=6a3FR$Ebhh1UA9$md)|9WF3gWV93XMz?4rLaJ%Sjf&yBo4)O2M{dl^nzy&J8K*f?bF-rslk8jk~;wH?6zMwM!*ZA^GqWk z#dU(gGB~TXp4&f&aENUc{Ru!Tw7le9l7H- z``TJ}v`J}IA>ak?rwB-aR0zqxDY0gDWL*|hbF03sPB@EBy*|65$8R+P8R5r-ASi`R zI@PFW2c1XPa$Oeq4M+c$gQmwTY|Ka%0FqT@r#d6 zX}cTe<)dX29}l!e?E1f{U*X{KKeWz2-Qgb5a6fkDUV)i83Z5uryK z5tPEJ*{RR0v!JKe{_7|0PftzSsnrwq%HZ4HCIv2G(=r_kjer!_34)UK2@F4U`AwplI4K5{D7C@M@r!Bm|ixRzA2f>PzQJf-h0D4tN zNG+sZ=w`86F#d PX6(@L_)F&Q9Xrkc222># literal 6290 zcmaKwTZmRw6vy|M(o^I^FM%Tt7)cMBUFNOkY%CwL3pEt<(9oEs4NjBjkOWcZA?ad7 zHxLHF5DF=X!YGyM>@ON2??X`tF*ZzwNa0gb5c9SFd!PSaYk%LF5r+Rd2iI?}y)OHl z^X;6N*!t|I9h=h&8AJ2veeH^cri{_AhgcPi&?*E0R>PG@C1w@Wv+`>gGo zK3YJFx%GofKAH=m4`vd&b?k zYN+`A;F_>9_450x?E(n888gzRtr2j=b%rqY$_U=Hml|VzG~TwgZQQ5jT8q`8gTpV` zL&uL6&=iG6h#L^xAQ5zh0=WQ!Zit9>-<#*{!0gv{&+wFeYVcxETqndx`mfl3+(=9< zZRP@s4WO{uMl_<#5R8Hdx;2)eS!31QX#Z3_PMshg6GK0pqj z*ucS&`FtaS&~C7qBO>Su?P_qJ^g0hRoig}kXmCts|IOEi35B9MX(Ps;4-ui=T0R%? z?8p&tMJ_S~(#a?^P7p{ZqJS%P0fb&T7Pj9E3Pwytc*g&h>VYnc`@$z_7isd z(bX3E;*t4ccycCaLoT$N*kwY{6$+$6#BoAS*iMK-B6@tuhxW-0mu&l|x0Bv}sagmj z8zG`}8Ua^aXNa)6UsXpDZB|M*I1j+=1kVw4i%1vH8Ua^UsLq9M@s%Av5j8mJ(Ov~GRIC6DPDpa+WMrgM)eo~tda0OB!P=9&+ zgw)!YO4wzvdDI|{IJKYy!|&<7$Pv*E=q3bQfm{$FZh|llg`DY3+gH{MCEYmvO>-1P z7{3W_Fh{@@$Swo}u5(~(^%!i*xIZra8y<*IJP;o~b}^_LvtC4uq8mZi2R$NtrZV7A z4fQ~@$$t0lZ^LtB{`!xD{^vED5oss=1Z(-H8T*1Q#itlF>kC0>H{E6$0oShXL{sy5 zpkMdK=2iX z2)aVESCkwg7*bMS16DwovgnEug{B!K=2$h zAi9d$i$E0lMu4Czqe)Ses*q)BCtn%9@fF|go3ZB~+GC+VKlYlPeZ&P_6oDv+E)#;T zP#_gTIQNMSDD7XP4aIFxMP8Jdsp&cuNqlW#_Q&a|= zyCD}5EeN_ofvls@haFayBZqcbe0Ag ziz5&P(Pg0#aK&|o;7J8H+K33YvtAufDJV`Y6twxtUL&HLAj*OWxB zC?ZA?(So2WH0w_Jbg5J5PzAAF#qSV)(m>H8skNFAu98oh906A#GlYJoT6K=nc2#-Z zU3U8|zuH&l2a;y3)r3G4yq_cB3Zz0v{f&do>WJ;C$>}R$toD1wq+Xr6tdHMj1S-Oh z2|>^mnoX)v&khEUiqLiye#6nf0~as1+=Q$^8>h*8A*f}kr@ePl}JQ4#ssL+m(aCznl!NktAYW-1rWh*%NM2!eq=j896m=U}zEQ)ZIpanr!sCt^A{&G^u?>F5?4h}k=UR_5{ zGa}ANM8|XjL070cJ7xd*F{4kdEmsfNAD`H3C$H?c=Qh6;G;454n|9N=&)1CQ7^ahFGMi`Ys#22C%1yd+3=PDq~vBMTo;6;hi zEP!A~V&pg@8i5Tksv4o|ua6m-T7TsDN^o^3kquGkV@CQ#Hi8MohM+(-M4?yK2u8ux gyAWfe+n$;5zQ(lt-{|> 16) ^ x) * 0x45d9f3b; + x = ((x >> 16) ^ x) * 0x45d9f3b; + x = (x >> 16) ^ x; + return x; +} + +[[vk::binding(1)]] +uniform Sampler2D textures[]; + + +float4 main( + VertexOutput input, + uint triid: SV_PrimitiveID, + uniform PushConstants constants, +) : SV_TARGET +{ + return float4(textures[constants.albedoID].Sample(input.uv).xyz, 1); + +} + diff --git a/funnyassets/gfx_shaders/mesh_shared.slang b/funnyassets/gfx_shaders/mesh_shared.slang new file mode 100644 index 0000000..c4d96ff --- /dev/null +++ b/funnyassets/gfx_shaders/mesh_shared.slang @@ -0,0 +1,15 @@ +#pragma once + +struct VertexOutput +{ + float4 position: SV_Position; + float2 uv: TEXCOORD0; +}; + +struct PushConstants +{ + float4x4 modelMatrix; + uint albedoID; + uint roughnessID; + uint metalnessID; +}; diff --git a/funnyassets/gfx_shaders/mesh_vert.slang b/funnyassets/gfx_shaders/mesh_vert.slang new file mode 100644 index 0000000..3204921 --- /dev/null +++ b/funnyassets/gfx_shaders/mesh_vert.slang @@ -0,0 +1,24 @@ +#include "mesh_shared.slang" + +struct VertexInput +{ + float3 position: POSITION; + float2 uv: TEXCOORD0; +}; + +[[vk::binding(0)]] +cbuffer CameraInfo +{ + float4x4 projection; +}; + +VertexOutput main( + VertexInput input, + uniform PushConstants constants, +) +{ + VertexOutput output; + output.position = mul(projection, mul(constants.modelMatrix, float4(input.position,1))); + output.uv = input.uv; + return output; +} diff --git a/funnyassets/maps/test_map.fmap b/funnyassets/maps/test_map.fmap index eaba6618205c7b842403f9fc69ab189d918e3a9c..5d27d77d44feafb8f855fe5fd6fe900c943af8d6 100644 GIT binary patch literal 6290 zcmaKwU1%Le6vwAc@JZ~e(3Au!1|L$Ym^aN%s(rA2ph3Y0LsL_YAu*OV7zDBVVDTd& zR)x|~s05UvAW8+BqV85q!P?peMF~i1h?NkOJXsV??2`X)&YZ8^ zy$8p~pM8Gcfx*qjn28q-j_yBnVBf@;>35gmUq^4NG1jfiTCKfzvnd){@dQQT7i4zr}++x-C=wBU$Ljo z&t$OC3ylyN5Ii6el)?hJ4uUebdqlLoHE+8Yzp_XAXYJEH*Sy7bL=40~#rf$xLd!K{ z0gD45vB^O+LS#BSL{JKw97G}y8MA=(^zr!&;baCNMJ8ak{5`AdqDqECRUse+GC|}P zJGou)->sQcN$`)|hka6E5d$VShEpR%=CH9|h@g~7jtHyHZ=>^meuuj-k~E zNO7GY(gN2W5upp512CE3DT1=la>k-AGy+m)s2&Sl$Z3JM#vWlov%s&u*=bd?rwEZ< zy4V_fga}GuRgdVMF||2nYPBpr9JxC?6;_p&MrheZ*QtEIY6PUXRtO|dCKW=qDmIfrU?Nl+HG9~JPI;Fm=cLxsLk0|yZWNtGxv417es^t58kB+ zNP%oZaA!Gxy|mmxO!?>XfBu08iwEMPXRmpy+Dx1$f?fbE2udGzh~$~7Gr~0x@|1t~ z-f#SKWbKxZy}jXV(j!t%`UzI6?TvN8lHyYgHmM6iXqhfEjexYFI^i&%7y9K$djtu3 zf{$l<6T_Jz*dw}MGy)w;uM|SwY$Sy6g0Co$VAQ~(z~KdKB|>CC5KRQ7u*oZmjen|T zSTjZ%0Vxn_Uf|5!P0MtcH3CvxCkS0mjXmNEKVwgz&CnaLLz5>Z7FCEG?^v#D{p?5( zkOG+?bO?1uxXv>aG+&j1yUiTwDQ;& zK!gJZ1a^lPEvG;8UchdM2wnuVAh0_TKq`cUlZiw|xDH9hs9}9HC6x}RGJOz8fuIx? z*L5%Su*1$Wa=6a3FR$Ebhh1UA9$md)|9WF3gWV93XMz?4rLaJ%Sjf&yBo4)O2M{dl^nzy&J8K*f?bF-rslk8jk~;wH?6zMwM!*ZA^GqWk z#dU(gGB~TXp4&f&aENUc{Ru!Tw7le9l7H- z``TJ}v`J}IA>ak?rwB-aR0zqxDY0gDWL*|hbF03sPB@EBy*|65$8R+P8R5r-ASi`R zI@PFW2c1XPa$Oeq4M+c$gQmwTY|Ka%0FqT@r#d6 zX}cTe<)dX29}l!e?E1f{U*X{KKeWz2-Qgb5a6fkDUV)i83Z5uryK z5tPEJ*{RR0v!JKe{_7|0PftzSsnrwq%HZ4HCIv2G(=r_kjer!_34)UK2@F4U`AwplI4K5{D7C@M@r!Bm|ixRzA2f>PzQJf-h0D4tN zNG+sZ=w`86F#d PX6(@L_)F&Q9Xrkc222># literal 6290 zcmaKwTZmRw6vy|M(o^I^FM%Tt7)cMBUFNOkY%CwL3pEt<(9oEs4NjBjkOWcZA?ad7 zHxLHF5DF=X!YGyM>@ON2??X`tF*ZzwNa0gb5c9SFd!PSaYk%LF5r+Rd2iI?}y)OHl z^X;6N*!t|I9h=h&8AJ2veeH^cri{_AhgcPi&?*E0R>PG@C1w@Wv+`>gGo zK3YJFx%GofKAH=m4`vd&b?k zYN+`A;F_>9_450x?E(n888gzRtr2j=b%rqY$_U=Hml|VzG~TwgZQQ5jT8q`8gTpV` zL&uL6&=iG6h#L^xAQ5zh0=WQ!Zit9>-<#*{!0gv{&+wFeYVcxETqndx`mfl3+(=9< zZRP@s4WO{uMl_<#5R8Hdx;2)eS!31QX#Z3_PMshg6GK0pqj z*ucS&`FtaS&~C7qBO>Su?P_qJ^g0hRoig}kXmCts|IOEi35B9MX(Ps;4-ui=T0R%? z?8p&tMJ_S~(#a?^P7p{ZqJS%P0fb&T7Pj9E3Pwytc*g&h>VYnc`@$z_7isd z(bX3E;*t4ccycCaLoT$N*kwY{6$+$6#BoAS*iMK-B6@tuhxW-0mu&l|x0Bv}sagmj z8zG`}8Ua^aXNa)6UsXpDZB|M*I1j+=1kVw4i%1vH8Ua^UsLq9M@s%Av5j8mJ(Ov~GRIC6DPDpa+WMrgM)eo~tda0OB!P=9&+ zgw)!YO4wzvdDI|{IJKYy!|&<7$Pv*E=q3bQfm{$FZh|llg`DY3+gH{MCEYmvO>-1P z7{3W_Fh{@@$Swo}u5(~(^%!i*xIZra8y<*IJP;o~b}^_LvtC4uq8mZi2R$NtrZV7A z4fQ~@$$t0lZ^LtB{`!xD{^vED5oss=1Z(-H8T*1Q#itlF>kC0>H{E6$0oShXL{sy5 zpkMdK=2iX z2)aVESCkwg7*bMS16DwovgnEug{B!K=2$h zAi9d$i$E0lMu4Czqe)Ses*q)BCtn%9@fF|go3ZB~+GC+VKlYlPeZ&P_6oDv+E)#;T zP#_gTIQNMSDD7XP4aIFxMP8Jdsp&cuNqlW#_Q&a|= zyCD}5EeN_ofvls@haFayBZqcbe0Ag ziz5&P(Pg0#aK&|o;7J8H+K33YvtAufDJV`Y6twxtUL&HLAj*OWxB zC?ZA?(So2WH0w_Jbg5J5PzAAF#qSV)(m>H8skNFAu98oh906A#GlYJoT6K=nc2#-Z zU3U8|zuH&l2a;y3)r3G4yq_cB3Zz0v{f&do>WJ;C$>}R$toD1wq+Xr6tdHMj1S-Oh z2|>^mnoX)v&khEUiqLiye#6nf0~as1+=Q$^8>h*8A*f}kr@ePl}JQ4#ssL+m(aCznl!NktAYW-1rWh*%NM2!eq=j896m=U}zEQ)ZIpanr!sCt^A{&G^u?>F5?4h}k=UR_5{ zGa}ANM8|XjL070cJ7xd*F{4kdEmsfNAD`H3C$H?c=Qh6;G;454n|9N=&)1CQ7^ahFGMi`Ys#22C%1yd+3=PDq~vBMTo;6;hi zEP!A~V&pg@8i5Tksv4o|ua6m-T7TsDN^o^3kquGkV@CQ#Hi8MohM+(-M4?yK2u8ux gyAWfe+n$;5zQ(lt-{| g_entities; typedef CBaseEntity*(*EntityRegistryFn)( void ); typedef C_BaseEntity*(*ClientEntityRegistryFn)( void ); -class CEntityRegistry +interface CEntityRegistry { public: CEntityRegistry( const char *szName, const char *szClass, EntityRegistryFn pfn ); @@ -43,7 +46,6 @@ public: ClientEntityRegistryFn m_pClientfn; }; -extern CUtlVector g_RegisteredEntities; #define DECLARE_ENTITY(name, class) \ @@ -66,9 +68,10 @@ public: virtual void Destroy( void ) = 0; /* happens every frame instead of tick */ virtual void Think( float fDelta ) = 0; +private: }; -class C_EntityRegistry +interface C_EntityRegistry { public: C_EntityRegistry( const char *pName, ClientEntityRegistryFn pfn ); @@ -82,6 +85,8 @@ C_BaseEntity *__c_entity_alloc_##server() \ C_EntityRegistry __c_entity_##server##_registry(#server, __c_entity_alloc_##server); \ +extern CUtlSelfReferencingVector g_entities; +extern CUtlVector g_RegisteredEntities; #endif diff --git a/public/console.h b/public/console.h index ff7371e..5815ac9 100644 --- a/public/console.h +++ b/public/console.h @@ -1,7 +1,7 @@ #ifndef CONSOLE_H #define CONSOLE_H -#include "tier0/platform.h" +#include "engine.h" #include "tier1/utlstring.h" class ConVar; @@ -95,4 +95,4 @@ void Msg( const char* message ); void Warning( const char* message ); void Error( const char* message ); -#endif \ No newline at end of file +#endif diff --git a/public/engine.h b/public/engine.h index d9ed617..6149938 100644 --- a/public/engine.h +++ b/public/engine.h @@ -1,6 +1,7 @@ #ifndef ENGINE_H #define ENGINE_H +/* for windows as it sucks */ #include "tier0/platform.h" class CBaseEntity; @@ -17,11 +18,9 @@ public: interface IIEngine { public: - static void PrecacheModel( const char *psz ); - static void PrecacheSound( const char *psz ); - static CBaseEntity *SpawnEntity( const char *szName ); static void DestroyEntity( CBaseEntity *pEntity ); }; + #endif diff --git a/public/filesystem.h b/public/filesystem.h index 6f1d9b6..787c021 100644 --- a/public/filesystem.h +++ b/public/filesystem.h @@ -3,6 +3,7 @@ #include "tier0/platform.h" #include "tier1/utlbuffer.h" #include "tier1/utlstring.h" +#include "engine.h" enum EFileOptions { diff --git a/public/level.h b/public/level.h index 90b35f1..f631215 100644 --- a/public/level.h +++ b/public/level.h @@ -1,7 +1,7 @@ #ifndef LEVEL_H #define LEVEL_H -#include "tier0/platform.h" +#include "engine.h" interface ILevel { diff --git a/public/physics_gen.h b/public/physics_gen.h index 2aa56b5..7fbab84 100644 --- a/public/physics_gen.h +++ b/public/physics_gen.h @@ -60,6 +60,8 @@ struct px_cast_result px_box_cast(struct funnyphysics *px_world, struct px_vec3 vel, float time); +void px_fixedbody(struct funnyphysics *px_world, Collider *collider); + void px_frame(struct funnyphysics *px_world, float delta); struct px_matrix px_getmatrix(struct funnyphysics *px_world, RigidBodyHandle *body); diff --git a/public/rendering.h b/public/rendering.h index 77aadd2..a0903ce 100644 --- a/public/rendering.h +++ b/public/rendering.h @@ -29,20 +29,6 @@ public: virtual void Unmap() = 0; }; -abstract_class IBrush -{ -public: - virtual void SetPosition( vec3 position ) = 0; - virtual void SetRotationEuler( vec3 angle ) = 0; - virtual void SetRotationQuat( vec4 quaternion) = 0; - virtual void SetMatrix( mat3 matrix ) = 0; - virtual void SetScale( vec3 scale ) = 0; - - virtual void SetVertexBuffer( IVertexBuffer *pBuffer ) = 0; - virtual void SetIndexBuffer( IIndexBuffer *pBuffer ) = 0; - virtual void Draw() = 0; -}; - enum EMaterialType { IMATERIAL_ERROR = 0, @@ -82,20 +68,64 @@ public: Material_t m; }; +interface IRenderer +{ +public: + + static IVertexBuffer *CreateVertexBuffer( uint32_t uSize ); + static IIndexBuffer *CreateIndexBuffer( uint32_t uSize ); + + static IMaterial *LoadMaterial( const char *szName ); + static void SetMaterial( IMaterial *pMaterial ); +}; + + +//---------------------------------------------------------------------------- +// Brush handler for the rendering +//---------------------------------------------------------------------------- +abstract_class IBrush +{ +public: + virtual void SetVertexBuffer( IVertexBuffer *pBuffer ) = 0; + virtual void SetIndexBuffer( IIndexBuffer *pBuffer ) = 0; + virtual void Draw() = 0; +}; + interface IBrushRenderer { public: static void Init(); static void Frame( float fDelta ); - static IVertexBuffer *CreateVertexBuffer( uint32_t uSize ); - static IIndexBuffer *CreateIndexBuffer( uint32_t uSize ); - static IBrush *CreateMesh(); static void Destroy( IBrush *pModel ); +}; - static IMaterial *LoadMaterial( const char *szName ); - static void SetMaterial( IMaterial *pMaterial ); +//---------------------------------------------------------------------------- +// Mesh handler for the rendering +//---------------------------------------------------------------------------- +abstract_class IMesh +{ +public: + virtual void SetPosition( vec3 position ) = 0; + virtual void SetRotationEuler( vec3 angle ) = 0; + virtual void SetRotationQuat( vec4 quaternion) = 0; + virtual void SetMatrix( mat4 matrix ) = 0; + virtual void SetScale( vec3 scale ) = 0; + + virtual void SetVertexBuffer( IVertexBuffer *pBuffer ) = 0; + virtual void SetIndexBuffer( IIndexBuffer *pBuffer ) = 0; + virtual void Draw() = 0; +}; + +interface IMeshRenderer +{ +public: + static void Init(); + static void Frame( float fDelta ); + + static IMesh *CreateMesh(); + static void Destroy( IBrush *pModel ); }; abstract_class ITexture diff --git a/public/tier0/platform.h b/public/tier0/platform.h index 710fbd1..32cf75a 100644 --- a/public/tier0/platform.h +++ b/public/tier0/platform.h @@ -4,6 +4,16 @@ #include "stdint.h" #include "stddef.h" +#ifdef __WIN32__ +#define DLL_EXPORT extern "C" __declspec(dllexport) +#define DLL_IMPORT extern "C" __declspec(dllimport) + +#define DLL_CLASS_EXPORT __declspec(dllexport) +#define DLL_CLASS_IMPORT __declspec(dllimport) + +#define DLL_GLOBAL_EXPORT extern __declspec(dllexport) +#define DLL_GLOBAL_IMPORT extern __declspec(dllimport) +#else #define DLL_EXPORT extern "C" __attribute__ ((visibility("default"))) #define DLL_IMPORT extern "C" @@ -12,6 +22,7 @@ #define DLL_GLOBAL_EXPORT extern __attribute ((visibility("default"))) #define DLL_GLOBAL_IMPORT extern +#endif #ifdef TIER0_STATIC diff --git a/public/tier1/utlvector.h b/public/tier1/utlvector.h index ac3c944..0fb3021 100644 --- a/public/tier1/utlvector.h +++ b/public/tier1/utlvector.h @@ -320,4 +320,4 @@ void CUtlSelfReferencingVector::RemoveTail( void ) } -#endif \ No newline at end of file +#endif diff --git a/rapier/__build.c b/rapier/__build.c index f7089f9..531dbf7 100644 --- a/rapier/__build.c +++ b/rapier/__build.c @@ -1,3 +1,4 @@ +#include "god/build.h" #include "god/c.h" #include "god/ld.h" #include "god/utils.h" @@ -9,6 +10,12 @@ void rapier_build(struct build_data b) cargo_build.wd = "rapier"; run_add_arg(&cargo_build, "build"); run_add_arg(&cargo_build, "--release"); + if (b.kernel == BUILD_KERNEL_LINUX) + { + run_add_arg(&cargo_build, "--target"); + run_add_arg(&cargo_build, "x86_64-unknown-linux-gnu"); + rapierLib = "rapier/target/x86_64-unknown-linux-gnu/release/librapier_rtt.a"; + } run_run(&cargo_build); struct run_project cbindgen = run_new("cbindgen"); cbindgen.wd = "rapier"; @@ -17,7 +24,6 @@ void rapier_build(struct build_data b) run_add_arg(&cbindgen, "--crate"); run_add_arg(&cbindgen, "rapier_rtt"); run_add_arg(&cbindgen, "--output"); - run_add_arg(&cbindgen, "../public/physics_gen.h"); + run_add_arg(&cbindgen, "../public/physics_gen.h"); run_run(&cbindgen); - rapierLib = "rapier/target/release/librapier_rtt.a"; } diff --git a/rapier/px.rs b/rapier/px.rs index 390436e..2105215 100644 --- a/rapier/px.rs +++ b/rapier/px.rs @@ -49,9 +49,9 @@ pub unsafe extern "C" fn px_frame(px_world: *mut funnyphysics, delta:f32) { let gravity = vector![0.0, 0.0, -9.81]; let mut integration_parameters = IntegrationParameters::default(); integration_parameters.dt=delta; - integration_parameters.min_island_size=1; - integration_parameters.num_solver_iterations=NonZeroUsize::new(4).unwrap(); - integration_parameters.num_internal_stabilization_iterations=2; + integration_parameters.min_island_size=256; + integration_parameters.num_solver_iterations=NonZeroUsize::new(8).unwrap(); + integration_parameters.num_internal_stabilization_iterations=4; let physics_hooks = (); let event_handler = (); if let Some(px) = px_world.as_mut() { @@ -107,6 +107,13 @@ pub unsafe extern "C" fn px_staticbody(px_world: *mut funnyphysics, collider: *m Box::into_raw(Box::new(body)) } +#[unsafe(no_mangle)] +pub unsafe extern "C" fn px_fixedbody(px_world: *mut funnyphysics, collider: *mut Collider) { + let c = &mut *collider; + let px = px_world.as_mut().unwrap(); + px.collider_set.insert(c.clone()); +} + #[repr(C)] pub struct px_matrix { diff --git a/src/main.rs b/src/main.rs deleted file mode 100644 index e7a11a9..0000000 --- a/src/main.rs +++ /dev/null @@ -1,3 +0,0 @@ -fn main() { - println!("Hello, world!"); -} diff --git a/tier0/__build.c b/tier0/__build.c index a52e972..64c8893 100644 --- a/tier0/__build.c +++ b/tier0/__build.c @@ -1,7 +1,8 @@ +#include "god/build.h" #include "god/c.h" #include "god/ld.h" -char* tier0_dll = 0; +char* tier0_lib = 0; void tier0_build(struct build_data b) { char* files[] = { @@ -33,9 +34,9 @@ void tier0_build(struct build_data b) NULL, }; - tier0_dll = ld_link_project(o, (struct link_settings){ + tier0_lib = ld_link_project(o, (struct link_settings){ .type = LINK_TYPE_DYNAMIC, .libs = libs, }); - mv("build/"GAME_NAME"/game/bin/libtier0.so",tier0_dll); -} \ No newline at end of file + mv("build/"GAME_NAME"/game/bin/libtier0.so",tier0_lib); +} diff --git a/tier0/platform.cpp b/tier0/platform.cpp index d9caf61..b83899f 100644 --- a/tier0/platform.cpp +++ b/tier0/platform.cpp @@ -3,11 +3,16 @@ #include "stdarg.h" #include "unistd.h" #include "sys/stat.h" -#include "execinfo.h" #include "dirent.h" -#include "dlfcn.h" #include "time.h" - +#ifdef __linux__ +#include "dlfcn.h" +#include "execinfo.h" +#endif +#ifdef __WIN32__ +#include "windows.h" +#include "dbghelp.h" +#endif PLATFORM_INTERFACE void Plat_FatalErrorFunc(const char* szFormat, ...) { va_list list; @@ -76,6 +81,7 @@ PLATFORM_INTERFACE char *Plat_GetExtension( const char *szPath ) PLATFORM_INTERFACE void Plat_Backtrace( void ) { +#ifdef __linux__ void *buffer[64]; int nptrs = backtrace(buffer, 64); char **symbols = backtrace_symbols(buffer, nptrs); @@ -90,22 +96,64 @@ PLATFORM_INTERFACE void Plat_Backtrace( void ) } free(symbols); +#endif +#ifdef __WIN32__ + void* buffer[64]; + USHORT nptrs = CaptureStackBackTrace(0, 64, buffer, NULL); + + HANDLE process = GetCurrentProcess(); + SymInitialize(process, NULL, TRUE); + + SYMBOL_INFO* symbol = (SYMBOL_INFO*)calloc(sizeof(SYMBOL_INFO) + 256, 1); + symbol->MaxNameLen = 255; + symbol->SizeOfStruct = sizeof(SYMBOL_INFO); + + if (!symbol) { + V_printf("Backtrace failed\n"); + return; + } + + for (USHORT i = 0; i < nptrs; i++) { + if (SymFromAddr(process, (DWORD64)(buffer[i]), 0, symbol)) { + V_printf(" [%d] %s - 0x%0llX\n", i, symbol->Name, symbol->Address); + } else { + V_printf(" [%d] ??? - 0x%0llX\n", i, (DWORD64)(buffer[i])); + } + } + + free(symbol); +#endif }; PLATFORM_INTERFACE void *Plat_LoadLibrary( const char *psz ) { +#ifdef __linux__ void *lib = dlopen(psz, RTLD_GLOBAL | RTLD_NOW); if (!lib) V_printf("Failed to open %s\n\t%s\n", psz, dlerror()); return lib; +#endif +#ifdef __WIN32__ + return LoadLibraryA(psz); +#endif } PLATFORM_INTERFACE void *Plat_GetProc( void *lib, const char *psz ) { +#ifdef __linux__ return dlsym(lib, psz); +#endif +#ifdef __WIN32__ + return (void*)GetProcAddress((HMODULE)lib, psz); +#endif } PLATFORM_INTERFACE void Plat_UnloadLibrary( void *lib ) { +#ifdef __linux__ dlclose(lib); +#endif +#ifdef __WIN32__ + FreeLibrary((HMODULE)lib); +#endif }; PLATFORM_INTERFACE double Plat_GetTime( void )