void CFullscreenTriangleDrawer::DrawDX11( ID3D11ShaderResourceView* pTextureSRV ) { ID3D11Device* pDevice = static_cast<ID3D11Device*>( gD3DDevice ); ID3D11DeviceContext* pContext = NULL; pDevice->GetImmediateContext( &pContext ); CDX11StateGuard stateGuard; pContext->IASetInputLayout( NULL ); pContext->IASetIndexBuffer( NULL, DXGI_FORMAT_UNKNOWN, 0 ); pContext->IASetVertexBuffers( 0, 0, NULL, NULL, NULL ); pContext->IASetPrimitiveTopology( D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST ); pContext->VSSetShader( m_pVertexShader11, NULL, 0 ); pContext->PSSetShader( m_pPixelShader11, NULL, 0 ); ID3D11SamplerState* pNullSampler[] = { NULL }; pContext->PSSetSamplers( 0, 1, pNullSampler ); pContext->PSSetShaderResources( 0, 1, &pTextureSRV ); pContext->OMSetBlendState( m_pBlendState11, NULL, 0xFFFFFFFF ); // Draw pContext->Draw( 3, 0 ); }
void RenderTargetPingPong::Apply(ID3D11Device* device, ID3DX11EffectTechnique* technique) { ID3D11DeviceContext* context; device->GetImmediateContext(&context); ID3D11Buffer* zero = 0; UINT nought = 0; context->IASetVertexBuffers(0,1,&zero,&nought,&nought); context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP); context->IASetInputLayout(0); { ID3D11RenderTargetView* view[] = { m_target->RenderTargetView() }; context->OMSetRenderTargets(1, const_cast<ID3D11RenderTargetView**> (view), m_depth_stencil_view); } m_shader_resource_variable->SetResource(m_source->ShaderResourceView()); for(UINT n = 0; n < Effect::NumPasses(technique); ++n) { technique->GetPassByIndex(n)->Apply(0,context); context->Draw(4,0); } m_shader_resource_variable->SetResource(0); m_last_target = m_target; std::swap(m_source,m_target); }
//----------------------------------------- void CPUTSprite::DrawSprite( CPUTRenderParameters &renderParams, CPUTMaterial &material ) { // TODO: Should we warn here? // If it doesn't draw, make sure you created it with createDebugSprite == true if( mpVertexBuffer ) { ID3D11DeviceContext *pContext = ((CPUTRenderParametersDX*)&renderParams)->mpContext; material.SetRenderStates(renderParams); UINT stride = sizeof( SpriteVertex ); UINT offset = 0; pContext->IASetVertexBuffers( 0, 1, &mpVertexBuffer, &stride, &offset ); // Set the input layout pContext->IASetInputLayout( mpInputLayout ); // Set primitive topology pContext->IASetPrimitiveTopology( D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST ); pContext->Draw( 6, 0 ); } } // CPUTSprite::DrawSprite()
void ParticleManager::RenderParticles(DxGraphics* pDxGraphics, Camera& cam) { cam.CalculateViewMatrix(); XMMATRIX tWorld = XMMatrixTranspose(m_worldMat); XMMATRIX tView = XMMatrixTranspose(cam.GetViewMatrix()); XMMATRIX tProj = XMMatrixTranspose(cam.GetProjMatrix()); ID3D11DeviceContext* pCon = pDxGraphics->GetImmediateContext(); UINT stride = sizeof(Particle); UINT offset = 0; pCon->IASetVertexBuffers(0, 1, &m_vBuffer, &stride, &offset); pCon->IASetInputLayout(m_inputLayout); pCon->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_POINTLIST); pCon->VSSetShader(m_vShader, 0, 0); pCon->PSSetShader(m_pShader, 0, 0); pCon->UpdateSubresource(m_camWorldBuffer, 0, NULL, &tWorld, 0, 0); pCon->UpdateSubresource(m_camViewBuffer, 0, NULL, &tView, 0, 0); pCon->UpdateSubresource(m_camProjBuffer, 0, NULL, &tProj, 0, 0); pCon->VSSetConstantBuffers(0, 1, &m_camWorldBuffer); pCon->VSSetConstantBuffers(1, 1, &m_camViewBuffer); pCon->VSSetConstantBuffers(2, 1, &m_camProjBuffer); pCon->Draw(m_particleList.size(), 0); pCon->VSSetShader(NULL, 0, 0); pCon->GSSetShader(NULL, 0, 0); pCon->PSSetShader(NULL, 0, 0); }
static void DoRendering (const float* worldMatrix, const float* identityMatrix, float* projectionMatrix, const MyVertex* verts) { // Does actual rendering of a simple triangle #if SUPPORT_D3D11 // D3D11 case if (s_DeviceType == kUnityGfxRendererD3D11 && EnsureD3D11ResourcesAreCreated()) { ID3D11DeviceContext* ctx = NULL; g_D3D11Device->GetImmediateContext (&ctx); ID3D11RenderTargetView* pCurrentRenderTarget; ID3D11DepthStencilView* pCurrentDepthStencil; // Get the current render targets ctx->OMGetRenderTargets(1, &pCurrentRenderTarget, &pCurrentDepthStencil); ctx->OMSetRenderTargets(1, &g_pD3D11RenderTargetView, nullptr); /* // update native texture from code D3D11_TEXTURE2D_DESC desc; g_TexturePointer->GetDesc(&desc); unsigned char* data = new unsigned char[desc.Width*desc.Height * 4]; FillTextureFromCode(desc.Width, desc.Height, desc.Width * 4, data); ctx->UpdateSubresource(g_TexturePointer, 0, NULL, data, desc.Width * 4, 0); delete[] data; */ const float CLEAR_CLR[4] = { 1, 1, 0, 1 }; // Yellow ctx->ClearRenderTargetView(g_pD3D11RenderTargetView, CLEAR_CLR); // Restore the original render target ctx->OMSetRenderTargets(1, &pCurrentRenderTarget, pCurrentDepthStencil); // update constant buffer - just the world matrix in our case ctx->UpdateSubresource (g_D3D11CB, 0, NULL, worldMatrix, 64, 0); // set shaders ctx->VSSetConstantBuffers (0, 1, &g_D3D11CB); ctx->VSSetShader (g_D3D11VertexShader, NULL, 0); ctx->PSSetShader (g_D3D11PixelShader, NULL, 0); // update vertex buffer ctx->UpdateSubresource (g_D3D11VB, 0, NULL, verts, sizeof(verts[0])*3, 0); // set input assembler data and draw ctx->IASetInputLayout (g_D3D11InputLayout); ctx->IASetPrimitiveTopology (D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST); UINT stride = sizeof(MyVertex); UINT offset = 0; ctx->IASetVertexBuffers (0, 1, &g_D3D11VB, &stride, &offset); ctx->Draw (3, 0); ctx->Release(); } #endif }
void Mesh::Draw() { ID3D11DeviceContext * context = GetContext(); unsigned int offset = 0; context->IASetVertexBuffers(0,1,&vertexBuffer,&stride,&offset); context->IASetPrimitiveTopology(topology); context->Draw(numberOfVerts,0); }
void Grid::Render() { basicShader->cpu_vs_buffer0.viewMatrix = World::GetCurrentLevel()->currentCamera->GetViewMatrix(); basicShader->cpu_vs_buffer0.worldMatrix = XMMatrixIdentity(); basicShader->cpu_vs_buffer0.useVertexColor = true; basicShader->SetParameters(); basicShader->Activate(); ID3D11DeviceContext *devcon = (ID3D11DeviceContext*)EngineCore::GetGraphicsAPI()->GetDeviceContext(); UINT stride = sizeof(Vertex); UINT offset = 0; devcon->IASetVertexBuffers(0, 1, &buff, &stride, &offset); devcon->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_LINELIST); devcon->Draw(2*(n * 2 + 1), 0); basicShader->cpu_vs_buffer0.worldMatrix = XMMatrixRotationZ(XM_PIDIV2); basicShader->SetParameters(); devcon->Draw(2 * (n * 2 + 1), 0); }
void ParticleManager::UpdateParticles(float dt, DxGraphics* pDxGraphics, Camera& cam) { // Update the world mat XMMATRIX transMat = XMMatrixTranslation(0.0f, 0.0f, 0.0f); XMMATRIX rotMat = XMMatrixRotationRollPitchYaw(0.0f, 0.0f, 0.0f); XMMATRIX scaleMat = XMMatrixScaling(1.0f, 1.0f, 1.0f); m_worldMat = rotMat * scaleMat * transMat; cam.CalculateViewMatrix(); // stream out the particles which runs through the physics XMMATRIX tWorld = XMMatrixTranspose(m_worldMat); XMMATRIX tView = XMMatrixTranspose(cam.GetViewMatrix()); XMMATRIX tProj = XMMatrixTranspose(cam.GetProjMatrix()); m_massPoint.dt = dt; ID3D11DeviceContext* pCon = pDxGraphics->GetImmediateContext(); // Set the stream out buffer UINT offsetSO[1] = { 0 }; pCon->SOSetTargets(1, &m_vStream, offsetSO); UINT stride = sizeof(Particle); UINT offset = 0; pCon->IASetVertexBuffers(0, 1, &m_vBuffer, &stride, &offset); pCon->IASetInputLayout(m_inputLayout); pCon->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_POINTLIST); pCon->VSSetShader(m_vUpdate, 0, 0); pCon->GSSetShader(m_gUpdate, 0, 0); pCon->PSSetShader(NULL, 0, 0); //// Update the cBuffer pCon->UpdateSubresource(m_pointBuffer, 0, NULL, &m_massPoint, 0, 0); pCon->VSSetConstantBuffers(3, 1, &m_pointBuffer); pCon->Draw(m_particleList.size(), 0); pCon->VSSetShader(NULL, 0, 0); pCon->GSSetShader(NULL, 0, 0); pCon->PSSetShader(NULL, 0, 0); // Unbind the SO ID3D11Buffer* bufferArray[1] = { 0 }; pCon->SOSetTargets(1, bufferArray, offsetSO); std::swap(m_vStream, m_vBuffer); }
void MSAAFilter::RenderAA() { PIXEvent pixEvent(L"MSAA Resolve + Temporal AA"); ProfileBlock profileBlock(L"MSAA Resolve + Temporal AA"); ID3D11DeviceContext* context = deviceManager.ImmediateContext(); ID3D11RenderTargetView* rtvs[1] = { resolveTarget.RTView }; context->OMSetRenderTargets(1, rtvs, nullptr); if(AppSettings::UseStandardResolve) { if(AppSettings::MSAAMode == 0) context->CopyResource(resolveTarget.Texture, colorTarget.Texture); else context->ResolveSubresource(resolveTarget.Texture, 0, colorTarget.Texture, 0, colorTarget.Format); return; } const uint32 SampleRadius = static_cast<uint32>((AppSettings::ResolveFilterDiameter / 2.0f) + 0.499f); ID3D11PixelShader* pixelShader = resolvePS[AppSettings::MSAAMode]; context->PSSetShader(pixelShader, nullptr, 0); context->VSSetShader(resolveVS, nullptr, 0); resolveConstants.Data.TextureSize = Float2(static_cast<float>(colorTarget.Width), static_cast<float>(colorTarget.Height)); resolveConstants.Data.SampleRadius = SampleRadius;; resolveConstants.ApplyChanges(context); resolveConstants.SetPS(context, 0); ID3D11ShaderResourceView* srvs[] = { colorTarget.SRView, velocityTarget.SRView, depthBuffer.SRView, prevFrameTarget.SRView}; context->PSSetShaderResources(0, ArraySize_(srvs), srvs); ID3D11SamplerState* samplers[] = { samplerStates.LinearClamp(), samplerStates.Point() }; context->PSSetSamplers(0, ArraySize_(samplers), samplers); ID3D11Buffer* vbs[1] = { nullptr }; UINT strides[1] = { 0 }; UINT offsets[1] = { 0 }; context->IASetVertexBuffers(0, 1, vbs, strides, offsets); context->IASetInputLayout(nullptr); context->IASetIndexBuffer(nullptr, DXGI_FORMAT_R16_UINT, 0); context->Draw(3, 0); rtvs[0] = nullptr; context->OMSetRenderTargets(1, rtvs, nullptr); srvs[0] = srvs[1] = srvs[2] = nullptr; context->PSSetShaderResources(0, 3, srvs); context->CopyResource(prevFrameTarget.Texture, resolveTarget.Texture); }
// Callbacks to draw things in world space, left-hand space, and right-hand // space. void DrawWorld( void* userData //< Passed into AddRenderCallback , osvr::renderkit::GraphicsLibrary library //< Graphics library context to use , osvr::renderkit::RenderBuffer buffers //< Buffers to use , osvr::renderkit::OSVR_ViewportDescription viewport //< Viewport we're rendering into , OSVR_PoseState pose //< OSVR ModelView matrix set by RenderManager , osvr::renderkit::OSVR_ProjectionMatrix projection //< Projection matrix set by RenderManager , OSVR_TimeValue deadline //< When the frame should be sent to the screen ) { // Make sure our pointers are filled in correctly. if (library.D3D11 == nullptr) { std::cerr << "DrawWorld: No D3D11 GraphicsLibrary, this should not happen" << std::endl; return; } if (buffers.D3D11 == nullptr) { std::cerr << "DrawWorld: No D3D11 RenderBuffer, this should not happen" << std::endl; return; } ID3D11DeviceContext* context = library.D3D11->context; ID3D11RenderTargetView* renderTargetView = buffers.D3D11->colorBufferView; // Set vertex buffer UINT stride = sizeof(SimpleVertex); UINT offset = 0; context->IASetVertexBuffers(0, 1, &g_vertexBuffer, &stride, &offset); // Set primitive topology context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST); // Set depth/stencil state context->OMSetDepthStencilState(g_depthStencilState, 1); // Draw a triangle using the simple shaders context->VSSetShader(vertexShader.Get(), nullptr, 0); context->PSSetShader(pixelShader.Get(), nullptr, 0); context->Draw(3, 0); }
void D3D11Mesh::Render() { ID3D11DeviceContext* pContext = m_shader->GetContext(); ID3D11ShaderResourceView* ptexRv = dynamic_cast<D3D11Texture*>(m_tex)->m_textureRV; unsigned int stride = sizeof(Vertex); unsigned int offset = 0; pContext->IASetInputLayout(m_vertexLayout); pContext->IASetVertexBuffers(0, 1, &m_vertexBuffer, &stride, &offset); pContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST); pContext->PSSetShaderResources(0, 1, &ptexRv); pContext->Draw(m_numtriangles*3, 0); }
void D3D11App::DebugViewTexture2D(ID3D11ShaderResourceView *srv, const float x, const float y, const float width, const float height, const int slice) { // Make sure we have enough space in the vertex buffer SetToolsVBSize(4 * sizeof(Pos2Tex3)); // Fill vertex buffer Pos2Tex3 *dest; ID3D11DeviceContext* context = m_context->GetDeviceContext(); D3D11_MAPPED_SUBRESOURCE resource; context->Map(m_toolsVB, 0, D3D11_MAP_WRITE_DISCARD, 0, &resource); dest = reinterpret_cast<Pos2Tex3*> ( resource.pData ); dest[0].pos = float2(x, y + height); dest[0].tex = float3(0, 0, (float) slice); dest[1].pos = float2(x + width, y + height); dest[1].tex = float3(1, 0, (float) slice); dest[2].pos = float2(x, y); dest[2].tex = float3(0, 1, (float) slice); dest[3].pos = float2(x + width, y); dest[3].tex = float3(1, 1, (float) slice); context->Unmap(m_toolsVB, 0); ID3D11DeviceContext *dev = m_context->GetDeviceContext(); // Setup the effect m_context->SetEffect(m_toolsEffect); if (slice < 0) { m_context->SetTexture("tex2d", srv); m_context->Apply(2, 0); } else { m_context->SetTexture("texArray", srv); m_context->Apply(2, 1); } dev->IASetInputLayout(m_pos2Tex3Layout); UINT stride = sizeof(Pos2Tex3); UINT offset = 0; dev->IASetVertexBuffers(0, 1, &m_toolsVB, &stride, &offset); // Render a textured quad dev->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP); dev->Draw(4, 0); }
void Draw() { ID3D11DeviceContext* context = g_d3d.context_.get(); // Clear float clearColor[] = { 0.3f, 0.3f, 0.3f, 1.0f }; context->ClearRenderTargetView( g_d3d.backBufferRTV_.get(), clearColor ); auto* rtv = g_d3d.backBufferRTV_.get(); context->OMSetRenderTargets( 1, &rtv, nullptr ); // Draw body auto cbModelWVP = DirectX::XMMatrixIdentity(); auto matWorld = DirectX::XMMatrixIdentity(); matWorld = DirectX::XMMatrixRotationRollPitchYaw( g_d3d.jointRot_[ 0 ], g_d3d.jointRot_[ 1 ], g_d3d.jointRot_[ 2 ] ); auto matView = DirectX::XMMatrixLookAtLH( DirectX::XMVectorSet( 0, 0, -3, 0 ), DirectX::XMVectorSet( 0, 0, 5, 0 ), DirectX::XMVectorSet( 0, 1, 0, 0 ) ); auto matProj = DirectX::XMMatrixPerspectiveFovLH( DirectX::XMConvertToRadians( 50 ), (float)g_windowWidth / (float)g_windowHeight, 0.01f, 1000.0f ); cbModelWVP = matWorld * matView * matProj; cbModelWVP = DirectX::XMMatrixTranspose( cbModelWVP ); g_d3d.context_->UpdateSubresource( g_d3d.modelCB_.get(), 0, nullptr, &cbModelWVP, 0, 0 ); auto* vb = g_d3d.modelVB_.get(); unsigned int stride = sizeof( D3D::MeshFormat ); unsigned int offset = 0; auto* cb = g_d3d.modelCB_.get(); D3D11_VIEWPORT viewport = { 0, 0, g_windowWidth, g_windowHeight, 0, 1 }; context->IASetPrimitiveTopology( D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST ); context->IASetInputLayout( g_d3d.modelIL_.get() ); context->IASetVertexBuffers( 0, 1, &vb, &stride, &offset ); context->VSSetShader( g_d3d.modelVS_.get(), nullptr, 0 ); context->VSSetConstantBuffers( 0, 1, &cb ); context->RSSetState( g_d3d.rasterState_.get() ); context->PSSetShader( g_d3d.modelPS_.get(), nullptr, 0 ); context->RSSetViewports( 1, &viewport ); context->Draw( 18, 0 ); g_d3d.swapChain_->Present( 1, 0 ); }
//---------------------------------------------------------------------------------------------------- bool EEPoints2D::Render() { if (!EEObject::Render()) return false; MapObjectBuffer(); ID3D11DeviceContext *deviceContext = EECore::s_EECore->GetDeviceContext(); deviceContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_POINTLIST); deviceContext->IASetInputLayout(s_pointsIL); UINT stride = sizeof(EEPoints2DVertex); UINT offset = 0; deviceContext->IASetVertexBuffers(0, 1, &m_pointsVB, &stride, &offset); deviceContext->IASetIndexBuffer(NULL, DXGI_FORMAT_R32_UINT, 0); deviceContext->VSSetShader(s_pointsVS, NULL, 0); deviceContext->PSSetShader(s_pointsPS, NULL, 0); deviceContext->Draw(m_points.size(), 0); return true; }
//-------------------------------------------------------------------------------------------------------------------- void RDX11RenderHelper::DrawLine() { UINT dataBytes = m_LineVertices.GetSize() * sizeof( CVertexPC ); if( m_LineBufferBytes < dataBytes ) { SAFE_RELEASE( m_pLineBuffer ); m_LineBufferBytes = dataBytes; D3D11_BUFFER_DESC BufferDesc; BufferDesc.ByteWidth = m_LineBufferBytes; BufferDesc.Usage = D3D11_USAGE_DYNAMIC; BufferDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER; BufferDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; BufferDesc.MiscFlags = 0; GLOBAL::D3DDevice()->CreateBuffer( &BufferDesc, NULL, &m_pLineBuffer ); DXUT_SetDebugName( m_pLineBuffer, "LineBuffer" ); } ////////////////////////////////////////////////////////////////////////// // refresh vertex buffer ID3D11DeviceContext* pContext = GLOBAL::D3DContext(); D3D11_MAPPED_SUBRESOURCE MappedResource; if ( S_OK == pContext->Map( m_pLineBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &MappedResource ) ) { CopyMemory( MappedResource.pData, (void*)m_LineVertices.GetData(), dataBytes ); pContext->Unmap(m_pLineBuffer, 0); } ////////////////////////////////////////////////////////////////////////// // Draw UINT Stride = sizeof( CVertexPC ); UINT Offset = 0; GLOBAL::RenderStateMgr()->SetTopology(D3D_PRIMITIVE_TOPOLOGY_LINELIST); GLOBAL::RenderStateMgr()->SetVertexInput(FVF_3FP_1DC); pContext->IASetVertexBuffers( 0, 1, &m_pLineBuffer, &Stride, &Offset ); pContext->Draw( m_LineVertices.GetSize(), 0 ); m_LineVertices.Reset(); }
void CGUIShaderDX::DrawQuad(Vertex& v1, Vertex& v2, Vertex& v3, Vertex& v4) { if (!m_bCreated) return; ApplyChanges(); ID3D11DeviceContext* pContext = g_Windowing.Get3D11Context(); // update vertex buffer D3D11_MAPPED_SUBRESOURCE resource; if (SUCCEEDED(pContext->Map(m_pVertexBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &resource))) { // we are using strip topology Vertex vertices[4] = { v2, v3, v1, v4 }; memcpy(resource.pData, &vertices, sizeof(Vertex) * 4); pContext->Unmap(m_pVertexBuffer, 0); // Draw primitives pContext->Draw(4, 0); } }
//----------------------------------------------------------------------------- void CPUTMeshDX11::Draw() { // Skip empty meshes. if( mIndexCount == 0 && mVertexCount == 0) return; ID3D11DeviceContext *pContext = CPUT_DX11::GetContext(); pContext->IASetPrimitiveTopology( mD3DMeshTopology ); pContext->IASetVertexBuffers(0, 1, &mpVertexBuffer, &mVertexStride, &mVertexBufferOffset); if (mIndexCount) { pContext->IASetIndexBuffer(mpIndexBuffer, mIndexBufferFormat, 0); pContext->DrawIndexed( mIndexCount, 0, 0 ); } else { pContext->Draw( mVertexCount, 0 ); } }
/** Draws a single pipeline-state */ void D3D11GraphicsEngineQueued::DrawPipelineState(const PipelineState* state) { if (Engine::GAPI->GetRendererState()->RendererSettings.DisableDrawcalls) return; ID3D11DeviceContext* context = GetDeferredContextByThread(); switch(state->BaseState.DrawCallType) { case PipelineState::DCT_DrawTriangleList: context->Draw(state->BaseState.NumVertices, 0); break; case PipelineState::DCT_DrawIndexed: context->DrawIndexed(state->BaseState.NumIndices, state->BaseState.IndexOffset, 0); break; case PipelineState::DCT_DrawIndexedInstanced: context->DrawIndexedInstanced(state->BaseState.NumIndices, state->BaseState.NumInstances, 0, 0, state->BaseState.InstanceOffset); break; } }
//---------------------------------------------------------------------------------------------------- bool EECurve2D::Render() { if (!EEObject::Render()) return false; MapObjectBuffer(); ID3D11DeviceContext *deviceContext = EECore::s_EECore->GetDeviceContext(); deviceContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP); deviceContext->IASetInputLayout(s_curveIL); UINT stride = sizeof(EECurve2DVertex); UINT offset = 0; deviceContext->IASetVertexBuffers(0, 1, &m_curveVB, &stride, &offset); deviceContext->IASetIndexBuffer(NULL, DXGI_FORMAT_R32_UINT, 0); deviceContext->VSSetShader(s_curveVS, NULL, 0); ID3D11ShaderResourceView *texture = m_tex.GetTexture(); deviceContext->PSSetShaderResources(0, 1, &texture); deviceContext->PSSetShader(s_curvePS, NULL, 0); deviceContext->Draw(m_curve.size() << 1, 0); return true; }
void Model::Paint(const XMMATRIX &world, Camera *camera, XMFLOAT3 lightPos) { unsigned int stride = mSizeOfVertexDesc; unsigned int offset = 0; XMMATRIX view = camera->GetViewMatrix(); XMMATRIX proj = camera->GetProjectionMatrix(); MatrixBuffer buffer; buffer.world = XMMatrixTranspose(world); buffer.view = XMMatrixTranspose(view); buffer.proj = XMMatrixTranspose(proj); buffer.wvp = XMMatrixTranspose(world * view * proj); buffer.cameraPos = camera->GetPosition(); ID3D11DeviceContext *dc = GameEngine::GetInstance()->GetGraphicsManager()->GetGraphicsDeviceContext(); dc->IASetVertexBuffers(0, 1, &mVertexBuffer, &stride, &offset); dc->IASetInputLayout(mInputLayout); dc->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST); dc->VSSetShader(mVertexShader, 0, 0); dc->PSSetShader(mFragmentShader, 0, 0); dc->PSSetShaderResources(0, 1, &mTextureView); dc->PSSetSamplers(0, 1, &mTextureSamplerState); dc->UpdateSubresource(mMatrixBuffer, 0, 0, &buffer, 0, 0); dc->VSSetConstantBuffers(0, 1, &mMatrixBuffer); dc->UpdateSubresource(mLightBuffer, 0, 0, &lightPos, 0, 0); dc->VSSetConstantBuffers(1, 1, &mLightBuffer); if (mAnimation) { mAnimation->SetAnimationProperties(dc); } dc->Draw(mNumberOfVertices, 0); }
//----------------------------------------------------------------------------- void CPUTMeshDX11::Draw(CPUTRenderParameters &renderParams, ID3D11InputLayout *pInputLayout ) { // Skip empty meshes. //if( !mIndexCount ) { return; } ID3D11DeviceContext *pContext = ((CPUTRenderParametersDX*)&renderParams)->mpContext; pContext->IASetPrimitiveTopology( mD3DMeshTopology ); pContext->IASetVertexBuffers(0, 1, &mpVertexBuffer, &mVertexStride, &mVertexBufferOffset); if (mIndexCount) { pContext->IASetIndexBuffer(mpIndexBuffer, mIndexBufferFormat, 0); } pContext->IASetInputLayout( pInputLayout ); if (mIndexCount) { pContext->DrawIndexed( mIndexCount, 0, 0 ); } else { pContext->Draw( mVertexCount, 0 ); } }
// parameters should be validated/clamped by caller EGLint SwapChain11::swapRect(EGLint x, EGLint y, EGLint width, EGLint height) { if (!mSwapChain) { return EGL_SUCCESS; } ID3D11Device *device = mRenderer->getDevice(); ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext(); // Set vertices D3D11_MAPPED_SUBRESOURCE mappedResource; HRESULT result = deviceContext->Map(mQuadVB, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource); if (FAILED(result)) { return EGL_BAD_ACCESS; } d3d11::PositionTexCoordVertex *vertices = static_cast<d3d11::PositionTexCoordVertex*>(mappedResource.pData); // Create a quad in homogeneous coordinates float x1 = (x / float(mWidth)) * 2.0f - 1.0f; float y1 = (y / float(mHeight)) * 2.0f - 1.0f; float x2 = ((x + width) / float(mWidth)) * 2.0f - 1.0f; float y2 = ((y + height) / float(mHeight)) * 2.0f - 1.0f; float u1 = x / float(mWidth); float v1 = y / float(mHeight); float u2 = (x + width) / float(mWidth); float v2 = (y + height) / float(mHeight); d3d11::SetPositionTexCoordVertex(&vertices[0], x1, y1, u1, v1); d3d11::SetPositionTexCoordVertex(&vertices[1], x1, y2, u1, v2); d3d11::SetPositionTexCoordVertex(&vertices[2], x2, y1, u2, v1); d3d11::SetPositionTexCoordVertex(&vertices[3], x2, y2, u2, v2); deviceContext->Unmap(mQuadVB, 0); static UINT stride = sizeof(d3d11::PositionTexCoordVertex); static UINT startIdx = 0; deviceContext->IASetVertexBuffers(0, 1, &mQuadVB, &stride, &startIdx); // Apply state deviceContext->OMSetDepthStencilState(NULL, 0xFFFFFFFF); static const float blendFactor[4] = { 1.0f, 1.0f, 1.0f, 1.0f }; deviceContext->OMSetBlendState(NULL, blendFactor, 0xFFFFFFF); deviceContext->RSSetState(NULL); // Apply shaders deviceContext->IASetInputLayout(mPassThroughIL); deviceContext->IASetPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP); deviceContext->VSSetShader(mPassThroughVS, NULL, 0); deviceContext->PSSetShader(mPassThroughPS, NULL, 0); deviceContext->GSSetShader(NULL, NULL, 0); // Apply render targets mRenderer->setOneTimeRenderTarget(mBackBufferRTView); // Set the viewport D3D11_VIEWPORT viewport; viewport.TopLeftX = 0; viewport.TopLeftY = 0; viewport.Width = mWidth; viewport.Height = mHeight; viewport.MinDepth = 0.0f; viewport.MaxDepth = 1.0f; deviceContext->RSSetViewports(1, &viewport); // Apply textures deviceContext->PSSetShaderResources(0, 1, &mOffscreenSRView); deviceContext->PSSetSamplers(0, 1, &mPassThroughSampler); // Draw deviceContext->Draw(4, 0); result = mSwapChain->Present(mSwapInterval, 0); if (result == DXGI_ERROR_DEVICE_REMOVED) { HRESULT removedReason = device->GetDeviceRemovedReason(); ERR("Present failed: the D3D11 device was removed: 0x%08X", removedReason); return EGL_CONTEXT_LOST; } else if (result == DXGI_ERROR_DEVICE_RESET) { ERR("Present failed: the D3D11 device was reset from a bad command."); return EGL_CONTEXT_LOST; } else if (FAILED(result)) { ERR("Present failed with error code 0x%08X", result); } // Unbind static ID3D11ShaderResourceView *const nullSRV = NULL; deviceContext->PSSetShaderResources(0, 1, &nullSRV); mRenderer->unapplyRenderTargets(); mRenderer->markAllStateDirty(); return EGL_SUCCESS; }
gl::Error PixelTransfer11::copyBufferToTexture(const gl::PixelUnpackState &unpack, unsigned int offset, RenderTargetD3D *destRenderTarget, GLenum destinationFormat, GLenum sourcePixelsType, const gl::Box &destArea) { ANGLE_TRY(loadResources()); gl::Extents destSize = destRenderTarget->getExtents(); ASSERT(destArea.x >= 0 && destArea.x + destArea.width <= destSize.width && destArea.y >= 0 && destArea.y + destArea.height <= destSize.height && destArea.z >= 0 && destArea.z + destArea.depth <= destSize.depth ); const gl::Buffer &sourceBuffer = *unpack.pixelBuffer.get(); ASSERT(mRenderer->supportsFastCopyBufferToTexture(destinationFormat)); ID3D11PixelShader *pixelShader = findBufferToTexturePS(destinationFormat); ASSERT(pixelShader); // The SRV must be in the proper read format, which may be different from the destination format // EG: for half float data, we can load full precision floats with implicit conversion GLenum unsizedFormat = gl::GetInternalFormatInfo(destinationFormat).format; GLenum sourceFormat = gl::GetSizedInternalFormat(unsizedFormat, sourcePixelsType); const d3d11::Format &sourceFormatInfo = d3d11::Format::Get(sourceFormat, mRenderer->getRenderer11DeviceCaps()); DXGI_FORMAT srvFormat = sourceFormatInfo.srvFormat; ASSERT(srvFormat != DXGI_FORMAT_UNKNOWN); Buffer11 *bufferStorage11 = GetAs<Buffer11>(sourceBuffer.getImplementation()); ID3D11ShaderResourceView *bufferSRV = nullptr; ANGLE_TRY_RESULT(bufferStorage11->getSRV(srvFormat), bufferSRV); ASSERT(bufferSRV != nullptr); ID3D11RenderTargetView *textureRTV = GetAs<RenderTarget11>(destRenderTarget)->getRenderTargetView(); ASSERT(textureRTV != nullptr); CopyShaderParams shaderParams; setBufferToTextureCopyParams(destArea, destSize, sourceFormat, unpack, offset, &shaderParams); ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext(); ID3D11Buffer *nullBuffer = nullptr; UINT zero = 0; // Are we doing a 2D or 3D copy? ID3D11GeometryShader *geometryShader = ((destSize.depth > 1) ? mBufferToTextureGS : NULL); auto stateManager = mRenderer->getStateManager(); deviceContext->VSSetShader(mBufferToTextureVS, NULL, 0); deviceContext->GSSetShader(geometryShader, NULL, 0); deviceContext->PSSetShader(pixelShader, NULL, 0); stateManager->setShaderResource(gl::SAMPLER_PIXEL, 0, bufferSRV); deviceContext->IASetInputLayout(NULL); deviceContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_POINTLIST); deviceContext->IASetVertexBuffers(0, 1, &nullBuffer, &zero, &zero); deviceContext->OMSetBlendState(NULL, NULL, 0xFFFFFFF); deviceContext->OMSetDepthStencilState(mCopyDepthStencilState, 0xFFFFFFFF); deviceContext->RSSetState(mCopyRasterizerState); stateManager->setOneTimeRenderTarget(textureRTV, nullptr); if (!StructEquals(mParamsData, shaderParams)) { d3d11::SetBufferData(deviceContext, mParamsConstantBuffer, shaderParams); mParamsData = shaderParams; } deviceContext->VSSetConstantBuffers(0, 1, &mParamsConstantBuffer); // Set the viewport D3D11_VIEWPORT viewport; viewport.TopLeftX = 0; viewport.TopLeftY = 0; viewport.Width = static_cast<FLOAT>(destSize.width); viewport.Height = static_cast<FLOAT>(destSize.height); viewport.MinDepth = 0.0f; viewport.MaxDepth = 1.0f; deviceContext->RSSetViewports(1, &viewport); UINT numPixels = (destArea.width * destArea.height * destArea.depth); deviceContext->Draw(numPixels, 0); // Unbind textures and render targets and vertex buffer stateManager->setShaderResource(gl::SAMPLER_PIXEL, 0, NULL); deviceContext->VSSetConstantBuffers(0, 1, &nullBuffer); mRenderer->markAllStateDirty(); return gl::NoError(); }
/** * Handle Stereo Drawing. ***/ void* StereoPresenter::Provoke(void* pThis, int eD3D, int eD3DInterface, int eD3DMethod, DWORD dwNumberConnected, int& nProvokerIndex) { #ifdef _DEBUG_STP { wchar_t buf[128]; wsprintf(buf, L"[STP] ifc %u mtd %u", eD3DInterface, eD3DMethod); OutputDebugString(buf); } #endif // update our global time static float fGlobalTime = 0.0f; static DWORD dwTimeStart = 0; DWORD dwTimeCur = GetTickCount(); if (dwTimeStart == 0) dwTimeStart = dwTimeCur; fGlobalTime = (dwTimeCur - dwTimeStart) / 1000.0f; // only present accepted bool bValid = false; if (((eD3DInterface == INTERFACE_IDXGISWAPCHAIN) && (eD3DMethod == METHOD_IDXGISWAPCHAIN_PRESENT)) || ((eD3DInterface == INTERFACE_IDIRECT3DDEVICE9) && (eD3DMethod == METHOD_IDIRECT3DDEVICE9_PRESENT))) bValid = true; if (!bValid) return nullptr; // clear all previous menu events ZeroMemory(&m_abMenuEvents[0], sizeof(VireioMenuEvent)* (int)VireioMenuEvent::NumberOfEvents); // main menu update ? if ((m_sMainMenu.bOnChanged) && (!m_sMenuControl.eSelectionMovement)) { m_sMainMenu.bOnChanged = false; // loop through entries for (size_t nIx = 0; nIx < m_sMainMenu.asEntries.size(); nIx++) { // entry index changed ? if (m_sMainMenu.asEntries[nIx].bOnChanged) { m_sMainMenu.asEntries[nIx].bOnChanged = false; // set new menu index.. selection to zero m_sMenuControl.nMenuIx = (INT)nIx; m_sMenuControl.unSelectionFormer = m_sMenuControl.unSelection = 0; } } } // sub menu update ? if ((m_sSubMenu.bOnChanged) && (!m_sMenuControl.eSelectionMovement)) { m_sSubMenu.bOnChanged = false; // exit ? if (m_sSubMenu.bOnExit) m_sMenuControl.nMenuIx = -1; // loop through entries for (size_t nIx = 0; nIx < m_sSubMenu.asEntries.size(); nIx++) { // entry index changed ? if (m_sSubMenu.asEntries[nIx].bOnChanged) { m_sSubMenu.asEntries[nIx].bOnChanged = false; // font ? if (nIx == ENTRY_FONT) { // get device and context ID3D11Device* pcDevice = nullptr; ID3D11DeviceContext* pcContext = nullptr; HRESULT nHr = S_OK; if ((eD3DInterface == INTERFACE_IDXGISWAPCHAIN) && (eD3DMethod == METHOD_IDXGISWAPCHAIN_PRESENT)) nHr = GetDeviceAndContext((IDXGISwapChain*)pThis, &pcDevice, &pcContext); else { if (m_ppcTexView11[0]) { if (*(m_ppcTexView11[0])) (*(m_ppcTexView11[0]))->GetDevice(&pcDevice); if (pcDevice) pcDevice->GetImmediateContext(&pcContext); else nHr = E_FAIL; if (!pcContext) nHr = E_FAIL; } else nHr = E_FAIL; } if (SUCCEEDED(nHr)) { HRESULT nHr; // get base directory std::string strVireioPath = GetBaseDir(); // add file path strVireioPath += "font//"; strVireioPath += m_sSubMenu.asEntries[nIx].astrValueEnumeration[m_sSubMenu.asEntries[nIx].unValue]; strVireioPath += ".spritefont"; OutputDebugStringA(strVireioPath.c_str()); // create font, make backup VireioFont* pcOldFont = m_pcFontSegeo128; m_pcFontSegeo128 = new VireioFont(pcDevice, pcContext, strVireioPath.c_str(), 128.0f, 1.0f, nHr, 1); if (FAILED(nHr)) { delete m_pcFontSegeo128; m_pcFontSegeo128 = pcOldFont; } else { // set new font name m_strFontName = m_sSubMenu.asEntries[nIx].astrValueEnumeration[m_sSubMenu.asEntries[nIx].unValue]; // write to ini file char szFilePathINI[1024]; GetCurrentDirectoryA(1024, szFilePathINI); strcat_s(szFilePathINI, "\\VireioPerception.ini"); WritePrivateProfileStringA("Stereo Presenter", "strFontName", m_strFontName.c_str(), szFilePathINI); } } SAFE_RELEASE(pcDevice); SAFE_RELEASE(pcContext); } } } } // get xbox controller input XINPUT_STATE sControllerState; bool bControllerAttached = false; ZeroMemory(&sControllerState, sizeof(XINPUT_STATE)); if (XInputGetState(0, &sControllerState) == ERROR_SUCCESS) { bControllerAttached = true; } if (true) { #pragma region menu hotkeys static bool bReleased = true; static bool s_bOnMenu = false; // keyboard menu on/off event + get hand poses UINT uIxHandPoses = 0, uIxPoseRequest = 0; s_bOnMenu = GetAsyncKeyState(VK_LCONTROL) && GetAsyncKeyState(0x51); for (UINT unIx = 0; unIx < 32; unIx++) { // set menu bool event if (m_apsSubMenues[unIx]) { if (m_apsSubMenues[unIx]->bOnBack) { // main menu ? exit if ((m_sMenuControl.nMenuIx == -1) && (!m_sMenuControl.eSelectionMovement)) s_bOnMenu = true; else m_abMenuEvents[VireioMenuEvent::OnExit] = TRUE; m_apsSubMenues[unIx]->bOnBack = false; } // hand poses ? if (m_apsSubMenues[unIx]->bHandPosesPresent) uIxHandPoses = unIx; if (m_apsSubMenues[unIx]->bHandPosesRequest) uIxPoseRequest = unIx; } } if ((m_apsSubMenues[uIxHandPoses]) && (m_apsSubMenues[uIxPoseRequest])) { // copy the hand pose data to the request node m_apsSubMenues[uIxPoseRequest]->sPoseMatrix[0] = m_apsSubMenues[uIxHandPoses]->sPoseMatrix[0]; m_apsSubMenues[uIxPoseRequest]->sPoseMatrix[1] = m_apsSubMenues[uIxHandPoses]->sPoseMatrix[1]; m_apsSubMenues[uIxPoseRequest]->sPosition[0] = m_apsSubMenues[uIxHandPoses]->sPosition[0]; m_apsSubMenues[uIxPoseRequest]->sPosition[1] = m_apsSubMenues[uIxHandPoses]->sPosition[1]; } // static hotkeys : LCTRL+Q - toggle vireio menu // F12 - toggle stereo output if (GetAsyncKeyState(VK_F12)) { m_bHotkeySwitch = true; } else if (s_bOnMenu) { m_bMenuHotkeySwitch = true; } else if (m_bMenuHotkeySwitch) { m_bMenuHotkeySwitch = false; m_bMenu = !m_bMenu; for (UINT unIx = 0; unIx < 32; unIx++) { // set sub menu active if menu is active if (m_apsSubMenues[unIx]) m_apsSubMenues[unIx]->bIsActive = m_bMenu; } } else if (m_bHotkeySwitch) { if (m_eStereoMode) m_eStereoMode = VireioMonitorStereoModes::Vireio_Mono; else m_eStereoMode = VireioMonitorStereoModes::Vireio_SideBySide; m_bHotkeySwitch = false; } else bReleased = true; #pragma endregion #pragma region menu events // menu is shown ? if (m_bMenu) { // handle controller if (bControllerAttached) { if (sControllerState.Gamepad.wButtons & XINPUT_GAMEPAD_BACK) { m_abMenuEvents[VireioMenuEvent::OnExit] = TRUE; } if (sControllerState.Gamepad.wButtons & XINPUT_GAMEPAD_A) { m_abMenuEvents[VireioMenuEvent::OnAccept] = TRUE; } if (sControllerState.Gamepad.sThumbLY > 28000) m_abMenuEvents[VireioMenuEvent::OnUp] = TRUE; if (sControllerState.Gamepad.sThumbLY < -28000) m_abMenuEvents[VireioMenuEvent::OnDown] = TRUE; if (sControllerState.Gamepad.sThumbLX > 28000) m_abMenuEvents[VireioMenuEvent::OnRight] = TRUE; if (sControllerState.Gamepad.sThumbLX < -28000) m_abMenuEvents[VireioMenuEvent::OnLeft] = TRUE; } // loop through sub menues for (UINT unIx = 0; unIx < 32; unIx++) { // set bool events if (m_apsSubMenues[unIx]) { if (m_apsSubMenues[unIx]->bOnUp) m_abMenuEvents[VireioMenuEvent::OnUp] = TRUE; if (m_apsSubMenues[unIx]->bOnDown) m_abMenuEvents[VireioMenuEvent::OnDown] = TRUE; if (m_apsSubMenues[unIx]->bOnLeft) m_abMenuEvents[VireioMenuEvent::OnLeft] = TRUE; if (m_apsSubMenues[unIx]->bOnRight) m_abMenuEvents[VireioMenuEvent::OnRight] = TRUE; if (m_apsSubMenues[unIx]->bOnAccept) m_abMenuEvents[VireioMenuEvent::OnAccept] = TRUE; // clear events m_apsSubMenues[unIx]->bOnUp = false; m_apsSubMenues[unIx]->bOnDown = false; m_apsSubMenues[unIx]->bOnLeft = false; m_apsSubMenues[unIx]->bOnRight = false; m_apsSubMenues[unIx]->bOnAccept = false; m_apsSubMenues[unIx]->bOnBack = false; } } #pragma endregion #pragma region menu update/render // update UpdateMenu(fGlobalTime); // get device and context ID3D11Device* pcDevice = nullptr; ID3D11DeviceContext* pcContext = nullptr; HRESULT nHr = S_OK; if ((eD3DInterface == INTERFACE_IDXGISWAPCHAIN) && (eD3DMethod == METHOD_IDXGISWAPCHAIN_PRESENT)) nHr = GetDeviceAndContext((IDXGISwapChain*)pThis, &pcDevice, &pcContext); else { if (m_ppcTexView11[0]) { if (*(m_ppcTexView11[0])) (*(m_ppcTexView11[0]))->GetDevice(&pcDevice); if (pcDevice) pcDevice->GetImmediateContext(&pcContext); else nHr = E_FAIL; if (!pcContext) nHr = E_FAIL; } else nHr = E_FAIL; } if (FAILED(nHr)) { // release frame texture+view if (pcDevice) { pcDevice->Release(); pcDevice = nullptr; } if (pcContext) { pcContext->Release(); pcContext = nullptr; } return nullptr; } // create the depth stencil... if D3D11 if ((eD3DInterface == INTERFACE_IDXGISWAPCHAIN) && (eD3DMethod == METHOD_IDXGISWAPCHAIN_PRESENT) && (!m_pcDSGeometry11)) { ID3D11Texture2D* pcBackBuffer = nullptr; ((IDXGISwapChain*)pThis)->GetBuffer(0, __uuidof(ID3D11Texture2D), (LPVOID*)&pcBackBuffer); if (pcBackBuffer) { D3D11_TEXTURE2D_DESC sDesc; pcBackBuffer->GetDesc(&sDesc); pcBackBuffer->Release(); // Create depth stencil texture D3D11_TEXTURE2D_DESC descDepth; ZeroMemory(&descDepth, sizeof(descDepth)); descDepth.Width = sDesc.Width; descDepth.Height = sDesc.Height; descDepth.MipLevels = 1; descDepth.ArraySize = 1; descDepth.Format = DXGI_FORMAT_D24_UNORM_S8_UINT; descDepth.SampleDesc.Count = 1; descDepth.SampleDesc.Quality = 0; descDepth.Usage = D3D11_USAGE_DEFAULT; descDepth.BindFlags = D3D11_BIND_DEPTH_STENCIL; descDepth.CPUAccessFlags = 0; descDepth.MiscFlags = 0; if (FAILED(pcDevice->CreateTexture2D(&descDepth, NULL, &m_pcDSGeometry11))) OutputDebugString(L"[STP] Failed to create depth stencil."); // Create the depth stencil view D3D11_DEPTH_STENCIL_VIEW_DESC descDSV; ZeroMemory(&descDSV, sizeof(descDSV)); descDSV.Format = descDepth.Format; descDSV.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D; descDSV.Texture2D.MipSlice = 0; if (FAILED(pcDevice->CreateDepthStencilView(m_pcDSGeometry11, &descDSV, &m_pcDSVGeometry11))) OutputDebugString(L"[STP] Failed to create depth stencil view."); } } // get the viewport UINT dwNumViewports = 1; D3D11_VIEWPORT psViewport[16]; pcContext->RSGetViewports(&dwNumViewports, psViewport); // backup all states D3DX11_STATE_BLOCK sStateBlock; CreateStateblock(pcContext, &sStateBlock); // clear all states, set targets ClearContextState(pcContext); // set the menu texture (if present) if (m_ppcTexViewMenu) { if (*m_ppcTexViewMenu) { // set render target ID3D11RenderTargetView* pcRTView = *m_ppcTexViewMenu; pcContext->OMSetRenderTargets(1, &pcRTView, NULL); // set viewport D3D11_VIEWPORT sViewport = {}; sViewport.TopLeftX = 0; sViewport.TopLeftY = 0; sViewport.Width = 1024; sViewport.Height = 1024; sViewport.MinDepth = 0.0f; sViewport.MaxDepth = 1.0f; pcContext->RSSetViewports(1, &sViewport); // clear render target...zero alpha FLOAT afColorRgba[4] = { 0.5f, 0.4f, 0.2f, 0.4f }; pcContext->ClearRenderTargetView(*m_ppcTexViewMenu, afColorRgba); } } else if ((eD3DInterface == INTERFACE_IDXGISWAPCHAIN) && (eD3DMethod == METHOD_IDXGISWAPCHAIN_PRESENT)) { // set first active render target - the stored back buffer - get the stored private data view ID3D11Texture2D* pcBackBuffer = nullptr; ((IDXGISwapChain*)pThis)->GetBuffer(0, __uuidof(ID3D11Texture2D), (LPVOID*)&pcBackBuffer); ID3D11RenderTargetView* pcView = nullptr; UINT dwSize = sizeof(pcView); pcBackBuffer->GetPrivateData(PDIID_ID3D11TextureXD_RenderTargetView, &dwSize, (void*)&pcView); if (dwSize) { pcContext->OMSetRenderTargets(1, (ID3D11RenderTargetView**)&pcView, m_pcDSVGeometry11); pcView->Release(); } else { // create render target view for the back buffer ID3D11RenderTargetView* pcRTV = nullptr; pcDevice->CreateRenderTargetView(pcBackBuffer, NULL, &pcRTV); if (pcRTV) { pcBackBuffer->SetPrivateDataInterface(PDIID_ID3D11TextureXD_RenderTargetView, pcRTV); pcRTV->Release(); } } pcContext->RSSetViewports(dwNumViewports, psViewport); pcBackBuffer->Release(); // clear the depth stencil pcContext->ClearDepthStencilView(m_pcDSVGeometry11, D3D11_CLEAR_DEPTH, 1.0f, 0); } // create the font class if not present nHr = S_OK; if (!m_pcFontSegeo128) { // get base directory std::string strVireioPath = GetBaseDir(); // add file path strVireioPath += "font//"; strVireioPath += m_strFontName; strVireioPath += ".spritefont"; OutputDebugStringA(strVireioPath.c_str()); // create font m_pcFontSegeo128 = new VireioFont(pcDevice, pcContext, strVireioPath.c_str(), 128.0f, 1.0f, nHr, 1); } if (FAILED(nHr)) { delete m_pcFontSegeo128; m_pcFontSegeo128 = nullptr; } // render text (if font present) if (m_pcFontSegeo128) { m_pcFontSegeo128->SetTextAttributes(0.0f, 0.2f, 0.0001f); // set additional tremble for "accepted" event float fDepthTremble = 0.0f; if (m_sMenuControl.eSelectionMovement == MenuControl::SelectionMovement::Accepted) { float fActionTimeElapsed = (fGlobalTime - m_sMenuControl.fActionStartTime) / m_sMenuControl.fActionTime; fDepthTremble = sin(fActionTimeElapsed*PI_F) * -3.0f; } m_pcFontSegeo128->ToRender(pcContext, fGlobalTime, m_sMenuControl.fYOrigin, 30.0f, fDepthTremble); RenderMenu(pcDevice, pcContext); } else OutputDebugString(L"Failed to create font!"); // set back device ApplyStateblock(pcContext, &sStateBlock); if (pcDevice) { pcDevice->Release(); pcDevice = nullptr; } if (pcContext) { pcContext->Release(); pcContext = nullptr; } } #pragma endregion #pragma region draw stereo (optionally) // draw stereo target to screen (optionally) if ((m_eStereoMode) && (eD3DInterface == INTERFACE_IDXGISWAPCHAIN) && (eD3DMethod == METHOD_IDXGISWAPCHAIN_PRESENT)) { // DX 11 if ((m_ppcTexView11[0]) && (m_ppcTexView11[1])) { // get device and context ID3D11Device* pcDevice = nullptr; ID3D11DeviceContext* pcContext = nullptr; if (FAILED(GetDeviceAndContext((IDXGISwapChain*)pThis, &pcDevice, &pcContext))) { // release frame texture+view if (pcDevice) { pcDevice->Release(); pcDevice = nullptr; } if (pcContext) { pcContext->Release(); pcContext = nullptr; } return nullptr; } // get the viewport UINT dwNumViewports = 1; D3D11_VIEWPORT psViewport[16]; pcContext->RSGetViewports(&dwNumViewports, psViewport); // backup all states D3DX11_STATE_BLOCK sStateBlock; CreateStateblock(pcContext, &sStateBlock); // clear all states, set targets ClearContextState(pcContext); // set first active render target - the stored back buffer - get the stored private data view ID3D11Texture2D* pcBackBuffer = nullptr; ((IDXGISwapChain*)pThis)->GetBuffer(0, __uuidof(ID3D11Texture2D), (LPVOID*)&pcBackBuffer); ID3D11RenderTargetView* pcView = nullptr; UINT dwSize = sizeof(pcView); pcBackBuffer->GetPrivateData(PDIID_ID3D11TextureXD_RenderTargetView, &dwSize, (void*)&pcView); if (dwSize) { pcContext->OMSetRenderTargets(1, (ID3D11RenderTargetView**)&pcView, m_pcDSVGeometry11); pcView->Release(); } else { // create render target view for the back buffer ID3D11RenderTargetView* pcRTV = nullptr; pcDevice->CreateRenderTargetView(pcBackBuffer, NULL, &pcRTV); if (pcRTV) { pcBackBuffer->SetPrivateDataInterface(PDIID_ID3D11TextureXD_RenderTargetView, pcRTV); pcRTV->Release(); } } pcContext->RSSetViewports(dwNumViewports, psViewport); pcBackBuffer->Release(); // clear the depth stencil pcContext->ClearDepthStencilView(m_pcDSVGeometry11, D3D11_CLEAR_DEPTH, 1.0f, 0); // create all bool bool bAllCreated = true; // create vertex shader if (!m_pcVertexShader11) { if (FAILED(CreateVertexShaderTechnique(pcDevice, &m_pcVertexShader11, &m_pcVertexLayout11, VertexShaderTechnique::PosUV2D))) bAllCreated = false; } // create pixel shader... TODO !! add option to switch output if (!m_pcPixelShader11) { if (FAILED(CreatePixelShaderEffect(pcDevice, &m_pcPixelShader11, PixelShaderTechnique::FullscreenSimple))) bAllCreated = false; } // Create vertex buffer if (!m_pcVertexBuffer11) { if (FAILED(CreateFullScreenVertexBuffer(pcDevice, &m_pcVertexBuffer11))) bAllCreated = false; } // create constant buffer if (!m_pcConstantBufferDirect11) { if (FAILED(CreateGeometryConstantBuffer(pcDevice, &m_pcConstantBufferDirect11, (UINT)sizeof(GeometryConstantBuffer)))) bAllCreated = false; } if (bAllCreated) { // left/right eye for (int nEye = 0; nEye < 2; nEye++) { // Set the input layout pcContext->IASetInputLayout(m_pcVertexLayout11); // Set vertex buffer UINT stride = sizeof(TexturedVertex); UINT offset = 0; pcContext->IASetVertexBuffers(0, 1, &m_pcVertexBuffer11, &stride, &offset); // Set constant buffer, first update it... scale and translate the left and right image D3DXMATRIX sScale; D3DXMatrixScaling(&sScale, 0.5f, 1.0f, 1.0f); D3DXMATRIX sTrans; if (nEye == 0) D3DXMatrixTranslation(&sTrans, -0.5f, 0.0f, 0.0f); else D3DXMatrixTranslation(&sTrans, 0.5f, 0.0f, 0.0f); D3DXMatrixTranspose(&sTrans, &sTrans); D3DXMATRIX sProj; D3DXMatrixMultiply(&sProj, &sTrans, &sScale); pcContext->UpdateSubresource((ID3D11Resource*)m_pcConstantBufferDirect11, 0, NULL, &sProj, 0, 0); pcContext->VSSetConstantBuffers(0, 1, &m_pcConstantBufferDirect11); // Set primitive topology pcContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST); // set texture pcContext->PSSetShaderResources(0, 1, m_ppcTexView11[nEye]); // set shaders pcContext->VSSetShader(m_pcVertexShader11, 0, 0); pcContext->PSSetShader(m_pcPixelShader11, 0, 0); // Render a triangle pcContext->Draw(6, 0); } } // set back device ApplyStateblock(pcContext, &sStateBlock); if (pcDevice) { pcDevice->Release(); pcDevice = nullptr; } if (pcContext) { pcContext->Release(); pcContext = nullptr; } } } #pragma endregion } return nullptr; }
void D3D11App::RenderCameraPath() { if (!m_displayPath) return; uint vertexCount = m_camera.GetPathNodeCount(); if (vertexCount) { const int smoothCount = 12; // Compute vertex count needed if (m_displayPathLooping) vertexCount++; if (m_displaySmooth) vertexCount *= smoothCount; uint size = vertexCount * sizeof(float3); // Make sure we have enough from in the vertex buffer SetToolsVBSize(size); // Fill vertex buffer float3 *dest; ID3D11DeviceContext* context = m_context->GetDeviceContext(); D3D11_MAPPED_SUBRESOURCE resource; context->Map(m_toolsVB, 0, D3D11_MAP_WRITE_DISCARD, 0, &resource); dest = reinterpret_cast<float3*> ( resource.pData ) ; if (m_displaySmooth) { float d = 1.0f / smoothCount; for (uint i = 0; i < vertexCount; i++) { m_camera.GetNodeAt(i * d, &dest[i], NULL, m_displayPathLooping); } } else { uint count = vertexCount; if (m_displayPathLooping) count--; for (uint i = 0; i < count; i++) { dest[i] = m_camera.GetPathNodePosition(i); } if (m_displayPathLooping) dest[count] = m_camera.GetPathNodePosition(0); } context->Unmap(m_toolsVB, 0); ID3D11DeviceContext *dev = m_context->GetDeviceContext(); // Set constants float4x4 *mvp; dev->Map( m_toolsVsCB, 0, D3D11_MAP_WRITE_DISCARD, 0, &resource); mvp = reinterpret_cast<float4x4*> ( resource.pData ) ; *mvp = m_camera.GetModelViewProjection(); dev->Unmap(m_toolsVsCB, 0 ); // Setup effect m_context->SetEffect(m_toolsEffect); m_context->Apply(0, 0); dev->IASetInputLayout(m_pos3Layout); UINT stride = sizeof(float3); UINT offset = 0; dev->IASetVertexBuffers(0, 1, &m_toolsVB, &stride, &offset); // Render the camera path dev->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_LINESTRIP); dev->Draw(vertexCount, 0); } }
ParticleGenerator::ParticleGenerator(Particle p, DirectX::XMFLOAT3 pos, float lt, float sr, float numRoots) { init = false; lifeTime = lt; spawnRate = sr; position = pos; // Get necessary resources ResourceManager* rManager = ResourceManager::Instance(); ID3D11Device* device = rManager->GetDevice(); ID3D11DeviceContext* deviceContext = rManager->GetDeviceContext(); generatorVS = dynamic_cast<SimpleVertexShader*>(rManager->GetShader("ParticleGeneratorVS")); generatorGS = dynamic_cast<SimpleGeometryShader*>(rManager->GetShader("ParticleGeneratorGS")); // Create Stream Output variables generatorGS->CreateCompatibleStreamOutBuffer(&readBuff, 1000000); generatorGS->CreateCompatibleStreamOutBuffer(&writeBuff, 1000000); // Create initial ROOT vertex buffer UINT stride = sizeof(Particle); UINT offset = 0; Particle vertices[] = { p }; D3D11_BUFFER_DESC vbd; vbd.Usage = D3D11_USAGE_IMMUTABLE; vbd.ByteWidth = sizeof(Particle); vbd.BindFlags = D3D11_BIND_VERTEX_BUFFER; vbd.CPUAccessFlags = 0; vbd.MiscFlags = 0; vbd.StructureByteStride = 0; D3D11_SUBRESOURCE_DATA initialVertexData; initialVertexData.pSysMem = vertices; device->CreateBuffer(&vbd, &initialVertexData, &particleBuff); // Set constant variables generatorGS->SetFloat("dt", 0.0f); generatorGS->SetFloat("tt", 0.0f); generatorGS->SetFloat("lifeTime", lifeTime); generatorGS->SetFloat("spawnRate", spawnRate); generatorGS->SetFloat3("generatorPos", position); generatorGS->SetSamplerState("randomSampler", rManager->GetSamplerState("trilinear")); generatorGS->SetShaderResourceView("randomTexture", rManager->GetTexture("randomTexture")); // Activate shaders generatorVS->SetShader(true); generatorGS->SetShader(true); deviceContext->PSSetShader(0, 0, 0); deviceContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_POINTLIST); // Unbind vertex buffers (incase) ID3D11Buffer* unset = 0; deviceContext->IASetVertexBuffers(0, 1, &unset, &stride, &offset); deviceContext->IASetVertexBuffers(0, 1, &particleBuff, &stride, &offset); deviceContext->SOSetTargets(1, &writeBuff, &offset); deviceContext->Draw(1, 0); SimpleGeometryShader::UnbindStreamOutStage(deviceContext); deviceContext->GSSetShader(0, 0, 0); SwapBuffers(); }
angle::Result PixelTransfer11::copyBufferToTexture(const gl::Context *context, const gl::PixelUnpackState &unpack, unsigned int offset, RenderTargetD3D *destRenderTarget, GLenum destinationFormat, GLenum sourcePixelsType, const gl::Box &destArea) { ANGLE_TRY(loadResources(context)); gl::Extents destSize = destRenderTarget->getExtents(); ASSERT(destArea.x >= 0 && destArea.x + destArea.width <= destSize.width && destArea.y >= 0 && destArea.y + destArea.height <= destSize.height && destArea.z >= 0 && destArea.z + destArea.depth <= destSize.depth ); const gl::Buffer &sourceBuffer = *context->getGLState().getTargetBuffer(gl::BufferBinding::PixelUnpack); ASSERT(mRenderer->supportsFastCopyBufferToTexture(destinationFormat)); const d3d11::PixelShader *pixelShader = findBufferToTexturePS(destinationFormat); ASSERT(pixelShader); // The SRV must be in the proper read format, which may be different from the destination format // EG: for half float data, we can load full precision floats with implicit conversion GLenum unsizedFormat = gl::GetUnsizedFormat(destinationFormat); const gl::InternalFormat &sourceglFormatInfo = gl::GetInternalFormatInfo(unsizedFormat, sourcePixelsType); const d3d11::Format &sourceFormatInfo = d3d11::Format::Get( sourceglFormatInfo.sizedInternalFormat, mRenderer->getRenderer11DeviceCaps()); DXGI_FORMAT srvFormat = sourceFormatInfo.srvFormat; ASSERT(srvFormat != DXGI_FORMAT_UNKNOWN); Buffer11 *bufferStorage11 = GetAs<Buffer11>(sourceBuffer.getImplementation()); const d3d11::ShaderResourceView *bufferSRV = nullptr; ANGLE_TRY(bufferStorage11->getSRV(context, srvFormat, &bufferSRV)); ASSERT(bufferSRV != nullptr); const d3d11::RenderTargetView &textureRTV = GetAs<RenderTarget11>(destRenderTarget)->getRenderTargetView(); ASSERT(textureRTV.valid()); CopyShaderParams shaderParams; setBufferToTextureCopyParams(destArea, destSize, sourceglFormatInfo.sizedInternalFormat, unpack, offset, &shaderParams); ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext(); // Are we doing a 2D or 3D copy? const auto *geometryShader = ((destSize.depth > 1) ? &mBufferToTextureGS : nullptr); StateManager11 *stateManager = mRenderer->getStateManager(); stateManager->setDrawShaders(&mBufferToTextureVS, geometryShader, pixelShader); stateManager->setShaderResource(gl::ShaderType::Fragment, 0, bufferSRV); stateManager->setInputLayout(nullptr); stateManager->setPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_POINTLIST); stateManager->setSingleVertexBuffer(nullptr, 0, 0); stateManager->setSimpleBlendState(nullptr); stateManager->setDepthStencilState(&mCopyDepthStencilState, 0xFFFFFFFF); stateManager->setRasterizerState(&mCopyRasterizerState); stateManager->setRenderTarget(textureRTV.get(), nullptr); if (!StructEquals(mParamsData, shaderParams)) { d3d11::SetBufferData(deviceContext, mParamsConstantBuffer.get(), shaderParams); mParamsData = shaderParams; } stateManager->setVertexConstantBuffer(0, &mParamsConstantBuffer); // Set the viewport stateManager->setSimpleViewport(destSize); UINT numPixels = (destArea.width * destArea.height * destArea.depth); deviceContext->Draw(numPixels, 0); return angle::Result::Continue(); }
gl::Error Clear11::clearFramebuffer(const ClearParameters &clearParams, const gl::Framebuffer::Data &fboData) { const auto &colorAttachments = fboData.mColorAttachments; const auto &drawBufferStates = fboData.mDrawBufferStates; const auto *depthAttachment = fboData.mDepthAttachment; const auto *stencilAttachment = fboData.mStencilAttachment; ASSERT(colorAttachments.size() == drawBufferStates.size()); // Iterate over the color buffers which require clearing and determine if they can be // cleared with ID3D11DeviceContext::ClearRenderTargetView or ID3D11DeviceContext1::ClearView. // This requires: // 1) The render target is being cleared to a float value (will be cast to integer when clearing integer // render targets as expected but does not work the other way around) // 2) The format of the render target has no color channels that are currently masked out. // Clear the easy-to-clear buffers on the spot and accumulate the ones that require special work. // // If these conditions are met, and: // - No scissored clear is needed, then clear using ID3D11DeviceContext::ClearRenderTargetView. // - A scissored clear is needed then clear using ID3D11DeviceContext1::ClearView if available. // Otherwise draw a quad. // // Also determine if the depth stencil can be cleared with ID3D11DeviceContext::ClearDepthStencilView // by checking if the stencil write mask covers the entire stencil. // // To clear the remaining buffers, quads must be drawn containing an int, uint or float vertex color // attribute. gl::Extents framebufferSize; auto iter = std::find_if(colorAttachments.begin(), colorAttachments.end(), [](const gl::FramebufferAttachment *attachment) { return attachment != nullptr; }); if (iter != colorAttachments.end()) { framebufferSize.width = (*iter)->getWidth(); framebufferSize.height = (*iter)->getHeight(); framebufferSize.depth = 1; } else if (depthAttachment != nullptr) { framebufferSize.width = depthAttachment->getWidth(); framebufferSize.height = depthAttachment->getHeight(); framebufferSize.depth = 1; } else if (stencilAttachment != nullptr) { framebufferSize.width = stencilAttachment->getWidth(); framebufferSize.height = stencilAttachment->getHeight(); framebufferSize.depth = 1; } else { UNREACHABLE(); return gl::Error(GL_INVALID_OPERATION); } if (clearParams.scissorEnabled && (clearParams.scissor.x >= framebufferSize.width || clearParams.scissor.y >= framebufferSize.height || clearParams.scissor.x + clearParams.scissor.width <= 0 || clearParams.scissor.y + clearParams.scissor.height <= 0)) { // Scissor is enabled and the scissor rectangle is outside the renderbuffer return gl::Error(GL_NO_ERROR); } bool needScissoredClear = clearParams.scissorEnabled && (clearParams.scissor.x > 0 || clearParams.scissor.y > 0 || clearParams.scissor.x + clearParams.scissor.width < framebufferSize.width || clearParams.scissor.y + clearParams.scissor.height < framebufferSize.height); std::vector<MaskedRenderTarget> maskedClearRenderTargets; RenderTarget11* maskedClearDepthStencil = NULL; ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext(); ID3D11DeviceContext1 *deviceContext1 = mRenderer->getDeviceContext1IfSupported(); for (size_t colorAttachment = 0; colorAttachment < colorAttachments.size(); colorAttachment++) { if (clearParams.clearColor[colorAttachment] && colorAttachments[colorAttachment] != nullptr && drawBufferStates[colorAttachment] != GL_NONE) { const gl::FramebufferAttachment *attachment = colorAttachments[colorAttachment]; RenderTarget11 *renderTarget = NULL; gl::Error error = d3d11::GetAttachmentRenderTarget(attachment, &renderTarget); if (error.isError()) { return error; } const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(attachment->getInternalFormat()); if (clearParams.colorClearType == GL_FLOAT && !(formatInfo.componentType == GL_FLOAT || formatInfo.componentType == GL_UNSIGNED_NORMALIZED || formatInfo.componentType == GL_SIGNED_NORMALIZED)) { ERR("It is undefined behaviour to clear a render buffer which is not normalized fixed point or floating-" "point to floating point values (color attachment %u has internal format 0x%X).", colorAttachment, attachment->getInternalFormat()); } if ((formatInfo.redBits == 0 || !clearParams.colorMaskRed) && (formatInfo.greenBits == 0 || !clearParams.colorMaskGreen) && (formatInfo.blueBits == 0 || !clearParams.colorMaskBlue) && (formatInfo.alphaBits == 0 || !clearParams.colorMaskAlpha)) { // Every channel either does not exist in the render target or is masked out continue; } else if ((!mSupportsClearView && needScissoredClear) || clearParams.colorClearType != GL_FLOAT || (formatInfo.redBits > 0 && !clearParams.colorMaskRed) || (formatInfo.greenBits > 0 && !clearParams.colorMaskGreen) || (formatInfo.blueBits > 0 && !clearParams.colorMaskBlue) || (formatInfo.alphaBits > 0 && !clearParams.colorMaskAlpha)) { // A masked clear is required, or a scissored clear is required and ID3D11DeviceContext1::ClearView is unavailable MaskedRenderTarget maskAndRt; bool clearColor = clearParams.clearColor[colorAttachment]; maskAndRt.colorMask[0] = (clearColor && clearParams.colorMaskRed); maskAndRt.colorMask[1] = (clearColor && clearParams.colorMaskGreen); maskAndRt.colorMask[2] = (clearColor && clearParams.colorMaskBlue); maskAndRt.colorMask[3] = (clearColor && clearParams.colorMaskAlpha); maskAndRt.renderTarget = renderTarget; maskedClearRenderTargets.push_back(maskAndRt); } else { // ID3D11DeviceContext::ClearRenderTargetView or ID3D11DeviceContext1::ClearView is possible ID3D11RenderTargetView *framebufferRTV = renderTarget->getRenderTargetView(); if (!framebufferRTV) { return gl::Error(GL_OUT_OF_MEMORY, "Internal render target view pointer unexpectedly null."); } const d3d11::DXGIFormat &dxgiFormatInfo = d3d11::GetDXGIFormatInfo(renderTarget->getDXGIFormat()); // Check if the actual format has a channel that the internal format does not and set them to the // default values const float clearValues[4] = { ((formatInfo.redBits == 0 && dxgiFormatInfo.redBits > 0) ? 0.0f : clearParams.colorFClearValue.red), ((formatInfo.greenBits == 0 && dxgiFormatInfo.greenBits > 0) ? 0.0f : clearParams.colorFClearValue.green), ((formatInfo.blueBits == 0 && dxgiFormatInfo.blueBits > 0) ? 0.0f : clearParams.colorFClearValue.blue), ((formatInfo.alphaBits == 0 && dxgiFormatInfo.alphaBits > 0) ? 1.0f : clearParams.colorFClearValue.alpha), }; if (needScissoredClear) { // We shouldn't reach here if deviceContext1 is unavailable. ASSERT(deviceContext1); D3D11_RECT rect; rect.left = clearParams.scissor.x; rect.right = clearParams.scissor.x + clearParams.scissor.width; rect.top = clearParams.scissor.y; rect.bottom = clearParams.scissor.y + clearParams.scissor.height; deviceContext1->ClearView(framebufferRTV, clearValues, &rect, 1); } else { deviceContext->ClearRenderTargetView(framebufferRTV, clearValues); } } } } if (clearParams.clearDepth || clearParams.clearStencil) { const gl::FramebufferAttachment *attachment = (depthAttachment != nullptr) ? depthAttachment : stencilAttachment; ASSERT(attachment != nullptr); RenderTarget11 *renderTarget = NULL; gl::Error error = d3d11::GetAttachmentRenderTarget(attachment, &renderTarget); if (error.isError()) { return error; } const d3d11::DXGIFormat &dxgiFormatInfo = d3d11::GetDXGIFormatInfo(renderTarget->getDXGIFormat()); unsigned int stencilUnmasked = (stencilAttachment != nullptr) ? (1 << dxgiFormatInfo.stencilBits) - 1 : 0; bool needMaskedStencilClear = clearParams.clearStencil && (clearParams.stencilWriteMask & stencilUnmasked) != stencilUnmasked; if (needScissoredClear || needMaskedStencilClear) { maskedClearDepthStencil = renderTarget; } else { ID3D11DepthStencilView *framebufferDSV = renderTarget->getDepthStencilView(); if (!framebufferDSV) { return gl::Error(GL_OUT_OF_MEMORY, "Internal depth stencil view pointer unexpectedly null."); } UINT clearFlags = (clearParams.clearDepth ? D3D11_CLEAR_DEPTH : 0) | (clearParams.clearStencil ? D3D11_CLEAR_STENCIL : 0); FLOAT depthClear = gl::clamp01(clearParams.depthClearValue); UINT8 stencilClear = clearParams.stencilClearValue & 0xFF; deviceContext->ClearDepthStencilView(framebufferDSV, clearFlags, depthClear, stencilClear); } } if (maskedClearRenderTargets.size() > 0 || maskedClearDepthStencil) { // To clear the render targets and depth stencil in one pass: // // Render a quad clipped to the scissor rectangle which draws the clear color and a blend // state that will perform the required color masking. // // The quad's depth is equal to the depth clear value with a depth stencil state that // will enable or disable depth test/writes if the depth buffer should be cleared or not. // // The rasterizer state's stencil is set to always pass or fail based on if the stencil // should be cleared or not with a stencil write mask of the stencil clear value. // // ====================================================================================== // // Luckily, the gl spec (ES 3.0.2 pg 183) states that the results of clearing a render- // buffer that is not normalized fixed point or floating point with floating point values // are undefined so we can just write floats to them and D3D11 will bit cast them to // integers. // // Also, we don't have to worry about attempting to clear a normalized fixed/floating point // buffer with integer values because there is no gl API call which would allow it, // glClearBuffer* calls only clear a single renderbuffer at a time which is verified to // be a compatible clear type. // Bind all the render targets which need clearing ASSERT(maskedClearRenderTargets.size() <= mRenderer->getRendererCaps().maxDrawBuffers); std::vector<ID3D11RenderTargetView*> rtvs(maskedClearRenderTargets.size()); for (unsigned int i = 0; i < maskedClearRenderTargets.size(); i++) { RenderTarget11 *renderTarget = maskedClearRenderTargets[i].renderTarget; ID3D11RenderTargetView *rtv = renderTarget->getRenderTargetView(); if (!rtv) { return gl::Error(GL_OUT_OF_MEMORY, "Internal render target view pointer unexpectedly null."); } rtvs[i] = rtv; } ID3D11DepthStencilView *dsv = maskedClearDepthStencil ? maskedClearDepthStencil->getDepthStencilView() : NULL; ID3D11BlendState *blendState = getBlendState(maskedClearRenderTargets); const FLOAT blendFactors[4] = { 1.0f, 1.0f, 1.0f, 1.0f }; const UINT sampleMask = 0xFFFFFFFF; ID3D11DepthStencilState *dsState = getDepthStencilState(clearParams); const UINT stencilClear = clearParams.stencilClearValue & 0xFF; // Set the vertices UINT vertexStride = 0; const UINT startIdx = 0; const ClearShader* shader = NULL; D3D11_MAPPED_SUBRESOURCE mappedResource; HRESULT result = deviceContext->Map(mVertexBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource); if (FAILED(result)) { return gl::Error(GL_OUT_OF_MEMORY, "Failed to map internal masked clear vertex buffer, HRESULT: 0x%X.", result); } const gl::Rectangle *scissorPtr = clearParams.scissorEnabled ? &clearParams.scissor : NULL; switch (clearParams.colorClearType) { case GL_FLOAT: ApplyVertices(framebufferSize, scissorPtr, clearParams.colorFClearValue, clearParams.depthClearValue, mappedResource.pData); vertexStride = sizeof(d3d11::PositionDepthColorVertex<float>); shader = &mFloatClearShader; break; case GL_UNSIGNED_INT: ApplyVertices(framebufferSize, scissorPtr, clearParams.colorUIClearValue, clearParams.depthClearValue, mappedResource.pData); vertexStride = sizeof(d3d11::PositionDepthColorVertex<unsigned int>); shader = &mUintClearShader; break; case GL_INT: ApplyVertices(framebufferSize, scissorPtr, clearParams.colorIClearValue, clearParams.depthClearValue, mappedResource.pData); vertexStride = sizeof(d3d11::PositionDepthColorVertex<int>); shader = &mIntClearShader; break; default: UNREACHABLE(); break; } deviceContext->Unmap(mVertexBuffer, 0); // Set the viewport to be the same size as the framebuffer D3D11_VIEWPORT viewport; viewport.TopLeftX = 0; viewport.TopLeftY = 0; viewport.Width = framebufferSize.width; viewport.Height = framebufferSize.height; viewport.MinDepth = 0; viewport.MaxDepth = 1; deviceContext->RSSetViewports(1, &viewport); // Apply state deviceContext->OMSetBlendState(blendState, blendFactors, sampleMask); deviceContext->OMSetDepthStencilState(dsState, stencilClear); deviceContext->RSSetState(mRasterizerState); // Apply shaders deviceContext->IASetInputLayout(shader->inputLayout); deviceContext->VSSetShader(shader->vertexShader, NULL, 0); deviceContext->PSSetShader(shader->pixelShader, NULL, 0); deviceContext->GSSetShader(NULL, NULL, 0); // Apply vertex buffer deviceContext->IASetVertexBuffers(0, 1, &mVertexBuffer, &vertexStride, &startIdx); deviceContext->IASetPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP); // Apply render targets deviceContext->OMSetRenderTargets(rtvs.size(), (rtvs.empty() ? NULL : &rtvs[0]), dsv); // Draw the clear quad deviceContext->Draw(4, 0); // Clean up mRenderer->markAllStateDirty(); } return gl::Error(GL_NO_ERROR); }
void Clear11::clearFramebuffer(const gl::ClearParameters &clearParams, gl::Framebuffer *frameBuffer) { // First determine if a scissored clear is needed, this will always require drawing a quad. // // Otherwise, iterate over the color buffers which require clearing and determine if they can be // cleared with ID3D11DeviceContext::ClearRenderTargetView... This requires: // 1) The render target is being cleared to a float value (will be cast to integer when clearing integer // render targets as expected but does not work the other way around) // 2) The format of the render target has no color channels that are currently masked out. // Clear the easy-to-clear buffers on the spot and accumulate the ones that require special work. // // Also determine if the depth stencil can be cleared with ID3D11DeviceContext::ClearDepthStencilView // by checking if the stencil write mask covers the entire stencil. // // To clear the remaining buffers, quads must be drawn containing an int, uint or float vertex color // attribute. gl::Extents framebufferSize; if (frameBuffer->getFirstColorbuffer() != NULL) { gl::Renderbuffer *renderBuffer = frameBuffer->getFirstColorbuffer(); framebufferSize.width = renderBuffer->getWidth(); framebufferSize.height = renderBuffer->getHeight(); framebufferSize.depth = 1; } else if (frameBuffer->getDepthOrStencilbuffer() != NULL) { gl::Renderbuffer *renderBuffer = frameBuffer->getDepthOrStencilbuffer(); framebufferSize.width = renderBuffer->getWidth(); framebufferSize.height = renderBuffer->getHeight(); framebufferSize.depth = 1; } else { UNREACHABLE(); return; } if (clearParams.scissorEnabled && (clearParams.scissor.x >= framebufferSize.width || clearParams.scissor.y >= framebufferSize.height || clearParams.scissor.x + clearParams.scissor.width <= 0 || clearParams.scissor.y + clearParams.scissor.height <= 0)) { // Scissor is enabled and the scissor rectangle is outside the renderbuffer return; } bool needScissoredClear = clearParams.scissorEnabled && (clearParams.scissor.x > 0 || clearParams.scissor.y > 0 || clearParams.scissor.x + clearParams.scissor.width < framebufferSize.width || clearParams.scissor.y + clearParams.scissor.height < framebufferSize.height); GLuint clientVersion = mRenderer->getCurrentClientVersion(); std::vector<RenderTarget11*> maskedClearRenderTargets; RenderTarget11* maskedClearDepthStencil = NULL; ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext(); for (unsigned int colorAttachment = 0; colorAttachment < gl::IMPLEMENTATION_MAX_DRAW_BUFFERS; colorAttachment++) { if (clearParams.clearColor[colorAttachment] && frameBuffer->isEnabledColorAttachment(colorAttachment)) { gl::Renderbuffer *renderbuffer = frameBuffer->getColorbuffer(colorAttachment); if (renderbuffer) { RenderTarget11 *renderTarget = RenderTarget11::makeRenderTarget11(renderbuffer->getRenderTarget()); if (!renderTarget) { ERR("Render target pointer unexpectedly null."); return; } GLenum internalFormat = renderbuffer->getInternalFormat(); GLenum actualFormat = renderbuffer->getActualFormat(); GLenum componentType = gl::GetComponentType(internalFormat, clientVersion); if (clearParams.colorClearType == GL_FLOAT && !(componentType == GL_FLOAT || componentType == GL_UNSIGNED_NORMALIZED || componentType == GL_SIGNED_NORMALIZED)) { ERR("It is undefined behaviour to clear a render buffer which is not normalized fixed point or floating-" "point to floating point values (color attachment %u has internal format 0x%X).", colorAttachment, internalFormat); } GLuint internalRedBits = gl::GetRedBits(internalFormat, clientVersion); GLuint internalGreenBits = gl::GetGreenBits(internalFormat, clientVersion); GLuint internalBlueBits = gl::GetBlueBits(internalFormat, clientVersion); GLuint internalAlphaBits = gl::GetAlphaBits(internalFormat, clientVersion); if ((internalRedBits == 0 || !clearParams.colorMaskRed) && (internalGreenBits == 0 || !clearParams.colorMaskGreen) && (internalBlueBits == 0 || !clearParams.colorMaskBlue) && (internalAlphaBits == 0 || !clearParams.colorMaskAlpha)) { // Every channel either does not exist in the render target or is masked out continue; } else if (needScissoredClear || clearParams.colorClearType != GL_FLOAT || (internalRedBits > 0 && !clearParams.colorMaskRed) || (internalGreenBits > 0 && !clearParams.colorMaskGreen) || (internalBlueBits > 0 && !clearParams.colorMaskBlue) || (internalAlphaBits > 0 && !clearParams.colorMaskAlpha)) { // A scissored or masked clear is required maskedClearRenderTargets.push_back(renderTarget); } else { // ID3D11DeviceContext::ClearRenderTargetView is possible ID3D11RenderTargetView *framebufferRTV = renderTarget->getRenderTargetView(); if (!framebufferRTV) { ERR("Render target view pointer unexpectedly null."); return; } // Check if the actual format has a channel that the internal format does not and set them to the // default values GLuint actualRedBits = gl::GetRedBits(actualFormat, clientVersion); GLuint actualGreenBits = gl::GetGreenBits(actualFormat, clientVersion); GLuint actualBlueBits = gl::GetBlueBits(actualFormat, clientVersion); GLuint actualAlphaBits = gl::GetAlphaBits(actualFormat, clientVersion); const float clearValues[4] = { ((internalRedBits == 0 && actualRedBits > 0) ? 0.0f : clearParams.colorFClearValue.red), ((internalGreenBits == 0 && actualGreenBits > 0) ? 0.0f : clearParams.colorFClearValue.green), ((internalBlueBits == 0 && actualBlueBits > 0) ? 0.0f : clearParams.colorFClearValue.blue), ((internalAlphaBits == 0 && actualAlphaBits > 0) ? 1.0f : clearParams.colorFClearValue.alpha), }; deviceContext->ClearRenderTargetView(framebufferRTV, clearValues); } } } } if (clearParams.clearDepth || clearParams.clearStencil) { gl::Renderbuffer *renderbuffer = frameBuffer->getDepthOrStencilbuffer(); if (renderbuffer) { RenderTarget11 *renderTarget = RenderTarget11::makeRenderTarget11(renderbuffer->getDepthStencil()); if (!renderTarget) { ERR("Depth stencil render target pointer unexpectedly null."); return; } GLenum actualFormat = renderbuffer->getActualFormat(); unsigned int stencilUnmasked = frameBuffer->hasStencil() ? (1 << gl::GetStencilBits(actualFormat, clientVersion)) - 1 : 0; bool needMaskedStencilClear = clearParams.clearStencil && (clearParams.stencilWriteMask & stencilUnmasked) != stencilUnmasked; if (needScissoredClear || needMaskedStencilClear) { maskedClearDepthStencil = renderTarget; } else { ID3D11DepthStencilView *framebufferDSV = renderTarget->getDepthStencilView(); if (!framebufferDSV) { ERR("Depth stencil view pointer unexpectedly null."); return; } UINT clearFlags = (clearParams.clearDepth ? D3D11_CLEAR_DEPTH : 0) | (clearParams.clearStencil ? D3D11_CLEAR_STENCIL : 0); FLOAT depthClear = gl::clamp01(clearParams.depthClearValue); UINT8 stencilClear = clearParams.stencilClearValue & 0xFF; deviceContext->ClearDepthStencilView(framebufferDSV, clearFlags, depthClear, stencilClear); } } } if (maskedClearRenderTargets.size() > 0 || maskedClearDepthStencil) { // To clear the render targets and depth stencil in one pass: // // Render a quad clipped to the scissor rectangle which draws the clear color and a blend // state that will perform the required color masking. // // The quad's depth is equal to the depth clear value with a depth stencil state that // will enable or disable depth test/writes if the depth buffer should be cleared or not. // // The rasterizer state's stencil is set to always pass or fail based on if the stencil // should be cleared or not with a stencil write mask of the stencil clear value. // // ====================================================================================== // // Luckily, the gl spec (ES 3.0.2 pg 183) states that the results of clearing a render- // buffer that is not normalized fixed point or floating point with floating point values // are undefined so we can just write floats to them and D3D11 will bit cast them to // integers. // // Also, we don't have to worry about attempting to clear a normalized fixed/floating point // buffer with integer values because there is no gl API call which would allow it, // glClearBuffer* calls only clear a single renderbuffer at a time which is verified to // be a compatible clear type. // Bind all the render targets which need clearing ASSERT(maskedClearRenderTargets.size() <= mRenderer->getMaxRenderTargets()); std::vector<ID3D11RenderTargetView*> rtvs(maskedClearRenderTargets.size()); for (unsigned int i = 0; i < maskedClearRenderTargets.size(); i++) { ID3D11RenderTargetView *renderTarget = maskedClearRenderTargets[i]->getRenderTargetView(); if (!renderTarget) { ERR("Render target pointer unexpectedly null."); return; } rtvs[i] = renderTarget; } ID3D11DepthStencilView *dsv = maskedClearDepthStencil ? maskedClearDepthStencil->getDepthStencilView() : NULL; ID3D11BlendState *blendState = getBlendState(clearParams, maskedClearRenderTargets); const FLOAT blendFactors[4] = { 1.0f, 1.0f, 1.0f, 1.0f }; const UINT sampleMask = 0xFFFFFFFF; ID3D11DepthStencilState *dsState = getDepthStencilState(clearParams); const UINT stencilClear = clearParams.stencilClearValue & 0xFF; // Set the vertices UINT vertexStride = 0; const UINT startIdx = 0; const ClearShader* shader = NULL; D3D11_MAPPED_SUBRESOURCE mappedResource; HRESULT result = deviceContext->Map(mVertexBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource); if (FAILED(result)) { ERR("Failed to map masked clear vertex buffer, HRESULT: 0x%X.", result); return; } const gl::Rectangle *scissorPtr = clearParams.scissorEnabled ? &clearParams.scissor : NULL; switch (clearParams.colorClearType) { case GL_FLOAT: ApplyVertices(framebufferSize, scissorPtr, clearParams.colorFClearValue, clearParams.depthClearValue, mappedResource.pData); vertexStride = sizeof(d3d11::PositionDepthColorVertex<float>); shader = &mFloatClearShader; break; case GL_UNSIGNED_INT: ApplyVertices(framebufferSize, scissorPtr, clearParams.colorUIClearValue, clearParams.depthClearValue, mappedResource.pData); vertexStride = sizeof(d3d11::PositionDepthColorVertex<unsigned int>); shader = &mUintClearShader; break; case GL_INT: ApplyVertices(framebufferSize, scissorPtr, clearParams.colorIClearValue, clearParams.depthClearValue, mappedResource.pData); vertexStride = sizeof(d3d11::PositionDepthColorVertex<int>); shader = &mIntClearShader; break; default: UNREACHABLE(); break; } deviceContext->Unmap(mVertexBuffer, 0); // Set the viewport to be the same size as the framebuffer D3D11_VIEWPORT viewport; viewport.TopLeftX = 0; viewport.TopLeftY = 0; viewport.Width = framebufferSize.width; viewport.Height = framebufferSize.height; viewport.MinDepth = 0; viewport.MaxDepth = 1; deviceContext->RSSetViewports(1, &viewport); // Apply state deviceContext->OMSetBlendState(blendState, blendFactors, sampleMask); deviceContext->OMSetDepthStencilState(dsState, stencilClear); deviceContext->RSSetState(mRasterizerState); // Apply shaders deviceContext->IASetInputLayout(shader->inputLayout); deviceContext->VSSetShader(shader->vertexShader, NULL, 0); deviceContext->PSSetShader(shader->pixelShader, NULL, 0); deviceContext->GSSetShader(NULL, NULL, 0); // Apply vertex buffer deviceContext->IASetVertexBuffers(0, 1, &mVertexBuffer, &vertexStride, &startIdx); deviceContext->IASetPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP); // Apply render targets deviceContext->OMSetRenderTargets(rtvs.size(), (rtvs.empty() ? NULL : &rtvs[0]), dsv); // Draw the clear quad deviceContext->Draw(4, 0); // Clean up mRenderer->markAllStateDirty(); } }
void D3D11App::RenderBillboards(const float3 *position, const int count, const float size, const float4 &color) { // Make sure we have enough room in the tool vertex buffer SetToolsVBSize(count * 6 * sizeof(float3)); float3 dx, dy; m_camera.GetBaseVectors(&dx, &dy, NULL); // Fill vertex buffer float3 *dest; ID3D11DeviceContext* context = m_context->GetDeviceContext(); D3D11_MAPPED_SUBRESOURCE resource; context->Map( m_toolsVB, 0, D3D11_MAP_WRITE_DISCARD, 0, &resource); dest = reinterpret_cast<float3*> ( resource.pData ); for (int i = 0; i < count; i++) { dest[6 * i + 0] = position[i] + size * (-dx + dy); dest[6 * i + 1] = position[i] + size * ( dx + dy); dest[6 * i + 2] = position[i] + size * (-dx - dy); dest[6 * i + 3] = position[i] + size * (-dx - dy); dest[6 * i + 4] = position[i] + size * ( dx + dy); dest[6 * i + 5] = position[i] + size * ( dx - dy); } context->Unmap(m_toolsVB, 0 ); ID3D11DeviceContext *dev = m_context->GetDeviceContext(); // Set constants float4x4 *mvp; dev->Map(m_toolsVsCB, 0, D3D11_MAP_WRITE_DISCARD, 0, &resource); mvp = reinterpret_cast<float4x4*> ( resource.pData ); *mvp = m_camera.GetModelViewProjection(); dev->Unmap(m_toolsVsCB, 0); float4 *col; dev->Map( m_toolsPsCB, 0, D3D11_MAP_WRITE_DISCARD, 0, &resource); col = reinterpret_cast<float4*> ( resource.pData ); *col = color; dev->Unmap( m_toolsPsCB, 0 ); // Setup effect m_context->SetEffect(m_toolsEffect); m_context->Apply(1, 0); dev->IASetInputLayout(m_pos3Layout); UINT stride = sizeof(float3); UINT offset = 0; dev->IASetVertexBuffers(0, 1, &m_toolsVB, &stride, &offset); // Render the quads dev->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST); dev->Draw(6 * count, 0); }