Point Sprites problems

Started by
8 comments, last by Kiristu 18 years ago
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.
Advertisement
That all looks right to me. Have you tried it with the reference rasterizer?
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 ?
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.
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 !
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.
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?
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

<hr align="left" width="25%" />
Jack Hoxley <small>[</small><small> Forum FAQ | Revised FAQ | MVP Profile | Developer Journal ]</small>

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

This topic is closed to new replies.

Advertisement