Commit cefa68f1 authored by Clark Lin's avatar Clark Lin
Browse files

Merge branch 'study' into 'main'

merge up to "add bindables and drawables"

See merge request !1
parents 90937151 42c3decc
...@@ -3,3 +3,6 @@ ...@@ -3,3 +3,6 @@
# Exclude x64 folder # Exclude x64 folder
x64/ 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
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment