Sign in to follow this  
Kiristu

Point Sprites problems

Recommended Posts

Kiristu    135
Hi, 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:
[SOURCE]

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 );

[/SOURCE]
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 don't know if it can be useful: I got a Radeon 9700 pro (128 Mo) with the latest drivers (or nearly). Thanks, K.

Share this post


Link to post
Share on other sites
Kiristu    135
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.

Is there a way to do intentionally what I have ? (X, Y as the bottom-right of the particle). Maybe I have set elsewhere a render state that causes that behaviour ?

Share this post


Link to post
Share on other sites
Evil Steve    2017
Do any of your matrices contain a translation? What happens if you render a small triangle or line at the same poition as the sprite? If the triangle ends up in the bottom right, it's your transform matrices, otherwise it's a point sprite setting.

Share this post


Link to post
Share on other sites
Kiristu    135
Yes, I got several translations matrices to draw sprites via D3DXSPRITE interface.
But I don't understand how they could impact the point sprites, all of them are drawn in the same way (X, Y = bottom-right) whatever their sizes or positions are. I apply the matrices with D3DXSPRITE->SetTransform() method, and it should not modify the drawprimitive coordinates (?).

However, I have set 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);




Do I forgot something ?

If I draw a triangle "starting" anywhere in the screen and "finishing" at (X, Y), the end is on the bottom-right of the point sprite (so I believe the point sprite is not at the correct position but the triangle is !).

In fact, that is exactly my problem: I would want to draw a triangle from somewhere in the screen to the center of the point sprite. I can compute this location with the bottom-right and the size of the point sprite, but since point sprites are supposed to be drawn from their center, I don't how this will work on other hardwares !

Share this post


Link to post
Share on other sites
Kiristu    135
I've heard of a problem with point sprites and ATI drivers.

Could it be linked ?
Is there any work around to be sure it will work on different hardware/drivers ?

Should I use ID3DXSPRITE to display each particle ? (slower but should work everywhere) ?

Thanks,
K.

Share this post


Link to post
Share on other sites
Evil Steve    2017
If you get the same problem on the reference rasterizer, then it's not a driver problem.

Quote:
If I draw a triangle "starting" anywhere in the screen and "finishing" at (X, Y), the end is on the bottom-right of the point sprite (so I believe the point sprite is not at the correct position but the triangle is !).
If the triangle ends at (X, Y), and that results in it ending at the bottom right of the point sprite, then yeah, it's a problem with the sprite itself, not a transform. If however, the triangle ends in the center of the sprite, it's a transform problem.

All I can suggest is that you should perhaps specify a view matrix, but I don't really know if that'd help.

What exactly are you trying to do? Is this for rendering sprites, or particles, or something else entirely?

Share this post


Link to post
Share on other sites
jollyjeffers    1570
There are a couple of other render states for point sprites. It's a long-shot, but maybe they've been corrupted, or their default values conflict with something else...

D3DRS_POINTSIZE
D3DRS_POINTSIZE_MIN
D3DRS_POINTSPRITEENABLE
D3DRS_POINTSCALEENABLE
D3DRS_POINTSCALE_A
D3DRS_POINTSCALE_B
D3DRS_POINTSCALE_C

D3DRS_POINTSIZE_MAX


Two things in particular:

D3DCAPS9::MaxPointSize must be greater than 1.0 if the device allows you to modify the size.

The size/scale render states determine the size of the sprite (see docs for equation), this in turn defines how the 4 vertices are offset from the input. If the previous render states are broken you could be getting odd values and thus later calculations are being thrown out...

Also, have you checked the debug output - it might well be screaming and shouting about an invalid parameter. Something that might not strictly be an error, but will cause odd results...

hth
Jack

Share this post


Link to post
Share on other sites
Kiristu    135
What I'm trying to do is "tails" that follow all the particles.

To do that, I have a set of vertices that define a triangle strip, starting at the point position (its center), and ending where was the point a moment before (with some intermediaries positions).

The point is a unique vertex I draw at the same position than the first vertex of the tail, then all other vertices of the tail "follow" the point sprite.

The process is to draw first all point sprites, and then all tails after changing some render states (but no matrix).

Maybe my solution is not the best to do that.

Share this post


Link to post
Share on other sites
Kiristu    135
I've manually defined:
D3DRS_POINTSCALE_A
D3DRS_POINTSCALE_B
D3DRS_POINTSCALE_C

and still got the same result ...

Could my vertices definition be the problem ??



#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 )






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 ...

Thanks,
K.

[Edited by - Kiristu on April 19, 2006 1:18:15 PM]

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this