added ui rendering
This commit is contained in:
193
fgui/fgui.cpp
193
fgui/fgui.cpp
@@ -3,10 +3,17 @@
|
||||
#include "rendering.h"
|
||||
#include "tier1/utlvector.h"
|
||||
#include "fgui/widget.h"
|
||||
#include <cctype>
|
||||
|
||||
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<CFGUI_Widget*> 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<CFont*> 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()
|
||||
|
||||
Reference in New Issue
Block a user