HRESULT ParticleSystem::CreateRndTex(int size) { HRESULT hr = S_OK; D3DXVECTOR4* randomValues = new D3DXVECTOR4[size]; for(int i = 0; i < size; i++) { randomValues[i].x = RndFloat(-1.0f, 1.0f); randomValues[i].y = RndFloat(-1.0f, 1.0f); randomValues[i].z = RndFloat(-1.0f, 1.0f); randomValues[i].w = RndFloat(-1.0f, 1.0f); } D3D11_SUBRESOURCE_DATA subresData; subresData.pSysMem = randomValues; subresData.SysMemPitch = sizeof(D3DXVECTOR4) * size; subresData.SysMemSlicePitch = sizeof(D3DXVECTOR4) * size; D3D11_TEXTURE1D_DESC texDesc; texDesc.Width = size; texDesc.MipLevels = 1; texDesc.Format = DXGI_FORMAT_R32G32B32A32_FLOAT; texDesc.Usage = D3D11_USAGE_IMMUTABLE; texDesc.BindFlags = D3D11_BIND_SHADER_RESOURCE; texDesc.CPUAccessFlags = 0; texDesc.MiscFlags = 0; texDesc.ArraySize = 1; ID3D11Texture1D* rndTex = NULL; hr = this->gDevice->CreateTexture1D(&texDesc, &subresData, &rndTex); if(FAILED(hr)) { MessageBox(0, "Failed to create random texture", "CreateTexture1D", MB_ICONERROR); } D3D11_SHADER_RESOURCE_VIEW_DESC viewDesc; viewDesc.Format = texDesc.Format; viewDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE1D; viewDesc.Texture1D.MipLevels = texDesc.MipLevels; viewDesc.Texture1D.MostDetailedMip = 0; hr = this->gDevice->CreateShaderResourceView(rndTex, &viewDesc, &this->mRndTexSRV); if(FAILED(hr)) { MessageBox(0, "Failed to create shader resource view", "CreateShaderResourceView", MB_ICONERROR); } rndTex->Release(); delete [] randomValues; return hr; }
void LevelDirector::Update( float dt, IGameContext & context ) { // Debug code to see current spawn parameters { //GetRender().DrawText( 0, 50, Color(255,255,255), 25, "%i% (%i/%i ~ %f)", m_sinkPercent, m_currentSinkPixels, m_initialSinkPixels, m_currentSinkPixels/(float)m_initialSinkPixels ); /*int totalObjects = 0; for ( SpawnedVector::iterator iter = m_spawns.begin(); iter != m_spawns.end(); ++iter ) { const GameObject *pObj = context.GetOjectsStorage().GetGameObject( iter->m_id ); if ( pObj ) ++totalObjects; } IRender & render = GetRender(); render.DrawText( 0, 50, Color(255,255,255), 10, "Spawn timeout: %f", m_spawnTimeout ); render.DrawText( 0, 60, Color(255,255,255), 10, "Objects: %i/%i", totalObjects, m_maxObjects ); float totalProb = 0; for ( AIProtoVector::iterator iter = m_protos.begin(); iter != m_protos.end(); ++iter ) { totalProb += iter->m_spawnProb; } for ( AIProtoVector::iterator iter = m_protos.begin(); iter != m_protos.end(); ++iter ) { SAIProto & p = *iter; render.DrawText( 0, 70 + (iter-m_protos.begin())*10, Color(255,255,255), 10, "%10.10s: %3.3f %3.3f", p.m_objectProto.c_str(), iter->m_spawnProb, iter->m_spawnProb / totalProb ); }*/ } // Creating target objects if ( !m_targetObjectID.IsValid() ) { if ( !m_createTargetRequestID.IsValid() ) { SCreateObjectRequest::SData data; data.x = m_targetObjectX; data.y = m_targetObjectY; m_createTargetRequestID = context.CreateGameObject( m_targetObjectProto, data ); } else { m_targetObjectID = context.GetCreateRequestResult( m_createTargetRequestID ); assert( m_targetObjectID.IsValid() ); m_createTargetRequestID.Invalidate(); m_initialSinkPixels = 0; const PhysicComponent *pPhys = context.GetOjectsStorage().GetPhysicComponent( context.GetOjectsStorage().GetGameObject( m_targetObjectID )->GetPhysicComponent() ); if ( pPhys ) { for ( int x = 0; x < pPhys->m_collisionMask.GetWidth(); ++x ) { if ( pPhys->m_collisionMask.Get( x, m_sinkLineY ) ) ++m_initialSinkPixels; } } m_currentSinkPixels = m_initialSinkPixels; } } SpawnRequestRemover remover( this, context ); SpawnRequests::iterator newEnd = std::remove_if( m_requests.begin(), m_requests.end(), remover ); m_requests.erase( newEnd, m_requests.end() ); // Process spawn cooldowns for ( AIProtoVector::iterator iter = m_protos.begin(); iter != m_protos.end(); ++iter ) { if ( iter->m_spawnProb < 1.0f ) iter->m_spawnProb += iter->m_cooldownPerSecond * dt; if ( iter->m_spawnProb > 1.0f ) iter->m_spawnProb = 1.0f; } // Process global spawn timeout m_spawnTimeout -= dt; if ( m_spawnTimeout > 0 ) return; // Count objects by type for ( CountMap::iterator iter = m_objectsCounts.begin(); iter != m_objectsCounts.end(); ++iter ) iter->second = 0; const ObjectsStorage & storage = context.GetOjectsStorage(); int totalObjects = 0; for ( int i = 0; i < (int)m_spawns.size(); ++i ) { const SSpawnedObject & spawn = m_spawns[ i ]; const GameObject *pObj = storage.GetGameObject( spawn.m_id ); if ( pObj ) { ++m_objectsCounts[ spawn.m_proto ]; ++totalObjects; } else { m_spawns.erase( m_spawns.begin() + i ); --i; } } if ( totalObjects >= m_maxObjects ) return; // Calculate total spawn probability for all objects float totalProb = 0.0f; for ( AIProtoVector::iterator iter = m_protos.begin(); iter != m_protos.end(); ++iter ) { totalProb += iter->m_spawnProb; } if ( totalProb <= 0.0001f ) return; // Choose an object to spawn based on relative weight float prob1 = 0; float rnd1 = RndFloat( 0, 1.0f ); for ( AIProtoVector::iterator iter = m_protos.begin(); iter != m_protos.end(); ++iter ) { prob1 += iter->m_spawnProb / totalProb; if ( rnd1 < prob1 ) { SAIProto & p = *iter; const int intervalIndex = RndInt( 0, (int)p.m_intervals.size() - 1 ); const SAIInterval & in = p.m_intervals[ intervalIndex ]; if ( in.m_schemesWeight <= 0 ) continue; SCreateObjectRequest::SData data; int dx = ( in.x2 <= in.x1 ) ? 0 : ( RndInt( 0, in.x2 - in.x1 ) ); int dy = ( in.y2 <= in.y1 ) ? 0 : ( RndInt( 0, in.y2 - in.y1 ) ); data.x = in.x1 + dx; data.y = in.y1 + dy; data.dir = in.dir; int prob = 0; int rnd = RndInt( 0, in.m_schemesWeight - 1 ); for ( SAIInterval::SchemeVector::const_iterator sIter = in.m_schemes.begin(); sIter != in.m_schemes.end(); ++sIter ) { prob += sIter->m_weight; if ( rnd < prob ) { data.ai = sIter->m_aiName; break; } } m_requests.push_back( SSpawnRequest( context.CreateGameObject( p.m_objectProto, data ), iter - m_protos.begin() ) ); p.m_spawnProb = 0; const float fillPercent = totalObjects / (float)m_maxObjects; const int minSpawnTimeout = 100 + fillPercent * 500; const int maxSpawnTimeout = 200 + fillPercent * 1000; m_spawnTimeout = RndInt( minSpawnTimeout, maxSpawnTimeout ) / 1000.0f; break; } } }