Archived

This topic is now archived and is closed to further replies.

Made a particle engine, an easy problem

This topic is 5644 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Ok, I made my own particle engine! I''m pretty proud of myself because I didn''t copy any code except setting up render states which I didn''t know how to do, but I have a small problem, and I''m not quite sure what is wrong. Ok, when NOTHING else besides particles is rendered, it works fine, but when I add in a cube that I made that is behind the particles, the particles just look really bright, and you can hardly see them. It looks like the cube is just more lit up. I did do a
  
D3DDevice->SetRenderState(D3DRS_ALPHABLENDABLE, FALSE);
  
In fact, here''s my render code for the particle:
  
void Particle::Render() {
	D3DDevice->SetRenderState(D3DRS_LIGHTING,FALSE);
	D3DDevice->SetRenderState(D3DRS_ZENABLE,FALSE);
	D3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE,TRUE);
	D3DDevice->SetRenderState( D3DRS_SRCBLEND,  D3DBLEND_SRCALPHA );
    D3DDevice->SetRenderState( D3DRS_DESTBLEND, D3DBLEND_ONE );
	D3DDevice->SetTexture(0,tex);
	D3DDevice->SetVertexShader(PARTICLEFVF);
	D3DDevice->SetStreamSource(0,vb,sizeof(CustomV));
	D3DDevice->DrawPrimitive(D3DPT_TRIANGLELIST,0,2);
	D3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE,FALSE);
	D3DDevice->SetTexture(0,NULL);
	D3DDevice->SetRenderState(D3DRS_LIGHTING,TRUE);
	D3DDevice->SetRenderState(D3DRS_ZENABLE,TRUE);
}
  
any help?

Share this post


Link to post
Share on other sites
I''d guess it''s the alpha value of the bitmap you are using as a particle. Try making the particle bitmap darker (I think paintshop pro includes alpha values in the colour selector if it helps). I believe its possible to have black with an alpha value of 0 all the way through to 255 and the same for any other colour, so if you are using black and white for your particle, try checking the colours alpha value in your paint package if the option is available, you may find that your white is acting more as you''d expect a light grey to work because it has an alpha value of less than 255 and is therefore not solid but still semi transparent.

Share this post


Link to post
Share on other sites
Ok, I have a little bit better an explanation of the problem. The lighter the background is, the less you can see of the particle. I tried darkening it and it didn''t work. I think the problem is that no matter what, it builds up on the brightness rather than taking it away. I''m not sure, but I think this is called like additive alpha blending or something like that. Does anyone know how to remedy it?

Share this post


Link to post
Share on other sites
I figured I might as well post the code, its not long at all


  
#include "particle.h"

Particle::Particle(LPDIRECT3DDEVICE8 device) {
D3DDevice=device;

//High quality filtering to make things look nice


SetSize(5.0f);
SetTexture("Particle.bmp");

D3DDevice->CreateVertexBuffer(6*sizeof(CustomV),D3DUSAGE_WRITEONLY,PARTICLEFVF,D3DPOOL_MANAGED,&vb);
SetColor(255,255,255);
UpdateVertices();
}

void Particle::SetColor(int r, int g, int b) {
r1=r;
g1=g;
b1=b;
UpdateVertices();
}
void Particle::UpdateVertices() {
VOID* pVertices;
CustomV cvVertices[]={
{-size, -size,0.0f,D3DCOLOR_XRGB(r1,g1,b1), 0.0f,1.0f,},
{-size, size, 0.0f, D3DCOLOR_XRGB(r1,g1,b1),0.0f, 0.0f,},
{size, -size, 0.0f,D3DCOLOR_XRGB(r1,g1,b1), 1.0f, 1.0f,},


{size, -size, 0.0f, D3DCOLOR_XRGB(r1,g1,b1),1.0f, 1.0f,},
{-size, size,0.0f,D3DCOLOR_XRGB(r1,g1,b1), 0.0f, 0.0f, },
{size, size,0.0f,D3DCOLOR_XRGB(r1,g1,b1), 1.0f, 0.0f, }};
vb->Lock(0,0, (BYTE**)&pVertices,0);
memcpy(pVertices,cvVertices,sizeof(cvVertices));
vb->Unlock();

}

void Particle::SetSize(float s) {
size=s;
}

void Particle::SetTexture(char *file) {
D3DXCreateTextureFromFile(D3DDevice, file, &tex);
}

void Particle::Render() {
D3DDevice->SetRenderState(D3DRS_SRCBLEND,D3DBLEND_ONE);
D3DDevice->SetRenderState(D3DRS_DESTBLEND,D3DBLEND_ONE);

D3DDevice->SetRenderState(D3DRS_LIGHTING,FALSE);
D3DDevice->SetRenderState(D3DRS_ZENABLE, D3DZB_FALSE);
D3DDevice->SetTexture(0,tex);
D3DDevice->SetVertexShader(PARTICLEFVF);
D3DDevice->SetStreamSource(0,vb,sizeof(CustomV));
D3DDevice->DrawPrimitive(D3DPT_TRIANGLELIST,0,2);
D3DDevice->SetRenderState(D3DRS_LIGHTING,TRUE);
D3DDevice->SetRenderState(D3DRS_ZENABLE, D3DZB_TRUE);
}

Share this post


Link to post
Share on other sites

      
BOOL cGraphics::EnableAlphaBlending(BOOL Enable){
m_pD3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, Enable);
m_pD3DDevice->SetRenderState(D3DRS_SRCBLEND,D3DBLEND_SRCALPHA);
m_pD3DDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_ONE);
return TRUE;
}


That function sorts my alpha blending, I believe your line "D3DDevice->SetRenderState(D3DRS_SRCBLEND,D3DBLEND_ONE);" , needs replacing with "D3DDevice->SetRenderState(D3DRS_SRCBLEND,D3DBLEND_SRCALPHA);"

Hope that helps


[edited by - mephs on June 25, 2002 9:37:05 PM]

Share this post


Link to post
Share on other sites
Close, but no cigar. now Color keying goes away.. here''s the new code for render:


  

void Particle::Alpha(BOOL enable) {
D3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, enable);
D3DDevice->SetRenderState(D3DRS_SRCBLEND,D3DBLEND_SRCALPHA);
D3DDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_ONE);
}

void Particle::Render() {
Alpha(TRUE);
D3DDevice->SetTransform(D3DTS_WORLD,&mat);
D3DDevice->SetRenderState(D3DRS_LIGHTING,FALSE);
D3DDevice->SetRenderState(D3DRS_ZENABLE, D3DZB_FALSE);
D3DDevice->SetTexture(0,tex);
D3DDevice->SetVertexShader(PARTICLEFVF);
D3DDevice->SetStreamSource(0,vb,sizeof(CustomV));
D3DDevice->DrawPrimitive(D3DPT_TRIANGLELIST,0,2);
D3DDevice->SetRenderState(D3DRS_LIGHTING,TRUE);
D3DDevice->SetRenderState(D3DRS_ZENABLE, D3DZB_TRUE);
Alpha(FALSE);
}

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
Not that it has anything to do with your problem but...

You might want to split your classes up into ParticleType and Particle (or ParticleInstance).
The ParticleType class contains all the parameters for that particular type of particle (ie the fire particles) and the ParticleInstance class holds the individual particle''s data (ie position, color).

Make the ParticleType class contain a linked list (or stl vector or whatever) of all the ParticleInstances.

Then put the a Render routine in the ParticleType... this routine should setup your d3d render states, loop through each ParticleInstance in it''s list and call the ParticleInstance''s Render function, then cleanup. In the instances Render function you only need to draw the actual triangles (no d3d setup).

The advantage of doing everything like this is that you dont set the render state for every particle - you only do it once... far more efficient use of d3d! Changing render states, setting textures, whaever should be avoided where possible on ALL hardware.


Sorry to be such a ''smart ass'' but hopefully you dont mind a little friendly advice...

Share this post


Link to post
Share on other sites
still doesn''t work, I''ve tried it both with:


  
D3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, enable);
D3DDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
D3DDevice->SetRenderState(D3DRS_SRCBLEND,D3DBLEND_ONE);

and

  
D3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, enable);
D3DDevice->SetRenderState(D3DRS_SRCBLEND,D3DBLEND_SRCALPHA);
D3DDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);

Share this post


Link to post
Share on other sites
Please don''t tell me you''re using a bmp?
If you are, don''t tell me, and use a 32bpp tga instead...

T

--
MFC is sorta like the swedish police... It''''s full of crap, and nothing can communicate with anything else.

Share this post


Link to post
Share on other sites