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 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(); }
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(); }
void ParticleSystem::Draw(const Camera& cam) { Matrix44f VP = cam.getProjectionMatrix() * cam.getModelViewMatrix(); ID3D11DeviceContext* dc = getImmediateContext(); // // Set constants. // mFX.uniform("gViewProj", VP); mFX.uniform("gGameTime", mGameTime); mFX.uniform("gTimeStep", mTimeStep); mFX.uniform("gEyePosW", mEyePosW); mFX.uniform("gEmitPosW", mEmitPosW); mFX.uniform("gEmitDirW", mEmitDirW); mFX.uniform("gTexture", mTexure); mFX.uniform("gRandomTex", mRandomTex); // // Set IA stage. // dc->IASetInputLayout(mInputLayout); dc->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_POINTLIST); UINT stride = sizeof(Vertex); UINT offset = 0; // On the first pass, use the initialization VB. Otherwise, use // the VB that contains the current particle list. if( mFirstRun ) dc->IASetVertexBuffers(0, 1, &mInitVB, &stride, &offset); else dc->IASetVertexBuffers(0, 1, &mDrawVB, &stride, &offset); // // Draw the current particle list using stream-out only to update them. // The updated vertices are streamed-out to the target VB. // dc->SOSetTargets(1, &mStreamOutVB, &offset); mFX.useTechnique("StreamOutTech"); if (mFirstRun) { mFX.draw(1); mFirstRun = false; } else mFX.drawAuto(); // done streaming-out--unbind the vertex buffer ID3D11Buffer* bufferArray[1] = {0}; dc->SOSetTargets(1, bufferArray, &offset); // ping-pong the vertex buffers std::swap(mDrawVB, mStreamOutVB); // // Draw the updated particle system we just streamed-out. // dc->IASetVertexBuffers(0, 1, &mDrawVB, &stride, &offset); mFX.useTechnique("DrawTech"); mFX.drawAuto(); }