You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
383 lines
11 KiB
383 lines
11 KiB
4 years ago
|
#include "no_gui.h"
|
||
|
|
||
|
bool no_gui::init(IDXGISwapChain* swapchain)
|
||
|
{
|
||
|
HRESULT hr;
|
||
|
m_swap_chain = swapchain;
|
||
|
if (!m_swap_chain)
|
||
|
return false;
|
||
|
|
||
|
m_swap_chain->GetDevice(__uuidof(m_device), (void**)&m_device);
|
||
|
m_device->GetImmediateContext(&m_device_context);
|
||
|
hr = m_device->CreateVertexShader(vs_blob, sizeof(vs_blob), NULL, &m_vertex_shader);
|
||
|
|
||
|
D3D11_INPUT_ELEMENT_DESC layout[] =
|
||
|
{
|
||
|
{ "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 }
|
||
|
};
|
||
|
|
||
|
hr = m_device->CreateInputLayout(layout, ARRAYSIZE(layout), vs_blob, sizeof(vs_blob), &m_input_layout);
|
||
|
hr = m_device->CreatePixelShader(ps_blob, sizeof(ps_blob), NULL, &m_pixel_shader);
|
||
|
|
||
|
D3D11_BUFFER_DESC buffer_desc;
|
||
|
|
||
|
buffer_desc.Usage = D3D11_USAGE_DYNAMIC;
|
||
|
buffer_desc.ByteWidth = 4 * sizeof(COLOR_VERTEX);
|
||
|
buffer_desc.BindFlags = D3D11_BIND_VERTEX_BUFFER;
|
||
|
buffer_desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
|
||
|
buffer_desc.MiscFlags = 0;
|
||
|
|
||
|
hr = m_device->CreateBuffer(&buffer_desc, NULL, &m_pvertex_buffer);
|
||
|
if (FAILED(hr))
|
||
|
return false;
|
||
|
|
||
|
D3D11_BLEND_DESC blend_state_desc;
|
||
|
ZeroMemory(&blend_state_desc, sizeof(blend_state_desc));
|
||
|
blend_state_desc.AlphaToCoverageEnable = false;
|
||
|
blend_state_desc.RenderTarget[0].BlendEnable = true;
|
||
|
blend_state_desc.RenderTarget[0].SrcBlend = D3D11_BLEND_SRC_ALPHA;
|
||
|
blend_state_desc.RenderTarget[0].DestBlend = D3D11_BLEND_INV_SRC_ALPHA;
|
||
|
blend_state_desc.RenderTarget[0].BlendOp = D3D11_BLEND_OP_ADD;
|
||
|
blend_state_desc.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_ONE;
|
||
|
blend_state_desc.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_INV_SRC_ALPHA;
|
||
|
blend_state_desc.RenderTarget[0].BlendOpAlpha = D3D11_BLEND_OP_ADD;
|
||
|
blend_state_desc.RenderTarget[0].RenderTargetWriteMask = D3D11_COLOR_WRITE_ENABLE_ALL;
|
||
|
|
||
|
hr = m_device->CreateBlendState(&blend_state_desc, &m_transparency);
|
||
|
if (FAILED(hr))
|
||
|
return false;
|
||
|
|
||
|
memset((void*)vs_blob, NULL, sizeof(vs_blob));
|
||
|
memset((void*)ps_blob, NULL, sizeof(ps_blob));
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
void no_gui::reset()
|
||
|
{
|
||
|
init(m_swap_chain);
|
||
|
}
|
||
|
|
||
|
void no_gui::fill_rect(float x, float y, float w, float h, color color)
|
||
|
{
|
||
|
if (!m_device_context)
|
||
|
return;
|
||
|
|
||
|
int a = color.A & 0xff;
|
||
|
int r = color.R & 0xff;
|
||
|
int g = color.G & 0xff;
|
||
|
int b = color.B & 0xff;
|
||
|
|
||
|
DXGI_SWAP_CHAIN_DESC swap_chain_desc;
|
||
|
memset(&swap_chain_desc, 0, sizeof(swap_chain_desc));
|
||
|
|
||
|
m_swap_chain->GetDesc(&swap_chain_desc);
|
||
|
float width = swap_chain_desc.BufferDesc.Width;
|
||
|
float height = swap_chain_desc.BufferDesc.Height;
|
||
|
|
||
|
UINT numViewports = 1;
|
||
|
D3D11_VIEWPORT vp = { 0, 0, width, height, 1, 1 };
|
||
|
m_device_context->RSSetViewports(numViewports, &vp);
|
||
|
|
||
|
float x0 = x;
|
||
|
float y0 = y;
|
||
|
float x1 = x + w;
|
||
|
float y1 = y + h;
|
||
|
|
||
|
float xx0 = 2.0f * (x0 - 0.5f) / vp.Width - 1.0f;
|
||
|
float yy0 = 1.0f - 2.0f * (y0 - 0.5f) / vp.Height;
|
||
|
float xx1 = 2.0f * (x1 - 0.5f) / vp.Width - 1.0f;
|
||
|
float yy1 = 1.0f - 2.0f * (y1 - 0.5f) / vp.Height;
|
||
|
|
||
|
COLOR_VERTEX* v = NULL;
|
||
|
D3D11_MAPPED_SUBRESOURCE mapData;
|
||
|
|
||
|
if (FAILED(m_device_context->Map(m_pvertex_buffer, NULL, D3D11_MAP_WRITE_DISCARD, NULL, &mapData)))
|
||
|
return;
|
||
|
|
||
|
v = (COLOR_VERTEX*)mapData.pData;
|
||
|
|
||
|
v[0].Position.x = (float)x0;
|
||
|
v[0].Position.y = (float)y0;
|
||
|
v[0].Position.z = 0;
|
||
|
v[0].Color = vec4(
|
||
|
((float)r / 255.0f),
|
||
|
((float)g / 255.0f),
|
||
|
((float)b / 255.0f),
|
||
|
((float)a / 255.0f));
|
||
|
|
||
|
v[1].Position.x = (float)x1;
|
||
|
v[1].Position.y = (float)y1;
|
||
|
v[1].Position.z = 0;
|
||
|
v[1].Color = vec4(
|
||
|
((float)r / 255.0f),
|
||
|
((float)g / 255.0f),
|
||
|
((float)b / 255.0f),
|
||
|
((float)a / 255.0f));
|
||
|
|
||
|
v[0].Position.x = xx0;
|
||
|
v[0].Position.y = yy0;
|
||
|
v[0].Position.z = 0;
|
||
|
v[0].Color = vec4(
|
||
|
((float)r / 255.0f),
|
||
|
((float)g / 255.0f),
|
||
|
((float)b / 255.0f),
|
||
|
((float)a / 255.0f));
|
||
|
|
||
|
v[1].Position.x = xx1;
|
||
|
v[1].Position.y = yy0;
|
||
|
v[1].Position.z = 0;
|
||
|
v[1].Color = vec4(
|
||
|
((float)r / 255.0f),
|
||
|
((float)g / 255.0f),
|
||
|
((float)b / 255.0f),
|
||
|
((float)a / 255.0f));
|
||
|
|
||
|
v[2].Position.x = xx0;
|
||
|
v[2].Position.y = yy1;
|
||
|
v[2].Position.z = 0;
|
||
|
v[2].Color = vec4(
|
||
|
((float)r / 255.0f),
|
||
|
((float)g / 255.0f),
|
||
|
((float)b / 255.0f),
|
||
|
((float)a / 255.0f));
|
||
|
|
||
|
v[3].Position.x = xx1;
|
||
|
v[3].Position.y = yy1;
|
||
|
v[3].Position.z = 0;
|
||
|
v[3].Color = vec4(
|
||
|
((float)r / 255.0f),
|
||
|
((float)g / 255.0f),
|
||
|
((float)b / 255.0f),
|
||
|
((float)a / 255.0f));
|
||
|
|
||
|
|
||
|
m_device_context->Unmap(m_pvertex_buffer, NULL);
|
||
|
|
||
|
UINT Stride = sizeof(COLOR_VERTEX);
|
||
|
UINT Offset = 0;
|
||
|
|
||
|
m_device_context->IASetVertexBuffers(0, 1, &m_pvertex_buffer, &Stride, &Offset);
|
||
|
m_device_context->IASetPrimitiveTopology(D3D10_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
|
||
|
m_device_context->IASetInputLayout(m_input_layout);
|
||
|
|
||
|
m_device_context->VSSetShader(m_vertex_shader, 0, 0);
|
||
|
m_device_context->PSSetShader(m_pixel_shader, 0, 0);
|
||
|
m_device_context->GSSetShader(NULL, 0, 0);
|
||
|
m_device_context->Draw(4, 0);
|
||
|
}
|
||
|
|
||
|
void no_gui::draw_line(float x1, float y1, float x2, float y2, color color)
|
||
|
{
|
||
|
float blendFactor[] = { 1.0f, 1.0f, 1.0f, 1.0f };
|
||
|
m_device_context->OMSetBlendState(m_transparency, blendFactor, 0xffffffff);
|
||
|
|
||
|
if (m_device_context == NULL) {
|
||
|
return;
|
||
|
}
|
||
|
int a = color.A & 0xff;
|
||
|
int r = color.R & 0xff;
|
||
|
int g = color.G & 0xff;
|
||
|
int b = color.B & 0xff;
|
||
|
|
||
|
UINT viewportNumber = 1;
|
||
|
|
||
|
D3D11_VIEWPORT vp;
|
||
|
|
||
|
m_device_context->RSGetViewports(&viewportNumber, &vp);
|
||
|
|
||
|
float xx0 = 2.0f * (x1 - 0.5f) / vp.Width - 1.0f;
|
||
|
float yy0 = 1.0f - 2.0f * (y1 - 0.5f) / vp.Height;
|
||
|
float xx1 = 2.0f * (x2 - 0.5f) / vp.Width - 1.0f;
|
||
|
float yy1 = 1.0f - 2.0f * (y2 - 0.5f) / vp.Height;
|
||
|
|
||
|
COLOR_VERTEX* v = NULL;
|
||
|
|
||
|
D3D11_MAPPED_SUBRESOURCE mapData;
|
||
|
|
||
|
if (FAILED(m_device_context->Map(m_pvertex_buffer, NULL, D3D11_MAP_WRITE_DISCARD, NULL, &mapData)))
|
||
|
return;
|
||
|
|
||
|
v = (COLOR_VERTEX*)mapData.pData;
|
||
|
v[0].Position.x = xx0;
|
||
|
v[0].Position.y = yy0;
|
||
|
|
||
|
v[0].Position.z = 0;
|
||
|
v[0].Color = vec4(
|
||
|
((float)r / 255.0f),
|
||
|
((float)g / 255.0f),
|
||
|
((float)b / 255.0f),
|
||
|
((float)a / 255.0f));
|
||
|
|
||
|
v[1].Position.x = xx1;
|
||
|
v[1].Position.y = yy1;
|
||
|
v[1].Position.z = 0;
|
||
|
v[1].Color = vec4(
|
||
|
((float)r / 255.0f),
|
||
|
((float)g / 255.0f),
|
||
|
((float)b / 255.0f),
|
||
|
((float)a / 255.0f));
|
||
|
|
||
|
m_device_context->Unmap(m_pvertex_buffer, NULL);
|
||
|
UINT Stride = sizeof(COLOR_VERTEX);
|
||
|
UINT Offset = 0;
|
||
|
|
||
|
m_device_context->IASetVertexBuffers(0, 1, &m_pvertex_buffer, &Stride, &Offset);
|
||
|
m_device_context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_LINESTRIP);
|
||
|
m_device_context->IASetInputLayout(m_input_layout);
|
||
|
|
||
|
m_device_context->VSSetShader(m_vertex_shader, 0, 0);
|
||
|
m_device_context->PSSetShader(m_pixel_shader, 0, 0);
|
||
|
m_device_context->GSSetShader(NULL, 0, 0);
|
||
|
m_device_context->Draw(2, 0);
|
||
|
}
|
||
|
|
||
|
void no_gui::draw_rect(float x, float y, float w, float h, color strokeColor)
|
||
|
{
|
||
|
fill_rect(x, y, w, 1, strokeColor);
|
||
|
fill_rect(x, y + h - 1, w, 1, strokeColor);
|
||
|
fill_rect(x, y + 1, 1, h - 2 * 1, strokeColor);
|
||
|
fill_rect(x + w - 1, y + 1, 1, h - 2 * 1, strokeColor);
|
||
|
}
|
||
|
|
||
|
void no_gui::draw_outlined_rect(const vec4& rect, const color& strokeColor, const color& color)
|
||
|
{
|
||
|
fill_rect(rect.x, rect.y, rect.z, rect.w, color);
|
||
|
draw_rect(rect.x, rect.y, rect.z, rect.w, strokeColor);
|
||
|
}
|
||
|
|
||
|
void no_gui::draw_corner_box(int x, int y, int w, int h, int borderPx, color& temp)
|
||
|
{
|
||
|
fill_rect(x - (w / 2), (y - h + borderPx), w / 3, borderPx, temp); //top
|
||
|
fill_rect(x - (w / 2) + w - w / 3, (y - h + borderPx), w / 3, borderPx, temp); //top
|
||
|
fill_rect(x - (w / 2), (y - h + borderPx), borderPx, w / 3, temp); //left
|
||
|
fill_rect(x - (w / 2), (y - h + borderPx) + h - w / 3, borderPx, w / 3, temp); //left
|
||
|
fill_rect(x - (w / 2), y, w / 3, borderPx, temp); //bottom
|
||
|
fill_rect(x - (w / 2) + w - w / 3, y, w / 3, borderPx, temp); //bottom
|
||
|
fill_rect((x + w - borderPx) - (w / 2), (y - h + borderPx), borderPx, w / 3, temp); //right
|
||
|
fill_rect((x + w - borderPx) - (w / 2), (y - h + borderPx) + h - w / 3, borderPx, w / 3, temp); //right
|
||
|
}
|
||
|
|
||
|
void no_gui::draw_border(int x, int y, int w, int h, int px, color& temp)
|
||
|
{
|
||
|
fill_rect(x, (y + h - px), w, px, temp);
|
||
|
fill_rect(x, y, px, h, temp);
|
||
|
fill_rect(x, y, w, px, temp);
|
||
|
fill_rect((x + w - px), y, px, h, temp);
|
||
|
}
|
||
|
|
||
|
void no_gui::draw_cross(float x, float y, float width, float height, const color& color)
|
||
|
{
|
||
|
fill_rect(x - width, y - 0.5f, (width * 2.0f), 1.0f, color);
|
||
|
fill_rect(x - 0.5f, y - height, 1.0f, (height * 2.0f), color);
|
||
|
}
|
||
|
|
||
|
void no_gui::draw_circle(float x0, float y0, float radius, const color& color, float thickness)
|
||
|
{
|
||
|
int x = radius, y = 0;
|
||
|
int radius_error = 1 - x;
|
||
|
|
||
|
while (x >= y)
|
||
|
{
|
||
|
fill_rect(x + x0, y + y0, thickness, thickness, color);
|
||
|
fill_rect(y + x0, x + y0, thickness, thickness, color);
|
||
|
fill_rect(-x + x0, y + y0, thickness, thickness, color);
|
||
|
fill_rect(-y + x0, x + y0, thickness, thickness, color);
|
||
|
fill_rect(-x + x0, -y + y0, thickness, thickness, color);
|
||
|
fill_rect(-y + x0, -x + y0, thickness, thickness, color);
|
||
|
fill_rect(x + x0, -y + y0, thickness, thickness, color);
|
||
|
fill_rect(y + x0, -x + y0, thickness, thickness, color);
|
||
|
y++;
|
||
|
|
||
|
if (radius_error < 0)
|
||
|
radius_error += 2 * y + 1;
|
||
|
else
|
||
|
{
|
||
|
x--;
|
||
|
radius_error += 2 * (y - x + 1);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void no_gui::draw_health_bar(int x, int y, float health, float max_health, int w, int h, bool is_shield)
|
||
|
{
|
||
|
auto c_black = ::color(12, 12, 12, 228);
|
||
|
auto c_red = ::color(255, 0, 0, 255);
|
||
|
auto c_green = ::color(255, 0, 255, 0);
|
||
|
auto c_yellow = ::color(255, 255, 255, 0);
|
||
|
auto c_cyan = ::color(255, 0, 255, 255);
|
||
|
auto c_orange = ::color(255, 255, 153, 0);
|
||
|
|
||
|
if (is_shield)
|
||
|
{
|
||
|
c_red = ::color(255, 102, 2, 209);
|
||
|
c_green = ::color(255, 19, 105, 244);
|
||
|
c_yellow = ::color(255, 13, 175, 229);
|
||
|
c_orange = ::color(255, 171, 13, 229);
|
||
|
}
|
||
|
|
||
|
if (health > max_health)
|
||
|
health = max_health;
|
||
|
|
||
|
FLOAT hp = health;
|
||
|
FLOAT factor = max_health / 4;
|
||
|
auto color = ::color(0.f, 0.f, 0.f, 0.f);
|
||
|
|
||
|
if (hp <= factor)
|
||
|
color = c_red;
|
||
|
else if (hp <= factor * 2)
|
||
|
color = c_orange;
|
||
|
else if (hp <= factor * 3)
|
||
|
color = c_yellow;
|
||
|
else if (hp <= max_health)
|
||
|
color = c_green;
|
||
|
|
||
|
fill_rect(x, y, w, h + 1, ::color(255, 0, 0, 0));
|
||
|
UINT hw = (UINT)(((w - 2) * health) / max_health);
|
||
|
fill_rect(x + 1, y + 1, hw, h - 1, color);
|
||
|
|
||
|
}
|
||
|
|
||
|
HWND no_gui::get_window()
|
||
|
{
|
||
|
return m_hwnd;
|
||
|
}
|
||
|
|
||
|
float no_gui::get_width()
|
||
|
{
|
||
|
return m_width;
|
||
|
}
|
||
|
|
||
|
float no_gui::get_height()
|
||
|
{
|
||
|
return m_height;
|
||
|
}
|
||
|
|
||
|
void no_gui::begin_scene()
|
||
|
{
|
||
|
m_swap_chain->GetBuffer(0, __uuidof(ID3D11Texture2D), (void**)&m_back_buffer);
|
||
|
ID3D11RenderTargetView* p_rtv;
|
||
|
m_device->CreateRenderTargetView(m_back_buffer, NULL, &p_rtv);
|
||
|
m_device_context->OMSetRenderTargets(1, &p_rtv, NULL);
|
||
|
|
||
|
DXGI_SWAP_CHAIN_DESC swap_chain_desc;
|
||
|
memset(&swap_chain_desc, 0, sizeof(swap_chain_desc));
|
||
|
m_swap_chain->GetDesc(&swap_chain_desc);
|
||
|
m_width = swap_chain_desc.BufferDesc.Width;
|
||
|
m_height = swap_chain_desc.BufferDesc.Height;
|
||
|
|
||
|
m_restore_state = false;
|
||
|
if (SUCCEEDED(m_state_saver.save_current_state(m_device_context)))
|
||
|
m_restore_state = true;
|
||
|
m_device_context->IASetInputLayout(m_input_layout);
|
||
|
}
|
||
|
|
||
|
void no_gui::end_scene()
|
||
|
{
|
||
|
D3D11_TEXTURE2D_DESC backBufferDesc;
|
||
|
m_back_buffer->GetDesc(&backBufferDesc);
|
||
|
m_back_buffer->Release();
|
||
|
|
||
|
if (m_restore_state)
|
||
|
m_state_saver.restore_saved_state();
|
||
|
}
|