mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-07-24 14:49:42 -06:00
Remove old RasterFont classes
This commit is contained in:
@ -98,390 +98,7 @@ private:
|
||||
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;
|
||||
|
||||
#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* point_copy_sampler = nullptr;
|
||||
|
||||
@ -560,13 +177,10 @@ void InitUtils()
|
||||
util_vbuf->AddWrapObserver(&stq_observer);
|
||||
util_vbuf->AddWrapObserver(&cq_observer);
|
||||
util_vbuf->AddWrapObserver(&clearq_observer);
|
||||
|
||||
font.Init();
|
||||
}
|
||||
|
||||
void ShutdownUtils()
|
||||
{
|
||||
font.Shutdown();
|
||||
SAFE_RELEASE(point_copy_sampler);
|
||||
SAFE_RELEASE(linear_copy_sampler);
|
||||
SAFE_DELETE(util_vbuf);
|
||||
@ -788,10 +402,6 @@ void DrawEFBPokeQuads(EFBAccessType type, const EfbPokeData* points, size_t num_
|
||||
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 DX11
|
||||
|
@ -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 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);
|
||||
}
|
||||
}
|
||||
|
@ -237,13 +237,6 @@ Renderer::CreateFramebuffer(const AbstractTexture* color_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,
|
||||
const char* source, size_t length)
|
||||
{
|
||||
|
@ -55,8 +55,6 @@ public:
|
||||
void SetFullscreen(bool enable_fullscreen) 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;
|
||||
void PokeEFB(EFBAccessType type, const EfbPokeData* points, size_t num_points) override;
|
||||
|
||||
|
Reference in New Issue
Block a user