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

Implementa StepTimer entre outros

This commit is contained in:
Danilo 2024-04-23 16:11:17 -03:00
parent cdff5cc0f8
commit aa63d7cef9
19 changed files with 494 additions and 215 deletions

View File

@ -11,6 +11,8 @@ endif()
# TODO: Add tests and install targets if needed.
# -- Biblioteca DirectxTK --
# Url: https://github.com/microsoft/DirectXTK/wiki/DirectXTK
#
@ -29,5 +31,4 @@ endif()
# }
#
find_package(directxtk CONFIG REQUIRED)
target_link_libraries(${PROJECT_NAME} D3d11.lib dxgi.lib dxguid.lib d3dcompiler.lib Microsoft::DirectXTK)

View File

@ -34,8 +34,8 @@ namespace xna {
static constexpr int64_t MinutesPerHour = TicksPerHour / TicksPerMinute;
static constexpr int64_t MinutesPerDay = TicksPerDay / TicksPerMinute;
static constexpr int64_t HoursPerDay = TicksPerDay / TicksPerHour;
static constexpr int64_t MinTicks = std::numeric_limits<int64_t>::min();
static constexpr int64_t MaxTicks = std::numeric_limits<int64_t>::max();
static constexpr int64_t MinTicks = (std::numeric_limits<int64_t>::min)();
static constexpr int64_t MaxTicks = (std::numeric_limits<int64_t>::max)();
static constexpr int64_t MinMicroseconds = MinTicks / TicksPerMicrosecond;
static constexpr int64_t MaxMicroseconds = MaxTicks / TicksPerMicrosecond;
static constexpr int64_t MinMilliseconds = MinTicks / TicksPerMillisecond;

View File

@ -20,6 +20,9 @@ namespace xna {
virtual Uint SubSystemId() const = 0;
virtual Uint VendorId() const = 0;
virtual UDisplayModeCollection SupportedDisplayModes() const = 0;
virtual UDisplayModeCollection SupportedDisplayModes(SurfaceFormat surfaceFormat) const = 0;
virtual PDisplayMode CurrentDisplayMode() = 0;
virtual void CurrentDisplayMode(SurfaceFormat surfaceFormat, Uint width, Uint height) = 0;
static UGraphicsAdapter DefaultAdapter();
static void Adapters(std::vector<PGraphicsAdapter>& adapters);

View File

@ -19,8 +19,6 @@ namespace xna {
class IDisplayModeCollection {
public:
virtual ~IDisplayModeCollection() {}
virtual std::vector<PDisplayMode> At(SurfaceFormat format) const = 0;
virtual void At(SurfaceFormat format, std::vector<PDisplayMode>& modes) const = 0;
virtual size_t SurfaceCount(SurfaceFormat format) const = 0;
};
}

View File

@ -1,8 +1,7 @@
#ifndef XNA_GRAPHICS_PRESENTPARAMS_HPP
#define XNA_GRAPHICS_PRESENTPARAMS_HPP
#include "../types.hpp"
#include "../enums.hpp"
#include "../default.hpp"
namespace xna {
class PresentationParameters {

View File

@ -1,7 +1,10 @@
#include "adapter-dx.hpp"
#include "../helpers.hpp"
#include "gdevicemanager-dx.hpp"
namespace xna {
static size_t getDisplayModesCount(IDXGIAdapter* adapter);
static UDisplayModeCollection createDisplayModeCollection(std::vector<DXGI_MODE_DESC> const& source);
UGraphicsAdapter IGraphicsAdapter::DefaultAdapter() {
IDXGIFactory1* pFactory = nullptr;
@ -15,7 +18,7 @@ namespace xna {
auto adp = uNew<GraphicsAdapter>();
adp->_index = 0;
adp->_adapter = pAdapter;
adp->dxadapter = pAdapter;
return adp;
}
@ -39,7 +42,7 @@ namespace xna {
auto adp = New<GraphicsAdapter>();
adp->_index = count;
adp->_adapter = pAdapter;
adp->dxadapter = pAdapter;
adapters.push_back(adp);
}
@ -61,7 +64,7 @@ namespace xna {
auto adp = uNew<GraphicsAdapter>();
adp->_index = count;
adp->_adapter = pAdapter;
adp->dxadapter = pAdapter;
adapters.push_back(std::move(adp));
}
@ -71,30 +74,30 @@ namespace xna {
}
String GraphicsAdapter::Description() const {
if (!_adapter) return String();
if (!dxadapter) return String();
DXGI_ADAPTER_DESC1 desc;
_adapter->GetDesc1(&desc);
dxadapter->GetDesc1(&desc);
String description = XnaHToString(desc.Description);
return description;
}
Uint GraphicsAdapter::DeviceId() const {
if (!_adapter) return 0;
if (!dxadapter) return 0;
DXGI_ADAPTER_DESC1 desc;
_adapter->GetDesc1(&desc);
dxadapter->GetDesc1(&desc);
return static_cast<Uint>(desc.DeviceId);
}
String GraphicsAdapter::DeviceName() const {
if (!_adapter) return String();
if (!dxadapter) return String();
IDXGIOutput* pOutput = nullptr;
DXGI_OUTPUT_DESC outputDesc;
if (_adapter->EnumOutputs(0, &pOutput) != DXGI_ERROR_NOT_FOUND) {
if (dxadapter->EnumOutputs(0, &pOutput) != DXGI_ERROR_NOT_FOUND) {
pOutput->GetDesc(&outputDesc);
String deviceName = XnaHToString(outputDesc.DeviceName);
@ -108,12 +111,12 @@ namespace xna {
}
intptr_t GraphicsAdapter::MonitorHandle() const {
if (!_adapter) return 0;
if (!dxadapter) return 0;
IDXGIOutput* pOutput = nullptr;
DXGI_OUTPUT_DESC outputDesc;
if (_adapter->EnumOutputs(0, &pOutput) != DXGI_ERROR_NOT_FOUND) {
if (dxadapter->EnumOutputs(0, &pOutput) != DXGI_ERROR_NOT_FOUND) {
pOutput->GetDesc(&outputDesc);
pOutput->Release();
@ -126,32 +129,134 @@ namespace xna {
}
Uint GraphicsAdapter::Revision() const {
if (!_adapter) return 0;
if (!dxadapter) return 0;
DXGI_ADAPTER_DESC1 desc;
_adapter->GetDesc1(&desc);
dxadapter->GetDesc1(&desc);
return static_cast<Uint>(desc.Revision);
}
Uint GraphicsAdapter::SubSystemId() const {
if (!_adapter) return 0;
if (!dxadapter) return 0;
DXGI_ADAPTER_DESC1 desc;
_adapter->GetDesc1(&desc);
dxadapter->GetDesc1(&desc);
return static_cast<Uint>(desc.SubSysId);
}
Uint GraphicsAdapter::VendorId() const {
if (!_adapter) return 0;
if (!dxadapter) return 0;
DXGI_ADAPTER_DESC1 desc;
_adapter->GetDesc1(&desc);
dxadapter->GetDesc1(&desc);
return static_cast<Uint>(desc.VendorId);
}
UDisplayModeCollection GraphicsAdapter::SupportedDisplayModes() const {
if (!dxadapter) return nullptr;
const auto totalDisplay = getDisplayModesCount(dxadapter);
if (totalDisplay == 0)
return nullptr;
IDXGIOutput* pOutput = nullptr;
UINT bufferOffset = 0;
std::vector<DXGI_MODE_DESC> buffer(totalDisplay);
if (dxadapter->EnumOutputs(0, &pOutput) != DXGI_ERROR_NOT_FOUND) {
for (size_t f = 0; f < SURFACE_FORMAT_COUNT; ++f) {
const auto currentSurface = static_cast<SurfaceFormat>(f);
DXGI_FORMAT format = GraphicsAdapter::ToDXGI(currentSurface);
UINT numModes = 0;
pOutput->GetDisplayModeList(format, 0, &numModes, nullptr);
if (numModes == 0)
continue;
pOutput->GetDisplayModeList(format, 0, &numModes, buffer.data() + bufferOffset);
bufferOffset += numModes;
}
}
if (!pOutput)
return nullptr;
pOutput->Release();
pOutput = nullptr;
return createDisplayModeCollection(buffer);
}
UDisplayModeCollection GraphicsAdapter::SupportedDisplayModes(SurfaceFormat surfaceFormat) const
{
if (!dxadapter) return nullptr;
IDXGIOutput* pOutput = nullptr;
UINT bufferOffset = 0;
if (dxadapter->EnumOutputs(0, &pOutput) != DXGI_ERROR_NOT_FOUND) {
DXGI_FORMAT format = GraphicsAdapter::ToDXGI(surfaceFormat);
UINT numModes = 0;
pOutput->GetDisplayModeList(format, 0, &numModes, nullptr);
if (numModes == 0)
return uNew<DisplayModeCollection>();
std::vector<DXGI_MODE_DESC> buffer(numModes);
pOutput->GetDisplayModeList(format, 0, &numModes, buffer.data());
pOutput->Release();
pOutput = nullptr;
return createDisplayModeCollection(buffer);
}
return uNew<DisplayModeCollection>();
}
PDisplayMode GraphicsAdapter::CurrentDisplayMode() {
if (!_currentDisplayMode) {
CurrentDisplayMode(SurfaceFormat::Color, GraphicsDeviceManager::DefaultBackBufferWidth, GraphicsDeviceManager::DefaultBackBufferHeight);
}
return _currentDisplayMode;
}
void GraphicsAdapter::CurrentDisplayMode(SurfaceFormat surfaceFormat, Uint width, Uint height) {
const auto modes = SupportedDisplayModes(surfaceFormat);
for (size_t i = 0; i < modes->_displayModes.size(); ++i) {
auto& m = modes->_displayModes[i];
if (m->_format == surfaceFormat && m->_width == width && m->_height == height) {
_currentDisplayMode = m;
}
else if(i + 1 == modes->_displayModes.size()) {
_currentDisplayMode = m;
}
}
}
bool GraphicsAdapter::GetOutput(UINT slot, IDXGIOutput*& output) {
if (!dxadapter) return false;
if (dxadapter->EnumOutputs(slot, &output) != DXGI_ERROR_NOT_FOUND)
return true;
return false;
}
//INTERNAL FUNCTIONS
static size_t getDisplayModesCount(IDXGIAdapter* adapter) {
IDXGIOutput* pOutput = nullptr;
size_t numModes = 0;
@ -174,49 +279,14 @@ namespace xna {
return numModes;
}
UDisplayModeCollection GraphicsAdapter::SupportedDisplayModes() const {
if (!_adapter) return nullptr;
const auto totalDisplay = getDisplayModesCount(_adapter);
if (totalDisplay == 0)
return nullptr;
IDXGIOutput* pOutput = nullptr;
UINT bufferOffset = 0;
std::vector<DXGI_MODE_DESC> buffer(totalDisplay);
if (_adapter->EnumOutputs(0, &pOutput) != DXGI_ERROR_NOT_FOUND) {
for (size_t f = 0; f < SURFACE_FORMAT_COUNT; ++f) {
const auto currentSurface = static_cast<SurfaceFormat>(f);
DXGI_FORMAT format = GraphicsAdapter::ToDXGI(currentSurface);
UINT numModes = 0;
pOutput->GetDisplayModeList(format, 0, &numModes, nullptr);
if (numModes == 0)
continue;
pOutput->GetDisplayModeList(format, 0, &numModes, buffer.data() + bufferOffset);
bufferOffset += numModes;
}
}
if (!pOutput)
return nullptr;
pOutput->Release();
pOutput = nullptr;
static UDisplayModeCollection createDisplayModeCollection(std::vector<DXGI_MODE_DESC> const& source) {
auto collection = uNew<DisplayModeCollection>();
DisplayMode currentDisplayMode;
std::vector<PDisplayMode> displayList;
PDisplayMode pDisplay = nullptr;
for (size_t i = 0; i < totalDisplay; ++i) {
auto& modedesc = buffer[i];
for (size_t i = 0; i < source.size(); ++i) {
auto& modedesc = source[i];
DisplayModeDescription description;
description._refreshRate = modedesc.RefreshRate;
@ -238,16 +308,6 @@ namespace xna {
collection->_displayModes = displayList;
return std::move(collection);
}
bool GraphicsAdapter::GetOutput(UINT slot, IDXGIOutput*& output) {
if (!_adapter) return false;
if (_adapter->EnumOutputs(slot, &output) != DXGI_ERROR_NOT_FOUND)
return true;
return false;
return collection;
}
}

View File

@ -13,9 +13,9 @@ namespace xna {
GraphicsAdapter() {}
virtual ~GraphicsAdapter() override {
if (_adapter) {
_adapter->Release();
_adapter = nullptr;
if (dxadapter) {
dxadapter->Release();
dxadapter = nullptr;
}
}
@ -27,13 +27,17 @@ namespace xna {
virtual Uint SubSystemId() const override;
virtual Uint VendorId() const override;
virtual UDisplayModeCollection SupportedDisplayModes() const override;
virtual UDisplayModeCollection SupportedDisplayModes(SurfaceFormat surfaceFormat) const override;
virtual PDisplayMode CurrentDisplayMode() override;
virtual void CurrentDisplayMode(SurfaceFormat surfaceFormat, Uint width, Uint height) override;
virtual constexpr bool IsDefaultAdapter() const { return _index == 0; }
bool GetOutput(UINT slot, IDXGIOutput*& output);
public:
IDXGIAdapter1* _adapter{ nullptr };
IDXGIAdapter1* dxadapter{ nullptr };
private:
Uint _index{ 0 };
Uint _index{ 0 };
PDisplayMode _currentDisplayMode = nullptr;
public:
static constexpr DXGI_FORMAT ToDXGI(SurfaceFormat format)

View File

@ -6,16 +6,19 @@
#include "blendstate-dx.hpp"
#include "gdeviceinfo-dx.hpp"
#include "../common/color.hpp"
#include "gdevicemanager-dx.hpp"
namespace xna {
GraphicsDevice::GraphicsDevice() {
_blendState = BlendState::NonPremultiplied();
_adapter = GraphicsAdapter::DefaultAdapter();
_adapter->CurrentDisplayMode(SurfaceFormat::Color, GraphicsDeviceManager::DefaultBackBufferWidth, GraphicsDeviceManager::DefaultBackBufferHeight);
}
GraphicsDevice::GraphicsDevice(GraphicsDeviceInformation const& info) {
_adapter = info.Adapter();
_adapter = info.Adapter();
_presentParameters = info.PresentationParameters();
_adapter->CurrentDisplayMode(_presentParameters.BackBufferFormat, _presentParameters.BackBufferWidth, _presentParameters.BackBufferHeight);
}
bool GraphicsDevice::Initialize(GameWindow& gameWindow) {
@ -95,18 +98,11 @@ namespace xna {
}
bool GraphicsDevice::Present() {
_swapChain->_swapChain->Present(_usevsync, NULL);
const auto result = _swapChain->Present(_usevsync);
_context->OMSetRenderTargets(1, &_renderTarget2D->_renderTargetView, nullptr);
return true;
}
bool GraphicsDevice::GetSwapChainBackBuffer(ID3D11Texture2D*& texture2D) {
if FAILED(_swapChain->_swapChain->GetBuffer(0, __uuidof(texture2D), (void**)(&texture2D)))
return false;
return true;
}
return result;
}
bool GraphicsDevice::createDevice() {
#if _DEBUG
@ -115,7 +111,7 @@ namespace xna {
if FAILED(
D3D11CreateDevice(
_adapter->_adapter,
_adapter->dxadapter,
D3D_DRIVER_TYPE_UNKNOWN,
NULL,
_createDeviceFlags,

View File

@ -1,31 +1,6 @@
#include "displaymode-dx.hpp"
namespace xna {
std::vector<PDisplayMode> DisplayModeCollection::At(SurfaceFormat format) const
{
std::vector<PDisplayMode> modes;
At(format, modes);
return modes;
}
void DisplayModeCollection::At(SurfaceFormat format, std::vector<PDisplayMode>& modes) const
{
size_t counter = 0;
for (size_t i = 0; i < _displayModes.size(); ++i) {
const auto& displayMode = _displayModes[i];
if (displayMode->Format() == format)
{
modes.push_back(displayMode);
++counter;
}
}
if (!modes.empty())
modes.resize(counter);
}
size_t DisplayModeCollection::SurfaceCount(SurfaceFormat format) const
{
size_t counter = 0;
@ -38,4 +13,43 @@ namespace xna {
return counter;
}
std::vector<PDisplayMode> DisplayModeCollection::Query(SurfaceFormat format) const
{
const auto count = SurfaceCount(format);
size_t index = 0;
std::vector<PDisplayMode> modes(count);
for (size_t i = 0; i < _displayModes.size(); ++i) {
if (_displayModes[i]->Format() == format) {
modes[index] = _displayModes[i];
++index;
}
if (index == count)
break;
}
return modes;
}
PDisplayMode DisplayModeCollection::Query(SurfaceFormat format, Uint width, Uint height) const
{
PDisplayMode matched = nullptr;
for (size_t i = 0; i < _displayModes.size(); ++i) {
const auto& mode = _displayModes[i];
if (mode->Format() == format && mode->_width == width && mode->_height == height) {
return _displayModes[i];
}
else if(mode->Format() == format && mode->_width == width) {
matched = mode;
}
}
return matched;
}
}

View File

@ -88,15 +88,10 @@ namespace xna {
DisplayModeCollection(std::vector<PDisplayMode> const& displayModes) :
_displayModes(displayModes) {}
virtual std::vector<PDisplayMode> At(SurfaceFormat format) const override;
virtual void At(SurfaceFormat format, std::vector<PDisplayMode>& modes) const override;
virtual size_t SurfaceCount(SurfaceFormat format) const override;
std::vector<PDisplayMode> operator[](SurfaceFormat format) const {
return At(format);
}
std::vector<PDisplayMode> Query(SurfaceFormat format) const;
PDisplayMode Query(SurfaceFormat format, Uint width, Uint height) const;
public:
std::vector<PDisplayMode> _displayModes;

View File

@ -0,0 +1,191 @@
//
// StepTimer.h - A simple timer that provides elapsed time information
//
// https://github.com/microsoft/DirectXTK/wiki/StepTimer
#pragma once
#include <cmath>
#include <cstdint>
#include <exception>
namespace DX
{
// Helper class for animation and simulation timing.
class StepTimer
{
public:
StepTimer() noexcept(false) :
m_elapsedTicks(0),
m_totalTicks(0),
m_leftOverTicks(0),
m_frameCount(0),
m_framesPerSecond(0),
m_framesThisSecond(0),
m_qpcSecondCounter(0),
m_isFixedTimeStep(false),
m_targetElapsedTicks(TicksPerSecond / 60)
{
if (!QueryPerformanceFrequency(&m_qpcFrequency))
{
throw std::exception();
}
if (!QueryPerformanceCounter(&m_qpcLastTime))
{
throw std::exception();
}
// Initialize max delta to 1/10 of a second.
m_qpcMaxDelta = static_cast<uint64_t>(m_qpcFrequency.QuadPart / 10);
}
// Get elapsed time since the previous Update call.
uint64_t GetElapsedTicks() const noexcept { return m_elapsedTicks; }
double GetElapsedSeconds() const noexcept { return TicksToSeconds(m_elapsedTicks); }
// Get total time since the start of the program.
uint64_t GetTotalTicks() const noexcept { return m_totalTicks; }
double GetTotalSeconds() const noexcept { return TicksToSeconds(m_totalTicks); }
// Get total number of updates since start of the program.
uint32_t GetFrameCount() const noexcept { return m_frameCount; }
// Get the current framerate.
uint32_t GetFramesPerSecond() const noexcept { return m_framesPerSecond; }
// Set whether to use fixed or variable timestep mode.
void SetFixedTimeStep(bool isFixedTimestep) noexcept { m_isFixedTimeStep = isFixedTimestep; }
// Set how often to call Update when in fixed timestep mode.
void SetTargetElapsedTicks(uint64_t targetElapsed) noexcept { m_targetElapsedTicks = targetElapsed; }
void SetTargetElapsedSeconds(double targetElapsed) noexcept { m_targetElapsedTicks = SecondsToTicks(targetElapsed); }
// Integer format represents time using 10,000,000 ticks per second.
static constexpr uint64_t TicksPerSecond = 10000000;
static constexpr double TicksToSeconds(uint64_t ticks) noexcept { return static_cast<double>(ticks) / TicksPerSecond; }
static constexpr uint64_t SecondsToTicks(double seconds) noexcept { return static_cast<uint64_t>(seconds * TicksPerSecond); }
// After an intentional timing discontinuity (for instance a blocking IO operation)
// call this to avoid having the fixed timestep logic attempt a set of catch-up
// Update calls.
void ResetElapsedTime()
{
if (!QueryPerformanceCounter(&m_qpcLastTime))
{
throw std::exception();
}
m_leftOverTicks = 0;
m_framesPerSecond = 0;
m_framesThisSecond = 0;
m_qpcSecondCounter = 0;
}
// Update timer state, calling the specified Update function the appropriate number of times.
template<typename TUpdate>
void Tick(const TUpdate& update)
{
// Query the current time.
LARGE_INTEGER currentTime;
if (!QueryPerformanceCounter(&currentTime))
{
throw std::exception();
}
uint64_t timeDelta = static_cast<uint64_t>(currentTime.QuadPart - m_qpcLastTime.QuadPart);
m_qpcLastTime = currentTime;
m_qpcSecondCounter += timeDelta;
// Clamp excessively large time deltas (e.g. after paused in the debugger).
if (timeDelta > m_qpcMaxDelta)
{
timeDelta = m_qpcMaxDelta;
}
// Convert QPC units into a canonical tick format. This cannot overflow due to the previous clamp.
timeDelta *= TicksPerSecond;
timeDelta /= static_cast<uint64_t>(m_qpcFrequency.QuadPart);
const uint32_t lastFrameCount = m_frameCount;
if (m_isFixedTimeStep)
{
// Fixed timestep update logic
// If the app is running very close to the target elapsed time (within 1/4 of a millisecond) just clamp
// the clock to exactly match the target value. This prevents tiny and irrelevant errors
// from accumulating over time. Without this clamping, a game that requested a 60 fps
// fixed update, running with vsync enabled on a 59.94 NTSC display, would eventually
// accumulate enough tiny errors that it would drop a frame. It is better to just round
// small deviations down to zero to leave things running smoothly.
if (static_cast<uint64_t>(std::abs(static_cast<int64_t>(timeDelta - m_targetElapsedTicks))) < TicksPerSecond / 4000)
{
timeDelta = m_targetElapsedTicks;
}
m_leftOverTicks += timeDelta;
while (m_leftOverTicks >= m_targetElapsedTicks)
{
m_elapsedTicks = m_targetElapsedTicks;
m_totalTicks += m_targetElapsedTicks;
m_leftOverTicks -= m_targetElapsedTicks;
m_frameCount++;
update();
}
}
else
{
// Variable timestep update logic.
m_elapsedTicks = timeDelta;
m_totalTicks += timeDelta;
m_leftOverTicks = 0;
m_frameCount++;
update();
}
// Track the current framerate.
if (m_frameCount != lastFrameCount)
{
m_framesThisSecond++;
}
if (m_qpcSecondCounter >= static_cast<uint64_t>(m_qpcFrequency.QuadPart))
{
m_framesPerSecond = m_framesThisSecond;
m_framesThisSecond = 0;
m_qpcSecondCounter %= static_cast<uint64_t>(m_qpcFrequency.QuadPart);
}
}
private:
// Source timing data uses QPC units.
LARGE_INTEGER m_qpcFrequency;
LARGE_INTEGER m_qpcLastTime;
uint64_t m_qpcMaxDelta;
// Derived timing data uses a canonical tick format.
uint64_t m_elapsedTicks;
uint64_t m_totalTicks;
uint64_t m_leftOverTicks;
// Members for tracking the framerate.
uint32_t m_frameCount;
uint32_t m_framesPerSecond;
uint32_t m_framesThisSecond;
uint64_t m_qpcSecondCounter;
// Members for configuring fixed timestep mode.
bool m_isFixedTimeStep;
uint64_t m_targetElapsedTicks;
};
}

View File

@ -1,15 +1,21 @@
#include "game-dx.hpp"
#include "window-dx.hpp"
#include "device-dx.hpp"
#include "Windows.h"
#define NOMINMAX
#include "../game/time.hpp"
#include "audioengine-dx.hpp"
#include "device-dx.hpp"
#include "game-dx.hpp"
#include "gamepad-dx.hpp"
#include "gdevicemanager-dx.hpp"
#include "keyboard-dx.hpp"
#include "mouse-dx.hpp"
#include "audioengine-dx.hpp"
#include "window-dx.hpp"
#include "Windows.h"
namespace xna {
Game::Game() {
Keyboard::_dxKeyboard = uNew<DirectX::Keyboard>();
Mouse::_dxMouse = uNew<DirectX::Mouse>();
GamePad::_dxGamePad = uNew<DirectX::GamePad>();
_gameWindow = New<GameWindow>();
_gameWindow->Color(255, 155, 55);
_gameWindow->Title("XN65");
@ -24,14 +30,8 @@ namespace xna {
MessageBox(nullptr, "Ocorreu um erro ao executar a função CoInitializeEx", "XN65", MB_OK);
}
_audioEngine = New<AudioEngine>();
Keyboard::_dxKeyboard = uNew<DirectX::Keyboard>();
Mouse::_dxMouse = uNew<DirectX::Mouse>();
}
static void intializeAudioEngine() {
}
_audioEngine = New<AudioEngine>();
}
void Game::Exit()
{
@ -49,6 +49,10 @@ namespace xna {
return startLoop();
}
void Game::Draw(GameTime const& gameTime) {
_graphicsDevice->Present();
}
void Game::Initialize() {
LoadContent();
}
@ -56,19 +60,19 @@ namespace xna {
void Game::Update(GameTime const& gameTime) {
_audioEngine->Update();
}
int Game::startLoop() {
MSG msg{};
_clock.Start();
MSG msg{};
_stepTimer = DX::StepTimer();
do {
if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
{
{
TranslateMessage(&msg);
DispatchMessage(&msg);
DispatchMessage(&msg);
}
else {
tick();
step();
}
} while (msg.message != WM_QUIT);
@ -76,19 +80,19 @@ namespace xna {
return static_cast<int>(msg.wParam);
}
void Game::tick() {
_clock.Reset();
void Game::step()
{
_stepTimer.Tick([&]()
{
const auto elapsed = _stepTimer.GetElapsedSeconds();
const auto total =_stepTimer.GetTotalSeconds();
const auto elapsedTimeSpan = TimeSpan::FromSeconds(elapsed);
const auto totalTimeSpan = TimeSpan::FromSeconds(total);
_currentGameTime.ElapsedGameTime = elapsedTimeSpan;
_currentGameTime.TotalGameTime = totalTimeSpan;
Update(_currentGameTime);
});
this->Update(_currentGameTime);
_currentGameTime.ElapsedGameTime = _clock.ElapsedTime();
_currentGameTime.TotalGameTime = _clock.TotalTime();
this->Draw(_currentGameTime);
_graphicsDevice->Present();
_currentGameTime.ElapsedGameTime = _clock.ElapsedTime();
_currentGameTime.TotalGameTime = _clock.TotalTime();
Draw(_currentGameTime);
}
}

View File

@ -4,8 +4,8 @@
#include "../default.hpp"
#include "../game/game.hpp"
#include "clock-dx.hpp"
#include "dxgi.h"
#include "d3d11.h"
#include "dxheaders.hpp"
#include "dx/StepTimer.hpp"
namespace xna {
class Game : public IGame {
@ -28,7 +28,7 @@ namespace xna {
}
protected:
virtual void Draw(GameTime const& gameTime) override{}
virtual void Draw(GameTime const& gameTime) override;
virtual void Initialize() override;
@ -41,14 +41,14 @@ namespace xna {
protected:
PGameWindow _gameWindow{ nullptr };
PAudioEngine _audioEngine = nullptr;
PAudioEngine _audioEngine = nullptr;
GameClock _clock{};
GameTime _currentGameTime{};
DX::StepTimer _stepTimer;
private:
int startLoop();
void tick();
void step();
};
}

View File

@ -20,6 +20,8 @@ namespace xna {
PresentationParameters parameters;
parameters.BackBufferWidth = _backBufferWidth;
parameters.BackBufferHeight = _backBufferHeight;
parameters.BackBufferFormat = SurfaceFormat::Color;
parameters.IsFullScreen = false;
information.PresentationParameters(parameters);
information.Window(_game->Window());
@ -39,13 +41,19 @@ namespace xna {
auto& swap = _game->_graphicsDevice->_swapChain;
BOOL state = false;
swap->_swapChain->GetFullscreenState(&state, nullptr);
swap->_swapChain->SetFullscreenState(!state, nullptr);
auto hr = swap->dxSwapChain->GetFullscreenState(&state, nullptr);
if (FAILED(hr)) return;
hr = swap->dxSwapChain->SetFullscreenState(!state, nullptr);
if (FAILED(hr)) return;
_ifFullScreen = !state;
}
void GraphicsDeviceManager::CreateDevice(GraphicsDeviceInformation const& info) {
_device = New<GraphicsDevice>(info);
_device->Adapter(info.Adapter());
auto window = info.Window();
window->Size(_backBufferWidth, _backBufferHeight);

View File

@ -38,7 +38,7 @@ namespace xna {
public:
static constexpr int DefaultBackBufferWidth = 800;//800;
static constexpr int DefaultBackBufferHeight = 480;// 480;
static constexpr int DefaultBackBufferHeight = 600;// 480;
private:
Game* _game;
@ -46,6 +46,7 @@ namespace xna {
Int _backBufferHeight{ DefaultBackBufferHeight };
bool _isDeviceDirty{ false };
PGraphicsDevice _device;
bool _ifFullScreen{ false };
};
}

View File

@ -13,7 +13,7 @@ namespace xna {
}
auto adapter = device.Adapter();
auto dxAdapter = adapter->_adapter;
auto dxAdapter = adapter->dxadapter;
IDXGIFactory1* dxFactory1 = nullptr;
auto hr = dxAdapter->GetParent(IID_IDXGIFactory1, (void**)&dxFactory1);
@ -40,27 +40,46 @@ namespace xna {
bool SwapChain::Initialize(GraphicsDevice& device, GameWindow const& gameWindow) {
const auto bounds = gameWindow.ClientBounds();
_description.Width = static_cast<UINT>(bounds.Width);
_description.Height = static_cast<UINT>(bounds.Height);
_description.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
_description.SampleDesc.Count = 1;
_description.SampleDesc.Quality = 0;
_description.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
_description.BufferCount = 2;
_description.SwapEffect = DXGI_SWAP_EFFECT_FLIP_DISCARD;
_description.Flags = DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH;
_description.AlphaMode = DXGI_ALPHA_MODE::DXGI_ALPHA_MODE_UNSPECIFIED;
_fullScreenDescription.RefreshRate.Numerator = 60;
_fullScreenDescription.RefreshRate.Denominator = 1;
_fullScreenDescription.Scaling = DXGI_MODE_SCALING_UNSPECIFIED;
_fullScreenDescription.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED;
_fullScreenDescription.Windowed = gameWindow.Mode() != GameWindowMode::Fullscreen;
dxDescription.Width = static_cast<UINT>(bounds.Width);
dxDescription.Height = static_cast<UINT>(bounds.Height);
dxDescription.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
dxDescription.SampleDesc.Count = 1;
dxDescription.SampleDesc.Quality = 0;
dxDescription.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
dxDescription.BufferCount = 2;
dxDescription.SwapEffect = DXGI_SWAP_EFFECT_FLIP_DISCARD;
dxDescription.Flags = DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH;
dxDescription.AlphaMode = DXGI_ALPHA_MODE::DXGI_ALPHA_MODE_UNSPECIFIED;
dxFullScreenDescription.RefreshRate.Numerator = 60;
dxFullScreenDescription.RefreshRate.Denominator = 1;
dxFullScreenDescription.Scaling = DXGI_MODE_SCALING_UNSPECIFIED;
dxFullScreenDescription.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED;
dxFullScreenDescription.Windowed = gameWindow.Mode() != GameWindowMode::Fullscreen;
return internalInit(device, gameWindow, _swapChain, _description, _fullScreenDescription);
return internalInit(device, gameWindow, dxSwapChain, dxDescription, dxFullScreenDescription);
}
bool SwapChain::Initialize(GraphicsDevice& device, GameWindow const& gameWindow, DXGI_SWAP_CHAIN_DESC1 const& desc, DXGI_SWAP_CHAIN_FULLSCREEN_DESC const& fullScreenDesc)
{
return internalInit(device, gameWindow, _swapChain, _description, _fullScreenDescription);
dxDescription = desc;
dxFullScreenDescription = fullScreenDesc;
return internalInit(device, gameWindow, dxSwapChain, dxDescription, dxFullScreenDescription);
}
bool SwapChain::GetBackBuffer(ID3D11Texture2D*& texture2D) {
if (!dxSwapChain)
return false;
const auto hr = dxSwapChain->GetBuffer(0, __uuidof(texture2D), (void**)(&texture2D));
return !FAILED(hr);
}
bool SwapChain::Present(bool vsync) {
if (!dxSwapChain)
return false;
const auto hr = dxSwapChain->Present(vsync, NULL);
return !FAILED(hr);
}
}

View File

@ -9,26 +9,23 @@ namespace xna {
class SwapChain : public ISwapChain{
public:
virtual ~SwapChain() override {
if (_swapChain) {
_swapChain->Release();
_swapChain = nullptr;
if (dxSwapChain) {
dxSwapChain->Release();
dxSwapChain = nullptr;
}
}
virtual bool Initialize(GraphicsDevice& device, GameWindow const& gameWindow) override;
bool Initialize(GraphicsDevice& device, GameWindow const& gameWindow, DXGI_SWAP_CHAIN_DESC1 const& desc, DXGI_SWAP_CHAIN_FULLSCREEN_DESC const& fullScreenDesc);
bool GetBackBuffer(ID3D11Texture2D*& texture2D) {
if FAILED(_swapChain->GetBuffer(0, __uuidof(texture2D), (void**)(&texture2D)))
return false;
bool GetBackBuffer(ID3D11Texture2D*& texture2D);
return true;
}
bool Present(bool vsync);
public:
IDXGISwapChain1* _swapChain{ nullptr };
DXGI_SWAP_CHAIN_DESC1 _description{};
DXGI_SWAP_CHAIN_FULLSCREEN_DESC _fullScreenDescription{};
IDXGISwapChain1* dxSwapChain{ nullptr };
DXGI_SWAP_CHAIN_DESC1 dxDescription{};
DXGI_SWAP_CHAIN_FULLSCREEN_DESC dxFullScreenDescription{};
};
}

View File

@ -23,6 +23,7 @@ namespace xna {
void Initialize() override {
graphics->Initialize();
const auto modes = _graphicsDevice->_adapter->SupportedDisplayModes();
Game::Initialize();
}
@ -41,18 +42,6 @@ namespace xna {
if (Keyboard::GetState().IsKeyDown(Keys::Escape) || GamePad::GetState(PlayerIndex::One).IsButtonDown(Buttons::Back))
Exit();
oldState = currentState;
currentState = Mouse::GetState();
const auto rec = Rectangle((graphics->PreferredBackBufferWidth() / 2) - 100, (graphics->PreferredBackBufferHeight() / 2) - 100, 200, 200);
if (currentState.LeftButton == ButtonState::Pressed && oldState.LeftButton == ButtonState::Released) {
graphics->ToggleFullScreen();
}
if (currentState.RightButton == ButtonState::Pressed && oldState.RightButton == ButtonState::Released) {
position.X += 50;
}
Game::Update(gameTime);
}

View File

@ -4,21 +4,21 @@
#pragma once
#define NOMINMAX
#include <iostream>
#include "Windows.h"
#include "common/color.hpp"
#include "csharp/stream.hpp"
#include "game/window.hpp"
#include "platform/window-dx.hpp"
#include "platform/adapter-dx.hpp"
#include "platform/audioengine-dx.hpp"
#include "platform/device-dx.hpp"
#include "platform/game-dx.hpp"
#include "csharp/stream.hpp"
#include "platform/gamepad-dx.hpp"
#include "platform/gdevicemanager-dx.hpp"
#include "platform/texture-dx.hpp"
#include "platform/spritebatch-dx.hpp"
#include "common/color.hpp"
#include "platform/keyboard-dx.hpp"
#include "platform/mouse-dx.hpp"
#include "platform/gamepad-dx.hpp"
#include "platform/audioengine-dx.hpp"
#include "platform/adapter-dx.hpp"
#include "platform/spritebatch-dx.hpp"
#include "platform/texture-dx.hpp"
#include "platform/window-dx.hpp"
#include "Windows.h"
#include <iostream>
// TODO: Reference additional headers your program requires here.