0

I got point sprites working almost immediately, but I'm only stuck on one thing, they are rendered as probably 2x2 pixel sprites, which is not really very easy to see, especially if there's other motion. Now, I've tried tweaking all the variables, here's the code that probably works best:

void renderParticles()
{
    for(int i = 0; i < particleCount; i ++)
    {
        particlePoints[i] += particleSpeeds[i];
    }

void* data;
pParticleBuffer->Lock(0, particleCount*sizeof(PARTICLE_VERTEX), &data, NULL);
memcpy(data, particlePoints, sizeof(particlePoints));
pParticleBuffer->Unlock();

pd3dDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
pd3dDevice->SetRenderState(D3DRS_ZWRITEENABLE, TRUE);
pd3dDevice->SetRenderState(D3DRS_POINTSPRITEENABLE, TRUE);
pd3dDevice->SetRenderState(D3DRS_POINTSCALEENABLE, TRUE);
pd3dDevice->SetRenderState(D3DRS_POINTSIZE, (DWORD)1.0f);
//pd3dDevice->SetRenderState(D3DRS_POINTSIZE_MAX, (DWORD)9999.0f);
//pd3dDevice->SetRenderState(D3DRS_POINTSIZE_MIN, (DWORD)0.0f);
pd3dDevice->SetRenderState(D3DRS_POINTSCALE_A, (DWORD)0.0f);
pd3dDevice->SetRenderState(D3DRS_POINTSCALE_B, (DWORD)0.0f);
pd3dDevice->SetRenderState(D3DRS_POINTSCALE_C, (DWORD)1.0f);

pd3dDevice->SetStreamSource(0, pParticleBuffer, 0, sizeof(D3DXVECTOR3));
pd3dDevice->DrawPrimitive(D3DPT_POINTLIST, 0, particleCount);

pd3dDevice->SetRenderState(D3DRS_POINTSPRITEENABLE, FALSE);
pd3dDevice->SetRenderState(D3DRS_POINTSCALEENABLE, FALSE);

}

Ok, so when I change POINTSCALE_A and POINTSCALE_B, nothing really changes much, same for C. POINTSIZE also makes no difference. When I try to assign something to POINTSIZE_MAX and _MIN, no matter what I assign, it always stops the rendering of the sprites. I also tried setting POINTSIZE with POINTSCALEENABLE set to false, no luck there either.

This looks like something not many people who looked around found an answer to. An explanation of the mechanism exists on MSDN, while, yes, I did check stackoverflow and found a similar question with no answer. Another source only suggested seting the max and min variables, which as I said, are pretty much making my particles disappear.

ParticlePoints and particleSpeeds are D3DXVector3 arrays, and I get what I expect from them. A book I follow suggested I define a custom vertex with XYZ and diffuse but I see no reason for this to be honest, it just adds a lot more to a long list of declarations.

Any help is welcome, thanks in advance.

Edit: Further tweaking showed than when any of the scale values are above 0.99999997f (at least between that and 0.99999998f I see the effect), I get the tiny version, if I put them there or lower I pretty much get the size of the texture - though that is still not really that good as it may be large, and it pretty much fails the task of being controllable.

Community
  • 1
  • 1
user3079666
  • 1,159
  • 10
  • 23
  • You've set the stream source with a size of a vector, but actually your vertexbuffer is locked with `particleCount*sizeof(PARTICLE_VERTEX)`, a bit inconsistent, but shouldn't the problem here. How did you created the vertexbuffer, with a FVF or dynamic sized? Moreover you haven't set a FVF or vertex declaration for rendering or did you set it elsewhere? – Gnietschow Jul 03 '15 at 09:07
  • One more problem that I've seen is you float to dword cast. The official documentation suggests the following conversion `*((DWORD*)&Variable` (https://msdn.microsoft.com/en-us/library/windows/desktop/bb172599%28v=vs.85%29.aspx) to be put into `SetRenderState`. I'm not very familiar with C++, but I would assume that this makes a difference, because your cast sets a real dword, but the API expects a float in the dwords memory space. – Gnietschow Jul 03 '15 at 09:17
  • @Gnietschow, I have set the FVF elsewhere, the buffer is fixed size and larger than will be used. You were right about the way I pass the float, that was the problem from the start, turns out the book I was following had it as a macro defined elsewhere and I didn't realize it's importance, thank you. You may post it as an answer so I can accept it and close this thread – user3079666 Jul 03 '15 at 10:04

1 Answers1

1

Glad to help :) My comment as an answer:

One more problem that I've seen is you float to dword cast. The official documentation suggests the following conversion *((DWORD*)&Variable (doc) to be put into SetRenderState. I'm not very familiar with C++, but I would assume that this makes a difference, because your cast sets a real dword, but the API expects a float in the dwords memory space.

Gnietschow
  • 3,070
  • 1
  • 18
  • 28