1
0
mirror of https://github.com/borgesdan/xn65 synced 2024-12-29 21:54:47 +01:00

428 lines
13 KiB
C++
Raw Normal View History

2024-06-03 21:55:09 -03:00
#include "xna/graphics/rasterizerstate.hpp"
#include "xna/graphics/samplerstate.hpp"
#include "xna/common/color.hpp"
#include "xna/common/numerics.hpp"
#include "xna/graphics/sprite.hpp"
#include "xna/graphics/viewport.hpp"
#include "xna/graphics/blendstate.hpp"
#include "xna/graphics/depthstencilstate.hpp"
2024-06-05 21:28:53 -03:00
#include "xna/platform-dx/dx.hpp"
2024-04-14 16:11:15 -03:00
using DxSpriteBatch = DirectX::SpriteBatch;
using DxSpriteSortMode = DirectX::SpriteSortMode;
using DxMatrix = DirectX::FXMMATRIX;
using DxSpriteEffects = DirectX::SpriteEffects;
using DirectX::XMFLOAT2;
using DirectX::FXMVECTOR;
using DirectX::XMVECTORF32;
using DirectX::GXMVECTOR;
2024-05-18 21:14:56 -03:00
using DxSpriteFont = DirectX::SpriteFont;
2024-05-30 17:37:40 -03:00
using DxGlyph = DirectX::SpriteFont::Glyph;
2024-04-14 16:11:15 -03:00
namespace xna {
2024-05-30 17:37:40 -03:00
SpriteFont::SpriteFont(
sptr<Texture2D> const& texture,
std::vector<Rectangle> const& glyphs,
std::vector<Rectangle> const& cropping,
2024-05-31 22:30:45 -03:00
std::vector<Char> const& charMap,
2024-05-30 17:37:40 -03:00
Int lineSpacing,
float spacing,
std::vector<Vector3> const& kerning,
2024-06-06 14:18:16 -03:00
std::optional<Char> const& defaultCharacter)
2024-05-18 21:14:56 -03:00
{
2024-06-06 14:18:16 -03:00
if (!texture || !texture->impl->dxShaderResource)
2024-05-30 17:37:40 -03:00
throw std::invalid_argument("SpriteFont: texture is null.");
2024-06-06 14:18:16 -03:00
if(cropping.size() != glyphs.size() || charMap.size() != glyphs.size() || (!kerning.empty() && kerning.size() != glyphs.size()))
throw std::invalid_argument("SpriteFont: cropping, charmap and kerning (if not empty) must all be the same size.");
2024-05-31 22:30:45 -03:00
std::vector<DxGlyph> dxGlyps(glyphs.size());
2024-05-30 17:37:40 -03:00
for (size_t i = 0; i < dxGlyps.size(); ++i) {
DxGlyph g;
2024-06-06 14:18:16 -03:00
g.Subrect.left = static_cast<LONG>(glyphs[i].Left());
g.Subrect.right = static_cast<LONG>(glyphs[i].Right());
g.Subrect.top = static_cast<LONG>(glyphs[i].Top());
g.Subrect.bottom = static_cast<LONG>(glyphs[i].Bottom());
2024-05-31 22:30:45 -03:00
g.Character = static_cast<Uint>(charMap[i]);
2024-06-06 14:18:16 -03:00
if (!kerning.empty()) {
g.XOffset = kerning[i].X;
g.YOffset = static_cast<float>(cropping[i].Y);
g.XAdvance = kerning[i].Z + spacing;
}
else {
g.XOffset = 0;
g.YOffset = 0;
g.XAdvance = spacing;
}
2024-05-31 22:30:45 -03:00
dxGlyps[i] = g;
}
impl = unew<PlatformImplementation>();
2024-05-30 17:37:40 -03:00
impl->_dxSpriteFont = unew<DxSpriteFont>(
//ID3D11ShaderResourceView* texture
2024-06-25 17:06:37 -03:00
texture->impl->dxShaderResource.Get(),
2024-05-30 17:37:40 -03:00
//Glyph const* glyphs
dxGlyps.data(),
//size_t glyphCount
glyphs.size(),
//float lineSpacing
static_cast<float>(lineSpacing)
);
if (defaultCharacter.has_value()) {
const auto defChar = static_cast<wchar_t>(defaultCharacter.value());
impl->_dxSpriteFont->SetDefaultCharacter(defChar);
}
2024-06-06 14:18:16 -03:00
}
2024-05-18 21:14:56 -03:00
Vector2 SpriteFont::MeasureString(String const& text, bool ignoreWhiteSpace)
{
2024-05-30 17:37:40 -03:00
if (!impl->_dxSpriteFont)
2024-05-18 21:14:56 -03:00
return Vector2();
2024-05-30 17:37:40 -03:00
const auto size = impl->_dxSpriteFont->MeasureString(text.c_str(), ignoreWhiteSpace);
2024-05-18 21:14:56 -03:00
Vector2 vec2{};
vec2.X = size.m128_f32[0];
vec2.Y = size.m128_f32[1];
return vec2;
2024-05-30 17:37:40 -03:00
}
2024-05-18 19:58:38 -03:00
2024-06-01 12:43:11 -03:00
Vector2 SpriteFont::MeasureString(WString const& text, bool ignoreWhiteSpace)
{
if (!impl->_dxSpriteFont)
return Vector2();
const auto size = impl->_dxSpriteFont->MeasureString(text.c_str(), ignoreWhiteSpace);
Vector2 vec2{};
vec2.X = size.m128_f32[0];
vec2.Y = size.m128_f32[1];
return vec2;
}
2024-06-06 14:18:16 -03:00
Char SpriteFont::DefaultCharacter() const {
const auto defChar = impl->_dxSpriteFont->GetDefaultCharacter();
return static_cast<Char>(defChar);
}
void SpriteFont::DefaultCharacter(Char value) {
const auto defChar = static_cast<wchar_t>(value);
impl->_dxSpriteFont->SetDefaultCharacter(defChar);
}
Int SpriteFont::LineSpacing() const {
const auto space = impl->_dxSpriteFont->GetLineSpacing();
return static_cast<Int>(space);
2024-05-18 19:58:38 -03:00
}
2024-06-06 14:18:16 -03:00
void SpriteFont::LineSpacing(Int value) {
impl->_dxSpriteFont->SetLineSpacing(static_cast<float>(value));
}
SpriteBatch::SpriteBatch(sptr<GraphicsDevice> const& device) : GraphicsResource(device) {
if (!device->impl->_context)
2024-04-25 14:51:33 -03:00
return;
implementation = unew<PlatformImplementation>();
implementation->_dxspriteBatch = snew<DxSpriteBatch>(
2024-06-06 14:18:16 -03:00
//ID3D11DeviceContext* deviceContext
2024-06-25 17:06:37 -03:00
device->impl->_context.Get()
2024-06-06 14:18:16 -03:00
);
2024-04-14 16:11:15 -03:00
Viewport(device->Viewport());
2024-06-06 14:18:16 -03:00
}
2024-05-30 17:37:40 -03:00
2024-06-25 22:04:09 -03:00
void SpriteBatch::Begin(SpriteSortMode sortMode, BlendState* blendState, SamplerState* samplerState, DepthStencilState* depthStencil, RasterizerState* rasterizerState, Effect* effect, Matrix const& transformMatrix) {
2024-04-14 16:11:15 -03:00
2024-05-18 19:58:38 -03:00
if (!implementation->_dxspriteBatch)
2024-04-14 16:11:15 -03:00
return;
2024-06-25 22:04:09 -03:00
DxSpriteSortMode sort = DxHelpers::SpriteSortToDx(sortMode);
2024-05-30 17:37:40 -03:00
2024-04-14 16:11:15 -03:00
const auto& t = transformMatrix;
DxMatrix matrix = DxMatrix(
t.M11, t.M12, t.M13, t.M14,
t.M21, t.M22, t.M23, t.M24,
t.M31, t.M32, t.M33, t.M34,
t.M41, t.M42, t.M43, t.M44);
2024-05-30 17:37:40 -03:00
2024-05-18 19:58:38 -03:00
implementation->_dxspriteBatch->Begin(
2024-04-14 16:11:15 -03:00
sort,
2024-06-25 17:06:37 -03:00
blendState ? blendState->impl->dxBlendState.Get() : nullptr,
samplerState ? samplerState->impl->_samplerState.Get() : nullptr,
depthStencil ? depthStencil->impl->dxDepthStencil.Get() : nullptr,
rasterizerState ? rasterizerState->impl->dxRasterizerState.Get() : nullptr,
2024-04-14 16:11:15 -03:00
nullptr,
matrix
);
}
void SpriteBatch::End() {
2024-05-18 19:58:38 -03:00
if (!implementation->_dxspriteBatch)
2024-04-14 16:11:15 -03:00
return;
2024-05-18 19:58:38 -03:00
implementation->_dxspriteBatch->End();
2024-04-14 16:11:15 -03:00
}
void SpriteBatch::Draw(Texture2D& texture, Vector2 const& position, Color const& color) {
2024-05-18 19:58:38 -03:00
if (!implementation->_dxspriteBatch)
2024-04-14 16:11:15 -03:00
return;
2024-05-23 14:38:16 -03:00
if (!texture.impl->dxShaderResource)
2024-04-14 16:11:15 -03:00
return;
2024-04-14 21:23:09 -03:00
const auto _position = XMFLOAT2(position.X, position.Y);
2024-04-14 16:11:15 -03:00
const auto v4 = color.ToVector4();
2024-04-14 21:23:09 -03:00
XMVECTORF32 _color = { v4.X, v4.Y, v4.Z, v4.W };
2024-04-14 16:11:15 -03:00
2024-05-18 19:58:38 -03:00
implementation->_dxspriteBatch->Draw(
2024-06-25 17:06:37 -03:00
texture.impl->dxShaderResource.Get(),
2024-04-14 16:11:15 -03:00
_position,
_color
);
}
2024-06-06 14:18:16 -03:00
void SpriteBatch::Draw(Texture2D& texture, Vector2 const& position, std::optional<Rectangle> const& sourceRectangle, Color const& color) {
2024-05-18 19:58:38 -03:00
if (!implementation->_dxspriteBatch)
2024-04-14 16:11:15 -03:00
return;
2024-06-06 14:18:16 -03:00
2024-05-23 14:38:16 -03:00
if (!texture.impl->dxShaderResource)
2024-04-14 16:11:15 -03:00
return;
2024-04-14 21:23:09 -03:00
const auto _position = XMFLOAT2(position.X, position.Y);
2024-04-14 16:11:15 -03:00
const auto v4 = color.ToVector4();
2024-04-14 21:23:09 -03:00
const XMVECTORF32 _color = { v4.X, v4.Y, v4.Z, v4.W };
2024-04-14 16:11:15 -03:00
RECT _sourceRect{};
2024-06-06 14:18:16 -03:00
if (sourceRectangle.has_value()) {
2024-04-14 16:11:15 -03:00
_sourceRect.top = sourceRectangle->Y;
_sourceRect.left = sourceRectangle->X;
_sourceRect.right = sourceRectangle->X + sourceRectangle->Width;
_sourceRect.bottom = sourceRectangle->Y + sourceRectangle->Height;
};
2024-05-18 19:58:38 -03:00
implementation->_dxspriteBatch->Draw(
2024-06-25 17:06:37 -03:00
texture.impl->dxShaderResource.Get(),
2024-04-14 16:11:15 -03:00
_position,
sourceRectangle ? &_sourceRect : nullptr,
_color);
}
2024-06-06 14:18:16 -03:00
void SpriteBatch::Draw(Texture2D& texture, Vector2 const& position, std::optional<Rectangle> const& sourceRectangle, Color const& color, float rotation, Vector2 const& origin, float scale, SpriteEffects effects, float layerDepth) {
2024-05-18 19:58:38 -03:00
if (!implementation->_dxspriteBatch)
2024-04-14 16:11:15 -03:00
return;
2024-05-23 14:38:16 -03:00
if (!texture.impl->dxShaderResource)
2024-04-14 16:11:15 -03:00
return;
2024-04-14 21:23:09 -03:00
const auto _position = XMFLOAT2(position.X, position.Y);
const auto _origin = XMFLOAT2(origin.X, origin.Y);
2024-04-14 16:11:15 -03:00
const auto v4 = color.ToVector4();
2024-04-14 21:23:09 -03:00
const XMVECTORF32 _color = { v4.X, v4.Y, v4.Z, v4.W };
2024-04-14 16:11:15 -03:00
RECT _sourceRect{};
2024-06-06 14:18:16 -03:00
if (sourceRectangle.has_value()) {
2024-04-14 16:11:15 -03:00
_sourceRect.top = sourceRectangle->Y;
_sourceRect.left = sourceRectangle->X;
_sourceRect.right = sourceRectangle->X + sourceRectangle->Width;
_sourceRect.bottom = sourceRectangle->Y + sourceRectangle->Height;
};
2024-04-14 21:23:09 -03:00
const DxSpriteEffects _effects = static_cast<DxSpriteEffects>(effects);
2024-04-14 16:11:15 -03:00
2024-05-18 19:58:38 -03:00
implementation->_dxspriteBatch->Draw(
2024-06-25 17:06:37 -03:00
texture.impl->dxShaderResource.Get(),
2024-04-14 16:11:15 -03:00
_position,
sourceRectangle ? &_sourceRect : nullptr,
_color,
rotation,
_origin,
scale,
_effects,
layerDepth);
}
2024-06-06 14:18:16 -03:00
void SpriteBatch::Draw(Texture2D& texture, Vector2 const& position, std::optional<Rectangle> const& sourceRectangle, Color const& color, float rotation, Vector2 const& origin, Vector2 const& scale, SpriteEffects effects, float layerDepth) {
2024-05-18 19:58:38 -03:00
if (!implementation->_dxspriteBatch)
2024-04-14 16:11:15 -03:00
return;
2024-05-23 14:38:16 -03:00
if (!texture.impl->dxShaderResource)
2024-04-14 16:11:15 -03:00
return;
2024-04-14 21:23:09 -03:00
const auto _position = XMFLOAT2(position.X, position.Y);
const auto _origin = XMFLOAT2(origin.X, origin.Y);
2024-04-14 16:11:15 -03:00
const auto v4 = color.ToVector4();
2024-04-14 21:23:09 -03:00
const XMVECTORF32 _color = { v4.X, v4.Y, v4.Z, v4.W };
2024-04-14 16:11:15 -03:00
RECT _sourceRect{};
2024-06-06 14:18:16 -03:00
if (sourceRectangle.has_value()) {
2024-04-14 16:11:15 -03:00
_sourceRect.top = sourceRectangle->Y;
_sourceRect.left = sourceRectangle->X;
_sourceRect.right = sourceRectangle->X + sourceRectangle->Width;
_sourceRect.bottom = sourceRectangle->Y + sourceRectangle->Height;
};
2024-04-14 21:23:09 -03:00
const auto _effects = static_cast<DxSpriteEffects>(effects);
2024-04-14 16:11:15 -03:00
const XMFLOAT2 _scale = { scale.X, scale.Y };
2024-05-18 19:58:38 -03:00
implementation->_dxspriteBatch->Draw(
2024-06-25 17:06:37 -03:00
texture.impl->dxShaderResource.Get(),
2024-04-14 16:11:15 -03:00
_position,
sourceRectangle ? &_sourceRect : nullptr,
_color,
rotation,
_origin,
_scale,
_effects,
layerDepth);
}
void SpriteBatch::Draw(Texture2D& texture, Rectangle const& destinationRectangle, Color const& color) {
2024-05-18 19:58:38 -03:00
if (!implementation->_dxspriteBatch)
2024-04-14 16:11:15 -03:00
return;
2024-05-23 14:38:16 -03:00
if (!texture.impl->dxShaderResource)
2024-04-14 16:11:15 -03:00
return;
RECT _destinationRect{};
_destinationRect.left = destinationRectangle.X;
_destinationRect.top = destinationRectangle.Y;
_destinationRect.right = destinationRectangle.X + destinationRectangle.Width;
_destinationRect.bottom = destinationRectangle.Y + destinationRectangle.Height;
const auto v4 = color.ToVector4();
2024-04-14 21:23:09 -03:00
const XMVECTORF32 _color = { v4.X, v4.Y, v4.Z, v4.W };
2024-04-14 16:11:15 -03:00
2024-06-25 17:06:37 -03:00
implementation->_dxspriteBatch->Draw(texture.impl->dxShaderResource.Get(), _destinationRect, _color);
2024-04-14 16:11:15 -03:00
}
2024-06-06 14:18:16 -03:00
void SpriteBatch::Draw(Texture2D& texture, Rectangle const& destinationRectangle, std::optional<Rectangle> const& sourceRectangle, Color const& color) {
2024-05-18 19:58:38 -03:00
if (!implementation->_dxspriteBatch)
2024-04-14 16:11:15 -03:00
return;
2024-05-23 14:38:16 -03:00
if (!texture.impl->dxShaderResource)
2024-04-14 16:11:15 -03:00
return;
RECT _destinationRect{};
_destinationRect.left = destinationRectangle.X;
_destinationRect.top = destinationRectangle.Y;
_destinationRect.right = destinationRectangle.X + destinationRectangle.Width;
_destinationRect.bottom = destinationRectangle.Y + destinationRectangle.Height;
const auto v4 = color.ToVector4();
2024-04-14 21:23:09 -03:00
const XMVECTORF32 _color = { v4.X, v4.Y, v4.Z, v4.W };
2024-04-14 16:11:15 -03:00
RECT _sourceRect{};
2024-06-06 14:18:16 -03:00
if (sourceRectangle.has_value()) {
2024-04-14 16:11:15 -03:00
_sourceRect.top = sourceRectangle->Y;
_sourceRect.left = sourceRectangle->X;
_sourceRect.right = sourceRectangle->X + sourceRectangle->Width;
_sourceRect.bottom = sourceRectangle->Y + sourceRectangle->Height;
};
2024-06-25 17:06:37 -03:00
implementation->_dxspriteBatch->Draw(texture.impl->dxShaderResource.Get(), _destinationRect, sourceRectangle ? &_sourceRect : nullptr, _color);
2024-04-14 16:11:15 -03:00
}
2024-06-06 14:18:16 -03:00
void SpriteBatch::Draw(Texture2D& texture, Rectangle const& destinationRectangle, std::optional<Rectangle> const& sourceRectangle, Color const& color, float rotation, Vector2 const& origin, SpriteEffects effects, float layerDepth) {
2024-05-18 19:58:38 -03:00
if (!implementation->_dxspriteBatch)
2024-04-14 16:11:15 -03:00
return;
2024-05-23 14:38:16 -03:00
if (!texture.impl->dxShaderResource)
2024-04-14 16:11:15 -03:00
return;
RECT _destinationRect{};
_destinationRect.left = destinationRectangle.X;
_destinationRect.top = destinationRectangle.Y;
_destinationRect.right = destinationRectangle.X + destinationRectangle.Width;
_destinationRect.bottom = destinationRectangle.Y + destinationRectangle.Height;
const auto v4 = color.ToVector4();
2024-04-14 21:23:09 -03:00
const XMVECTORF32 _color = { v4.X, v4.Y, v4.Z, v4.W };
2024-04-14 16:11:15 -03:00
RECT _sourceRect{};
2024-06-06 14:18:16 -03:00
if (sourceRectangle.has_value()) {
2024-04-14 16:11:15 -03:00
_sourceRect.top = sourceRectangle->Y;
_sourceRect.left = sourceRectangle->X;
_sourceRect.right = sourceRectangle->X + sourceRectangle->Width;
_sourceRect.bottom = sourceRectangle->Y + sourceRectangle->Height;
};
auto _origin = XMFLOAT2(origin.X, origin.Y);
2024-04-14 21:23:09 -03:00
const auto _effects = static_cast<DxSpriteEffects>(effects);
2024-04-14 16:11:15 -03:00
2024-05-18 19:58:38 -03:00
implementation->_dxspriteBatch->Draw(
2024-06-25 17:06:37 -03:00
texture.impl->dxShaderResource.Get(),
2024-04-14 16:11:15 -03:00
_destinationRect,
sourceRectangle ? &_sourceRect : nullptr,
_color,
rotation,
_origin,
_effects,
layerDepth);
}
2024-05-30 17:37:40 -03:00
void SpriteBatch::Viewport(xna::Viewport const& value) {
2024-05-18 19:58:38 -03:00
if (!implementation->_dxspriteBatch)
2024-04-14 16:11:15 -03:00
return;
D3D11_VIEWPORT _view{};
_view.TopLeftX = value.X;
_view.TopLeftY = value.Y;
_view.Width = value.Width;
_view.Height = value.Height;
_view.MinDepth = value.MinDetph;
_view.MaxDepth = value.MaxDepth;
2024-05-18 19:58:38 -03:00
implementation->_dxspriteBatch->SetViewport(_view);
2024-05-30 17:37:40 -03:00
}
2024-04-14 21:23:09 -03:00
void SpriteBatch::DrawString(SpriteFont& spriteFont, String const& text, Vector2 const& position, Color const& color) {
2024-05-30 17:37:40 -03:00
if (!implementation->_dxspriteBatch || !spriteFont.impl->_dxSpriteFont)
2024-04-14 21:23:09 -03:00
return;
const auto _position = XMFLOAT2(position.X, position.Y);
const auto v4 = color.ToVector4();
const XMVECTORF32 _color = { v4.X, v4.Y, v4.Z, v4.W };
2024-05-30 17:37:40 -03:00
spriteFont.impl->_dxSpriteFont->DrawString(
2024-05-18 19:58:38 -03:00
implementation->_dxspriteBatch.get(),
2024-04-14 21:23:09 -03:00
text.c_str(),
_position,
_color
);
}
2024-05-30 17:37:40 -03:00
2024-04-14 21:23:09 -03:00
void SpriteBatch::DrawString(SpriteFont& spriteFont, String const& text, Vector2 const& position,
Color const& color, float rotation, Vector2 const& origin, float scale, SpriteEffects effects, float layerDepth) {
2024-05-30 17:37:40 -03:00
if (!implementation->_dxspriteBatch || !spriteFont.impl->_dxSpriteFont)
2024-04-14 21:23:09 -03:00
return;
const auto _position = XMFLOAT2(position.X, position.Y);
const auto _origin = XMFLOAT2(origin.X, origin.Y);
const auto v4 = color.ToVector4();
const XMVECTORF32 _color = { v4.X, v4.Y, v4.Z, v4.W };
const auto _effects = static_cast<DxSpriteEffects>(effects);
2024-05-30 17:37:40 -03:00
spriteFont.impl->_dxSpriteFont->DrawString(
2024-05-18 19:58:38 -03:00
implementation->_dxspriteBatch.get(),
2024-04-14 21:23:09 -03:00
text.c_str(),
_position,
2024-05-30 17:37:40 -03:00
_color,
rotation,
_origin,
scale,
_effects,
2024-04-14 21:23:09 -03:00
layerDepth
);
}
2024-04-14 16:11:15 -03:00
}