void RenderSystem::clearRenderTargets(int clearBits, float depthValue, int stencilValue) { ID3D11RenderTargetView* rtvs[8] = {0}; ID3D11DepthStencilView* dsv = 0; if (clearBits & (RT_DEPTH | RT_STENCIL)) m_renderContext->OMGetRenderTargets(8, rtvs, &dsv); else m_renderContext->OMGetRenderTargets(8, rtvs, NULL); float clearColor[] = {0, 0, 0, 1}; for (int i = 0; i < 8; ++i) { if (rtvs[i] && clearBits & (1 << i)) { m_renderContext->ClearRenderTargetView(rtvs[i], clearColor); rtvs[i]->Release(); } } if (dsv) { UINT flags = 0; if (clearBits & RT_DEPTH) flags |= D3D11_CLEAR_DEPTH; if (clearBits & RT_STENCIL) flags |= D3D11_CLEAR_STENCIL; m_renderContext->ClearDepthStencilView(dsv, flags, depthValue, stencilValue); dsv->Release(); } }
/** Copies the given texture to the given RTV */ XRESULT D3D11PfxRenderer::CopyTextureToRTV(ID3D11ShaderResourceView* texture, ID3D11RenderTargetView* rtv, INT2 targetResolution, bool useCustomPS, INT2 offset) { D3D11GraphicsEngine* engine = (D3D11GraphicsEngine *)Engine::GraphicsEngine; D3D11_VIEWPORT oldVP; if(targetResolution.x != 0 && targetResolution.y != 0) { UINT n=1; engine->GetContext()->RSGetViewports(&n, &oldVP); D3D11_VIEWPORT vp; vp.TopLeftX = (float)offset.x; vp.TopLeftY = (float)offset.y; vp.MinDepth = 0.0f; vp.MaxDepth = 0.0f; vp.Width = (float)targetResolution.x; vp.Height = (float)targetResolution.y; engine->GetContext()->RSSetViewports(1, &vp); } // Save old rendertargets ID3D11RenderTargetView* oldRTV = NULL; ID3D11DepthStencilView* oldDSV = NULL; engine->GetContext()->OMGetRenderTargets(1, &oldRTV, &oldDSV); // Bind shaders if(!useCustomPS) { D3D11PShader* simplePS = engine->GetShaderManager()->GetPShader("PS_PFX_Simple"); simplePS->Apply(); } engine->GetShaderManager()->GetVShader("VS_PFX")->Apply(); ID3D11ShaderResourceView* srv = NULL; engine->GetContext()->PSSetShaderResources(0,1,&srv); engine->GetContext()->OMSetRenderTargets(1, &rtv, NULL); if(texture) engine->GetContext()->PSSetShaderResources(0,1, &texture); DrawFullScreenQuad(); engine->GetContext()->PSSetShaderResources(0,1,&srv); engine->GetContext()->OMSetRenderTargets(1, &oldRTV, oldDSV); if(oldRTV)oldRTV->Release(); if(oldDSV)oldDSV->Release(); if(targetResolution.x != 0 && targetResolution.y != 0) { engine->GetContext()->RSSetViewports(1, &oldVP); } return XR_SUCCESS; }
void dumpFramebuffer(JSONWriter &json, ID3D11DeviceContext *pDevice) { json.beginMember("framebuffer"); json.beginObject(); ID3D11RenderTargetView *pRenderTargetViews[D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT]; ID3D11DepthStencilView *pDepthStencilView; pDevice->OMGetRenderTargets(ARRAYSIZE(pRenderTargetViews), pRenderTargetViews, &pDepthStencilView); for (UINT i = 0; i < ARRAYSIZE(pRenderTargetViews); ++i) { if (!pRenderTargetViews[i]) { continue; } image::Image *image; DXGI_FORMAT dxgiFormat; image = getRenderTargetViewImage(pDevice, pRenderTargetViews[i], &dxgiFormat); if (image) { char label[64]; _snprintf(label, sizeof label, "RENDER_TARGET_%u", i); JSONWriter::ImageDesc imgDesc; imgDesc.depth = 1; imgDesc.format = getDXGIFormatName(dxgiFormat); json.beginMember(label); json.writeImage(image, imgDesc); json.endMember(); // RENDER_TARGET_* delete image; } pRenderTargetViews[i]->Release(); } if (pDepthStencilView) { image::Image *image; DXGI_FORMAT dxgiFormat; image = getDepthStencilViewImage(pDevice, pDepthStencilView, &dxgiFormat); if (image) { JSONWriter::ImageDesc imgDesc; imgDesc.depth = 1; imgDesc.format = getDXGIFormatName(dxgiFormat); json.beginMember("DEPTH_STENCIL"); json.writeImage(image, imgDesc); json.endMember(); delete image; } pDepthStencilView->Release(); } json.endObject(); json.endMember(); // framebuffer }
void D3DGraphicContextProvider::clear_stencil(int value) { ID3D11DepthStencilView *dsv = 0; window->get_device_context()->OMGetRenderTargets(0, 0, &dsv); if (dsv) { window->get_device_context()->ClearDepthStencilView(dsv, D3D11_CLEAR_STENCIL, 0, value); dsv->Release(); } }
/** Draws this effect to the given buffer */ XRESULT D3D11PFX_HDR::Render(RenderToTextureBuffer* fxbuffer) { D3D11GraphicsEngine* engine = (D3D11GraphicsEngine *)Engine::GraphicsEngine; Engine::GAPI->GetRendererState()->BlendState.BlendEnabled = false; Engine::GAPI->GetRendererState()->BlendState.SetDirty(); // Save old rendertargets ID3D11RenderTargetView* oldRTV = NULL; ID3D11DepthStencilView* oldDSV = NULL; engine->GetContext()->OMGetRenderTargets(1, &oldRTV, &oldDSV); RenderToTextureBuffer* lum = CalcLuminance(); CreateBloom(lum); // Copy the original image to our temp-buffer FxRenderer->CopyTextureToRTV(engine->GetHDRBackBuffer()->GetShaderResView(), FxRenderer->GetTempBuffer()->GetRenderTargetView(), engine->GetResolution()); // Bind scene and luminance FxRenderer->GetTempBuffer()->BindToPixelShader(engine->GetContext(), 0); lum->BindToPixelShader(engine->GetContext(), 1); // Bind bloom FxRenderer->GetTempBufferDS4_1()->BindToPixelShader(engine->GetContext(), 2); // Draw the HDR-Shader D3D11PShader* hps = engine->GetShaderManager()->GetPShader("PS_PFX_HDR"); hps->Apply(); HDRSettingsConstantBuffer hcb; hcb.HDR_LumWhite = Engine::GAPI->GetRendererState()->RendererSettings.HDRLumWhite; hcb.HDR_MiddleGray = Engine::GAPI->GetRendererState()->RendererSettings.HDRMiddleGray; hcb.HDR_Threshold = Engine::GAPI->GetRendererState()->RendererSettings.BloomThreshold; hcb.HDR_BloomStrength = Engine::GAPI->GetRendererState()->RendererSettings.BloomStrength; hps->GetConstantBuffer()[0]->UpdateBuffer(&hcb); hps->GetConstantBuffer()[0]->BindToPixelShader(0); FxRenderer->CopyTextureToRTV(FxRenderer->GetTempBuffer()->GetShaderResView(), oldRTV, engine->GetResolution(), true); // Show lumBuffer //FxRenderer->CopyTextureToRTV(currentLum->GetShaderResView(), oldRTV, INT2(LUM_SIZE,LUM_SIZE), false); // Restore rendertargets ID3D11ShaderResourceView* srv = NULL; engine->GetContext()->PSSetShaderResources(1,1,&srv); engine->GetContext()->OMSetRenderTargets(1, &oldRTV, oldDSV); if(oldRTV)oldRTV->Release(); if(oldDSV)oldDSV->Release(); return XR_SUCCESS; }
//-- ClearFloat --------------------------------------------------------------- // //----------------------------------------------------------------------------- void Renderer::ClearFloat(float r, float g, float b) { ID3D11RenderTargetView* rtView = NULL; ID3D11DepthStencilView* depthView = NULL; m_pD3D11Contex->OMGetRenderTargets(1, &rtView, &depthView); if (rtView != NULL) { float color[4] = { r, g, b, 1.0 }; m_pD3D11Contex->ClearRenderTargetView(rtView, color); rtView->Release(); } if (depthView != NULL) { m_pD3D11Contex->ClearDepthStencilView(depthView, D3D11_CLEAR_DEPTH, 1.0, 0); depthView->Release(); } } // ClearFloat
void Renderer::Clear( DWORD Col ) { Col |= 0xff000000; ID3D11RenderTargetView* rtView = NULL; ID3D11DepthStencilView* depthView = NULL; m_pD3D11Contex->OMGetRenderTargets(1, &rtView, &depthView); if (rtView != NULL) { XMCOLOR xcolor(Col); float color[4] = { xcolor.r / 255.0f, xcolor.g / 255.0f, xcolor.b / 255.0f, 1.0f }; m_pD3D11Contex->ClearRenderTargetView(rtView, color); rtView->Release(); } if (depthView != NULL) { m_pD3D11Contex->ClearDepthStencilView(depthView, D3D11_CLEAR_DEPTH, 1.0, 0); depthView->Release(); } }
void init_for_dimensions(unsigned width, unsigned height) { if(zsv) zsv->Release(); ID3D11Texture2D* zsbuf; D3D11_TEXTURE2D_DESC zsbufd; memset(&zsbufd, 0, sizeof(zsbufd)); zsbufd.Width = width; zsbufd.Height = height; zsbufd.Format = DXGI_FORMAT_D24_UNORM_S8_UINT; zsbufd.ArraySize = 1; zsbufd.MipLevels = 1; zsbufd.SampleDesc.Count = 1; zsbufd.BindFlags = D3D11_BIND_DEPTH_STENCIL; ensure(dev->CreateTexture2D(&zsbufd, 0, &zsbuf)); ensure(dev->CreateDepthStencilView(zsbuf, 0, &zsv)); zsbuf->Release(); ID3D11Texture2D* offscreen; if(offscreen_rtv) { offscreen_rtv->Release(); offscreen_srv->Release(); offscreen_rtv = 0; offscreen_srv = 0; } if(impressions > 1) { DXGI_FORMAT formats[] = { DXGI_FORMAT_R32G32B32A32_FLOAT, DXGI_FORMAT_R16G16B16A16_UNORM, DXGI_FORMAT_R16G16B16A16_FLOAT, DXGI_FORMAT_R10G10B10A2_UNORM, }; DXGI_FORMAT format = DXGI_FORMAT_R8G8B8A8_UNORM; // this won't work well at all unsigned needed_support = D3D11_FORMAT_SUPPORT_RENDER_TARGET | D3D11_FORMAT_SUPPORT_BLENDABLE | D3D11_FORMAT_SUPPORT_SHADER_SAMPLE; for(unsigned i = 0; i < sizeof(formats); ++i) { unsigned support; dev->CheckFormatSupport(DXGI_FORMAT_R32G32B32A32_FLOAT, &support); if((support & needed_support) == needed_support) { format = formats[i]; break; } } D3D11_TEXTURE2D_DESC offscreend; memset(&offscreend, 0, sizeof(offscreend)); offscreend.Width = width; offscreend.Height = height; offscreend.Format = format; offscreend.MipLevels = 1; offscreend.ArraySize = 1; offscreend.SampleDesc.Count = 1; offscreend.BindFlags = D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET; ensure(dev->CreateTexture2D(&offscreend, 0, &offscreen)); ensure(dev->CreateRenderTargetView(offscreen, 0, &offscreen_rtv)); ensure(dev->CreateShaderResourceView(offscreen, 0, &offscreen_srv)); offscreen->Release(); } cur_width = width; cur_height = height; }
void SimpleDeferredDemo::renderPost() { // if(1) return; ADLASSERT( TILE_SIZE <= 16 ); int nClusterX = calcNumTiles(g_wWidth, CLUSTER_SIZE);//max2( 1, (g_wWidth/CLUSTER_SIZE)+(!(g_wWidth%CLUSTER_SIZE)?0:1) ); int nClusterY = calcNumTiles(g_wHeight, CLUSTER_SIZE);//max2( 1, (g_wHeight/CLUSTER_SIZE)+(!(g_wHeight%CLUSTER_SIZE)?0:1) ); // todo. define own constant buffer ConstantBuffer cb; { cb.m_world = XMMatrixIdentity(); cb.m_view = g_ViewTr; cb.m_projection = g_ProjectionTr; } { // clear lightIdxBuffer BufferInfo bInfo[] = { BufferInfo( &m_tileBuffer ) }; Launcher launcher( m_deviceData, &m_clearLightIdxKernel ); launcher.setBuffers( bInfo, sizeof(bInfo)/sizeof(Launcher::BufferInfo) ); // launcher.pushBackRW( m_tileBuffer ); launcher.launch1D( nClusterX*nClusterY*MAX_LIGHTS_PER_TILE_IN_32B ); } { // set lightIdxBuffer BufferInfo bInfo[] = { BufferInfo( &m_lightPosBuffer, true ), BufferInfo( &m_lightColorBuffer, true ), BufferInfo( &m_tileBuffer ) }; Launcher launcher( m_deviceData, &m_buildLightIdxKernel ); launcher.setBuffers( bInfo, sizeof(bInfo)/sizeof(Launcher::BufferInfo) ); // launcher.pushBackR( m_lightPosBuffer ); // launcher.pushBackR( m_lightColorBuffer ); // launcher.pushBackRW( m_tileBuffer ); launcher.setConst( g_constBuffer, cb ); launcher.launch1D( 64 ); } Stopwatch dsw( m_deviceData ); dsw.start(); { // run CS BufferDX11<int> cBuffer; cBuffer.m_srv = m_colorRT.m_srv; BufferDX11<int> pBuffer; pBuffer.m_srv = m_posRT.m_srv; BufferDX11<int> nBuffer; nBuffer.m_srv = m_normalRT.m_srv; BufferInfo bInfo[] = { BufferInfo( &m_lightPosBuffer, true ), BufferInfo( &m_lightColorBuffer, true ), BufferInfo( &cBuffer, true ), BufferInfo( &pBuffer, true ), BufferInfo( &nBuffer, true ), BufferInfo( &m_tileBuffer, true ), BufferInfo( &m_buffer ) }; Launcher launcher( m_deviceData, &m_kernel ); launcher.setBuffers( bInfo, sizeof(bInfo)/sizeof(Launcher::BufferInfo) ); // launcher.pushBackR( m_lightPosBuffer ); // launcher.pushBackR( m_lightColorBuffer ); // launcher.pushBackR( cBuffer ); // launcher.pushBackR( pBuffer ); // launcher.pushBackR( nBuffer ); // launcher.pushBackR( m_tileBuffer ); // launcher.pushBackRW( m_buffer ); launcher.setConst( g_constBuffer, cb ); launcher.launch2D( nClusterX*TILE_SIZE, nClusterY*TILE_SIZE, TILE_SIZE, TILE_SIZE ); } dsw.stop(); { m_nTxtLines = 0; sprintf_s(m_txtBuffer[m_nTxtLines++], LINE_CAPACITY, "%3.3fms", dsw.getMs()); } // DeviceDX11* dd = (DeviceDX11*)m_deviceData; ID3D11RenderTargetView* pOrigRTV = NULL; ID3D11DepthStencilView* pOrigDSV = NULL; dd->m_context->OMGetRenderTargets( 1, &pOrigRTV, &pOrigDSV ); // release for the renderPre pOrigRTV->Release(); pOrigDSV->Release(); { float ClearColor[4] = { 0.f, 0.f, 0.f, 1.0f }; ID3D11RenderTargetView* aRTViews[ 1 ] = { pOrigRTV }; dd->m_context->OMSetRenderTargets( 1, aRTViews, pOrigDSV ); dd->m_context->ClearDepthStencilView( pOrigDSV, D3D11_CLEAR_DEPTH, 1.0f, 0 ); dd->m_context->ClearRenderTargetView( pOrigRTV, ClearColor ); dd->m_context->PSSetShaderResources( 0, 1, ((BufferDX11<float4>*)&m_buffer)->getSRVPtr() ); // render to screen renderFullQuad( m_deviceData, &g_bufferToRTPixelShader, make_float4((float)g_wWidth, (float)g_wHeight, 0,0 ) ); ID3D11ShaderResourceView* ppSRVNULL[16] = { 0 }; dd->m_context->PSSetShaderResources( 0, 1, ppSRVNULL ); } pOrigRTV->Release(); pOrigDSV->Release(); g_defaultVertexShader = m_gVShader; g_defaultPixelShader = m_gPShader; }
inline DepthStencil::~DepthStencil() { view_->Release(); }
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR cmdLine, int cmdShow) { DXTInputHandlerDefault inputHandler; DXTWindowEventHandlerDefault eventHandler; DXTWindow window(hInstance, &inputHandler, &eventHandler); DXTRenderParams params; params.Extent = { 800, 600 }; params.UseVSync = true; params.Windowed = true; HRESULT result; result = window.Initialize(params, "DXT Example (DirectX 11)"); if (SUCCEEDED(result)) { ID3D11Device* device; ID3D11DeviceContext* context; IDXGISwapChain* swapChain; result = DXTInitDevice(params, &window, &swapChain, &device, &context); if (SUCCEEDED(result)) { eventHandler.SetSwapChain(swapChain); FLOAT clearColor[] = { 0.5f, 0.5f, 1.0f, 1.0f }; D3D11_INPUT_ELEMENT_DESC inputDesc[] = { { "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 }, { "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, sizeof(float) * 3, D3D11_INPUT_PER_VERTEX_DATA, 0 }, { "NORMAL", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, sizeof(float) * 5, D3D11_INPUT_PER_VERTEX_DATA, 0 }, }; UINT elementCount = 3; UINT stride = 8 * sizeof(FLOAT); UINT offset = 0; UINT indexCount = 0; FLOAT deltaTime = 0.016f; DXTSphericalCamera camera; DXTFirstPersonCameraController cameraController(&camera, &inputHandler); inputHandler.AddInputInterface(&cameraController); cameraController.Velocity = 40.0f; cameraController.RotationVelocity = 0.005f; camera.Position = DirectX::XMFLOAT3(20.0f, 20.0f, 20.0f); camera.LookAt(DirectX::XMFLOAT3(0.0f, 0.0f, 0.0f)); ID3D11RenderTargetView* renderTargetView; ID3D11Texture2D* depthBuffer; ID3D11DepthStencilView* depthBufferView; ID3D11VertexShader* vertexShader; ID3D11PixelShader* pixelShader; DXTBytecodeBlob vertexBytecode; ID3D11DepthStencilState* depthState; ID3D11RasterizerState* rasterizerState; ID3D11Buffer* vertexBuffer; ID3D11Buffer* indexBuffer; ID3D11InputLayout* inputLayout; ID3D11Buffer* transformBuffer; DXTCreateRenderTargetFromBackBuffer(swapChain, device, &renderTargetView); DXTCreateDepthStencilBuffer(device, params.Extent.Width, params.Extent.Height, DXGI_FORMAT_D24_UNORM_S8_UINT, &depthBuffer, &depthBufferView); DXTVertexShaderFromFile(device, "VertexShader.cso", &vertexShader, &vertexBytecode); DXTPixelShaderFromFile(device, "PixelShader.cso", &pixelShader); DXTCreateDepthStencilStateDepthTestEnabled(device, &depthState); DXTCreateRasterizerStateSolid(device, &rasterizerState); DXTLoadStaticMeshFromFile(device, "mesh.ase", DXTVertexAttributePosition | DXTVertexAttributeUV | DXTVertexAttributeNormal, DXTIndexTypeShort, &vertexBuffer, &indexBuffer, &indexCount); DXTCreateBuffer(device, sizeof(DirectX::XMFLOAT4X4) * 2, D3D11_BIND_CONSTANT_BUFFER, D3D11_CPU_ACCESS_WRITE, D3D11_USAGE_DYNAMIC, &transformBuffer); device->CreateInputLayout(inputDesc, elementCount, vertexBytecode.Bytecode, vertexBytecode.BytecodeLength, &inputLayout); vertexBytecode.Destroy(); window.Present(false); while (!window.QuitMessageReceived()) { window.MessagePump(); if (inputHandler.IsKeyDown(VK_ESCAPE)) break; cameraController.Update(deltaTime); XMFLOAT4X4 ViewProj; XMFLOAT4X4 World; camera.GetViewProjectionMatrix(&ViewProj, params.Extent); XMStoreFloat4x4(&World, XMMatrixIdentity()); D3D11_MAPPED_SUBRESOURCE subres; context->Map(transformBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &subres); XMFLOAT4X4* ptr = (XMFLOAT4X4*)subres.pData; ptr[0] = World; ptr[1] = ViewProj; context->Unmap(transformBuffer, 0); D3D11_VIEWPORT viewport = { 0.0f, 0.0f, (FLOAT)params.Extent.Width, (FLOAT)params.Extent.Height, 0.0f, 1.0f }; context->ClearRenderTargetView(renderTargetView, clearColor); context->ClearDepthStencilView(depthBufferView, D3D11_CLEAR_DEPTH, 1.0f, 0); context->OMSetDepthStencilState(depthState, 0); context->OMSetRenderTargets(1, &renderTargetView, depthBufferView); context->RSSetState(rasterizerState); context->RSSetViewports(1, &viewport); context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST); context->IASetVertexBuffers(0, 1, &vertexBuffer, &stride, &offset); context->IASetIndexBuffer(indexBuffer, DXGI_FORMAT_R16_UINT, 0); context->IASetInputLayout(inputLayout); context->VSSetShader(vertexShader, nullptr, 0); context->PSSetShader(pixelShader, nullptr, 0); context->VSSetConstantBuffers(0, 1, &transformBuffer); context->DrawIndexed(indexCount, 0, 0); swapChain->Present(1, 0); } swapChain->SetFullscreenState(false, nullptr); transformBuffer->Release(); depthBufferView->Release(); depthBuffer->Release(); inputLayout->Release(); vertexBuffer->Release(); indexBuffer->Release(); depthState->Release(); rasterizerState->Release(); vertexShader->Release(); pixelShader->Release(); renderTargetView->Release(); swapChain->Release(); context->Release(); device->Release(); } window.Destroy(); } }
void SuzanneDX::RenderShadowMaps() { D3D11_TEXTURE2D_DESC shadowMapDesc; ZeroMemory(&shadowMapDesc, sizeof(shadowMapDesc)); shadowMapDesc.Width = SHADOW_RESOLUTION; shadowMapDesc.Height = SHADOW_RESOLUTION; shadowMapDesc.MipLevels = 1; shadowMapDesc.ArraySize = 1; shadowMapDesc.Format = DXGI_FORMAT_R24G8_TYPELESS; shadowMapDesc.SampleDesc.Count = 1; shadowMapDesc.SampleDesc.Quality = 0; shadowMapDesc.Usage = D3D11_USAGE_DEFAULT; shadowMapDesc.BindFlags = D3D11_BIND_DEPTH_STENCIL | D3D11_BIND_SHADER_RESOURCE; shadowMapDesc.CPUAccessFlags = 0; shadowMapDesc.MiscFlags = 0; D3D11_DEPTH_STENCIL_VIEW_DESC shadowMapDsvDesc; ZeroMemory(&shadowMapDsvDesc, sizeof(shadowMapDsvDesc)); shadowMapDsvDesc.Format = DXGI_FORMAT_D24_UNORM_S8_UINT; shadowMapDsvDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D; shadowMapDsvDesc.Texture2D.MipSlice = 0; D3D11_SHADER_RESOURCE_VIEW_DESC shadowMapResourceDesc; ZeroMemory(&shadowMapResourceDesc, sizeof(shadowMapResourceDesc)); shadowMapResourceDesc.Format = DXGI_FORMAT_R24_UNORM_X8_TYPELESS; shadowMapResourceDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D; shadowMapResourceDesc.Texture2D.MipLevels = 1; shadowMapResourceDesc.Texture2D.MostDetailedMip = 0; D3D11_VIEWPORT shadowMapViewport; shadowMapViewport.Width = (FLOAT)SHADOW_RESOLUTION; shadowMapViewport.Height = (FLOAT)SHADOW_RESOLUTION; shadowMapViewport.MinDepth = 0.0f; shadowMapViewport.MaxDepth = 1.0f; shadowMapViewport.TopLeftX = 0; shadowMapViewport.TopLeftY = 0; mDeviceContext->RSSetViewports(1, &shadowMapViewport); XMMATRIX shadowViewProjectionMatrices[NUMBER_OF_LIGHTS]; for (int i = 0; i < NUMBER_OF_LIGHTS; ++i) { ID3D11Texture2D* shadowMap; mDevice->CreateTexture2D(&shadowMapDesc, NULL, &shadowMap); ID3D11DepthStencilView* shadowMapDsv; mDevice->CreateDepthStencilView(shadowMap, &shadowMapDsvDesc, &shadowMapDsv); mDevice->CreateShaderResourceView(shadowMap, &shadowMapResourceDesc, &shadowMapResources[i]); mDeviceContext->OMSetRenderTargets(0, 0, shadowMapDsv); mDeviceContext->ClearDepthStencilView(shadowMapDsv, D3D11_CLEAR_DEPTH, 1.0f, 0); XMVECTOR lightInvDir = XMVector3Normalize(XMVectorSet(lighting.lights[i].position.x, lighting.lights[i].position.y, lighting.lights[i].position.z, 1.0f)); XMMATRIX shadowProjectionMatrix = XMMatrixOrthographicRH(20, 20, -10, 20); XMMATRIX shadowViewMatrix = XMMatrixLookAtRH(lightInvDir, XMVectorSet(0, 0, 0, 1), XMVectorSet(0, 1, 0, 1)); shadowViewProjectionMatrices[i] = shadowViewMatrix * shadowProjectionMatrix; ID3D11Buffer* shadowViewProjectionMatrixBuffer = DXUtil::CreateMatrixBuffer(mDevice, shadowViewProjectionMatrices[i]); mDeviceContext->VSSetConstantBuffers(shadowViewProjectionMatrixBufferSlot, 1, &shadowViewProjectionMatrixBuffer); UINT stride = sizeof(Vertex); UINT offset = 0; for (ModelDX model : models) { mDeviceContext->IASetVertexBuffers(0, 1, &model.vertexBuffer, &stride, &offset); mDeviceContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST); mDeviceContext->IASetInputLayout(model.inputLayout); mDeviceContext->VSSetShader(shadowVertexShader, 0, 0); mDeviceContext->PSSetShader(shadowPixelShader, 0, 0); mDeviceContext->VSSetConstantBuffers(modelMatrixBufferSlot, 1, &model.modelMatrixBuffer); mDeviceContext->Draw(model.vertexCount, 0); } shadowMap->Release(); shadowMapDsv->Release(); shadowViewProjectionMatrixBuffer->Release(); } mDeviceContext->OMSetRenderTargets(1, &mRenderTargetView, mDepthStencilView); mDeviceContext->RSSetViewports(1, &mViewport); D3D11_BUFFER_DESC matrixDesc; ZeroMemory(&matrixDesc, sizeof(matrixDesc)); matrixDesc.ByteWidth = sizeof(XMMATRIX) * NUMBER_OF_LIGHTS; matrixDesc.Usage = D3D11_USAGE_DEFAULT; matrixDesc.BindFlags = D3D11_BIND_CONSTANT_BUFFER; matrixDesc.CPUAccessFlags = 0; D3D11_SUBRESOURCE_DATA matrixData; ZeroMemory(&matrixData, sizeof(matrixData)); matrixData.pSysMem = &shadowViewProjectionMatrices[0]; ID3D11Buffer* matrixBuffer; mDevice->CreateBuffer(&matrixDesc, &matrixData, &matrixBuffer); mDeviceContext->VSSetConstantBuffers(shadowViewProjectionMatrixBufferSlot, 1, &matrixBuffer); matrixBuffer->Release(); XMMATRIX biasMatrix = XMMatrixSet( 0.5, 0.0, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.5, 0.5, 0.0, 1.0 ); ID3D11Buffer* shadowBiasMatrixBuffer = DXUtil::CreateMatrixBuffer(mDevice, biasMatrix); mDeviceContext->VSSetConstantBuffers(shadowBiasMatrixBufferSlot, 1, &shadowBiasMatrixBuffer); shadowBiasMatrixBuffer->Release(); }
// Renders meshes using cascaded shadow mapping void MeshRenderer::RenderShadowMap(ID3D11DeviceContext* context, const Camera& camera, const Float4x4& world) { PIXEvent event(L"Mesh Shadow Map Rendering"); // Get the current render targets + viewport ID3D11RenderTargetView* renderTargets[D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT] = { NULL }; ID3D11DepthStencilView* depthStencil = NULL; context->OMGetRenderTargets(D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT, renderTargets, &depthStencil); uint32 numViewports = D3D11_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE; D3D11_VIEWPORT oldViewports[D3D11_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE]; context->RSGetViewports(&numViewports, oldViewports); const float sMapSize = static_cast<float>(ShadowMapSize); const float MinDistance = _shadowDepthBounds.x; const float MaxDistance = _shadowDepthBounds.y; // Compute the split distances based on the partitioning mode float CascadeSplits[4] = { 0.0f, 0.0f, 0.0f, 0.0f }; { float lambda = 1.0f; float nearClip = camera.NearClip(); float farClip = camera.FarClip(); float clipRange = farClip - nearClip; float minZ = nearClip + MinDistance * clipRange; float maxZ = nearClip + MaxDistance * clipRange; float range = maxZ - minZ; float ratio = maxZ / minZ; for(uint32 i = 0; i < NumCascades; ++i) { float p = (i + 1) / static_cast<float>(NumCascades); float log = minZ * std::pow(ratio, p); float uniform = minZ + range * p; float d = lambda * (log - uniform) + uniform; CascadeSplits[i] = (d - nearClip) / clipRange; } } Float3 c0Extents; Float4x4 c0Matrix; // Render the meshes to each cascade for(uint32 cascadeIdx = 0; cascadeIdx < NumCascades; ++cascadeIdx) { PIXEvent cascadeEvent((L"Rendering Shadow Map Cascade " + ToString(cascadeIdx)).c_str()); // Set the viewport D3D11_VIEWPORT viewport; viewport.TopLeftX = 0.0f; viewport.TopLeftY = 0.0f; viewport.Width = sMapSize; viewport.Height = sMapSize; viewport.MinDepth = 0.0f; viewport.MaxDepth = 1.0f; context->RSSetViewports(1, &viewport); // Set the shadow map as the depth target ID3D11DepthStencilView* dsv = _shadowMap.DSView; ID3D11RenderTargetView* nullRenderTargets[D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT] = { NULL }; context->OMSetRenderTargets(D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT, nullRenderTargets, dsv); context->ClearDepthStencilView(dsv, D3D11_CLEAR_DEPTH|D3D11_CLEAR_STENCIL, 1.0f, 0); // Get the 8 points of the view frustum in world space XMVECTOR frustumCornersWS[8] = { XMVectorSet(-1.0f, 1.0f, 0.0f, 1.0f), XMVectorSet( 1.0f, 1.0f, 0.0f, 1.0f), XMVectorSet( 1.0f, -1.0f, 0.0f, 1.0f), XMVectorSet(-1.0f, -1.0f, 0.0f, 1.0f), XMVectorSet(-1.0f, 1.0f, 1.0f, 1.0f), XMVectorSet( 1.0f, 1.0f, 1.0f, 1.0f), XMVectorSet( 1.0f, -1.0f, 1.0f, 1.0f), XMVectorSet(-1.0f, -1.0f, 1.0f, 1.0f), }; float prevSplitDist = cascadeIdx == 0 ? MinDistance : CascadeSplits[cascadeIdx - 1]; float splitDist = CascadeSplits[cascadeIdx]; XMVECTOR det; XMMATRIX invViewProj = XMMatrixInverse(&det, camera.ViewProjectionMatrix().ToSIMD()); for(uint32 i = 0; i < 8; ++i) frustumCornersWS[i] = XMVector3TransformCoord(frustumCornersWS[i], invViewProj); // Get the corners of the current cascade slice of the view frustum for(uint32 i = 0; i < 4; ++i) { XMVECTOR cornerRay = XMVectorSubtract(frustumCornersWS[i + 4], frustumCornersWS[i]); XMVECTOR nearCornerRay = XMVectorScale(cornerRay, prevSplitDist); XMVECTOR farCornerRay = XMVectorScale(cornerRay, splitDist); frustumCornersWS[i + 4] = XMVectorAdd(frustumCornersWS[i], farCornerRay); frustumCornersWS[i] = XMVectorAdd(frustumCornersWS[i], nearCornerRay); } // Calculate the centroid of the view frustum slice XMVECTOR frustumCenterVec = XMVectorZero(); for(uint32 i = 0; i < 8; ++i) frustumCenterVec = XMVectorAdd(frustumCenterVec, frustumCornersWS[i]); frustumCenterVec = XMVectorScale(frustumCenterVec, 1.0f / 8.0f); Float3 frustumCenter = frustumCenterVec; // Pick the up vector to use for the light camera Float3 upDir = camera.Right(); Float3 minExtents; Float3 maxExtents; { // Create a temporary view matrix for the light Float3 lightCameraPos = frustumCenter; Float3 lookAt = frustumCenter - AppSettings::LightDirection; XMMATRIX lightView = XMMatrixLookAtLH(lightCameraPos.ToSIMD(), lookAt.ToSIMD(), upDir.ToSIMD()); // Calculate an AABB around the frustum corners XMVECTOR mins = XMVectorSet(REAL_MAX, REAL_MAX, REAL_MAX, REAL_MAX); XMVECTOR maxes = XMVectorSet(-REAL_MAX, -REAL_MAX, -REAL_MAX, -REAL_MAX); for(uint32 i = 0; i < 8; ++i) { XMVECTOR corner = XMVector3TransformCoord(frustumCornersWS[i], lightView); mins = XMVectorMin(mins, corner); maxes = XMVectorMax(maxes, corner); } minExtents = mins; maxExtents = maxes; } // Adjust the min/max to accommodate the filtering size float scale = (ShadowMapSize + FilterSize) / static_cast<float>(ShadowMapSize); minExtents.x *= scale; minExtents.y *= scale; maxExtents.x *= scale; maxExtents.x *= scale; Float3 cascadeExtents = maxExtents - minExtents; // Get position of the shadow camera Float3 shadowCameraPos = frustumCenter + AppSettings::LightDirection.Value() * -minExtents.z; // Come up with a new orthographic camera for the shadow caster OrthographicCamera shadowCamera(minExtents.x, minExtents.y, maxExtents.x, maxExtents.y, 0.0f, cascadeExtents.z); shadowCamera.SetLookAt(shadowCameraPos, frustumCenter, upDir); // Draw the mesh with depth only, using the new shadow camera RenderDepth(context, shadowCamera, world, true); // Apply the scale/offset matrix, which transforms from [-1,1] // post-projection space to [0,1] UV space XMMATRIX texScaleBias; texScaleBias.r[0] = XMVectorSet(0.5f, 0.0f, 0.0f, 0.0f); texScaleBias.r[1] = XMVectorSet(0.0f, -0.5f, 0.0f, 0.0f); texScaleBias.r[2] = XMVectorSet(0.0f, 0.0f, 1.0f, 0.0f); texScaleBias.r[3] = XMVectorSet(0.5f, 0.5f, 0.0f, 1.0f); XMMATRIX shadowMatrix = shadowCamera.ViewProjectionMatrix().ToSIMD(); shadowMatrix = XMMatrixMultiply(shadowMatrix, texScaleBias); // Store the split distance in terms of view space depth const float clipDist = camera.FarClip() - camera.NearClip(); _meshPSConstants.Data.CascadeSplits[cascadeIdx] = camera.NearClip() + splitDist * clipDist; if(cascadeIdx == 0) { c0Extents = cascadeExtents; c0Matrix = shadowMatrix; _meshPSConstants.Data.ShadowMatrix = XMMatrixTranspose(shadowMatrix); _meshPSConstants.Data.CascadeOffsets[0] = Float4(0.0f, 0.0f, 0.0f, 0.0f); _meshPSConstants.Data.CascadeScales[0] = Float4(1.0f, 1.0f, 1.0f, 1.0f); } else { // Calculate the position of the lower corner of the cascade partition, in the UV space // of the first cascade partition Float4x4 invCascadeMat = Float4x4::Invert(shadowMatrix); Float3 cascadeCorner = Float3::Transform(Float3(0.0f, 0.0f, 0.0f), invCascadeMat); cascadeCorner = Float3::Transform(cascadeCorner, c0Matrix); // Do the same for the upper corner Float3 otherCorner = Float3::Transform(Float3(1.0f, 1.0f, 1.0f), invCascadeMat); otherCorner = Float3::Transform(otherCorner, c0Matrix); // Calculate the scale and offset Float3 cascadeScale = Float3(1.0f, 1.0f, 1.f) / (otherCorner - cascadeCorner); _meshPSConstants.Data.CascadeOffsets[cascadeIdx] = Float4(-cascadeCorner, 0.0f); _meshPSConstants.Data.CascadeScales[cascadeIdx] = Float4(cascadeScale, 1.0f); } ConvertToEVSM(context, cascadeIdx, _meshPSConstants.Data.CascadeScales[cascadeIdx].To3D()); } // Restore the previous render targets and viewports context->OMSetRenderTargets(D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT, renderTargets, depthStencil); context->RSSetViewports(D3D11_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE, oldViewports); for(uint32 i = 0; i < D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT; ++i) if(renderTargets[i] != NULL) renderTargets[i]->Release(); if(depthStencil != NULL) depthStencil->Release(); }
/** Draws this effect to the given buffer */ XRESULT D3D11PFX_HeightFog::Render(RenderToTextureBuffer* fxbuffer) { D3D11GraphicsEngine* engine = (D3D11GraphicsEngine *)Engine::GraphicsEngine; // Save old rendertargets ID3D11RenderTargetView* oldRTV = NULL; ID3D11DepthStencilView* oldDSV = NULL; engine->GetContext()->OMGetRenderTargets(1, &oldRTV, &oldDSV); D3D11VShader* vs = engine->GetShaderManager()->GetVShader("VS_PFX"); D3D11PShader* hfPS = engine->GetShaderManager()->GetPShader("PS_PFX_Heightfog"); hfPS->Apply(); vs->Apply(); HeightfogConstantBuffer cb; D3DXMatrixInverse(&cb.InvProj, NULL, &Engine::GAPI->GetProjectionMatrix()); Engine::GAPI->GetViewMatrix(&cb.InvView); D3DXMatrixInverse(&cb.InvView, NULL, &cb.InvView); cb.CameraPosition = Engine::GAPI->GetCameraPosition(); float NearPlane=Engine::GAPI->GetRendererState()->RendererInfo.NearPlane; float FarPlane=Engine::GAPI->GetRendererState()->RendererInfo.FarPlane; D3DXMATRIX invViewProj, view; Engine::GAPI->GetViewMatrix(&view); D3DXMatrixMultiply(&invViewProj, &Engine::GAPI->GetProjectionMatrix(), &view); D3DXMatrixInverse(&invViewProj, NULL, &invViewProj); D3DXVECTOR3 vecFrustum[4]; /*vecFrustum[0] = D3DXVECTOR3(-1.0f, -1.0f, 0.0f); // xyz vecFrustum[1] = D3DXVECTOR3( 1.0f, -1.0f, 0.0f); // Xyz vecFrustum[2] = D3DXVECTOR3(-1.0f, 1.0f, 0.0f); // xYz vecFrustum[3] = D3DXVECTOR3( 1.0f, 1.0f, 0.0f); // XYz*/ vecFrustum[0] = D3DXVECTOR3(-1.0f, -1.0f, 1.0f); // xyZ vecFrustum[1] = D3DXVECTOR3( 1.0f, -1.0f, 1.0f); // XyZ vecFrustum[2] = D3DXVECTOR3(-1.0f, 1.0f, 1.0f); // xYZ vecFrustum[3] = D3DXVECTOR3( 1.0f, 1.0f, 1.0f); // XYZ // Get world space frustum corners PFXVS_ConstantBuffer vcb; for( int i = 0; i < 4; i++ ) { D3DXVec3TransformCoord( &vecFrustum[i], &vecFrustum[i], &cb.InvProj ); D3DXVec3Normalize(&vecFrustum[i], &vecFrustum[i]); D3DXVec3TransformNormal( &vecFrustum[i], &vecFrustum[i], &cb.InvView ); } /*vcb.PFXVS_FrustumCorners[0] = D3DXVECTOR4(vecFrustum[0].x, vecFrustum[0].y, vecFrustum[0].z, 0.0f); vcb.PFXVS_FrustumCorners[1] = D3DXVECTOR4(vecFrustum[2].x, vecFrustum[2].y, vecFrustum[2].z, 0.0f); vcb.PFXVS_FrustumCorners[2] = D3DXVECTOR4(vecFrustum[1].x, vecFrustum[1].y, vecFrustum[1].z, 0.0f); vcb.PFXVS_FrustumCorners[3] = D3DXVECTOR4(vecFrustum[3].x, vecFrustum[3].y, vecFrustum[3].z, 0.0f); vcb.PFXVS_FrustumCorners[4] = D3DXVECTOR4(vecFrustum[1].x, vecFrustum[1].y, vecFrustum[1].z, 0.0f); vcb.PFXVS_FrustumCorners[5] = D3DXVECTOR4(vecFrustum[2].x, vecFrustum[2].y, vecFrustum[2].z, 0.0f);*/ cb.HF_GlobalDensity = Engine::GAPI->GetRendererState()->RendererSettings.FogGlobalDensity; cb.HF_HeightFalloff = Engine::GAPI->GetRendererState()->RendererSettings.FogHeightFalloff; float height = Engine::GAPI->GetRendererState()->RendererSettings.FogHeight; D3DXVECTOR3 color = *Engine::GAPI->GetRendererState()->RendererSettings.FogColorMod.toD3DXVECTOR3(); float fnear = 15000.0f; float ffar = 60000.0f; float secScale = Engine::GAPI->GetRendererState()->RendererSettings.SectionDrawRadius; cb.HF_WeightZNear = std::max(0.0f, WORLD_SECTION_SIZE * ((secScale - 0.5f) * 0.7f) - (ffar - fnear)); // Keep distance from original fog but scale the near-fog up to section draw distance cb.HF_WeightZFar = WORLD_SECTION_SIZE * ((secScale - 0.5f) * 0.8f); float atmoMax = 83200.0f; // Fixme: Calculate! float atmoMin = 27799.9922f; cb.HF_WeightZFar = std::min(cb.HF_WeightZFar, atmoMax); cb.HF_WeightZNear = std::min(cb.HF_WeightZNear, atmoMin); if(Engine::GAPI->GetFogOverride() > 0.0f) { // Make sure the camera is inside the fog when in fog zone height = Toolbox::lerp(height, Engine::GAPI->GetCameraPosition().y + 10000, Engine::GAPI->GetFogOverride()); // TODO: Get this from the actual fog-distance in the fogzone! // Override fog color when in fog zone color = Engine::GAPI->GetFogColor(); // Make it z-Fog cb.HF_HeightFalloff = Toolbox::lerp(cb.HF_HeightFalloff, 0.000001f, Engine::GAPI->GetFogOverride()); // Turn up density cb.HF_GlobalDensity = Toolbox::lerp(cb.HF_GlobalDensity, cb.HF_GlobalDensity * 2, Engine::GAPI->GetFogOverride()); // Use other fog-values for fog-zones float distNear = WORLD_SECTION_SIZE * ((ffar - fnear) / ffar); cb.HF_WeightZNear = Toolbox::lerp(cb.HF_WeightZNear, WORLD_SECTION_SIZE * 0.09f, Engine::GAPI->GetFogOverride()); cb.HF_WeightZFar = Toolbox::lerp(cb.HF_WeightZFar, WORLD_SECTION_SIZE * 0.8, Engine::GAPI->GetFogOverride()); } /*static float s_smoothHeight = Engine::GAPI->GetRendererState()->RendererSettings.FogHeight; static float s_smoothZF = cb.HF_WeightZFar; static float s_smoothZN = cb.HF_WeightZNear; // Fade Z-Far and z-Near s_smoothZF = Toolbox::lerp(s_smoothZF, cb.HF_WeightZFar, std::min(Engine::GAPI->GetFrameTimeSec() * 5.0f, 1.0f)); s_smoothZN = Toolbox::lerp(s_smoothZN, cb.HF_WeightZNear, std::min(Engine::GAPI->GetFrameTimeSec() * 5.0f, 1.0f)); cb.HF_WeightZNear = s_smoothZN; cb.HF_WeightZFar = s_smoothZF;*/ //static D3DXVECTOR3 s_smoothColor = *Engine::GAPI->GetRendererState()->RendererSettings.FogColorMod.toD3DXVECTOR3(); // Fade fog height in case it changes //s_smoothHeight = Toolbox::lerp(s_smoothHeight, height, std::min(Engine::GAPI->GetFrameTimeSec() * 5.0f, 1.0f)); // Fade color, because leaving a fogzone would make the fog-color pop otherwise //D3DXVec3Lerp(&s_smoothColor, &s_smoothColor, &color, std::min(Engine::GAPI->GetFrameTimeSec() * 5.0f, 1.0f)); //D3DXVECTOR3 fogColorMod = Engine::GAPI->GetRendererState()->RendererSettings.FogColorMod; cb.HF_FogColorMod = color;//Engine::GAPI->GetRendererState()->RendererSettings.FogColorMod; cb.HF_FogHeight = height; //cb.HF_FogColorMod = Engine::GAPI->GetRendererState()->GraphicsState.FF_FogColor; cb.HF_ProjAB = float2( Engine::GAPI->GetProjectionMatrix()._33, Engine::GAPI->GetProjectionMatrix()._34); // Modify fog when raining float rain = Engine::GAPI->GetRainFXWeight(); // Color D3DXVec3Lerp(cb.HF_FogColorMod.toD3DXVECTOR3(), cb.HF_FogColorMod.toD3DXVECTOR3(), &Engine::GAPI->GetRendererState()->RendererSettings.RainFogColor, std::min(1.0f, rain * 2.0f)); // Scale color faster here, so it looks better on light rain // Raining Density, only when not in fogzone cb.HF_GlobalDensity = Toolbox::lerp(cb.HF_GlobalDensity, Engine::GAPI->GetRendererState()->RendererSettings.RainFogDensity, rain * (1.0f - Engine::GAPI->GetFogOverride())); hfPS->GetConstantBuffer()[0]->UpdateBuffer(&cb); hfPS->GetConstantBuffer()[0]->BindToPixelShader(0); vs->GetConstantBuffer()[0]->UpdateBuffer(&vcb); vs->GetConstantBuffer()[0]->BindToVertexShader(0); GSky* sky = Engine::GAPI->GetSky(); hfPS->GetConstantBuffer()[1]->UpdateBuffer(&sky->GetAtmosphereCB()); hfPS->GetConstantBuffer()[1]->BindToPixelShader(1); engine->GetContext()->OMSetRenderTargets(1, &oldRTV, NULL); // Bind depthbuffer engine->GetDepthBuffer()->BindToPixelShader(engine->GetContext(), 1); Engine::GAPI->GetRendererState()->BlendState.SetDefault(); //Engine::GAPI->GetRendererState()->BlendState.SetAdditiveBlending(); Engine::GAPI->GetRendererState()->BlendState.BlendEnabled = true; Engine::GAPI->GetRendererState()->BlendState.SetDirty(); // Copy FxRenderer->DrawFullScreenQuad(); // Restore rendertargets ID3D11ShaderResourceView* srv = NULL; engine->GetContext()->PSSetShaderResources(1,1,&srv); engine->GetContext()->OMSetRenderTargets(1, &oldRTV, oldDSV); if(oldRTV)oldRTV->Release(); if(oldDSV)oldDSV->Release(); return XR_SUCCESS; }
void draw(ID3D11DeviceContext* ctx, ID3D11RenderTargetView* rtv, unsigned width, unsigned height, double time) { D3D11_VIEWPORT vp; memset(&vp, 0, sizeof(vp)); vp.Width = (float)width; vp.Height = (float)height; vp.MaxDepth = 1.0f; if(width != cur_width || height != cur_height) { if(zsv) zsv->Release(); ID3D11Texture2D* zsbuf; D3D11_TEXTURE2D_DESC zsbufd; memset(&zsbufd, 0, sizeof(zsbufd)); zsbufd.Width = width; zsbufd.Height = height; zsbufd.Format = DXGI_FORMAT_D32_FLOAT; zsbufd.ArraySize = 1; zsbufd.MipLevels = 1; zsbufd.SampleDesc.Count = 1; zsbufd.BindFlags = D3D11_BIND_DEPTH_STENCIL; ensure(dev->CreateTexture2D(&zsbufd, 0, &zsbuf)); ensure(dev->CreateDepthStencilView(zsbuf, 0, &zsv)); zsbuf->Release(); } float black[4] = {0, 0, 0, 0}; D3D11_MAPPED_SUBRESOURCE map; ensure(ctx->Map(cb_frame, 0, D3D11_MAP_WRITE_DISCARD, 0, &map)); cb_frame_t* cb_frame_data = (cb_frame_t*)map.pData; D3DXMatrixIdentity(&cb_frame_data->model); D3DXMATRIX view; D3DXVECTOR3 eye(2.0f * (float)sin(time), 0.0f, 2.0f * (float)cos(time)); D3DXVECTOR3 at(0, 0, 0); D3DXVECTOR3 up(0, 1, 0); D3DXMatrixLookAtLH(&view, &eye, &at, &up); D3DXMATRIX proj; D3DXMatrixPerspectiveLH(&proj, 1.1f, 1.1f, 1.0f, 3.0f); cb_frame_data->view_proj = view * proj; float min_tess_factor = 1.0f; cb_frame_data->tess_factor = (1.0f - (float)cos(time)) * ((64.0f - min_tess_factor) / 2.0f) + min_tess_factor; cb_frame_data->disp_scale = 0.9f; //cb_frame_data->disp_scale = (sin(time) + 1.0) / 2.0; cb_frame_data->disp_freq = 5.0f * (float)M_PI; //cb_frame_data->disp_freq = (4.0 + 4.0 * cos(time / 5.0)) * PI; ctx->Unmap(cb_frame, 0); ctx->HSSetConstantBuffers(0, 1, &cb_frame); ctx->DSSetConstantBuffers(0, 1, &cb_frame); //ctx->OMSetBlendState(bs, black, ~0); //ctx->OMSetDepthStencilState(dss, 0); ctx->OMSetRenderTargets(1, &rtv, zsv); //ctx->RSSetState(rs); ctx->RSSetViewports(1, &vp); ctx->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_3_CONTROL_POINT_PATCHLIST); ctx->IASetInputLayout(layout); unsigned stride = 3 * 4; unsigned offset = 0; ctx->IASetVertexBuffers(0, 1, &vb, &stride, &offset); ctx->VSSetShader(vs, NULL, 0); ctx->HSSetShader(hs, NULL, 0); ctx->DSSetShader(ds, NULL, 0); ctx->GSSetShader(NULL, NULL, 0); ctx->PSSetShader(ps, NULL, 0); ctx->ClearRenderTargetView(rtv, black); ctx->ClearDepthStencilView(zsv, D3D11_CLEAR_DEPTH, 1.0f, 0); ctx->Draw(3 * 8, 0); }