diff --git a/engine/vk_video.cpp b/engine/vk_video.cpp index cf1444f..0d5f30b 100644 --- a/engine/vk_video.cpp +++ b/engine/vk_video.cpp @@ -174,7 +174,6 @@ void IVulkan::Init() }; void IVulkan::CreatePipelines() { - V_printf("Created %i pipelines\n",g_StepMeshRendering.GetSize()); for (auto &step: g_StepPrepass) step.pPipeline->Init(); for (auto &step: g_StepMeshRendering) diff --git a/fgui/__build.cpp b/fgui/__build.cpp index 5e0fc68..efe223f 100644 --- a/fgui/__build.cpp +++ b/fgui/__build.cpp @@ -7,7 +7,7 @@ CUtlVector fgui_CompiledFiles = { "fgui/fgui.cpp", "fgui/widget.cpp", - "fgui/rectangle.cpp", + "fgui/rect.cpp", "fgui/label.cpp", }; CUtlString fgui_lib; diff --git a/fgui/fgui.cpp b/fgui/fgui.cpp index f3b3867..0eef478 100644 --- a/fgui/fgui.cpp +++ b/fgui/fgui.cpp @@ -3,10 +3,17 @@ #include "rendering.h" #include "tier1/utlvector.h" #include "fgui/widget.h" +#include +float fgui_fRectColor[4]; +float fgui_fTextColor[4]; +float fgui_fTextPosition[2]; +CFont *fgui_pTextFont; IGraphicsPipeline *fgui_RectPipeline; IGraphicsPipeline *fgui_TextPipeline; +IVertexBuffer *fgui_pRectangleBuffer; +IVertexBuffer *fgui_pUVRectangleBuffer; void IFGUI::Init( void ) { @@ -18,30 +25,78 @@ void IFGUI::Frame( void ) } + +//---------------------------------------------------------------------------- +// Creates new widget in the world +//---------------------------------------------------------------------------- CUtlVector fgui_widgets; void IFGUI::AppendWidget( CFGUI_Widget *pWidget ) { fgui_widgets.AppendTail(pWidget); } +//---------------------------------------------------------------------------- +// Destroys widget +//---------------------------------------------------------------------------- void IFGUI::DestroyWidget( CFGUI_Widget *pWidget ) { + size_t i = 0; + for (auto &widget: fgui_widgets) + { + if (widget == pWidget) + { + fgui_widgets.RemoveAt(i); + return; + } + i++; + } } +//---------------------------------------------------------------------------- +// +//---------------------------------------------------------------------------- void IFGUI::SetRectColor( float r, float g, float b, float a ) { - + fgui_fRectColor[0] = r; + fgui_fRectColor[1] = g; + fgui_fRectColor[2] = b; + fgui_fRectColor[3] = a; } +//---------------------------------------------------------------------------- +// Draws rectangle on the screen +//---------------------------------------------------------------------------- void IFGUI::DrawRect( int32_t iPosX, int32_t iPosY, uint32_t uSizeX, uint32_t uSizeY ) { + IRenderer::BindPipeline(fgui_RectPipeline); + struct RectConstants_t + { + uint32_t nResolution[2]; + uint32_t nSize[2]; + int32_t nPosition[2]; + float offest0[2]; + float fColor[4]; + } constants; + constants.nResolution[0] = g_nWindowWidth; + constants.nResolution[1] = g_nWindowHeight; + constants.nPosition[0] = iPosX; + constants.nPosition[1] = iPosY; + constants.nSize[0] = uSizeX; + constants.nSize[1] = uSizeY; + for ( int i = 0; i < 4; i++ ) + constants.fColor[i] = fgui_fRectColor[i]; + IRenderer::SetConstants(sizeof(RectConstants_t), &constants); + IRenderer::Draw(fgui_pRectangleBuffer, NULL); } CUtlVector fgui_fonts; CFont *fgui_pCurrentFont; +//---------------------------------------------------------------------------- +// Loads new font +//---------------------------------------------------------------------------- CFont *IFGUI::LoadFont( CUtlString szFontPath ) { for (auto &font: fgui_fonts) @@ -57,31 +112,90 @@ CFont *IFGUI::LoadFont( CUtlString szFontPath ) IFileSystem::Read(f, b.GetMemory(), IFileSystem::Size(f)); IFileSystem::Close(f); char cCharacterSet[256] = {}; + V_memset(cCharacterSet, 0, 256); uint32_t nElementsWidth; uint32_t nElementsHeight; V_sscanf(b, "%u %u %255s", &nElementsWidth, &nElementsHeight, cCharacterSet); - V_printf("%i %i\n", nElementsWidth, nElementsHeight); + uint32_t nGlyphWidth = pFont->pTexture->x / nElementsWidth; + uint32_t nGlyphHeight = pFont->pTexture->y / nElementsHeight; + for ( int i = 0; i < 255; i++ ) + { + if (isprint(cCharacterSet[i]) && !isspace(cCharacterSet[i])) + pFont->cCharacterSet[cCharacterSet[i]] = i; + else + pFont->cCharacterSet[cCharacterSet[i]] = -1; + } + pFont->glyphWidth = nGlyphWidth; + pFont->glyphHeight = nGlyphHeight; + pFont->nGlyphsPerRow = nElementsWidth; + pFont->nGlyphsPerColumn = nElementsHeight; return pFont; } void IFGUI::SetTextFont( CFont *pFont ) { - + fgui_pTextFont = pFont; } void IFGUI::SetTextPos( float x, float y ) { - + fgui_fTextPosition[0] = x; + fgui_fTextPosition[1] = y; } void IFGUI::SetTextColor( float r, float g, float b, float a ) { - + fgui_fRectColor[0] = r; + fgui_fRectColor[1] = g; + fgui_fRectColor[2] = b; + fgui_fRectColor[3] = a; } void IFGUI::DrawText( CUtlString psz ) { + if (fgui_pTextFont == NULL) + { + V_printf("Forgot to call IFGUI::SetTextFont()?\n"); + return; + } + IRenderer::BindPipeline(fgui_TextPipeline); + struct RectConstants_t + { + uint32_t nResolution[2]; + uint32_t nSize[2]; + int32_t nPosition[2]; + float offest0[2]; + float fColor[4]; + float fGlyphPos[2]; + float fGlyphSize[2]; + uint32_t nFont; + } constants; + + constants.nResolution[0] = g_nWindowWidth; + constants.nResolution[1] = g_nWindowHeight; + constants.nPosition[0] = fgui_fTextPosition[0]; + constants.nPosition[1] = fgui_fTextPosition[1]; + constants.nSize[0] = fgui_pTextFont->glyphWidth; + constants.nSize[1] = fgui_pTextFont->glyphHeight; + constants.fGlyphSize[0] = 1.0 / fgui_pTextFont->nGlyphsPerRow; + constants.fGlyphSize[1] = 1.0 / fgui_pTextFont->nGlyphsPerColumn; + constants.nFont = ITextureManager::GetTextureID(fgui_pTextFont->pTexture); + for ( int i = 0; i < 4; i++ ) + constants.fColor[i] = fgui_fRectColor[i]; + + for ( int i = 0; psz[i]; i++) + { + constants.fGlyphPos[0] = fgui_pTextFont->cCharacterSet[psz[i]] % fgui_pTextFont->nGlyphsPerRow; + constants.fGlyphPos[1] = fgui_pTextFont->cCharacterSet[psz[i]] / fgui_pTextFont->nGlyphsPerRow; + if (isprint(psz[i]) && !isspace(psz[i])) + { + IRenderer::SetConstants(sizeof(RectConstants_t), &constants); + IRenderer::PushBindings(); + IRenderer::Draw(fgui_pUVRectangleBuffer, NULL); + } + constants.nPosition[0] += fgui_pTextFont->glyphWidth; + } } class CFGUI_Rendering: public IRenderingPipelineStep @@ -101,10 +215,10 @@ void CFGUI_Rendering::Init() {"gfx/fgui_rect_frag.shader", SHADER_TYPE_FRAGMENT}, }, {}, - 24, + 48, 8, - {{0,0,EVertexFormat::VERTEX_FORMAT_X32Y32}}, - {EImageFormat::IMAGE_FORMAT_R8G8B8A8}, + {{0,0,VERTEX_FORMAT_X32Y32}}, + {IMAGE_FORMAT_R8G8B8A8}, true ); fgui_TextPipeline = IRenderer::CreateGraphicsPipeline( @@ -113,24 +227,75 @@ void CFGUI_Rendering::Init() {"gfx/fgui_text_frag.shader", SHADER_TYPE_FRAGMENT}, }, { - {SHADER_INPUT_TYPE_TEXTURES, 0}, + {SHADER_INPUT_TYPE_TEXTURES, 29}, }, - 25, - 8, - {{0,0,EVertexFormat::VERTEX_FORMAT_X32Y32}}, - {EImageFormat::IMAGE_FORMAT_R8G8B8A8}, + 80, + 16, + {{0,0, VERTEX_FORMAT_X32Y32},{8,1, VERTEX_FORMAT_X32Y32}}, + {IMAGE_FORMAT_WINDOW}, true - ); + ); + { + float vertices[6*2] = { + 0,0, + 0,1, + 1,0, + 1,0, + 0,1, + 1,1, + }; + fgui_pRectangleBuffer = IRenderer::CreateVertexBuffer(sizeof(vertices)); + void *pMapping = fgui_pRectangleBuffer->Map(); + V_memcpy(pMapping, vertices, sizeof(vertices)); + fgui_pRectangleBuffer->Unmap(); + } + { + float vertices[6*4] = { + 0,0, 0,0, + 0,1, 0,1, + 1,0, 1,0, + 1,0, 1,0, + 0,1, 0,1, + 1,1, 1,1, + }; + fgui_pUVRectangleBuffer = IRenderer::CreateVertexBuffer(sizeof(vertices)); + void *pMapping = fgui_pUVRectangleBuffer->Map(); + V_memcpy(pMapping, vertices, sizeof(vertices)); + fgui_pUVRectangleBuffer->Unmap(); + } }; void CFGUI_Rendering::Frame( float fDelta ) { + IRenderer::Barrier(BARRIER_STAGE_TOP, BARRIER_STAGE_COLOR_OUTPUT, {}, { + { + BARRIER_MEMORY_PERMISSIONS_NONE, + BARRIER_MEMORY_PERMISSIONS_COLOR_WRITE, + IRenderer::GetOutputImage(), + } + }); + IRenderer::Begin(g_nWindowWidth, g_nWindowHeight, { + { + IRenderer::GetOutputImage(), + NULL, + ATTACHMENT_LOAD_MODE_LOAD, + ATTACHMENT_STORE_MODE_STORE, + } + }, {}); IRenderer::ResetState(); IRenderer::SetDepthMode(DEPTH_MODE_LESS); for (auto &widget: fgui_widgets) { widget->Draw(); } + IRenderer::End(); + IRenderer::Barrier(BARRIER_STAGE_COLOR_OUTPUT, BARRIER_STAGE_BOTTOM, {}, { + { + BARRIER_MEMORY_PERMISSIONS_COLOR_WRITE, + BARRIER_MEMORY_PERMISSIONS_NONE, + IRenderer::GetOutputImage(), + } + }); }; void CFGUI_Rendering::Deinit() diff --git a/fgui/label.cpp b/fgui/label.cpp index b784020..85e2b06 100644 --- a/fgui/label.cpp +++ b/fgui/label.cpp @@ -8,7 +8,7 @@ CFGUI_Label::CFGUI_Label() void CFGUI_Label::SetFont( CUtlString font ) { - IFGUI::LoadFont(font); + m_pFont = IFGUI::LoadFont(font); } void CFGUI_Label::SetLabel( CUtlString text ) @@ -28,7 +28,9 @@ void CFGUI_Label::Event( FGUI_Event_t event ) void CFGUI_Label::Draw() { + IFGUI::SetTextFont(m_pFont); IFGUI::SetTextColor(1, 1, 1, 1); + IFGUI::SetTextPos(m_iPosition[0], m_iPosition[1]); IFGUI::DrawText(m_szText); } diff --git a/fgui/rect.cpp b/fgui/rect.cpp new file mode 100644 index 0000000..7b5ca17 --- /dev/null +++ b/fgui/rect.cpp @@ -0,0 +1,21 @@ +#include "fgui/rect.h" + +void CFGUI_Rect::SetBoxColor( float r, float g, float b, float a ) +{ + m_fBoxColor[0] = r; + m_fBoxColor[1] = g; + m_fBoxColor[2] = b; + m_fBoxColor[3] = a; +}; + +void CFGUI_Rect::Event( FGUI_Event_t event ) +{ + +} + +void CFGUI_Rect::Draw() +{ + IFGUI::SetRectColor(m_fBoxColor[0],m_fBoxColor[1],m_fBoxColor[2],m_fBoxColor[3]); + IFGUI::DrawRect(m_iPosition[0],m_iPosition[1],m_iSize[0],m_iSize[1]); +} + diff --git a/fgui/rectangle.cpp b/fgui/rectangle.cpp deleted file mode 100644 index e69de29..0000000 diff --git a/funnyassets/fonts/IBMPlexMono-Regular.fontdata b/funnyassets/fonts/IBMPlexMono-Regular.fontdata index 81c969b..c2541cb 100644 --- a/funnyassets/fonts/IBMPlexMono-Regular.fontdata +++ b/funnyassets/fonts/IBMPlexMono-Regular.fontdata @@ -1,2 +1,2 @@ -12 8 !"#$&'()*+,-./0123456789:;<=>?@ABCDEFGIJKLMNOPQRSTUVWXYZ[\]^_`abcdefgijklmnopqrstuvwxyz{|}~ +12 8 !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~ diff --git a/funnyassets/gfx_shaders/fgui_rect_frag.slang b/funnyassets/gfx_shaders/fgui_rect_frag.slang index cecec1c..1e1079d 100644 --- a/funnyassets/gfx_shaders/fgui_rect_frag.slang +++ b/funnyassets/gfx_shaders/fgui_rect_frag.slang @@ -6,6 +6,6 @@ float4 _main( uint triid: SV_PrimitiveID, ) : SV_TARGET { - return float4(0.2,0.2,0.2,1); + return float4(color); } diff --git a/funnyassets/gfx_shaders/fgui_rect_shared.slang b/funnyassets/gfx_shaders/fgui_rect_shared.slang index f8e2bc1..9cb9be5 100644 --- a/funnyassets/gfx_shaders/fgui_rect_shared.slang +++ b/funnyassets/gfx_shaders/fgui_rect_shared.slang @@ -8,9 +8,10 @@ struct VertexOutput DECLARE_CONSTANTS() { - int2 resolution; + uint2 resolution; uint2 size; int2 position; + float4 color; }; diff --git a/funnyassets/gfx_shaders/fgui_text_frag.slang b/funnyassets/gfx_shaders/fgui_text_frag.slang index fd9f931..1111ef8 100644 --- a/funnyassets/gfx_shaders/fgui_text_frag.slang +++ b/funnyassets/gfx_shaders/fgui_text_frag.slang @@ -6,6 +6,10 @@ float4 _main( uint triid: SV_PrimitiveID, ) : SV_TARGET { - return float4(0.2,0.2,0.2,1); + float dist = SampleTexture(font, (input.uv+glyphPos)*glyphSize).x; + float smoothing = 0.2; + float alpha = smoothstep(0.5-smoothing, 0.5+smoothing, dist); + if (alpha<0.01) discard; + return float4(color); } diff --git a/funnyassets/gfx_shaders/fgui_text_shared.slang b/funnyassets/gfx_shaders/fgui_text_shared.slang index c5185f9..d8fa8ff 100644 --- a/funnyassets/gfx_shaders/fgui_text_shared.slang +++ b/funnyassets/gfx_shaders/fgui_text_shared.slang @@ -3,6 +3,7 @@ struct VertexOutput { float4 position: SV_Position; + float2 uv: TEXCOORD0; } #include "shader_base.h" @@ -11,8 +12,11 @@ DECLARE_CONSTANTS() int2 resolution; uint2 size; int2 position; - int8_t character; + float4 color; + float2 glyphPos; + float2 glyphSize; + uint font; }; -DECLARE_TEXTURES(0); +DECLARE_TEXTURES(29); diff --git a/funnyassets/gfx_shaders/fgui_text_vert.slang b/funnyassets/gfx_shaders/fgui_text_vert.slang index 083ed3e..a1ebfda 100644 --- a/funnyassets/gfx_shaders/fgui_text_vert.slang +++ b/funnyassets/gfx_shaders/fgui_text_vert.slang @@ -13,6 +13,7 @@ VertexOutput _main( { VertexOutput output; output.position = float4((input.position*size+position)/resolution*2-1, 0, 1.0f); + output.uv = input.uv; FIX_VERTEX_POSITION(output.position); return output; } diff --git a/funnyassets/gfx_shaders/shader_base.h b/funnyassets/gfx_shaders/shader_base.h index 519b119..7054035 100644 --- a/funnyassets/gfx_shaders/shader_base.h +++ b/funnyassets/gfx_shaders/shader_base.h @@ -41,19 +41,19 @@ SamplerState mlGetSampler() _mlGetSampler(); }; -#define DECLARE_CBUFFER(b) \ -[[vk::binding(b)]] cbuffer cbuffer_##b : register(t##b) +#define DECLARE_CBUFFER(n) \ +[[vk::binding(n)]] cbuffer cbuffer_##b : register(b##n) #define DECLARE_CONSTANTS() \ [[vk::push_constant]] \ -cbuffer cbuffer_constants : register(t29) +cbuffer cbuffer_constants : register(b29) #define FIX_VERTEX_POSITION(g) g = float4(g.x, -g.y, g.z, g.w); #elif defined(__SPIRV__) -#define DECLARE_TEXTURES(b) \ -[[vk::binding(b)]] \ +#define DECLARE_TEXTURES(n) \ +[[vk::binding(n)]] \ Sampler2D g_textures[]; \ float4 SampleTexture(uint32_t binding, float2 uv) \ { \ diff --git a/game/client/milmoba/player.cpp b/game/client/milmoba/player.cpp index 0f0b3de..648c1c2 100644 --- a/game/client/milmoba/player.cpp +++ b/game/client/milmoba/player.cpp @@ -5,6 +5,7 @@ #include "rendering.h" #include "input.h" #include "fgui/widget.h" +#include "fgui/rect.h" #include "fgui/label.h" #include "mesh.h" @@ -23,14 +24,18 @@ public: void C_MOBAPlayer::Precache() { } +CFGUI_Rect *pRect = new CFGUI_Rect(); CFGUI_Label *pText = new CFGUI_Label(); void C_MOBAPlayer::Spawn() { - pText->SetFont("fonts/IBMPlexMono-Regular"); - pText->SetPosition(100, 100); - pText->SetLabelSize(15); - pText->SetLabel("Hello, world!"); + pRect->SetPosition(0, 0); + pRect->SetSize(200, 200); + pRect->SetBoxColor(0, 1, 0, 1); + pText->SetFont("fonts/IBMPlexMono-Regular"); + pText->SetPosition(0, 0); + pText->SetLabelSize(15); + pText->SetLabel("Hello world!"); float cubeVertices[] = { // Front face diff --git a/public/fgui/fgui.h b/public/fgui/fgui.h index d22a384..e9c9543 100644 --- a/public/fgui/fgui.h +++ b/public/fgui/fgui.h @@ -19,6 +19,8 @@ public: ITexture *pTexture; uint32_t glyphWidth; uint32_t glyphHeight; + uint32_t nGlyphsPerRow; + uint32_t nGlyphsPerColumn; char cCharacterSet[256]; }; diff --git a/public/fgui/label.h b/public/fgui/label.h index 3b53de2..f64f2fd 100644 --- a/public/fgui/label.h +++ b/public/fgui/label.h @@ -20,7 +20,8 @@ public: virtual void Event( FGUI_Event_t event ) override; virtual void Draw() override; - uint32_t m_fGlyphSize[2]; +private: + CFont *m_pFont; }; #endif diff --git a/public/fgui/rect.h b/public/fgui/rect.h new file mode 100644 index 0000000..c739851 --- /dev/null +++ b/public/fgui/rect.h @@ -0,0 +1,16 @@ +#ifndef FGUI_RECT_H +#define FGUI_RECT_H +#include "widget.h" + +class CFGUI_Rect: public CFGUI_Widget +{ +public: + void SetBoxColor( float r, float g, float b, float a ); + + virtual void Event( FGUI_Event_t event ) override; + virtual void Draw() override; + + float m_fBoxColor[4]; +}; + +#endif