2016-06-12 1 views
0

J'ai récemment réalisé un système de rendu volumétrique dans l'espoir de les utiliser pour les effets de particules. En essayant un émetteur de poussière, j'ai remarqué que le positionnement des particules était complètement faux. Je génère des nombres aléatoires ensemencés que je nourris dans chaque particule individuelle afin de définir la position. Quand je commence le débogage comme d'habitude, les particules apparaissent seulement les unes sur les autres dans deux positions. Lors de l'application d'un point de rupture et en passant par la boucle une particule à la fois et ensuite continuer, chaque particule était dans sa position aléatoire assignée. En plus de cela, tout en testant le problème sur un grand pool de particules, j'ai utilisé un hitcount pour casser la boucle sur un certain nombre, et j'ai trouvé que quand cela se produit, il les initialise seulement aux deux positions susmentionnées. Qu'est-ce qui peut causer cela?Les valeurs constructeurs ne sont pas appliquées au démarrage

VolumetricDust::VolumetricDust(string type, Transform* transform, ID3D11Device* pDevice, int width, int height, int depth, bool instanceFlag, int instanceCount) 
{ 

    for (int i = 0; i < POOL_SIZE; i++) 
{ 
    // PROBLEM LOOP 
    particles_[i] = new ParticleVolume("Resources\\nucleon.raw", transform, width, height, depth, instanceFlag, instanceCount); 
    particles_[i]->Initialise(pDevice); 

    srand((unsigned int)time(NULL)); 
    int test = (rand() % 100 + 1); 
    int test1 = rand() % 30 + 1; 
    int test2 = rand() % 50 + 1; 

    particles_[i]->SetVelocity(XMFLOAT3(0.0f, (float)test, 0.0f)); 
    particles_[i]->GetTransform()->SetPosition((float)test, (float)test1, (float)test2); 


    } 

posReset = transform; 
_transform = transform; 

mWidth = width; 
mHeight = height; 
mDepth = depth; 

isInstance = instanceFlag; 
instanceNum = instanceCount; 

_currentTime = 0.0f; 
_spawnTime = 5.0f; 
_newTime = 0.1f; 
_dustTime = 0.0f; 
particleTime = 5.0f; 
_type = type; 
_pd3dDevice = pDevice; 
} 

void VolumetricDust::SpawnEmitter() 
{ 

for (int i = 0; i < POOL_SIZE; i++) 
{ 
    if (!particles_[i]->GetParticleOn()) 
    { 

     particles_[i]->SetParticleOn(true); 
     break; 
    } 

} 

} 

void VolumetricDust::Update(float dt, Camera* cam) 
{ 
_transform->Update(); 
_currentTime += dt; 
_dustTime += dt; 


for (int i = 0; i < POOL_SIZE; i++) 
{ 
    SpawnEmitter(); 

    if (particles_[i]->GetParticleOn()) 
    { 

     //posReset->SetPosition(XMFLOAT3(0.0f, 0.0f, 0.0f)); 

     particles_[i]->Update(dt, cam, posReset->GetPosition()); 
    } 

    if (_transform) 
    { 
     _transform->Update(); 
    } 

} 



} 

void VolumetricDust::Draw(ID3D11DeviceContext * _pImmediateContext, ConstantBuffer3D & cb, ID3D11Buffer* _pConstantBuffer) 
{ 
for (int i = 0; i < POOL_SIZE; i++) 
{ 
    if (particles_[i]->GetParticleOn()) 
    { 
     particles_[i]->Draw(_pImmediateContext, cb, _pConstantBuffer); 
    } 

} 

} 

Répondre

4

Vous devez appeler srand une seule fois. Lorsque vous l'appelez dans une boucle comme celle-ci, les chances sont très élevées que vous obtenez la même valeur de temps à chaque tour. Cela réinitialise les nombres aléatoires, et vous obtiendrez le même résultat pour la plupart des points, sinon tous. L'arrêt dans le débogueur laissera le temps réel changer entre les appels à time, et vous obtenez des valeurs aléatoires séparées parce que la graine sera maintenant différente.

+0

Merci beaucoup! Je n'ai commencé à utiliser srand que récemment, et je n'étais pas au courant de ça! – MrPurple

+2

Vous devriez envisager d'utiliser [] (http://fr.cppreference.com/w/cpp/numeric/random) au lieu des anciennes fonctions '' rand''/'' srand'' –