port from perforce

This commit is contained in:
2026-04-18 22:31:51 +02:00
commit 8d0ab5b7cc
8409 changed files with 3972376 additions and 0 deletions

View File

@@ -0,0 +1,308 @@
#include "stdafx.h"
#include <algorithm>
#include "RenderTargetBase.h"
RenderTargetBase::RenderTargetBase(IEngine& argEngine)
: m_Engine(argEngine)
, m_ClearDepthStencilBufferDepth(1.0f) // 1.0f is the maximum depth
, m_ClearDepthStencilBufferStencil(0) // clear the full stencil buffer
, m_ClearColorBufferColor(D3DXCOLOR(0.0f, 0.0f, 0.0f, 1.0f)) // good old black opaque
, m_RenderTargetView(NULL)
, m_DepthStencilView(NULL)
, m_DepthStencilTexture(NULL)
, m_RenderingTargets(NULL)
, m_D3D10Viewports(NULL)
, m_MultiSampleCount(1)
, m_MultiSampleQuality(0)
, m_LastBindFlags(BindFlags::Default)
, m_ActiveRenderTargetCount(0)
{
this->set_ViewPort(this->get_ViewPort()); // force d3d10 viewport generation
m_Commands.push_back(new Command(this, CommandFlags::EndChain | CommandFlags::FlushChain, SetRenderTargetCommandType, 0));
memset(m_EmptyShaderResView, 0, sizeof(m_EmptyShaderResView));
}
RenderTargetBase::~RenderTargetBase()
{
this->Uninitialize();
}
void RenderTargetBase::Uninitialize()
{
if (m_Engine.get_EngineStates().LastRenderTarget == this)
m_Engine.get_EngineStates().LastRenderTarget = NULL;
// clear used states
ID3D10Device& device = m_Engine.get_DX10Device();
ID3D10RenderTargetView* activeRenderTargetViews[D3D10_SIMULTANEOUS_RENDER_TARGET_COUNT];
ID3D10DepthStencilView* activeDepthStencilView;
device.OMGetRenderTargets(D3D10_SIMULTANEOUS_RENDER_TARGET_COUNT, activeRenderTargetViews, &activeDepthStencilView);
bool clearRenderTargets = false;
if (activeDepthStencilView == m_DepthStencilView && m_DepthStencilView != NULL)
clearRenderTargets = true;
for (uint32 i = 0; i < D3D10_SIMULTANEOUS_RENDER_TARGET_COUNT; ++i)
{
if (activeRenderTargetViews[i] != NULL)
{
for (uint32 k = 0; k < m_AdditionalRenderingTargets.size() + 1; ++k)
{
if (m_RenderingTargets != NULL && m_RenderingTargets[k] == activeRenderTargetViews[i])
clearRenderTargets = true;
}
activeRenderTargetViews[i]->Release();
}
else
break;
}
if (clearRenderTargets)
device.OMSetRenderTargets(0, NULL, NULL);
if (m_RenderTargetView != NULL)
m_RenderTargetView->Release();
m_RenderTargetView = NULL;
if (m_DepthStencilView != NULL)
m_DepthStencilView->Release();
m_DepthStencilView = NULL;
if (m_DepthStencilTexture != NULL)
m_DepthStencilTexture->Release();
m_DepthStencilTexture = NULL;
this->KillViewPortAndRenderTargetData();
}
void RenderTargetBase::set_ViewPort(const ViewPort& argViewPort)
{
m_ViewPort = argViewPort;
this->KillViewPortAndRenderTargetData();
this->BuildViewPortAndRenderTargetData();
}
void RenderTargetBase::set_HasDepthStencilBuffer(bool argState)
{
if (m_RenderTargetView == NULL)
{
throw L"RenderTarget: Access forbidden until resource has been initialized.";
}
m_Engine.get_DX10Device().ClearState();
if (m_DepthStencilView != NULL)
m_DepthStencilView->Release();
m_DepthStencilView = NULL;
if (m_DepthStencilTexture != NULL)
m_DepthStencilTexture->Release();
m_DepthStencilTexture = NULL;
if (!argState)
return; // no further effort needed here
ID3D10Device& device = m_Engine.get_DX10Device();
D3D10_TEXTURE2D_DESC depthTextureDesc;
D3D10_DEPTH_STENCIL_VIEW_DESC depthStencilViewDesc;
ZeroMemory(&depthTextureDesc,sizeof(depthTextureDesc));
depthTextureDesc.Width = this->get_RenderTargetWidth();
depthTextureDesc.Height = this->get_RenderTargetHeight();
depthTextureDesc.MipLevels = 1;
depthTextureDesc.ArraySize = 1;
depthTextureDesc.Format = DXGI_FORMAT_D24_UNORM_S8_UINT;
depthTextureDesc.SampleDesc.Count = m_MultiSampleCount == 0 ? 1 : m_MultiSampleCount;
depthTextureDesc.SampleDesc.Quality = m_MultiSampleQuality;
depthTextureDesc.Usage = D3D10_USAGE_DEFAULT;
depthTextureDesc.BindFlags = D3D10_BIND_DEPTH_STENCIL;
depthTextureDesc.CPUAccessFlags = 0;
depthTextureDesc.MiscFlags = 0;
if(device.CreateTexture2D(&depthTextureDesc, 0, &m_DepthStencilTexture) != S_OK)
{
throw L"RenderTarget: Unable to create depthstencil texture.";
}
ZeroMemory(&depthStencilViewDesc, sizeof(depthStencilViewDesc));
depthStencilViewDesc.Format = depthTextureDesc.Format;
depthStencilViewDesc.ViewDimension = m_MultiSampleCount >= 1 ? D3D10_DSV_DIMENSION_TEXTURE2DMS : D3D10_DSV_DIMENSION_TEXTURE2D;
depthStencilViewDesc.Texture2D.MipSlice = 0;
if(device.CreateDepthStencilView(m_DepthStencilTexture, &depthStencilViewDesc, &m_DepthStencilView) != S_OK)
{
if (m_DepthStencilTexture != NULL)
m_DepthStencilTexture->Release();
m_DepthStencilTexture = NULL;
throw L"RenderTarget: Unable to create depth stencil view.";
}
}
void RenderTargetBase::AddAdditionalRenderTarget(IRenderTargetBase& argTarget)
{
this->RemoveAdditionalRenderTarget(argTarget);
if (m_AdditionalRenderingTargets.size() + 1 == D3D10_SIMULTANEOUS_RENDER_TARGET_COUNT)
{
throw L"RenderTarget: Unable to add an additional rendering target, list is full.";
}
if (argTarget.get_DX10RenderTargetView() == NULL)
{
throw L"RenderingResource: Unable to add an additional rendering target, new target is not initialized.";
}
m_AdditionalRenderingTargets.push_back(&argTarget);
this->KillViewPortAndRenderTargetData();
this->BuildViewPortAndRenderTargetData();
}
void RenderTargetBase::RemoveAdditionalRenderTarget(IRenderTargetBase& argTarget)
{
std::vector<IRenderTargetBase*>::iterator found = std::find(m_AdditionalRenderingTargets.begin(), m_AdditionalRenderingTargets.end(), &argTarget);
if (found != m_AdditionalRenderingTargets.end())
m_AdditionalRenderingTargets.erase(found);
this->KillViewPortAndRenderTargetData();
this->BuildViewPortAndRenderTargetData();
}
void RenderTargetBase::BuildViewPortAndRenderTargetData()
{
// Rebuild rendertargets
if (m_RenderingTargets == NULL)
{
if ((m_LastBindFlags & BindFlags::BindAllTextures) == BindFlags::BindAllTextures)
{
m_ActiveRenderTargetCount = 1 + m_AdditionalRenderingTargets.size();
m_RenderingTargets = new ID3D10RenderTargetView*[m_ActiveRenderTargetCount];
m_RenderingTargets[0] = m_RenderTargetView;
for (uint32 i = 0; i < m_AdditionalRenderingTargets.size(); ++i)
m_RenderingTargets[i + 1] = m_AdditionalRenderingTargets[i]->get_DX10RenderTargetView();
}
else if (m_LastBindFlags & BindFlags::BindAllTextures)
{
m_ActiveRenderTargetCount = 0;
if (m_LastBindFlags & BindFlags::BindBaseTexture) ++m_ActiveRenderTargetCount;
if (m_LastBindFlags & BindFlags::BindAdditionalTexture0) ++m_ActiveRenderTargetCount;
if (m_LastBindFlags & BindFlags::BindAdditionalTexture1) ++m_ActiveRenderTargetCount;
if (m_LastBindFlags & BindFlags::BindAdditionalTexture2) ++m_ActiveRenderTargetCount;
if (m_LastBindFlags & BindFlags::BindAdditionalTexture3) ++m_ActiveRenderTargetCount;
m_RenderingTargets = new ID3D10RenderTargetView*[m_ActiveRenderTargetCount];
int bufferIndex = 0;
if (m_LastBindFlags & BindFlags::BindBaseTexture) m_RenderingTargets[bufferIndex++] = m_RenderTargetView;
if (m_LastBindFlags & BindFlags::BindAdditionalTexture0) m_RenderingTargets[bufferIndex++] = m_AdditionalRenderingTargets[0]->get_DX10RenderTargetView();
if (m_LastBindFlags & BindFlags::BindAdditionalTexture1) m_RenderingTargets[bufferIndex++] = m_AdditionalRenderingTargets[1]->get_DX10RenderTargetView();
if (m_LastBindFlags & BindFlags::BindAdditionalTexture2) m_RenderingTargets[bufferIndex++] = m_AdditionalRenderingTargets[2]->get_DX10RenderTargetView();
if (m_LastBindFlags & BindFlags::BindAdditionalTexture3) m_RenderingTargets[bufferIndex++] = m_AdditionalRenderingTargets[3]->get_DX10RenderTargetView();
}
else
throw L"No render target bindable.";
}
// Rebuild viewports
if (m_D3D10Viewports == NULL)
{
m_D3D10Viewports = new D3D10_VIEWPORT[m_ActiveRenderTargetCount];
m_D3D10Viewports[0].Height = m_ViewPort.m_Height;
m_D3D10Viewports[0].Width = m_ViewPort.m_Width;
m_D3D10Viewports[0].MinDepth = m_ViewPort.m_MinDepth;
m_D3D10Viewports[0].MaxDepth = m_ViewPort.m_MaxDepth;
m_D3D10Viewports[0].TopLeftX = m_ViewPort.m_TopLeftX;
m_D3D10Viewports[0].TopLeftY = m_ViewPort.m_TopLeftY;
for (uint32 i = 0; i < m_ActiveRenderTargetCount - 1; ++i)
{
ViewPort viewPort = m_AdditionalRenderingTargets[i]->get_ViewPort();
m_D3D10Viewports[i + 1].Height = viewPort.m_Height;
m_D3D10Viewports[i + 1].Width = viewPort.m_Width;
m_D3D10Viewports[i + 1].MinDepth = viewPort.m_MinDepth;
m_D3D10Viewports[i + 1].MaxDepth = viewPort.m_MaxDepth;
m_D3D10Viewports[i + 1].TopLeftX = viewPort.m_TopLeftX;
m_D3D10Viewports[i + 1].TopLeftY = viewPort.m_TopLeftY;
}
}
}
void RenderTargetBase::KillViewPortAndRenderTargetData()
{
if (m_RenderingTargets != NULL)
delete [] m_RenderingTargets;
m_RenderingTargets = NULL;
if (m_D3D10Viewports != NULL)
delete [] m_D3D10Viewports;
m_D3D10Viewports = NULL;
m_ActiveRenderTargetCount = 0;
}
void RenderTargetBase::Bind(DWORD argBindFlags)
{
if ((argBindFlags & ~ BindFlags::ClearAll) != (m_LastBindFlags & ~ BindFlags::ClearAll))
{
m_LastBindFlags = argBindFlags;
this->KillViewPortAndRenderTargetData();
this->BuildViewPortAndRenderTargetData();
}
m_LastBindFlags = argBindFlags;
ID3D10Device& device = m_Engine.get_DX10Device();
this->Clear(argBindFlags);
device.PSSetShaderResources(0, 128, m_EmptyShaderResView);
device.OMSetRenderTargets(m_ActiveRenderTargetCount, m_RenderingTargets, m_DepthStencilView);
device.RSSetViewports(m_ActiveRenderTargetCount, m_D3D10Viewports);
m_Engine.get_EngineStates().LastRenderTarget = this;
}
void RenderTargetBase::UnbindAllRenderTargets()
{
m_Engine.get_DX10Device().OMSetRenderTargets(0, NULL, NULL);
m_Engine.get_DX10Device().RSSetViewports(0, NULL);
m_Engine.get_EngineStates().LastRenderTarget = NULL;
}
CommandExecuteResult::Enumeration RenderTargetBase::ExecuteCommand(unsigned char argCommandType, ICommandBuffer& argCurrentBuffer, uint32 argCurrentPositon)
{
if (argCommandType == RenderTargetBase::SetRenderTargetCommandType)
{
if (m_Engine.get_EngineStates().LastRenderTarget != this)
{
this->UnbindAllRenderTargets();
this->Bind();
}
else
this->Clear();
}
return CommandExecuteResult::None;
}
void RenderTargetBase::Clear(DWORD argBindFlags)
{
ID3D10Device& device = m_Engine.get_DX10Device();
if (argBindFlags & BindFlags::ClearColor)
device.ClearRenderTargetView(m_RenderTargetView, (FLOAT*)m_ClearColorBufferColor);
if ((argBindFlags & BindFlags::ClearDepthStencil) && m_DepthStencilView != NULL)
device.ClearDepthStencilView(m_DepthStencilView, 0x01L | 0x02L, m_ClearDepthStencilBufferDepth, m_ClearDepthStencilBufferStencil);
}

View File

@@ -0,0 +1,81 @@
#pragma once
#include "IEngine.h"
#include "IRenderTargetBase.h"
#include "../Commands/CommandUserBase.h"
class RenderTargetBase
: public IRenderTargetBase
, public CommandUserBase
{
protected:
static const unsigned char SetRenderTargetCommandType = 0;
public:
RenderTargetBase(IEngine& argEngine);
virtual ~RenderTargetBase();
virtual void set_ClearDepth(float argValue) { m_ClearDepthStencilBufferDepth = argValue; }
virtual float get_ClearDepth() const { return m_ClearDepthStencilBufferDepth; }
virtual void set_ClearStencil(unsigned char argValue) { m_ClearDepthStencilBufferStencil = argValue; }
virtual unsigned char get_ClearStencil() const { return m_ClearDepthStencilBufferStencil; }
virtual void set_ClearColor(const D3DXCOLOR& argValue) { m_ClearColorBufferColor = argValue; }
virtual D3DXCOLOR get_ClearColor() const { return m_ClearColorBufferColor; }
virtual void set_ViewPort(const ViewPort& argValue);
virtual ViewPort get_ViewPort() const { return m_ViewPort; }
virtual uint32 get_RenderTargetWidth() const = 0;
virtual uint32 get_RenderTargetHeight() const = 0;
virtual DataFormat::Enumeration get_RenderTargetFormat() const = 0;
virtual void set_HasDepthStencilBuffer(bool argState);
virtual bool get_HasDepthStencilBuffer() const { return m_DepthStencilView != NULL; }
virtual void AddAdditionalRenderTarget(IRenderTargetBase& argTarget);
virtual void RemoveAdditionalRenderTarget(IRenderTargetBase& argTarget);
virtual ID3D10RenderTargetView* get_DX10RenderTargetView() const { return m_RenderTargetView; }
virtual ID3D10DepthStencilView* get_DX10DepthStencilView() const { return m_DepthStencilView; }
virtual void Bind(DWORD argBindFlags = BindFlags::Default);
virtual void UnbindAllRenderTargets();
// ICommandUser
virtual CommandExecuteResult::Enumeration ExecuteCommand(unsigned char argCommandType, ICommandBuffer& argCurrentBuffer, uint32 argCurrentPositon);
protected:
void Clear(DWORD argBindFlags = BindFlags::Default);
virtual void Uninitialize();
void BuildViewPortAndRenderTargetData();
void KillViewPortAndRenderTargetData();
protected:
IEngine& m_Engine;
float m_ClearDepthStencilBufferDepth;
unsigned char m_ClearDepthStencilBufferStencil;
D3DXCOLOR m_ClearColorBufferColor;
ViewPort m_ViewPort;
ID3D10RenderTargetView* m_RenderTargetView;
ID3D10DepthStencilView* m_DepthStencilView;
ID3D10Texture2D* m_DepthStencilTexture;
uint32 m_MultiSampleCount;
uint32 m_MultiSampleQuality;
std::vector<IRenderTargetBase*> m_AdditionalRenderingTargets;
ID3D10RenderTargetView** m_RenderingTargets;
D3D10_VIEWPORT* m_D3D10Viewports;
uint32 m_ActiveRenderTargetCount;
DWORD m_LastBindFlags;
ID3D10ShaderResourceView* m_EmptyShaderResView[128];
};

View File

@@ -0,0 +1,105 @@
#include "stdafx.h"
#include "ITexture.h"
#include "IEngine.h"
#include "IResourcefactory.h"
#include "RenderTargetTexture.h"
RenderTargetTexture::RenderTargetTexture(IEngine& argEngine)
: RenderTargetBase(argEngine)
, m_Texture(NULL)
{
}
RenderTargetTexture::~RenderTargetTexture()
{
delete m_Texture;
m_Engine.get_ResourceFactory().DeleteRenderTargetTexture(*const_cast<RenderTargetTexture*>(this), true);
}
void RenderTargetTexture::SetTextureParameters(uint32 argWidth, uint32 argHeight, DataFormat::Enumeration argFormat, uint32 argMultiSampleCount, uint32 argMultiSampleQuality)
{
if (argWidth == this->get_RenderTargetWidth() &&
argHeight == this->get_RenderTargetHeight() &&
argFormat == this->get_RenderTargetFormat() &&
m_MultiSampleCount == argMultiSampleCount &&
m_MultiSampleQuality == argMultiSampleQuality)
{
return;
}
RenderTargetBase::Uninitialize();
// get missing information
if (argMultiSampleCount == 0)
argMultiSampleCount = 1;
if (argWidth == 0)
argWidth = 1;
if (argHeight == 0)
argHeight = 1;
if (argFormat == DataFormat::Unknown)
argFormat = DataFormat::R8G8B8A8_UnsignedNormalized;
if (m_Texture == NULL)
m_Texture = &m_Engine.get_ResourceFactory().CreateOrFindTexture();
m_MultiSampleCount = argMultiSampleCount;
m_MultiSampleQuality = argMultiSampleQuality;
m_Texture->CreateRenderTargetTexture(argWidth, argHeight, argFormat, argMultiSampleCount, argMultiSampleQuality);
HRESULT lh_Result = m_Engine.get_DX10Device().CreateRenderTargetView(m_Texture->get_Texture2D(), NULL, &m_RenderTargetView);
if(FAILED(lh_Result))
throw L"RenderTargetTexture: Unable to retrieve rendertarget view.";
ViewPort viewPort;
viewPort.m_Width = argWidth;
viewPort.m_Height = argHeight;
this->set_ViewPort(viewPort);
}
void RenderTargetTexture::Resize(int argWidth, int argHeight)
{
if (m_Texture == NULL)
throw L"SwapChainResource: Access forbidden until resource has been initialized.";
if (this->get_RenderTargetWidth() == argWidth
|| this->get_RenderTargetHeight() == argHeight)
return;
bool lb_DepthStencilBuffer = this->get_HasDepthStencilBuffer();
this->SetTextureParameters(argWidth, argHeight, this->get_RenderTargetFormat(), m_MultiSampleCount, m_MultiSampleQuality);
this->set_HasDepthStencilBuffer(lb_DepthStencilBuffer);
}
void RenderTargetTexture::Uninitialize()
{
if (m_Texture != NULL)
m_Engine.get_ResourceFactory().DeleteTexture(*m_Texture);
RenderTargetBase::Uninitialize();
}
uint32 RenderTargetTexture::get_RenderTargetWidth() const
{
return m_Texture == NULL ? 0 : m_Texture->get_TextureWidth();
}
uint32 RenderTargetTexture::get_RenderTargetHeight() const
{
return m_Texture == NULL ? 0 : m_Texture->get_TextureHeight();
}
DataFormat::Enumeration RenderTargetTexture::get_RenderTargetFormat() const
{
return m_Texture == NULL ? DataFormat::Unknown : m_Texture->get_TextureFormat();
}

View File

@@ -0,0 +1,34 @@
#pragma once
#include "IRenderTargetTexture.h"
#include "../RenderTargetBase.h"
struct ITexture;
class RenderTargetTexture
: public RenderTargetBase
, public IRenderTargetTexture
{
public:
RenderTargetTexture(IEngine& argEngine);
virtual ~RenderTargetTexture();
virtual void SetTextureParameters(uint32 argWidth, uint32 argHeight, DataFormat::Enumeration argFormat, uint32 argMultiSampleCount = 1, uint32 argMultiSampleQuality = 0);
virtual void Resize(int argWidth, int argHeight);
virtual ITexture& get_TextureResource() const { return *m_Texture; }
virtual IRenderTargetBase& get_Base() { return *dynamic_cast<IRenderTargetBase*>(this); }
virtual void Uninitialize();
// IRenderTargetBase
virtual uint32 get_RenderTargetWidth() const;
virtual uint32 get_RenderTargetHeight() const;
virtual DataFormat::Enumeration get_RenderTargetFormat() const;
protected:
//ICommandUser
virtual string8 get_UserName() const { return "RenderTargetTexture"; }
private:
ITexture* m_Texture;
};

View File

@@ -0,0 +1,187 @@
#include "stdafx.h"
#include "SwapChain.h"
#include "IResourceFactory.h"
#include <exception>
SwapChain::SwapChain(IEngine& argEngine)
: RenderTargetBase(argEngine)
, m_SwapChain(NULL)
, m_VSync(true)
{
}
SwapChain::~SwapChain()
{
this->Uninitialize();
m_Engine.get_ResourceFactory().DeleteSwapChain(*const_cast<SwapChain*>(this), true);
}
void SwapChain::SetWindowParameters(HWND argWindowHandle, uint32 argWidth, uint32 argHeight, uint32 argRefreshRate, DataFormat::Enumeration argFormat, uint32 argMultiSampleCount, uint32 argMultiSampleQuality)
{
if (m_SwapChain != NULL)
this->Uninitialize();
// get missing information
if (argMultiSampleCount == 0)
argMultiSampleCount = 1;
if (argWidth == 0 || argHeight == 0)
{
RECT windowRect;
::GetClientRect(argWindowHandle, &windowRect);
if (argWidth == 0)
argWidth = windowRect.right - windowRect.left;
if (argHeight == 0)
argHeight = windowRect.bottom - windowRect.top;
}
if (argRefreshRate == 0)
argRefreshRate = 60; // 60Hz
if (argFormat == DataFormat::Unknown)
argFormat = DataFormat::R8G8B8A8_UnsignedNormalized; // RGBA(X) 8Bit per channel -> 32Bit
// build the description
ZeroMemory(&m_SwapChainDescription, sizeof(m_SwapChainDescription));
m_SwapChainDescription.BufferCount = 1;
m_SwapChainDescription.BufferDesc.Width = argWidth;
m_SwapChainDescription.BufferDesc.Height = argHeight;
m_SwapChainDescription.BufferDesc.Format = (DXGI_FORMAT)argFormat;
m_SwapChainDescription.BufferDesc.RefreshRate.Numerator = argRefreshRate;
m_SwapChainDescription.BufferDesc.RefreshRate.Denominator = 1;
m_SwapChainDescription.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
m_SwapChainDescription.OutputWindow = argWindowHandle;
m_MultiSampleCount = m_SwapChainDescription.SampleDesc.Count = argMultiSampleCount;
m_MultiSampleQuality = m_SwapChainDescription.SampleDesc.Quality = argMultiSampleQuality;
m_SwapChainDescription.Windowed = TRUE;
if (S_OK != m_Engine.get_DXGIFactory().CreateSwapChain(&m_Engine.get_DX10Device(), &m_SwapChainDescription, &m_SwapChain))
{
throw L"SwapChain: Unable to create swapchain.";
}
this->RetriveData();
ViewPort vp;
vp.m_Width = argWidth;
vp.m_Height = argHeight;
this->set_ViewPort(vp);
}
void SwapChain::Uninitialize()
{
RenderTargetBase::Uninitialize();
/*if (m_SwapChain != NULL)
m_SwapChain->Release();*/
m_SwapChain = NULL;
}
void SwapChain::Resize(int argWidth, int argHeight)
{
if (m_SwapChain == NULL || m_RenderTargetView == NULL)
{
throw L"SwapChain: Access forbidden until resource has been initialized.";
}
if (argWidth == 0 || argHeight == 0)
{
RECT windowRect;
::GetClientRect(m_SwapChainDescription.OutputWindow, &windowRect);
if (argWidth == 0)
argWidth = windowRect.right - windowRect.left;
if (argHeight == 0)
argHeight = windowRect.bottom - windowRect.top;
}
if (m_SwapChainDescription.BufferDesc.Width == argWidth ||
m_SwapChainDescription.BufferDesc.Height == argHeight)
return;
bool depthStencilBuffer = this->get_HasDepthStencilBuffer();
m_Engine.get_DX10Device().ClearState();
this->set_HasDepthStencilBuffer(false);
if (m_RenderTargetView != NULL)
m_RenderTargetView->Release();
m_RenderTargetView = NULL;
m_SwapChain->ResizeBuffers(m_SwapChainDescription.BufferCount, argWidth, argHeight, m_SwapChainDescription.BufferDesc.Format, DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH);
m_SwapChainDescription.BufferDesc.Width = argWidth;
m_SwapChainDescription.BufferDesc.Height = argHeight;
this->RetriveData();
this->set_HasDepthStencilBuffer(depthStencilBuffer);
ViewPort vp = this->get_ViewPort();
vp.m_Width = argWidth;
vp.m_Height = argHeight;
this->set_ViewPort(vp);
}
void SwapChain::set_Fullscreen(bool argState)
{
if (m_SwapChainDescription.Windowed == FALSE && argState)
{
throw L"SwapChain: Fullscreen mode already set.";
}
if (m_SwapChainDescription.Windowed == TRUE && !argState)
{
throw L"SwapChain: Windowed mode already set.";
}
m_SwapChainDescription.Windowed = argState ? FALSE : TRUE;
bool depthStencilBuffer = this->get_HasDepthStencilBuffer();
m_Engine.get_DX10Device().ClearState();
this->set_HasDepthStencilBuffer(false);
if (m_RenderTargetView != NULL)
m_RenderTargetView->Release();
m_RenderTargetView = NULL;
m_SwapChain->SetFullscreenState(m_SwapChainDescription.Windowed == FALSE, NULL);
this->RetriveData();
this->set_HasDepthStencilBuffer(depthStencilBuffer);
}
void SwapChain::Present()
{
if (m_SwapChain == NULL || m_RenderTargetView == NULL)
{
throw L"SwapChain: Access forbidden until resource has been initialized.";
}
m_SwapChain->Present(m_VSync ? 1 : 0, 0); // VSync, Flags
}
void SwapChain::RetriveData()
{
if (m_SwapChain == NULL || m_RenderTargetView != NULL)
{
throw L"SwapChain: Access forbidden until resource has been initialized.";
}
ID3D10Texture2D* backBuffer;
HRESULT result = m_SwapChain->GetBuffer(0, __uuidof(ID3D10Texture2D), (void**)&backBuffer);
if(FAILED(result))
{
throw L"SwapChain: Unable to retrive backbuffer.";
}
result = m_Engine.get_DX10Device().CreateRenderTargetView(backBuffer, NULL, &m_RenderTargetView);
backBuffer->Release();
if(FAILED(result))
{
throw L"SwapChain: Unable to retrive rendertarget view.";
}
}

View File

@@ -0,0 +1,44 @@
#pragma once
#include "IEngine.h"
#include "ISwapChain.h"
#include "../RenderTargetBase.h"
class SwapChain
: public RenderTargetBase
, public ISwapChain
{
public:
SwapChain(IEngine& argEngine);
virtual ~SwapChain();
virtual void SetWindowParameters(HWND argWindowHandle, uint32 argWidth = 0, uint32 argHeight = 0, uint32 argRefreshRate = 0, DataFormat::Enumeration argFormat = DataFormat::Unknown, uint32 argMultiSampleCount = 0, uint32 argMultiSampleQuality = 0);
virtual void Resize(int argWidth, int argHeight);
virtual void Present();
virtual bool get_Fullscreen() const { return !m_SwapChainDescription.Windowed; }
virtual void set_Fullscreen(bool argState);
virtual bool get_VSync() const { return m_VSync; }
virtual void set_VSync(bool argState) {m_VSync = argState; }
virtual IRenderTargetBase& get_Base() { return *dynamic_cast<IRenderTargetBase*>(this); }
// IRenderTargetBase
virtual uint32 get_RenderTargetWidth() const { return m_SwapChainDescription.BufferDesc.Width; }
virtual uint32 get_RenderTargetHeight() const { return m_SwapChainDescription.BufferDesc.Height; }
virtual DataFormat::Enumeration get_RenderTargetFormat() const { return (DataFormat::Enumeration)m_SwapChainDescription.BufferDesc.Format; }
protected:
//ICommandUser
virtual string8 get_UserName() const { return "SwapChain"; }
protected:
void RetriveData();
virtual void Uninitialize();
private:
DXGI_SWAP_CHAIN_DESC m_SwapChainDescription;
IDXGISwapChain* m_SwapChain;
bool m_VSync;
};