I'm using point sprites in a 2D engine, based on some tutorials.
It works quite well, but point sprites are not centered on (X, Y), instead of that, (X, Y) is the lower-right corner.
The code is something like:
result = lpDirect3DDevice9->SetFVF( D3DFVF_PARTICLEVERTEX );
result = lpDirect3DDevice9->SetRenderState(D3DRS_POINTSPRITEENABLE, TRUE);
result = lpDirect3DDevice9->SetRenderState(D3DRS_POINTSCALEENABLE, FALSE);
result = lpDirect3DDevice9->SetRenderState( D3DRS_ALPHABLENDENABLE, TRUE );
result = lpDirect3DDevice9->SetRenderState( D3DRS_DESTBLEND, D3DBLEND_ONE );
...
result = lpDirect3DDevice9->SetStreamSource( 0, vertex, 0, sizeof(PARTICLEVERTEX));
result = lpDirect3DDevice9->SetTexture( 0, texture );
result = lpDirect3DDevice9->SetRenderState(D3DRS_POINTSIZE, FtoDW(size));
result = lpDirect3DDevice9->DrawPrimitive( D3DPT_POINTLIST, offset, nbParticle );
Is there some render state to set to center the point sprite I've read in the SDK doc that it should be centered on the vertex without doing anything special.
Another problem with the same point sprites is that I can't set their size correctly, it seems to be in world unit instead of screen units whatever is D3DRS_POINTSCALEENABLE.
I've tried the reference rasterizer, and the point sprites are still displayed at the bad place.
I've also tried software and hardware vertex processing and it is exactly the same result.
If I try to render some triangles at the same position, I see the triangle at the correct place, even if I draw the triangle just after the point sprite, without setting any matrix.
Here is how I define the world:
D3DXMATRIX Ortho2D;
D3DXMATRIX Identity;
D3DXMatrixOrthoLH(&Ortho2D, (FLOAT)screenWidth, (FLOAT)screenWidth, 0.0f, 1.0f);
D3DXMatrixIdentity(&Identity);
lpDirect3DDevice9->SetTransform(D3DTS_PROJECTION, &Ortho2D);
lpDirect3DDevice9->SetTransform(D3DTS_WORLD, &Identity);
lpDirect3DDevice9->SetTransform(D3DTS_VIEW, &Identity);
And this is how I define the vertices:
#define D3DFVF_PARTICLEVERTEX (D3DFVF_XYZRHW|D3DFVF_DIFFUSE)
struct PARTICLEVERTEX
{
FLOAT x, y, z, rhw; // The transformed position for the vertex
DWORD color; // The vertex color
};
...
lpDirect3DDevice9->CreateVertexBuffer(
nbParticles*sizeof(PARTICLEVERTEX),
D3DUSAGE_DYNAMIC|D3DUSAGE_POINTS, D3DFVF_PARTICLEVERTEX,
D3DPOOL_DEFAULT, &vertex, NULL )
Finally, I have also tried to set:
lpDirect3DDevice9->SetRenderState(D3DRS_POINTSPRITEENABLE, FALSE);
and
lpDirect3DDevice9->SetRenderState( D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA );
lpDirect3DDevice9->SetRenderState( D3DRS_SRCBLEND, D3DBLEND_SRCALPHA );
just to see, and in that case I got a full black rectangle CENTERED, so there is definitely something wrong with the point sprites ...
I don't know if it can be useful: I got a Radeon 9700 pro (128 Mo) with the latest drivers (or nearly).
Thanks,
K.

Point Sprite are displayed at the correct place
Peter Bromberg
This may not be what you want to hear, but my recommendation is to drop Point Sprites. Support for them was always kind of iffy and in a 2D game it is incredibly unlikely that processing a few more vertices is going to have any significant impact on your performance. Fill rate is far more likely to be a limiting factor. Just use textured quads or D3DXSprite.
I should also mention that if you're using transformed coordinates your Orthographic projection is ignored. It will use real screen coords, which could be slightly different.
Leonid Fro
Thanks Ken.
In fact, that's what I wanted to hear, because I'm not really at ease with point sprites and I don't know how it could work on different hardware ... so that's it I'll use ID3DXSPRITE.
K.