added font rendering

This commit is contained in:
2026-05-25 01:35:19 +03:00
parent a9766d6dd6
commit f127ac3801
27 changed files with 657 additions and 43 deletions

View File

@@ -38,15 +38,16 @@ DECLARE_BUILD_STAGE(install_game)
if ( GET_PROJECT_VALUE(config, "bundle") == "true" ) {
return 0;
}
filesystem2->CopyFile(szOutputDir, GET_PROJECT_OBJECT(launcher, "launcher"));
filesystem2->MakeDirectory(CUtlString("%s/core/",szOutputDir.GetString()));
filesystem2->CopyFile(szOutputDir, GET_PROJECT_OBJECT(launcher, "launcher"));
filesystem2->CopyDirectory(CUtlString("%s/core/",szOutputDir.GetString()), "funnyassets/maps");
filesystem2->CopyDirectory(CUtlString("%s/core/",szOutputDir.GetString()), "funnyassets/models");
filesystem2->CopyDirectory(CUtlString("%s/core/",szOutputDir.GetString()), "funnyassets/meshes");
filesystem2->CopyDirectory(CUtlString("%s/core/",szOutputDir.GetString()), "funnyassets/materials");
filesystem2->CopyDirectory(CUtlString("%s/core/",szOutputDir.GetString()), "funnyassets/textures");
filesystem2->CopyDirectory(CUtlString("%s/core/",szOutputDir.GetString()), "funnyassets/physics");
filesystem2->CopyDirectory(CUtlString("%s/core/",szOutputDir.GetString()), "funnyassets/fonts");
filesystem2->CopyFile(CUtlString("%s/core/",szOutputDir.GetString()), "funnyassets/default.cfg");
filesystem2->CopyDirectory(CUtlString("%s/core/",szOutputDir.GetString()), "build/funnygame/assets/shaders");
if (Target_t::DefaultTarget().kernel == TARGET_KERNEL_WINDOWS)

View File

@@ -158,6 +158,8 @@ extern "C" void FunnyMain( int argc, char **argv )
fCurrent = Plat_GetTime();
};
Plat_Exit(0);
g_pClientGame->Shutdown();
g_pServerGame->Shutdown();
g_pRenderContext->Shutdown();

View File

@@ -1,23 +1,399 @@
#include "kottui/kottui.h"
#include "tier0/lib.h"
#include "tier0/mem.h"
#include "tier1/utlstring.h"
#include "tier2/ifilesystem.h"
#include "tier2/fileformats/json.h"
#include "trig.h"
struct GlyphData_t
{
uint32_t m_uCharacter;
float m_fX;
float m_fY;
float m_fWidth;
float m_fHeight;
};
class CKotRenderFont: public IKotRenderFont
{
public:
virtual IImage *GetAtlas() override;
virtual bool IsLetterPresent( uint32_t letter ) override;
virtual float GetLetterX( uint32_t letter ) override;
virtual float GetLetterY( uint32_t letter ) override;
virtual float GetWidth( uint32_t letter ) override;
virtual float GetHeight( uint32_t letter ) override;
virtual bool IsMono() override;
virtual uint32_t GetLetterWidth() override;
virtual uint32_t GetLetterHeight() override;
GlyphData_t *m_glyphs;
uint32_t m_uGlyphCount;
IImage *m_pAtlas;
};
class CKotUIBuffer: public IKotUIBuffer
{
public:
virtual void SetColor( char c ) = 0;
virtual void SetPosition( int iY, int iX ) = 0;
virtual void Printf(const char *szFormat, ...) = 0;
virtual void PutChar( char c ) = 0;
virtual void Clear( char c ) = 0;
virtual void SetPosition( int iY, int iX ) override;
virtual void Move( int iY, int iX ) override;
virtual void SetColor( char c ) override;
virtual void Clear( char c ) override;
virtual void PutChar( char c ) override;
virtual void Printf(const char *szFormat, ...) override;
virtual void Draw( IImage *pImage ) override;
virtual void SetTextSize( int iY, int iX ) override;
virtual void SetTextFont( IKotRenderFont *pFont ) override;
uint32_t *m_buffer;
ColorAlpha *m_primaryColor;
ColorAlpha *m_secondaryColor;
int m_iWidth = 0;
int m_iHeight = 0;
IBuffer *m_pDataBuffer;
IMaterial *m_pMaterial;
IRenderContext *m_pRenderContext;
IKotRenderFont *m_pFont;
uint32_t m_uCursor = 0;
};
class CKotUIManager: public IKotUIManager
{
public:
virtual void SetTextSize( int iY, int iX ) = 0;
virtual void SetTextFont( IRenderFont *pFont ) = 0;
virtual void Init() override;
virtual void Shutdown() override;
virtual void ConnectInterface( void *pIface, const char *szName ) override;
virtual void CreateBuffer( int iWidth, int iHeight, int iY, int iX ) = 0;
virtual void Draw( IRenderContext *pRenderContext );
virtual IKotRenderFont *LoadFont( const char *szPath ) override;
virtual IKotUIBuffer *CreateBuffer( int iWidth, int iHeight ) override;
virtual void DeleteBuffer( IKotUIBuffer *pBuffer ) override;
IRenderContext *m_pRenderContext;
ITextureArray *m_pFonts;
};
IKotUIManager *KotUIManager();
static IShader *s_pShader;
static CKotUIManager s_kotUIManager;
static IVertexBuffer *s_pGlyphBuffer;
IKotUIManager *KotUIManager()
{
return &s_kotUIManager;
}
EXPOSE_INTERFACE_FN(KotUIManager, IKotUIManager, KOT_UI_INTEFACE_VERSION);
IImage *CKotRenderFont::GetAtlas()
{
return m_pAtlas;
}
bool CKotRenderFont::IsLetterPresent( uint32_t letter )
{
for ( int i = 0; i < m_uGlyphCount; i++ )
{
GlyphData_t g = m_glyphs[i];
if (g.m_uCharacter == letter)
return true;
}
return false;
}
float CKotRenderFont::GetLetterX( uint32_t letter )
{
for ( int i = 0; i < m_uGlyphCount; i++ )
{
GlyphData_t g = m_glyphs[i];
if (g.m_uCharacter == letter)
return g.m_fX;
}
return 0;
}
float CKotRenderFont::GetLetterY( uint32_t letter )
{
for ( int i = 0; i < m_uGlyphCount; i++ )
{
GlyphData_t g = m_glyphs[i];
if (g.m_uCharacter == letter)
return g.m_fY;
}
return 0;
}
float CKotRenderFont::GetWidth( uint32_t letter )
{
for ( int i = 0; i < m_uGlyphCount; i++ )
{
GlyphData_t g = m_glyphs[i];
if (g.m_uCharacter == letter)
return g.m_fWidth;
}
return 0;
}
float CKotRenderFont::GetHeight( uint32_t letter )
{
for ( int i = 0; i < m_uGlyphCount; i++ )
{
GlyphData_t g = m_glyphs[i];
if (g.m_uCharacter == letter)
return g.m_fHeight;
}
return 0;
}
void CKotUIBuffer::SetPosition( int iY, int iX )
{
}
void CKotUIBuffer::Move( int iY, int iX )
{
m_uCursor = iY*m_iWidth+iX;
m_uCursor = m_uCursor % (m_iWidth * m_iHeight);
}
void CKotUIBuffer::SetColor( char c )
{
}
void CKotUIBuffer::Clear( char c )
{
}
void CKotUIBuffer::PutChar( char c )
{
m_buffer[m_uCursor] = c;
Move(0, m_uCursor+1);
}
void CKotUIBuffer::Printf(const char *szFormat, ...)
{
va_list vlArgs;
va_start(vlArgs, szFormat);
va_list vlArgs2;
va_copy(vlArgs2, vlArgs);
size_t nSize = V_vsnprintf(NULL, 0, szFormat, vlArgs2);
va_end(vlArgs2);
char *psz = (char*)V_malloc(nSize+1);
va_copy(vlArgs2, vlArgs);
V_vsnprintf(psz, nSize+1, szFormat, vlArgs2);
for ( size_t u = 0, i = m_uCursor; u < nSize; u++, i = (i + 1 % (m_iWidth * m_iHeight)) )
{
m_buffer[i] = psz[u];
}
va_end(vlArgs2);
V_free(psz);
va_end(vlArgs);
Move(0, m_uCursor+1);
}
struct TextDrawData_t
{
float m_vTexcoordOffsetX;
float m_vTexcoordOffsetY;
float m_vTexcoordSizeX;
float m_vTexcoordSizeY;
float m_fPosX;
float m_fPosY;
float m_fSizeX;
float m_fSizeY;
float m_fColor[4];
float m_fColor2[4];
};
struct ScreenData_t
{
float m_fScreenSizeX;
float m_fScreenSizeY;
};
void CKotUIBuffer::Draw( IImage *pImage )
{
uint32_t uGlyphCount = m_iWidth*m_iHeight;
uint32_t uRealGlyphCount = 0;
IRenderCommandList *pList = m_pRenderContext->CreateCommandList();
pList->StartRecording();
m_pDataBuffer->Lock();
TextDrawData_t *pData = (TextDrawData_t*)m_pDataBuffer->Map();
for ( uint32_t i = 0; i < uGlyphCount; i++ )
{
uint32_t l = m_buffer[i];
if ( !m_pFont->IsLetterPresent(l) )
continue;
pData[uRealGlyphCount].m_vTexcoordOffsetX = m_pFont->GetLetterX(l);
pData[uRealGlyphCount].m_vTexcoordOffsetY = m_pFont->GetLetterY(l);
pData[uRealGlyphCount].m_vTexcoordSizeX = m_pFont->GetWidth(l);
pData[uRealGlyphCount].m_vTexcoordSizeY = m_pFont->GetHeight(l);
pData[uRealGlyphCount].m_fSizeX = 16;
pData[uRealGlyphCount].m_fSizeY = 16;
pData[uRealGlyphCount].m_fPosX = i%m_iWidth*16;
pData[uRealGlyphCount].m_fPosY = i/m_iWidth*16;
uRealGlyphCount++;
}
m_pDataBuffer->Unmap();
m_pDataBuffer->Unlock();
IBuffer *pScreenBuffer = m_pRenderContext->CreateConstantBuffer(sizeof(ScreenData_t));
pScreenBuffer->Lock();
ScreenData_t *pScreenData = (ScreenData_t*)pScreenBuffer->Map();
pScreenData->m_fScreenSizeX = pImage->GetImageWidth();
pScreenData->m_fScreenSizeY = pImage->GetImageHeight();
pScreenBuffer->Unmap();
pScreenBuffer->Unlock();
m_pMaterial = m_pRenderContext->CreateMaterial(s_pShader);
m_pMaterial->PSSetShaderResource(0, m_pDataBuffer);
m_pMaterial->PSSetShaderResource(1, pScreenBuffer);
m_pMaterial->PSSetTexture(2, m_pFont->GetAtlas());
m_pMaterial->PSSetSampler(3, m_pRenderContext->GetDefaultSampler());
pList->SetRenderTarget(0, pImage);
pList->SetLoadStoreModes(0, LOAD_MODE_LOAD, STORE_MODE_STORE);
pList->SetRenderResolution(pImage->GetImageWidth(), pImage->GetImageHeight());
pList->SetMaterial(m_pMaterial);
pList->SetVertexBuffer(0, s_pGlyphBuffer);
pList->DrawPrimitives(6, 0, uRealGlyphCount, 0);
pList->EndRecording();
m_pRenderContext->SubmitCommandList(pList);
}
void CKotUIBuffer::SetTextSize( int iY, int iX )
{
}
void CKotUIBuffer::SetTextFont( IKotRenderFont *pFont )
{
m_pFont = pFont;
}
void CKotUIManager::Init()
{
s_pShader = m_pRenderContext->CreateShader("game/core/shaders/kottui.shader_c");
s_pShader->AddLayout(0, 8);
s_pShader->AddAttribute(0, 0, VERTEX_FORMAT_XY32_SFLOAT, 0);
s_pShader->AddOutputImage(0, IMAGE_FORMAT_RGBA8_UNORM);
s_pShader->Build();
s_pGlyphBuffer = m_pRenderContext->CreateVertexBuffer(sizeof(float)*12);
void *pBuffer = s_pGlyphBuffer->Map();
float vertices[12] = {
0, 0,
0, 1,
1, 0,
1, 0,
0, 1,
1, 1,
};
V_memcpy(pBuffer, vertices, sizeof(vertices));
s_pGlyphBuffer->Unmap();
m_pFonts = m_pRenderContext->CreateTextureArray();
}
void CKotUIManager::Shutdown()
{
}
void CKotUIManager::ConnectInterface( void *pFace, const char *psz )
{
if (!V_strcmp(psz, RENDER_CONTEXT_INTERFACE_VERSION))
m_pRenderContext = (IRenderContext*)pFace;
}
IKotRenderFont *CKotUIManager::LoadFont( const char *szPath )
{
CUtlString szAtlas = CUtlString("%s.png", szPath);
CUtlString szMeta = CUtlString("%s.fmd", szPath);
IFileHandle *pMetadataFile = filesystem->Open(szMeta, FILEMODE_READ);
if (!pMetadataFile)
return NULL;
const char *szMetadata = filesystem->ReadString(pMetadataFile);
filesystem->Close(pMetadataFile);
IJSONValue *pValue = JSONManager()->ReadString(szMetadata);
IJSONArray *pGlyphs = pValue->GetObject()->GetValue("glyphs")->GetArray();
uint32_t uAtlas = m_pFonts->LoadTexture(szAtlas);
CKotRenderFont *pFont = new CKotRenderFont;
pFont->m_pAtlas = pFont->m_pAtlas = m_pFonts->GetTexture(uAtlas);
uint32_t atlasWidth = pValue->GetObject()->GetValue("atlas")->GetObject()->GetValue("width")->GetNumberValue();
uint32_t atlasHeight = pValue->GetObject()->GetValue("atlas")->GetObject()->GetValue("height")->GetNumberValue();
pFont->m_uGlyphCount = 0;
pFont->m_glyphs = (GlyphData_t*)V_malloc(sizeof(GlyphData_t)*pGlyphs->GetCount());
for ( uint32_t i = 0; i < pGlyphs->GetCount(); i++ )
{
GlyphData_t glyph = {};
IJSONObject *pGlyph = pGlyphs->GetParameter(i)->GetObject();
if (pGlyph->GetValue("atlasBounds") == NULL)
continue;
IJSONObject *pAtlasBounds = pGlyph->GetValue("atlasBounds")->GetObject();
glyph.m_uCharacter = pGlyph->GetValue("unicode")->GetNumberValue();
glyph.m_fX = pAtlasBounds->GetValue("left")->GetNumberValue()/atlasWidth;
glyph.m_fY = 1-(pAtlasBounds->GetValue("bottom")->GetNumberValue()/atlasHeight);
glyph.m_fWidth = (
pAtlasBounds->GetValue("right")->GetNumberValue()
- pAtlasBounds->GetValue("left")->GetNumberValue()
) / atlasWidth;
glyph.m_fHeight = (
pAtlasBounds->GetValue("bottom")->GetNumberValue()
- pAtlasBounds->GetValue("top")->GetNumberValue()
) / atlasHeight;
pFont->m_glyphs[pFont->m_uGlyphCount++] = glyph;
}
return pFont;
}
IKotUIBuffer *CKotUIManager::CreateBuffer( int iWidth, int iHeight )
{
CKotUIBuffer *pBuffer = new CKotUIBuffer;
pBuffer->m_pRenderContext = m_pRenderContext;
pBuffer->m_buffer = (uint32_t*)V_malloc(sizeof(uint32_t)*iWidth*iHeight);
V_memset(pBuffer->m_buffer, 0, sizeof(uint32_t)*iWidth*iHeight);
pBuffer->m_iWidth = iWidth;
pBuffer->m_iHeight = iHeight;
pBuffer->m_pDataBuffer = m_pRenderContext->CreateStorageBuffer(sizeof(TextDrawData_t)*iWidth*iHeight);
return pBuffer;
}
void CKotUIManager::DeleteBuffer( IKotUIBuffer *pBuffer )
{
}

File diff suppressed because one or more lines are too long

View File

@@ -1,2 +0,0 @@
12 8 !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

After

Width:  |  Height:  |  Size: 45 KiB

View File

@@ -0,0 +1,85 @@
#include "macros.hlsl"
COMMON {
struct PS_INPUT
{
float4 m_vPosition: SV_POSITION;
float2 m_vUV: TEXCOORD0;
uint m_uFont;
}
struct TextDrawData_t
{
float2 m_vTexcoordOffset;
float2 m_vTexcoordSize;
float2 m_vPos;
float2 m_vSize;
float4 m_vFGColor;
float4 m_vBGColor;
}
StructuredBuffer<TextDrawData_t> g_textData: register( t0 );
cbuffer ScreenData_t: register( b1 )
{
float2 g_vScreenSize;
}
Texture2D<float4> g_atlas: register( t2 );
SamplerState g_atlasSampler: register(s3);
}
VS
{
struct VS_INPUT
{
float2 m_vPosition: POSITION;
}
PS_INPUT vsMain( VS_INPUT input, uint uInstance: SV_InstanceID, uint uBaseInstance: SV_StartInstanceLocation )
{
uint uInstance = uBaseInstance + uInstance;
float2 position = input.m_vPosition;
position*=g_textData[uInstance].m_vSize;
position+=g_textData[uInstance].m_vPos;
position/=g_vScreenSize;
position.y = 1-position.y;
position*=2;
position-=1;
float2 uv = input.m_vPosition;
uv.y = 1-uv.y;
uv*=g_textData[uInstance].m_vTexcoordSize;
uv+=g_textData[uInstance].m_vTexcoordOffset;
PS_INPUT output = {};
output.m_vPosition = float4(position, 0, 1);
output.m_vUV = uv;
return output;
}
}
PS
{
struct PS_OUTPUT
{
float4 m_vAlbedo: SV_Target0;
}
float ScreenPixelRange( float2 uv )
{
uint uWidth, uHeight;
g_atlas.GetDimensions(uWidth, uHeight);
float2 vUnitRange = 2.0/float2(uWidth, uHeight);
float2 vScreenTexSize = 1.0/fwidth(uv);
return max(0.5*dot(vUnitRange, vScreenTexSize), 1);
}
PS_OUTPUT psMain( PS_INPUT input )
{
PS_OUTPUT output = {};
float4 vMsd = g_atlas.Sample(g_atlasSampler, input.m_vUV.xy);
float fSd = median3(vMsd.x, vMsd.y, vMsd.z);
float fScreenPixelDistance = ScreenPixelRange(input.m_vUV)*(fSd-0.5);
float fOpacity = clamp(fScreenPixelDistance+0.5, 0.0, 1.0);
output.m_vAlbedo = fOpacity;
return output;
}
}

View File

@@ -90,8 +90,7 @@ PS
if ( data.m_material.m_uAlbedo != -1 )
{
output.m_vAlbedo = g_textures[data.m_material.m_uAlbedo]
.Sample(g_textureSampler, input.m_vTexCoord.xy)
* data.m_material.m_vAlbedoColor;
.Sample(g_textureSampler, input.m_vTexCoord.xy);
}
else
{

View File

@@ -10,6 +10,7 @@
#define MAX_SHADER_COUNT 1024
#define MAX_PHYSICS_COUNT 1024
#define MAX_FONT_COUNT 128
template<typename T, uint32_t nCount>
class CAssetArc

View File

@@ -240,14 +240,10 @@ void CEntitySystem::NetRecvPacket( NetPacket_t *pPacket )
}
break;
case k_EMessage_EntityDeleted:
C_BaseEntity **ppEntities = m_pEntities;
for ( int i = 0; i < MAX_EDICTS; i++ )
{
if (ppEntities[i] == NULL)
{
}
{
DestroyEntityByIndex((uint32_t)pPlayerPacket->m_deleteEntity.m_uIndex);
}
break;
default:
break;
}

View File

@@ -38,6 +38,7 @@ IEngineBridge *EngineBridge()
EXPOSE_INTERFACE_FN(EngineBridge, IEngineBridge, ENGINE_BRIDGE_INTERFACE_VERSION)
static IKotUIBuffer *s_pUIBuffer;
void CFunnyGameBridge::Init()
{
@@ -70,6 +71,22 @@ void CFunnyGameBridge::Init()
g_pPhysicsWorld = g_pPhysics->CreateWorld();
g_pHumanDeviceManager->SetDefaultInput(g_pMainInput);
CreateInterfaceFn fnEngineFactory = Sys_GetFactory("engine");
g_pKotUI = (IKotUIManager*)fnEngineFactory(KOT_UI_INTEFACE_VERSION, NULL);
g_pKotUI->ConnectInterface(g_pRenderContext, RENDER_CONTEXT_INTERFACE_VERSION);
g_pKotUI->Init();
IKotRenderFont *pFont = g_pKotUI->LoadFont("game/core/fonts/IBMPlexMono-Regular");
s_pUIBuffer = g_pKotUI->CreateBuffer(40, 30);
s_pUIBuffer->SetTextFont(pFont);
s_pUIBuffer->SetTextSize(, int iX)
s_pUIBuffer->Move(0, 0);
s_pUIBuffer->Printf("hello %f", 20.0);
s_pUIBuffer->Move(1, 0);
s_pUIBuffer->Printf("hello %f", 40.0);
s_pUIBuffer->Move(2, 0);
s_pUIBuffer->Printf("hello %f", 40.0);
}
void CFunnyGameBridge::Tick( float fDelta )
@@ -166,6 +183,7 @@ void CFunnyGameBridge::Frame( float fDelta )
EntitySystem()->NetSendThink(pCurrentServer);
}
g_pWorldRenderer->Frame(fDelta);
s_pUIBuffer->Draw(g_pMainWindow->GetOutputImage());
}
void CFunnyGameBridge::Shutdown()

View File

@@ -32,7 +32,7 @@ void C_MOBAPlayer::Think( float fDelta )
g_pWorldRenderer->SetCameraPosition(vCameraPos);
Quat vCameraRot;
glm_euler_yxz_quat((vec3){m_fPitch, m_fYaw, 0}, *(versor*)&vCameraRot);
g_pWorldRenderer->SetCameraRotation(vCameraRot);
//g_pWorldRenderer->SetCameraRotation(vCameraRot);
}
BaseClass::Think(fDelta);
};

View File

@@ -298,7 +298,12 @@ void CFunnyWorldRenderer::Frame( float fDelta )
m_pRasterCommandList->SetViewport(0, 0, uWidth, uHeight, 0, 1);
m_pRasterCommandList->SetScissors(0, 0, uWidth, uHeight);
m_pRasterCommandList->SetClearColor(0, 0, 0, 0, 0);
m_pRasterCommandList->SetClearColor(1, 0, 0, 0, 0);
m_pRasterCommandList->SetClearColor(2, 0, 0, 0, 0);
m_pRasterCommandList->SetClearDepth(1);
m_pRasterCommandList->SetLoadStoreModes(0, LOAD_MODE_CLEAR, STORE_MODE_STORE);
m_pRasterCommandList->SetLoadStoreModes(1, LOAD_MODE_CLEAR, STORE_MODE_STORE);
m_pRasterCommandList->SetLoadStoreModes(2, LOAD_MODE_CLEAR, STORE_MODE_STORE);
uint32_t uTotalMeshes = 0;
uint32_t u = 0;
for ( auto mesh: m_pMeshes)

View File

@@ -40,6 +40,8 @@ extern EngineConsts_t *g_pEngineConstants;
extern IPhysics *g_pPhysics;
extern IPhysicsWorld *g_pPhysicsWorld;
extern IKotUIManager *g_pKotUI;
#define FUNNY_SECURE_PORT 27015
#define FUNNY_QUERY_PORT 27016

View File

@@ -38,11 +38,22 @@ DECLARE_VULKAN_COMMAND(Begin)
VkRenderingAttachmentInfo a = {};
a.sType = VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO;
a.imageLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
a.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
a.clearValue.color.float32[0] = i.m_fClearColor[0];
a.clearValue.color.float32[1] = i.m_fClearColor[1];
a.clearValue.color.float32[2] = i.m_fClearColor[2];
a.clearValue.color.float32[3] = i.m_fClearColor[3];
switch( i.m_eLoadMode )
{
case LOAD_MODE_DONT_CARE:
a.loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
break;
case LOAD_MODE_LOAD:
a.loadOp = VK_ATTACHMENT_LOAD_OP_LOAD;
break;
case LOAD_MODE_CLEAR:
a.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
a.clearValue.color.float32[0] = i.m_fClearColor[0];
a.clearValue.color.float32[1] = i.m_fClearColor[1];
a.clearValue.color.float32[2] = i.m_fClearColor[2];
a.clearValue.color.float32[3] = i.m_fClearColor[3];
break;
}
a.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
a.imageView = ((CVkImage*)VulkanGetObject(i.m_stImage, iCurrentFrame))->m_imageView;
attachments.AppendTail(a);

View File

@@ -76,6 +76,17 @@ void CVkMaterial::PSSetTextureArray( uint32_t uSet, ITextureArray *pArray )
SetShaderResource(0, uSet, pArray);
}
void CVkMaterial::PSSetTexture( uint32_t uRegister, IImage *pImage )
{
SetShaderResource(uRegister, 0, pImage);
}
void CVkMaterial::PSSetSampler( uint32_t uRegister, ISampler *pImage )
{
SetShaderResource(uRegister, 0, pImage);
}
void CVkMaterial::SetShaderResource( uint32_t uRegister, uint32_t uSet, IRenderingObject *pObject)
{
if ( m_pVkShader->m_setLayouts.GetSize() == 0 )
@@ -84,6 +95,8 @@ void CVkMaterial::SetShaderResource( uint32_t uRegister, uint32_t uSet, IRenderi
IRenderingObject *pVkObject;
CVkBuffer *pBuffer;
CVkTextureArray *pArray;
CVkImage *pImage;
CVkSampler *pSampler;
};
pVkObject = pObject;
if (dynamic_cast<IBuffer*>(pObject))
@@ -101,6 +114,36 @@ void CVkMaterial::SetShaderResource( uint32_t uRegister, uint32_t uSet, IRenderi
stInfo.range = pBuffer->m_nSize;
vkUpdateDescriptorSets(m_pVkShader->m_hDevice, 1, &write, 0, 0);
}
if (dynamic_cast<IImage*>(pObject))
{
VkWriteDescriptorSet write = {};
VkDescriptorImageInfo stInfo = {};
write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
write.dstSet = m_hSets[uSet];
write.dstBinding = uRegister;
write.dstArrayElement = 0;
write.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE;
write.descriptorCount = 1;
write.pImageInfo = &stInfo;
stInfo.imageView = pImage->m_imageView;
stInfo.imageLayout = VK_IMAGE_LAYOUT_GENERAL;
vkUpdateDescriptorSets(m_pVkShader->m_hDevice, 1, &write, 0, 0);
}
if (dynamic_cast<CVkSampler*>(pObject))
{
VkWriteDescriptorSet write = {};
VkDescriptorImageInfo stInfo = {};
write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
write.dstSet = m_hSets[uSet];
write.dstBinding = uRegister;
write.dstArrayElement = 0;
write.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER;
write.descriptorCount = 1;
write.pImageInfo = &stInfo;
stInfo.sampler = pSampler->m_sampler;
vkUpdateDescriptorSets(m_pVkShader->m_hDevice, 1, &write, 0, 0);
}
if (dynamic_cast<ITextureArray*>(pObject))
{
VkWriteDescriptorSet writes[2] = {};

View File

@@ -36,6 +36,15 @@ void CVkRenderCommandList::SetClearColor( uint32_t uIndex, float r, float g, flo
pOutput->m_fClearColor[3] = a;
}
void CVkRenderCommandList::SetLoadStoreModes( uint32_t uIndex, ELoadMode eLoadMode, EStoreMode eStoreMode )
{
SwitchRenderingStage(RENDERING_STAGE_SETUP_RASTER);
VulkanRenderOutput_t *pOutput = FindOrCreateRenderOutput(uIndex);
pOutput->m_eLoadMode = eLoadMode;
pOutput->m_eStoreMode = eStoreMode;
}
void CVkRenderCommandList::SetDepthTarget( IImage *pDepth )
{
SwitchRenderingStage(RENDERING_STAGE_SETUP_RASTER);

View File

@@ -325,6 +325,11 @@ uint32_t CVkBuffer::GetSize()
return m_nSize;
}
void CVkSampler::SetDebugName( const char *szName )
{
};
CVkTextureArray::~CVkTextureArray()
{
@@ -357,7 +362,6 @@ void CVkTextureArray::Build()
samplerInfo.mipLodBias = 0.0f;
samplerInfo.minLod = 0.0f;
samplerInfo.maxLod = VK_LOD_CLAMP_NONE;
vkCreateSampler(m_hDevice, &samplerInfo, nullptr, &m_hSampler);
LoadTexture("game/core/textures/error.png");
@@ -427,6 +431,11 @@ uint32_t CVkTextureArray::GetTextureID( const char *szPath )
{
}
IImage *CVkTextureArray::GetTexture( uint32_t uTextureID )
{
return m_pImages[uTextureID];
}
void CVkTextureArray::UnloadTexture( uint32_t uTextureID )
{
@@ -477,6 +486,8 @@ public:
virtual ITextureArray *CreateTextureArray() override;
virtual void DestroyTextureArray() override;
virtual ISampler *GetDefaultSampler() override;
private:
VkPhysicalDevice SelectPhysicalDevice( CUtlVector<VkPhysicalDevice> physicalDevices );
CUtlVector<const char *> GetDeviceExtensions();
@@ -498,6 +509,8 @@ private:
CUtlVector<CVkTextureArray*> m_scheduledRemovalTextureArrays;
CUtlVector<CVkBuffer*> m_scheduledRemovalBuffers;
CUtlVector<CVkImage*> m_scheduledRemovalImages;
CVkSampler m_defaultSampler;
};
EXPOSE_INTERFACE(CVkRenderContext, IRenderContext, RENDER_CONTEXT_INTERFACE_VERSION);
@@ -677,12 +690,18 @@ void CVkRenderContext::DestroyTextureArray()
{
}
ISampler *CVkRenderContext::GetDefaultSampler()
{
return &m_defaultSampler;
}
VkPipelineLayout g_pLibraryEmptyLayout;
static IVkCommandBuffer *s_pPresentCommandBuffer;
void CVkRenderContext::Init()
{
VkResult r;
int nExtensionCount;
@@ -834,6 +853,23 @@ void CVkRenderContext::Init()
m_pCommandBufferManager = (IVkCommandBufferManager*)CreateInterface(VULKAN_COMMAND_BUFFER_MANAGER_INTERFACE_NAME, NULL);
m_pCommandBufferManager->SetVulkanHandlers(s_vkInstance, s_vkDevice);
m_pCommandBufferManager->Init();
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.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 = VK_LOD_CLAMP_NONE;
vkCreateSampler(s_vkDevice, &samplerInfo, nullptr, &m_defaultSampler.m_sampler);
}
void CVkRenderContext::Frame( float fDeltaTime )
@@ -1059,8 +1095,8 @@ formatPicked:
pImage->m_eImageType = IMAGE_TYPE_2D;
pImage->m_eMultisampleType = MULTISAMPLE_TYPE_NONE;
pImage->m_eFormat = IMAGE_FORMAT_BGRA8_UNORM;
pImage->m_nHeight = 1280;
pImage->m_nWidth = 720;
pImage->m_nHeight = pWindow->GetRenderWidth();
pImage->m_nWidth = pWindow->GetRenderHeight();
pImage->m_ePreferredLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR;
pImage->CreateImageView();
window.m_images[i] = pImage;

View File

@@ -225,6 +225,13 @@ public:
uint32_t m_nSize;
};
class CVkSampler: public ISampler
{
public:
virtual void SetDebugName( const char *szName ) override;
VkSampler m_sampler;
};
class CVkPipelineLibrary
{
public:
@@ -349,6 +356,7 @@ public:
virtual void SetDebugName( const char *szName ) override;
virtual uint32_t LoadTexture( const char *szPath ) override;
virtual uint32_t GetTextureID( const char *szPath ) override;
virtual IImage *GetTexture( uint32_t uTextureID ) override;
virtual void UnloadTexture( uint32_t uTextureID ) override;
void Frame();
@@ -374,7 +382,10 @@ public:
virtual void PSSetShaderResource( uint32_t uRegister, IRenderingObject *pResource ) override;
virtual void PSSetConstantsBuffer( uint32_t uRegister, IBuffer *pConstants ) override;
virtual void PSSetTextureArray( uint32_t uSet, ITextureArray *pArray ) override;
virtual void PSSetTexture( uint32_t uRegister, IImage *pImage ) override;
virtual void PSSetSampler( uint32_t uRegister, ISampler *pImage ) override;
CVkShader *m_pVkShader;
CUtlVector<VkDescriptorSet> m_hSets;
@@ -402,6 +413,7 @@ struct VulkanMaterialCommandBuffer_t
};
enum EVkFrameObjectType_t
{
FRAME_OBJECT_TYPE_SINGLE,
@@ -438,6 +450,7 @@ public:
virtual void SetRenderTarget( uint32_t uIndex, IImage *pImage ) override;
virtual void SetClearColor( uint32_t uIndex, float r, float g, float b, float a ) override;
virtual void SetLoadStoreModes( uint32_t uIndex, ELoadMode eLoadMode, EStoreMode eStoreMode ) override;
virtual void SetDepthTarget( IImage *pDepth ) override;
virtual void SetClearDepth( float fVal ) override;

View File

View File

View File

View File

@@ -5,15 +5,19 @@
#include "../materialsystem/igamewindow.h"
#include "tier2/iappsystem.h"
abstract_class IRenderFont
abstract_class IKotRenderFont
{
public:
virtual IImage *GetAtlas();
virtual bool IsLetterPresent( uint32_t letter );
virtual float GetLetterX( uint32_t letter );
virtual float GetLetterY( uint32_t letter );
virtual float GetWidthX( uint32_t letter );
virtual float GetWidthY( uint32_t letter );
virtual IImage *GetAtlas() = 0;
virtual bool IsLetterPresent( uint32_t letter ) = 0;
virtual float GetLetterX( uint32_t letter ) = 0;
virtual float GetLetterY( uint32_t letter ) = 0;
virtual float GetWidth( uint32_t letter ) = 0;
virtual float GetHeight( uint32_t letter ) = 0;
virtual bool IsMono() = 0;
virtual uint32_t GetLetterWidth() = 0;
virtual uint32_t GetLetterHeight() = 0;
};
abstract_class IKotUIBuffer
@@ -29,18 +33,21 @@ public:
virtual void PutChar( char c ) = 0;
virtual void Printf(const char *szFormat, ...) = 0;
virtual void Draw( IRenderContext *pRenderContext );
virtual void Draw( IImage *pImage ) = 0;
virtual void SetTextSize( int iY, int iX ) = 0;
virtual void SetTextFont( IRenderFont *pFont ) = 0;
virtual void SetTextFont( IKotRenderFont *pFont ) = 0;
};
abstract_class IKotUIManager: public IAppSystem
abstract_class IKotUIManager: public IAppSystem2
{
public:
virtual void CreateBuffer( int iWidth, int iHeight ) = 0;
virtual IKotRenderFont *LoadFont( const char *szPath ) = 0;
virtual IKotUIBuffer *CreateBuffer( int iWidth, int iHeight ) = 0;
virtual void DeleteBuffer( IKotUIBuffer *pBuffer ) = 0;
};
IKotUIManager *KotUIManager();
#define KOT_UI_INTEFACE_VERSION "KotUI001"

View File

@@ -166,12 +166,18 @@ public:
virtual EMultisampleType GetMultisampleType() = 0;
};
abstract_class ISampler : public IRenderingObject
{
};
abstract_class ITextureArray: public IRenderingObject
{
public:
virtual void Build() = 0;
virtual uint32_t LoadTexture( const char *szPath ) = 0;
virtual uint32_t GetTextureID( const char *szPath ) = 0;
virtual IImage *GetTexture( uint32_t uTextureID ) = 0;
virtual void UnloadTexture( uint32_t uTextureID ) = 0;
};
@@ -250,6 +256,8 @@ public:
virtual void VSSetConstantsBuffer( uint32_t uRegister, IBuffer *pImage ) = 0;
virtual void PSSetConstantsBuffer( uint32_t uRegister, IBuffer *pImage ) = 0;
virtual void PSSetTextureArray( uint32_t uSet, ITextureArray *pArray ) = 0;
virtual void PSSetTexture( uint32_t uRegister, IImage *pImage ) = 0;
virtual void PSSetSampler( uint32_t uRegister, ISampler *pImage ) = 0;
};
abstract_class IRenderCommandList
@@ -259,6 +267,7 @@ public:
virtual void SetRenderTarget( uint32_t uIndex, IImage *pImage ) = 0;
virtual void SetClearColor( uint32_t uIndex, float r, float g, float b, float a ) = 0;
virtual void SetLoadStoreModes( uint32_t uIndex, ELoadMode eLoadMode, EStoreMode eStoreMode ) = 0;
virtual void SetDepthTarget( IImage *pDepth ) = 0;
virtual void SetClearDepth( float fVal ) = 0;
@@ -321,6 +330,8 @@ public:
virtual ITextureArray *CreateTextureArray() = 0;
virtual void DestroyTextureArray() = 0;
virtual ISampler *GetDefaultSampler() = 0;
};
#define RENDER_CONTEXT_INTERFACE_VERSION "RenderContext001"

View File

Binary file not shown.