Files
LifeProject/LifeGraphics/render/dx11/RendererDX11.cpp
T
2025-05-13 02:46:21 +03:00

1335 lines
42 KiB
C++

#pragma once
#include "render/dx11/RendererDX11.h"
#include "vfs/fs_win/IFSContentProvider.h"
#include "LString.h"
#include "vfs/IFile.h"
#include <log/CLog.h>
#include "render/dx11/IConstantBuffer11.h"
#include "render/IMaterial.h"
#include "D3DX10math.h"
#include "render/dx11/IDepthStencilState11.h"
#include <D3Dcompiler.h>
#include "d3d11sdklayers.h"
#include <dxgi.h>
#include <assert.h>
namespace LifeGraphics
{
HRESULT RendererDX11::Open(RenderParams params)
{
HRESULT hr = S_OK;
g_params = params;
D3D_DRIVER_TYPE drivers[]=
{
D3D_DRIVER_TYPE_HARDWARE,
D3D_DRIVER_TYPE_WARP,
D3D_DRIVER_TYPE_REFERENCE
};
D3D_FEATURE_LEVEL featureLevels[] =
{
D3D_FEATURE_LEVEL_11_0,
D3D_FEATURE_LEVEL_10_1,
D3D_FEATURE_LEVEL_10_0,
};
int numDrivers = 1;
for(int i = 0; i< numDrivers; i++)
{
g_driverType = drivers[i];
#ifdef _DEBUG
hr = D3D11CreateDevice(0,g_driverType,NULL, D3D11_CREATE_DEVICE_DEBUG,featureLevels,3,D3D11_SDK_VERSION,&g_pDevice, &g_pFeatureLevel, &g_pDeviceContext);
#else
hr = D3D11CreateDevice(0,g_driverType,NULL, NULL,featureLevels,3,D3D11_SDK_VERSION,&g_pDevice, &g_pFeatureLevel, &g_pDeviceContext);
#endif
if(SUCCEEDED(hr))
break;
}
char ps[] = "Texture2D diffuseTexture : register(t0);" \
"SamplerState diffuseSampler : register(s0);" \
"half4 main_PS( in float4 Pos : SV_Position, in float2 t : TEXCOORD0 ) : SV_Target" \
"{half4 data = diffuseTexture.Sample(diffuseSampler, t); return data; }";
char vs[] = "struct VS_OUTPUT" \
"{float4 Position : SV_Position;" \
"float2 Texcoord : TEXCOORD0;};" \
"void main_VS( in float4 Pos : POSITION, in float2 t : TEXCOORD0, out float4 Position : SV_Position, out float2 texcoord : TEXCOORD0 )" \
"{Position = Pos; texcoord = t;}";
char vbPs[] = "cbuffer data : register(b0){float4 vBlurOffsets[9];};" \
"Texture2D originalSceneSampler : register(t0);" \
"SamplerState linearSampler : register(s0);" \
"float4 main_PS( in float4 Position : SV_Position, in float2 texcoord : TEXCOORD0 ) : SV_Target" \
"{ float4 color = { 0.0f, 0.0f, 0.0f, 0.0f };" \
"for( int i = 0; i < 9; i++ )" \
" color += originalSceneSampler.Sample( linearSampler, texcoord + float2( 0.0f, vBlurOffsets[i].x ) ) * vBlurOffsets[i].y;" \
"return float4( color.rgb, 1.0f ); }";
ID3DBlob* vbblob = NULL;
hr = D3DX11CompileFromMemory(vbPs, strlen(vbPs), "system_shader", NULL, NULL, "main_PS", "ps_4_0",0,0,NULL, &vbblob,NULL, NULL);
if( FAILED( hr ) )
return hr;
hr = g_pDevice->CreatePixelShader(vbblob->GetBufferPointer(), vbblob->GetBufferSize(), NULL, &psVerticalBlur);
if( FAILED( hr ) )
return hr;
SAFE_RELEASE(vbblob);
ID3DBlob* blob = NULL;
hr = D3DX11CompileFromMemory(ps, strlen(ps), "system_shader", NULL, NULL, "main_PS", "ps_4_0",0,0,NULL, &blob,NULL, NULL);
if( FAILED( hr ) )
return hr;
hr = g_pDevice->CreatePixelShader(blob->GetBufferPointer(), blob->GetBufferSize(), NULL, &psQuad);
if( FAILED( hr ) )
return hr;
ID3DBlob* vsblob = NULL;
hr = D3DX11CompileFromMemory(vs, strlen(vs), "system_shader2", NULL, NULL, "main_VS", "vs_4_0",0,0,NULL, &vsblob,NULL, NULL);
if( FAILED( hr ) )
return hr;
hr = g_pDevice->CreateVertexShader(vsblob->GetBufferPointer(), vsblob->GetBufferSize(), NULL, &vsQuad);
if( FAILED( hr ) )
return hr;
SimpleVertex geometry[] =
{
LifeMath::float4(-1.0f,-1.0f,0.0f,1.0f), LifeMath::float2(0.0f,1.0f),
LifeMath::float4(-1.0f,1.0f,0.0f,1.0f), LifeMath::float2(0.0f,0.0f),
LifeMath::float4(1.0f,-1.0f,0.0f,1.0f), LifeMath::float2(1.0f,1.0f),
LifeMath::float4(1.0f,1.0f,0.0f,1.0f), LifeMath::float2(1.0f,0.0f),
};
char ds2x2_data[] =
" cbuffer texInfo : register(b12)" \
"{" \
" float2 texelSize;" \
" float2 dummy;" \
"};" \
"Texture2D diffuseMap : register(t0);" \
"SamplerState pointSampler : register(s0);" \
"static const float PixelKernel[13] =" \
"{" \
" -6.0f," \
" -5.0f," \
" -4.0f," \
" -3.0f," \
" -2.0f," \
" -1.0f," \
" 0.0f," \
" 1.0f," \
" 2.0f," \
" 3.0f," \
" 4.0f," \
" 5.0f," \
" 6.0f," \
"};" \
"static const float BlurWeights[13] = " \
"{" \
" 0.001108f," \
" 0.004382f," \
" 0.013497f," \
" 0.032379f," \
" 0.060493f," \
" 0.088017f," \
" 0.099735f," \
" 0.088017f," \
" 0.060493f," \
" 0.032379f," \
" 0.013497f," \
" 0.004382f," \
" 0.001108f," \
"};" \
"float4 main_PS(in float4 Position : SV_Position, in float2 texcoord : TEXCOORD0) : SV_Target" \
"{" \
" float4 color = (float4)0;" \
"[Unroll]" \
" for(int i = 0; i < 13; i++)" \
" {" \
" color += diffuseMap.Sample(pointSampler, texcoord + float2(0.0f, PixelKernel[i] * texelSize.y)) * BlurWeights[i];" \
" color += diffuseMap.Sample(pointSampler, texcoord + float2(PixelKernel[i] * texelSize.x, 0.0f)) * BlurWeights[i];" \
" }" \
" return color;" \
"} ";
ds2x2 = CompileUserShaderPS(ds2x2_data);
ds2x2cb = CreateConstantBuffer(sizeof(LifeMath::float4));
D3D11_BUFFER_DESC bd;
ZeroMemory( &bd, sizeof(bd) );
bd.Usage = D3D11_USAGE_DEFAULT;
bd.ByteWidth = sizeof( SimpleVertex ) * 4;
bd.BindFlags = D3D11_BIND_VERTEX_BUFFER;
bd.CPUAccessFlags = 0;
D3D11_SUBRESOURCE_DATA InitData;
ZeroMemory( &InitData, sizeof(InitData) );
InitData.pSysMem = geometry;
hr = g_pDevice->CreateBuffer( &bd, &InitData, &fsQuadBuffer );
if( FAILED( hr ) )
return hr;
D3D11_INPUT_ELEMENT_DESC desc[] =
{
{ "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 },
{ "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 16, D3D11_INPUT_PER_VERTEX_DATA, 0 },
};
UINT numElements = ARRAYSIZE( desc );
fsQuadLayout = 0;
hr = g_pDevice->CreateInputLayout(desc,numElements, vsblob->GetBufferPointer(), vsblob->GetBufferSize(), &fsQuadLayout);
if( FAILED( hr ) )
return hr;
SAFE_RELEASE(vsblob);
SAFE_RELEASE(blob);
/*D3D11_VIEWPORT vp;
vp.Height = (float)g_params.ScreenHeight;
vp.Width = (float)g_params.ScreenWidth;
vp.TopLeftX = 0.0f;
vp.TopLeftY = 0.0f;
vp.MinDepth = 0.0f;
vp.MaxDepth = 1.0f;
g_pDeviceContext->RSSetViewports(1, &vp);*/
D3D11_SAMPLER_DESC lsDesc;
ZeroMemory(&lsDesc, sizeof(D3D11_SAMPLER_DESC));
lsDesc.AddressU = D3D11_TEXTURE_ADDRESS_WRAP;
lsDesc.AddressV = D3D11_TEXTURE_ADDRESS_WRAP;
lsDesc.AddressW = D3D11_TEXTURE_ADDRESS_WRAP;
lsDesc.ComparisonFunc = D3D11_COMPARISON_NEVER;
lsDesc.MaxAnisotropy = 0;
lsDesc.MinLOD = 0;
lsDesc.MaxLOD = 16;
lsDesc.Filter = D3D11_FILTER_MIN_MAG_MIP_POINT;
g_pDevice->CreateSamplerState(&lsDesc,&samplerPoint);
g_pDeviceContext->PSSetSamplers(1,1, &samplerPoint);
D3D11_SAMPLER_DESC lsDesc2;
ZeroMemory(&lsDesc2, sizeof(D3D11_SAMPLER_DESC));
lsDesc2.AddressU = D3D11_TEXTURE_ADDRESS_WRAP;
lsDesc2.AddressV = D3D11_TEXTURE_ADDRESS_WRAP;
lsDesc2.AddressW = D3D11_TEXTURE_ADDRESS_WRAP;
lsDesc2.ComparisonFunc = D3D11_COMPARISON_NEVER;
lsDesc2.MaxAnisotropy = 16;
lsDesc2.MinLOD = 0;
lsDesc2.MaxLOD = 16;
lsDesc2.Filter = D3D11_FILTER_MIN_MAG_MIP_LINEAR;
g_pDevice->CreateSamplerState(&lsDesc2,&samplerLinear);
g_pDeviceContext->PSSetSamplers(0,1, &samplerLinear);
D3D11_RASTERIZER_DESC rsDesc;
rsDesc.AntialiasedLineEnable = false;
rsDesc.CullMode = D3D11_CULL_BACK;
rsDesc.DepthBias = 0;
rsDesc.DepthBiasClamp = 0.0f;
rsDesc.SlopeScaledDepthBias = 0.0f;
rsDesc.DepthClipEnable = TRUE;
rsDesc.FillMode = D3D11_FILL_SOLID;
rsDesc.FrontCounterClockwise = FALSE;
rsDesc.MultisampleEnable = FALSE;
rsDesc.ScissorEnable = TRUE;
g_pDevice->CreateRasterizerState(&rsDesc, &rState);
g_pDeviceContext->RSSetState(rState);
vbBuffer = CreateConstantBuffer(16 * 16);
return hr;
}
ISwapChain* RendererDX11::CreateSwapChain(LifeCore::IRenderWindow* window){
return static_cast<ISwapChain*>(new ISwapChain11(g_pDevice, window));
}
int RendererDX11::GetDisplayModes(LifeCore::DisplayMode** modeList)
{
//get display mode count
UINT numModes;
pDXGIOutput->GetDisplayModeList(DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_ENUM_MODES_INTERLACED, &numModes, NULL);
//get display modes
DXGI_MODE_DESC* modes = new DXGI_MODE_DESC[numModes];
pDXGIOutput->GetDisplayModeList(DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_ENUM_MODES_INTERLACED, &numModes, modes);
LifeCore::DisplayMode* m = new LifeCore::DisplayMode[numModes];
int pos = 0;
for(UINT i = 0; i < numModes; i++)
{
if(pos==0)
{
m[pos].width = modes[i].Width;
m[pos].height = modes[i].Height;
m[pos].refreshRate = modes[i].RefreshRate.Numerator;
m[pos].bpp = 4;
pos++;
}
else
{
int prev = i - 1;
if(modes[prev].Width != modes[i].Width || modes[prev].Height != modes[i].Height || modes[prev].RefreshRate.Numerator != modes[i].RefreshRate.Numerator)
{
m[pos].width = modes[i].Width;
m[pos].height = modes[i].Height;
m[pos].refreshRate = modes[i].RefreshRate.Numerator;
m[pos].bpp = 4;
pos++;
}
}
}
(*modeList) = m;
return pos;
}
void RendererDX11::DownSample2x2(ITexture2D* src, ITexture2D* dst, ITexture2D* depth)
{
LifeMath::float4 data;
data.X = 1.0f / (float)dst->Width();
data.Y = 1.0f / (float)dst->Height();
ds2x2cb->Update(&data, sizeof(LifeMath::float4));
LifeMath::Rect2i vp = LifeMath::Rect2i(0,0,dst->Width(), dst->Height());
SetPixelShader(ds2x2);
SetPSConstantBuffer(ds2x2cb, 12);
SetScissorRectangle(vp);
SetViewport(vp);
SetPSTexture(src, 0);
SetTargets(dst, depth);
RenderToTextureNoPs();
}
void RendererDX11::BlurGaussH(ITexture2D* src, ITexture2D* dst, ITexture2D* depth)
{
LifeMath::float4 data;
data.X = 1.0f / (float)dst->Width();
data.Y = 1.0f / (float)dst->Height();
ds2x2cb->Update(&data, sizeof(LifeMath::float4));
}
void RendererDX11::BlurGaussV(ITexture2D* src, ITexture2D* dst, ITexture2D* depth)
{
LifeMath::float4 data;
data.X = 1.0f / (float)src->Width();
data.Y = 1.0f / (float)src->Height();
ds2x2cb->Update(&data, sizeof(LifeMath::float4));
}
void ClearD3D11DeviceContext( ID3D11DeviceContext* pd3dDeviceContext )
{
// Unbind all objects from the immediate context
if (pd3dDeviceContext == NULL) return;
ID3D11ShaderResourceView* pSRVs[16] = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 };
ID3D11RenderTargetView* pRTVs[16] = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 };
ID3D11DepthStencilView* pDSV = NULL;
ID3D11Buffer* pBuffers[16] = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 };
ID3D11SamplerState* pSamplers[16] = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 };
UINT StrideOffset[16] = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 };
// Shaders
pd3dDeviceContext->VSSetShader( NULL, NULL, 0 );
pd3dDeviceContext->HSSetShader( NULL, NULL, 0 );
pd3dDeviceContext->DSSetShader( NULL, NULL, 0 );
pd3dDeviceContext->GSSetShader( NULL, NULL, 0 );
pd3dDeviceContext->PSSetShader( NULL, NULL, 0 );
// IA clear
pd3dDeviceContext->IASetVertexBuffers( 0, 16, pBuffers, StrideOffset, StrideOffset );
pd3dDeviceContext->IASetIndexBuffer( NULL, DXGI_FORMAT_R16_UINT, 0 );
pd3dDeviceContext->IASetInputLayout( NULL );
// Constant buffers
pd3dDeviceContext->VSSetConstantBuffers( 0, 14, pBuffers );
pd3dDeviceContext->HSSetConstantBuffers( 0, 14, pBuffers );
pd3dDeviceContext->DSSetConstantBuffers( 0, 14, pBuffers );
pd3dDeviceContext->GSSetConstantBuffers( 0, 14, pBuffers );
pd3dDeviceContext->PSSetConstantBuffers( 0, 14, pBuffers );
// Resources
pd3dDeviceContext->VSSetShaderResources( 0, 16, pSRVs );
pd3dDeviceContext->HSSetShaderResources( 0, 16, pSRVs );
pd3dDeviceContext->DSSetShaderResources( 0, 16, pSRVs );
pd3dDeviceContext->GSSetShaderResources( 0, 16, pSRVs );
pd3dDeviceContext->PSSetShaderResources( 0, 16, pSRVs );
// Samplers
pd3dDeviceContext->VSSetSamplers( 0, 16, pSamplers );
pd3dDeviceContext->HSSetSamplers( 0, 16, pSamplers );
pd3dDeviceContext->DSSetSamplers( 0, 16, pSamplers );
pd3dDeviceContext->GSSetSamplers( 0, 16, pSamplers );
pd3dDeviceContext->PSSetSamplers( 0, 16, pSamplers );
// Render targets
pd3dDeviceContext->OMSetRenderTargets( 8, pRTVs, pDSV );
// States
FLOAT blendFactor[4] = { 0,0,0,0 };
pd3dDeviceContext->OMSetBlendState( NULL, blendFactor, 0xFFFFFFFF );
pd3dDeviceContext->OMSetDepthStencilState( NULL, 0 );
pd3dDeviceContext->RSSetState( NULL );
}
void RendererDX11::BeginCleanup()
{
g_pDeviceContext->ClearState();
g_pDeviceContext->Flush();
ClearD3D11DeviceContext(g_pDeviceContext);
SAFE_DELETE(vbBuffer);
SAFE_RELEASE(rState);
SAFE_RELEASE(samplerLinear);
SAFE_RELEASE(samplerPoint);
SAFE_RELEASE(fsQuadLayout);
SAFE_RELEASE(fsQuadBuffer);
SAFE_RELEASE(psVerticalBlur);
SAFE_RELEASE(psQuad);
SAFE_RELEASE(vsQuad);
g_pDeviceContext->ClearState();
g_pDeviceContext->Flush();
}
void RendererDX11::EndCleanup()
{
g_pDeviceContext->ClearState();
g_pDeviceContext->Flush();
SAFE_RELEASE(g_pDevice);
g_pDeviceContext->Release();
g_pDeviceContext->ClearState();
g_pDeviceContext->Flush();
SAFE_RELEASE(g_pDeviceContext);
}
void RendererDX11::Close()
{
/*#ifdef _DEBUG
ID3D11Debug* pDebug;
g_pDevice->QueryInterface( IID_ID3D11Debug, (VOID**)(&pDebug) );
pDebug->ReportLiveDeviceObjects(D3D11_RLDO_DETAIL);
pDebug->Release();
#endif*/
}
IRasterizerState* RendererDX11::CreateRasterizerState(FILL_MODE mode)
{
return new IRasterizerState11(mode, g_pDevice);
}
IRasterizerState* RendererDX11::CreateRasterizerState(FILL_MODE mode, CULL_MODE cmode)
{
return new IRasterizerState11(mode, g_pDevice, cmode);
}
void RendererDX11::SetRasterizerState(IRasterizerState* state)
{
IRasterizerState11* s = static_cast<IRasterizerState11*>(state);
g_pDeviceContext->RSSetState(s->state);
}
IShader* RendererDX11::CompileUserShaderPS(char* data)
{
//HRESULT hr;
ID3D11PixelShader* ps;
ID3DBlob* vbblob = NULL;
D3DX11CompileFromMemory(data, strlen(data), "system_shader", NULL, NULL, "main_PS", "ps_4_0",0,0,NULL, &vbblob,NULL, NULL);
g_pDevice->CreatePixelShader(vbblob->GetBufferPointer(), vbblob->GetBufferSize(), NULL, &ps);
ID3DBlob* dasm = NULL;
D3DDisassemble(vbblob->GetBufferPointer(), vbblob->GetBufferSize(), D3D_DISASM_ENABLE_DEFAULT_VALUE_PRINTS | D3D_DISASM_ENABLE_INSTRUCTION_NUMBERING, "OLOLO", &dasm);
LifeCore::CLog::me()->Write(String((char*)dasm->GetBufferPointer()));
IPixelShader11* nps = new IPixelShader11(g_pDevice);
nps->g_shader = ps;
vbblob->Release();
return nps;
}
void RendererDX11::SetPSTextureSampler(ITextureSampler* sampler, int slot)
{
ITextureSampler11* ts = static_cast<ITextureSampler11*>(sampler);
g_pDeviceContext->PSSetSamplers(slot,1,&ts->state);
}
void RendererDX11::SetPSTextureNULL(int slot)
{
ID3D11ShaderResourceView *const pSRV[1] = {NULL};
g_pDeviceContext->PSSetShaderResources(slot,1, pSRV);
}
/*void RendererDX11::ClearBuffers(int flags, int rtColor, float zValue, int stencilValue)
{
if(g_pDevice)
{
float r,g,b,a;
r = (float)((rtColor >> 24) & 0xff) / 255.0f;
g = (float)((rtColor >> 16) & 0xff) / 255.0f;
b = (float)((rtColor >> 8) & 0xff) / 255.0f;
a = (float)((rtColor >> 0) & 0xff) / 255.0f;
float clearColor[4];
clearColor[0] = r;
clearColor[1] = g;
clearColor[2] = b;
clearColor[3] = a;
if((flags & CF_COLOR_TARGET)!=0)
g_pDeviceContext->ClearRenderTargetView(currentBackBuffer, clearColor);
if((flags & CF_DEPTH_BUFFER)!=0)
g_pDeviceContext->ClearDepthStencilView(currentDepthBuffer,D3D11_CLEAR_DEPTH | D3D11_CLEAR_STENCIL, zValue, (UINT8)stencilValue);
}
}*/
void RendererDX11::ClearDepthStencil(ITexture2D* tex, float zValue, int stencilValue)
{
g_pDeviceContext->ClearDepthStencilView(static_cast<ITexture2D11*>(tex)->getDSView(),D3D11_CLEAR_DEPTH | D3D11_CLEAR_STENCIL,zValue, (UINT8)stencilValue);
}
void RendererDX11::ClearDepthStencil(ITexture2D* tex, int flag, float zValue, int stencilValue)
{
g_pDeviceContext->ClearDepthStencilView(static_cast<ITexture2D11*>(tex)->getDSView(),flag,zValue, (UINT8)stencilValue);
}
void RendererDX11::ClearRenderTarget(ITexture2D* tex, LifeMath::float4* color)
{
float clearColor[4];
clearColor[0] = color->X;
clearColor[1] = color->Y;
clearColor[2] = color->Z;
clearColor[3] = color->W;
IRenderTargetView11* rtv = static_cast<IRenderTargetView11*>(tex->getRTView());
g_pDeviceContext->ClearRenderTargetView(rtv->view, clearColor);
}
void RendererDX11::ClearRenderTarget(ISurface* target, LifeMath::float4* color)
{
float clearColor[4];
clearColor[0] = color->X;
clearColor[1] = color->Y;
clearColor[2] = color->Z;
clearColor[3] = color->W;
ISurface11* rtv = static_cast<ISurface11*>(target);
g_pDeviceContext->ClearRenderTargetView(rtv->getRTV(), clearColor);
}
void RendererDX11::ClearDepthStencil(ISurface* target, int flag, float zValue, int stencilValue)
{
g_pDeviceContext->ClearDepthStencilView(static_cast<ISurface11*>(target)->getDSV(), flag, zValue, (UINT8)stencilValue);
}
ITexture2D* RendererDX11::CreateRenderTarget(int width, int height, int format)
{
DXGI_SAMPLE_DESC samDesc;
samDesc.Count = 1;
samDesc.Quality = 0;
D3D11_TEXTURE2D_DESC desc = {0};
desc.ArraySize = 1;
desc.BindFlags = D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE;
desc.CPUAccessFlags = 0;
desc.Format = (DXGI_FORMAT)format;
desc.MipLevels = 1;
desc.SampleDesc = samDesc;
desc.Usage = D3D11_USAGE_DEFAULT;
desc.Width = width;
desc.Height = height;
ID3D11Texture2D* tex;
g_pDevice->CreateTexture2D(&desc, NULL, &tex);
ITexture2D11* rTex = new ITexture2D11(g_pDevice);
rTex->pDevice = g_pDevice;
rTex->FromTexture(tex);
ID3D11RenderTargetView* rt;
g_pDevice->CreateRenderTargetView(tex, NULL, &rt);
IRenderTargetView11* rtv = new IRenderTargetView11(rt);
rTex->pDevice = g_pDevice;
rTex->IsRenderTarget = true;
rTex->addRenderTargetView(rtv);
ID3D11ShaderResourceView* rv;
g_pDevice->CreateShaderResourceView(tex, NULL, &rv);
rTex->addShaderResourceView(new IShaderResourceView11(rv));
return rTex;
}
ITexture2D* RendererDX11::LoadTexture2D(LifeCore::IDataStreamPtr src)
{
ITexture2D11* ret = new ITexture2D11(g_pDevice);
ret->pDevice = g_pDevice;
ret->Load(src);
ret->GetData()->AddRef();
ID3D11ShaderResourceView* rv;
g_pDevice->CreateShaderResourceView(ret->GetData(), NULL, &rv);
ret->addShaderResourceView(new IShaderResourceView11(rv));
rv->AddRef();
return ret;
}
ITexture2D* RendererDX11::CreateTexture2D(int canRead, int canWrite, int width, int height, int format)
{
DXGI_SAMPLE_DESC samDesc;
samDesc.Count = 1;
samDesc.Quality = 0;
D3D11_TEXTURE2D_DESC desc = {0};
desc.ArraySize = 1;
desc.BindFlags = D3D11_BIND_SHADER_RESOURCE;
if (canWrite)
desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
else
desc.CPUAccessFlags = 0;
if (canRead)
desc.CPUAccessFlags |= D3D11_CPU_ACCESS_READ;
desc.Format = (DXGI_FORMAT)format;
desc.MipLevels = 1;
desc.SampleDesc = samDesc;
desc.Width = width;
desc.Height = height;
if (canWrite | canRead)
desc.Usage = D3D11_USAGE_DYNAMIC;
// else
// desc.Usage = D3D11_USAGE_DYNAMIC;
ID3D11Texture2D* tex;
g_pDevice->CreateTexture2D(&desc, NULL, &tex);
ITexture2D11* result = new ITexture2D11(g_pDevice);
result->FromTexture(tex);
ID3D11ShaderResourceView* rv;
g_pDevice->CreateShaderResourceView(tex, NULL, &rv);
result->addShaderResourceView(new IShaderResourceView11(rv));
rv->AddRef();
tex->AddRef();
return result;
}
void RendererDX11::RenderToTextureNoShader()
{
g_pDeviceContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
g_pDeviceContext->IASetInputLayout(fsQuadLayout);
UINT stride = sizeof(SimpleVertex);
UINT offset = 0;
g_pDeviceContext->IASetVertexBuffers(0,1, &fsQuadBuffer, &stride, &offset);
g_pDeviceContext->Draw(4, 0);
}
void RendererDX11::RenderToTexture()
{
g_pDeviceContext->PSSetShader(psQuad, NULL, 0);
g_pDeviceContext->VSSetShader(vsQuad, NULL, 0);
g_pDeviceContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
g_pDeviceContext->IASetInputLayout(fsQuadLayout);
UINT stride = sizeof(SimpleVertex);
UINT offset = 0;
g_pDeviceContext->IASetVertexBuffers(0,1, &fsQuadBuffer, &stride, &offset);
g_pDeviceContext->Draw(4, 0);
}
void RendererDX11::RenderToTextureNoPs()
{
g_pDeviceContext->VSSetShader(vsQuad, NULL, 0);
g_pDeviceContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
g_pDeviceContext->IASetInputLayout(fsQuadLayout);
UINT stride = sizeof(SimpleVertex);
UINT offset = 0;
g_pDeviceContext->IASetVertexBuffers(0,1, &fsQuadBuffer, &stride, &offset);
g_pDeviceContext->Draw(4, 0);
}
IVertexBuffer* RendererDX11::CreateVertexBuffer(int size, void* data, int stride)
{
return new IVertexBuffer11(g_pDevice, data, size, stride, false);
}
IVertexBuffer* RendererDX11::CreateVertexBufferDynamic(int size, int stride)
{
return new IVertexBuffer11(g_pDevice, NULL, size, stride, false);
}
IIndexBuffer* RendererDX11::CreateIndexBuffer(int size, void* data, int sixteenBit)
{
return new IIndexBuffer11(g_pDevice, data, size,sixteenBit, false);
}
IIndexBuffer* RendererDX11::CreateIndexBufferDynamic(int size, bool sixteenBit)
{
return new IIndexBuffer11(g_pDevice, NULL, size,sixteenBit, false);
}
IInputLayout* RendererDX11::CreateInputLayout(IInputElement* elements, int elementCount, IShader* vertexShader)
{
IVertexShader11* vs = (IVertexShader11*)vertexShader;
D3D11_INPUT_ELEMENT_DESC* desc = new D3D11_INPUT_ELEMENT_DESC[elementCount];
HRESULT hr;
for(int i = 0; i< elementCount; i++)
{
desc[i].SemanticName = elements[i].Name.c_str();
desc[i].SemanticIndex = elements[i].SemanticIndex;
desc[i].InstanceDataStepRate = elements[i].InstancingRate;
desc[i].Format = (DXGI_FORMAT)elements[i].Format;
desc[i].InputSlot = elements[i].Slot;
desc[i].AlignedByteOffset = elements[i].Offset;
if(elements[i].IsInstancingData)
desc[i].InputSlotClass = D3D11_INPUT_PER_INSTANCE_DATA;
else
desc[i].InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA;
}
IInputLayout11* layout = new IInputLayout11();
hr = g_pDevice->CreateInputLayout(desc,elementCount, vs->g_bytecode->GetBufferPointer(), vs->g_bytecode->GetBufferSize(), &layout->Decl);
// if( FAILED( hr ) )
// return hr;
return layout;
}
IShader* RendererDX11::CompileVertexShader(const char* pData, int length)
{
char* tmp = new char[length + 1];
tmp[length] = 0;
memcpy(&tmp[0], pData, length);
//printf("%s\n", tmp);
IVertexShader11* vs = new IVertexShader11(g_pDevice);
vs->Compile(pData, length, NULL);
return vs;
}
IShader* RendererDX11::CompileVertexShader(LifeCore::IDataStreamPtr stream)
{
IVertexShader11* vs = new IVertexShader11(g_pDevice);
vs->Compile(stream, NULL);
return vs;
}
IShader* RendererDX11::CompileVertexShader(LifeCore::IDataStreamPtr stream, std::vector<IMacroDefine>* defines)
{
IVertexShader11* vs = new IVertexShader11(g_pDevice);
vs->Compile(stream, defines);
return vs;
}
IShader* RendererDX11::CompilePixelShader(const char* pData, int length)
{
IPixelShader11* ps = new IPixelShader11(g_pDevice);
ps->Compile(pData, length, NULL);
return ps;
}
IShader* RendererDX11::CompilePixelShader(LifeCore::IDataStreamPtr stream)
{
IPixelShader11* ps = new IPixelShader11(g_pDevice);
ps->Compile(stream, NULL);
return ps;
}
IShader* RendererDX11::CompilePixelShader(LifeCore::IDataStreamPtr stream, std::vector<IMacroDefine>* defines)
{
IPixelShader11* ps = new IPixelShader11(g_pDevice);
ps->Compile(stream, defines);
return ps;
}
IConstantBuffer* RendererDX11::CreateConstantBuffer(int size)
{
return new IConstantBuffer11(g_pDevice, size);
}
void RendererDX11::SetVSConstantBuffer(IConstantBuffer* buffer, int slot)
{
IConstantBuffer11* cb = (IConstantBuffer11*)buffer;
g_pDeviceContext->VSSetConstantBuffers(slot,1,&cb->buffer);
}
void RendererDX11::SetPSConstantBuffer(IConstantBuffer* buffer, int slot)
{
IConstantBuffer11* cb = (IConstantBuffer11*)buffer;
g_pDeviceContext->PSSetConstantBuffers(slot,1,&cb->buffer);
}
void RendererDX11::RenderMesh(IMesh* mesh)
{
IIndexBuffer11* ib = (IIndexBuffer11*)mesh->indexData;
IVertexBuffer11* vb = (IVertexBuffer11*)mesh->vertexData;
g_pDeviceContext->IASetIndexBuffer(ib->ib, DXGI_FORMAT_R16_UINT, 0);
UINT offset = 0;
g_pDeviceContext->IASetVertexBuffers(0,1, &vb->vb, &vb->stride, &offset);
SetInputLayout(mesh->inputLayout);
g_pDeviceContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
for(int i = 0; i<mesh->subsetCount; i++)
{
//IMaterial* mat = &mesh->subsets[i].material;
//SetMaterial(mat);
g_pDeviceContext->DrawIndexed(mesh->subsets[i].Length * 3, mesh->subsets[i].Offset * 3, 0);
}
}
void RendererDX11::SetInputLayout(IInputLayout* layout)
{
IInputLayout11* il = (IInputLayout11*)layout;
g_pDeviceContext->IASetInputLayout(il->Decl);
}
void RendererDX11::SetMaterial(IMaterial* material)
{
assert(false && "SetMaterial is obsolete!");
/*if(material->diffuseMap.ptr())
{
ITexture2D11* diffuse = (ITexture2D11*)material->diffuseMap.ptr();
ID3D11ShaderResourceView* tex = static_cast<IShaderResourceView11*>(diffuse->getSRView())->view;
g_pDeviceContext->PSSetShaderResources(0,1,&tex);
}*/
//IVertexShader11* vs = (IVertexShader11*)material->vertexShader;
// IPixelShader11* ps = (IPixelShader11*)material->pixelShader;
// g_pDeviceContext->PSSetShader(ps->g_shader,NULL, 0);
// g_pDeviceContext->VSSetShader(vs->g_shader,NULL, 0);
}
ITexture2D* RendererDX11::CreateDepthTarget(int width, int height, int format)
{
D3D11_TEXTURE2D_DESC desc;
ZeroMemory(&desc, sizeof(D3D11_TEXTURE2D_DESC));
desc.ArraySize = 1;
desc.BindFlags = D3D11_BIND_DEPTH_STENCIL;
desc.Format = (DXGI_FORMAT)format;
if(desc.Format == DXGI_FORMAT_R32_TYPELESS)
{
desc.BindFlags |= D3D11_BIND_SHADER_RESOURCE;
}
desc.CPUAccessFlags = 0;
//desc.Format = DXGI_FORMAT_D32_FLOAT;
desc.MipLevels = 1;
desc.SampleDesc.Count = 1;
desc.SampleDesc.Quality = 0;
desc.Usage = D3D11_USAGE_DEFAULT;
desc.Width = width;
desc.Height = height;
ID3D11Texture2D* tex;
g_pDevice->CreateTexture2D(&desc, NULL, &tex);
ITexture2D11* rTex = new ITexture2D11(g_pDevice);
rTex->pDevice = g_pDevice;
rTex->FromTexture(tex);
ID3D11DepthStencilView* dt;
D3D11_DEPTH_STENCIL_VIEW_DESC dsViewDesc;
if(desc.Format == DXGI_FORMAT_R32_TYPELESS)
dsViewDesc.Format = DXGI_FORMAT_D32_FLOAT;
else
dsViewDesc.Format = desc.Format;
dsViewDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2DMS;
dsViewDesc.Texture2D.MipSlice = 0;
dsViewDesc.Flags = 0;
g_pDevice->CreateDepthStencilView(tex, &dsViewDesc, &dt);
//g_pDevice->CreateRenderTargetView(tex, NULL, &dt);
if(desc.Format == DXGI_FORMAT_R32_TYPELESS)
{
ID3D11ShaderResourceView* srv;
D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
srvDesc.Format = DXGI_FORMAT_R32_FLOAT;
srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
srvDesc.Texture2D.MipLevels = 1;
srvDesc.Texture2D.MostDetailedMip = 0;
g_pDevice->CreateShaderResourceView(tex,&srvDesc,&srv);
IShaderResourceView11* srv11 = new IShaderResourceView11(srv);
rTex->addShaderResourceView(srv11);
}
rTex->pDevice = g_pDevice;
rTex->IsDepthTarget = true;
rTex->addDepthStencilView(dt);
return rTex;
}
ITexture2D* RendererDX11::CreateDepthTargetCube(int width, int format)
{
D3D11_TEXTURE2D_DESC desc;
ZeroMemory(&desc, sizeof(D3D11_TEXTURE2D_DESC));
desc.ArraySize = 6;
desc.BindFlags = D3D11_BIND_DEPTH_STENCIL;
desc.CPUAccessFlags = 0;
desc.Format = (DXGI_FORMAT)format;
if(desc.Format == DXGI_FORMAT_R32_TYPELESS)
{
desc.BindFlags |= D3D11_BIND_SHADER_RESOURCE;
}
desc.MipLevels = 1;
desc.SampleDesc.Count = 1;
desc.SampleDesc.Quality = 0;
desc.Usage = D3D11_USAGE_DEFAULT;
desc.Width = width;
desc.Height = desc.Width;
desc.MiscFlags = D3D11_RESOURCE_MISC_TEXTURECUBE;
//create depth texture
ID3D11Texture2D* tex;
g_pDevice->CreateTexture2D(&desc, NULL, &tex);
ITexture2D11* rTex = new ITexture2D11(g_pDevice);
rTex->pDevice = g_pDevice;
rTex->FromTexture(tex);
for(int i = 0; i<6; i++)
{
ID3D11DepthStencilView* dt;
D3D11_DEPTH_STENCIL_VIEW_DESC dsv;
ZeroMemory(&dsv, sizeof(D3D11_DEPTH_STENCIL_VIEW_DESC));
dsv.Format = desc.Format;
dsv.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2DARRAY;
dsv.Texture2DArray.ArraySize = 1;
dsv.Texture2DArray.FirstArraySlice = i;
dsv.Texture2DArray.MipSlice = 0;
//create depth-stencil view for 1-st cube map face
g_pDevice->CreateDepthStencilView(tex, &dsv, &dt);
rTex->addDepthStencilView(dt);
}
if(desc.Format == DXGI_FORMAT_R32_TYPELESS)
{
ID3D11ShaderResourceView* srv;
D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
srvDesc.Format = DXGI_FORMAT_R32_FLOAT;
srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DARRAY;
srvDesc.Texture2D.MipLevels = 1;
srvDesc.Texture2D.MostDetailedMip = 0;
g_pDevice->CreateShaderResourceView(tex,&srvDesc,&srv);
IShaderResourceView11* srv11 = new IShaderResourceView11(srv);
rTex->addShaderResourceView(srv11);
}
rTex->pDevice = g_pDevice;
rTex->IsDepthTarget = true;
return rTex;
}
void RendererDX11::SetTargets(ITexture2D* colorTarget, ITexture2D* depthTarget)
{
ITexture2D11* depth = static_cast<ITexture2D11*>(depthTarget);
if(colorTarget)
{
ITexture2D11* color = static_cast<ITexture2D11*>(colorTarget);
IRenderTargetView11* rtv =static_cast<IRenderTargetView11*>(color->getRTView());
g_pDeviceContext->OMSetRenderTargets(1, &rtv->view, depth->getDSView());
}
else
{
g_pDeviceContext->OMSetRenderTargets(0, NULL, depth->getDSView());
}
}
void RendererDX11::SetTargets(ISurface* colorTarget, ISurface* depthTarget)
{
ISurface11* depth = static_cast<ISurface11*>(depthTarget);
if(colorTarget)
{
ISurface11* color = static_cast<ISurface11*>(colorTarget);
ID3D11RenderTargetView* rtv = color->getRTV();
g_pDeviceContext->OMSetRenderTargets(1, &rtv, depth->getDSV());
}
else
{
g_pDeviceContext->OMSetRenderTargets(0, NULL, depth->getDSV());
}
}
void RendererDX11::SetCubeTarget(ITexture2D* colorTarget, ITexture2D* depthTarget, int faceIndex)
{
ITexture2D11* depth = static_cast<ITexture2D11*>(depthTarget);
if(colorTarget)
{
ITexture2D11* color = static_cast<ITexture2D11*>(colorTarget);
IRenderTargetView11* rtv =static_cast<IRenderTargetView11*>(color->getRTView(faceIndex));
g_pDeviceContext->OMSetRenderTargets(1, &rtv->view, depth->getDSView(faceIndex));
}
else
{
g_pDeviceContext->OMSetRenderTargets(0, NULL, depth->getDSView(faceIndex));
}
}
void RendererDX11::SetTargets(ITexture2D** colorTargets, int targetCount, ITexture2D* depthTarget)
{
ITexture2D11* depth = static_cast<ITexture2D11*>(depthTarget);
static ID3D11RenderTargetView* rtv[8] = {NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL};
for(int i = 0; i < targetCount; i++)
{
ITexture2D11* color = static_cast<ITexture2D11*>(colorTargets[i]);
rtv[i] = static_cast<IRenderTargetView11*>(color->getRTView())->view;
}
g_pDeviceContext->OMSetRenderTargets(targetCount, rtv, depth->getDSView());
}
void RendererDX11::UnbindRenderTargets()
{
ID3D11RenderTargetView* const rtv[8] = {NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL};
g_pDeviceContext->OMSetRenderTargets(8, rtv, NULL);
}
void RendererDX11::SetColorTarget(ITexture2D* colorTarget)
{
ITexture2D11* color = static_cast<ITexture2D11*>(colorTarget);
IRenderTargetView11* rtv =static_cast<IRenderTargetView11*>(color->getRTView());
assert(false && "Fix that");
//g_pDeviceContext->OMSetRenderTargets(1, &rtv->view, currentDepthBuffer);
}
void RendererDX11::SetDepthTarget(ITexture2D* depthTarget)
{
ITexture2D11* depth = static_cast<ITexture2D11*>(depthTarget);
assert(false && "Fix that");
//g_pDeviceContext->OMSetRenderTargets(1, &currentBackBuffer, depth->getDSView());
}
void RendererDX11::SetVertexBuffer(IVertexBuffer* buffer)
{
IVertexBuffer11* vb = static_cast<IVertexBuffer11*>(buffer);
UINT offset = 0;
g_pDeviceContext->IASetVertexBuffers(0,1, &vb->vb, &vb->stride, &offset);
}
void RendererDX11::SetVertexBuffer(IVertexBuffer** vb, int count)
{
UINT strides[4];
UINT offsets[4] = {0,0,0,0};
ID3D11Buffer* buf[4];
for(int i = 0; i< count; i++)
{
IVertexBuffer11* b = static_cast<IVertexBuffer11*>(vb[i]);
buf[i] = b->vb;
strides[i] = b->stride;
}
g_pDeviceContext->IASetVertexBuffers(0,count, buf, strides, offsets);
}
void RendererDX11::SetIndexBuffer(IIndexBuffer* buffer)
{
IIndexBuffer11* ib = static_cast<IIndexBuffer11*>(buffer);
DXGI_FORMAT fmt = DXGI_FORMAT_R16_UINT;
if(!ib->isShort)
fmt = DXGI_FORMAT_R32_UINT;
g_pDeviceContext->IASetIndexBuffer(ib->ib, fmt, 0);
}
void RendererDX11::SetPrimitiveTopology(PRIMITIVE_TOPOLOGY topology)
{
g_pDeviceContext->IASetPrimitiveTopology((D3D11_PRIMITIVE_TOPOLOGY)topology);
}
void RendererDX11::DrawIndexed(int offset, int length)
{
g_pDeviceContext->DrawIndexed(length * 3, offset * 3, 0);
}
void RendererDX11::DrawIndexed(int offset, int length, int baseVertex)
{
g_pDeviceContext->DrawIndexed(length * 3, offset * 3, baseVertex);
}
void RendererDX11::DrawIndexedInstanced(int offset, int length, int instanceCnt)
{
g_pDeviceContext->DrawIndexedInstanced(length * 3, instanceCnt, offset * 3, 0, 0);
}
void RendererDX11::DrawIndexedInstanced(int offset, int length, int baseVertex, int instanceCnt)
{
g_pDeviceContext->DrawIndexedInstanced(length * 3, instanceCnt, offset * 3, baseVertex,0);
}
void RendererDX11::SetVertexShader(IShader* shader)
{
IVertexShader11* vs = static_cast<IVertexShader11*>(shader);
g_pDeviceContext->VSSetShader(vs->g_shader, NULL, 0);
}
void RendererDX11::SetPixelShader(IShader* shader)
{
IPixelShader11* ps = static_cast<IPixelShader11*>(shader);
g_pDeviceContext->PSSetShader(ps->g_shader, NULL, 0);
}
void RendererDX11::SetPSTexture(ITexture2D* texture, int slot)
{
IShaderResourceView11* tex = static_cast<IShaderResourceView11*>(texture->getSRView());
g_pDeviceContext->PSSetShaderResources(slot,1,&tex->view);
}
void RendererDX11::SetPSTextureCube(ITexture2D* texture, int slot)
{
ID3D11ShaderResourceView* tex = static_cast<ITexture2D11*>(texture)->cubeResourceView;
g_pDeviceContext->PSSetShaderResources(slot,1,&tex);
}
void RendererDX11::SetPSTexture(ITexture2D* texture, ITexture2D* texture2, int start, int count)
{
ID3D11ShaderResourceView* views[2];
views[0] = static_cast<IShaderResourceView11*>(texture->getSRView())->view;
views[1] = static_cast<IShaderResourceView11*>(texture2->getSRView())->view;
//IShaderResourceView11* tex = static_cast<IShaderResourceView11*>(texture->getSRView());
g_pDeviceContext->PSSetShaderResources(start,2, views);
}
void RendererDX11::SetVSTexture(ITexture2D* texture, int slot)
{
IShaderResourceView11* tex = static_cast<IShaderResourceView11*>(texture->getSRView());
g_pDeviceContext->VSSetShaderResources(slot,1,&tex->view);
}
void RendererDX11::UnbindResourcesPS()
{
ID3D11ShaderResourceView *const pSRV[10] = {NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL};
g_pDeviceContext->PSSetShaderResources(0, 10, pSRV);
}
void RendererDX11::Draw(int vertexCount, int vertexOffset)
{
g_pDeviceContext->Draw(vertexCount, vertexOffset);
}
IBlendState* RendererDX11::CreateBlendState(bool blendEnable, bool atocEnable, BLEND_OP blendOperation, BLEND_SRC srcBlend, BLEND_SRC dstBlend, uint8 colorMask)
{
ID3D11BlendState* state;
D3D11_BLEND_DESC desc = {0};
desc.AlphaToCoverageEnable = atocEnable;
desc.IndependentBlendEnable = false;
desc.RenderTarget[0].BlendEnable = blendEnable;
desc.RenderTarget[0].BlendOp = static_cast<D3D11_BLEND_OP>(blendOperation);
desc.RenderTarget[0].BlendOpAlpha = static_cast<D3D11_BLEND_OP>(blendOperation);
desc.RenderTarget[0].SrcBlend = static_cast<D3D11_BLEND>(srcBlend);
desc.RenderTarget[0].DestBlend = static_cast<D3D11_BLEND>(dstBlend);
desc.RenderTarget[0].RenderTargetWriteMask = colorMask;
desc.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_ONE;
desc.RenderTarget[0].SrcBlendAlpha= D3D11_BLEND_ONE;
g_pDevice->CreateBlendState(&desc,&state);
return new IBlendState11(g_pDevice, state);
}
void RendererDX11::SetBlendState(IBlendState* state)
{
IBlendState11* s = static_cast<IBlendState11*>(state);
LifeMath::float4 BlendFactor( 1.0f, 1.0f, 1.0f, 1.0f );
g_pDeviceContext->OMSetBlendState(s->state, (const FLOAT*) &BlendFactor, 0xffffffff);
}
IDepthStencilState* RendererDX11::CreateDSState(bool zEnable, bool zWrite, COMPARISON_FUNC zFunc)
{
D3D11_DEPTH_STENCIL_DESC State;
State.DepthEnable = zEnable;
if(zWrite)
State.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ALL;
else
State.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ZERO;
State.DepthFunc = static_cast<D3D11_COMPARISON_FUNC>(zFunc);
State.StencilEnable = FALSE;
State.StencilReadMask = D3D11_DEFAULT_STENCIL_READ_MASK;
State.StencilWriteMask = D3D11_DEFAULT_STENCIL_WRITE_MASK;
State.FrontFace.StencilFunc = D3D11_COMPARISON_ALWAYS;
State.FrontFace.StencilPassOp = D3D11_STENCIL_OP_KEEP;
State.FrontFace.StencilFailOp = D3D11_STENCIL_OP_KEEP;
State.FrontFace.StencilDepthFailOp = D3D11_STENCIL_OP_KEEP;
State.BackFace.StencilFunc = D3D11_COMPARISON_NEVER;
State.BackFace.StencilPassOp = D3D11_STENCIL_OP_KEEP;
State.BackFace.StencilFailOp = D3D11_STENCIL_OP_KEEP;
State.BackFace.StencilDepthFailOp = D3D11_STENCIL_OP_KEEP;
ID3D11DepthStencilState* s;
g_pDevice->CreateDepthStencilState(&State, &s);
return new IDepthStencilState11(g_pDevice, s);
}
IDepthStencilState* RendererDX11::CreateDSState(bool zEnable, bool zWrite, COMPARISON_FUNC zFunc, bool stencil, int stencilMask,
int stencilFunc, int stencilFail, int depthFail, int depthFailBack, int stencilPass)
{
D3D11_DEPTH_STENCIL_DESC State;
State.DepthEnable = zEnable;
if(zWrite)
State.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ALL;
else
State.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ZERO;
State.DepthFunc = static_cast<D3D11_COMPARISON_FUNC>(zFunc);
State.StencilEnable = stencil;
State.StencilReadMask = stencilMask;
State.StencilWriteMask = stencilMask;
State.FrontFace.StencilFunc = (D3D11_COMPARISON_FUNC)stencilFunc;
State.FrontFace.StencilPassOp = (D3D11_STENCIL_OP)stencilPass;
State.FrontFace.StencilFailOp = (D3D11_STENCIL_OP)stencilFail;
State.FrontFace.StencilDepthFailOp = (D3D11_STENCIL_OP)depthFail;
State.BackFace.StencilFunc = (D3D11_COMPARISON_FUNC)stencilFunc;
State.BackFace.StencilPassOp = (D3D11_STENCIL_OP)stencilPass;
State.BackFace.StencilFailOp = (D3D11_STENCIL_OP)stencilFail;
State.BackFace.StencilDepthFailOp = (D3D11_STENCIL_OP)depthFailBack;
ID3D11DepthStencilState* s;
g_pDevice->CreateDepthStencilState(&State, &s);
return new IDepthStencilState11(g_pDevice, s);
}
void RendererDX11::SetDepthStencilState(IDepthStencilState* state, UINT sref)
{
IDepthStencilState11* ds = static_cast<IDepthStencilState11*>(state);
g_pDeviceContext->OMSetDepthStencilState(ds->state, sref);
}
void RendererDX11::SetScissorRectangle(const LifeMath::Rect2i& rect)
{
g_pDeviceContext->RSSetState(rState);
D3D11_RECT sr[1];
sr[0].top = (LONG)rect.y;
sr[0].bottom = (LONG)rect.GetMaxY();
sr[0].left = (LONG)rect.x;
sr[0].right = (LONG)rect.GetMaxX();
g_pDeviceContext->RSSetScissorRects(1, sr);
}
void RendererDX11::SetViewport(const LifeMath::Rect2i& rect)
{
D3D11_VIEWPORT vp;
vp.Height = static_cast<float>(rect.height);
vp.Width = static_cast<float>(rect.width);
vp.TopLeftX = static_cast<float>(rect.x);
vp.TopLeftY = static_cast<float>(rect.y);
vp.MinDepth = 0.0f;
vp.MaxDepth = 1.0f;
g_pDeviceContext->RSSetViewports(1, &vp);
}
void RendererDX11::SetViewport(const LifeMath::Rect2i& rect, float minDepth, float maxDepth)
{
D3D11_VIEWPORT vp;
vp.Height = static_cast<float>(rect.height);
vp.Width = static_cast<float>(rect.width);
vp.TopLeftX = static_cast<float>(rect.x);
vp.TopLeftY = static_cast<float>(rect.y);
vp.MinDepth = minDepth;
vp.MaxDepth = maxDepth;
g_pDeviceContext->RSSetViewports(1, &vp);
}
ITexture2D* RendererDX11::CreateRenderTargetCube(int size, int format)
{
ID3D11Texture2D* tex;
D3D11_TEXTURE2D_DESC dstex;
ZeroMemory(&dstex, sizeof(D3D11_TEXTURE2D_DESC));
dstex.Width = size;
dstex.Height = size;
dstex.MipLevels = 1;
dstex.ArraySize = 6;
dstex.SampleDesc.Count = 1;
dstex.SampleDesc.Quality = 0;
dstex.Format = static_cast<DXGI_FORMAT>(format);
dstex.Usage = D3D11_USAGE_DEFAULT;
dstex.BindFlags = D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE;
dstex.CPUAccessFlags = 0;
dstex.MiscFlags = D3D11_RESOURCE_MISC_TEXTURECUBE;
g_pDevice->CreateTexture2D( &dstex, NULL, &tex );
ITexture2D11* newTex = new ITexture2D11(g_pDevice);
newTex->FromTexture(tex);
D3D11_RENDER_TARGET_VIEW_DESC rDesc;
rDesc.Format = dstex.Format;
rDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DARRAY;
rDesc.Texture2DArray.ArraySize = 1;
rDesc.Texture2DArray.MipSlice = 0;
rDesc.Texture2DArray.FirstArraySlice = 0;
D3D11_SHADER_RESOURCE_VIEW_DESC rvDesc;
ZeroMemory(&rvDesc, sizeof(D3D11_SHADER_RESOURCE_VIEW_DESC));
rvDesc.Format = dstex.Format;
rvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURECUBE;
rvDesc.TextureCube.MipLevels = 1;
rvDesc.TextureCube.MostDetailedMip = 0;
ID3D11ShaderResourceView* srView;
g_pDevice->CreateShaderResourceView(tex, &rvDesc, &srView);
newTex->addShaderResourceView(new IShaderResourceView11(srView));
// Create the one-face renderTarget views
for( int i = 0; i < 6; i++ )
{
ID3D11RenderTargetView* rtView;
rDesc.Texture2DArray.FirstArraySlice = i;
g_pDevice->CreateRenderTargetView( tex, &rDesc, &rtView );
newTex->addRenderTargetView(new IRenderTargetView11(rtView));
}
//create 6-face shader resource view
ID3D11ShaderResourceView* fullView;
D3D11_SHADER_RESOURCE_VIEW_DESC SRVDesc;
ZeroMemory( &SRVDesc, sizeof( SRVDesc ) );
SRVDesc.Format = dstex.Format;
SRVDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURECUBE;
SRVDesc.TextureCube.MipLevels = 1;
SRVDesc.TextureCube.MostDetailedMip = 0;
g_pDevice->CreateShaderResourceView(tex, &SRVDesc, &fullView);
newTex->cubeResourceView = fullView;
return newTex;
}
ITextureSampler* RendererDX11::CreateTextureSampler(ISamplerDescription* desc)
{
return new ITextureSampler11(desc, g_pDevice);
}
void RendererDX11::VerticalBlur(ITexture2D* src, ITexture2D* dst, int numSamples)
{
SetColorTarget(dst);
SetPSTexture(src, 0);
g_pDeviceContext->PSSetShader(psVerticalBlur, NULL, 0);
LifeMath::float4* offsets4 = new LifeMath::float4[numSamples];
GetBlurWeightedOffsets((float)numSamples, dst->Height(), offsets4);
//g_verticalBlurPS.SetFloat4A("vBlurOffsets", offsets4);
vbBuffer->Update(offsets4, 0);
SetPSConstantBuffer(vbBuffer, 0);
RenderToTextureNoPs();
delete[] offsets4;
}
}