Commits (21)
......@@ -3,3 +3,6 @@
# Exclude x64 folder
x64/
# Exclude cso files
*.cso
#include "App.h"
#include <sstream>
#include <iomanip>
#include "Box.h"
#include <memory>
App::App()
:
wnd( 800,600,"Oasis Demo")
{
std::mt19937 rng(std::random_device{}());
std::uniform_real_distribution<float> adist(0.0f, 3.1415f * 2.0f);
std::uniform_real_distribution<float> ddist(0.0f, 3.1415f * 2.0f);
std::uniform_real_distribution<float> odist(0.0f, 3.1415f * 0.3f);
std::uniform_real_distribution<float> rdist(6.0f, 20.0f);
for (auto i = 0; i < 8; i++)
{
boxes.push_back(std::make_unique<Box>(
wnd.Gfx(), rng, adist,
ddist, odist, rdist
));
}
wnd.Gfx().SetProjection(DirectX::XMMatrixPerspectiveLH(1.0f, 3.0f / 4.0f, 0.5f, 40.0f));
}
int App::Go()
{
while (true)
{
// process all messages pending, but to not block for new messages
if (const auto ecode = Window::ProcessMessages())
{
// if return optional has value, means we're quitting so return exit code
return *ecode;
}
DoFrame();
}
}
App::~App()
{}
void App::DoFrame()
{
auto dt = timer.Mark();
wnd.Gfx().ClearBuffer(0.07f, 0.0f, 0.12f);
for (auto& b : boxes)
{
b->Update(dt);
b->Draw(wnd.Gfx());
}
wnd.Gfx().EndFrame();
}
\ No newline at end of file
#pragma once
#include "Window.h"
#include "ChiliTimer.h"
class App
{
public:
App();
// master frame / message loop
int Go();
~App();
private:
void DoFrame();
private:
Window wnd;
ChiliTimer timer;
std::vector<std::unique_ptr<class Box>> boxes;
};
\ No newline at end of file
#include "Bindable.h"
ID3D11DeviceContext* Bindable::GetContext( Graphics& gfx ) noexcept
{
return gfx.pContext.Get();
}
ID3D11Device* Bindable::GetDevice( Graphics& gfx ) noexcept
{
return gfx.pDevice.Get();
}
DxgiInfoManager& Bindable::GetInfoManager( Graphics& gfx ) noexcept(!IS_DEBUG)
{
#ifndef NDEBUG
return gfx.infoManager;
#else
throw std::logic_error( "YouFuckedUp! (tried to access gfx.infoManager in Release config)" );
#endif
}
#pragma once
#include "Graphics.h"
class Bindable
{
public:
virtual void Bind( Graphics& gfx ) noexcept = 0;
virtual ~Bindable() = default;
protected:
static ID3D11DeviceContext* GetContext( Graphics& gfx ) noexcept;
static ID3D11Device* GetDevice( Graphics& gfx ) noexcept;
static DxgiInfoManager& GetInfoManager( Graphics& gfx ) noexcept(!IS_DEBUG);
};
\ No newline at end of file
#pragma once
#include "ConstantBuffers.h"
#include "IndexBuffer.h"
#include "InputLayout.h"
#include "PixelShader.h"
#include "Topology.h"
#include "TransformCbuf.h"
#include "VertexBuffer.h"
#include "VertexShader.h"
\ No newline at end of file
#include "Box.h"
#include "BindableBase.h"
#include "GraphicsThrowMacros.h"
Box::Box( Graphics& gfx,
std::mt19937& rng,
std::uniform_real_distribution<float>& adist,
std::uniform_real_distribution<float>& ddist,
std::uniform_real_distribution<float>& odist,
std::uniform_real_distribution<float>& rdist )
:
r( rdist( rng ) ),
droll( ddist( rng ) ),
dpitch( ddist( rng ) ),
dyaw( ddist( rng ) ),
dphi( odist( rng ) ),
dtheta( odist( rng ) ),
dchi( odist( rng ) ),
chi( adist( rng ) ),
theta( adist( rng ) ),
phi( adist( rng ) )
{
struct Vertex
{
struct
{
float x;
float y;
float z;
} pos;
};
const std::vector<Vertex> vertices =
{
{ -1.0f,-1.0f,-1.0f },
{ 1.0f,-1.0f,-1.0f },
{ -1.0f,1.0f,-1.0f },
{ 1.0f,1.0f,-1.0f },
{ -1.0f,-1.0f,1.0f },
{ 1.0f,-1.0f,1.0f },
{ -1.0f,1.0f,1.0f },
{ 1.0f,1.0f,1.0f },
};
AddBind( std::make_unique<VertexBuffer>( gfx,vertices ) );
auto pvs = std::make_unique<VertexShader>( gfx,L"VertexShader.cso" );
auto pvsbc = pvs->GetBytecode();
AddBind( std::move( pvs ) );
AddBind( std::make_unique<PixelShader>( gfx,L"PixelShader.cso" ) );
const std::vector<unsigned short> indices =
{
0,2,1, 2,3,1,
1,3,5, 3,7,5,
2,6,3, 3,6,7,
4,5,7, 4,7,6,
0,4,2, 2,4,6,
0,1,4, 1,5,4
};
AddIndexBuffer( std::make_unique<IndexBuffer>( gfx,indices ) );
struct ConstantBuffer2
{
struct
{
float r;
float g;
float b;
float a;
} face_colors[6];
};
const ConstantBuffer2 cb2 =
{
{
{ 1.0f,0.0f,1.0f },
{ 1.0f,0.0f,0.0f },
{ 0.0f,1.0f,0.0f },
{ 0.0f,0.0f,1.0f },
{ 1.0f,1.0f,0.0f },
{ 0.0f,1.0f,1.0f },
}
};
AddBind( std::make_unique<PixelConstantBuffer<ConstantBuffer2>>( gfx,cb2 ) );
const std::vector<D3D11_INPUT_ELEMENT_DESC> ied =
{
{ "Position",0,DXGI_FORMAT_R32G32B32_FLOAT,0,0,D3D11_INPUT_PER_VERTEX_DATA,0 },
};
AddBind( std::make_unique<InputLayout>( gfx,ied,pvsbc ) );
AddBind( std::make_unique<Topology>( gfx,D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST ) );
AddBind( std::make_unique<TransformCbuf>( gfx,*this ) );
}
void Box::Update( float dt ) noexcept
{
roll += droll * dt;
pitch += dpitch * dt;
yaw += dyaw * dt;
theta += dtheta * dt;
phi += dphi * dt;
chi += dchi * dt;
}
DirectX::XMMATRIX Box::GetTransformXM() const noexcept
{
return DirectX::XMMatrixRotationRollPitchYaw( pitch,yaw,roll ) *
DirectX::XMMatrixTranslation( r,0.0f,0.0f ) *
DirectX::XMMatrixRotationRollPitchYaw( theta,phi,chi ) *
DirectX::XMMatrixTranslation( 0.0f,0.0f,20.0f );
}
#pragma once
#include "Drawable.h"
class Box : public Drawable
{
public:
Box( Graphics& gfx,std::mt19937& rng,
std::uniform_real_distribution<float>& adist,
std::uniform_real_distribution<float>& ddist,
std::uniform_real_distribution<float>& odist,
std::uniform_real_distribution<float>& rdist );
void Update( float dt ) noexcept override;
DirectX::XMMATRIX GetTransformXM() const noexcept override;
private:
// positional
float r;
float roll = 0.0f;
float pitch = 0.0f;
float yaw = 0.0f;
float theta;
float phi;
float chi;
// speed (delta/s)
float droll;
float dpitch;
float dyaw;
float dtheta;
float dphi;
float dchi;
};
\ No newline at end of file
#include "ChiliTimer.h"
using namespace std::chrono;
ChiliTimer::ChiliTimer() noexcept
{
last = steady_clock::now();
}
float ChiliTimer::Mark() noexcept
{
const auto old = last;
last = steady_clock::now();
const duration<float> frameTime = last - old;
return frameTime.count();
}
float ChiliTimer::Peek() const noexcept
{
return duration<float>( steady_clock::now() - last ).count();
}
#pragma once
#include <chrono>
class ChiliTimer
{
public:
ChiliTimer() noexcept;
float Mark() noexcept;
float Peek() const noexcept;
private:
std::chrono::steady_clock::time_point last;
};
\ No newline at end of file
#pragma once
#include "Bindable.h"
#include "GraphicsThrowMacros.h"
template<typename C>
class ConstantBuffer : public Bindable
{
public:
void Update( Graphics& gfx,const C& consts )
{
INFOMAN( gfx );
D3D11_MAPPED_SUBRESOURCE msr;
GFX_THROW_INFO( GetContext( gfx )->Map(
pConstantBuffer.Get(),0u,
D3D11_MAP_WRITE_DISCARD,0u,
&msr
) );
memcpy( msr.pData,&consts,sizeof( consts ) );
GetContext( gfx )->Unmap( pConstantBuffer.Get(),0u );
}
ConstantBuffer( Graphics& gfx,const C& consts )
{
INFOMAN( gfx );
D3D11_BUFFER_DESC cbd;
cbd.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
cbd.Usage = D3D11_USAGE_DYNAMIC;
cbd.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
cbd.MiscFlags = 0u;
cbd.ByteWidth = sizeof( consts );
cbd.StructureByteStride = 0u;
D3D11_SUBRESOURCE_DATA csd = {};
csd.pSysMem = &consts;
GFX_THROW_INFO( GetDevice( gfx )->CreateBuffer( &cbd,&csd,&pConstantBuffer ) );
}
ConstantBuffer( Graphics& gfx )
{
INFOMAN( gfx );
D3D11_BUFFER_DESC cbd;
cbd.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
cbd.Usage = D3D11_USAGE_DYNAMIC;
cbd.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
cbd.MiscFlags = 0u;
cbd.ByteWidth = sizeof( C );
cbd.StructureByteStride = 0u;
GFX_THROW_INFO( GetDevice( gfx )->CreateBuffer( &cbd,nullptr,&pConstantBuffer ) );
}
protected:
Microsoft::WRL::ComPtr<ID3D11Buffer> pConstantBuffer;
};
template<typename C>
class VertexConstantBuffer : public ConstantBuffer<C>
{
using ConstantBuffer<C>::pConstantBuffer;
using Bindable::GetContext;
public:
using ConstantBuffer<C>::ConstantBuffer;
void Bind( Graphics& gfx ) noexcept override
{
GetContext( gfx )->VSSetConstantBuffers( 0u,1u,pConstantBuffer.GetAddressOf() );
}
};
template<typename C>
class PixelConstantBuffer : public ConstantBuffer<C>
{
using ConstantBuffer<C>::pConstantBuffer;
using Bindable::GetContext;
public:
using ConstantBuffer<C>::ConstantBuffer;
void Bind( Graphics& gfx ) noexcept override
{
GetContext( gfx )->PSSetConstantBuffers( 0u,1u,pConstantBuffer.GetAddressOf() );
}
};
\ No newline at end of file
This diff is collapsed.
This diff is collapsed.
DX_CHAR strBufferLine[128];
DX_CHAR strBufferError[256];
DX_CHAR strBuffer[BUFFER_SIZE];
DX_SPRINTF_S( strBufferLine, 128, DX_STR_WRAP("%lu"), dwLine );
if( strFile )
{
DX_SPRINTF_S( strBuffer, BUFFER_SIZE, DX_STR_WRAP(STR_FMT_SPEC "(" STR_FMT_SPEC "): "), strFile, strBufferLine );
DX_OUTPUTDEBUGSTRING( strBuffer );
}
size_t nMsgLen = (strMsg) ? DX_STRNLEN_S( strMsg, 1024 ) : 0;
if( nMsgLen > 0 )
{
DX_OUTPUTDEBUGSTRING( strMsg );
DX_OUTPUTDEBUGSTRING( DX_STR_WRAP(" ") );
}
DX_SPRINTF_S( strBufferError, 256, DX_STR_WRAP(STR_FMT_SPEC " (0x%0.8x)"), DX_GETERRORSTRING(hr), hr );
DX_SPRINTF_S( strBuffer, BUFFER_SIZE, DX_STR_WRAP("hr=" STR_FMT_SPEC), strBufferError );
DX_OUTPUTDEBUGSTRING( strBuffer );
DX_OUTPUTDEBUGSTRING( DX_STR_WRAP("\n") );
#if !defined(WINAPI_FAMILY) || (WINAPI_FAMILY == WINAPI_FAMILY_DESKTOP_APP)
if( bPopMsgBox )
{
DX_CHAR strBufferFile[MAX_PATH];
DX_STRCPY_S( strBufferFile, MAX_PATH, DX_STR_WRAP("") );
if( strFile )
DX_STRCPY_S( strBufferFile, MAX_PATH, strFile );
DX_CHAR strBufferMsg[1024];
DX_STRCPY_S( strBufferMsg, 1024, DX_STR_WRAP("") );
if( nMsgLen > 0 )
DX_SPRINTF_S( strBufferMsg, 1024, DX_STR_WRAP("Calling: " STR_FMT_SPEC "\n"), strMsg );
DX_SPRINTF_S( strBuffer, BUFFER_SIZE, DX_STR_WRAP("File: " STR_FMT_SPEC "\nLine: " STR_FMT_SPEC "\nError Code: " STR_FMT_SPEC "\n" STR_FMT_SPEC "Do you want to debug the application?"),
strBufferFile, strBufferLine, strBufferError, strBufferMsg );
int nResult = DX_MESSAGEBOX( GetForegroundWindow(), strBuffer, DX_STR_WRAP("Unexpected error encountered"), MB_YESNO | MB_ICONERROR );
if( nResult == IDYES )
DebugBreak();
}
#else
UNREFERENCED_PARAMETER(bPopMsgBox);
#endif
return hr;
#include "Drawable.h"
#include "GraphicsThrowMacros.h"
#include "IndexBuffer.h"
#include <cassert>
#include <typeinfo>
void Drawable::Draw( Graphics& gfx ) const noexcept(!IS_DEBUG)
{
for( auto& b : binds )
{
b->Bind( gfx );
}
gfx.DrawIndexed( pIndexBuffer->GetCount() );
}
void Drawable::AddBind( std::unique_ptr<Bindable> bind ) noexcept(!IS_DEBUG)
{
assert( "*Must* use AddIndexBuffer to bind index buffer" && typeid(*bind) != typeid(IndexBuffer) );
binds.push_back( std::move( bind ) );
}
void Drawable::AddIndexBuffer( std::unique_ptr<IndexBuffer> ibuf ) noexcept
{
assert( "Attempting to add index buffer a second time" && pIndexBuffer == nullptr );
pIndexBuffer = ibuf.get();
binds.push_back( std::move( ibuf ) );
}
#pragma once
#include "Graphics.h"
#include <DirectXMath.h>
class Bindable;
class Drawable
{
public:
Drawable() = default;
Drawable( const Drawable& ) = delete;
virtual DirectX::XMMATRIX GetTransformXM() const noexcept = 0;
void Draw( Graphics& gfx ) const noexcept(!IS_DEBUG);
virtual void Update( float dt ) noexcept = 0;
void AddBind( std::unique_ptr<Bindable> bind ) noexcept(!IS_DEBUG);
void AddIndexBuffer( std::unique_ptr<class IndexBuffer> ibuf ) noexcept;
virtual ~Drawable() = default;
private:
const IndexBuffer* pIndexBuffer = nullptr;
std::vector<std::unique_ptr<Bindable>> binds;
};
\ No newline at end of file
#include "DxgiInfoManager.h"
#include "Window.h"
#include "Graphics.h"
#include <dxgidebug.h>
#include <memory>
#include "GraphicsThrowMacros.h"
#include "WindowsThrowMacros.h"
#pragma comment(lib, "dxguid.lib")
DxgiInfoManager::DxgiInfoManager()
{
// define function signature of DXGIGetDebugInterface
typedef HRESULT (WINAPI* DXGIGetDebugInterface)(REFIID,void **);
// load the dll that contains the function DXGIGetDebugInterface
const auto hModDxgiDebug = LoadLibraryEx( "dxgidebug.dll",nullptr,LOAD_LIBRARY_SEARCH_SYSTEM32 );
if( hModDxgiDebug == nullptr )
{
throw CHWND_LAST_EXCEPT();
}
// get address of DXGIGetDebugInterface in dll
const auto DxgiGetDebugInterface = reinterpret_cast<DXGIGetDebugInterface>(
reinterpret_cast<void*>(GetProcAddress( hModDxgiDebug,"DXGIGetDebugInterface" ))
);
if( DxgiGetDebugInterface == nullptr )
{
throw CHWND_LAST_EXCEPT();
}
HRESULT hr;
GFX_THROW_NOINFO(DxgiGetDebugInterface(__uuidof(IDXGIInfoQueue), &pDxgiInfoQueue));
}
void DxgiInfoManager::Set() noexcept
{
// set the index (next) so that the next all to GetMessages()
// will only get errors generated after this call
next = pDxgiInfoQueue->GetNumStoredMessages( DXGI_DEBUG_ALL );
}
std::vector<std::string> DxgiInfoManager::GetMessages() const
{
std::vector<std::string> messages;
const auto end = pDxgiInfoQueue->GetNumStoredMessages( DXGI_DEBUG_ALL );
for( auto i = next; i < end; i++ )
{
HRESULT hr;
SIZE_T messageLength;
// get the size of message i in bytes
GFX_THROW_NOINFO( pDxgiInfoQueue->GetMessage( DXGI_DEBUG_ALL,i,nullptr,&messageLength ) );
// allocate memory for message
auto bytes = std::make_unique<byte[]>( messageLength );
auto pMessage = reinterpret_cast<DXGI_INFO_QUEUE_MESSAGE*>(bytes.get());
// get the message and push its description into the vector
GFX_THROW_NOINFO( pDxgiInfoQueue->GetMessage( DXGI_DEBUG_ALL,i,pMessage,&messageLength ) );
messages.emplace_back( pMessage->pDescription );
}
return messages;
}
#pragma once
#include "ChiliWin.h"
#include <wrl.h>
#include <vector>
#include <dxgidebug.h>
#include <string>
class DxgiInfoManager
{
public:
DxgiInfoManager();
~DxgiInfoManager() = default;
DxgiInfoManager( const DxgiInfoManager& ) = delete;
DxgiInfoManager& operator=( const DxgiInfoManager& ) = delete;
void Set() noexcept;
std::vector<std::string> GetMessages() const;
private:
unsigned long long next = 0u;
Microsoft::WRL::ComPtr<IDXGIInfoQueue> pDxgiInfoQueue;
};
\ No newline at end of file
#include "Graphics.h"
#include "dxerr.h"
#include <sstream>
#include <d3dcompiler.h>
#include <DirectXMath.h>
#include "GraphicsThrowMacros.h"
namespace wrl = Microsoft::WRL;
namespace dx = DirectX;
#pragma comment(lib,"d3d11.lib")
#pragma comment(lib,"D3DCompiler.lib")
Graphics::Graphics( HWND hWnd )
{
// 交换链的参数定义
DXGI_SWAP_CHAIN_DESC sd = {};
sd.BufferDesc.Width = 0;
sd.BufferDesc.Height = 0;
sd.BufferDesc.Format = DXGI_FORMAT_B8G8R8A8_UNORM;
sd.BufferDesc.RefreshRate.Numerator = 0;
sd.BufferDesc.RefreshRate.Denominator = 0;
sd.BufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED;
sd.BufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED;
sd.SampleDesc.Count = 1;
sd.SampleDesc.Quality = 0;
sd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
sd.BufferCount = 1;
sd.OutputWindow = hWnd;
sd.Windowed = TRUE;
sd.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;
sd.Flags = 0;
UINT swapCreateFlags = 0u;
#ifndef NDEBUG
swapCreateFlags |= D3D11_CREATE_DEVICE_DEBUG;
#endif
// for checking results of d3d functions
HRESULT hr;
// create device and front/back buffers, and swap chain and rendering context
// 创建Device,SwapChain和Context
GFX_THROW_INFO(D3D11CreateDeviceAndSwapChain(
nullptr,
D3D_DRIVER_TYPE_HARDWARE,
nullptr,
swapCreateFlags,
nullptr,
0,
D3D11_SDK_VERSION,
&sd,
&pSwap,
&pDevice,
nullptr,
&pContext
));
// gain access to texture subresource in swap chain (back buffer)
wrl::ComPtr<ID3D11Resource> pBackBuffer;
GFX_THROW_INFO(pSwap->GetBuffer(0, __uuidof(ID3D11Resource), &pBackBuffer));
GFX_THROW_INFO(pDevice->CreateRenderTargetView(pBackBuffer.Get(), nullptr, &pTarget));
// Create depth stencil state
D3D11_DEPTH_STENCIL_DESC depthStencilDesc = {};
depthStencilDesc.DepthEnable = TRUE;
depthStencilDesc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ALL;
depthStencilDesc.DepthFunc = D3D11_COMPARISON_LESS;
wrl::ComPtr<ID3D11DepthStencilState> pDepthStencilState;
// Create depth stencil state
GFX_THROW_INFO(pDevice->CreateDepthStencilState(&depthStencilDesc, &pDepthStencilState));
// bind depth state
pContext->OMSetDepthStencilState(pDepthStencilState.Get(), 1u);
// Create the depth stencil texture
wrl::ComPtr<ID3D11Texture2D> depthStencilTexture;
D3D11_TEXTURE2D_DESC depthStencilTextureDesc = {};
depthStencilTextureDesc.Width = 800;
depthStencilTextureDesc.Height = 600;
depthStencilTextureDesc.MipLevels = 1u;
depthStencilTextureDesc.ArraySize = 1u;
depthStencilTextureDesc.Format = DXGI_FORMAT_D32_FLOAT;
depthStencilTextureDesc.SampleDesc.Count = 1u;
depthStencilTextureDesc.SampleDesc.Quality = 0u;
depthStencilTextureDesc.Usage = D3D11_USAGE_DEFAULT;
depthStencilTextureDesc.BindFlags = D3D11_BIND_DEPTH_STENCIL;
GFX_THROW_INFO(pDevice->CreateTexture2D(&depthStencilTextureDesc, nullptr, &depthStencilTexture));
// Create the depth stencil view
D3D11_DEPTH_STENCIL_VIEW_DESC depthStencilViewDesc = {};
depthStencilViewDesc.Format = DXGI_FORMAT_D32_FLOAT;
depthStencilViewDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D;
depthStencilViewDesc.Texture2D.MipSlice = 0u;
GFX_THROW_INFO(pDevice->CreateDepthStencilView(depthStencilTexture.Get(), &depthStencilViewDesc, &pDSView));
// Bind depth stencil view to out put merger
pContext->OMSetRenderTargets(1u, pTarget.GetAddressOf(), pDSView.Get());
// configure viewport
D3D11_VIEWPORT vp;
vp.Width = 800.0f;
vp.Height = 600.0f;
vp.MinDepth = 0.0f;
vp.MaxDepth = 1.0f;
vp.TopLeftX = 0.0f;
vp.TopLeftY = 0.0f;
pContext->RSSetViewports(1u, &vp);
}
void Graphics::EndFrame()
{
// flipping,使用SwapChain将back buffer的内容展现到屏幕
HRESULT hr;
#ifndef NDEBUG
infoManager.Set();
#endif
if (FAILED(hr = pSwap->Present(1u, 0u))) // 同步频率1,代表屏幕每刷新一次,就进行图形刷新。
{
if (hr == DXGI_ERROR_DEVICE_REMOVED)
{
throw GFX_DEVICE_REMOVED_EXCEPT(pDevice->GetDeviceRemovedReason());
}
else
{
throw GFX_EXCEPT(hr);
}
}
}
void Graphics::ClearBuffer(float red, float green, float blue) noexcept
{
const float color[] = { red,green,blue,1.0f };
pContext->ClearRenderTargetView(pTarget.Get(), color);
pContext->ClearDepthStencilView(pDSView.Get(), D3D11_CLEAR_DEPTH, 1.0f, 0u);
}
void Graphics::DrawIndexed(UINT count) noexcept(!IS_DEBUG)
{
GFX_THROW_INFO_ONLY( pContext->DrawIndexed( count,0u,0u ) );
}
void Graphics::SetProjection( DirectX::FXMMATRIX proj ) noexcept
{
projection = proj;
}
DirectX::XMMATRIX Graphics::GetProjection() const noexcept
{
return projection;
}
// Graphics exception stuff
Graphics::HrException::HrException(int line, const char* file, HRESULT hr, std::vector<std::string> infoMsgs) noexcept
:
Exception(line, file),
hr(hr)
{
// join all info messages with newlines into single string
for (const auto& m : infoMsgs)
{
info += m;
info.push_back('\n');
}
// remove final newline if exists
if (!info.empty())
{
info.pop_back();
}
}
const char* Graphics::HrException::what() const noexcept
{
std::ostringstream oss;
oss << GetType() << std::endl
<< "[Error Code] 0x" << std::hex << std::uppercase << GetErrorCode()
<< std::dec << " (" << (unsigned long)GetErrorCode() << ")" << std::endl
<< "[Error String] " << GetErrorString() << std::endl
<< "[Description] " << GetErrorDescription() << std::endl;
if (!info.empty())
{
oss << "\n[Error Info]\n" << GetErrorInfo() << std::endl << std::endl;
}
oss << GetOriginString();
whatBuffer = oss.str();
return whatBuffer.c_str();
}
const char* Graphics::HrException::GetType() const noexcept
{
return "Chili Graphics Exception";
}
HRESULT Graphics::HrException::GetErrorCode() const noexcept
{
return hr;
}
std::string Graphics::HrException::GetErrorString() const noexcept
{
return DXGetErrorString(hr);
}
std::string Graphics::HrException::GetErrorDescription() const noexcept
{
char buf[512];
DXGetErrorDescription(hr, buf, sizeof(buf));
return buf;
}
std::string Graphics::HrException::GetErrorInfo() const noexcept
{
return info;
}
const char* Graphics::DeviceRemovedException::GetType() const noexcept
{
return "Chili Graphics Exception [Device Removed] (DXGI_ERROR_DEVICE_REMOVED)";
}
Graphics::InfoException::InfoException(int line, const char* file, std::vector<std::string> infoMsgs) noexcept
:
Exception(line, file)
{
// join all info messages with newlines into single string
for (const auto& m : infoMsgs)
{
info += m;
info.push_back('\n');
}
// remove final newline if exists
if (!info.empty())
{
info.pop_back();
}
}
const char* Graphics::InfoException::what() const noexcept
{
std::ostringstream oss;
oss << GetType() << std::endl
<< "\n[Error Info]\n" << GetErrorInfo() << std::endl << std::endl;
oss << GetOriginString();
whatBuffer = oss.str();
return whatBuffer.c_str();
}
const char* Graphics::InfoException::GetType() const noexcept
{
return "Chili Graphics Info Exception";
}
std::string Graphics::InfoException::GetErrorInfo() const noexcept
{
return info;
}
\ No newline at end of file
#pragma once
#include "ChiliWin.h"
#include "ChiliException.h"
#include <d3d11.h>
#include <wrl.h>
#include <vector>
#include "DxgiInfoManager.h"
#include <d3dcompiler.h>
#include <DirectXMath.h>
#include <memory>
#include <random>
class Graphics
{
friend class Bindable;
public:
class Exception : public ChiliException
{
using ChiliException::ChiliException;
};
class HrException : public Exception
{
public:
HrException(int line, const char* file, HRESULT hr, std::vector<std::string> infoMsgs = {}) noexcept;
const char* what() const noexcept override;
const char* GetType() const noexcept override;
HRESULT GetErrorCode() const noexcept;
std::string GetErrorString() const noexcept;
std::string GetErrorDescription() const noexcept;
std::string GetErrorInfo() const noexcept;
private:
HRESULT hr;
std::string info;
};
class InfoException : public Exception
{
public:
InfoException(int line, const char* file, std::vector<std::string> infoMsgs) noexcept;
const char* what() const noexcept override;
const char* GetType() const noexcept override;
std::string GetErrorInfo() const noexcept;
private:
std::string info;
};
class DeviceRemovedException : public HrException
{
using HrException::HrException;
public:
const char* GetType() const noexcept override;
private:
std::string reason;
};
public:
Graphics( HWND hWnd );
Graphics( const Graphics& ) = delete;
Graphics& operator=( const Graphics& ) = delete;
~Graphics() = default;
void EndFrame();
// 刷新RGB
void ClearBuffer(float red, float green, float blue) noexcept;
//void DrawTestTriangle(float angle, float x, float y);
void DrawIndexed(UINT count) noexcept(!IS_DEBUG);
void SetProjection(DirectX::FXMMATRIX proj) noexcept;
DirectX::XMMATRIX GetProjection() const noexcept;
private:
DirectX::XMMATRIX projection;
#ifndef NDEBUG
DxgiInfoManager infoManager;
#endif
// 指向Device的指针
Microsoft::WRL::ComPtr<ID3D11Device> pDevice;
// 指向交换链的指针
Microsoft::WRL::ComPtr<IDXGISwapChain> pSwap;
// 指向Context的指针
Microsoft::WRL::ComPtr<ID3D11DeviceContext> pContext;
// 指向View的指针
Microsoft::WRL::ComPtr<ID3D11RenderTargetView> pTarget;
// 指向Depth Buffer View的指针
Microsoft::WRL::ComPtr<ID3D11DepthStencilView> pDSView;
};
\ No newline at end of file