void RenderShadow(LPDIRECT3DDEVICE7 lpDevice,D3DVERTEX* vertices,int numvertices,WORD* indices,DWORD numindices) { // Turn depth buffer off, and stencil buffer on lpDevice->SetRenderState( D3DRENDERSTATE_ZWRITEENABLE, FALSE ); lpDevice->SetRenderState( D3DRENDERSTATE_STENCILENABLE, TRUE ); // Set up stencil compare fuction, reference value, and masks // Stencil test passes if ((ref & mask) cmpfn (stencil & mask)) is true lpDevice->SetRenderState( D3DRENDERSTATE_STENCILFUNC, D3DCMP_ALWAYS ); lpDevice->SetRenderState( D3DRENDERSTATE_STENCILREF, 0x1 ); lpDevice->SetRenderState( D3DRENDERSTATE_STENCILMASK, 0xffffffff ); lpDevice->SetRenderState( D3DRENDERSTATE_STENCILWRITEMASK,0xffffffff ); // If ztest passes, write 1 into stencil buffer lpDevice->SetRenderState( D3DRENDERSTATE_STENCILZFAIL, D3DSTENCILOP_KEEP ); lpDevice->SetRenderState( D3DRENDERSTATE_STENCILFAIL, D3DSTENCILOP_KEEP ); lpDevice->SetRenderState( D3DRENDERSTATE_STENCILPASS, D3DSTENCILOP_REPLACE ); // Make sure that no pixels get drawn to the frame buffer lpDevice->SetRenderState( D3DRENDERSTATE_ALPHABLENDENABLE, TRUE ); lpDevice->SetRenderState( D3DRENDERSTATE_SRCBLEND, D3DBLEND_ZERO ); lpDevice->SetRenderState( D3DRENDERSTATE_DESTBLEND, D3DBLEND_ONE ); lpDevice->SetTexture(0,NULL); // Draw front-side of shadow volume in stencil/z only if (indices==NULL) { lpDevice->DrawPrimitive( D3DPT_TRIANGLELIST, D3DFVF_VERTEX, vertices, numvertices, NULL ); } else lpDevice->DrawIndexedPrimitive( D3DPT_TRIANGLELIST, D3DFVF_VERTEX, vertices, numvertices, indices, numindices, NULL ); // Now reverse cull order so back sides of shadow volume are written, // writing 0's into stencil. Result will be any pixel which still has a bit // set in the stencil buffer, is inside the shadow. lpDevice->SetRenderState( D3DRENDERSTATE_STENCILREF, 0x0 ); // Draw back-side of shadow volume in stencil/z only lpDevice->SetRenderState( D3DRENDERSTATE_CULLMODE, D3DCULL_CW ); if (indices==NULL) { lpDevice->DrawPrimitive( D3DPT_TRIANGLELIST, D3DFVF_VERTEX, vertices, numvertices, NULL ); } else lpDevice->DrawIndexedPrimitive( D3DPT_TRIANGLELIST, D3DFVF_VERTEX, vertices, numvertices, indices, numindices, NULL ); // Restore render states lpDevice->SetRenderState( D3DRENDERSTATE_CULLMODE, D3DCULL_CCW ); lpDevice->SetRenderState( D3DRENDERSTATE_ZWRITEENABLE, TRUE ); lpDevice->SetRenderState( D3DRENDERSTATE_STENCILENABLE, FALSE ); lpDevice->SetRenderState( D3DRENDERSTATE_ALPHABLENDENABLE, FALSE ); }
/// <summary> /// <c>wDrawIndexedPrimitive</c> /// </summary> /// <remarks> /// </remarks> /// <param name="d3dDevice7"></param> /// <param name="d3dptPrimitiveType"></param> /// <param name="dwVertexTypeDesc"></param> /// <param name="pvVertices"></param> /// <param name="dwVertexCount"></param> /// <param name="pwIndices"></param> /// <param name="dwIndexCount"></param> /// <param name="dwFlags"></param> /// <returns></returns> HRESULT __stdcall wDrawIndexedPrimitive( LPDIRECT3DDEVICE7 d3dDevice7, D3DPRIMITIVETYPE d3dptPrimitiveType, ULONG dwVertexTypeDesc, PVOID pvVertices, ULONG dwVertexCount, PUSHORT pwIndices, ULONG dwIndexCount, ULONG dwFlags) { PSTR pszPrimitiveData; PSTR pszErrorMessage; HRESULT hResult; pszPrimitiveData = GetDrawIndexedPrimitiveData( d3dptPrimitiveType, dwVertexTypeDesc, pvVertices, dwVertexCount, pwIndices, dwIndexCount, dwFlags); InternalFunctionSpew("GameOS_Direct3D", "DrawIndexedPrimitive( %s)", pszPrimitiveData); hResult = d3dDevice7->DrawIndexedPrimitive( d3dptPrimitiveType, dwVertexTypeDesc, pvVertices, dwVertexCount, pwIndices, dwIndexCount, dwFlags); if (FAILED(hResult)) { if ( hResult != DDERR_SURFACELOST) { pszPrimitiveData = GetDrawIndexedPrimitiveData( d3dptPrimitiveType, dwVertexTypeDesc, pvVertices, dwVertexCount, pwIndices, dwIndexCount, dwFlags); pszErrorMessage = ErrorNumberToMessage(hResult); if ( InternalFunctionPause("FAILED (0x%x - %s) - DrawIndexedPrimitive( %s)", hResult, pszErrorMessage, pszPrimitiveData) ) ENTER_DEBUGGER; } } return hResult; }
//----------------------------------------------------------------------------- float CExplosion::Render(LPDIRECT3DDEVICE7 device) { if (this->key > 1) return 0; SETALPHABLEND(device, TRUE); SETZWRITE(device, FALSE); device->SetRenderState(D3DRENDERSTATE_SRCBLEND, D3DBLEND_ONE); device->SetRenderState(D3DRENDERSTATE_DESTBLEND, D3DBLEND_ONE); //calcul du disque D3DTLVERTEX d3dvs, *d3dv; EERIE_3D * vertex; int nb, col, col2; float rin; switch (key) { case 0: rin = 255.f * scale; vertex = disquevertex; d3dv = disqued3d; nb = disquenbvertex >> 1; while (nb) { d3dvs.sx = pos.x + (vertex + 1)->x + ((vertex->x - (vertex + 1)->x) * scale); d3dvs.sy = pos.y; d3dvs.sz = pos.z + (vertex + 1)->z + ((vertex->z - (vertex + 1)->z) * scale); EE_RTP(&d3dvs, d3dv); d3dv->color = RGBA_MAKE(255, 200, 0, 255); vertex++; d3dv++; d3dvs.sx = pos.x + vertex->x; d3dvs.sy = pos.y; d3dvs.sz = pos.z + vertex->z; EE_RTP(&d3dvs, d3dv); if (!ARXPausedTimer) d3dv->color = RGBA_MAKE((int)(rin * rnd()), 0, 0, 255); vertex++; d3dv++; nb--; } if (rnd() > .25f) { int j = ARX_PARTICLES_GetFree(); if ((j != -1) && (!ARXPausedTimer)) { ParticleCount++; particle[j].exist = 1; particle[j].zdec = 0; float a = DEG2RAD(360.f * scale); float b = rin; particle[j].ov.x = pos.x + b * EEcos(a); particle[j].ov.y = pos.y; particle[j].ov.z = pos.z + b * EEsin(a); particle[j].move.x = 0.f; particle[j].move.y = rnd(); particle[j].move.z = 0.f; particle[j].siz = 10.f + 10.f * rnd(); particle[j].tolive = 500 + (unsigned long)(float)(rnd() * 500.f); particle[j].scale.x = 1.f; particle[j].scale.y = 1.f; particle[j].scale.z = 1.f; particle[j].timcreation = lARXTime; particle[j].tc = tp; particle[j].special = FADE_IN_AND_OUT | ROTATING | MODULATE_ROTATION | DISSIPATING; particle[j].fparam = 0.0000001f; particle[j].r = 1.f; particle[j].g = 1.f; particle[j].b = 1.f; } j = ARX_PARTICLES_GetFree(); if ((j != -1) && (!ARXPausedTimer)) { ParticleCount++; particle[j].exist = 1; particle[j].zdec = 0; float a = DEG2RAD(-360.f * scale); float b = this->rin; particle[j].ov.x = pos.x + b * EEcos(a); particle[j].ov.y = pos.y; particle[j].ov.z = pos.z + b * EEsin(a); particle[j].move.x = 0.f; particle[j].move.y = rnd(); particle[j].move.z = 0.f; particle[j].siz = 10.f + 10.f * rnd(); particle[j].tolive = 500 + (unsigned long)(float)(rnd() * 500.f); particle[j].scale.x = 1.f; particle[j].scale.y = 1.f; particle[j].scale.z = 1.f; particle[j].timcreation = lARXTime; particle[j].tc = tp; particle[j].special = FADE_IN_AND_OUT | ROTATING | MODULATE_ROTATION | DISSIPATING; particle[j].fparam = 0.0000001f; particle[j].r = 1.f; particle[j].g = 1.f; particle[j].b = 1.f; } } if (rnd() > .1f) { int j = ARX_PARTICLES_GetFree(); if ((j != -1) && (!ARXPausedTimer)) { ParticleCount++; particle[j].exist = 1; particle[j].zdec = 0; float a = rnd() * 360.f; float b = rin * rnd(); particle[j].ov.x = pos.x + b * EEcos(a); particle[j].ov.y = pos.y + 70.f; particle[j].ov.z = pos.z + b * EEsin(a); particle[j].move.x = 0.f; particle[j].move.y = -(5.f + 10.f * rnd()); particle[j].move.z = 0.f; particle[j].siz = 10.f + 20.f * rnd(); particle[j].tolive = 1000 + (unsigned long)(float)(rnd() * 1000.f); particle[j].scale.x = 1.f; particle[j].scale.y = 1.f; particle[j].scale.z = 1.f; particle[j].timcreation = lARXTime; particle[j].tc = tp2; particle[j].special = FADE_IN_AND_OUT | ROTATING | MODULATE_ROTATION | DISSIPATING; particle[j].fparam = 0.0000001f; particle[j].r = 1.f; particle[j].g = 1.f; particle[j].b = 1.f; } } break; case 1: D3DTLVERTEX d3dvs2; rin = 1.f + (puissance * scale); vertex = disquevertex; d3dv = disqued3d; nb = disquenbvertex >> 1; float a = 1.f - scale; col = RGBA_MAKE((int)(255.f * a), (int)(200.f * a), 0, 255); col2 = RGBA_MAKE((int)(255.f * a * rnd()), 0, 0, 0); while (nb--) { d3dvs.sx = pos.x + vertex->x * rin; d3dvs.sy = pos.y; d3dvs.sz = pos.z + vertex->z * rin; vertex++; d3dvs2.sx = pos.x + vertex->x * rin; d3dvs2.sy = pos.y; d3dvs2.sz = pos.z + vertex->z * rin; vertex++; if (tactif[nb] >= 0) { EERIE_3D pos, dir; pos.x = d3dvs2.sx; pos.y = d3dvs2.sy; pos.z = d3dvs2.sz; dir.x = d3dvs.sx; dir.y = d3dvs.sy; dir.z = d3dvs.sz; DynLight[tactif[nb]].pos.x = dir.x; DynLight[tactif[nb]].pos.y = dir.y; DynLight[tactif[nb]].pos.z = dir.z; DynLight[tactif[nb]].intensity = .7f + 2.f * rnd(); Collision(nb, &pos, &dir); ExplosionAddParticule(nb, &d3dvs, tp); } EE_RTP(&d3dvs, d3dv); if (!ARXPausedTimer) d3dv->color = col; d3dv++; EE_RTP(&d3dvs2, d3dv); if (!ARXPausedTimer) d3dv->color = col2; d3dv++; } break; } //tracé du disque SETCULL(device, D3DCULL_NONE); device->SetTexture(0, NULL); device->DrawIndexedPrimitive(D3DPT_TRIANGLESTRIP, D3DFVF_TLVERTEX, disqued3d, disquenbvertex, (unsigned short *)disqueind, disquenbvertex + 2, 0); device->SetRenderState(D3DRENDERSTATE_SRCBLEND, D3DBLEND_ONE); device->SetRenderState(D3DRENDERSTATE_DESTBLEND, D3DBLEND_ZERO); SETALPHABLEND(device, FALSE); SETZWRITE(device, TRUE); return 0; }
/*--------------------------------------------------------------------------*/ float CPortal::Render(LPDIRECT3DDEVICE7 device) { SETALPHABLEND(device, TRUE); SETZWRITE(device, FALSE); device->SetRenderState(D3DRENDERSTATE_SRCBLEND, D3DBLEND_ONE); device->SetRenderState(D3DRENDERSTATE_DESTBLEND, D3DBLEND_ONE); //calcul sphere int nb = this->spherenbpt; D3DTLVERTEX * v = this->sphered3d, d3dvs; EERIE_3D * pt = this->spherevertex; int col = RGBA_MAKE(0, (int)(200.f * this->spherealpha), (int)(255.f * this->spherealpha), 255); while (nb) { d3dvs.sx = pt->x + this->pos.x; //pt du bas d3dvs.sy = pt->y + this->pos.y; d3dvs.sz = pt->z + this->pos.z; EE_RTP(&d3dvs, v); if (!ARXPausedTimer) v->color = col; v++; pt++; nb--; } //update les couleurs aux impacts nb = 256; while (nb--) { if (this->tabeclair[nb].actif) { float a; a = 1.f - ((float)this->tabeclair[nb].currduration / (float)this->tabeclair[nb].duration); if (a < 0.f) a = 0.f; if (this->tabeclair[nb].numpt >= 0) { int r = (int)((0.f + (255.f - 0.f) * a) * this->spherealpha * 3.f); if (r > 255) r = 255; int g = (int)((200.f + (255.f - 200.f) * a) * this->spherealpha * 3.f); if (g > 255) g = 255; int b = (int)(255.f * this->spherealpha * 3.f); if (b > 255) b = 255; if (!ARXPausedTimer) this->sphered3d[this->tabeclair[nb].numpt].color = RGBA_MAKE(r, g, b, 255); } } } //affichage de la sphere back SETCULL(device, D3DCULL_CW); device->SetTexture(0, NULL); device->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, D3DFVF_TLVERTEX, this->sphered3d, this->spherenbpt, (unsigned short *)this->sphereind, this->spherenbfaces * 3, 0); //affichage eclair this->DrawAllEclair(device); //affichage des particules à l'interieur if (rnd() > .25f) { int j = ARX_PARTICLES_GetFree(); if ((j != -1) && (!ARXPausedTimer)) { ParticleCount++; particle[j].exist = 1; particle[j].zdec = 0; float a = rnd() * 360.f; float b = rnd() * 360.f; float rr = this->r * (rnd() + .25f) * 0.05f; particle[j].ov.x = this->pos.x; particle[j].ov.y = this->pos.y; particle[j].ov.z = this->pos.z; particle[j].move.x = rr * EEsin(DEG2RAD(a)) * EEcos(DEG2RAD(b)); particle[j].move.y = rr * EEcos(DEG2RAD(a)); particle[j].move.z = rr * EEsin(DEG2RAD(a)) * EEsin(DEG2RAD(b)); particle[j].siz = 10.f; particle[j].tolive = 1000 + (unsigned long)(float)(rnd() * 1000.f); particle[j].scale.x = 1.f; particle[j].scale.y = 1.f; particle[j].scale.z = 1.f; particle[j].timcreation = lARXTime; particle[j].tc = tp; particle[j].special = FADE_IN_AND_OUT | ROTATING | MODULATE_ROTATION | DISSIPATING; particle[j].fparam = 0.0000001f; particle[j].r = 1.f; particle[j].g = 1.f; particle[j].b = 1.f; } } //affichage de la sphere front SETCULL(device, D3DCULL_CCW); device->SetTexture(0, NULL); device->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, D3DFVF_TLVERTEX, this->sphered3d, this->spherenbpt, (unsigned short *)this->sphereind, this->spherenbfaces * 3, 0); device->SetRenderState(D3DRENDERSTATE_SRCBLEND, D3DBLEND_ONE); device->SetRenderState(D3DRENDERSTATE_DESTBLEND, D3DBLEND_ZERO); SETALPHABLEND(device, FALSE); SETCULL(device, D3DCULL_NONE); SETZWRITE(device, TRUE); return 0; }