Sign in to follow this  
xegoth

Point sprites not alpha blending?

Recommended Posts

I'm trying to fade my point sprites out using alpha blending, the trouble is.. No matter what I set my alpha value to they are completely opaque. Here's my code, maybe someone can figure out why they aren't blending. initialize...
//-----------------------------------------------------------------------------
// Name: initPointSprites()
// Desc: 
//-----------------------------------------------------------------------------
void ParticleSys::initPointSprites(LPDIRECT3DDEVICE9 m_pD3DDevice)
{
	//
	// Load up the point sprite's texture...
	//

	if(FAILED(D3DXCreateTextureFromFile( m_pD3DDevice, "particle.bmp", &m_texParticle )))
		LogError("<li>Unable to load particle texture.");
	else
		LogInfo("<li>particle.bmp loaded OK");

	m_pD3DDevice->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
	m_pD3DDevice->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);

	//
	// Create a vertex bufer which can be used with point sprites...
	//

    m_pD3DDevice->CreateVertexBuffer( 2048 * sizeof(Vertex), 
                                      D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY | D3DUSAGE_POINTS, 
									  Vertex::FVF_Flags, D3DPOOL_DEFAULT, 
									  &m_particleVertexBuffer, NULL );

	//
    // If you want to know the max size that a point sprite can be set to, 
	// and whether or not you can change the size of point sprites in hardware 
	// by sending D3DFVF_PSIZE with the FVF, do this.
	//

	float fMaxPointSize = 0.0f;
	bool  bDeviceSupportsPSIZE = false;
	
    D3DCAPS9 d3dCaps;
    m_pD3DDevice->GetDeviceCaps( &d3dCaps );

    fMaxPointSize = d3dCaps.MaxPointSize;

    if( d3dCaps.FVFCaps & D3DFVFCAPS_PSIZE )
        bDeviceSupportsPSIZE = true;
    else
        bDeviceSupportsPSIZE = false;

}


updating..
//-----------------------------------------------------------------------------
// Name: updatePointSprites()
// Desc: 
//-----------------------------------------------------------------------------
void ParticleSys::updatePointSprites( void )
{

	float SLOWEST_VEL = .001f;
	
	//
	// To repeat the sample automatically, keep track of the overall app time.
	//

	if(dStartAppTime == 0)
	dStartAppTime = timeGetTime();
	
	float fElpasedAppTime = (float)((timeGetTime() - dStartAppTime) * 0.001);

	//
	// After 5 seconds, repeat the sample by returning all the particles 
	// back to the origin.
	//

    if( fElpasedAppTime >= 5.0f )
	{
		
		for( int i = 0; i < MAX_PARTICLES; ++i )
			g_particles[i].m_vCurPos = D3DXVECTOR3(10.0f,0.0f,0.0f);
		
		isActive = false; // Deactivate it.

		dStartAppTime = 0;
		return;
	}
	

	//
	// Move each particle via its velocity and elapsed frame time.
	//
	
	for( int i = 0; i < MAX_PARTICLES; ++i )
	{
		g_particles[i].m_vCurPos += g_particles[i].m_vCurVel;
	
		// Slow particles down unless they're already moving at slowest velocity.
		if(fabs(g_particles[i].m_vCurVel.x) > SLOWEST_VEL || fabs(g_particles[i].m_vCurVel.y) > SLOWEST_VEL || fabs(g_particles[i].m_vCurVel.z) > SLOWEST_VEL)
		{
			g_particles[i].m_vCurVel /= 1.01f;
		}

		g_particles[i].m_fAge += 0.001f; // Increase the particles age.

	}
}


rendering..
//-----------------------------------------------------------------------------
// Name: renderPointSprites()
// Desc: 
//-----------------------------------------------------------------------------
void ParticleSys::renderPointSprites( LPDIRECT3DDEVICE9 m_pD3DDevice )
{
	//
	// Setting D3DRS_ZWRITEENABLE to FALSE makes the Z-Buffer read-only, which 
	// helps remove graphical artifacts generated from  rendering a list of 
	// particles that haven't been sorted by distance to the eye.
	//
    // Setting D3DRS_ALPHABLENDENABLE to TRUE allows particles, which overlap, 
	// to alpha blend with each other correctly.
	//

	m_pD3DDevice->SetRenderState(D3DRS_LIGHTING, FALSE);

    m_pD3DDevice->SetRenderState( D3DRS_ZWRITEENABLE, FALSE );

    m_pD3DDevice->SetRenderState( D3DRS_ALPHABLENDENABLE, TRUE );

	m_pD3DDevice->SetRenderState(D3DRS_SRCBLEND,D3DBLEND_ONE);

	m_pD3DDevice->SetRenderState(D3DRS_DESTBLEND,D3DBLEND_ONE);



	//
	// Set up the render states for using point sprites...
	//

    m_pD3DDevice->SetRenderState( D3DRS_POINTSPRITEENABLE, TRUE );    // Turn on point sprites
    m_pD3DDevice->SetRenderState( D3DRS_POINTSCALEENABLE,  TRUE );    // Allow sprites to be scaled with distance
    m_pD3DDevice->SetRenderState( D3DRS_POINTSIZE,     FtoDW(1.0) );  // Float value that specifies the size to use for point size computation in cases where point size is not specified for each vertex.
    m_pD3DDevice->SetRenderState( D3DRS_POINTSIZE_MIN, FtoDW(1.0f) ); // Float value that specifies the minimum size of point primitives. Point primitives are clamped to this size during rendering. 
    m_pD3DDevice->SetRenderState( D3DRS_POINTSCALE_A,  FtoDW(0.0f) ); // Default 1.0
    m_pD3DDevice->SetRenderState( D3DRS_POINTSCALE_B,  FtoDW(0.0f) ); // Default 0.0
    m_pD3DDevice->SetRenderState( D3DRS_POINTSCALE_C,  FtoDW(1.0f) ); // Default 0.0

	//
	// Lock the vertex buffer, and set up our point sprites in accordance with 
	// our particles that we're keeping track of in our application.
	//

	Vertex *pPointVertices;

	m_particleVertexBuffer->Lock( 0, MAX_PARTICLES * sizeof(Vertex),
		                   (void**)&pPointVertices, D3DLOCK_DISCARD );

	for( int i = 0; i < MAX_PARTICLES; ++i )
    {
        pPointVertices->posit = g_particles[i].m_vCurPos;
        pPointVertices->color = g_particles[i].m_vColor;
        pPointVertices++;
    }

    m_particleVertexBuffer->Unlock();
	
	//
	// Render point sprites...
	//

    m_pD3DDevice->SetStreamSource( 0, m_particleVertexBuffer, 0, sizeof(Vertex) );
    m_pD3DDevice->SetFVF( Vertex::FVF_Flags );
	m_pD3DDevice->DrawPrimitive( D3DPT_POINTLIST, 0, MAX_PARTICLES );

	//
    // Reset render states...
	//
	
    m_pD3DDevice->SetRenderState( D3DRS_POINTSPRITEENABLE, FALSE );
    m_pD3DDevice->SetRenderState( D3DRS_POINTSCALEENABLE,  FALSE );

    m_pD3DDevice->SetRenderState( D3DRS_ZWRITEENABLE, TRUE );
    m_pD3DDevice->SetRenderState( D3DRS_ALPHABLENDENABLE, FALSE );
	m_pD3DDevice->SetRenderState(D3DRS_LIGHTING, TRUE);
}


I want them to fade away but they aren't fading at all! I can set my sprites alpha to any number it makes no difference.

Share this post


Link to post
Share on other sites
What are your Vertex::FVF_Flags?

EDIT - added:
Also you are setting
m_pD3DDevice->SetRenderState( D3DRS_ALPHABLENDENABLE, FALSE );

I'm pretty much a DX newb, so I may be way off. And I have to go now, so no time to look anything up.

Share this post


Link to post
Share on other sites
I don't see where you're modifying your alpha values at all... the other thing is that you have it to blend with the background. You may want to try putting something in the background and/or playing with the blending states.

Okay - what you need is alpha texture blending. Since you're using point sprites, the alpha diffuse color of the vertices won'y do anything - the texture takes priority. You probabaly don't want to use the D3DBLEND_ONE; instead try

D3DBLEND_SRCALPHA as the SourceBlendFactor and
D3DBLEND_INVSRCALPHA as the DestBlendFactor

That should get it to work. Refer to "Alpha Texture Blending" in the SDK for more info...


Mushu - trying to help those he doesn't know, with things he doesn't know.
Why won't he just go away? An question the universe may never have an answer to...

Share this post


Link to post
Share on other sites
Quote:
Original post by Mushu
I don't see where you're modifying your alpha values at all...


I didn't paste the part of my code that sets the alpha, I'll try what you told me though and see what that does. Thanks.

Share this post


Link to post
Share on other sites
Okay I made a mistake, it's not Alpha blending I'm having trouble with... It's Alpha Transparency.

If I put my red sprites on a green background they DO blend and turn yellow. The thing is I want to make them go transparent to fade away. When I set their color I set it as RGBA but the A has no effect.


//-----------------------------------------------------------------------------
// Name: begin(float originX, float originY, float originZ)
// Desc: Start an explosion
//-----------------------------------------------------------------------------
void ParticleSys::begin(float originX, float originY, float originZ)
{
isActive = true; // It's active now
dStartAppTime = 0;

//
// Initialize our particles so they'll start at the origin with some
// random direction and color.
//


for( int i = 0; i < MAX_PARTICLES; ++i )
{
g_particles[i].m_vCurPos = D3DXVECTOR3(10.0f,0.0f,0.0f);
g_particles[i].m_vCurVel = getRandomVector() * getRandomMinMax( 0.01f, 0.03f );

g_particles[i].m_red = 1.0f;
g_particles[i].m_green = getRandomMinMax( 0.3f, 0.5f );
g_particles[i].m_blue = 0.1f;

g_particles[i].m_vColor = D3DCOLOR_COLORVALUE( g_particles[i].m_red,
g_particles[i].m_green,
g_particles[i].m_blue,
1.0f );

// Age must start at 1.0 or greater for correct effect because it's used as a divisor.
g_particles[i].m_fAge = 1.0f;
}



}

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
Try to setup the alpha operation in modulate mode. It seems like it was in add mode.

m_pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAOP, D3DTOP_MODULATE);

Good Luck!

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