port from perforce
This commit is contained in:
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