improved font rendering

This commit is contained in:
2026-05-26 01:29:26 +03:00
parent f127ac3801
commit 5fdb17b773
21 changed files with 217 additions and 158 deletions

View File

@@ -32,6 +32,10 @@ public:
GlyphData_t *m_glyphs;
uint32_t m_uGlyphCount;
IImage *m_pAtlas;
bool m_bIsMono = false;
uint32_t m_uMonoWidth = 0;
uint32_t m_uMonoHeight = 0;
};
class CKotUIBuffer: public IKotUIBuffer
@@ -41,8 +45,11 @@ public:
virtual void Move( int iY, int iX ) override;
virtual void SetColor( char c ) override;
virtual void Clear( char c ) override;
virtual void SetColor( float fX, float fY, float fZ, float fA ) override;
virtual void SetBackgroundColor( float fX, float fY, float fZ, float fA ) override;
virtual void Clear( float fX, float fY, float fZ, float fA ) override;
virtual void PutChar( char c ) override;
virtual void Printf(const char *szFormat, ...) override;
@@ -64,6 +71,12 @@ public:
IKotRenderFont *m_pFont;
uint32_t m_uCursor = 0;
uint32_t m_uTextWidth = 16;
uint32_t m_uTextHeight = 16;
ColorAlpha m_fgColor = {1,1,1,1};
ColorAlpha m_bgColor = {0,0,0,0};
};
class CKotUIManager: public IKotUIManager
@@ -155,6 +168,24 @@ float CKotRenderFont::GetHeight( uint32_t letter )
bool CKotRenderFont::IsMono()
{
return m_bIsMono;
}
uint32_t CKotRenderFont::GetLetterWidth()
{
return m_uMonoWidth;
}
uint32_t CKotRenderFont::GetLetterHeight()
{
return m_uMonoHeight;
}
void CKotUIBuffer::SetPosition( int iY, int iX )
{
@@ -166,19 +197,30 @@ void CKotUIBuffer::Move( int iY, int iX )
m_uCursor = m_uCursor % (m_iWidth * m_iHeight);
}
void CKotUIBuffer::SetColor( char c )
void CKotUIBuffer::SetColor( float fX, float fY, float fZ, float fA )
{
m_fgColor = {fX, fY, fZ, fA};
}
void CKotUIBuffer::SetBackgroundColor( float fX, float fY, float fZ, float fA )
{
m_bgColor = {fX, fY, fZ, fA};
}
void CKotUIBuffer::Clear( float fX, float fY, float fZ, float fA )
{
}
void CKotUIBuffer::Clear( char c )
{
}
void CKotUIBuffer::PutChar( char c )
{
m_buffer[m_uCursor] = c;
m_primaryColor[m_uCursor] = m_fgColor;
m_secondaryColor[m_uCursor] = m_bgColor;
Move(0, m_uCursor+1);
}
@@ -199,6 +241,8 @@ void CKotUIBuffer::Printf(const char *szFormat, ...)
for ( size_t u = 0, i = m_uCursor; u < nSize; u++, i = (i + 1 % (m_iWidth * m_iHeight)) )
{
m_buffer[i] = psz[u];
m_primaryColor[i] = m_fgColor;
m_secondaryColor[i] = m_bgColor;
}
va_end(vlArgs2);
V_free(psz);
@@ -217,8 +261,8 @@ struct TextDrawData_t
float m_fPosY;
float m_fSizeX;
float m_fSizeY;
float m_fColor[4];
float m_fColor2[4];
ColorAlpha m_fColor1;
ColorAlpha m_fColor2;
};
struct ScreenData_t
@@ -240,16 +284,16 @@ void CKotUIBuffer::Draw( IImage *pImage )
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;
pData[uRealGlyphCount].m_fSizeX = m_uTextWidth;
pData[uRealGlyphCount].m_fSizeY = m_uTextHeight;
pData[uRealGlyphCount].m_fPosX = i%m_iWidth*m_uTextWidth;
pData[uRealGlyphCount].m_fPosY = i/m_iWidth*m_uTextHeight;
pData[uRealGlyphCount].m_fColor1 = m_primaryColor[i];
pData[uRealGlyphCount].m_fColor2 = m_secondaryColor[i];
uRealGlyphCount++;
}
m_pDataBuffer->Unmap();
@@ -274,17 +318,24 @@ void CKotUIBuffer::Draw( IImage *pImage )
pList->SetLoadStoreModes(0, LOAD_MODE_LOAD, STORE_MODE_STORE);
pList->SetRenderResolution(pImage->GetImageWidth(), pImage->GetImageHeight());
pList->Barrier(m_pDataBuffer, true, false);
pList->Barrier(pScreenBuffer, true, false);
pList->Barrier(m_pFont->GetAtlas(), true, false);
pList->SetMaterial(m_pMaterial);
pList->SetVertexBuffer(0, s_pGlyphBuffer);
pList->DrawPrimitives(6, 0, uRealGlyphCount, 0);
pList->EndRecording();
m_pRenderContext->SubmitCommandList(pList);
m_pRenderContext->DestroyBuffer(pScreenBuffer);
}
void CKotUIBuffer::SetTextSize( int iY, int iX )
{
m_uTextHeight = iY;
m_uTextWidth = iX;
}
@@ -301,7 +352,7 @@ 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->AddOutputImage(0, IMAGE_FORMAT_RGBA8_UNORM, true);
s_pShader->Build();
s_pGlyphBuffer = m_pRenderContext->CreateVertexBuffer(sizeof(float)*12);
void *pBuffer = s_pGlyphBuffer->Map();
@@ -349,9 +400,16 @@ IKotRenderFont *CKotUIManager::LoadFont( const char *szPath )
uint32_t uAtlas = m_pFonts->LoadTexture(szAtlas);
CKotRenderFont *pFont = new CKotRenderFont;
IJSONObject *pAtlas = pValue->GetObject()->GetValue("atlas")->GetObject();
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();
uint32_t atlasWidth = pAtlas->GetValue("width")->GetNumberValue();
uint32_t atlasHeight = pAtlas->GetValue("height")->GetNumberValue();
pFont->m_bIsMono = pAtlas->GetValue("grid") != NULL;
if (pFont->m_bIsMono)
{
pFont->m_uMonoWidth = pAtlas->GetValue("grid")->GetObject()->GetValue("cellWidth")->GetNumberValue();
pFont->m_uMonoHeight = pAtlas->GetValue("grid")->GetObject()->GetValue("cellHeight")->GetNumberValue();
}
pFont->m_uGlyphCount = 0;
pFont->m_glyphs = (GlyphData_t*)V_malloc(sizeof(GlyphData_t)*pGlyphs->GetCount());
@@ -385,6 +443,10 @@ IKotUIBuffer *CKotUIManager::CreateBuffer( int iWidth, int iHeight )
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_primaryColor = (ColorAlpha*)V_malloc(sizeof(ColorAlpha)*iWidth*iHeight);
V_memset(pBuffer->m_primaryColor, 0, sizeof(ColorAlpha)*iWidth*iHeight);
pBuffer->m_secondaryColor = (ColorAlpha*)V_malloc(sizeof(ColorAlpha)*iWidth*iHeight);
V_memset(pBuffer->m_secondaryColor, 0, sizeof(ColorAlpha)*iWidth*iHeight);
pBuffer->m_iWidth = iWidth;
pBuffer->m_iHeight = iHeight;