port from perforce
This commit is contained in:
308
aiwaz/Aiwaz/Resources/RenderTarget/RenderTargetBase.cpp
Normal file
308
aiwaz/Aiwaz/Resources/RenderTarget/RenderTargetBase.cpp
Normal 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);
|
||||
}
|
||||
81
aiwaz/Aiwaz/Resources/RenderTarget/RenderTargetBase.h
Normal file
81
aiwaz/Aiwaz/Resources/RenderTarget/RenderTargetBase.h
Normal 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];
|
||||
};
|
||||
@@ -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();
|
||||
}
|
||||
@@ -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;
|
||||
};
|
||||
187
aiwaz/Aiwaz/Resources/RenderTarget/SwapChain/SwapChain.cpp
Normal file
187
aiwaz/Aiwaz/Resources/RenderTarget/SwapChain/SwapChain.cpp
Normal 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.";
|
||||
}
|
||||
}
|
||||
44
aiwaz/Aiwaz/Resources/RenderTarget/SwapChain/SwapChain.h
Normal file
44
aiwaz/Aiwaz/Resources/RenderTarget/SwapChain/SwapChain.h
Normal 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;
|
||||
};
|
||||
Reference in New Issue
Block a user