#pragma once #include "render/dx11/RendererDX11.h" #include "vfs/fs_win/IFSContentProvider.h" #include "LString.h" #include "vfs/IFile.h" #include #include "render/dx11/IConstantBuffer11.h" #include "render/IMaterial.h" #include "D3DX10math.h" #include "render/dx11/IDepthStencilState11.h" #include #include "d3d11sdklayers.h" #include #include 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(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(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(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(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(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(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(target); g_pDeviceContext->ClearRenderTargetView(rtv->getRTV(), clearColor); } void RendererDX11::ClearDepthStencil(ISurface* target, int flag, float zValue, int stencilValue) { g_pDeviceContext->ClearDepthStencilView(static_cast(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* 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* 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; isubsetCount; 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(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(depthTarget); if(colorTarget) { ITexture2D11* color = static_cast(colorTarget); IRenderTargetView11* rtv =static_cast(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(depthTarget); if(colorTarget) { ISurface11* color = static_cast(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(depthTarget); if(colorTarget) { ITexture2D11* color = static_cast(colorTarget); IRenderTargetView11* rtv =static_cast(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(depthTarget); static ID3D11RenderTargetView* rtv[8] = {NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL}; for(int i = 0; i < targetCount; i++) { ITexture2D11* color = static_cast(colorTargets[i]); rtv[i] = static_cast(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(colorTarget); IRenderTargetView11* rtv =static_cast(color->getRTView()); assert(false && "Fix that"); //g_pDeviceContext->OMSetRenderTargets(1, &rtv->view, currentDepthBuffer); } void RendererDX11::SetDepthTarget(ITexture2D* depthTarget) { ITexture2D11* depth = static_cast(depthTarget); assert(false && "Fix that"); //g_pDeviceContext->OMSetRenderTargets(1, ¤tBackBuffer, depth->getDSView()); } void RendererDX11::SetVertexBuffer(IVertexBuffer* buffer) { IVertexBuffer11* vb = static_cast(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(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(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(shader); g_pDeviceContext->VSSetShader(vs->g_shader, NULL, 0); } void RendererDX11::SetPixelShader(IShader* shader) { IPixelShader11* ps = static_cast(shader); g_pDeviceContext->PSSetShader(ps->g_shader, NULL, 0); } void RendererDX11::SetPSTexture(ITexture2D* texture, int slot) { IShaderResourceView11* tex = static_cast(texture->getSRView()); g_pDeviceContext->PSSetShaderResources(slot,1,&tex->view); } void RendererDX11::SetPSTextureCube(ITexture2D* texture, int slot) { ID3D11ShaderResourceView* tex = static_cast(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(texture->getSRView())->view; views[1] = static_cast(texture2->getSRView())->view; //IShaderResourceView11* tex = static_cast(texture->getSRView()); g_pDeviceContext->PSSetShaderResources(start,2, views); } void RendererDX11::SetVSTexture(ITexture2D* texture, int slot) { IShaderResourceView11* tex = static_cast(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(blendOperation); desc.RenderTarget[0].BlendOpAlpha = static_cast(blendOperation); desc.RenderTarget[0].SrcBlend = static_cast(srcBlend); desc.RenderTarget[0].DestBlend = static_cast(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(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(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(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(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(rect.height); vp.Width = static_cast(rect.width); vp.TopLeftX = static_cast(rect.x); vp.TopLeftY = static_cast(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(rect.height); vp.Width = static_cast(rect.width); vp.TopLeftX = static_cast(rect.x); vp.TopLeftY = static_cast(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(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; } }