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 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); }
void dx11ShaderOverride::terminateKey(MHWRender::MDrawContext& context, const MString& /*key*/) { if (fShaderNode) { MHWRender::MRenderer* theRenderer = MHWRender::MRenderer::theRenderer(); if (theRenderer) { dx11ShaderDX11Device* dxDevice = (dx11ShaderDX11Device*)theRenderer->GPUDeviceHandle(); if (dxDevice) { ID3D11DeviceContext* dxContext = NULL; dxDevice->GetImmediateContext(&dxContext); if (dxContext) { fShaderNode->restoreStates(dxContext, fStates); dxContext->VSSetShader(NULL, NULL, 0); dxContext->PSSetShader(NULL, NULL, 0); dxContext->GSSetShader(NULL, NULL, 0); dxContext->HSSetShader(NULL, NULL, 0); dxContext->DSSetShader(NULL, NULL, 0); dxContext->Release(); } } } } }
void D11State::draw() { clock_t t = clock(); float elapsed = static_cast<float>(t - timeT) / CLOCKS_PER_SEC; ++frameCount; if (elapsed > OVERLAY_FPS_INTERVAL) { OverlayMsg om; om.omh.uiMagic = OVERLAY_MAGIC_NUMBER; om.omh.uiType = OVERLAY_MSGTYPE_FPS; om.omh.iLength = sizeof(OverlayMsgFps); om.omf.fps = frameCount / elapsed; sendMessage(om); frameCount = 0; timeT = t; } checkMessage(static_cast<unsigned int>(vp.Width), static_cast<unsigned int>(vp.Height)); if (a_ucTexture && pSRView && (uiLeft != uiRight)) { if (!bDeferredContext) { pOrigStateBlock->Capture(); pMyStateBlock->Apply(); } // Set vertex buffer UINT stride = sizeof(SimpleVertex); UINT offset = 0; pDeviceContext->IASetVertexBuffers(0, 1, &pVertexBuffer, &stride, &offset); pDeviceContext->VSSetShader(pVertexShader, NULL, 0); pDeviceContext->GSSetShader(NULL, NULL, 0); pDeviceContext->PSSetShaderResources(0, 1, &pSRView); pDeviceContext->PSSetShader(pPixelShader, NULL, 0); pDeviceContext->DrawIndexed(6, 0, 0); if (bDeferredContext) { ID3D11CommandList *pCommandList; pDeviceContext->FinishCommandList(TRUE, &pCommandList); ID3D11DeviceContext *ctx = NULL; pDevice->GetImmediateContext(&ctx); ctx->ExecuteCommandList(pCommandList, TRUE); ctx->Release(); pCommandList->Release(); } else { pDeviceContext->Flush(); pMyStateBlock->Capture(); pOrigStateBlock->Apply(); } } }
void Shader::bind(D3DRenderer* renderer) { ID3D11DeviceContext* context = renderer->context(); context->IASetInputLayout(mpInputLayout); context->IASetPrimitiveTopology(mPrimitiveTopology); //Set any active shaders and disable ones not in use context->VSSetShader(mpVertexShader, NULL, 0); context->PSSetShader(mpPixelShader, NULL, 0); context->GSSetShader(mpGeometryShader, NULL, 0); context->CSSetShader(mpComputeShader, NULL, 0); context->HSSetShader(mpHullShader, NULL, 0); context->DSSetShader(mpDomainShader, NULL, 0); }
const void ShaderClass::RenderShader(UINT indexCount, UINT indexStart)const { ID3D11DeviceContext* c = SystemClass::GetInstance()->mGrapInst->GetContext(); // Set the vertex input layout. c->IASetInputLayout(mLayout); // Set the vertex and pixel shaders that will be used to render this triangle. c->VSSetShader(mVertexShader, nullptr, 0); c->HSSetShader(mHullShader, nullptr, 0); c->DSSetShader(mDomainShader, nullptr, 0); c->GSSetShader(mGeometryShader, nullptr, 0); c->PSSetShader(mPixelShader, nullptr, 0); // Render mesh stored in active buffers c->DrawIndexed(indexCount, indexStart, 0); }
void FontShader::renderShader(int i_indexCount) { ID3D11DeviceContext* deviceContext = GraphicsDX::GetDeviceContext(); // Set the vertex input layout. deviceContext->IASetInputLayout(_layout); // Set the vertex and pixel shaders that will be used to render the triangles. deviceContext->VSSetShader(_vertexShader, NULL, 0); deviceContext->HSSetShader(nullptr, NULL, 0); deviceContext->DSSetShader(nullptr, NULL, 0); deviceContext->GSSetShader(nullptr, NULL, 0); deviceContext->PSSetShader(_pixelShader, NULL, 0); // Set the sampler state in the pixel shader. deviceContext->PSSetSamplers(0, 1, &_sampleState); // Render the triangles. deviceContext->DrawIndexed(i_indexCount, 0, 0); }
void ParticleGenerator::Update(Transform eTransform, float dt, float tt) { ResourceManager* rManager = ResourceManager::Instance(); ID3D11DeviceContext* deviceContext = rManager->GetDeviceContext(); UINT stride = sizeof(Particle); UINT offset = 0; generatorVS = dynamic_cast<SimpleVertexShader*>(rManager->GetShader("ParticleGeneratorVS")); generatorGS = dynamic_cast<SimpleGeometryShader*>(rManager->GetShader("ParticleGeneratorGS")); DirectX::XMMATRIX translationMat = DirectX::XMMatrixTranslation(position.x, position.y, position.z); DirectX::XMMATRIX rotationMat = DirectX::XMMatrixRotationRollPitchYaw(eTransform.GetRotation().x * 2, eTransform.GetRotation().y * 2, eTransform.GetRotation().z * 2); DirectX::XMFLOAT4X4 transformMat; DirectX::XMStoreFloat4x4(&transformMat, DirectX::XMMatrixTranspose(translationMat * rotationMat)); DirectX::XMFLOAT3 finalPos = DirectX::XMFLOAT3(eTransform.GetTranslation().x + transformMat._14, eTransform.GetTranslation().y + transformMat._24, eTransform.GetTranslation().z + transformMat._34); // Set constant variables generatorGS->SetFloat("dt", dt); generatorGS->SetFloat("tt", tt); generatorGS->SetFloat3("generatorPos", finalPos); generatorGS->SetFloat("spawnRate", spawnRate); generatorGS->SetFloat("lifeTime", lifeTime); 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); // Unbind vertex buffers (incase) ID3D11Buffer* unset = 0; UINT unsetStride = 0; deviceContext->IASetVertexBuffers(0, 1, &unset, &stride, &offset); deviceContext->IASetVertexBuffers(0, 1, &readBuff, &stride, &offset); deviceContext->SOSetTargets(1, &writeBuff, &offset); deviceContext->DrawAuto(); // Kill everything SimpleGeometryShader::UnbindStreamOutStage(deviceContext); deviceContext->GSSetShader(0, 0, 0); SwapBuffers(); }
//--------------------------------------------------------------------------- void ShadowMapGen::Begin(RenderContext* rc, RenderSurface* pSurface, const AABB& bounds ) { m_rc = rc; m_pSurface = pSurface; ID3D11DeviceContext* dc = m_rc->Context(); // set depth-stencil state to default. dc->OMSetDepthStencilState(NULL,0); ShadowMaps::Inst()->UpdateLightCamera(dc, LightingState::Inst()->ProminentDirLight(), bounds); ShadowMaps::Inst()->SetAndClear(dc); dc->RSSetState( m_rasterStateShadow ); const Camera& lightCam = ShadowMaps::Inst()->GetCamera(); // update per frame cb ConstantBufferShadowMapGenPerFrame constBuffer; Matrix::Transpose(lightCam.View() ,constBuffer.view); Matrix::Transpose(lightCam.Proj(),constBuffer.proj); UpdateConstantBuffer(dc,m_pConstantBufferPerFrame,&constBuffer,sizeof(constBuffer)); // set imput layout. dc->IASetInputLayout( m_pVertexLayoutMesh ); // set shaders dc->VSSetShader( m_shaderShadowMapsVS, NULL, 0 ); dc->PSSetShader( NULL, NULL, 0 ); dc->GSSetShader( NULL, NULL, 0 ); ID3D11Buffer* constantBuffers[] = { m_pConstantBufferPerFrame, m_pConstantBufferPerDraw }; // set const buffers for vertex shader. dc->VSSetConstantBuffers( 0, ARRAY_SIZE(constantBuffers), constantBuffers ); }
// 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; }
void BillboardTrees::Render() { if (!m_loadingComplete) return; auto renderStateMgr = RenderStateMgr::Instance(); ID3D11DeviceContext* context = m_deviceResources->GetD3DDeviceContext(); // Set IA stage UINT stride = sizeof(PointSize); UINT offset = 0; if (ShaderChangement::PrimitiveType != D3D11_PRIMITIVE_TOPOLOGY_POINTLIST) { context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_POINTLIST); ShaderChangement::PrimitiveType = D3D11_PRIMITIVE_TOPOLOGY_POINTLIST; } if (ShaderChangement::InputLayout != m_treeInputLayout.Get()) { context->IASetInputLayout(m_treeInputLayout.Get()); ShaderChangement::InputLayout = m_treeInputLayout.Get(); } context->IASetVertexBuffers(0, 1, m_treeSpriteVB.GetAddressOf(), &stride, &offset); ID3D11Buffer* cbuffers[2] = { m_perFrameCB->GetBuffer(), m_treeSettingsCB.GetBuffer() }; ID3D11SamplerState* samplers[1] = { renderStateMgr->LinearSam() }; // Bind shaders, constant buffers, srvs and samplers context->VSSetShader(m_treeVS.Get(), 0, 0); ShaderChangement::VS = m_treeVS.Get(); context->GSSetShader(m_treeGS.Get(), 0, 0); context->GSSetConstantBuffers(0, 1, cbuffers); switch (m_renderOptions) { case BillTreeRenderOption::Light3: // Light context->PSSetShader(m_treeLight3PS.Get(), 0, 0); ShaderChangement::PS = m_treeLight3PS.Get(); break; case BillTreeRenderOption::Light3TexClip: // LightTexClip context->PSSetShader(m_treeLight3TexClipPS.Get(), 0, 0); ShaderChangement::PS = m_treeLight3TexClipPS.Get(); break; case BillTreeRenderOption::Light3TexClipFog: // LightTexClipFog context->PSSetShader(m_treeLight3TexClipFogPS.Get(), 0, 0); ShaderChangement::PS = m_treeLight3TexClipFogPS.Get(); break; default: throw ref new Platform::InvalidArgumentException("No such render option"); } context->PSSetConstantBuffers(0, 2, cbuffers); context->PSSetSamplers(0, 1, samplers); context->PSSetShaderResources(0, 1, m_treeTextureMapArraySRV.GetAddressOf()); float blendFactor[4] = { 0.0f, 0.0f, 0.0f, 0.0f }; if (m_alphaToCoverage) context->OMSetBlendState(renderStateMgr->AlphaToCoverBS(), blendFactor, 0xffffffff); context->Draw(m_treeCount, 0); // Recover render state if (m_alphaToCoverage) context->OMSetBlendState(nullptr, blendFactor, 0xffffffff); // Remove gs context->GSSetShader(nullptr, 0, 0); ShaderChangement::GS = nullptr; }
// parameters should be validated/clamped by caller EGLint SwapChain11::swapRect(EGLint x, EGLint y, EGLint width, EGLint height) { if (!mSwapChain) { return EGL_SUCCESS; } if (mRenderToBackBuffer) { // When rendering directly to the backbuffer, we must swap the whole buffer. if (!(x == 0 && y == 0 && width == mWidth && height == mHeight)) { ERR("When rendering directly to the backbuffer, swapRect can only be called on the entire backbuffer."); ASSERT(false); return EGL_FALSE; } } HRESULT result = S_OK; ID3D11Device *device = mRenderer->getDevice(); if (!mRenderToBackBuffer) { ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext(); // Set vertices D3D11_MAPPED_SUBRESOURCE mappedResource; 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 = static_cast<FLOAT>(mWidth); viewport.Height = static_cast<FLOAT>(mHeight); viewport.MinDepth = 0.0f; viewport.MaxDepth = 1.0f; deviceContext->RSSetViewports(1, &viewport); // Apply textures mRenderer->setShaderResource(gl::SAMPLER_PIXEL, 0, mOffscreenSRView); deviceContext->PSSetSamplers(0, 1, &mPassThroughSampler); // Draw deviceContext->Draw(4, 0); } #if ANGLE_VSYNC == ANGLE_DISABLED result = mSwapChain->Present(0, 0); #else // Use IDXGISwapChain1::Present1 with a dirty rect if DXGI 1.2 is available. if (mSwapChain1 != nullptr) { RECT rect = { static_cast<LONG>(x), static_cast<LONG>(mHeight - y - height), static_cast<LONG>(x + width), static_cast<LONG>(mHeight - y) }; DXGI_PRESENT_PARAMETERS params = { 1, &rect, nullptr, nullptr }; result = mSwapChain1->Present1(mSwapInterval, 0, ¶ms); } else { result = mSwapChain->Present(mSwapInterval, 0); } #endif if (result == DXGI_ERROR_DEVICE_REMOVED) { HRESULT removedReason = device->GetDeviceRemovedReason(); UNUSED_TRACE_VARIABLE(removedReason); 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 mRenderer->setShaderResource(gl::SAMPLER_PIXEL, 0, NULL); mRenderer->unapplyRenderTargets(); mRenderer->markAllStateDirty(); return EGL_SUCCESS; }
EGLint SwapChain11::copyOffscreenToBackbuffer(EGLint x, EGLint y, EGLint width, EGLint height) { if (!mSwapChain) { return EGL_SUCCESS; } initPassThroughResources(); 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); // Invert the quad vertices depending on the surface orientation. if ((mOrientation & EGL_SURFACE_ORIENTATION_INVERT_X_ANGLE) != 0) { std::swap(x1, x2); } if ((mOrientation & EGL_SURFACE_ORIENTATION_INVERT_Y_ANGLE) != 0) { std::swap(y1, y2); } 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(mPassThroughRS); // 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); auto stateManager = mRenderer->getStateManager(); // Apply render targets stateManager->setOneTimeRenderTarget(mBackBufferRTView, nullptr); // Set the viewport D3D11_VIEWPORT viewport; viewport.TopLeftX = 0; viewport.TopLeftY = 0; viewport.Width = static_cast<FLOAT>(mWidth); viewport.Height = static_cast<FLOAT>(mHeight); viewport.MinDepth = 0.0f; viewport.MaxDepth = 1.0f; deviceContext->RSSetViewports(1, &viewport); // Apply textures stateManager->setShaderResource(gl::SAMPLER_PIXEL, 0, mOffscreenSRView); deviceContext->PSSetSamplers(0, 1, &mPassThroughSampler); // Draw deviceContext->Draw(4, 0); // Rendering to the swapchain is now complete. Now we can call Present(). // Before that, we perform any cleanup on the D3D device. We do this before Present() to make sure the // cleanup is caught under the current eglSwapBuffers() PIX/Graphics Diagnostics call rather than the next one. stateManager->setShaderResource(gl::SAMPLER_PIXEL, 0, NULL); mRenderer->markAllStateDirty(); return EGL_SUCCESS; }
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(); } }
// WinMain int APIENTRY _tWinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow ) { HRESULT hr; // ウィンドウクラスを登録 WNDCLASSEX wcex = { sizeof( WNDCLASSEX ), // cbSize CS_HREDRAW | CS_VREDRAW, // style WndProc, // lpfnWndProc 0, // cbClsExtra 0, // cbWndExtra hInstance, // hInstance NULL, // hIcon NULL, // hCursor ( HBRUSH )( COLOR_WINDOW + 1 ), // hbrBackGround NULL, // lpszMenuName g_className, // lpszClassName NULL // hIconSm }; if ( ! RegisterClassEx( &wcex ) ) { MessageBox( NULL, _T( "失敗: RegisterClassEx()" ), _T( "エラー" ), MB_OK | MB_ICONERROR ); return 0; } dtprintf( _T( "RegisterClassEx: ok\n" ) ); // ウィンドウサイズを計算 RECT r = { 0, 0, 800, 450 }; // 800x450 (16:9) if ( ! AdjustWindowRect( &r, WS_OVERLAPPEDWINDOW, FALSE ) ) { MessageBox( NULL, _T( "失敗: AdjustWindowRect()" ), _T( "エラー" ), MB_OK | MB_ICONERROR ); return 0; } dtprintf( _T( "AdjustWindowRect: ok (%d, %d)-(%d, %d)\n" ), r.left, r.top, r.right, r.bottom ); // ウィンドウ生成 HWND hWnd; hWnd = CreateWindow( g_className, g_windowName, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, 0, r.right - r.left, r.bottom - r.top, NULL, NULL, hInstance, NULL ); if ( hWnd == NULL ) { MessageBox( NULL, _T( "失敗: CreateWindow()" ), _T( "エラー" ), MB_OK | MB_ICONERROR ); return 0; } dtprintf( _T( "CreateWindow: ok\n" ) ); // ウィンドウ表示 ShowWindow(hWnd, nCmdShow); dtprintf( _T( "ShowWindow: ok\n" ) ); // スワップチェイン設定 DXGI_SWAP_CHAIN_DESC scDesc = { { 1280, // BufferDesc.Width 720, // BufferDesc.Height { 60, // BufferDesc.RefreshRate.Numerator 1 // BufferDesc.RefreshRate.Denominator }, DXGI_FORMAT_R16G16B16A16_FLOAT, // BufferDesc.Format DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED, // BufferDesc.ScanlineOrdering DXGI_MODE_SCALING_CENTERED // BufferDesc.Scaling }, { 1, // SampleDesc.Count 0 // SampleDesc.Quality }, DXGI_USAGE_RENDER_TARGET_OUTPUT, // BufferUsage 1, // BufferCount hWnd, // OutputWindow TRUE, // Windowed DXGI_SWAP_EFFECT_DISCARD, // SwapEffect DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH // Flags }; // Direct3D11 デバイス・デバイスコンテキスト・スワップチェーン生成 ID3D11Device * pDevice = NULL; ID3D11DeviceContext * pDeviceContext = NULL; IDXGISwapChain * pSwapChain = NULL; D3D_FEATURE_LEVEL feature; hr = D3D11CreateDeviceAndSwapChain( NULL, D3D_DRIVER_TYPE_HARDWARE, NULL, 0, NULL, 0, D3D11_SDK_VERSION, &scDesc, &pSwapChain, &pDevice, &feature, &pDeviceContext ); if ( FAILED( hr ) ) { MessageBox( NULL, _T( "失敗: D3D11CreateDeviceAndSwapChain()" ), _T( "エラー" ), MB_OK | MB_ICONERROR ); return 0; } dtprintf( _T( "D3D11CreateDeviceAndSwapChain: ok (pDevice: 0x%p, pDeviceContext: 0x%p, pSwapChain: 0x%p, feature: 0x%4x)\n" ), pDevice, pDeviceContext, pSwapChain, ( int ) feature ); // バックバッファテクスチャ取得 ID3D11Texture2D * pBackBuffer = NULL; hr = pSwapChain->GetBuffer( 0, __uuidof( pBackBuffer ), reinterpret_cast< void ** >( &pBackBuffer ) ); if ( FAILED( hr ) ) { MessageBox( NULL, _T( "失敗: IDXGISwapChain::GetBuffer()" ), _T( "エラー" ), MB_OK | MB_ICONERROR ); return 0; } dtprintf( _T( "IDXGISwapChain::GetBuffer: ok (pBackBuffer: 0x%p)\n" ), pBackBuffer ); // レンダーターゲットビュー生成 ID3D11RenderTargetView * pRenderTargetView = NULL; hr = pDevice->CreateRenderTargetView( pBackBuffer, NULL, &pRenderTargetView ); if ( FAILED( hr ) ) { MessageBox( NULL, _T( "失敗: ID3D11Device::CreateRenderTargetView()" ), _T( "エラー" ), MB_OK | MB_ICONERROR ); return 0; } dtprintf( _T( "ID3D11Device::CreateRenderTargetView: ok (pRenderTargetView: 0x%p)\n" ), pRenderTargetView ); // レンダーターゲットビューをバインド pDeviceContext->OMSetRenderTargets( 1, &pRenderTargetView, NULL ); dtprintf( _T( "ID3D11DeviceContext::OMSetRenderTargets: ok\n" ) ); // バックバッファはもうここでは使わない COM_SAFE_RELEASE( pBackBuffer ); // ビューポートをバインド D3D11_VIEWPORT viewport = { 0.0f, // TopLeftX 0.0f, // TopLeftY 1280.0f, // Width 720.0f, // Height 0.0f, // MinDepth 1.0f // MaxDepth }; pDeviceContext->RSSetViewports( 1, &viewport ); dtprintf( _T( "ID3D11DeviceContext::RSSetViewports: ok\n" ) ); // 頂点データ float vertices[ 5 ][ 7 ] = { // Xaxis Yaxis Zaxis 赤 緑 青 Alpha { 0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f }, // 原点 { -0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 0.0f, 1.0f }, // 左上 { 0.5f, 0.5f, 0.5f, 1.0f, 1.0f, 0.0f, 1.0f }, // 右上 { 0.5f, -0.5f, 0.5f, 0.0f, 1.0f, 0.0f, 1.0f }, // 右下 { -0.5f, -0.5f, 0.5f, 0.0f, 1.0f, 1.0f, 1.0f } // 左下 }; // 入力エレメント記述子 D3D11_INPUT_ELEMENT_DESC verticesDesc[] = { { "IN_POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 }, { "IN_COLOR", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, sizeof(float)*3, D3D11_INPUT_PER_VERTEX_DATA, 0 } }; // 頂点バッファを生成 D3D11_BUFFER_DESC vertexBufferDesc = { 5 * sizeof( float ) * 7, // ByteWidth D3D11_USAGE_DEFAULT, // Usage D3D11_BIND_VERTEX_BUFFER, // BindFlags 0, // CPUAccessFlags 0, // MiscFlags 0 // StructureByteStride }; D3D11_SUBRESOURCE_DATA vertexResourceData = { vertices }; ID3D11Buffer * pVertexBuffer = NULL; hr = pDevice->CreateBuffer( &vertexBufferDesc, &vertexResourceData, &pVertexBuffer ); if ( FAILED( hr ) ) { MessageBox( NULL, _T( "失敗: ID3D11Device::CreateBuffer()" ), _T( "エラー" ), MB_OK | MB_ICONERROR ); return 0; } dtprintf( _T( "ID3D11Device::CreateBuffer: ok (pVertexBuffer: 0x%p)\n" ), pVertexBuffer ); // 頂点バッファをバインド UINT strides[] = { sizeof( float ) * 7 }; UINT offsets[] = { 0 }; pDeviceContext->IASetVertexBuffers( 0, 1, &pVertexBuffer, strides, offsets ); dtprintf( _T( "ID3D11DeviceContext::IASetVertexBuffers: ok\n" ) ); // インデックスデータ unsigned int indices[] = { 0, 1, 2, 0, 2, 3, 0, 3, 4, 0, 4, 1 }; // インデックスバッファを生成 D3D11_BUFFER_DESC indexBufferDesc = { sizeof( unsigned int ) * 12, // ByteWidth D3D11_USAGE_DEFAULT, // Usage D3D11_BIND_INDEX_BUFFER, // BindFlags 0, // CPUAccessFlags 0, // MiscFlags 0 // StructureByteStride }; D3D11_SUBRESOURCE_DATA indexResourceData = { indices }; ID3D11Buffer * pIndexBuffer = NULL; hr = pDevice->CreateBuffer( &indexBufferDesc, &indexResourceData, &pIndexBuffer ); if ( FAILED( hr ) ) { MessageBox( NULL, _T( "失敗: ID3D11Device::CreateBuffer()" ), _T( "エラー" ), MB_OK | MB_ICONERROR ); return 0; } dtprintf( _T( "ID3D11Device::CreateBuffer: ok (pIndexBuffer: 0x%p)\n" ), pIndexBuffer ); // インデックスバッファをバインド pDeviceContext->IASetIndexBuffer( pIndexBuffer, DXGI_FORMAT_R32_UINT, 0 ); dtprintf( _T( "ID3D11DeviceContext::IASetIndexBuffer: ok\n" ) ); // プリミティブタイプを設定 pDeviceContext->IASetPrimitiveTopology( D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST ); dtprintf( _T( "ID3D11DeviceContext::IASetPrimitiveTopology: ok\n" ) ); // 頂点シェーダを作成 ID3D11VertexShader * pVertexShader = NULL; hr = pDevice->CreateVertexShader( g_vs_constant, sizeof( g_vs_constant ), NULL, &pVertexShader ); if ( FAILED( hr ) ) { MessageBox( NULL, _T( "失敗: ID3D11Device::CreateVertexShader()" ), _T( "エラー" ), MB_OK | MB_ICONERROR ); return 0; } dtprintf( _T( "ID3D11Device::CreateVertexShader: ok (pVertexShader: 0x%p)\n" ), pVertexShader ); // ピクセルシェーダを作成 ID3D11PixelShader * pPixelShader = NULL; hr = pDevice->CreatePixelShader( g_ps_constant, sizeof( g_ps_constant ), NULL, &pPixelShader ); if ( FAILED( hr ) ) { MessageBox( NULL, _T( "失敗: ID3D11Device::CreatePixelShader()" ), _T( "エラー" ), MB_OK | MB_ICONERROR ); return 0; } dtprintf( _T( "ID3D11Device::CreatePixelShader: ok (pPixelShader: 0x%p)\n" ), pPixelShader ); // シェーダをバインド pDeviceContext->VSSetShader( pVertexShader, NULL, 0 ); dtprintf( _T( "ID3D11DeviceContext::VSSetShader: ok\n" ) ); pDeviceContext->PSSetShader( pPixelShader, NULL, 0 ); dtprintf( _T( "ID3D11DeviceContext::PSSetShader: ok\n" ) ); pDeviceContext->GSSetShader( NULL, NULL, 0 ); pDeviceContext->HSSetShader( NULL, NULL, 0 ); pDeviceContext->DSSetShader( NULL, NULL, 0 ); // 入力レイアウトを生成 ID3D11InputLayout * pInputLayout = NULL; hr = pDevice->CreateInputLayout( verticesDesc, 2, g_vs_constant, sizeof( g_vs_constant ), &pInputLayout ); if ( FAILED( hr ) ) { MessageBox( NULL, _T( "失敗: ID3D11Device::CreateInputLayout()" ), _T( "エラー" ), MB_OK | MB_ICONERROR ); return 0; } dtprintf( _T( "ID3D11Device::CreateInputLayout: ok (pInputLayout: 0x%p)\n" ), pInputLayout ); // 入力レイアウトをバインド pDeviceContext->IASetInputLayout( pInputLayout ); dtprintf( _T( "ID3D11DeviceContext::IASetInputLayout: ok\n" ) ); MSG msg; while ( 1 ) { // メッセージを取得 if ( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) ) { if ( msg.message == WM_QUIT ) { dtprintf( _T( "PeekMessage: WM_QUIT\n" ) ); break; } // メッセージ処理 DispatchMessage( &msg ); } else { // レンダーターゲットをクリア const float clear[ 4 ] = { 0.0f, 0.0f, 1.0f, 1.0f }; // RGBA pDeviceContext->ClearRenderTargetView( pRenderTargetView, clear ); // 描画 pDeviceContext->DrawIndexed( 12, 0, 0 ); pSwapChain->Present( 1, 0 ); // ちょっとだけ待つ Sleep( 5 ); } } // シェーダをアンバインド pDeviceContext->VSSetShader( NULL, NULL, 0 ); pDeviceContext->PSSetShader( NULL, NULL, 0 ); // デバイス・リソース解放 COM_SAFE_RELEASE( pInputLayout ); COM_SAFE_RELEASE( pPixelShader ); COM_SAFE_RELEASE( pVertexShader ); COM_SAFE_RELEASE( pIndexBuffer ); COM_SAFE_RELEASE( pVertexBuffer ); COM_SAFE_RELEASE( pRenderTargetView ); COM_SAFE_RELEASE( pSwapChain ); COM_SAFE_RELEASE( pDeviceContext ); COM_SAFE_RELEASE( pDevice ); return msg.wParam; }
// WinMain int APIENTRY _tWinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow ) { HRESULT hr; // ウィンドウクラスを登録 WNDCLASSEX wcex = { sizeof( WNDCLASSEX ), // cbSize CS_HREDRAW | CS_VREDRAW, // style WndProc, // lpfnWndProc 0, // cbClsExtra 0, // cbWndExtra hInstance, // hInstance NULL, // hIcon NULL, // hCursor ( HBRUSH )( COLOR_WINDOW + 1 ), // hbrBackGround NULL, // lpszMenuName g_className, // lpszClassName NULL // hIconSm }; if ( ! RegisterClassEx( &wcex ) ) { MessageBox( NULL, _T( "失敗: RegisterClassEx()" ), _T( "エラー" ), MB_OK | MB_ICONERROR ); return 0; } dtprintf( _T( "RegisterClassEx: ok\n" ) ); // ウィンドウサイズを計算 RECT r = { 0, 0, 800, 450 }; // 800x450 (16:9) if ( ! AdjustWindowRect( &r, WS_OVERLAPPEDWINDOW, FALSE ) ) { MessageBox( NULL, _T( "失敗: AdjustWindowRect()" ), _T( "エラー" ), MB_OK | MB_ICONERROR ); return 0; } dtprintf( _T( "AdjustWindowRect: ok (%d, %d)-(%d, %d)\n" ), r.left, r.top, r.right, r.bottom ); // ウィンドウ生成 HWND hWnd; hWnd = CreateWindow( g_className, g_windowName, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, 0, r.right - r.left, r.bottom - r.top, NULL, NULL, hInstance, NULL ); if ( hWnd == NULL ) { MessageBox( NULL, _T( "失敗: CreateWindow()" ), _T( "エラー" ), MB_OK | MB_ICONERROR ); return 0; } dtprintf( _T( "CreateWindow: ok\n" ) ); // ウィンドウ表示 ShowWindow(hWnd, nCmdShow); dtprintf( _T( "ShowWindow: ok\n" ) ); // スワップチェイン設定 DXGI_SWAP_CHAIN_DESC scDesc = { { 1280, // BufferDesc.Width 720, // BufferDesc.Height { 60, // BufferDesc.RefreshRate.Numerator 1 // BufferDesc.RefreshRate.Denominator }, DXGI_FORMAT_R16G16B16A16_FLOAT, // BufferDesc.Format DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED, // BufferDesc.ScanlineOrdering DXGI_MODE_SCALING_CENTERED // BufferDesc.Scaling }, { 1, // SampleDesc.Count 0 // SampleDesc.Quality }, DXGI_USAGE_RENDER_TARGET_OUTPUT, // BufferUsage 1, // BufferCount hWnd, // OutputWindow TRUE, // Windowed DXGI_SWAP_EFFECT_DISCARD, // SwapEffect DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH // Flags }; // Direct3D11 デバイス・デバイスコンテキスト・スワップチェーンを生成 ID3D11Device * pDevice = NULL; ID3D11DeviceContext * pDeviceContext = NULL; IDXGISwapChain * pSwapChain = NULL; D3D_FEATURE_LEVEL feature; hr = D3D11CreateDeviceAndSwapChain( NULL, D3D_DRIVER_TYPE_HARDWARE, NULL, 0, NULL, 0, D3D11_SDK_VERSION, &scDesc, &pSwapChain, &pDevice, &feature, &pDeviceContext ); if ( FAILED( hr ) ) { MessageBox( NULL, _T( "失敗: D3D11CreateDeviceAndSwapChain()" ), _T( "エラー" ), MB_OK | MB_ICONERROR ); return 0; } dtprintf( _T( "D3D11CreateDeviceAndSwapChain: ok (pDevice: 0x%p, pDeviceContext: 0x%p, pSwapChain: 0x%p, feature: 0x%4x)\n" ), pDevice, pDeviceContext, pSwapChain, ( int ) feature ); // バックバッファテクスチャを取得 ID3D11Texture2D * pBackBuffer = NULL; hr = pSwapChain->GetBuffer( 0, __uuidof( pBackBuffer ), reinterpret_cast< void ** >( &pBackBuffer ) ); if ( FAILED( hr ) ) { MessageBox( NULL, _T( "失敗: IDXGISwapChain::GetBuffer()" ), _T( "エラー" ), MB_OK | MB_ICONERROR ); return 0; } dtprintf( _T( "IDXGISwapChain::GetBuffer: ok (pBackBuffer: 0x%p)\n" ), pBackBuffer ); // レンダーターゲットビューを生成 ID3D11RenderTargetView * pRenderTargetView = NULL; hr = pDevice->CreateRenderTargetView( pBackBuffer, NULL, &pRenderTargetView ); if ( FAILED( hr ) ) { MessageBox( NULL, _T( "失敗: ID3D11Device::CreateRenderTargetView()" ), _T( "エラー" ), MB_OK | MB_ICONERROR ); return 0; } dtprintf( _T( "ID3D11Device::CreateRenderTargetView: ok (pRenderTargetView: 0x%p)\n" ), pRenderTargetView ); // デプス・ステンシルバッファとなるテクスチャを生成 D3D11_TEXTURE2D_DESC depthStencilBufferDesc = { 1280, // Width 720, // Height 1, // MipLevels 1, // ArraySize DXGI_FORMAT_D32_FLOAT, // Format { 1, // SampleDesc.Count 0 // SampleDesc.Quality }, D3D11_USAGE_DEFAULT, // Usage D3D11_BIND_DEPTH_STENCIL, // BindFlags 0, // CPUAccessFlags 0 // MiscFlags }; ID3D11Texture2D * pDepthStencilBuffer = NULL; hr = pDevice->CreateTexture2D( &depthStencilBufferDesc, NULL, &pDepthStencilBuffer ); if ( FAILED( hr ) ) { MessageBox( NULL, _T( "失敗: ID3D11Device::CreateTexture2D()" ), _T( "エラー" ), MB_OK | MB_ICONERROR ); return 0; } dtprintf( _T( "ID3D11Device::CreateTexture2D: ok (pDepthStencilBuffer: 0x%p)\n" ), pDepthStencilBuffer ); // デプス・ステンシルビューを生成 ID3D11DepthStencilView * pDepthStencilView = NULL; hr = pDevice->CreateDepthStencilView( pDepthStencilBuffer, NULL, &pDepthStencilView ); if ( FAILED( hr ) ) { MessageBox( NULL, _T( "失敗: ID3D11Device::CreateDepthStencilView()" ), _T( "エラー" ), MB_OK | MB_ICONERROR ); return 0; } dtprintf( _T( "ID3D11Device::CreateDepthStencilView: ok (pDepthStencilView: 0x%p)\n" ), pDepthStencilView ); // レンダーターゲットビューとデプス・ステンシルビューをバインド ID3D11RenderTargetView * pRenderTargetViews[] = { pRenderTargetView }; pDeviceContext->OMSetRenderTargets( 1, pRenderTargetViews, pDepthStencilView ); dtprintf( _T( "ID3D11DeviceContext::OMSetRenderTargets: ok\n" ) ); // バックバッファはもうここでは使わない COM_SAFE_RELEASE( pBackBuffer ); // ビューポートをバインド D3D11_VIEWPORT viewport = { 0.0f, // TopLeftX 0.0f, // TopLeftY 1280.0f, // Width 720.0f, // Height 0.0f, // MinDepth 1.0f // MaxDepth }; pDeviceContext->RSSetViewports( 1, &viewport ); dtprintf( _T( "ID3D11DeviceContext::RSSetViewports: ok\n" ) ); // 頂点データ float vertices[ 8 ][ 7 ] = { // Xaxis Yaxis Zaxis 赤 緑 青 Alpha { -0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 0.0f, 1.0f }, // 手前左上 { 0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 1.0f }, // 手前右上 { 0.5f, -0.5f, 0.5f, 0.0f, 1.0f, 0.0f, 1.0f }, // 手前右下 { -0.5f, -0.5f, 0.5f, 0.0f, 1.0f, 1.0f, 1.0f }, // 手前左下 { -0.5f, 0.5f, -0.5f, 1.0f, 0.0f, 0.0f, 1.0f }, // 奥左上 { 0.5f, 0.5f, -0.5f, 1.0f, 0.0f, 1.0f, 1.0f }, // 奥右上 { 0.5f, -0.5f, -0.5f, 1.0f, 1.0f, 0.0f, 1.0f }, // 奥右下 { -0.5f, -0.5f, -0.5f, 1.0f, 1.0f, 1.0f, 1.0f } // 奥左下 }; // 頂点バッファを生成 D3D11_BUFFER_DESC vertexBufferDesc = { sizeof( vertices ), // ByteWidth D3D11_USAGE_DEFAULT, // Usage D3D11_BIND_VERTEX_BUFFER, // BindFlags 0, // CPUAccessFlags 0, // MiscFlags 0 // StructureByteStride }; D3D11_SUBRESOURCE_DATA vertexResourceData = { vertices }; ID3D11Buffer * pVertexBuffer = NULL; hr = pDevice->CreateBuffer( &vertexBufferDesc, &vertexResourceData, &pVertexBuffer ); if ( FAILED( hr ) ) { MessageBox( NULL, _T( "失敗: ID3D11Device::CreateBuffer()" ), _T( "エラー" ), MB_OK | MB_ICONERROR ); return 0; } dtprintf( _T( "ID3D11Device::CreateBuffer: ok (pVertexBuffer: 0x%p)\n" ), pVertexBuffer ); // 頂点バッファをバインド UINT strides[] = { sizeof( float ) * 7 }; UINT offsets[] = { 0 }; pDeviceContext->IASetVertexBuffers( 0, 1, &pVertexBuffer, strides, offsets ); dtprintf( _T( "ID3D11DeviceContext::IASetVertexBuffers: ok\n" ) ); // インデックスデータ unsigned int indices[] = { 0, 1, 2, 0, 2, 3, // 手前 4, 0, 3, 4, 3, 7, // 左 1, 5, 6, 1, 6, 2, // 右 0, 4, 5, 0, 5, 1, // 上 2, 6, 7, 2, 7, 3, // 下 5, 4, 7, 5, 7, 6 }; // 裏 // インデックスバッファを生成 D3D11_BUFFER_DESC indexBufferDesc = { sizeof( indices ), // ByteWidth D3D11_USAGE_DEFAULT, // Usage D3D11_BIND_INDEX_BUFFER, // BindFlags 0, // CPUAccessFlags 0, // MiscFlags 0 // StructureByteStride }; D3D11_SUBRESOURCE_DATA indexResourceData = { indices }; ID3D11Buffer * pIndexBuffer = NULL; hr = pDevice->CreateBuffer( &indexBufferDesc, &indexResourceData, &pIndexBuffer ); if ( FAILED( hr ) ) { MessageBox( NULL, _T( "失敗: ID3D11Device::CreateBuffer()" ), _T( "エラー" ), MB_OK | MB_ICONERROR ); return 0; } dtprintf( _T( "ID3D11Device::CreateBuffer: ok (pIndexBuffer: 0x%p)\n" ), pIndexBuffer ); // インデックスバッファをバインド pDeviceContext->IASetIndexBuffer( pIndexBuffer, DXGI_FORMAT_R32_UINT, 0 ); dtprintf( _T( "ID3D11DeviceContext::IASetIndexBuffer: ok\n" ) ); // プリミティブタイプを設定 pDeviceContext->IASetPrimitiveTopology( D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST ); dtprintf( _T( "ID3D11DeviceContext::IASetPrimitiveTopology: ok\n" ) ); // 頂点シェーダ用の定数バッファを作成 D3D11_BUFFER_DESC VSConstantBufferDesc = { sizeof( D3DXMATRIX ) * 3, // ByteWidth D3D11_USAGE_DYNAMIC, // Usage D3D11_BIND_CONSTANT_BUFFER, // BindFlags D3D11_CPU_ACCESS_WRITE, // CPUAccessFlags 0, // MiscFlags 0 // StructureByteStride }; ID3D11Buffer * pVSConstantBuffer = NULL; hr = pDevice->CreateBuffer( &VSConstantBufferDesc, NULL, &pVSConstantBuffer ); if ( FAILED( hr ) ) { MessageBox( NULL, _T( "失敗: ID3D11Device::CreateBuffer()" ), _T( "エラー" ), MB_OK | MB_ICONERROR ); return 0; } dtprintf( _T( "ID3D11Device::CreateBuffer: ok (pVSConstantBuffer: 0x%p)\n" ), pVSConstantBuffer ); // 定数バッファをバインド pDeviceContext->VSSetConstantBuffers( 0, 1, &pVSConstantBuffer ); dtprintf( _T( "ID3D11DeviceContext::VSSetConstantBuffers: ok\n" ) ); // 頂点シェーダを作成 ID3D11VertexShader * pVertexShader = NULL; hr = pDevice->CreateVertexShader( g_vs_perspective, sizeof( g_vs_perspective ), NULL, &pVertexShader ); if ( FAILED( hr ) ) { MessageBox( NULL, _T( "失敗: ID3D11Device::CreateVertexShader()" ), _T( "エラー" ), MB_OK | MB_ICONERROR ); return 0; } dtprintf( _T( "ID3D11Device::CreateVertexShader: ok (pVertexShader: 0x%p)\n" ), pVertexShader ); // ピクセルシェーダを作成 ID3D11PixelShader * pPixelShader = NULL; hr = pDevice->CreatePixelShader( g_ps_constant, sizeof( g_ps_constant ), NULL, &pPixelShader ); if ( FAILED( hr ) ) { MessageBox( NULL, _T( "失敗: ID3D11Device::CreatePixelShader()" ), _T( "エラー" ), MB_OK | MB_ICONERROR ); return 0; } dtprintf( _T( "ID3D11Device::CreatePixelShader: ok (pPixelShader: 0x%p)\n" ), pPixelShader ); // シェーダをバインド pDeviceContext->VSSetShader( pVertexShader, NULL, 0 ); dtprintf( _T( "ID3D11DeviceContext::VSSetShader: ok\n" ) ); pDeviceContext->PSSetShader( pPixelShader, NULL, 0 ); dtprintf( _T( "ID3D11DeviceContext::PSSetShader: ok\n" ) ); pDeviceContext->GSSetShader( NULL, NULL, 0 ); pDeviceContext->HSSetShader( NULL, NULL, 0 ); pDeviceContext->DSSetShader( NULL, NULL, 0 ); // 入力エレメント記述子 D3D11_INPUT_ELEMENT_DESC verticesDesc[] = { { "IN_POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 }, { "IN_COLOR", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, sizeof(float)*3, D3D11_INPUT_PER_VERTEX_DATA, 0 } }; // 入力レイアウトを生成 ID3D11InputLayout * pInputLayout = NULL; hr = pDevice->CreateInputLayout( verticesDesc, 2, g_vs_perspective, sizeof( g_vs_perspective ), &pInputLayout ); if ( FAILED( hr ) ) { MessageBox( NULL, _T( "失敗: ID3D11Device::CreateInputLayout()" ), _T( "エラー" ), MB_OK | MB_ICONERROR ); return 0; } dtprintf( _T( "ID3D11Device::CreateInputLayout: ok (pInputLayout: 0x%p)\n" ), pInputLayout ); // 入力レイアウトをバインド pDeviceContext->IASetInputLayout( pInputLayout ); dtprintf( _T( "ID3D11DeviceContext::IASetInputLayout: ok\n" ) ); // ラスタライザステートを生成 D3D11_RASTERIZER_DESC rasterizerStateDesc = { D3D11_FILL_SOLID, // FillMode // D3D11_FILL_WIREFRAME, // FillMode (ワイヤーフレーム表示) D3D11_CULL_BACK, // CullMode // D3D11_CULL_NONE, // CullMode (カリングなし) FALSE, // FrontCounterClockwise 0, // DepthBias 0.0f, // DepthBiasClamp 0.0f, // SlopeScaledDepthBias TRUE, // DepthClipEnable FALSE, // ScissorEnable FALSE, // MultisampleEnable FALSE // AntialiasedLineEnable }; ID3D11RasterizerState * pRasterizerState = NULL; hr = pDevice->CreateRasterizerState( &rasterizerStateDesc, &pRasterizerState ); if ( FAILED( hr ) ) { MessageBox( NULL, _T( "失敗: ID3D11Device::CreateRasterizerState()" ), _T( "エラー" ), MB_OK | MB_ICONERROR ); return 0; } dtprintf( _T( "ID3D11Device::CreateRasterizerState: ok (pRasterizerState: 0x%p)\n" ), pRasterizerState ); // ラスタライザステートをバインド pDeviceContext->RSSetState( pRasterizerState ); dtprintf( _T( "ID3D11DeviceContext::RSSetState: ok\n" ) ); // デプス・ステンシルステートを生成 D3D11_DEPTH_STENCIL_DESC depthStencilStateDesc = { TRUE, // DepthEnable D3D11_DEPTH_WRITE_MASK_ALL, // DepthWriteMask D3D11_COMPARISON_LESS, // DepthFunc FALSE, // StencilEnable D3D11_DEFAULT_STENCIL_READ_MASK, // StencilReadMask D3D11_DEFAULT_STENCIL_WRITE_MASK, // StencilWriteMask { D3D11_STENCIL_OP_KEEP, // FrontFace.StencilFailOp D3D11_STENCIL_OP_KEEP, // FrontFace.StencilDepthFailOp D3D11_STENCIL_OP_KEEP, // FrontFace.StencilPassOp D3D11_COMPARISON_ALWAYS // FrontFace.StencilFunc }, { D3D11_STENCIL_OP_KEEP, // BackFace.StencilFailOp D3D11_STENCIL_OP_KEEP, // BackFace.StencilDepthFailOp D3D11_STENCIL_OP_KEEP, // BackFace.StencilPassOp D3D11_COMPARISON_ALWAYS // BackFace.StencilFunc } }; ID3D11DepthStencilState * pDepthStencilState = NULL; hr = pDevice->CreateDepthStencilState( &depthStencilStateDesc, &pDepthStencilState ); if ( FAILED( hr ) ) { MessageBox( NULL, _T( "失敗: ID3D11Device::CreateDepthStencilState()" ), _T( "エラー" ), MB_OK | MB_ICONERROR ); return 0; } dtprintf( _T( "ID3D11Device::CreateDepthStencilState: ok (pDepthStencilState: 0x%p)\n" ), pDepthStencilState ); // デプス・ステンシルステートをバインド pDeviceContext->OMSetDepthStencilState( pDepthStencilState, 0 ); dtprintf( _T( "ID3D11DeviceContext::OMSetDepthStencilState: ok\n" ) ); MSG msg; while ( 1 ) { // メッセージを取得 if ( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) ) { if ( msg.message == WM_QUIT ) { dtprintf( _T( "PeekMessage: WM_QUIT\n" ) ); break; } // メッセージ処理 DispatchMessage( &msg ); } else { HRESULT hr; static unsigned int count = 0; float theta = ( count++ / 200.0f ) * ( 3.141593f / 2.0f ); // World-View-Projection 行列をそれぞれ生成 D3DXMATRIX world, view, projection; D3DXMatrixIdentity( &world ); const D3DXVECTOR3 eye( 1.8f * 1.414214f * -cosf( theta ), 1.8f, 1.8f * 1.414214f * sinf( theta ) ); const D3DXVECTOR3 at( 0.0f, 0.0f, 0.0f ); const D3DXVECTOR3 up( 0.0f, 1.0f, 0.0f ); D3DXMatrixLookAtRH( &view, &eye, &at, &up ); D3DXMatrixPerspectiveFovRH( &projection, 3.141593f / 4.0f, 1280.0f / 720.0f, 1.0f, 10000.0f ); // 頂点シェーダ用定数バッファへアクセス D3D11_MAPPED_SUBRESOURCE mapped; hr = pDeviceContext->Map( pVSConstantBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mapped ); if ( SUCCEEDED( hr ) ) { D3DXMATRIX * mapped_m = static_cast< D3DXMATRIX * >( mapped.pData ); mapped_m[0] = world; mapped_m[1] = view; mapped_m[2] = projection; // 後始末 pDeviceContext->Unmap( pVSConstantBuffer, 0 ); } // レンダーターゲットビューをクリア const float clear[ 4 ] = { 0.0f, 0.0f, 0.3f, 1.0f }; // RGBA pDeviceContext->ClearRenderTargetView( pRenderTargetView, clear ); // デプス・ステンシルビューをクリア pDeviceContext->ClearDepthStencilView( pDepthStencilView, D3D11_CLEAR_DEPTH | D3D11_CLEAR_STENCIL, 1.0f, 0 ); // 描画 pDeviceContext->DrawIndexed( 36, 0, 0 ); pSwapChain->Present( 1, 0 ); // ちょっとだけ待つ Sleep( 5 ); } } // シェーダをアンバインド pDeviceContext->VSSetShader( NULL, NULL, 0 ); pDeviceContext->PSSetShader( NULL, NULL, 0 ); // デバイス・リソース解放 COM_SAFE_RELEASE( pDepthStencilState ); COM_SAFE_RELEASE( pRasterizerState ); COM_SAFE_RELEASE( pInputLayout ); COM_SAFE_RELEASE( pPixelShader ); COM_SAFE_RELEASE( pVertexShader ); COM_SAFE_RELEASE( pVSConstantBuffer ); COM_SAFE_RELEASE( pIndexBuffer ); COM_SAFE_RELEASE( pVertexBuffer ); COM_SAFE_RELEASE( pDepthStencilView ); COM_SAFE_RELEASE( pDepthStencilBuffer ); COM_SAFE_RELEASE( pRenderTargetView ); COM_SAFE_RELEASE( pSwapChain ); COM_SAFE_RELEASE( pDeviceContext ); COM_SAFE_RELEASE( pDevice ); return msg.wParam; }
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(); }
/** Binds a pipeline-state */ void D3D11GraphicsEngineQueued::BindPipelineState(const PipelineState* state) { D3D11PipelineState* s = (D3D11PipelineState*)state; D3D11PipelineState* b = (D3D11PipelineState*)BoundPipelineStateByThread[GetCurrentThreadId()]; ID3D11DeviceContext* context = GetDeferredContextByThread(); if(!b) b = (D3D11PipelineState*)&DefaultPipelineState; // Bind state if(b->BlendState != s->BlendState) SC_DBG(context->OMSetBlendState(s->BlendState, (float *)&D3DXVECTOR4(0, 0, 0, 0), 0xFFFFFFFF), GothicRendererInfo::SC_BS); if(b->SamplerState != s->SamplerState) SC_DBG(context->PSSetSamplers(0, 1, &s->SamplerState), GothicRendererInfo::SC_SMPL); if(b->DepthStencilState != s->DepthStencilState) SC_DBG(context->OMSetDepthStencilState(s->DepthStencilState, 0), GothicRendererInfo::SC_DSS); if(b->RasterizerState != s->RasterizerState) SC_DBG(context->RSSetState(s->RasterizerState), GothicRendererInfo::SC_RS); // Bind constantbuffers (They are likely to change for every object) if(!s->ConstantBuffersVS.empty() && s->ConstantBuffersVS != b->ConstantBuffersVS)SC_DBG(context->VSSetConstantBuffers(0, s->ConstantBuffersVS.size(), &s->ConstantBuffersVS[0]),GothicRendererInfo::SC_CB); if(!s->ConstantBuffersPS.empty() && s->ConstantBuffersPS != b->ConstantBuffersPS)SC_DBG(context->PSSetConstantBuffers(0, s->ConstantBuffersPS.size(), &s->ConstantBuffersPS[0]),GothicRendererInfo::SC_CB); if(!s->ConstantBuffersHDS.empty() && s->ConstantBuffersHDS != b->ConstantBuffersHDS)SC_DBG(context->HSSetConstantBuffers(0, s->ConstantBuffersHDS.size(), &s->ConstantBuffersHDS[0]),GothicRendererInfo::SC_CB); if(!s->ConstantBuffersHDS.empty() && s->ConstantBuffersHDS != b->ConstantBuffersHDS)SC_DBG(context->DSSetConstantBuffers(0, s->ConstantBuffersHDS.size(), &s->ConstantBuffersHDS[0]),GothicRendererInfo::SC_CB); if(!s->ConstantBuffersGS.empty() && s->ConstantBuffersGS != b->ConstantBuffersGS)SC_DBG(context->GSSetConstantBuffers(0, s->ConstantBuffersGS.size(), &s->ConstantBuffersGS[0]),GothicRendererInfo::SC_CB); // Vertexbuffers UINT off[] = {0,0}; if(memcmp(s->BaseState.VertexBuffers, b->BaseState.VertexBuffers, sizeof(b->BaseState.VertexBuffers)) != 0) SC_DBG(context->IASetVertexBuffers(0, s->VertexBuffers.size(), &s->VertexBuffers[0], s->BaseState.VertexStride, off), GothicRendererInfo::SC_VB); if(!s->StructuredBuffersVS.empty() && memcmp(s->BaseState.StructuredBuffersVS, b->BaseState.StructuredBuffersVS, sizeof(b->BaseState.StructuredBuffersVS)) != 0) SC_DBG(context->VSSetShaderResources(0, 1, &s->StructuredBuffersVS[0]), GothicRendererInfo::SC_VB); if(s->IndexBuffer != b->IndexBuffer) SC_DBG(context->IASetIndexBuffer(s->IndexBuffer, s->BaseState.IndexStride == 4 ? DXGI_FORMAT_R32_UINT : DXGI_FORMAT_R16_UINT, 0), GothicRendererInfo::SC_IB); // Shaders if(s->VertexShader != b->VertexShader) SC_DBG(context->VSSetShader(s->VertexShader, NULL, NULL), GothicRendererInfo::SC_VS); if(s->InputLayout != b->InputLayout) SC_DBG(context->IASetInputLayout(s->InputLayout), GothicRendererInfo::SC_IL); if(s->PixelShader != b->PixelShader) SC_DBG(context->PSSetShader(s->PixelShader, NULL, NULL), GothicRendererInfo::SC_PS); if(s->HullShader != b->HullShader) SC_DBG(context->HSSetShader(s->HullShader, NULL, NULL), GothicRendererInfo::SC_HS); if(s->DomainShader != b->DomainShader) SC_DBG(context->DSSetShader(s->DomainShader, NULL, NULL), GothicRendererInfo::SC_DS); if(s->GeometryShader != b->GeometryShader) SC_DBG(context->GSSetShader(s->GeometryShader, NULL, NULL), GothicRendererInfo::SC_GS); // Rendertargets if(memcmp(s->RenderTargetViews, b->RenderTargetViews, sizeof(void*) * s->NumRenderTargetViews) != 0 || s->DepthStencilView != b->DepthStencilView) SC_DBG(context->OMSetRenderTargets(s->NumRenderTargetViews, s->RenderTargetViews, s->DepthStencilView), GothicRendererInfo::SC_RTVDSV); // Textures if(memcmp(s->Textures, b->Textures, sizeof(void*) * s->BaseState.NumTextures) != 0) SC_DBG(context->PSSetShaderResources(0, s->BaseState.NumTextures, s->Textures), GothicRendererInfo::SC_TX); // Primitive topology //Context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST); // Replace old state // FIXME: Might not threadsave BoundPipelineStateByThread[GetCurrentThreadId()] = s; }
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); }
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(); }
void DrawCoordinate() { struct CB { XMMATRIX mWorldViewProj; }; ID3D11Device* pDevice = WE::D3DDevice(); ID3D11DeviceContext* pImmediateContext = WE::ImmediateContext(); static ID3D11VertexShader* g_pVertexShader = NULL; static ID3D11PixelShader* g_pPixelShader = NULL; static ID3D11Buffer* g_pCB = NULL; static const char* g_strBuffer = " cbuffer cbPerObject : register( b0 ) \r\n" " { \r\n" " matrix g_mWorldViewProjection : packoffset( c0 ); \r\n" " }; \r\n" " \r\n" " struct VS_In \r\n" " { \r\n" " uint id : SV_VERTEXID; \r\n" " }; \r\n" " \r\n" " struct VS_Out \r\n" " { \r\n" " float4 pos : SV_POSITION; \r\n" " float4 color : COLOR; \r\n" " }; \r\n" " \r\n" " \r\n" " cbuffer cbImmutable \r\n" " { \r\n" " static float4 g_positions[6] = \r\n" " { \r\n" " float4( 0.0f, 0.0f, 0.0f, 1.0f ), \r\n" " float4( 1.0f, 0.0f, 0.0f, 1.0f ), \r\n" " float4( 0.0f, 0.0f, 0.0f, 1.0f ), \r\n" " float4( 0.0f, 1.0f, 0.0f, 1.0f ), \r\n" " float4( 0.0f, 0.0f, 0.0f, 1.0f ), \r\n" " float4( 0.0f, 0.0f, 1.0f, 1.0f ), \r\n" " }; \r\n" " \r\n" " static float4 g_colors[6] = \r\n" " { \r\n" " float4( 1.0f, 0.0f, 0.0f, 1.0f ), \r\n" " float4( 1.0f, 0.0f, 0.0f, 1.0f ), \r\n" " float4( 0.0f, 1.0f, 0.0f, 1.0f ), \r\n" " float4( 0.0f, 1.0f, 0.0f, 1.0f ), \r\n" " float4( 0.0f, 0.0f, 1.0f, 1.0f ), \r\n" " float4( 0.0f, 0.0f, 1.0f, 1.0f ), \r\n" " }; \r\n" " }; \r\n" " VS_Out VSMain(VS_In input) \r\n" " { \r\n" " VS_Out output; \r\n" " \r\n" " output.pos = mul( g_positions[input.id] * 5, g_mWorldViewProjection ); \r\n" " output.color = g_colors[input.id]; \r\n" " return output; \r\n" " } \r\n" " \r\n" " float4 PSMain(VS_Out input) : SV_Target \r\n" " { \r\n" " return input.color; \r\n" " return float4( 1.0f, 1.0f, 0.0f, 1.0f ); \r\n" " } \r\n" ""; HRESULT hr; if ( g_pVertexShader == NULL ) { // Create shaders ID3DBlob* pVSBlob = NULL; ID3DBlob* pPSBlob = NULL; UINT dwBufferSize = ( UINT )strlen( g_strBuffer ) + 1; V( WE::CompileShaderFromMemory( g_strBuffer, dwBufferSize, NULL, "VSMain", "vs_5_0", &pVSBlob ) ); V( WE::CompileShaderFromMemory( g_strBuffer, dwBufferSize, NULL, "PSMain", "ps_5_0", &pPSBlob ) ); V( pDevice->CreateVertexShader( pVSBlob->GetBufferPointer(), pVSBlob->GetBufferSize(), NULL, &g_pVertexShader ) ); V( pDevice->CreatePixelShader( pPSBlob->GetBufferPointer(), pPSBlob->GetBufferSize(), NULL, &g_pPixelShader ) ); SAFE_RELEASE( pVSBlob ); SAFE_RELEASE( pPSBlob ); // Create the constant buffers D3D11_BUFFER_DESC Desc; Desc.Usage = D3D11_USAGE_DYNAMIC; Desc.BindFlags = D3D11_BIND_CONSTANT_BUFFER; Desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; Desc.MiscFlags = 0; Desc.ByteWidth = sizeof( CB ); V( pDevice->CreateBuffer( &Desc, NULL, &g_pCB ) ); } D3D11_MAPPED_SUBRESOURCE MappedResource; V(pImmediateContext->Map( g_pCB, 0, D3D11_MAP_WRITE_DISCARD, 0, &MappedResource ) ); CB* pPerFrame = ( CB* )MappedResource.pData; pPerFrame->mWorldViewProj = XMMatrixTranspose( WE::Camera()->GetViewProjMtx() ); pImmediateContext->Unmap( g_pCB, 0 ); pImmediateContext->VSSetConstantBuffers( 0, 1, &g_pCB ); pImmediateContext->OMSetDepthStencilState( NULL, 0 ); float vBlendFactor[4] = { 0.0f, 0.0f, 0.0f, 0.0f }; pImmediateContext->OMSetBlendState( NULL, vBlendFactor, 0xFFFFFFFF ); pImmediateContext->RSSetState( NULL ); pImmediateContext->IASetPrimitiveTopology( D3D11_PRIMITIVE_TOPOLOGY_LINELIST ); pImmediateContext->VSSetShader( g_pVertexShader, NULL, 0 ); pImmediateContext->PSSetShader( g_pPixelShader, NULL, 0 ); pImmediateContext->GSSetShader( NULL, NULL, 0 ); // Draw pImmediateContext->Draw( 6, 0 ); }