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

Implementa interfaces

This commit is contained in:
Danilo 2024-03-21 16:01:47 -03:00
parent 99c8486c90
commit 42e202f06e
30 changed files with 727 additions and 425 deletions

View File

@ -3,7 +3,7 @@
# #
# Add source to this project's executable. # Add source to this project's executable.
add_executable (xna WIN32 "xna.cpp" "xna.h" "platform/window-dx.cpp" "platform/device-dx.cpp" "platform/adapter-dx.cpp" "platform/swapchain-dx.cpp" "platform/rendertarget-dx.cpp" "platform/texture-dx.cpp" "platform/blendstate-dx.cpp") add_executable (xna WIN32 "xna.cpp" "xna.h" "platform/window-dx.cpp" "platform/device-dx.cpp" "platform/adapter-dx.cpp" "platform/swapchain-dx.cpp" "platform/rendertarget-dx.cpp" "platform/texture-dx.cpp" "platform/blendstate-dx.cpp" "platform/game-dx.cpp")
if (CMAKE_VERSION VERSION_GREATER 3.12) if (CMAKE_VERSION VERSION_GREATER 3.12)
set_property(TARGET xna PROPERTY CXX_STANDARD 20) set_property(TARGET xna PROPERTY CXX_STANDARD 20)

View File

@ -23,7 +23,16 @@ namespace xna {
struct Vector3; struct Vector3;
struct Vector4; struct Vector4;
//Audio //Game
class DrawableGameComponent;
class Game;
class GameComponent;
class GameComponentCollection;
class GameTime;
class GameWindow;
class IDrawable;
class IGameComponent;
class IUpdatable;
//Graphics //Graphics
class BlendState; class BlendState;
@ -35,18 +44,7 @@ namespace xna {
class SwapChain; class SwapChain;
class Texture; class Texture;
class Texture2D; class Texture2D;
struct Viewport; struct Viewport;
//Game
class DrawableGameComponent;
class Game;
class GameComponent;
class GameComponentCollection;
class GameTime;
class GameWindow;
class IDrawable;
class IGameComponent;
class IUpdatable;
using PBoundingBox = std::shared_ptr<BoundingBox>; using PBoundingBox = std::shared_ptr<BoundingBox>;
using PBoundingFrustum = std::shared_ptr<BoundingFrustum>; using PBoundingFrustum = std::shared_ptr<BoundingFrustum>;
@ -64,18 +62,7 @@ namespace xna {
using PRectangle = std::shared_ptr<Rectangle>; using PRectangle = std::shared_ptr<Rectangle>;
using PVector2 = std::shared_ptr<Vector2>; using PVector2 = std::shared_ptr<Vector2>;
using PVector3 = std::shared_ptr<Vector3>; using PVector3 = std::shared_ptr<Vector3>;
using PVector4 = std::shared_ptr<Vector4>; using PVector4 = std::shared_ptr<Vector4>;
using PBlendState = std::shared_ptr<BlendState>;
using PDisplayMode = std::shared_ptr<DisplayMode>;
using PDisplayModeCollection = std::shared_ptr<DisplayModeCollection>;
using PGraphicsAdapter = std::shared_ptr<GraphicsAdapter>;
using PGraphicsDevice = std::shared_ptr<GraphicsDevice>;
using PRenderTarget2D = std::shared_ptr<RenderTarget2D>;
using PSwapChain = std::shared_ptr<SwapChain>;
using PTexture = std::shared_ptr<Texture>;
using PTexture2D = std::shared_ptr<Texture2D>;
using PViewport = std::shared_ptr<Viewport>;
using PDrawableGameComponent = std::shared_ptr<DrawableGameComponent>; using PDrawableGameComponent = std::shared_ptr<DrawableGameComponent>;
using PGame = std::shared_ptr<Game>; using PGame = std::shared_ptr<Game>;
@ -86,6 +73,17 @@ namespace xna {
using PIDrawable = std::shared_ptr<IDrawable>; using PIDrawable = std::shared_ptr<IDrawable>;
using PIGameComponent = std::shared_ptr<IGameComponent>; using PIGameComponent = std::shared_ptr<IGameComponent>;
using PIUpdatable = std::shared_ptr<IUpdatable>; using PIUpdatable = std::shared_ptr<IUpdatable>;
using PBlendState = std::shared_ptr<BlendState>;
using PDisplayMode = std::shared_ptr<DisplayMode>;
using PDisplayModeCollection = std::shared_ptr<DisplayModeCollection>;
using PGraphicsAdapter = std::shared_ptr<GraphicsAdapter>;
using PGraphicsDevice = std::shared_ptr<GraphicsDevice>;
using PRenderTarget2D = std::shared_ptr<RenderTarget2D>;
using PSwapChain = std::shared_ptr<SwapChain>;
using PTexture = std::shared_ptr<Texture>;
using PTexture2D = std::shared_ptr<Texture2D>;
using PViewport = std::shared_ptr<Viewport>;
} }
#endif #endif

25
framework/game/game.hpp Normal file
View File

@ -0,0 +1,25 @@
#ifndef XNA_GAME_GAME_HPP
#define XNA_GAME_GAME_HPP
#include "../enums.hpp"
#include "../forward.hpp"
#include "../types.hpp"
#include "time.hpp"
#include "window.hpp"
namespace xna {
class IGame {
public:
virtual ~IGame(){}
virtual void Exit() = 0;
virtual int Run() = 0;
protected:
virtual void Draw(GameTime const& gameTime) = 0;
virtual void Initialize() = 0;
virtual void Update(GameTime const& gameTime) = 0;
};
}
#endif

37
framework/game/time.hpp Normal file
View File

@ -0,0 +1,37 @@
#ifndef XNA_GAME_TIME_HPP
#define XNA_GAME_TIME_HPP
#include "../forward.hpp"
#include "../types.hpp"
#include "../timespan.hpp"
namespace xna {
class GameTime {
public:
constexpr GameTime() = default;
constexpr GameTime(const TimeSpan& elapsedGameTime, bool isRunningSlowly, const TimeSpan& totalGameTime) :
_elapsedGameTime(elapsedGameTime),
_isRunningSlowly(isRunningSlowly),
_totalGameTime(totalGameTime) { }
constexpr TimeSpan ElapsedGameTime() const {
return _elapsedGameTime;
}
constexpr bool IsRunningSlowly() const {
return _isRunningSlowly;
}
constexpr TimeSpan TotalGameTime() const {
return _totalGameTime;
}
private:
TimeSpan _elapsedGameTime{ 0 };
bool _isRunningSlowly{ false };
TimeSpan _totalGameTime{ 0 };
};
}
#endif

View File

@ -5,25 +5,14 @@
#include "../common/rectangle.hpp" #include "../common/rectangle.hpp"
namespace xna { namespace xna {
class GameWindow { class IGameWindow {
public: public:
PLATFORM_DEVELOPMENT virtual ~IGameWindow(){}
GameWindow();
PLATFORM_DEVELOPMENT
String Title() const;
PLATFORM_DEVELOPMENT
void Title(String const& title);
PLATFORM_DEVELOPMENT
Rectangle ClientBounds() const;
PLATFORM_DEVELOPMENT
intptr_t Handle() const;
private: virtual String Title() const = 0;
class InternalProperty; virtual void Title(String const& title) = 0;
friend class InternalProperty; virtual Rectangle ClientBounds() const = 0;
virtual intptr_t Handle() const = 0;
public:
sptr<InternalProperty> ip_GameWindow{ nullptr };
}; };
} }

View File

@ -7,64 +7,49 @@
#include "displaymode.hpp" #include "displaymode.hpp"
namespace xna { namespace xna {
class GraphicsAdapter { class IGraphicsAdapter {
public: public:
PLATFORM_DEVELOPMENT virtual ~IGraphicsAdapter() {
GraphicsAdapter(); }
static PGraphicsAdapter DefaultAdapter() { static PGraphicsAdapter DefaultAdapter() {
if (_adaptersList.empty()) if (_adaptersList.empty())
return nullptr; return nullptr;
if (_defaultAdapter >= _adaptersList.size()) if (_defaultAdapterIndex >= _adaptersList.size())
return nullptr; return nullptr;
return _adaptersList[_defaultAdapter]; return _adaptersList[_defaultAdapterIndex];
} }
static constexpr void DefaultAdapter(size_t index) { static constexpr void DefaultAdapter(size_t index) {
_defaultAdapter = index; _defaultAdapterIndex = index;
} }
static constexpr std::vector<PGraphicsAdapter> Adapters() { static constexpr std::vector<PGraphicsAdapter> Adapters() {
return _adaptersList; return _adaptersList;
} }
PLATFORM_DEVELOPMENT virtual String Description() const = 0;
String Description() const; virtual Uint DeviceId() const = 0;
PLATFORM_DEVELOPMENT virtual String DeviceName() const = 0;
Uint DeviceId() const;
PLATFORM_DEVELOPMENT
String DeviceName() const;
bool IsDefaultAdapter() const { constexpr bool IsDefaultAdapter() const {
auto def = DefaultAdapter(); return _index == _defaultAdapterIndex;
return this == def.get();
} }
PLATFORM_DEVELOPMENT virtual intptr_t MonitorHandle() const = 0;
intptr_t MonitorHandle() const; virtual Uint Revision() const = 0;
PLATFORM_DEVELOPMENT virtual Uint SubSystemId() const = 0;
Uint Revision() const; virtual Uint VendorId() const = 0;
PLATFORM_DEVELOPMENT
Uint SubSystemId() const;
PLATFORM_DEVELOPMENT
Uint VendorId() const;
PLATFORM_DEVELOPMENT
PDisplayModeCollection SupportedDisplayModes() const;
private:
inline static size_t _defaultAdapter = 0;
PLATFORM_DEVELOPMENT
static std::vector<PGraphicsAdapter> getAllAdapters();
virtual PDisplayModeCollection SupportedDisplayModes() const = 0;
protected:
Uint _index{ 0 };
inline static size_t _defaultAdapterIndex = 0;
static std::vector<PGraphicsAdapter> getAllAdapters();
inline static std::vector<PGraphicsAdapter> _adaptersList = getAllAdapters(); inline static std::vector<PGraphicsAdapter> _adaptersList = getAllAdapters();
public:
class InternalProperty;
friend class InternalProperty;
sptr<InternalProperty> ip_GraphicsAdapter{ nullptr };
}; };
} }

View File

@ -6,53 +6,16 @@
#include "../enums.hpp" #include "../enums.hpp"
namespace xna { namespace xna {
class BlendState { class IBlendState {
public: public:
PLATFORM_DEVELOPMENT virtual ~IBlendState(){}
BlendState(GraphicsDevice* device);
static PBlendState Opaque() { static PBlendState Opaque();
auto blendState = New<BlendState>(nullptr); static PBlendState AlphaBlend();
blendState->_source = Blend::SourceAlpha; static PBlendState Additive();
blendState->_sourceAlpha = Blend::SourceAlpha; static PBlendState NonPremultiplied();
blendState->_destination = Blend::Zero;
blendState->_destinationAlpha = Blend::Zero; virtual bool Apply(GraphicsDevice* device) = 0;
return blendState;
}
static PBlendState AlphaBlend() {
auto blendState = New<BlendState>(nullptr);
blendState->_source = Blend::One;
blendState->_sourceAlpha = Blend::One;
blendState->_destination = Blend::InverseSourceAlpha;
blendState->_destinationAlpha = Blend::InverseSourceAlpha;
return blendState;
}
static PBlendState Additive() {
auto blendState = New<BlendState>(nullptr);
blendState->_source = Blend::SourceAlpha;
blendState->_sourceAlpha = Blend::SourceAlpha;
blendState->_destination = Blend::One;
blendState->_destinationAlpha = Blend::One;
return blendState;
}
static PBlendState NonPremultiplied() {
auto blendState = New<BlendState>(nullptr);
blendState->_source = Blend::SourceAlpha;
blendState->_sourceAlpha = Blend::SourceAlpha;
blendState->_destination = Blend::InverseSourceAlpha;
blendState->_destinationAlpha = Blend::InverseSourceAlpha;
return blendState;
}
PLATFORM_DEVELOPMENT
bool Apply(GraphicsDevice* device);
public: public:
bool _alphaToCoverage{ false }; bool _alphaToCoverage{ false };
@ -64,13 +27,7 @@ namespace xna {
Blend _destinationAlpha{ Blend::Zero }; Blend _destinationAlpha{ Blend::Zero };
BlendOperation _operationAlpha{ BlendOperation::Add }; BlendOperation _operationAlpha{ BlendOperation::Add };
ColorWriteChannels _writeMask{ ColorWriteChannels::All }; ColorWriteChannels _writeMask{ ColorWriteChannels::All };
GraphicsDevice* _device{nullptr}; };
public:
class InternalProperty;
friend class InternalProperty;
sptr<InternalProperty> ip_BlendState{ nullptr };
};
} }
#endif #endif

View File

@ -12,22 +12,12 @@
#include "blendstate.hpp" #include "blendstate.hpp"
namespace xna { namespace xna {
class GraphicsDevice : public std::enable_shared_from_this<GraphicsDevice> { class IGraphicsDevice {
public: public:
PLATFORM_DEVELOPMENT virtual ~IGraphicsDevice() {}
GraphicsDevice(); virtual void Clear() = 0;
virtual bool Initialize(GameWindow& gameWindow) = 0;
PLATFORM_DEVELOPMENT virtual bool Present() = 0;
void Clear();
PLATFORM_DEVELOPMENT
void Clear(Color const& color);
PLATFORM_DEVELOPMENT
bool Initialize(GameWindow& gameWindow);
PLATFORM_DEVELOPMENT
bool Present();
PGraphicsAdapter Adapter() const { PGraphicsAdapter Adapter() const {
return _adapter; return _adapter;
@ -35,7 +25,7 @@ namespace xna {
void Adapter(PGraphicsAdapter const& adapter) { void Adapter(PGraphicsAdapter const& adapter) {
_adapter = adapter; _adapter = adapter;
} }
constexpr xna::Viewport Viewport() const { constexpr xna::Viewport Viewport() const {
return _viewport; return _viewport;
@ -49,17 +39,17 @@ namespace xna {
return _swapChain; return _swapChain;
} }
private: constexpr void UseVSync(bool use) {
_usevsync = use;
}
protected:
PGraphicsAdapter _adapter{ nullptr }; PGraphicsAdapter _adapter{ nullptr };
PSwapChain _swapChain{ nullptr }; PSwapChain _swapChain{ nullptr };
PRenderTarget2D _renderTarget2D{ nullptr }; PRenderTarget2D _renderTarget2D{ nullptr };
xna::Viewport _viewport{}; xna::Viewport _viewport{};
PBlendState _blendState{ nullptr }; PBlendState _blendState{ nullptr };
bool _usevsync{ false };
public:
class InternalProperty;
friend class InternalProperty;
sptr<InternalProperty> ip_GraphicsDevice{ nullptr };
}; };
} }

View File

@ -5,21 +5,15 @@
namespace xna { namespace xna {
class RenderTarget2D : public Texture2D { class IRenderTarget2D {
public: public:
RenderTarget2D(GraphicsDevice* device); virtual ~IRenderTarget2D(){}
PLATFORM_DEVELOPMENT virtual bool Apply() = 0;
bool Apply();
private: protected:
GraphicsDevice* _device; GraphicsDevice* _device{nullptr};
};
public:
class InternalProperty;
friend class InternalProperty;
sptr<InternalProperty> ip_RenderTarget2D{ nullptr };
};
} }
#endif #endif

View File

@ -7,25 +7,12 @@
#include "../game/window.hpp" #include "../game/window.hpp"
namespace xna { namespace xna {
class SwapChain { class ISwapChain {
public: public:
PLATFORM_DEVELOPMENT virtual ~ISwapChain() {}
SwapChain(GraphicsDevice* device); virtual bool Initialize(GameWindow const& gameWindow) = 0;
virtual bool Apply() = 0;
PLATFORM_DEVELOPMENT };
bool Initialize(GameWindow const& gameWindow);
PLATFORM_DEVELOPMENT
bool Apply();
private:
GraphicsDevice* _device{ nullptr };
public:
class InternalProperty;
friend class InternalProperty;
sptr<InternalProperty> ip_SwapChain{ nullptr };
};
} }
#endif #endif

View File

@ -9,15 +9,9 @@ namespace xna {
class Texture { class Texture {
}; };
class Texture2D : public Texture { class ITexture2D {
public: public:
PLATFORM_DEVELOPMENT virtual ~ITexture2D(){}
Texture2D();
public:
class InternalProperty;
friend class InternalProperty;
sptr<InternalProperty> ip_Texture2D{ nullptr };
}; };
} }

View File

@ -2,33 +2,26 @@
#include "../helpers.hpp" #include "../helpers.hpp"
namespace xna { namespace xna {
GraphicsAdapter::GraphicsAdapter() {
ip_GraphicsAdapter = New<InternalProperty>();
}
String GraphicsAdapter::Description() const { String GraphicsAdapter::Description() const {
auto& p = ip_GraphicsAdapter;
DXGI_ADAPTER_DESC1 desc; DXGI_ADAPTER_DESC1 desc;
p->_adapter->GetDesc1(&desc); _adapter->GetDesc1(&desc);
String description = WStringToString(desc.Description); String description = WStringToString(desc.Description);
return description; return description;
} }
Uint GraphicsAdapter::DeviceId() const { Uint GraphicsAdapter::DeviceId() const {
auto& p = ip_GraphicsAdapter;
DXGI_ADAPTER_DESC1 desc; DXGI_ADAPTER_DESC1 desc;
p->_adapter->GetDesc1(&desc); _adapter->GetDesc1(&desc);
return static_cast<Uint>(desc.DeviceId); return static_cast<Uint>(desc.DeviceId);
} }
String GraphicsAdapter::DeviceName() const { String GraphicsAdapter::DeviceName() const {
auto& p = ip_GraphicsAdapter;
IDXGIOutput* pOutput = nullptr; IDXGIOutput* pOutput = nullptr;
DXGI_OUTPUT_DESC outputDesc; DXGI_OUTPUT_DESC outputDesc;
if (p->_adapter->EnumOutputs(0, &pOutput) != DXGI_ERROR_NOT_FOUND) { if (_adapter->EnumOutputs(0, &pOutput) != DXGI_ERROR_NOT_FOUND) {
pOutput->GetDesc(&outputDesc); pOutput->GetDesc(&outputDesc);
String deviceName = WStringToString(outputDesc.DeviceName); String deviceName = WStringToString(outputDesc.DeviceName);
@ -42,12 +35,10 @@ namespace xna {
} }
intptr_t GraphicsAdapter::MonitorHandle() const { intptr_t GraphicsAdapter::MonitorHandle() const {
auto& p = ip_GraphicsAdapter;
IDXGIOutput* pOutput = nullptr; IDXGIOutput* pOutput = nullptr;
DXGI_OUTPUT_DESC outputDesc; DXGI_OUTPUT_DESC outputDesc;
if (p->_adapter->EnumOutputs(0, &pOutput) != DXGI_ERROR_NOT_FOUND) { if (_adapter->EnumOutputs(0, &pOutput) != DXGI_ERROR_NOT_FOUND) {
pOutput->GetDesc(&outputDesc); pOutput->GetDesc(&outputDesc);
pOutput->Release(); pOutput->Release();
@ -60,37 +51,33 @@ namespace xna {
} }
Uint GraphicsAdapter::Revision() const { Uint GraphicsAdapter::Revision() const {
auto& p = ip_GraphicsAdapter;
DXGI_ADAPTER_DESC1 desc; DXGI_ADAPTER_DESC1 desc;
p->_adapter->GetDesc1(&desc); _adapter->GetDesc1(&desc);
return static_cast<Uint>(desc.Revision); return static_cast<Uint>(desc.Revision);
} }
Uint GraphicsAdapter::SubSystemId() const { Uint GraphicsAdapter::SubSystemId() const {
auto& p = ip_GraphicsAdapter;
DXGI_ADAPTER_DESC1 desc; DXGI_ADAPTER_DESC1 desc;
p->_adapter->GetDesc1(&desc); _adapter->GetDesc1(&desc);
return static_cast<Uint>(desc.SubSysId); return static_cast<Uint>(desc.SubSysId);
} }
Uint GraphicsAdapter::VendorId() const { Uint GraphicsAdapter::VendorId() const {
auto& p = ip_GraphicsAdapter;
DXGI_ADAPTER_DESC1 desc; DXGI_ADAPTER_DESC1 desc;
p->_adapter->GetDesc1(&desc); _adapter->GetDesc1(&desc);
return static_cast<Uint>(desc.VendorId); return static_cast<Uint>(desc.VendorId);
} }
PDisplayModeCollection GraphicsAdapter::SupportedDisplayModes() const { PDisplayModeCollection GraphicsAdapter::SupportedDisplayModes() const {
auto& p = ip_GraphicsAdapter;
IDXGIOutput* pOutput = nullptr; IDXGIOutput* pOutput = nullptr;
UINT numModes = 0; UINT numModes = 0;
UINT totalModes = 0; UINT totalModes = 0;
std::vector<DXGI_MODE_DESC> buffer(250); std::vector<DXGI_MODE_DESC> buffer(250);
if (p->_adapter->EnumOutputs(0, &pOutput) != DXGI_ERROR_NOT_FOUND) { if (_adapter->EnumOutputs(0, &pOutput) != DXGI_ERROR_NOT_FOUND) {
for (size_t f = 0; f < SURFACE_FORMAT_COUNT; ++f) { for (size_t f = 0; f < SURFACE_FORMAT_COUNT; ++f) {
const auto currentSurface = static_cast<SurfaceFormat>(f); const auto currentSurface = static_cast<SurfaceFormat>(f);
DXGI_FORMAT format = SurfaceFormatMapper::ParseToDXGI(currentSurface); DXGI_FORMAT format = SurfaceFormatMapper::ParseToDXGI(currentSurface);
@ -100,8 +87,8 @@ namespace xna {
if (numModes == 0) if (numModes == 0)
continue; continue;
if (buffer.size() < totalModes + numModes) if (buffer.size() < static_cast<size_t>(totalModes) + numModes)
buffer.resize(totalModes * 2); buffer.resize(static_cast<size_t>(totalModes * 2));
pOutput->GetDisplayModeList(format, 0, &numModes, buffer.data() + totalModes); pOutput->GetDisplayModeList(format, 0, &numModes, buffer.data() + totalModes);
@ -127,7 +114,7 @@ namespace xna {
return New<DisplayModeCollection>(); return New<DisplayModeCollection>();
} }
std::vector<PGraphicsAdapter> GraphicsAdapter::getAllAdapters() { std::vector<PGraphicsAdapter> IGraphicsAdapter::getAllAdapters() {
IDXGIFactory1* pFactory = nullptr; IDXGIFactory1* pFactory = nullptr;
std::vector<PGraphicsAdapter> adapters; std::vector<PGraphicsAdapter> adapters;
@ -140,9 +127,10 @@ namespace xna {
for (; pFactory->EnumAdapters1(count, &pAdapter) != DXGI_ERROR_NOT_FOUND; ++count) { for (; pFactory->EnumAdapters1(count, &pAdapter) != DXGI_ERROR_NOT_FOUND; ++count) {
auto adp = New<GraphicsAdapter>(); auto adp = New<GraphicsAdapter>();
const auto& p = adp->ip_GraphicsAdapter;
adp->_index = count;
adp->_adapter = pAdapter;
p->_adapter = pAdapter;
adapters.push_back(adp); adapters.push_back(adp);
} }

View File

@ -6,23 +6,29 @@
#include "d3d11.h" #include "d3d11.h"
namespace xna { namespace xna {
class GraphicsAdapter::InternalProperty { class GraphicsAdapter : public IGraphicsAdapter {
friend class GraphicsAdapter;
public: public:
InternalProperty() { GraphicsAdapter() {}
}
~InternalProperty() { virtual ~GraphicsAdapter() override {
if (_adapter) { if (_adapter) {
_adapter->Release(); _adapter->Release();
_adapter = nullptr; _adapter = nullptr;
} }
} }
virtual String Description() const override;
virtual Uint DeviceId() const override;
virtual String DeviceName() const override;
virtual intptr_t MonitorHandle() const override;
virtual Uint Revision() const override;
virtual Uint SubSystemId() const override;
virtual Uint VendorId() const override;
virtual PDisplayModeCollection SupportedDisplayModes() const override;
public: public:
IDXGIAdapter1* _adapter{ nullptr }; IDXGIAdapter1* _adapter{ nullptr };
}; };
struct SurfaceFormatMapper { struct SurfaceFormatMapper {
static constexpr DXGI_FORMAT ParseToDXGI(SurfaceFormat format) static constexpr DXGI_FORMAT ParseToDXGI(SurfaceFormat format)

View File

@ -2,8 +2,8 @@
#include "device-dx.hpp" #include "device-dx.hpp"
namespace xna { namespace xna {
BlendState::BlendState(GraphicsDevice* device) : _device(device) { BlendState::BlendState(GraphicsDevice* device) {
ip_BlendState = New<InternalProperty>(); _device = device;
} }
bool BlendState::Apply(GraphicsDevice* device) { bool BlendState::Apply(GraphicsDevice* device) {
@ -23,12 +23,51 @@ namespace xna {
if (_device == nullptr || _device != device) if (_device == nullptr || _device != device)
_device = device; _device = device;
auto& p = _device->ip_GraphicsDevice; if FAILED(_device->_device->CreateBlendState(&blendDesc, &_blendState))
if FAILED(p->_device->CreateBlendState(&blendDesc, &ip_BlendState->_blendState))
return false; return false;
p->_context->OMSetBlendState(ip_BlendState->_blendState, nullptr, 0xffffffff); _device->_context->OMSetBlendState(_blendState, nullptr, 0xffffffff);
return true; return true;
} }
PBlendState IBlendState::Opaque() {
auto blendState = New<BlendState>(nullptr);
blendState->_source = Blend::SourceAlpha;
blendState->_sourceAlpha = Blend::SourceAlpha;
blendState->_destination = Blend::Zero;
blendState->_destinationAlpha = Blend::Zero;
return blendState;
}
PBlendState IBlendState::AlphaBlend() {
auto blendState = New<BlendState>(nullptr);
blendState->_source = Blend::One;
blendState->_sourceAlpha = Blend::One;
blendState->_destination = Blend::InverseSourceAlpha;
blendState->_destinationAlpha = Blend::InverseSourceAlpha;
return blendState;
}
PBlendState IBlendState::Additive() {
auto blendState = New<BlendState>(nullptr);
blendState->_source = Blend::SourceAlpha;
blendState->_sourceAlpha = Blend::SourceAlpha;
blendState->_destination = Blend::One;
blendState->_destinationAlpha = Blend::One;
return blendState;
}
PBlendState IBlendState::NonPremultiplied() {
auto blendState = New<BlendState>(nullptr);
blendState->_source = Blend::SourceAlpha;
blendState->_sourceAlpha = Blend::SourceAlpha;
blendState->_destination = Blend::InverseSourceAlpha;
blendState->_destinationAlpha = Blend::InverseSourceAlpha;
return blendState;
}
} }

View File

@ -6,20 +6,23 @@
#include "d3d11.h" #include "d3d11.h"
namespace xna { namespace xna {
class BlendState::InternalProperty { class BlendState : public IBlendState {
friend class BlendState;
friend class GraphicsDevice;
public: public:
~InternalProperty() { BlendState(GraphicsDevice* device);
virtual ~BlendState() override {
if (_blendState) { if (_blendState) {
_blendState->Release(); _blendState->Release();
_blendState = nullptr; _blendState = nullptr;
} }
} }
private: virtual bool Apply(GraphicsDevice* device) override;
ID3D11BlendState* _blendState{ nullptr };
}; public:
ID3D11BlendState* _blendState{ nullptr };
GraphicsDevice* _device{ nullptr };
};
struct BlendMapper { struct BlendMapper {
static constexpr D3D11_BLEND ConvertBlend(Blend blend) { static constexpr D3D11_BLEND ConvertBlend(Blend blend) {

View File

@ -3,28 +3,25 @@
#include "swapchain-dx.hpp" #include "swapchain-dx.hpp"
#include "rendertarget-dx.hpp" #include "rendertarget-dx.hpp"
#include "adapter-dx.hpp" #include "adapter-dx.hpp"
#include "blendstate-dx.hpp"
namespace xna { namespace xna {
GraphicsDevice::GraphicsDevice() { GraphicsDevice::GraphicsDevice() {
_adapter = New<GraphicsAdapter>();
_blendState = BlendState::NonPremultiplied(); _blendState = BlendState::NonPremultiplied();
_adapter = GraphicsAdapter::DefaultAdapter(); _adapter = GraphicsAdapter::DefaultAdapter();
ip_GraphicsDevice = New<InternalProperty>();
} }
bool GraphicsDevice::Initialize(GameWindow& gameWindow) { bool GraphicsDevice::Initialize(GameWindow& gameWindow) {
auto& p = ip_GraphicsDevice; _createDeviceFlags |= D3D11_CREATE_DEVICE_DEBUG;
p->_createDeviceFlags |= D3D11_CREATE_DEVICE_DEBUG;
if (p->_device) { if (_device) {
p->_device->Release(); _device->Release();
p->_device = nullptr; _device = nullptr;
} }
if (p->_context) { if (_context) {
p->_context->Release(); _context->Release();
p->_context = nullptr; _context = nullptr;
} }
const auto bounds = gameWindow.ClientBounds(); const auto bounds = gameWindow.ClientBounds();
@ -33,43 +30,14 @@ namespace xna {
static_cast<float>(bounds.Height), static_cast<float>(bounds.Height),
0.0F, 1.F); 0.0F, 1.F);
if FAILED( if (!createDevice())
D3D11CreateDevice( return false;
_adapter->ip_GraphicsAdapter->_adapter, // adaptador de vídeo (NULL = adaptador padrão)
D3D_DRIVER_TYPE_HARDWARE, // tipo de driver D3D (Hardware, Reference ou Software)
NULL, // ponteiro para rasterizador em software
p->_createDeviceFlags, // modo de depuração ou modo normal
NULL, // featureLevels do Direct3D (NULL = maior suportada)
0, // tamanho do vetor featureLevels
D3D11_SDK_VERSION, // versão do SDK do Direct3D
&p->_device, // guarda o dispositivo D3D criado
&p->_featureLevel, // versão do Direct3D utilizada
&p->_context)) // contexto do dispositivo D3D
{
// sistema não suporta dispositivo D3D11
// fazendo a criação de um WARP Device que
// implementa um rasterizador em software
if FAILED(D3D11CreateDevice(
NULL,
D3D_DRIVER_TYPE_WARP,
NULL,
p->_createDeviceFlags,
NULL,
0,
D3D11_SDK_VERSION,
&p->_device,
&p->_featureLevel,
&p->_context))
return false;
OutputDebugString("---> Usando Adaptador WARP: não há suporte ao D3D11\n"); COLORREF color = gameWindow.Color();
} _backgroundColor[0] = GetRValue(color) / 255.0f;
_backgroundColor[1] = GetGValue(color) / 255.0f;
COLORREF color = gameWindow.ip_GameWindow->Color(); _backgroundColor[2] = GetBValue(color) / 255.0f;
p->_backgroundColor[0] = GetRValue(color) / 255.0f; _backgroundColor[3] = 1.0f;
p->_backgroundColor[1] = GetGValue(color) / 255.0f;
p->_backgroundColor[2] = GetBValue(color) / 255.0f;
p->_backgroundColor[3] = 1.0f;
if (!_swapChain) if (!_swapChain)
_swapChain = New<xna::SwapChain>(this); _swapChain = New<xna::SwapChain>(this);
@ -83,7 +51,7 @@ namespace xna {
if FAILED(CreateDXGIFactory1(__uuidof(IDXGIFactory1), (void**)&dxgiFactory)) if FAILED(CreateDXGIFactory1(__uuidof(IDXGIFactory1), (void**)&dxgiFactory))
return false; return false;
if FAILED(dxgiFactory->MakeWindowAssociation(gameWindow.ip_GameWindow->WindowHandle(), DXGI_MWA_NO_ALT_ENTER)) if FAILED(dxgiFactory->MakeWindowAssociation(gameWindow.WindowHandle(), DXGI_MWA_NO_ALT_ENTER))
return false; return false;
if (!_renderTarget2D) { if (!_renderTarget2D) {
@ -101,7 +69,7 @@ namespace xna {
view.MinDepth = _viewport.MinDetph; view.MinDepth = _viewport.MinDetph;
view.MaxDepth = _viewport.MaxDepth; view.MaxDepth = _viewport.MaxDepth;
p->_context->RSSetViewports(1, &view); _context->RSSetViewports(1, &view);
_blendState->Apply(this); _blendState->Apply(this);
@ -109,19 +77,57 @@ namespace xna {
} }
bool GraphicsDevice::Present() { bool GraphicsDevice::Present() {
_swapChain->ip_SwapChain->_swapChain->Present(false, NULL); _swapChain->_swapChain->Present(_usevsync, NULL);
auto& p = ip_GraphicsDevice; _context->OMSetRenderTargets(1, &_renderTarget2D->_renderTargetView, nullptr);
auto& pr = _renderTarget2D->ip_RenderTarget2D;
p->_context->OMSetRenderTargets(1, &pr->_renderTargetView, nullptr);
return true; return true;
} }
void GraphicsDevice::Clear() { bool GraphicsDevice::GetSwapChainBackBuffer(ID3D11Texture2D*& texture2D) {
auto& p = ip_GraphicsDevice; if FAILED(_swapChain->_swapChain->GetBuffer(0, __uuidof(texture2D), (void**)(&texture2D)))
auto& pr = _renderTarget2D->ip_RenderTarget2D; return false;
p->_context->ClearRenderTargetView(pr->_renderTargetView, p->_backgroundColor); return true;
}
bool GraphicsDevice::createDevice() {
#if _DEBUG
_createDeviceFlags |= D3D11_CREATE_DEVICE_FLAG::D3D11_CREATE_DEVICE_DEBUG;
#endif
if FAILED(
D3D11CreateDevice(
_adapter->_adapter,
D3D_DRIVER_TYPE_UNKNOWN,
NULL,
_createDeviceFlags,
NULL,
0,
D3D11_SDK_VERSION,
&_device,
&_featureLevel,
&_context)) {
if FAILED(D3D11CreateDevice(
NULL,
D3D_DRIVER_TYPE_WARP,
NULL,
_createDeviceFlags,
NULL,
0,
D3D11_SDK_VERSION,
&_device,
&_featureLevel,
&_context))
return false;
OutputDebugString("---> Usando Adaptador WARP: não há suporte ao D3D11\n");
}
return true;
}
void GraphicsDevice::Clear() {
_context->ClearRenderTargetView(_renderTarget2D->_renderTargetView, _backgroundColor);
} }
} }

View File

@ -6,13 +6,11 @@
#include "d3d11.h" #include "d3d11.h"
namespace xna { namespace xna {
class GraphicsDevice::InternalProperty { class GraphicsDevice : public IGraphicsDevice {
friend class GraphicsDevice;
public: public:
InternalProperty() {} GraphicsDevice();
~InternalProperty() { virtual ~GraphicsDevice() override {
if (_device) { if (_device) {
_device->Release(); _device->Release();
_device = nullptr; _device = nullptr;
@ -24,6 +22,10 @@ namespace xna {
} }
} }
virtual void Clear() override;
virtual bool Initialize(GameWindow& gameWindow) override;
virtual bool Present() override;
constexpr void SetCreateFlags(D3D11_CREATE_DEVICE_FLAG flags) { constexpr void SetCreateFlags(D3D11_CREATE_DEVICE_FLAG flags) {
_createDeviceFlags |= flags; _createDeviceFlags |= flags;
} }
@ -32,6 +34,8 @@ namespace xna {
_createDeviceFlags = 0; _createDeviceFlags = 0;
} }
bool GetSwapChainBackBuffer(ID3D11Texture2D*& texture2D);
public: public:
ID3D11Device* _device{ nullptr }; ID3D11Device* _device{ nullptr };
ID3D11DeviceContext* _context{ nullptr }; ID3D11DeviceContext* _context{ nullptr };
@ -40,7 +44,9 @@ namespace xna {
unsigned int _createDeviceFlags{ 0 }; unsigned int _createDeviceFlags{ 0 };
D3D_FEATURE_LEVEL _featureLevel{ D3D_FEATURE_LEVEL::D3D_FEATURE_LEVEL_11_0 }; D3D_FEATURE_LEVEL _featureLevel{ D3D_FEATURE_LEVEL::D3D_FEATURE_LEVEL_11_0 };
float _backgroundColor[4] = { 0, 0, 0, 0 }; float _backgroundColor[4] = { 0, 0, 0, 0 };
};
bool createDevice();
};
} }
#endif #endif

View File

@ -0,0 +1,50 @@
#include "game-dx.hpp"
#include "window-dx.hpp"
#include "device-dx.hpp"
#include "Windows.h"
namespace xna {
Game::Game() {
_gameWindow = New<GameWindow>();
_gameWindow->Color(255, 155, 55);
_gameWindow->Title("Teste de título");
_graphicsDevice = New<GraphicsDevice>();
}
int Game::Run() {
if (!_gameWindow->Create()) {
MessageBox(nullptr, "Falha na criação da janela", "Xna Game Engine", MB_OK);
return EXIT_FAILURE;
}
if (!_graphicsDevice->Initialize(*_gameWindow)) {
MessageBox(nullptr, "Falha na inicialização do dispositivo gráfico", "Xna Game Engine", MB_OK);
return EXIT_FAILURE;
}
return startLoop();
}
int Game::startLoop() {
MSG msg{};
do {
if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
else {
GameTime gt;
this->Update(gt);
_graphicsDevice->Clear();
this->Draw(gt);
_graphicsDevice->Present();
}
} while (msg.message != WM_QUIT);
return msg.wParam;
}
}

View File

@ -0,0 +1,32 @@
#ifndef XNA_PLATFORM_GAME_DX_HPP
#define XNA_PLATFORM_GAME_DX_HPP
#include "../game/game.hpp"
#include "dxgi.h"
#include "d3d11.h"
namespace xna {
class Game : public IGame {
public:
Game();
virtual ~Game() override {
}
virtual void Exit() override{}
virtual int Run() override;
protected:
virtual void Draw(GameTime const& gameTime) override{}
virtual void Initialize() override{}
virtual void Update(GameTime const& gameTime) override{}
private:
PGameWindow _gameWindow{ nullptr };
PGraphicsDevice _graphicsDevice{ nullptr };
int startLoop();
};
}
#endif

View File

@ -4,30 +4,26 @@
#include "device-dx.hpp" #include "device-dx.hpp"
namespace xna { namespace xna {
RenderTarget2D::RenderTarget2D(GraphicsDevice* device) : _device(device) { RenderTarget2D::RenderTarget2D(GraphicsDevice* device) {
this->ip_RenderTarget2D = New<InternalProperty>(); _device = device;
} }
bool RenderTarget2D::Apply() { bool RenderTarget2D::Apply() {
auto& p1 = this->ip_Texture2D; if (_texture2D) {
auto swapChain = _device->GetSwapChain(); _texture2D->Release();
_texture2D = nullptr;
if (p1->_texture2D) {
p1->_texture2D->Release();
p1->_texture2D = nullptr;
} }
if (!swapChain->ip_SwapChain->GetBackBuffer(p1->_texture2D)) if (!_device->GetSwapChainBackBuffer(_texture2D))
return false; return false;
auto& device = _device->ip_GraphicsDevice->_device; auto& device = _device->_device;
auto& p2 = this->ip_RenderTarget2D;
if FAILED(device->CreateRenderTargetView(p1->_texture2D, NULL, &p2->_renderTargetView)) if FAILED(device->CreateRenderTargetView(_texture2D, NULL, &_renderTargetView))
return false; return false;
auto& context = _device->ip_GraphicsDevice->_context; auto& context = _device->_context;
context->OMSetRenderTargets(1, &p2->_renderTargetView, nullptr); context->OMSetRenderTargets(1, &_renderTargetView, nullptr);
return true; return true;
} }

View File

@ -7,13 +7,21 @@
#include "d3d11.h" #include "d3d11.h"
namespace xna { namespace xna {
class RenderTarget2D::InternalProperty { class RenderTarget2D : public IRenderTarget2D, public Texture2D {
friend class RenderTarget2D;
friend class GraphicsDevice;
public: public:
RenderTarget2D(GraphicsDevice* device);
private: virtual ~RenderTarget2D() override {
ID3D11RenderTargetView* _renderTargetView; if (_renderTargetView) {
_renderTargetView->Release();
_renderTargetView = nullptr;
}
}
virtual bool Apply() override;
public:
ID3D11RenderTargetView* _renderTargetView = nullptr;
}; };
} }

View File

@ -4,46 +4,41 @@
#include "device-dx.hpp" #include "device-dx.hpp"
namespace xna { namespace xna {
SwapChain::SwapChain(GraphicsDevice* device) : SwapChain::SwapChain(GraphicsDevice* device){
_device(device) { _device = device;
ip_SwapChain = New<InternalProperty>();
} }
bool SwapChain::Initialize(GameWindow const& gameWindow) { bool SwapChain::Initialize(GameWindow const& gameWindow) {
auto& p = ip_SwapChain;
const auto bounds = gameWindow.ClientBounds(); const auto bounds = gameWindow.ClientBounds();
p->_swapDescription.BufferDesc.Width = static_cast<UINT>(bounds.Width); _swapDescription.BufferDesc.Width = static_cast<UINT>(bounds.Width);
p->_swapDescription.BufferDesc.Height = static_cast<UINT>(bounds.Height); _swapDescription.BufferDesc.Height = static_cast<UINT>(bounds.Height);
p->_swapDescription.BufferDesc.RefreshRate.Numerator = 60; _swapDescription.BufferDesc.RefreshRate.Numerator = 60;
p->_swapDescription.BufferDesc.RefreshRate.Denominator = 1; _swapDescription.BufferDesc.RefreshRate.Denominator = 1;
p->_swapDescription.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; _swapDescription.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
p->_swapDescription.SampleDesc.Count = 1; _swapDescription.SampleDesc.Count = 1;
p->_swapDescription.SampleDesc.Quality = 0; _swapDescription.SampleDesc.Quality = 0;
p->_swapDescription.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; _swapDescription.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
p->_swapDescription.BufferCount = 2; _swapDescription.BufferCount = 2;
p->_swapDescription.OutputWindow = gameWindow.ip_GameWindow->WindowHandle(); _swapDescription.OutputWindow = gameWindow.WindowHandle();
p->_swapDescription.Windowed = gameWindow.ip_GameWindow->Mode() != GameWindowMode::Fullscreen; _swapDescription.Windowed = gameWindow.Mode() != GameWindowMode::Fullscreen;
p->_swapDescription.SwapEffect = DXGI_SWAP_EFFECT_FLIP_DISCARD; _swapDescription.SwapEffect = DXGI_SWAP_EFFECT_FLIP_DISCARD;
p->_swapDescription.Flags = DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH; _swapDescription.Flags = DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH;
return true; return true;
} }
bool SwapChain::Apply() { bool SwapChain::Apply() {
auto& p = ip_SwapChain;
auto adapter = _device->Adapter(); auto adapter = _device->Adapter();
auto dxAdapter = adapter->ip_GraphicsAdapter->_adapter; auto dxAdapter = adapter->_adapter;
IDXGIFactory* dxFactory = nullptr; IDXGIFactory* dxFactory = nullptr;
if FAILED(dxAdapter->GetParent(__uuidof(IDXGIFactory), (void**)&dxFactory)) if FAILED(dxAdapter->GetParent(__uuidof(IDXGIFactory), (void**)&dxFactory))
return false; return false;
auto dxdevice = _device->ip_GraphicsDevice->_device; auto dxdevice = _device->_device;
if FAILED(dxFactory->CreateSwapChain(dxdevice, &p->_swapDescription, &p->_swapChain)) if FAILED(dxFactory->CreateSwapChain(dxdevice, &_swapDescription, &_swapChain))
return false; return false;
dxFactory->Release(); dxFactory->Release();

View File

@ -7,19 +7,20 @@
#include "d3d11.h" #include "d3d11.h"
namespace xna { namespace xna {
class SwapChain::InternalProperty { class SwapChain : public ISwapChain{
friend class SwapChain;
friend class GraphicsDevice;
public: public:
InternalProperty(){} SwapChain(GraphicsDevice* device);
~InternalProperty() { virtual ~SwapChain() override {
if (_swapChain) { if (_swapChain) {
_swapChain->Release(); _swapChain->Release();
_swapChain = nullptr; _swapChain = nullptr;
} }
} }
virtual bool Initialize(GameWindow const& gameWindow) override;
virtual bool Apply() override;
bool GetBackBuffer(ID3D11Texture2D*& texture2D) { bool GetBackBuffer(ID3D11Texture2D*& texture2D) {
if FAILED(_swapChain->GetBuffer(0, __uuidof(texture2D), (void**)(&texture2D))) if FAILED(_swapChain->GetBuffer(0, __uuidof(texture2D), (void**)(&texture2D)))
return false; return false;
@ -27,10 +28,11 @@ namespace xna {
return true; return true;
} }
private: public:
IDXGISwapChain* _swapChain{nullptr}; IDXGISwapChain* _swapChain{ nullptr };
DXGI_SWAP_CHAIN_DESC _swapDescription{}; DXGI_SWAP_CHAIN_DESC _swapDescription{};
}; GraphicsDevice* _device{ nullptr };
};
} }
#endif #endif

View File

@ -1,7 +1,6 @@
#include "texture-dx.hpp" #include "texture-dx.hpp"
namespace xna { namespace xna {
Texture2D::Texture2D() { Texture2D::Texture2D() {
ip_Texture2D = New<InternalProperty>();
} }
} }

View File

@ -6,13 +6,18 @@
#include "d3d11.h" #include "d3d11.h"
namespace xna { namespace xna {
class Texture2D::InternalProperty { class Texture2D : public ITexture2D {
friend class Texture2D; public:
friend class GraphicsDevice; Texture2D();
friend class RenderTarget2D;
public:
private: virtual ~Texture2D() override {
if (_texture2D) {
_texture2D->Release();
_texture2D = nullptr;
}
}
public:
ID3D11Texture2D* _texture2D{nullptr}; ID3D11Texture2D* _texture2D{nullptr};
}; };
} }

View File

@ -2,30 +2,27 @@
namespace xna { namespace xna {
GameWindow::GameWindow() { GameWindow::GameWindow() {
ip_GameWindow = New<InternalProperty>(this); _hInstance = GetModuleHandle(NULL);
auto& p = ip_GameWindow; _windowIcon = LoadIcon(NULL, IDI_APPLICATION);
_windowCursor = LoadCursor(NULL, IDC_ARROW);
_windowStyle = static_cast<int>(GameWindowMode::Windowed);
_windowCenterX = _windowWidth / 2.0F;
_windowCenterY = _windowHeight / 2.0F;
p->_hInstance = GetModuleHandle(NULL); }
p->_windowIcon = LoadIcon(NULL, IDI_APPLICATION);
p->_windowCursor = LoadCursor(NULL, IDC_ARROW); void GameWindow::Size(int width, int height) {
p->_windowStyle = static_cast<int>(GameWindowMode::Windowed); _windowWidth = width;
p->_windowCenterX = p->_windowWidth / 2.0F; _windowHeight = height;
p->_windowCenterY = p->_windowHeight / 2.0F; setPosition();
setCenter();
} }
void GameWindow::Title(String const& title) { void GameWindow::Title(String const& title) {
ip_GameWindow->_windowTitle = title; _windowTitle = title;
} }
void GameWindow::InternalProperty::Size(int width, int height) { bool GameWindow::Create() {
_windowWidth = width;
_windowHeight = height;
setCenter();
setPosition();
}
bool GameWindow::InternalProperty::Create() {
WNDCLASSEX wndClass{}; WNDCLASSEX wndClass{};
wndClass.cbSize = sizeof(WNDCLASSEX); wndClass.cbSize = sizeof(WNDCLASSEX);
wndClass.style = CS_DBLCLKS | CS_OWNDC | CS_HREDRAW | CS_VREDRAW; wndClass.style = CS_DBLCLKS | CS_OWNDC | CS_HREDRAW | CS_VREDRAW;
@ -75,27 +72,29 @@ namespace xna {
TRUE); TRUE);
return _windowHandle ? true : false; return _windowHandle ? true : false;
} }
return true;
} }
String GameWindow::Title() const { String GameWindow::Title() const {
return ip_GameWindow->_windowTitle; return _windowTitle;
} }
Rectangle GameWindow::ClientBounds() const { Rectangle GameWindow::ClientBounds() const {
return Rectangle( return Rectangle(
ip_GameWindow->_windowPosX, _windowPosX,
ip_GameWindow->_windowPosY, _windowPosY,
ip_GameWindow->_windowWidth, _windowWidth,
ip_GameWindow->_windowHeight _windowHeight
); );
} }
intptr_t GameWindow::Handle() const { intptr_t GameWindow::Handle() const {
return reinterpret_cast<intptr_t>(ip_GameWindow->_windowHandle); return reinterpret_cast<intptr_t>(_windowHandle);
} }
LRESULT GameWindow::InternalProperty::WinProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) LRESULT GameWindow::WinProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{ {
switch (msg) { switch (msg) {
case WM_DESTROY: case WM_DESTROY:

View File

@ -13,11 +13,9 @@ namespace xna {
Borderless = WS_EX_TOPMOST | WS_POPUP | WS_VISIBLE, Borderless = WS_EX_TOPMOST | WS_POPUP | WS_VISIBLE,
}; };
class GameWindow::InternalProperty { class GameWindow : public IGameWindow {
friend class GameWindow;
public: public:
InternalProperty(GameWindow* gamewindow) : GameWindow();
_gamewindow(gamewindow){}
constexpr void Mode(GameWindowMode mode) { constexpr void Mode(GameWindowMode mode) {
_windowStyle = static_cast<int>(mode); _windowStyle = static_cast<int>(mode);
@ -52,7 +50,7 @@ namespace xna {
inline void Icon(HICON icon) { inline void Icon(HICON icon) {
_windowIcon = icon; _windowIcon = icon;
} }
inline void Cursor(unsigned int cursor) { inline void Cursor(unsigned int cursor) {
_windowCursor = LoadCursor(GetModuleHandle(NULL), MAKEINTRESOURCE(cursor)); _windowCursor = LoadCursor(GetModuleHandle(NULL), MAKEINTRESOURCE(cursor));
} }
@ -81,7 +79,7 @@ namespace xna {
return _windowColor; return _windowColor;
} }
inline void Color(COLORREF color) { inline void Color(COLORREF color) {
_windowColor = color; _windowColor = color;
} }
@ -92,7 +90,12 @@ namespace xna {
bool Create(); bool Create();
static LRESULT CALLBACK WinProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam); static LRESULT CALLBACK WinProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
private: virtual String Title() const override;
virtual void Title(String const& title) override;
virtual Rectangle ClientBounds() const override;
virtual intptr_t Handle() const override;
private:
HINSTANCE _hInstance{ nullptr }; HINSTANCE _hInstance{ nullptr };
HWND _windowHandle{ nullptr }; HWND _windowHandle{ nullptr };
int _windowWidth{ 800 }; int _windowWidth{ 800 };
@ -108,8 +111,6 @@ namespace xna {
float _windowCenterY{ 0 }; float _windowCenterY{ 0 };
private: private:
GameWindow* _gamewindow = nullptr;
inline void setPosition() { inline void setPosition() {
_windowPosX = GetSystemMetrics(SM_CXSCREEN) / 2 - _windowWidth / 2; _windowPosX = GetSystemMetrics(SM_CXSCREEN) / 2 - _windowWidth / 2;
_windowPosY = GetSystemMetrics(SM_CYSCREEN) / 2 - _windowHeight / 2; _windowPosY = GetSystemMetrics(SM_CYSCREEN) / 2 - _windowHeight / 2;
@ -118,7 +119,7 @@ namespace xna {
inline void setCenter() { inline void setCenter() {
_windowCenterX = _windowWidth / 2.0f; _windowCenterX = _windowWidth / 2.0f;
_windowCenterY = _windowHeight / 2.0f; _windowCenterY = _windowHeight / 2.0f;
} }
}; };
} }

231
framework/timespan.hpp Normal file
View File

@ -0,0 +1,231 @@
#ifndef XNA_TIMESPAN_HPP
#define XNA_TIMESPAN_HPP
#include <limits>
#include <cstdint>
#include "types.hpp"
namespace xna {
struct TimeSpan {
static constexpr Long TicksPerMillisecond{ 10000 };
static constexpr Long TicksPerSecond{ TicksPerMillisecond * 1000 };
static constexpr Long TicksPerMinute{ TicksPerSecond * 60 };
static constexpr Long TicksPerHour{ TicksPerMinute * 60 };
static constexpr Long TicksPerDay{ TicksPerHour * 24 };
constexpr TimeSpan() = default;
constexpr TimeSpan(Long ticks) :
_ticks(ticks) {}
constexpr TimeSpan(Int hours, Int minutes, Int seconds) :
_ticks(TimeToTicks(hours, minutes, seconds)) {}
constexpr TimeSpan(Int days, Int hours, Int minutes, Int seconds) :
_ticks(DayToTicks(days, hours, minutes, seconds, 0)) {}
constexpr TimeSpan(Int days, Int hours, Int minutes, Int seconds, Int milliseconds) :
_ticks(DayToTicks(days, hours, minutes, seconds, milliseconds)) {}
constexpr TimeSpan operator -(TimeSpan const& t) {
return TimeSpan(-t._ticks);
}
constexpr TimeSpan operator +(TimeSpan const& t) {
return t;
}
constexpr friend TimeSpan operator +(TimeSpan const& t1, TimeSpan const& t2) {
return t1.Add(t2);
}
constexpr friend TimeSpan operator -(TimeSpan const& t1, TimeSpan const& t2) {
return t1.Subtract(t2);
}
constexpr friend bool operator ==(TimeSpan const& t1, TimeSpan const& t2) {
return t1._ticks == t2._ticks;
}
constexpr friend bool operator !=(TimeSpan const& t1, TimeSpan const& t2) {
return t1._ticks != t2._ticks;
}
constexpr friend bool operator <(TimeSpan const& t1, TimeSpan const& t2) {
return t1._ticks < t2._ticks;
}
constexpr friend bool operator <=(TimeSpan const& t1, TimeSpan const& t2) {
return t1._ticks <= t2._ticks;
}
constexpr friend bool operator >(TimeSpan const& t1, TimeSpan const& t2) {
return t1._ticks > t2._ticks;
}
constexpr friend bool operator >=(TimeSpan const& t1, TimeSpan const& t2) {
return t1._ticks >= t2._ticks;
}
static constexpr TimeSpan Zero() {
return TimeSpan();
}
static constexpr TimeSpan MaxValue() {
return TimeSpan(std::numeric_limits<Long>::max());
}
static constexpr TimeSpan MinValue() {
return TimeSpan(std::numeric_limits<Long>::min());
}
static constexpr Int Compare(TimeSpan const& t1, TimeSpan const& t2) {
if (t1._ticks > t2._ticks)
return 1;
if (t1._ticks < t2._ticks)
return -1;
return 0;
}
static constexpr TimeSpan FromDays(double value) {
return Interval(value, MillisPerDay);
}
static constexpr TimeSpan FromHours(double value) {
return Interval(value, MillisPerHour);
}
static constexpr TimeSpan Interval(double value, Int scale) {
double tmp = value * scale;
double millis = tmp + (value >= 0 ? 0.5 : -0.5);
return TimeSpan(static_cast<Long>(millis) * TicksPerMillisecond);
}
static constexpr TimeSpan FromMilliseconds(double value) {
return Interval(value, 1);
}
static constexpr TimeSpan FromMinutes(double value) {
return Interval(value, MillisPerMinute);
}
static constexpr TimeSpan FromSeconds(double value) {
return Interval(value, MillisPerSecond);
}
static constexpr TimeSpan FromTicks(Long value) {
return TimeSpan(value);
}
constexpr Long Ticks() const { return _ticks; }
constexpr Int Days() const { return static_cast<Int>(_ticks / TicksPerDay); }
constexpr Int Hours() const { return static_cast<Int>((_ticks / TicksPerHour) % 24); }
constexpr Int Milliseconds() const { return static_cast<Int>((_ticks / TicksPerMillisecond) % 1000); }
constexpr Int Minutes() const { return static_cast<Int>((_ticks / TicksPerMinute) % 60); }
constexpr Int Seconds() const { return static_cast<Int>((_ticks / TicksPerSecond) % 60); }
constexpr double TotalDays() const { return static_cast<double>(_ticks) * DaysPerTick; }
constexpr double TotalHours() const { return static_cast<double>(_ticks) * HoursPerTick; }
constexpr double TotalMilliseconds() const {
double temp = static_cast<double>(_ticks) * MillisecondsPerTick;
if (temp > MaxMilliSeconds)
return static_cast<double>(MaxMilliSeconds);
if (temp < MinMilliSeconds)
return static_cast<double>(MinMilliSeconds);
return temp;
}
constexpr double TotalMinutes() const { return static_cast<double>(_ticks) * MinutesPerTick; }
constexpr double TotalSeconds() const { return static_cast<double>(_ticks) * SecondsPerTick; }
constexpr TimeSpan Add(TimeSpan const& ts) const {
Long result = _ticks + ts._ticks;
if ((_ticks >> 63 == ts._ticks >> 63) && (_ticks >> 63 != result >> 63)) {
return TimeSpan(result, true);
}
return TimeSpan(result);
}
constexpr TimeSpan Duration() const {
if (Ticks() == TimeSpan::MinValue().Ticks()) {
return TimeSpan(Ticks(), true);
}
return TimeSpan(_ticks >= 0 ? _ticks : -_ticks);
}
constexpr bool Equals(TimeSpan other) const {
return _ticks == other._ticks;
}
constexpr TimeSpan Negate() const {
if (Ticks() == TimeSpan::MinValue().Ticks()) {
return TimeSpan(Ticks(), true);
}
return TimeSpan(-_ticks);
}
constexpr TimeSpan Subtract(TimeSpan const& ts) const {
Long result = _ticks - ts._ticks;
if ((_ticks >> 63 != ts._ticks >> 63) && (_ticks >> 63 != result >> 63)) {
return TimeSpan(result, true);
}
return TimeSpan(result);
}
constexpr bool HasOverflowException() {
return hasOverflowException;
}
private:
constexpr TimeSpan(Long ticks, bool overflow) :
_ticks(ticks),
hasOverflowException(overflow) {
}
static constexpr double MillisecondsPerTick = 1.0 / TicksPerMillisecond;
static constexpr double SecondsPerTick = 1.0 / TicksPerSecond;
static constexpr double MinutesPerTick = 1.0 / TicksPerMinute;
static constexpr double HoursPerTick = 1.0 / TicksPerHour;
static constexpr double DaysPerTick = 1.0 / TicksPerDay;
static constexpr Int MillisPerSecond = 1000;
static constexpr Int MillisPerMinute = MillisPerSecond * 60;
static constexpr Int MillisPerHour = MillisPerMinute * 60;
static constexpr Int MillisPerDay = MillisPerHour * 24;
static constexpr Long MaxSeconds = std::numeric_limits<Long>::max() / TicksPerSecond;
static constexpr Long MinSeconds = std::numeric_limits<Long>::min() / TicksPerSecond;
static constexpr Long MaxMilliSeconds = std::numeric_limits<Long>::max() / TicksPerMillisecond;
static constexpr Long MinMilliSeconds = std::numeric_limits<Long>::min() / TicksPerMillisecond;
static constexpr Long TicksPerTenthSecond = TicksPerMillisecond * 100;
bool hasOverflowException{ false };
Long _ticks{ 0 };
constexpr static Long TimeToTicks(Int const& hour, Int const& minute, Int const& second) {
Long totalSeconds =
static_cast<Long>(hour) * 3600 +
static_cast<Long>(minute) * 60 +
static_cast<Long>(second);
return totalSeconds * TicksPerSecond;
}
constexpr static Long DayToTicks(Int days, Int hours, Int minutes, Int seconds, Int milliseconds) {
Long totalMilliSeconds =
(static_cast<Long>(days) * 3600 * 24 +
static_cast<Long>(hours) * 3600 +
static_cast<Long>(minutes) * 60 + seconds) * 1000 + milliseconds;
return totalMilliSeconds * TicksPerMillisecond;
}
};
}
#endif

View File

@ -13,28 +13,7 @@ using namespace xna;
//} //}
int APIENTRY WinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ LPSTR lpCmdLine, _In_ int nCmdShow) { int APIENTRY WinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ LPSTR lpCmdLine, _In_ int nCmdShow) {
Game game;
GameWindow gw; game.Run();
MSG msg = { 0 };
gw.ip_GameWindow->Color(255, 155, 55);
gw.Title("Teste de título");
gw.ip_GameWindow->Create();
GraphicsDevice device;
device.Initialize(gw);
do {
if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
else {
device.Clear();
device.Present();
}
} while (msg.message != WM_QUIT);
return 0; return 0;
} }

View File

@ -8,6 +8,7 @@
#include "Windows.h" #include "Windows.h"
#include "game/window.hpp" #include "game/window.hpp"
#include "platform/window-dx.hpp" #include "platform/window-dx.hpp"
#include "graphics/device.hpp" #include "platform/device-dx.hpp"
#include "platform/game-dx.hpp"
// TODO: Reference additional headers your program requires here. // TODO: Reference additional headers your program requires here.