Particle system: Point size, color dont work? yer pos does?

Started by
4 comments, last by xsirxx 20 years, 1 month ago
Im having problems, my color and point size do not work? Yet the position are all correct.... check out this code...

void ParticleEmitter::Render(LPDIRECT3DDEVICE8 pDev, D3DXVECTOR3 vecCameraSource){
	pd3dDevice = pDev;
	D3DXMATRIX matWorld;
	D3DXMatrixIdentity( &matWorld );
	matWorld._41 = vecCameraSource.x;//0;

	matWorld._42 = vecCameraSource.y;//0;

	matWorld._43 = vecCameraSource.z;//+700;//0;//-530;

	pd3dDevice->SetTransform( D3DTS_WORLD, &matWorld );
	
//////////////    MATERIAL INFO?	/////////////////////

	D3DMATERIAL8 material;
	ZeroMemory(&material, sizeof(D3DMATERIAL8));
	material.Ambient.r = 1;
	material.Ambient.g = 1;
	material.Ambient.b = 1;
	material.Ambient.a = 1;
/////////////////////////////////////////////////////////


	pd3dDevice->SetRenderState( D3DRS_ZWRITEENABLE, FALSE );
	pd3dDevice->SetRenderState( D3DRS_ALPHABLENDENABLE, TRUE );
	pd3dDevice->SetRenderState( D3DRS_SRCBLEND, D3DBLEND_ONE );
	pd3dDevice->SetRenderState( D3DRS_DESTBLEND, D3DBLEND_ONE );
		pd3dDevice->SetRenderState( D3DRS_POINTSPRITEENABLE, TRUE );
	pd3dDevice->SetRenderState( D3DRS_POINTSCALEENABLE,  TRUE );
	pd3dDevice->SetRenderState( D3DRS_POINTSIZE,     FtoDW(10.0f) );
	pd3dDevice->SetRenderState( D3DRS_POINTSIZE_MIN, FtoDW(0.00f) );
//	pd3dDevice->SetRenderState( D3DRS_POINTSIZE_MAX, FtoDW(1000.00f) );

	pd3dDevice->SetRenderState( D3DRS_POINTSCALE_A,  FtoDW(0.00f) );
	pd3dDevice->SetRenderState( D3DRS_POINTSCALE_B,  FtoDW(1.00f) );
	pd3dDevice->SetRenderState( D3DRS_POINTSCALE_C,  FtoDW(1.00f) );

	pd3dDevice->SetStreamSource( 0, vbParticles, sizeof(VERTEX_PARTICLE) );
	pd3dDevice->SetVertexShader( D3DFVF_PARTICLE );
	pd3dDevice->SetTexture(0, texParticle);
//////////////    MATERIAL INFO?	/////////////////////

	pd3dDevice->SetMaterial( &material );
/////////////////////////////////////////////////////////

	VERTEX_PARTICLE *pVertices;
	DWORD dwNumParticlesToRender = 0;

	vbParticles->Lock(0, iVBSize * sizeof(VERTEX_PARTICLE), (BYTE **) &pVertices, D3DLOCK_DISCARD);
 
	 for (int i=0; i < NUMPARTICLES; i++) {
    
    if (partArray[i].IsAlive()) {
      Particle ∂ = partArray[i];
  
      pVertices->position = part.vPos;
	  pVertices->pointsize = part.fSize;
      pVertices->color = (DWORD)part.cColor;
      pVertices++;

      if( ++dwNumParticlesToRender == iVBSize ) {

		vbParticles->Unlock();
		pd3dDevice->DrawPrimitive(D3DPT_POINTLIST, 0, dwNumParticlesToRender);
		dwNumParticlesToRender = 0;
      }
    }
  }

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


}

void ParticleEmitter::LoadSprite(const char *strTextureFilename){
	D3DXCreateTextureFromFile(pd3dDevice, strTextureFilename, &texParticle);
//	D3DXCreateTextureFromFileEx(pd3dDevice, 

//		"Data\\3DObjects\\rain.bmp", D3DX_DEFAULT, D3DX_DEFAULT, 1, 0, D3DFMT_UNKNOWN,

//		D3DPOOL_MANAGED, D3DX_DEFAULT, D3DX_DEFAULT, 0, NULL, NULL, &texParticle);

}

void Particle::CreateRainDrop(void){
	iType		= 1;
	vPos.x		= RandomNumber((float)(-ScreenWidth/2), (float)(ScreenWidth/2));
	vPos.y		= (float)(ScreenHeight/2);
	vPos.z		= RandomNumber(0.0, 1000.0);
	cColor		= D3DCOLOR_RGBA(0,255,0,255);
	bAlive		= TRUE;
	vDir.y		= RandomNumber(-6.5f, -9.8f);
	fSize		= 1.0f;
	fLifeTime	= RandomNumber(10.0f ,7.0f);
	
}

#define D3DFVF_PARTICLE (D3DFVF_XYZ|D3DFVF_PSIZE|D3DFVF_DIFFUSE)

typedef struct 
{
    D3DXVECTOR3 position;
    float       pointsize;
    D3DCOLOR    color;
} VERTEX_PARTICLE;
--X
Advertisement
You are using textures, so you need to blend diffuse color with texure...
And, if you are using Geforce, size won`t work because it may lack of D3DFVFCAPS_PSIZE cap...
Bulma
Yea i have a GeForce FX GO, highest possible GO card... does have psize? thought geforce 4 on they fixed that? ive also heard that geforce fx is just a revamped 3 card.... hmm weird, well i can change that with depth so thats not the biggest issue, i just hate multiple stage state changes...

As far as that diffuse setting, could u give me an example? thanks..


ohh btw, these were my old settings:
// pd3dDevice->SetTextureStageState( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
// pd3dDevice->SetTextureStageState( 0, D3DTSS_COLOROP, D3DTOP_MODULATE );
// pd3dDevice->SetTextureStageState( 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE );
// pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE );
// pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAOP, D3DTOP_MODULATE );
// pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE );
// pd3dDevice->SetTextureStageState( 1, D3DTSS_COLOROP, D3DTOP_DISABLE );
// pd3dDevice->SetTextureStageState( 1, D3DTSS_ALPHAOP, D3DTOP_DISABLE );

but yet they didnt help .

Thanks
--X
- To get your colors from the vertices, you need to set the renderstate D3DRS_DIFFUSEMATERIALSOURCE (or DIFFUSECOLORSOURCE, something along these lines) to D3DMCS_COLOR1 (or 2, one of them specifies "get the color from the vertex" and the other says "get the color from the material").

Alternatively, you can just disable the lighting before rendering your sprites. This''ll force d3d to take colors from your point-sprites (and I think the point-size works in SpacePirates, by the way).

- I''ve not been able to find why the texture doesn''t show up yet (haven''t inspected it enough). It''s loading correctly, though.

- Regarding smart COM pointers, here''s a blurb (the weird syntax is because this was written for a wiki):

[begin blurb]
== Smart COM pointers ==
Often, programmers do not manage the lifetime of COM objects properly. For example, one could forget to Release() an interface, or forgets to AddRef() an interface on copying, ...etc. This introduces MemoryLeaks.

Smart COM pointers greatly simplify the lifetime-management burden.

To make your life much easier, there are many smart COM pointers out there, that do the management jobs automatically. We''ll examine the CComPtr smart pointer, defined in atlbase.h - part of the ATL (Active Template Library). It comes with Visual C++, though I''m not sure if ATL is shipped with other compilers. In case you don''t have the ATL, and can''t download it (if it''s downloadable), you''ll have to find yourself a smart COM pointer (and there''s got to be lots of these around. You can even use a boost::shared_ptr with a custom deleter, or whatever it''s called).

CComPtr offers a lot of functionality, of which we''re interested in:

* It AddRef()''s the interface it holds when copied
* It Release()''s the interface it holds when destroyed, or assigned to NULL

Note that CComPtr hides the methods AddRef() and Release() of the interface pointer, because you''ll no longer need them. It forces you to use a replacement Release() instead, on the smart pointer itself.

To access the methods of CComPtr, you use the dot operator ''.'', and to access the interface methods you use the arrow operator ''->''.

So, the above code example would look like this with smart pointers:

class A{public:    A( IDirect3D9 *pD3D )    {        // Keep a copy of the d3d interface, ref count incremented automatically        m_d3d = pD3D;    }    void DoSomething()    {        // Do something with the d3d interface        UINT numAdapters = m_d3d->GetAdapterCount();    }    void Destroy()    {        m_d3d.Release();    // m_d3d->Release() illegal, because Release() has been                            // been hidden by CComPtr    }// No need for the destructor here. The default constructor generated by the compiler// will call CComPtr''s destructor, which in turn will release the interface//  ~A()//  {//     Destroy();//  }    private:    CComPtr m_d3d;};class B{public:// Same goes for B...};CComPtr d3d = Direct3DCreate9( D3D_SDK_VERSION );// CComPtr is automatically cast to IDirect3D9A objA( d3d );B objB( d3d );// Release the d3d interface// This only decrements the reference count - it doesn''t actually destroy the objectd3d.Release();// The following functions will work OKobjA.DoSomething();objB.DoAnotherThing();objB.Destroy();    // decrement ref countobjA.Destroy();    // decrement ref count, and destroy the object 


I cannot stress enough the importance of smart COM pointers. In short, use them. I''ve forgotten about DirectX MemoryLeaks since I''ve started using smart COM pointers.
[/end blurb]

Muhammad Haggag
Bitwise account: MHaggag -

Thnx coder, i have found the problem with the texture and have since gotten ALOT of work done on the particle system, i rebuilt the entire thing...

What is the best way of tracking memory leaks? I will research more on smart com, but as of right now... what is it i should be looking at on tracking down this memory problem. I have added in all my deconstructors extra care in releasing and NULLing most com.... guess im not sure on the rest.

Thanks much
--X
quote:What is the best way of tracking memory leaks? I will research more on smart com, but as of right now... what is it i should be looking at on tracking down this memory problem. I have added in all my deconstructors extra care in releasing and NULLing most com.... guess im not sure on the rest.

Replace every interface pointer with a smart COM pointer, and remove all the releasing code from destructors (the smart COM pointer destructor releases its interface automatically).

If you have:
IDirect3DDevice8 *pDevice;  


Change it to:
CComPtr<IDirect3DDevice8> pDevice;  


You still can do all the operations on the d3d device using the -> operator:
pDevice->Clear( ... );  


When you want to release *now*, call Release on the smart pointer itself with the '.' operator:
pDevice.Release();  

or just do
pDevice = NULL;  


Muhammad Haggag
Bitwise account: MHaggag -

[edited by - Coder on March 12, 2004 9:40:35 AM]
[edit]code sections
[edit2]Angle brackets fix.

[edited by - Coder on March 12, 2004 9:41:50 AM]

This topic is closed to new replies.

Advertisement