Remove old RasterFont classes

This commit is contained in:
Stenzek 2018-10-10 01:34:26 +11:00
parent 600d1fc0bc
commit 63dd91628d
28 changed files with 4 additions and 1296 deletions

View File

@ -98,390 +98,7 @@ private:
std::list<bool*> observers; std::list<bool*> observers;
}; };
class CD3DFont
{
public:
CD3DFont();
// 2D text drawing function
// Initializing and destroying device-dependent objects
int Init();
int Shutdown();
int DrawTextScaled(float x, float y, float size, float spacing, u32 dwColor,
const std::string& text);
private:
ID3D11ShaderResourceView* m_pTexture;
ID3D11Buffer* m_pVB;
ID3D11InputLayout* m_InputLayout;
ID3D11PixelShader* m_pshader;
ID3D11VertexShader* m_vshader;
ID3D11BlendState* m_blendstate;
ID3D11RasterizerState* m_raststate;
const int m_dwTexWidth;
const int m_dwTexHeight;
unsigned int m_LineHeight;
float m_fTexCoords[128 - 32][4];
};
static CD3DFont font;
static UtilVertexBuffer* util_vbuf = nullptr; static UtilVertexBuffer* util_vbuf = nullptr;
#define MAX_NUM_VERTICES 50 * 6
struct FONT2DVERTEX
{
float x, y, z;
float col[4];
float tu, tv;
};
inline FONT2DVERTEX InitFont2DVertex(float x, float y, u32 color, float tu, float tv)
{
FONT2DVERTEX v;
v.x = x;
v.y = y;
v.z = 0;
v.tu = tu;
v.tv = tv;
v.col[0] = ((float)((color >> 16) & 0xFF)) / 255.f;
v.col[1] = ((float)((color >> 8) & 0xFF)) / 255.f;
v.col[2] = ((float)((color >> 0) & 0xFF)) / 255.f;
v.col[3] = ((float)((color >> 24) & 0xFF)) / 255.f;
return v;
}
CD3DFont::CD3DFont() : m_dwTexWidth(512), m_dwTexHeight(512)
{
m_pTexture = nullptr;
m_pVB = nullptr;
m_InputLayout = nullptr;
m_pshader = nullptr;
m_vshader = nullptr;
}
const char fontpixshader[] = {"Texture2D tex2D;\n"
"SamplerState linearSampler\n"
"{\n"
" Filter = MIN_MAG_MIP_LINEAR;\n"
" AddressU = D3D11_TEXTURE_ADDRESS_BORDER;\n"
" AddressV = D3D11_TEXTURE_ADDRESS_BORDER;\n"
" BorderColor = float4(0.f, 0.f, 0.f, 0.f);\n"
"};\n"
"struct PS_INPUT\n"
"{\n"
" float4 pos : SV_POSITION;\n"
" float4 col : COLOR;\n"
" float2 tex : TEXCOORD;\n"
"};\n"
"float4 main( PS_INPUT input ) : SV_Target\n"
"{\n"
" return tex2D.Sample( linearSampler, input.tex ) * input.col;\n"
"};\n"};
const char fontvertshader[] = {"struct VS_INPUT\n"
"{\n"
" float4 pos : POSITION;\n"
" float4 col : COLOR;\n"
" float2 tex : TEXCOORD;\n"
"};\n"
"struct PS_INPUT\n"
"{\n"
" float4 pos : SV_POSITION;\n"
" float4 col : COLOR;\n"
" float2 tex : TEXCOORD;\n"
"};\n"
"PS_INPUT main( VS_INPUT input )\n"
"{\n"
" PS_INPUT output;\n"
" output.pos = input.pos;\n"
" output.col = input.col;\n"
" output.tex = input.tex;\n"
" return output;\n"
"};\n"};
int CD3DFont::Init()
{
// Create vertex buffer for the letters
HRESULT hr;
// Prepare to create a bitmap
unsigned int* pBitmapBits;
BITMAPINFO bmi;
ZeroMemory(&bmi.bmiHeader, sizeof(BITMAPINFOHEADER));
bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
bmi.bmiHeader.biWidth = (int)m_dwTexWidth;
bmi.bmiHeader.biHeight = -(int)m_dwTexHeight;
bmi.bmiHeader.biPlanes = 1;
bmi.bmiHeader.biCompression = BI_RGB;
bmi.bmiHeader.biBitCount = 32;
// Create a DC and a bitmap for the font
HDC hDC = CreateCompatibleDC(nullptr);
HBITMAP hbmBitmap = CreateDIBSection(hDC, &bmi, DIB_RGB_COLORS, (void**)&pBitmapBits, nullptr, 0);
SetMapMode(hDC, MM_TEXT);
// create a GDI font
HFONT hFont =
CreateFont(24, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS,
CLIP_DEFAULT_PRECIS, PROOF_QUALITY, VARIABLE_PITCH, _T("Tahoma"));
if (nullptr == hFont)
return E_FAIL;
HGDIOBJ hOldbmBitmap = SelectObject(hDC, hbmBitmap);
HGDIOBJ hOldFont = SelectObject(hDC, hFont);
// Set text properties
SetTextColor(hDC, 0xFFFFFF);
SetBkColor(hDC, 0);
SetTextAlign(hDC, TA_TOP);
TEXTMETRICW tm;
GetTextMetricsW(hDC, &tm);
m_LineHeight = tm.tmHeight;
// Loop through all printable characters and output them to the bitmap
// Meanwhile, keep track of the corresponding tex coords for each character.
int x = 0, y = 0;
char str[2] = "\0";
for (int c = 0; c < 127 - 32; c++)
{
str[0] = c + 32;
SIZE size;
GetTextExtentPoint32A(hDC, str, 1, &size);
if ((int)(x + size.cx + 1) > m_dwTexWidth)
{
x = 0;
y += m_LineHeight;
}
ExtTextOutA(hDC, x + 1, y + 0, ETO_OPAQUE | ETO_CLIPPED, nullptr, str, 1, nullptr);
m_fTexCoords[c][0] = ((float)(x + 0)) / m_dwTexWidth;
m_fTexCoords[c][1] = ((float)(y + 0)) / m_dwTexHeight;
m_fTexCoords[c][2] = ((float)(x + 0 + size.cx)) / m_dwTexWidth;
m_fTexCoords[c][3] = ((float)(y + 0 + size.cy)) / m_dwTexHeight;
x += size.cx + 3; // 3 to work around annoying ij conflict (part of the j ends up with the i)
}
// Create a new texture for the font
// possible optimization: store the converted data in a buffer and fill the texture on creation.
// That way, we can use a static texture
ID3D11Texture2D* buftex;
D3D11_TEXTURE2D_DESC texdesc = CD3D11_TEXTURE2D_DESC(
DXGI_FORMAT_R8G8B8A8_UNORM, m_dwTexWidth, m_dwTexHeight, 1, 1, D3D11_BIND_SHADER_RESOURCE,
D3D11_USAGE_DYNAMIC, D3D11_CPU_ACCESS_WRITE);
hr = device->CreateTexture2D(&texdesc, nullptr, &buftex);
if (FAILED(hr))
{
PanicAlert("Failed to create font texture");
return hr;
}
D3D::SetDebugObjectName(buftex, "texture of a CD3DFont object");
// Lock the surface and write the alpha values for the set pixels
D3D11_MAPPED_SUBRESOURCE texmap;
hr = context->Map(buftex, 0, D3D11_MAP_WRITE_DISCARD, 0, &texmap);
if (FAILED(hr))
PanicAlert("Failed to map a texture at %s %d\n", __FILE__, __LINE__);
for (y = 0; y < m_dwTexHeight; y++)
{
u32* pDst32 = (u32*)((u8*)texmap.pData + y * texmap.RowPitch);
for (x = 0; x < m_dwTexWidth; x++)
{
const u8 bAlpha = (pBitmapBits[m_dwTexWidth * y + x] & 0xff);
*pDst32++ = (((bAlpha << 4) | bAlpha) << 24) | 0xFFFFFF;
}
}
// Done updating texture, so clean up used objects
context->Unmap(buftex, 0);
hr = D3D::device->CreateShaderResourceView(buftex, nullptr, &m_pTexture);
if (FAILED(hr))
PanicAlert("Failed to create shader resource view at %s %d\n", __FILE__, __LINE__);
SAFE_RELEASE(buftex);
SelectObject(hDC, hOldbmBitmap);
DeleteObject(hbmBitmap);
SelectObject(hDC, hOldFont);
DeleteObject(hFont);
// setup device objects for drawing
m_pshader = D3D::CompileAndCreatePixelShader(fontpixshader);
if (m_pshader == nullptr)
PanicAlert("Failed to create pixel shader, %s %d\n", __FILE__, __LINE__);
D3D::SetDebugObjectName(m_pshader, "pixel shader of a CD3DFont object");
D3DBlob* vsbytecode;
D3D::CompileVertexShader(fontvertshader, &vsbytecode);
if (vsbytecode == nullptr)
PanicAlert("Failed to compile vertex shader, %s %d\n", __FILE__, __LINE__);
m_vshader = D3D::CreateVertexShaderFromByteCode(vsbytecode);
if (m_vshader == nullptr)
PanicAlert("Failed to create vertex shader, %s %d\n", __FILE__, __LINE__);
D3D::SetDebugObjectName(m_vshader, "vertex shader of a CD3DFont object");
const D3D11_INPUT_ELEMENT_DESC desc[] = {
{"POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0},
{"COLOR", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0},
{"TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 28, D3D11_INPUT_PER_VERTEX_DATA, 0},
};
hr = D3D::device->CreateInputLayout(desc, 3, vsbytecode->Data(), vsbytecode->Size(),
&m_InputLayout);
if (FAILED(hr))
PanicAlert("Failed to create input layout, %s %d\n", __FILE__, __LINE__);
SAFE_RELEASE(vsbytecode);
D3D11_BLEND_DESC blenddesc;
blenddesc.AlphaToCoverageEnable = FALSE;
blenddesc.IndependentBlendEnable = FALSE;
blenddesc.RenderTarget[0].BlendEnable = TRUE;
blenddesc.RenderTarget[0].RenderTargetWriteMask = D3D11_COLOR_WRITE_ENABLE_ALL;
blenddesc.RenderTarget[0].SrcBlend = D3D11_BLEND_SRC_ALPHA;
blenddesc.RenderTarget[0].DestBlend = D3D11_BLEND_INV_SRC_ALPHA;
blenddesc.RenderTarget[0].BlendOp = D3D11_BLEND_OP_ADD;
blenddesc.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_SRC_ALPHA;
blenddesc.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_INV_SRC_ALPHA;
blenddesc.RenderTarget[0].BlendOpAlpha = D3D11_BLEND_OP_ADD;
hr = D3D::device->CreateBlendState(&blenddesc, &m_blendstate);
CHECK(hr == S_OK, "Create font blend state");
D3D::SetDebugObjectName(m_blendstate, "blend state of a CD3DFont object");
D3D11_RASTERIZER_DESC rastdesc = CD3D11_RASTERIZER_DESC(D3D11_FILL_SOLID, D3D11_CULL_NONE, false,
0, 0.f, 0.f, false, false, false, false);
hr = D3D::device->CreateRasterizerState(&rastdesc, &m_raststate);
CHECK(hr == S_OK, "Create font rasterizer state");
D3D::SetDebugObjectName(m_raststate, "rasterizer state of a CD3DFont object");
D3D11_BUFFER_DESC vbdesc =
CD3D11_BUFFER_DESC(MAX_NUM_VERTICES * sizeof(FONT2DVERTEX), D3D11_BIND_VERTEX_BUFFER,
D3D11_USAGE_DYNAMIC, D3D11_CPU_ACCESS_WRITE);
if (FAILED(hr = device->CreateBuffer(&vbdesc, nullptr, &m_pVB)))
{
PanicAlert("Failed to create font vertex buffer at %s, line %d\n", __FILE__, __LINE__);
return hr;
}
D3D::SetDebugObjectName(m_pVB, "vertex buffer of a CD3DFont object");
return S_OK;
}
int CD3DFont::Shutdown()
{
SAFE_RELEASE(m_pVB);
SAFE_RELEASE(m_pTexture);
SAFE_RELEASE(m_InputLayout);
SAFE_RELEASE(m_pshader);
SAFE_RELEASE(m_vshader);
SAFE_RELEASE(m_blendstate);
SAFE_RELEASE(m_raststate);
return S_OK;
}
int CD3DFont::DrawTextScaled(float x, float y, float size, float spacing, u32 dwColor,
const std::string& text)
{
if (!m_pVB)
return 0;
UINT stride = sizeof(FONT2DVERTEX);
UINT bufoffset = 0;
float scalex = 1.0f / g_renderer->GetBackbufferWidth() * 2.f;
float scaley = 1.0f / g_renderer->GetBackbufferHeight() * 2.f;
float sizeratio = size / m_LineHeight;
// translate starting positions
float sx = x * scalex - 1.f;
float sy = 1.f - y * scaley;
// Fill vertex buffer
FONT2DVERTEX* pVertices;
int dwNumTriangles = 0L;
D3D11_MAPPED_SUBRESOURCE vbmap;
HRESULT hr = context->Map(m_pVB, 0, D3D11_MAP_WRITE_DISCARD, 0, &vbmap);
if (FAILED(hr))
PanicAlert("Mapping vertex buffer failed, %s %d\n", __FILE__, __LINE__);
pVertices = (D3D::FONT2DVERTEX*)vbmap.pData;
// set general pipeline state
D3D::stateman->SetBlendState(m_blendstate);
D3D::stateman->SetRasterizerState(m_raststate);
D3D::stateman->SetPixelShader(m_pshader);
D3D::stateman->SetVertexShader(m_vshader);
D3D::stateman->SetGeometryShader(nullptr);
D3D::stateman->SetInputLayout(m_InputLayout);
D3D::stateman->SetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
D3D::stateman->SetTexture(0, m_pTexture);
float fStartX = sx;
for (char c : text)
{
if (c == '\n')
{
sx = fStartX;
sy -= scaley * size;
}
if (!std::isprint(c))
continue;
c -= 32;
float tx1 = m_fTexCoords[c][0];
float ty1 = m_fTexCoords[c][1];
float tx2 = m_fTexCoords[c][2];
float ty2 = m_fTexCoords[c][3];
float w = (float)(tx2 - tx1) * m_dwTexWidth * scalex * sizeratio;
float h = (float)(ty1 - ty2) * m_dwTexHeight * scaley * sizeratio;
FONT2DVERTEX v[6];
v[0] = InitFont2DVertex(sx, sy + h, dwColor, tx1, ty2);
v[1] = InitFont2DVertex(sx, sy, dwColor, tx1, ty1);
v[2] = InitFont2DVertex(sx + w, sy + h, dwColor, tx2, ty2);
v[3] = InitFont2DVertex(sx + w, sy, dwColor, tx2, ty1);
v[4] = v[2];
v[5] = v[1];
memcpy(pVertices, v, 6 * sizeof(FONT2DVERTEX));
pVertices += 6;
dwNumTriangles += 2;
if (dwNumTriangles * 3 > (MAX_NUM_VERTICES - 6))
{
context->Unmap(m_pVB, 0);
D3D::stateman->SetVertexBuffer(m_pVB, stride, bufoffset);
D3D::stateman->Apply();
D3D::context->Draw(3 * dwNumTriangles, 0);
dwNumTriangles = 0;
D3D11_MAPPED_SUBRESOURCE _vbmap;
hr = context->Map(m_pVB, 0, D3D11_MAP_WRITE_DISCARD, 0, &_vbmap);
if (FAILED(hr))
PanicAlert("Mapping vertex buffer failed, %s %d\n", __FILE__, __LINE__);
pVertices = (D3D::FONT2DVERTEX*)_vbmap.pData;
}
sx += w + spacing * scalex * size;
}
// Unlock and render the vertex buffer
context->Unmap(m_pVB, 0);
if (dwNumTriangles > 0)
{
D3D::stateman->SetVertexBuffer(m_pVB, stride, bufoffset);
D3D::stateman->Apply();
D3D::context->Draw(3 * dwNumTriangles, 0);
}
return S_OK;
}
static ID3D11SamplerState* linear_copy_sampler = nullptr; static ID3D11SamplerState* linear_copy_sampler = nullptr;
static ID3D11SamplerState* point_copy_sampler = nullptr; static ID3D11SamplerState* point_copy_sampler = nullptr;
@ -560,13 +177,10 @@ void InitUtils()
util_vbuf->AddWrapObserver(&stq_observer); util_vbuf->AddWrapObserver(&stq_observer);
util_vbuf->AddWrapObserver(&cq_observer); util_vbuf->AddWrapObserver(&cq_observer);
util_vbuf->AddWrapObserver(&clearq_observer); util_vbuf->AddWrapObserver(&clearq_observer);
font.Init();
} }
void ShutdownUtils() void ShutdownUtils()
{ {
font.Shutdown();
SAFE_RELEASE(point_copy_sampler); SAFE_RELEASE(point_copy_sampler);
SAFE_RELEASE(linear_copy_sampler); SAFE_RELEASE(linear_copy_sampler);
SAFE_DELETE(util_vbuf); SAFE_DELETE(util_vbuf);
@ -788,10 +402,6 @@ void DrawEFBPokeQuads(EFBAccessType type, const EfbPokeData* points, size_t num_
stateman->SetGeometryShader(GeometryShaderCache::GetClearGeometryShader()); stateman->SetGeometryShader(GeometryShaderCache::GetClearGeometryShader());
} }
void DrawTextScaled(float x, float y, float size, float spacing, u32 color, const std::string& text)
{
font.DrawTextScaled(x, y, size, spacing, color, text);
}
} // namespace D3D } // namespace D3D
} // namespace DX11 } // namespace DX11

View File

@ -28,7 +28,5 @@ void drawClearQuad(u32 Color, float z);
void drawColorQuad(u32 Color, float z, float x1, float y1, float x2, float y2); void drawColorQuad(u32 Color, float z, float x1, float y1, float x2, float y2);
void DrawEFBPokeQuads(EFBAccessType type, const EfbPokeData* points, size_t num_points); void DrawEFBPokeQuads(EFBAccessType type, const EfbPokeData* points, size_t num_points);
void DrawTextScaled(float x, float y, float size, float spacing, u32 color,
const std::string& text);
} }
} }

View File

@ -237,13 +237,6 @@ Renderer::CreateFramebuffer(const AbstractTexture* color_attachment,
static_cast<const DXTexture*>(depth_attachment)); static_cast<const DXTexture*>(depth_attachment));
} }
void Renderer::RenderText(const std::string& text, int left, int top, u32 color)
{
D3D::DrawTextScaled(static_cast<float>(left + 1), static_cast<float>(top + 1), 20.f, 0.0f,
color & 0xFF000000, text);
D3D::DrawTextScaled(static_cast<float>(left), static_cast<float>(top), 20.f, 0.0f, color, text);
}
std::unique_ptr<AbstractShader> Renderer::CreateShaderFromSource(ShaderStage stage, std::unique_ptr<AbstractShader> Renderer::CreateShaderFromSource(ShaderStage stage,
const char* source, size_t length) const char* source, size_t length)
{ {

View File

@ -55,8 +55,6 @@ public:
void SetFullscreen(bool enable_fullscreen) override; void SetFullscreen(bool enable_fullscreen) override;
bool IsFullscreen() const override; bool IsFullscreen() const override;
void RenderText(const std::string& text, int left, int top, u32 color) override;
u32 AccessEFB(EFBAccessType type, u32 x, u32 y, u32 poke_data) override; u32 AccessEFB(EFBAccessType type, u32 x, u32 y, u32 poke_data) override;
void PokeEFB(EFBAccessType type, const EfbPokeData* points, size_t num_points) override; void PokeEFB(EFBAccessType type, const EfbPokeData* points, size_t num_points) override;

View File

@ -82,11 +82,6 @@ Renderer::CreateFramebuffer(const AbstractTexture* color_attachment,
static_cast<const NullTexture*>(depth_attachment)); static_cast<const NullTexture*>(depth_attachment));
} }
void Renderer::RenderText(const std::string& text, int left, int top, u32 color)
{
NOTICE_LOG(VIDEO, "RenderText: %s", text.c_str());
}
TargetRectangle Renderer::ConvertEFBRectangle(const EFBRectangle& rc) TargetRectangle Renderer::ConvertEFBRectangle(const EFBRectangle& rc)
{ {
TargetRectangle result; TargetRectangle result;

View File

@ -29,7 +29,6 @@ public:
size_t length) override; size_t length) override;
std::unique_ptr<AbstractPipeline> CreatePipeline(const AbstractPipelineConfig& config) override; std::unique_ptr<AbstractPipeline> CreatePipeline(const AbstractPipelineConfig& config) override;
void RenderText(const std::string& pstr, int left, int top, u32 color) override;
u32 AccessEFB(EFBAccessType type, u32 x, u32 y, u32 poke_data) override { return 0; } u32 AccessEFB(EFBAccessType type, u32 x, u32 y, u32 poke_data) override { return 0; }
void PokeEFB(EFBAccessType type, const EfbPokeData* points, size_t num_points) override {} void PokeEFB(EFBAccessType type, const EfbPokeData* points, size_t num_points) override {}
u16 BBoxRead(int index) override { return 0; } u16 BBoxRead(int index) override { return 0; }

View File

@ -9,7 +9,6 @@ add_library(videoogl
PerfQuery.cpp PerfQuery.cpp
PostProcessing.cpp PostProcessing.cpp
ProgramShaderCache.cpp ProgramShaderCache.cpp
RasterFont.cpp
Render.cpp Render.cpp
SamplerCache.cpp SamplerCache.cpp
StreamBuffer.cpp StreamBuffer.cpp

View File

@ -46,7 +46,6 @@
<ClCompile Include="PerfQuery.cpp" /> <ClCompile Include="PerfQuery.cpp" />
<ClCompile Include="PostProcessing.cpp" /> <ClCompile Include="PostProcessing.cpp" />
<ClCompile Include="ProgramShaderCache.cpp" /> <ClCompile Include="ProgramShaderCache.cpp" />
<ClCompile Include="RasterFont.cpp" />
<ClCompile Include="Render.cpp" /> <ClCompile Include="Render.cpp" />
<ClCompile Include="SamplerCache.cpp" /> <ClCompile Include="SamplerCache.cpp" />
<ClCompile Include="StreamBuffer.cpp" /> <ClCompile Include="StreamBuffer.cpp" />
@ -64,7 +63,6 @@
<ClInclude Include="PerfQuery.h" /> <ClInclude Include="PerfQuery.h" />
<ClInclude Include="PostProcessing.h" /> <ClInclude Include="PostProcessing.h" />
<ClInclude Include="ProgramShaderCache.h" /> <ClInclude Include="ProgramShaderCache.h" />
<ClInclude Include="RasterFont.h" />
<ClInclude Include="Render.h" /> <ClInclude Include="Render.h" />
<ClInclude Include="SamplerCache.h" /> <ClInclude Include="SamplerCache.h" />
<ClInclude Include="StreamBuffer.h" /> <ClInclude Include="StreamBuffer.h" />

View File

@ -7,9 +7,6 @@
<Filter Include="GLUtil"> <Filter Include="GLUtil">
<UniqueIdentifier>{5bfec41c-1031-4925-8f98-38c7b49b1924}</UniqueIdentifier> <UniqueIdentifier>{5bfec41c-1031-4925-8f98-38c7b49b1924}</UniqueIdentifier>
</Filter> </Filter>
<Filter Include="Logging">
<UniqueIdentifier>{00dadfd8-a906-4b0c-b415-d42a69cf3ca7}</UniqueIdentifier>
</Filter>
<Filter Include="Render"> <Filter Include="Render">
<UniqueIdentifier>{696df73b-378e-4399-8f21-999b65d78dcd}</UniqueIdentifier> <UniqueIdentifier>{696df73b-378e-4399-8f21-999b65d78dcd}</UniqueIdentifier>
</Filter> </Filter>
@ -24,9 +21,6 @@
<ClCompile Include="TextureConverter.cpp"> <ClCompile Include="TextureConverter.cpp">
<Filter>GLUtil</Filter> <Filter>GLUtil</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="RasterFont.cpp">
<Filter>Logging</Filter>
</ClCompile>
<ClCompile Include="BoundingBox.cpp"> <ClCompile Include="BoundingBox.cpp">
<Filter>Render</Filter> <Filter>Render</Filter>
</ClCompile> </ClCompile>
@ -70,9 +64,6 @@
<ClInclude Include="TextureConverter.h"> <ClInclude Include="TextureConverter.h">
<Filter>GLUtil</Filter> <Filter>GLUtil</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="RasterFont.h">
<Filter>Logging</Filter>
</ClInclude>
<ClInclude Include="BoundingBox.h"> <ClInclude Include="BoundingBox.h">
<Filter>Render</Filter> <Filter>Render</Filter>
</ClInclude> </ClInclude>

View File

@ -198,11 +198,6 @@ void OpenGLPostProcessing::CreateHeader()
"#define SampleOffset(offset) textureOffset(samp9, float3(uv0, layer), offset)\n" "#define SampleOffset(offset) textureOffset(samp9, float3(uv0, layer), offset)\n"
"float4 SampleFontLocation(float2 location)\n"
"{\n"
"\treturn texture(samp8, location);\n"
"}\n"
"float2 GetResolution()\n" "float2 GetResolution()\n"
"{\n" "{\n"
"\treturn resolution.xy;\n" "\treturn resolution.xy;\n"

View File

@ -1,291 +0,0 @@
// Copyright 2008 Dolphin Emulator Project
// Licensed under GPLv2+
// Refer to the license.txt file included.
#include <vector>
#include "Common/Common.h"
#include "Common/GL/GLUtil.h"
#include "VideoBackends/OGL/ProgramShaderCache.h"
#include "VideoBackends/OGL/RasterFont.h"
#include "VideoBackends/OGL/VertexManager.h"
// globals
namespace OGL
{
static const int CHARACTER_WIDTH = 8;
static const int CHARACTER_HEIGHT = 13;
static const int CHARACTER_OFFSET = 32;
static const int CHARACTER_COUNT = 95;
static const u8 rasters[CHARACTER_COUNT][CHARACTER_HEIGHT] = {
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x36, 0x36, 0x36},
{0x00, 0x00, 0x00, 0x66, 0x66, 0xff, 0x66, 0x66, 0xff, 0x66, 0x66, 0x00, 0x00},
{0x00, 0x00, 0x18, 0x7e, 0xff, 0x1b, 0x1f, 0x7e, 0xf8, 0xd8, 0xff, 0x7e, 0x18},
{0x00, 0x00, 0x0e, 0x1b, 0xdb, 0x6e, 0x30, 0x18, 0x0c, 0x76, 0xdb, 0xd8, 0x70},
{0x00, 0x00, 0x7f, 0xc6, 0xcf, 0xd8, 0x70, 0x70, 0xd8, 0xcc, 0xcc, 0x6c, 0x38},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x1c, 0x0c, 0x0e},
{0x00, 0x00, 0x0c, 0x18, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x18, 0x0c},
{0x00, 0x00, 0x30, 0x18, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x18, 0x30},
{0x00, 0x00, 0x00, 0x00, 0x99, 0x5a, 0x3c, 0xff, 0x3c, 0x5a, 0x99, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0xff, 0xff, 0x18, 0x18, 0x18, 0x00, 0x00},
{0x00, 0x00, 0x30, 0x18, 0x1c, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x38, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x60, 0x60, 0x30, 0x30, 0x18, 0x18, 0x0c, 0x0c, 0x06, 0x06, 0x03, 0x03},
{0x00, 0x00, 0x3c, 0x66, 0xc3, 0xe3, 0xf3, 0xdb, 0xcf, 0xc7, 0xc3, 0x66, 0x3c},
{0x00, 0x00, 0x7e, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x78, 0x38, 0x18},
{0x00, 0x00, 0xff, 0xc0, 0xc0, 0x60, 0x30, 0x18, 0x0c, 0x06, 0x03, 0xe7, 0x7e},
{0x00, 0x00, 0x7e, 0xe7, 0x03, 0x03, 0x07, 0x7e, 0x07, 0x03, 0x03, 0xe7, 0x7e},
{0x00, 0x00, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0xff, 0xcc, 0x6c, 0x3c, 0x1c, 0x0c},
{0x00, 0x00, 0x7e, 0xe7, 0x03, 0x03, 0x07, 0xfe, 0xc0, 0xc0, 0xc0, 0xc0, 0xff},
{0x00, 0x00, 0x7e, 0xe7, 0xc3, 0xc3, 0xc7, 0xfe, 0xc0, 0xc0, 0xc0, 0xe7, 0x7e},
{0x00, 0x00, 0x30, 0x30, 0x30, 0x30, 0x18, 0x0c, 0x06, 0x03, 0x03, 0x03, 0xff},
{0x00, 0x00, 0x7e, 0xe7, 0xc3, 0xc3, 0xe7, 0x7e, 0xe7, 0xc3, 0xc3, 0xe7, 0x7e},
{0x00, 0x00, 0x7e, 0xe7, 0x03, 0x03, 0x03, 0x7f, 0xe7, 0xc3, 0xc3, 0xe7, 0x7e},
{0x00, 0x00, 0x00, 0x38, 0x38, 0x00, 0x00, 0x38, 0x38, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x30, 0x18, 0x1c, 0x1c, 0x00, 0x00, 0x1c, 0x1c, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0, 0x60, 0x30, 0x18, 0x0c, 0x06},
{0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x60, 0x30, 0x18, 0x0c, 0x06, 0x03, 0x06, 0x0c, 0x18, 0x30, 0x60},
{0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x18, 0x0c, 0x06, 0x03, 0xc3, 0xc3, 0x7e},
{0x00, 0x00, 0x3f, 0x60, 0xcf, 0xdb, 0xd3, 0xdd, 0xc3, 0x7e, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xc3, 0xc3, 0xc3, 0xc3, 0xff, 0xc3, 0xc3, 0xc3, 0x66, 0x3c, 0x18},
{0x00, 0x00, 0xfe, 0xc7, 0xc3, 0xc3, 0xc7, 0xfe, 0xc7, 0xc3, 0xc3, 0xc7, 0xfe},
{0x00, 0x00, 0x7e, 0xe7, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xe7, 0x7e},
{0x00, 0x00, 0xfc, 0xce, 0xc7, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc7, 0xce, 0xfc},
{0x00, 0x00, 0xff, 0xc0, 0xc0, 0xc0, 0xc0, 0xfc, 0xc0, 0xc0, 0xc0, 0xc0, 0xff},
{0x00, 0x00, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xfc, 0xc0, 0xc0, 0xc0, 0xff},
{0x00, 0x00, 0x7e, 0xe7, 0xc3, 0xc3, 0xcf, 0xc0, 0xc0, 0xc0, 0xc0, 0xe7, 0x7e},
{0x00, 0x00, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xff, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3},
{0x00, 0x00, 0x7e, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x7e},
{0x00, 0x00, 0x7c, 0xee, 0xc6, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06},
{0x00, 0x00, 0xc3, 0xc6, 0xcc, 0xd8, 0xf0, 0xe0, 0xf0, 0xd8, 0xcc, 0xc6, 0xc3},
{0x00, 0x00, 0xff, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0},
{0x00, 0x00, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xdb, 0xff, 0xff, 0xe7, 0xc3},
{0x00, 0x00, 0xc7, 0xc7, 0xcf, 0xcf, 0xdf, 0xdb, 0xfb, 0xf3, 0xf3, 0xe3, 0xe3},
{0x00, 0x00, 0x7e, 0xe7, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xe7, 0x7e},
{0x00, 0x00, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xfe, 0xc7, 0xc3, 0xc3, 0xc7, 0xfe},
{0x00, 0x00, 0x3f, 0x6e, 0xdf, 0xdb, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0x66, 0x3c},
{0x00, 0x00, 0xc3, 0xc6, 0xcc, 0xd8, 0xf0, 0xfe, 0xc7, 0xc3, 0xc3, 0xc7, 0xfe},
{0x00, 0x00, 0x7e, 0xe7, 0x03, 0x03, 0x07, 0x7e, 0xe0, 0xc0, 0xc0, 0xe7, 0x7e},
{0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xff},
{0x00, 0x00, 0x7e, 0xe7, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3},
{0x00, 0x00, 0x18, 0x3c, 0x3c, 0x66, 0x66, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3},
{0x00, 0x00, 0xc3, 0xe7, 0xff, 0xff, 0xdb, 0xdb, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3},
{0x00, 0x00, 0xc3, 0x66, 0x66, 0x3c, 0x3c, 0x18, 0x3c, 0x3c, 0x66, 0x66, 0xc3},
{0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x3c, 0x66, 0x66, 0xc3},
{0x00, 0x00, 0xff, 0xc0, 0xc0, 0x60, 0x30, 0x7e, 0x0c, 0x06, 0x03, 0x03, 0xff},
{0x00, 0x00, 0x3c, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x3c},
{0x00, 0x03, 0x03, 0x06, 0x06, 0x0c, 0x0c, 0x18, 0x18, 0x30, 0x30, 0x60, 0x60},
{0x00, 0x00, 0x3c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x3c},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0x66, 0x3c, 0x18},
{0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x38, 0x30, 0x70},
{0x00, 0x00, 0x7f, 0xc3, 0xc3, 0x7f, 0x03, 0xc3, 0x7e, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xfe, 0xc3, 0xc3, 0xc3, 0xc3, 0xfe, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0},
{0x00, 0x00, 0x7e, 0xc3, 0xc0, 0xc0, 0xc0, 0xc3, 0x7e, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x7f, 0xc3, 0xc3, 0xc3, 0xc3, 0x7f, 0x03, 0x03, 0x03, 0x03, 0x03},
{0x00, 0x00, 0x7f, 0xc0, 0xc0, 0xfe, 0xc3, 0xc3, 0x7e, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x30, 0x30, 0x30, 0x30, 0x30, 0xfc, 0x30, 0x30, 0x30, 0x33, 0x1e},
{0x7e, 0xc3, 0x03, 0x03, 0x7f, 0xc3, 0xc3, 0xc3, 0x7e, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xfe, 0xc0, 0xc0, 0xc0, 0xc0},
{0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x18, 0x00},
{0x38, 0x6c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x00, 0x00, 0x0c, 0x00},
{0x00, 0x00, 0xc6, 0xcc, 0xf8, 0xf0, 0xd8, 0xcc, 0xc6, 0xc0, 0xc0, 0xc0, 0xc0},
{0x00, 0x00, 0x7e, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x78},
{0x00, 0x00, 0xdb, 0xdb, 0xdb, 0xdb, 0xdb, 0xdb, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xfc, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0xc0, 0xc0, 0xc0, 0xfe, 0xc3, 0xc3, 0xc3, 0xc3, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x03, 0x03, 0x03, 0x7f, 0xc3, 0xc3, 0xc3, 0xc3, 0x7f, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xe0, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xfe, 0x03, 0x03, 0x7e, 0xc0, 0xc0, 0x7f, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x1c, 0x36, 0x30, 0x30, 0x30, 0x30, 0xfc, 0x30, 0x30, 0x30, 0x00},
{0x00, 0x00, 0x7e, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x18, 0x3c, 0x3c, 0x66, 0x66, 0xc3, 0xc3, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xc3, 0xe7, 0xff, 0xdb, 0xc3, 0xc3, 0xc3, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xc3, 0x66, 0x3c, 0x18, 0x3c, 0x66, 0xc3, 0x00, 0x00, 0x00, 0x00},
{0xc0, 0x60, 0x60, 0x30, 0x18, 0x3c, 0x66, 0x66, 0xc3, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xff, 0x60, 0x30, 0x18, 0x0c, 0x06, 0xff, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x0f, 0x18, 0x18, 0x18, 0x38, 0xf0, 0x38, 0x18, 0x18, 0x18, 0x0f},
{0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18},
{0x00, 0x00, 0xf0, 0x18, 0x18, 0x18, 0x1c, 0x0f, 0x1c, 0x18, 0x18, 0x18, 0xf0},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x8f, 0xf1, 0x60, 0x00, 0x00, 0x00}};
static const char* s_vertexShaderSrc = "uniform vec2 charSize;\n"
"uniform vec2 offset;"
"in vec2 rawpos;\n"
"in vec2 rawtex0;\n"
"out vec2 uv0;\n"
"void main(void) {\n"
" gl_Position = vec4(rawpos + offset,0,1);\n"
" uv0 = rawtex0 * charSize;\n"
"}\n";
static const char* s_fragmentShaderSrc = "SAMPLER_BINDING(8) uniform sampler2D samp8;\n"
"uniform vec4 color;\n"
"in vec2 uv0;\n"
"out vec4 ocol0;\n"
"void main(void) {\n"
" ocol0 = texture(samp8,uv0) * color;\n"
"}\n";
static SHADER s_shader;
RasterFont::RasterFont()
{
// generate the texture
glGenTextures(1, &texture);
glActiveTexture(GL_TEXTURE8);
glBindTexture(GL_TEXTURE_2D, texture);
std::vector<u32> texture_data(CHARACTER_WIDTH * CHARACTER_COUNT * CHARACTER_HEIGHT);
for (int y = 0; y < CHARACTER_HEIGHT; y++)
{
for (int c = 0; c < CHARACTER_COUNT; c++)
{
for (int x = 0; x < CHARACTER_WIDTH; x++)
{
bool pixel = (0 != (rasters[c][y] & (1 << (CHARACTER_WIDTH - x - 1))));
texture_data[CHARACTER_WIDTH * CHARACTER_COUNT * y + CHARACTER_WIDTH * c + x] =
pixel ? -1 : 0;
}
}
}
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, CHARACTER_WIDTH * CHARACTER_COUNT, CHARACTER_HEIGHT, 0,
GL_RGBA, GL_UNSIGNED_BYTE, texture_data.data());
// generate shader
ProgramShaderCache::CompileShader(s_shader, s_vertexShaderSrc, s_fragmentShaderSrc);
s_shader.Bind();
// bound uniforms
glUniform2f(glGetUniformLocation(s_shader.glprogid, "charSize"), 1.0f / GLfloat(CHARACTER_COUNT),
1.0f);
uniform_color_id = glGetUniformLocation(s_shader.glprogid, "color");
glUniform4f(uniform_color_id, 1.0f, 1.0f, 1.0f, 1.0f);
uniform_offset_id = glGetUniformLocation(s_shader.glprogid, "offset");
glUniform2f(uniform_offset_id, 0.0f, 0.0f);
// generate VBO & VAO
glGenBuffers(1, &VBO);
glGenVertexArrays(1, &VAO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBindVertexArray(VAO);
glEnableVertexAttribArray(SHADER_POSITION_ATTRIB);
glVertexAttribPointer(SHADER_POSITION_ATTRIB, 2, GL_FLOAT, 0, sizeof(GLfloat) * 4, nullptr);
glEnableVertexAttribArray(SHADER_TEXTURE0_ATTRIB);
glVertexAttribPointer(SHADER_TEXTURE0_ATTRIB, 2, GL_FLOAT, 0, sizeof(GLfloat) * 4,
(GLfloat*)nullptr + 2);
glBindBuffer(GL_ARRAY_BUFFER,
static_cast<VertexManager*>(g_vertex_manager.get())->GetVertexBufferHandle());
ProgramShaderCache::InvalidateVertexFormat();
}
RasterFont::~RasterFont()
{
glDeleteTextures(1, &texture);
glDeleteBuffers(1, &VBO);
glDeleteVertexArrays(1, &VAO);
s_shader.Destroy();
}
void RasterFont::printMultilineText(const std::string& text, double start_x, double start_y,
double z, int bbWidth, int bbHeight, u32 color)
{
std::vector<GLfloat> vertices(text.length() * 6 * 4);
int usage = 0;
GLfloat delta_x = GLfloat(2 * CHARACTER_WIDTH) / GLfloat(bbWidth);
GLfloat delta_y = GLfloat(2 * CHARACTER_HEIGHT) / GLfloat(bbHeight);
GLfloat border_x = 2.0f / GLfloat(bbWidth);
GLfloat border_y = 4.0f / GLfloat(bbHeight);
GLfloat x = GLfloat(start_x);
GLfloat y = GLfloat(start_y);
for (const char& c : text)
{
if (c == '\n')
{
x = GLfloat(start_x);
y -= delta_y + border_y;
continue;
}
// do not print spaces, they can be skipped easily
if (c == ' ')
{
x += delta_x + border_x;
continue;
}
if (c < CHARACTER_OFFSET || c >= CHARACTER_COUNT + CHARACTER_OFFSET)
continue;
vertices[usage++] = x;
vertices[usage++] = y;
vertices[usage++] = GLfloat(c - CHARACTER_OFFSET);
vertices[usage++] = 0.0f;
vertices[usage++] = x + delta_x;
vertices[usage++] = y;
vertices[usage++] = GLfloat(c - CHARACTER_OFFSET + 1);
vertices[usage++] = 0.0f;
vertices[usage++] = x + delta_x;
vertices[usage++] = y + delta_y;
vertices[usage++] = GLfloat(c - CHARACTER_OFFSET + 1);
vertices[usage++] = 1.0f;
vertices[usage++] = x;
vertices[usage++] = y;
vertices[usage++] = GLfloat(c - CHARACTER_OFFSET);
vertices[usage++] = 0.0f;
vertices[usage++] = x + delta_x;
vertices[usage++] = y + delta_y;
vertices[usage++] = GLfloat(c - CHARACTER_OFFSET + 1);
vertices[usage++] = 1.0f;
vertices[usage++] = x;
vertices[usage++] = y + delta_y;
vertices[usage++] = GLfloat(c - CHARACTER_OFFSET);
vertices[usage++] = 1.0f;
x += delta_x + border_x;
}
if (!usage)
{
return;
}
glBindVertexArray(VAO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, usage * sizeof(GLfloat), vertices.data(), GL_STREAM_DRAW);
s_shader.Bind();
// shadows
glUniform2f(uniform_offset_id, 2.0f / GLfloat(bbWidth), -2.0f / GLfloat(bbHeight));
glUniform4f(uniform_color_id, 0.0f, 0.0f, 0.0f, GLfloat((color >> 24) & 0xff) / 255.f);
glDrawArrays(GL_TRIANGLES, 0, usage / 4);
glUniform2f(uniform_offset_id, 0.0f, 0.0f);
glUniform4f(uniform_color_id, GLfloat((color >> 16) & 0xff) / 255.f,
GLfloat((color >> 8) & 0xff) / 255.f, GLfloat((color >> 0) & 0xff) / 255.f,
GLfloat((color >> 24) & 0xff) / 255.f);
glDrawArrays(GL_TRIANGLES, 0, usage / 4);
glBindBuffer(GL_ARRAY_BUFFER,
static_cast<VertexManager*>(g_vertex_manager.get())->GetVertexBufferHandle());
ProgramShaderCache::InvalidateVertexFormat();
}
}

View File

@ -1,30 +0,0 @@
// Copyright 2008 Dolphin Emulator Project
// Licensed under GPLv2+
// Refer to the license.txt file included.
#pragma once
#include <string>
#include "Common/CommonTypes.h"
namespace OGL
{
class RasterFont
{
public:
RasterFont();
~RasterFont();
static int debug;
void printMultilineText(const std::string& text, double x, double y, double z, int bbWidth,
int bbHeight, u32 color);
private:
u32 VBO;
u32 VAO;
u32 texture;
u32 uniform_color_id;
u32 uniform_offset_id;
};
}

View File

@ -33,7 +33,6 @@
#include "VideoBackends/OGL/OGLTexture.h" #include "VideoBackends/OGL/OGLTexture.h"
#include "VideoBackends/OGL/PostProcessing.h" #include "VideoBackends/OGL/PostProcessing.h"
#include "VideoBackends/OGL/ProgramShaderCache.h" #include "VideoBackends/OGL/ProgramShaderCache.h"
#include "VideoBackends/OGL/RasterFont.h"
#include "VideoBackends/OGL/SamplerCache.h" #include "VideoBackends/OGL/SamplerCache.h"
#include "VideoBackends/OGL/StreamBuffer.h" #include "VideoBackends/OGL/StreamBuffer.h"
#include "VideoBackends/OGL/TextureCache.h" #include "VideoBackends/OGL/TextureCache.h"
@ -57,7 +56,6 @@ VideoConfig g_ogl_config;
// Declarations and definitions // Declarations and definitions
// ---------------------------- // ----------------------------
static std::unique_ptr<RasterFont> s_raster_font;
// 1 for no MSAA. Use s_MSAASamples > 1 to check for MSAA. // 1 for no MSAA. Use s_MSAASamples > 1 to check for MSAA.
static int s_MSAASamples = 1; static int s_MSAASamples = 1;
@ -827,8 +825,6 @@ bool Renderer::Initialize()
m_current_framebuffer_height = m_target_height; m_current_framebuffer_height = m_target_height;
m_post_processor = std::make_unique<OpenGLPostProcessing>(); m_post_processor = std::make_unique<OpenGLPostProcessing>();
s_raster_font = std::make_unique<RasterFont>();
return true; return true;
} }
@ -839,7 +835,6 @@ void Renderer::Shutdown()
UpdateActiveConfig(); UpdateActiveConfig();
s_raster_font.reset();
m_post_processor.reset(); m_post_processor.reset();
} }
@ -862,21 +857,6 @@ Renderer::CreateFramebuffer(const AbstractTexture* color_attachment,
static_cast<const OGLTexture*>(depth_attachment)); static_cast<const OGLTexture*>(depth_attachment));
} }
void Renderer::RenderText(const std::string& text, int left, int top, u32 color)
{
int screen_width = m_backbuffer_width;
int screen_height = m_backbuffer_height;
if (screen_width >= 2000)
{
screen_width /= 2;
screen_height /= 2;
}
s_raster_font->printMultilineText(text, left * 2.0f / static_cast<float>(screen_width) - 1.0f,
1.0f - top * 2.0f / static_cast<float>(screen_height), 0,
screen_width, screen_height, color);
}
std::unique_ptr<AbstractShader> Renderer::CreateShaderFromSource(ShaderStage stage, std::unique_ptr<AbstractShader> Renderer::CreateShaderFromSource(ShaderStage stage,
const char* source, size_t length) const char* source, size_t length)
{ {

View File

@ -119,8 +119,6 @@ public:
void Draw(u32 base_vertex, u32 num_vertices) override; void Draw(u32 base_vertex, u32 num_vertices) override;
void DrawIndexed(u32 base_index, u32 num_indices, u32 base_vertex) override; void DrawIndexed(u32 base_index, u32 num_indices, u32 base_vertex) override;
void RenderText(const std::string& text, int left, int top, u32 color) override;
u32 AccessEFB(EFBAccessType type, u32 x, u32 y, u32 poke_data) override; u32 AccessEFB(EFBAccessType type, u32 x, u32 y, u32 poke_data) override;
void PokeEFB(EFBAccessType type, const EfbPokeData* points, size_t num_points) override; void PokeEFB(EFBAccessType type, const EfbPokeData* points, size_t num_points) override;

View File

@ -84,11 +84,6 @@ bool SWOGLWindow::Initialize(const WindowSystemInfo& wsi)
return true; return true;
} }
void SWOGLWindow::PrintText(const std::string& text, int x, int y, u32 color)
{
m_text.push_back({text, x, y, color});
}
void SWOGLWindow::ShowImage(AbstractTexture* image, const EFBRectangle& xfb_region) void SWOGLWindow::ShowImage(AbstractTexture* image, const EFBRectangle& xfb_region)
{ {
SW::SWTexture* sw_image = static_cast<SW::SWTexture*>(image); SW::SWTexture* sw_image = static_cast<SW::SWTexture*>(image);
@ -116,11 +111,5 @@ void SWOGLWindow::ShowImage(AbstractTexture* image, const EFBRectangle& xfb_regi
glBindVertexArray(m_image_vao); glBindVertexArray(m_image_vao);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
// TODO: implement OSD
// for (TextData& text : m_text)
// {
// }
m_text.clear();
m_gl_context->Swap(); m_gl_context->Swap();
} }

View File

@ -24,9 +24,6 @@ public:
GLContext* GetContext() const { return m_gl_context.get(); } GLContext* GetContext() const { return m_gl_context.get(); }
bool IsHeadless() const; bool IsHeadless() const;
// Will be printed on the *next* image
void PrintText(const std::string& text, int x, int y, u32 color);
// Image to show, will be swapped immediately // Image to show, will be swapped immediately
void ShowImage(AbstractTexture* image, const EFBRectangle& xfb_region); void ShowImage(AbstractTexture* image, const EFBRectangle& xfb_region);
@ -37,14 +34,6 @@ private:
bool Initialize(const WindowSystemInfo& wsi); bool Initialize(const WindowSystemInfo& wsi);
struct TextData
{
std::string text;
int x, y;
u32 color;
};
std::vector<TextData> m_text;
u32 m_image_program = 0; u32 m_image_program = 0;
u32 m_image_texture = 0; u32 m_image_texture = 0;
u32 m_image_vao = 0; u32 m_image_vao = 0;

View File

@ -55,11 +55,6 @@ SWRenderer::CreateFramebuffer(const AbstractTexture* color_attachment,
static_cast<const SW::SWTexture*>(depth_attachment)); static_cast<const SW::SWTexture*>(depth_attachment));
} }
void SWRenderer::RenderText(const std::string& pstr, int left, int top, u32 color)
{
m_window->PrintText(pstr, left, top, color);
}
class SWShader final : public AbstractShader class SWShader final : public AbstractShader
{ {
public: public:

View File

@ -32,7 +32,6 @@ public:
size_t length) override; size_t length) override;
std::unique_ptr<AbstractPipeline> CreatePipeline(const AbstractPipelineConfig& config) override; std::unique_ptr<AbstractPipeline> CreatePipeline(const AbstractPipelineConfig& config) override;
void RenderText(const std::string& pstr, int left, int top, u32 color) override;
u32 AccessEFB(EFBAccessType type, u32 x, u32 y, u32 poke_data) override; u32 AccessEFB(EFBAccessType type, u32 x, u32 y, u32 poke_data) override;
void PokeEFB(EFBAccessType type, const EfbPokeData* points, size_t num_points) override {} void PokeEFB(EFBAccessType type, const EfbPokeData* points, size_t num_points) override {}
u16 BBoxRead(int index) override; u16 BBoxRead(int index) override;

View File

@ -5,7 +5,6 @@ add_library(videovulkan
ObjectCache.cpp ObjectCache.cpp
PerfQuery.cpp PerfQuery.cpp
PostProcessing.cpp PostProcessing.cpp
RasterFont.cpp
Renderer.cpp Renderer.cpp
ShaderCache.cpp ShaderCache.cpp
ShaderCompiler.cpp ShaderCompiler.cpp

View File

@ -28,9 +28,8 @@ VulkanPostProcessing::~VulkanPostProcessing()
vkDestroyShaderModule(g_vulkan_context->GetDevice(), m_fragment_shader, nullptr); vkDestroyShaderModule(g_vulkan_context->GetDevice(), m_fragment_shader, nullptr);
} }
bool VulkanPostProcessing::Initialize(const Texture2D* font_texture) bool VulkanPostProcessing::Initialize()
{ {
m_font_texture = font_texture;
if (!CompileDefaultShader()) if (!CompileDefaultShader())
return false; return false;
@ -63,7 +62,6 @@ void VulkanPostProcessing::BlitFromTexture(const TargetRectangle& dst, const Tar
u8* uniforms = draw.AllocatePSUniforms(uniforms_size); u8* uniforms = draw.AllocatePSUniforms(uniforms_size);
FillUniformBuffer(uniforms, src, src_tex, src_layer); FillUniformBuffer(uniforms, src, src_tex, src_layer);
draw.CommitPSUniforms(uniforms_size); draw.CommitPSUniforms(uniforms_size);
draw.SetPSSampler(1, m_font_texture->GetView(), g_object_cache->GetLinearSampler());
} }
draw.DrawQuad(dst.left, dst.top, dst.GetWidth(), dst.GetHeight(), src.left, src.top, src_layer, draw.DrawQuad(dst.left, dst.top, dst.GetWidth(), dst.GetHeight(), src.left, src.top, src_layer,
@ -174,11 +172,6 @@ constexpr char POSTPROCESSING_SHADER_HEADER[] = R"(
#define SampleOffset(offset) float4(textureOffset(samp0, uv0, offset).xyz, 1.0) #define SampleOffset(offset) float4(textureOffset(samp0, uv0, offset).xyz, 1.0)
float4 SampleFontLocation(float2 location)
{
return texture(samp1, float3(location, 0.0));
}
float2 GetResolution() float2 GetResolution()
{ {
return options.resolution.xy; return options.resolution.xy;

View File

@ -21,7 +21,7 @@ public:
VulkanPostProcessing() = default; VulkanPostProcessing() = default;
~VulkanPostProcessing(); ~VulkanPostProcessing();
bool Initialize(const Texture2D* font_texture); bool Initialize();
void BlitFromTexture(const TargetRectangle& dst, const TargetRectangle& src, void BlitFromTexture(const TargetRectangle& dst, const TargetRectangle& src,
const Texture2D* src_tex, int src_layer, VkRenderPass render_pass); const Texture2D* src_tex, int src_layer, VkRenderPass render_pass);
@ -37,7 +37,6 @@ private:
bool RecompileShader(); bool RecompileShader();
std::string GetGLSLUniformBlock() const; std::string GetGLSLUniformBlock() const;
const Texture2D* m_font_texture = nullptr;
VkShaderModule m_fragment_shader = VK_NULL_HANDLE; VkShaderModule m_fragment_shader = VK_NULL_HANDLE;
VkShaderModule m_default_fragment_shader = VK_NULL_HANDLE; VkShaderModule m_default_fragment_shader = VK_NULL_HANDLE;
}; };

View File

@ -1,421 +0,0 @@
// Copyright 2016 Dolphin Emulator Project
// Licensed under GPLv2+
// Refer to the license.txt file included.
#include "VideoBackends/Vulkan/RasterFont.h"
#include <cstring>
#include <vector>
#include "VideoBackends/Vulkan/CommandBufferManager.h"
#include "VideoBackends/Vulkan/Texture2D.h"
#include "VideoBackends/Vulkan/Util.h"
#include "VideoBackends/Vulkan/VulkanContext.h"
// Based on OGL RasterFont
// TODO: We should move this to common.
namespace Vulkan
{
constexpr int CHARACTER_WIDTH = 8;
constexpr int CHARACTER_HEIGHT = 13;
constexpr int CHARACTER_OFFSET = 32;
constexpr int CHARACTER_COUNT = 95;
static const u8 rasters[CHARACTER_COUNT][CHARACTER_HEIGHT] = {
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x36, 0x36, 0x36},
{0x00, 0x00, 0x00, 0x66, 0x66, 0xff, 0x66, 0x66, 0xff, 0x66, 0x66, 0x00, 0x00},
{0x00, 0x00, 0x18, 0x7e, 0xff, 0x1b, 0x1f, 0x7e, 0xf8, 0xd8, 0xff, 0x7e, 0x18},
{0x00, 0x00, 0x0e, 0x1b, 0xdb, 0x6e, 0x30, 0x18, 0x0c, 0x76, 0xdb, 0xd8, 0x70},
{0x00, 0x00, 0x7f, 0xc6, 0xcf, 0xd8, 0x70, 0x70, 0xd8, 0xcc, 0xcc, 0x6c, 0x38},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x1c, 0x0c, 0x0e},
{0x00, 0x00, 0x0c, 0x18, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x18, 0x0c},
{0x00, 0x00, 0x30, 0x18, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x18, 0x30},
{0x00, 0x00, 0x00, 0x00, 0x99, 0x5a, 0x3c, 0xff, 0x3c, 0x5a, 0x99, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0xff, 0xff, 0x18, 0x18, 0x18, 0x00, 0x00},
{0x00, 0x00, 0x30, 0x18, 0x1c, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x38, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x60, 0x60, 0x30, 0x30, 0x18, 0x18, 0x0c, 0x0c, 0x06, 0x06, 0x03, 0x03},
{0x00, 0x00, 0x3c, 0x66, 0xc3, 0xe3, 0xf3, 0xdb, 0xcf, 0xc7, 0xc3, 0x66, 0x3c},
{0x00, 0x00, 0x7e, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x78, 0x38, 0x18},
{0x00, 0x00, 0xff, 0xc0, 0xc0, 0x60, 0x30, 0x18, 0x0c, 0x06, 0x03, 0xe7, 0x7e},
{0x00, 0x00, 0x7e, 0xe7, 0x03, 0x03, 0x07, 0x7e, 0x07, 0x03, 0x03, 0xe7, 0x7e},
{0x00, 0x00, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0xff, 0xcc, 0x6c, 0x3c, 0x1c, 0x0c},
{0x00, 0x00, 0x7e, 0xe7, 0x03, 0x03, 0x07, 0xfe, 0xc0, 0xc0, 0xc0, 0xc0, 0xff},
{0x00, 0x00, 0x7e, 0xe7, 0xc3, 0xc3, 0xc7, 0xfe, 0xc0, 0xc0, 0xc0, 0xe7, 0x7e},
{0x00, 0x00, 0x30, 0x30, 0x30, 0x30, 0x18, 0x0c, 0x06, 0x03, 0x03, 0x03, 0xff},
{0x00, 0x00, 0x7e, 0xe7, 0xc3, 0xc3, 0xe7, 0x7e, 0xe7, 0xc3, 0xc3, 0xe7, 0x7e},
{0x00, 0x00, 0x7e, 0xe7, 0x03, 0x03, 0x03, 0x7f, 0xe7, 0xc3, 0xc3, 0xe7, 0x7e},
{0x00, 0x00, 0x00, 0x38, 0x38, 0x00, 0x00, 0x38, 0x38, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x30, 0x18, 0x1c, 0x1c, 0x00, 0x00, 0x1c, 0x1c, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0, 0x60, 0x30, 0x18, 0x0c, 0x06},
{0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x60, 0x30, 0x18, 0x0c, 0x06, 0x03, 0x06, 0x0c, 0x18, 0x30, 0x60},
{0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x18, 0x0c, 0x06, 0x03, 0xc3, 0xc3, 0x7e},
{0x00, 0x00, 0x3f, 0x60, 0xcf, 0xdb, 0xd3, 0xdd, 0xc3, 0x7e, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xc3, 0xc3, 0xc3, 0xc3, 0xff, 0xc3, 0xc3, 0xc3, 0x66, 0x3c, 0x18},
{0x00, 0x00, 0xfe, 0xc7, 0xc3, 0xc3, 0xc7, 0xfe, 0xc7, 0xc3, 0xc3, 0xc7, 0xfe},
{0x00, 0x00, 0x7e, 0xe7, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xe7, 0x7e},
{0x00, 0x00, 0xfc, 0xce, 0xc7, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc7, 0xce, 0xfc},
{0x00, 0x00, 0xff, 0xc0, 0xc0, 0xc0, 0xc0, 0xfc, 0xc0, 0xc0, 0xc0, 0xc0, 0xff},
{0x00, 0x00, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xfc, 0xc0, 0xc0, 0xc0, 0xff},
{0x00, 0x00, 0x7e, 0xe7, 0xc3, 0xc3, 0xcf, 0xc0, 0xc0, 0xc0, 0xc0, 0xe7, 0x7e},
{0x00, 0x00, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xff, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3},
{0x00, 0x00, 0x7e, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x7e},
{0x00, 0x00, 0x7c, 0xee, 0xc6, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06},
{0x00, 0x00, 0xc3, 0xc6, 0xcc, 0xd8, 0xf0, 0xe0, 0xf0, 0xd8, 0xcc, 0xc6, 0xc3},
{0x00, 0x00, 0xff, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0},
{0x00, 0x00, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xdb, 0xff, 0xff, 0xe7, 0xc3},
{0x00, 0x00, 0xc7, 0xc7, 0xcf, 0xcf, 0xdf, 0xdb, 0xfb, 0xf3, 0xf3, 0xe3, 0xe3},
{0x00, 0x00, 0x7e, 0xe7, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xe7, 0x7e},
{0x00, 0x00, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xfe, 0xc7, 0xc3, 0xc3, 0xc7, 0xfe},
{0x00, 0x00, 0x3f, 0x6e, 0xdf, 0xdb, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0x66, 0x3c},
{0x00, 0x00, 0xc3, 0xc6, 0xcc, 0xd8, 0xf0, 0xfe, 0xc7, 0xc3, 0xc3, 0xc7, 0xfe},
{0x00, 0x00, 0x7e, 0xe7, 0x03, 0x03, 0x07, 0x7e, 0xe0, 0xc0, 0xc0, 0xe7, 0x7e},
{0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xff},
{0x00, 0x00, 0x7e, 0xe7, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3},
{0x00, 0x00, 0x18, 0x3c, 0x3c, 0x66, 0x66, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3},
{0x00, 0x00, 0xc3, 0xe7, 0xff, 0xff, 0xdb, 0xdb, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3},
{0x00, 0x00, 0xc3, 0x66, 0x66, 0x3c, 0x3c, 0x18, 0x3c, 0x3c, 0x66, 0x66, 0xc3},
{0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x3c, 0x66, 0x66, 0xc3},
{0x00, 0x00, 0xff, 0xc0, 0xc0, 0x60, 0x30, 0x7e, 0x0c, 0x06, 0x03, 0x03, 0xff},
{0x00, 0x00, 0x3c, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x3c},
{0x00, 0x03, 0x03, 0x06, 0x06, 0x0c, 0x0c, 0x18, 0x18, 0x30, 0x30, 0x60, 0x60},
{0x00, 0x00, 0x3c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x3c},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0x66, 0x3c, 0x18},
{0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x38, 0x30, 0x70},
{0x00, 0x00, 0x7f, 0xc3, 0xc3, 0x7f, 0x03, 0xc3, 0x7e, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xfe, 0xc3, 0xc3, 0xc3, 0xc3, 0xfe, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0},
{0x00, 0x00, 0x7e, 0xc3, 0xc0, 0xc0, 0xc0, 0xc3, 0x7e, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x7f, 0xc3, 0xc3, 0xc3, 0xc3, 0x7f, 0x03, 0x03, 0x03, 0x03, 0x03},
{0x00, 0x00, 0x7f, 0xc0, 0xc0, 0xfe, 0xc3, 0xc3, 0x7e, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x30, 0x30, 0x30, 0x30, 0x30, 0xfc, 0x30, 0x30, 0x30, 0x33, 0x1e},
{0x7e, 0xc3, 0x03, 0x03, 0x7f, 0xc3, 0xc3, 0xc3, 0x7e, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xfe, 0xc0, 0xc0, 0xc0, 0xc0},
{0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x18, 0x00},
{0x38, 0x6c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x00, 0x00, 0x0c, 0x00},
{0x00, 0x00, 0xc6, 0xcc, 0xf8, 0xf0, 0xd8, 0xcc, 0xc6, 0xc0, 0xc0, 0xc0, 0xc0},
{0x00, 0x00, 0x7e, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x78},
{0x00, 0x00, 0xdb, 0xdb, 0xdb, 0xdb, 0xdb, 0xdb, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xfc, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0xc0, 0xc0, 0xc0, 0xfe, 0xc3, 0xc3, 0xc3, 0xc3, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x03, 0x03, 0x03, 0x7f, 0xc3, 0xc3, 0xc3, 0xc3, 0x7f, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xe0, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xfe, 0x03, 0x03, 0x7e, 0xc0, 0xc0, 0x7f, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x1c, 0x36, 0x30, 0x30, 0x30, 0x30, 0xfc, 0x30, 0x30, 0x30, 0x00},
{0x00, 0x00, 0x7e, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x18, 0x3c, 0x3c, 0x66, 0x66, 0xc3, 0xc3, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xc3, 0xe7, 0xff, 0xdb, 0xc3, 0xc3, 0xc3, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xc3, 0x66, 0x3c, 0x18, 0x3c, 0x66, 0xc3, 0x00, 0x00, 0x00, 0x00},
{0xc0, 0x60, 0x60, 0x30, 0x18, 0x3c, 0x66, 0x66, 0xc3, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xff, 0x60, 0x30, 0x18, 0x0c, 0x06, 0xff, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x0f, 0x18, 0x18, 0x18, 0x38, 0xf0, 0x38, 0x18, 0x18, 0x18, 0x0f},
{0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18},
{0x00, 0x00, 0xf0, 0x18, 0x18, 0x18, 0x1c, 0x0f, 0x1c, 0x18, 0x18, 0x18, 0xf0},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x8f, 0xf1, 0x60, 0x00, 0x00, 0x00}};
static const char VERTEX_SHADER_SOURCE[] = R"(
layout(std140, push_constant) uniform PCBlock {
vec2 char_size;
vec2 offset;
vec4 color;
} PC;
layout(location = 0) in vec4 ipos;
layout(location = 5) in vec4 icol0;
layout(location = 8) in vec3 itex0;
layout(location = 0) out vec2 uv0;
void main()
{
gl_Position = vec4(ipos.xy + PC.offset, 0.0f, 1.0f);
gl_Position.y = -gl_Position.y;
uv0 = itex0.xy * PC.char_size;
}
)";
static const char FRAGMENT_SHADER_SOURCE[] = R"(
layout(std140, push_constant) uniform PCBlock {
vec2 char_size;
vec2 offset;
vec4 color;
} PC;
layout(set = 1, binding = 0) uniform sampler2DArray samp0;
layout(location = 0) in vec2 uv0;
layout(location = 0) out vec4 ocol0;
void main()
{
ocol0 = texture(samp0, float3(uv0, 0.0)) * PC.color;
}
)";
RasterFont::RasterFont()
{
}
RasterFont::~RasterFont()
{
if (m_vertex_shader != VK_NULL_HANDLE)
vkDestroyShaderModule(g_vulkan_context->GetDevice(), m_vertex_shader, nullptr);
if (m_fragment_shader != VK_NULL_HANDLE)
vkDestroyShaderModule(g_vulkan_context->GetDevice(), m_fragment_shader, nullptr);
}
const Texture2D* RasterFont::GetTexture() const
{
return m_texture.get();
}
bool RasterFont::Initialize()
{
// Create shaders and texture
if (!CreateShaders() || !CreateTexture())
return false;
return true;
}
bool RasterFont::CreateTexture()
{
// generate the texture
std::vector<u32> texture_data(CHARACTER_WIDTH * CHARACTER_COUNT * CHARACTER_HEIGHT);
for (int y = 0; y < CHARACTER_HEIGHT; y++)
{
for (int c = 0; c < CHARACTER_COUNT; c++)
{
for (int x = 0; x < CHARACTER_WIDTH; x++)
{
bool pixel = (0 != (rasters[c][y] & (1 << (CHARACTER_WIDTH - x - 1))));
texture_data[CHARACTER_WIDTH * CHARACTER_COUNT * y + CHARACTER_WIDTH * c + x] =
pixel ? -1 : 0;
}
}
}
// create the actual texture object
m_texture = Texture2D::Create(CHARACTER_WIDTH * CHARACTER_COUNT, CHARACTER_HEIGHT, 1, 1,
VK_FORMAT_R8G8B8A8_UNORM, VK_SAMPLE_COUNT_1_BIT,
VK_IMAGE_VIEW_TYPE_2D_ARRAY, VK_IMAGE_TILING_OPTIMAL,
VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT);
if (!m_texture)
return false;
// create temporary buffer for uploading texture
VkBufferCreateInfo buffer_info = {VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
nullptr,
0,
static_cast<VkDeviceSize>(texture_data.size() * sizeof(u32)),
VK_BUFFER_USAGE_TRANSFER_SRC_BIT,
VK_SHARING_MODE_EXCLUSIVE,
0,
nullptr};
VkBuffer temp_buffer;
VkResult res = vkCreateBuffer(g_vulkan_context->GetDevice(), &buffer_info, nullptr, &temp_buffer);
if (res != VK_SUCCESS)
{
LOG_VULKAN_ERROR(res, "vkCreateBuffer failed: ");
return false;
}
VkMemoryRequirements memory_requirements;
vkGetBufferMemoryRequirements(g_vulkan_context->GetDevice(), temp_buffer, &memory_requirements);
uint32_t memory_type_index = g_vulkan_context->GetMemoryType(memory_requirements.memoryTypeBits,
VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT);
VkMemoryAllocateInfo memory_allocate_info = {VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO, nullptr,
memory_requirements.size, memory_type_index};
VkDeviceMemory temp_buffer_memory;
res = vkAllocateMemory(g_vulkan_context->GetDevice(), &memory_allocate_info, nullptr,
&temp_buffer_memory);
if (res != VK_SUCCESS)
{
LOG_VULKAN_ERROR(res, "vkAllocateMemory failed: ");
vkDestroyBuffer(g_vulkan_context->GetDevice(), temp_buffer, nullptr);
return false;
}
// Bind buffer to memory
res = vkBindBufferMemory(g_vulkan_context->GetDevice(), temp_buffer, temp_buffer_memory, 0);
if (res != VK_SUCCESS)
{
LOG_VULKAN_ERROR(res, "vkBindBufferMemory failed: ");
vkDestroyBuffer(g_vulkan_context->GetDevice(), temp_buffer, nullptr);
vkFreeMemory(g_vulkan_context->GetDevice(), temp_buffer_memory, nullptr);
return false;
}
// Copy into buffer
void* mapped_ptr;
res = vkMapMemory(g_vulkan_context->GetDevice(), temp_buffer_memory, 0, buffer_info.size, 0,
&mapped_ptr);
if (res != VK_SUCCESS)
{
LOG_VULKAN_ERROR(res, "vkMapMemory failed: ");
vkDestroyBuffer(g_vulkan_context->GetDevice(), temp_buffer, nullptr);
vkFreeMemory(g_vulkan_context->GetDevice(), temp_buffer_memory, nullptr);
return false;
}
// Copy texture data into staging buffer
memcpy(mapped_ptr, texture_data.data(), texture_data.size() * sizeof(u32));
vkUnmapMemory(g_vulkan_context->GetDevice(), temp_buffer_memory);
// Copy from staging buffer to the final texture
VkBufferImageCopy region = {0,
CHARACTER_WIDTH * CHARACTER_COUNT,
CHARACTER_HEIGHT,
{VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1},
{0, 0, 0},
{CHARACTER_WIDTH * CHARACTER_COUNT, CHARACTER_HEIGHT, 1}};
m_texture->TransitionToLayout(g_command_buffer_mgr->GetCurrentInitCommandBuffer(),
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
vkCmdCopyBufferToImage(g_command_buffer_mgr->GetCurrentInitCommandBuffer(), temp_buffer,
m_texture->GetImage(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &region);
// Free temp buffers after command buffer executes
m_texture->TransitionToLayout(g_command_buffer_mgr->GetCurrentInitCommandBuffer(),
VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
g_command_buffer_mgr->DeferBufferDestruction(temp_buffer);
g_command_buffer_mgr->DeferDeviceMemoryDestruction(temp_buffer_memory);
return true;
}
bool RasterFont::CreateShaders()
{
m_vertex_shader = Util::CompileAndCreateVertexShader(VERTEX_SHADER_SOURCE);
m_fragment_shader = Util::CompileAndCreateFragmentShader(FRAGMENT_SHADER_SOURCE);
return m_vertex_shader != VK_NULL_HANDLE && m_fragment_shader != VK_NULL_HANDLE;
}
void RasterFont::PrintMultiLineText(VkRenderPass render_pass, const std::string& text,
float start_x, float start_y, u32 bbWidth, u32 bbHeight,
u32 color)
{
// skip empty strings
if (text.empty())
return;
UtilityShaderDraw draw(g_command_buffer_mgr->GetCurrentCommandBuffer(),
g_object_cache->GetPipelineLayout(PIPELINE_LAYOUT_PUSH_CONSTANT),
render_pass, m_vertex_shader, VK_NULL_HANDLE, m_fragment_shader,
PrimitiveType::Triangles);
UtilityShaderVertex* vertices = draw.ReserveVertices(text.length() * 6);
size_t num_vertices = 0;
if (!vertices)
return;
float delta_x = float(2 * CHARACTER_WIDTH) / float(bbWidth);
float delta_y = float(2 * CHARACTER_HEIGHT) / float(bbHeight);
float border_x = 2.0f / float(bbWidth);
float border_y = 4.0f / float(bbHeight);
float x = float(start_x);
float y = float(start_y);
for (const char& c : text)
{
if (c == '\n')
{
x = float(start_x);
y -= delta_y + border_y;
continue;
}
// do not print spaces, they can be skipped easily
if (c == ' ')
{
x += delta_x + border_x;
continue;
}
if (c < CHARACTER_OFFSET || c >= CHARACTER_COUNT + CHARACTER_OFFSET)
continue;
vertices[num_vertices].SetPosition(x, y);
vertices[num_vertices].SetTextureCoordinates(static_cast<float>(c - CHARACTER_OFFSET), 0.0f);
num_vertices++;
vertices[num_vertices].SetPosition(x + delta_x, y);
vertices[num_vertices].SetTextureCoordinates(static_cast<float>(c - CHARACTER_OFFSET + 1),
0.0f);
num_vertices++;
vertices[num_vertices].SetPosition(x + delta_x, y + delta_y);
vertices[num_vertices].SetTextureCoordinates(static_cast<float>(c - CHARACTER_OFFSET + 1),
1.0f);
num_vertices++;
vertices[num_vertices].SetPosition(x, y);
vertices[num_vertices].SetTextureCoordinates(static_cast<float>(c - CHARACTER_OFFSET), 0.0f);
num_vertices++;
vertices[num_vertices].SetPosition(x + delta_x, y + delta_y);
vertices[num_vertices].SetTextureCoordinates(static_cast<float>(c - CHARACTER_OFFSET + 1),
1.0f);
num_vertices++;
vertices[num_vertices].SetPosition(x, y + delta_y);
vertices[num_vertices].SetTextureCoordinates(static_cast<float>(c - CHARACTER_OFFSET), 1.0f);
num_vertices++;
x += delta_x + border_x;
}
// skip all whitespace strings
if (num_vertices == 0)
return;
draw.CommitVertices(num_vertices);
struct PCBlock
{
float char_size[2];
float offset[2];
float color[4];
} pc_block = {};
pc_block.char_size[0] = 1.0f / static_cast<float>(CHARACTER_COUNT);
pc_block.char_size[1] = 1.0f;
// shadows
pc_block.offset[0] = 2.0f / bbWidth;
pc_block.offset[1] = -2.0f / bbHeight;
pc_block.color[3] = (color >> 24) / 255.0f;
draw.SetPushConstants(&pc_block, sizeof(pc_block));
draw.SetPSSampler(0, m_texture->GetView(), g_object_cache->GetLinearSampler());
// Setup alpha blending
BlendingState blend_state = RenderState::GetNoBlendingBlendState();
blend_state.blendenable = true;
blend_state.srcfactor = BlendMode::SRCALPHA;
blend_state.dstfactor = BlendMode::INVSRCALPHA;
draw.SetBlendState(blend_state);
draw.Draw();
// non-shadowed part
pc_block.offset[0] = 0.0f;
pc_block.offset[1] = 0.0f;
pc_block.color[0] = ((color >> 16) & 0xFF) / 255.0f;
pc_block.color[1] = ((color >> 8) & 0xFF) / 255.0f;
pc_block.color[2] = (color & 0xFF) / 255.0f;
draw.SetPushConstants(&pc_block, sizeof(pc_block));
draw.Draw();
}
} // namespace Vulkan

View File

@ -1,41 +0,0 @@
// Copyright 2016 Dolphin Emulator Project
// Licensed under GPLv2+
// Refer to the license.txt file included.
#pragma once
#include <memory>
#include <string>
#include "Common/CommonTypes.h"
#include "VideoBackends/Vulkan/Constants.h"
namespace Vulkan
{
class Texture2D;
class RasterFont
{
public:
RasterFont();
~RasterFont();
const Texture2D* GetTexture() const;
bool Initialize();
void PrintMultiLineText(VkRenderPass render_pass, const std::string& text, float start_x,
float start_y, u32 bbWidth, u32 bbHeight, u32 color);
private:
bool CreateTexture();
bool CreateShaders();
std::unique_ptr<Texture2D> m_texture;
VkShaderModule m_vertex_shader = VK_NULL_HANDLE;
VkShaderModule m_fragment_shader = VK_NULL_HANDLE;
};
} // namespace Vulkan

View File

@ -21,7 +21,6 @@
#include "VideoBackends/Vulkan/FramebufferManager.h" #include "VideoBackends/Vulkan/FramebufferManager.h"
#include "VideoBackends/Vulkan/ObjectCache.h" #include "VideoBackends/Vulkan/ObjectCache.h"
#include "VideoBackends/Vulkan/PostProcessing.h" #include "VideoBackends/Vulkan/PostProcessing.h"
#include "VideoBackends/Vulkan/RasterFont.h"
#include "VideoBackends/Vulkan/Renderer.h" #include "VideoBackends/Vulkan/Renderer.h"
#include "VideoBackends/Vulkan/StateTracker.h" #include "VideoBackends/Vulkan/StateTracker.h"
#include "VideoBackends/Vulkan/StreamBuffer.h" #include "VideoBackends/Vulkan/StreamBuffer.h"
@ -89,13 +88,6 @@ bool Renderer::Initialize()
return false; return false;
} }
m_raster_font = std::make_unique<RasterFont>();
if (!m_raster_font->Initialize())
{
PanicAlert("Failed to initialize raster font.");
return false;
}
// Swap chain render pass. // Swap chain render pass.
if (m_swap_chain) if (m_swap_chain)
{ {
@ -130,8 +122,7 @@ bool Renderer::Initialize()
// Initialize post processing. // Initialize post processing.
m_post_processor = std::make_unique<VulkanPostProcessing>(); m_post_processor = std::make_unique<VulkanPostProcessing>();
if (!static_cast<VulkanPostProcessing*>(m_post_processor.get()) if (!static_cast<VulkanPostProcessing*>(m_post_processor.get())->Initialize())
->Initialize(m_raster_font->GetTexture()))
{ {
PanicAlert("failed to initialize post processor."); PanicAlert("failed to initialize post processor.");
return false; return false;
@ -259,17 +250,6 @@ void Renderer::SetPipeline(const AbstractPipeline* pipeline)
StateTracker::GetInstance()->SetPipeline(static_cast<const VKPipeline*>(pipeline)); StateTracker::GetInstance()->SetPipeline(static_cast<const VKPipeline*>(pipeline));
} }
void Renderer::RenderText(const std::string& text, int left, int top, u32 color)
{
u32 backbuffer_width = m_swap_chain->GetWidth();
u32 backbuffer_height = m_swap_chain->GetHeight();
m_raster_font->PrintMultiLineText(m_swap_chain_render_pass, text,
left * 2.0f / static_cast<float>(backbuffer_width) - 1,
1 - top * 2.0f / static_cast<float>(backbuffer_height),
backbuffer_width, backbuffer_height, color);
}
u32 Renderer::AccessEFB(EFBAccessType type, u32 x, u32 y, u32 poke_data) u32 Renderer::AccessEFB(EFBAccessType type, u32 x, u32 y, u32 poke_data)
{ {
if (type == EFBAccessType::PeekColor) if (type == EFBAccessType::PeekColor)

View File

@ -22,7 +22,6 @@ class FramebufferManager;
class SwapChain; class SwapChain;
class StagingTexture2D; class StagingTexture2D;
class Texture2D; class Texture2D;
class RasterFont;
class VKFramebuffer; class VKFramebuffer;
class VKPipeline; class VKPipeline;
class VKTexture; class VKTexture;
@ -55,7 +54,6 @@ public:
SwapChain* GetSwapChain() const { return m_swap_chain.get(); } SwapChain* GetSwapChain() const { return m_swap_chain.get(); }
BoundingBox* GetBoundingBox() const { return m_bounding_box.get(); } BoundingBox* GetBoundingBox() const { return m_bounding_box.get(); }
void RenderText(const std::string& pstr, int left, int top, u32 color) override;
u32 AccessEFB(EFBAccessType type, u32 x, u32 y, u32 poke_data) override; u32 AccessEFB(EFBAccessType type, u32 x, u32 y, u32 poke_data) override;
void PokeEFB(EFBAccessType type, const EfbPokeData* points, size_t num_points) override; void PokeEFB(EFBAccessType type, const EfbPokeData* points, size_t num_points) override;
u16 BBoxRead(int index) override; u16 BBoxRead(int index) override;
@ -128,7 +126,6 @@ private:
std::unique_ptr<SwapChain> m_swap_chain; std::unique_ptr<SwapChain> m_swap_chain;
std::unique_ptr<BoundingBox> m_bounding_box; std::unique_ptr<BoundingBox> m_bounding_box;
std::unique_ptr<RasterFont> m_raster_font;
// Keep a copy of sampler states to avoid cache lookups every draw // Keep a copy of sampler states to avoid cache lookups every draw
std::array<SamplerState, NUM_PIXEL_SHADER_SAMPLERS> m_sampler_states = {}; std::array<SamplerState, NUM_PIXEL_SHADER_SAMPLERS> m_sampler_states = {};

View File

@ -44,7 +44,6 @@
<ClCompile Include="ShaderCache.cpp" /> <ClCompile Include="ShaderCache.cpp" />
<ClCompile Include="TextureConverter.cpp" /> <ClCompile Include="TextureConverter.cpp" />
<ClCompile Include="PerfQuery.cpp" /> <ClCompile Include="PerfQuery.cpp" />
<ClCompile Include="RasterFont.cpp" />
<ClCompile Include="StagingBuffer.cpp" /> <ClCompile Include="StagingBuffer.cpp" />
<ClCompile Include="Util.cpp" /> <ClCompile Include="Util.cpp" />
<ClCompile Include="VertexFormat.cpp" /> <ClCompile Include="VertexFormat.cpp" />
@ -71,7 +70,6 @@
<ClInclude Include="PostProcessing.h" /> <ClInclude Include="PostProcessing.h" />
<ClInclude Include="ShaderCache.h" /> <ClInclude Include="ShaderCache.h" />
<ClInclude Include="TextureConverter.h" /> <ClInclude Include="TextureConverter.h" />
<ClInclude Include="RasterFont.h" />
<ClInclude Include="StagingBuffer.h" /> <ClInclude Include="StagingBuffer.h" />
<ClInclude Include="Util.h" /> <ClInclude Include="Util.h" />
<ClInclude Include="VertexFormat.h" /> <ClInclude Include="VertexFormat.h" />

View File

@ -65,6 +65,7 @@ PUBLIC
PRIVATE PRIVATE
png png
xxhash xxhash
imgui
) )
if(_M_X86) if(_M_X86)

View File

@ -159,8 +159,6 @@ public:
// ImGui initialization depends on being able to create textures and pipelines, so do it last. // ImGui initialization depends on being able to create textures and pipelines, so do it last.
bool InitializeImGui(); bool InitializeImGui();
virtual void RenderText(const std::string& text, int left, int top, u32 color) = 0;
virtual void ClearScreen(const EFBRectangle& rc, bool colorEnable, bool alphaEnable, bool zEnable, virtual void ClearScreen(const EFBRectangle& rc, bool colorEnable, bool alphaEnable, bool zEnable,
u32 color, u32 z) = 0; u32 color, u32 z) = 0;
virtual void ReinterpretPixelData(unsigned int convtype) = 0; virtual void ReinterpretPixelData(unsigned int convtype) = 0;