|
发表于 2007-11-1 17:51:00
|
显示全部楼层
Re:怎么在3d渲染中做火焰?
void CMyFire::OnFrameRender(IDirect3DDevice9* pd3dDevice, double fTime, float fElapsedTime)
{
POINTVERTEX* ppPointVertices;
float randFactorX=0.0f;
float randFactorZ=0.0f;
static int ii=0;
static int vbOffset=0;
if(vbOffset>=1000)
vbOffset=0;
HRESULT hr;
if( FAILED( hr = m_pFirePointVB->Lock( vbOffset*sizeof(POINTVERTEX),
201*sizeof(POINTVERTEX),
(VOID**)&ppPointVertices,
vbOffset?D3DLOCK_NOOVERWRITE 3DLOCK_DISCARD) ) )
{
ATLTRACE("CMyFire::OnFrameRender Lock vertex buffer error\n");
return;
//return DXTRACE_ERR( "Lock", hr );
}
DWORD numInBatch=0;
for(int k=0;k<6400;k++)
{
//30帧之前,just 喷射
if(m_fire[k].i<30)
{
m_fire[k].currentX=m_fire[k].x0+m_fire[k].vx*m_fire[k].i;
m_fire[k].currentY=m_fire[k].y0+m_fire[k].vy*m_fire[k].i;
m_fire[k].currentZ=m_fire[k].z0+m_fire[k].vz*m_fire[k].i;
D3DXVECTOR3 pos=D3DXVECTOR3(m_fire[k].currentX,m_fire[k].currentY,m_fire[k].currentZ);
ppPointVertices->v=pos;
ppPointVertices->color=0xff404040;//0x08ffff00;dwColor
numInBatch++;
ppPointVertices++;
//DXUtil_Trace("in i<30 state numInBatch=%d\n",numInBatch);
}
if(m_fire[k].i==29)
{
//x1[k]=(targetX-(m_fire[k].currentX))/90.0f;
//y1[k]=(targetY-(m_fire[k].currentY))/90.0f;
//y1[k]=(targetZ-(m_fire[k].currentZ))/90.0f;
m_fire[k].x0=m_fire[k].currentX;
m_fire[k].y0=m_fire[k].currentY;
m_fire[k].z0=m_fire[k].currentZ;
m_fire[k].deltax=(m_fire[k].targetX-(m_fire[k].currentX))/90.0f;
m_fire[k].deltay=(m_fire[k].targetY-(m_fire[k].currentY))/90.0f;
m_fire[k].deltaz=(m_fire[k].targetZ-(m_fire[k].currentZ))/90.0f;
}
//DXUtil_Trace("n=%d x1=%f\n",m_fire[k].i,x1[k]);
//30帧到90帧前,随机抖动火焰
if(m_fire[k].i>=30&&m_fire[k].i<90)
{
//DXUtil_Trace("n=%d tempX=%f tempY=%f tempZ=%f\n",k,tempX[k],tempY[k],tempZ[k]);
switch(rand()%10)
{
case 0:
randFactorX=-0.125f*5.0f;
break;
case 1:
randFactorX=-0.10f*5.0f;
break;
case 2:
randFactorX=-0.075f*5.0f;
break;
case 3:
randFactorX=-0.05f*5.0f;
break;
case 4:
randFactorX=-0.025f*5.0f;
break;
case 5:
randFactorX=0.025f*5.0f;
break;
case 6:
randFactorX=0.05f*5.0f;
break;
case 7:
randFactorX=0.075f*5.0f;
break;
case 8:
randFactorX=0.10f*5.0f;
break;
case 9:
randFactorX=0.125f*5.0f;
break;
}
switch(rand()%10)
{
case 0:
randFactorZ=-0.125f*5.0f;
break;
case 1:
randFactorZ=-0.10f*5.0f;
break;
case 2:
randFactorZ=-0.075f*5.0f;
break;
case 3:
randFactorZ=-0.05f*5.0f;
break;
case 4:
randFactorZ=-0.025f*5.0f;
break;
case 5:
randFactorZ=0.025f*5.0f;
break;
case 6:
randFactorZ=0.05f*5.0f;
break;
case 7:
randFactorZ=0.075f*5.0f;
break;
case 8:
randFactorZ=0.10f*5.0f;
break;
case 9:
randFactorZ=0.125f*5.0f;
break;
}
m_fire[k].currentX=m_fire[k].x0+(m_fire[k].i-29)*m_fire[k].deltax+randFactorX;
m_fire[k].currentZ=m_fire[k].z0+(m_fire[k].i-29)*m_fire[k].deltaz+randFactorZ;
m_fire[k].currentY=m_fire[k].y0+(m_fire[k].i-29)*m_fire[k].deltay;
D3DXVECTOR3 pos=D3DXVECTOR3(m_fire[k].currentX,
m_fire[k].currentY,m_fire[k].currentZ);
ppPointVertices->v=pos;
ppPointVertices->color=0xff404040;//0x08ffff00;dwColor
//DXUtil_Trace("n=%d x=%f y=%f z=%f\n",k,ppPointVertices[k].v.x,
// ppPointVertices[k].v.y,ppPointVertices[k].v.z);
numInBatch++;
ppPointVertices++;
}
if(m_fire[k].i==89)
{
//x1[k]=(targetX-m_fire[k].currentX)/30.0f;
//y1[k]=(targetY-m_fire[k].currentY)/30.0f;
//y1[k]=(targetZ-m_fire[k].currentZ)/30.0f;
m_fire[k].x0=m_fire[k].currentX;
m_fire[k].y0=m_fire[k].currentY;
m_fire[k].z0=m_fire[k].currentZ;
m_fire[k].deltax=(m_fire[k].targetX-(m_fire[k].currentX))/30.0f;
m_fire[k].deltay=(m_fire[k].targetY-(m_fire[k].currentY))/30.0f;
m_fire[k].deltaz=(m_fire[k].targetZ-(m_fire[k].currentZ))/30.0f;
}
//90frame-119frame go towards target
if(m_fire[k].i>=90&&m_fire[k].i<120)
{
m_fire[k].currentX=m_fire[k].x0+(m_fire[k].i-89)*m_fire[k].deltax;
m_fire[k].currentZ=m_fire[k].z0+(m_fire[k].i-89)*m_fire[k].deltaz;
m_fire[k].currentY=m_fire[k].y0+(m_fire[k].i-89)*m_fire[k].deltay;
//DXUtil_Trace("i>90 i=%d x=%f y=%f z=%f\n",m_fire[k].i,m_fire[k].currentX,
// m_fire[k].currentY,m_fire[k].currentZ);
ppPointVertices->v=D3DXVECTOR3(m_fire[k].currentX,
m_fire[k].currentY,m_fire[k].currentZ);
ppPointVertices->color=0xff404040;
numInBatch++;
ppPointVertices++;
}
//DXUtil_Trace("n=%d x=%f y=%f z=%f\n",k,ppPointVertices[k].v.x,
// ppPointVertices[k].v.y,ppPointVertices[k].v.z);
m_fire[k].i++;
static int jj=0;
if(m_fire[k].i>119&&k<1600)
{
static float targetX0=0.0f;
static float targetY0=6.0f;
static float targetZ0=0.0f;
float alpha=((float)rand()/(float)RAND_MAX)*D3DX_PI/3.0f;
float beta=((float)rand()/(float)RAND_MAX)*D3DX_PI*2.0f;
m_fire[k].x0=0.0f;
m_fire[k].y0=0.0f;
m_fire[k].z0=0.0f;
//m_fire[t].V=2.5f;
m_fire[k].currentX=m_fire[k].x0;
m_fire[k].currentY=m_fire[k].y0;
m_fire[k].currentZ=m_fire[k].z0;
m_fire[k].i=0;
m_fire[k].time=fTime;
m_fire[k].vy=0.075f*cosf(alpha);
m_fire[k].vx=0.075*sinf(alpha)*cosf(beta);
m_fire[k].vz=0.075*sinf(alpha)*sinf(beta);
m_fire[k].deltax=0.0f;
m_fire[k].deltay=0.0f;
m_fire[k].deltaz=0.0f;
m_fire[k].targetX=targetX0;
m_fire[k].targetY=targetY0;
m_fire[k].targetZ=targetZ0;
jj++;
if(jj==200)
{
float xRand=((float)rand()/(float)RAND_MAX)*3.0f;
float yRand=((float)rand()/(float)RAND_MAX)*4.0f;
float zRand=((float)rand()/(float)RAND_MAX)*3.0f;
targetX0=-1.5f+xRand;
targetY0=4.0f+yRand;
targetZ0=-1.5f+zRand;
jj=0;
}
}
if(m_fire[k].i>119&&k>=1600&&k<3200)
{
static float targetX0=0.0f;
static float targetY0=6.0f;
static float targetZ0=0.0f;
float alpha=((float)rand()/(float)RAND_MAX)*D3DX_PI/3.0f;
float beta=((float)rand()/(float)RAND_MAX)*D3DX_PI*2.0f;
m_fire[k].x0=0.0f;
m_fire[k].y0=0.0f;
m_fire[k].z0=0.0f;
//m_fire[t].V=2.5f;
m_fire[k].currentX=m_fire[k].x0;
m_fire[k].currentY=m_fire[k].y0;
m_fire[k].currentZ=m_fire[k].z0;
m_fire[k].i=0;
m_fire[k].time=fTime;
m_fire[k].vy=0.075f*cosf(alpha);
m_fire[k].vx=0.075f*sinf(alpha)*cosf(beta);
m_fire[k].vz=0.075f*sinf(alpha)*sinf(beta);
m_fire[k].deltax=0.0f;
m_fire[k].deltay=0.0f;
m_fire[k].deltaz=0.0f;
m_fire[k].targetX=targetX0;
m_fire[k].targetY=targetY0;
m_fire[k].targetZ=targetZ0;
jj++;
if(jj==200)
{
float xRand=((float)rand()/(float)RAND_MAX)*3.0f;
float yRand=((float)rand()/(float)RAND_MAX)*4.0f;
float zRand=((float)rand()/(float)RAND_MAX)*3.0f;
targetX0=-1.5f+xRand;
targetY0=4.0f+yRand;
targetZ0=-1.5f+zRand;
jj=0;
}
}
if(m_fire[k].i>119&&k>=3200&&k<4800)
{
static float targetX0=0.0f;
static float targetY0=6.0f;
static float targetZ0=0.0f;
float alpha=((float)rand()/(float)RAND_MAX)*D3DX_PI/3.0f;
float beta=((float)rand()/(float)RAND_MAX)*D3DX_PI*2.0f;
m_fire[k].x0=0.0f;
m_fire[k].y0=0.0f;
m_fire[k].z0=0.0f;
//m_fire[t].V=2.5f;
m_fire[k].currentX=m_fire[k].x0;
m_fire[k].currentY=m_fire[k].y0;
m_fire[k].currentZ=m_fire[k].z0;
m_fire[k].i=0;
m_fire[k].time=fTime;
m_fire[k].vy=0.075f*cosf(alpha);
m_fire[k].vx=0.075f*sinf(alpha)*cosf(beta);
m_fire[k].vz=0.075f*sinf(alpha)*sinf(beta);
m_fire[k].deltax=0.0f;
m_fire[k].deltay=0.0f;
m_fire[k].deltaz=0.0f;
m_fire[k].targetX=targetX0;
m_fire[k].targetY=targetY0;
m_fire[k].targetZ=targetZ0;
jj++;
if(jj==200)
{
float xRand=((float)rand()/(float)RAND_MAX)*3.0f;
float yRand=((float)rand()/(float)RAND_MAX)*4.0f;
float zRand=((float)rand()/(float)RAND_MAX)*3.0f;
targetX0=-1.5f+xRand;
targetY0=4.0f+yRand;
targetZ0=-1.5f+zRand;
jj=0;
}
}
if(m_fire[k].i>119&&k>=4800&&k<6400)
{
static float targetX0=0.0f;
static float targetY0=6.0f;
static float targetZ0=0.0f;
float alpha=((float)rand()/(float)RAND_MAX)*D3DX_PI/3.0f;
float beta=((float)rand()/(float)RAND_MAX)*D3DX_PI*2.0f;
m_fire[k].x0=0.0f;
m_fire[k].y0=0.0f;
m_fire[k].z0=0.0f;
//m_fire[t].V=2.5f;
m_fire[k].currentX=m_fire[k].x0;
m_fire[k].currentY=m_fire[k].y0;
m_fire[k].currentZ=m_fire[k].z0;
m_fire[k].i=0;
m_fire[k].time=fTime;
m_fire[k].vy=0.075f*cosf(alpha);
m_fire[k].vx=0.075f*sinf(alpha)*cosf(beta);
m_fire[k].vz=0.075f*sinf(alpha)*sinf(beta);
m_fire[k].deltax=0.0f;
m_fire[k].deltay=0.0f;
m_fire[k].deltaz=0.0f;
m_fire[k].targetX=targetX0;
m_fire[k].targetY=targetY0;
m_fire[k].targetZ=targetZ0;
jj++;
if(jj==200)
{
float xRand=((float)rand()/(float)RAND_MAX)*3.0f;
float yRand=((float)rand()/(float)RAND_MAX)*4.0f;
float zRand=((float)rand()/(float)RAND_MAX)*3.0f;
targetX0=-1.5f+xRand;
targetY0=4.0f+yRand;
targetZ0=-1.5f+zRand;
jj=0;
}
}
if(numInBatch==201)
{
m_pFirePointVB->Unlock();
pd3dDevice->SetRenderState(D3DRS_AMBIENT,0XFFFFFFFF);
pd3dDevice->SetFVF(POINTVERTEX::FVF);
pd3dDevice->SetStreamSource( 0, m_pFirePointVB, 0, sizeof(POINTVERTEX) );
//DXUtil_Trace("mat_11=%f mat_12=%f mat_13=%f mat_14=%f\n",matProj._11,matProj._12,matProj._13,matProj._14);
//DXUtil_Trace("mat_21=%f mat_22=%f mat_23=%f mat_24=%f\n",matProj._21,matProj._22,matProj._23,matProj._24);
//DXUtil_Trace("mat_31=%f mat_32=%f mat_33=%f mat_34=%f\n",matProj._31,matProj._32,matProj._33,matProj._34);
//DXUtil_Trace("mat_41=%f mat_42=%f mat_43=%f mat_44=%f\n",matProj._41,matProj._42,matProj._43,matProj._44);
//D3DXMATRIX mWorld;
//D3DXMatrixScaling(&mWorld,0.4F,0.4F,0.4F);
//mWorld._41=224.0f;
//mWorld._42=4.0f;
//mWorld._43=359.0f;
//pd3dDevice->SetTransform(D3DTS_WORLD,&mWorld);
pd3dDevice->DrawPrimitive( D3DPT_POINTLIST,vbOffset, 201 );
vbOffset+=201;
if(vbOffset>=1000)
vbOffset=0;
if( FAILED( hr = m_pFirePointVB->Lock( vbOffset*sizeof(POINTVERTEX),
201*sizeof(POINTVERTEX),
(VOID**)&ppPointVertices,
vbOffset?D3DLOCK_NOOVERWRITE:D3DLOCK_DISCARD) ) )
return;
numInBatch=0;
}
//DXUtil_Trace("numInBatch=%d\n",numInBatch);
}
m_pFirePointVB->Unlock();
pd3dDevice->SetRenderState(D3DRS_AMBIENT,0XFFFFFFFF);
pd3dDevice->SetStreamSource( 0, m_pFirePointVB, 0, sizeof(POINTVERTEX) );
if(numInBatch)
{
pd3dDevice->SetFVF(POINTVERTEX::FVF);
//D3DXMATRIX matProjection(matProj);
//matProjection._11*=2.0f;
//matProjection._22*=2.0f;
//matProjection._33*=2.0f;
//m_pd3dDevice->SetTransform(D3DTS_PROJECTION,&matProj);
// D3DXMATRIX mWorld;
// D3DXMatrixScaling(&mWorld,0.4F,0.4F,0.4F);
// mWorld._41=224.0f;
// mWorld._42=4.0f;
// mWorld._43=359.0f;
// m_pd3dDevice->SetTransform(D3DTS_WORLD,&mWorld);
pd3dDevice->DrawPrimitive( D3DPT_POINTLIST,vbOffset, numInBatch );
// D3DXMatrixIdentity(&mWorld);
// D3DXMatrixScaling(&mWorld,0.4F,0.4F,0.4F);
// mWorld._41=220.0f;
// mWorld._42=4.0f;
// mWorld._43=359.0f;
// m_pd3dDevice->SetTransform(D3DTS_WORLD,&mWorld);
// m_pd3dDevice->DrawPrimitive( D3DPT_POINTLIST,vbOffset, numInBatch );
}
vbOffset+=201;
if(vbOffset>=1000)
vbOffset=0;
pd3dDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, false);
pd3dDevice->SetRenderState(D3DRS_LIGHTING,m_dwLight);
pd3dDevice->SetRenderState(D3DRS_POINTSPRITEENABLE,false);
pd3dDevice->SetRenderState(D3DRS_POINTSCALEENABLE,false);
ppPointVertices=NULL;
return;
} |
|