/* =========================================================================== ARX FATALIS GPL Source Code Copyright (C) 1999-2010 Arkane Studios SA, a ZeniMax Media company. This file is part of the Arx Fatalis GPL Source Code ('Arx Fatalis Source Code'). Arx Fatalis Source Code is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. Arx Fatalis Source Code is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Arx Fatalis Source Code. If not, see . In addition, the Arx Fatalis Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Arx Fatalis Source Code. If not, please request a copy in writing from Arkane Studios at the address below. If you have questions concerning this license or the applicable additional terms, you may contact in writing Arkane Studios, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA. =========================================================================== */ ////////////////////////////////////////////////////////////////////////////////////// // @@ @@@ @@@ @@ @@@@@ // // @@@ @@@@@@ @@@ @@ @@@@ @@@ @@@ // // @@@ @@@@@@@ @@@ @@@@ @@@@ @@ @@@@ // // @@@ @@ @@@@ @@@ @@@@@ @@@@@@ @@@ @@@ // // @@@@@ @@ @@@@ @@@ @@@@@ @@@@@@@ @@@ @ @@@ // // @@@@@ @@ @@@@ @@@@@@@@ @@@@ @@@ @@@@@ @@ @@@@@@@ // // @@ @@@ @@ @@@@ @@@@@@@ @@@ @@@ @@@@@@ @@ @@@@ // // @@@ @@@ @@@ @@@@ @@@@@ @@@@@@@@@ @@@@@@@ @@@ @@@@ // // @@@ @@@@ @@@@@@@ @@@@@@ @@@ @@@@ @@@ @@@ @@@ @@@@ // // @@@@@@@@ @@@@@ @@@@@@@@@@ @@@ @@@ @@@ @@@ @@@ @@@@@ // // @@@ @@@@ @@@@ @@@ @@@@@@@ @@@ @@@ @@@@ @@@ @@@@ @@@@@ // //@@@ @@@@ @@@@@ @@@ @@@@@@ @@ @@@ @@@@ @@@@@@@ @@@@@ @@@@@ // //@@@ @@@@@ @@@@@ @@@@ @@@ @@ @@ @@@@ @@@@@@@ @@@@@@@@@ // //@@@ @@@@ @@@@@@@ @@@@ @@ @@ @@@@ @@@@@ @@@@@ // //@@@ @@@@ @@@@@@@ @@@@ @@ @@ @@@@ @@@@@ @@ // //@@@ @@@ @@@ @@@@@ @@ @@@ // // @@@ @@@ @@ @@ STUDIOS // ////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////// // ARX_Scene ////////////////////////////////////////////////////////////////////////////////////// // // Description: // ARX Scene Management // // Updates: (date) (person) (update) // // Code: Cyril Meynier // // Copyright (c) 1999-2000 ARKANE Studios SA. All rights reserved ////////////////////////////////////////////////////////////////////////////////////// #include "ARX_Scene.h" #include "ARX_Spells.h" #include "ARX_Sound.h" #include "ARX_Particles.h" #include "ARX_Draw.h" #include "ARX_player.h" #include "ARX_paths.h" #include "ARX_interface.h" #include "ARX_time.h" #include "ARX_HWTransform.h" #include "ARX_menu2.h" #include #include #include #include #include #include #define DIRECTINPUT_VERSION 0x0700 #include #include #define _CRTDBG_MAP_ALLOC #include extern long USE_LIGHT_OPTIM; using namespace std; //----------------------------------------------------------------------------- #define MAX_OUT 4 #define VAL_THRESHOLD 100.f #define PASSS 0.5f #define PASS 50.f #define MAX_DIST_BUMP (400.f) //----------------------------------------------------------------------------- extern HANDLE LIGHTTHREAD; extern EERIE_3DOBJ * eyeballobj; extern long NEED_TEST_TEXT; extern long DEBUGCODE; extern long VF_CLIP_IO; extern long DEBUG_FRUSTRUM; extern long HIDEANCHORS; extern long EXTERNALVIEW; extern long USE_D3DFOG; extern long WATERFX; extern long REFLECTFX; extern bool ARXPausedTimer; extern bool bUSE_D3DFOG_INTER; long LAST_PORTALS_COUNT=0; //----------------------------------------------------------------------------- extern TextureContainer *enviro; extern long ZMAPMODE; extern bool bRenderInterList; extern bool bALLOW_BUMP; extern unsigned long ulBKGColor; extern float fZFogStartWorld; extern float fZFogEndWorld; extern CDirectInput *pGetInfoDirectInput; extern CMenuConfig *pMenuConfig; //----------------------------------------------------------------------------- EERIEPOLY VF_Center; EERIEPOLY VF_Top; EERIEPOLY VF_Bottom; EERIEPOLY VF_Front; EERIEPOLY * TransPol[MAX_TRANSPOL]; D3DTLVERTEX InterTransPol[MAX_INTERTRANSPOL][4]; EERIE_FACE * InterTransFace[MAX_INTERTRANSPOL]; TextureContainer * InterTransTC[MAX_INTERTRANSPOL]; float WATEREFFECT=0.f; long INTERTRANSPOLYSPOS=0; long TRANSPOLYSPOS=0; long D3DTRANSFORM=0; long SHOWSHADOWS=1; long TESTMODE=1; long FRAME_COUNT=0; long LAST_ROOM=-1; float fZFogStart=0.3f; float fZFogEnd=.5f; long iTotPoly; unsigned long FrameCount; CMY_DYNAMIC_VERTEXBUFFER *pDynamicVertexBuffer; CMY_DYNAMIC_VERTEXBUFFER *pDynamicVertexBufferBump; // VB based on pDynamicVertexBuffer (for BUMP only). CMY_DYNAMIC_VERTEXBUFFER *pDynamicVertexBufferTransform; CMY_DYNAMIC_VERTEXBUFFER *pDynamicVertexBuffer_TLVERTEX; // VB using TLVERTEX format. CMY_DYNAMIC_VERTEXBUFFER *pDynamicVertexBuffer_D3DVERTEX3_T;// VB using D3DVERTEX3_T format (for BUMP). EERIE_FRUSTRUM_PLANE efpPlaneNear; EERIE_FRUSTRUM_PLANE efpPlaneFar; vector vPolyWater; vector vPolyLava; vector vPolyVoodooMetal; bool bOLD_CLIPP=false; void PopAllTriangleListTransparency(); extern long TSU_TEST; extern bool bGATI8500; extern bool bSoftRender; //----------------------------------------------------------------------------- CMY_DYNAMIC_VERTEXBUFFER::CMY_DYNAMIC_VERTEXBUFFER(unsigned short _ussMaxVertex,unsigned long _uslFormat) { uslFormat=_uslFormat; ussMaxVertex=_ussMaxVertex; ussNbVertex=0; ussNbIndice=0; D3DVERTEXBUFFERDESC d3dvbufferdesc; d3dvbufferdesc.dwSize=sizeof(D3DVERTEXBUFFERDESC); int iFlag=D3DVBCAPS_WRITEONLY; if(!(danaeApp.m_pDeviceInfo->ddDeviceDesc.dwDevCaps&D3DDEVCAPS_HWTRANSFORMANDLIGHT)) { iFlag|=D3DVBCAPS_SYSTEMMEMORY; } d3dvbufferdesc.dwCaps=iFlag; d3dvbufferdesc.dwFVF=uslFormat; d3dvbufferdesc.dwNumVertices=ussMaxVertex; pVertexBuffer=NULL; danaeApp.m_pD3D->CreateVertexBuffer( &d3dvbufferdesc, &pVertexBuffer, 0); pussIndice=(unsigned short*)malloc(ussMaxVertex*4*2); } //----------------------------------------------------------------------------- CMY_DYNAMIC_VERTEXBUFFER::~CMY_DYNAMIC_VERTEXBUFFER() { if(pVertexBuffer) pVertexBuffer->Release(); if(pussIndice) free((void*)pussIndice); } //----------------------------------------------------------------------------- void* CMY_DYNAMIC_VERTEXBUFFER::Lock(unsigned int uiFlag) { void *pVertex; if(FAILED(pVertexBuffer->Lock( DDLOCK_WRITEONLY|uiFlag, &pVertex , NULL ) ) ) { return NULL; } return pVertex; } //----------------------------------------------------------------------------- bool CMY_DYNAMIC_VERTEXBUFFER::UnLock() { pVertexBuffer->Unlock(); return true; } //----------------------------------------------------------------------------- void PopOneTriangleListClipp(D3DTLVERTEX *_pVertex,int *_piNbVertex) { D3DTLVERTEX *pD3DVertex=_pVertex; while(*_piNbVertex) { int iOldNbVertex=pDynamicVertexBufferTransform->ussNbVertex; pDynamicVertexBufferTransform->ussNbIndice=0; SMY_D3DVERTEX *pVertex; int iMin = min(*_piNbVertex,pDynamicVertexBufferTransform->ussMaxVertex); ARX_CHECK_USHORT(iMin); unsigned short iNbVertex=ARX_CLEAN_WARN_CAST_USHORT(iMin); pDynamicVertexBufferTransform->ussNbVertex+=iNbVertex; if(pDynamicVertexBufferTransform->ussNbVertex>=pDynamicVertexBufferTransform->ussMaxVertex) { pVertex=(SMY_D3DVERTEX*)pDynamicVertexBufferTransform->Lock(DDLOCK_DISCARDCONTENTS); pDynamicVertexBufferTransform->ussNbVertex=iNbVertex; iOldNbVertex=0; } else { pVertex=(SMY_D3DVERTEX*)pDynamicVertexBufferTransform->Lock(DDLOCK_NOOVERWRITE); pVertex+=iOldNbVertex; } *_piNbVertex-=iNbVertex; iNbVertex/=3; while(iNbVertex--) { pVertex->x=pD3DVertex->sx; pVertex->y=-pD3DVertex->sy; pVertex->z=pD3DVertex->sz; pVertex->color=pD3DVertex->color; pVertex->tu=pD3DVertex->tu; pVertex->tv=pD3DVertex->tv; pVertex++; pD3DVertex++; pVertex->x=pD3DVertex->sx; pVertex->y=-pD3DVertex->sy; pVertex->z=pD3DVertex->sz; pVertex->color=pD3DVertex->color; pVertex->tu=pD3DVertex->tu; pVertex->tv=pD3DVertex->tv; pVertex++; pD3DVertex++; pVertex->x=pD3DVertex->sx; pVertex->y=-pD3DVertex->sy; pVertex->z=pD3DVertex->sz; pVertex->color=pD3DVertex->color; pVertex->tu=pD3DVertex->tu; pVertex->tv=pD3DVertex->tv; pVertex++; pD3DVertex++; } pDynamicVertexBufferTransform->UnLock(); GDevice->DrawPrimitiveVB( D3DPT_TRIANGLELIST, pDynamicVertexBufferTransform->pVertexBuffer, iOldNbVertex, pDynamicVertexBufferTransform->ussNbVertex-iOldNbVertex, 0 ); } } //------------------------------------------------------------------------------ // This function will use appropriate VB depending on vertex format. (using template) /************************************************************************/ /* HRESULT ARX_DrawPrimitiveVB( * LPDIRECT3DDEVICE7 _d3dDevice, : pointer to the DX7 device * D3DPRIMITIVETYPE _dptPrimitiveType, : primitive type to draw * DWORD _dwVertexTypeDesc : vertex format. * _LPVERTEX_ _pVertex, : pointer to the first vertex to render * int* _piNbVertex, : number of vertices to render (must be positive) * DWORD _dwFlags : optionally flag for DrawPrimitiveVB. * CMY_DYNAMIC_VERTEXBUFFER* _pDynamicVB : mandatory : dynamicVertexBuffer to use for rendering. * * @return S_OK if function exit correctly. /************************************************************************/ template __declspec(dllexport) HRESULT ARX_DrawPrimitiveVB( LPDIRECT3DDEVICE7 _d3dDevice, D3DPRIMITIVETYPE _dptPrimitiveType, DWORD _dwVertexTypeDesc, _LPVERTEX_ _pVertex, int* _piNbVertex, DWORD _dwFlags, CMY_DYNAMIC_VERTEXBUFFER* _pDynamicVB) { _LPVERTEX_ pD3DVertex = _pVertex; HRESULT h_result = S_OK; CMY_DYNAMIC_VERTEXBUFFER* pDVB = _pDynamicVB; ARX_CHECK( pDVB ); while( *_piNbVertex ) { _LPVERTEX_ pVertex = NULL; int iOldNbVertex = pDVB->ussNbVertex; pDVB->ussNbIndice = 0; unsigned short iNbVertex = (unsigned short) min( *_piNbVertex, pDVB->ussMaxVertex ); //don't overload VB pDVB->ussNbVertex += iNbVertex; if( pDVB->ussNbVertex >= pDVB->ussMaxVertex ) { pVertex = (_LPVERTEX_)pDVB->Lock( DDLOCK_DISCARDCONTENTS ); pDVB->ussNbVertex = iNbVertex; iOldNbVertex = 0; } else { pVertex = (_LPVERTEX_)pDVB->Lock( DDLOCK_NOOVERWRITE ); pVertex += iOldNbVertex; } *_piNbVertex -= iNbVertex; if( D3DPT_TRIANGLELIST == _dptPrimitiveType ) { iNbVertex /= 3; while( iNbVertex-- ) { (*pVertex++) = (*pD3DVertex++); //structure copy (3 times) (*pVertex++) = (*pD3DVertex++); (*pVertex++) = (*pD3DVertex++); } } else { (*pVertex++) = (*pD3DVertex++); //structure copy } pDVB->UnLock(); HRESULT h_resultDPVB = _d3dDevice->DrawPrimitiveVB( _dptPrimitiveType, pDVB->pVertexBuffer, iOldNbVertex, pDVB->ussNbVertex - iOldNbVertex, _dwFlags ); if( h_resultDPVB != S_OK ) h_result = h_resultDPVB; //Getting last error for return in case of bad DrawPrimitiveVB result } return h_result; } //------------------------------------------------------------------------------ // Add function manager to call template-function. /************************************************************************/ /* HRESULT ARX_DrawPrimitiveVB( * LPDIRECT3DDEVICE7 _d3dDevice, : pointer to the DX7 device * D3DPRIMITIVETYPE _dptPrimitiveType, : primitive type to draw * DWORD _dwVertexTypeDesc : vertex format. * LPVOID _pVertex, : pointer to the first vertex to render * int* _piNbVertex, : number of vertices to render (must be positive) * DWORD _dwFlags ) : optionally flag for DrawPrimitiveVB. * * @return S_OK if function exit correctly. /************************************************************************/ HRESULT ARX_DrawPrimitiveVB( LPDIRECT3DDEVICE7 _d3dDevice, D3DPRIMITIVETYPE _dptPrimitiveType, DWORD _dwVertexTypeDesc, LPVOID _pVertex, int* _piNbVertex, DWORD _dwFlags ) { HRESULT h_result = S_FALSE; if( _pVertex ) { switch( _dwVertexTypeDesc ) { case FVF_D3DVERTEX: h_result = ARX_DrawPrimitiveVB( _d3dDevice, _dptPrimitiveType, _dwVertexTypeDesc, (SMY_D3DVERTEX*) _pVertex, _piNbVertex, _dwFlags, pDynamicVertexBufferTransform); break; case D3DFVF_TLVERTEX: h_result = ARX_DrawPrimitiveVB( _d3dDevice, _dptPrimitiveType, _dwVertexTypeDesc, (D3DTLVERTEX*) _pVertex, _piNbVertex, _dwFlags, pDynamicVertexBuffer_TLVERTEX); break; case FVF_D3DVERTEX3: h_result = ARX_DrawPrimitiveVB( _d3dDevice, _dptPrimitiveType, _dwVertexTypeDesc, (SMY_D3DVERTEX3*) _pVertex, _piNbVertex, _dwFlags, pDynamicVertexBuffer); break; case FVF_D3DVERTEX3_T: h_result = ARX_DrawPrimitiveVB( _d3dDevice, _dptPrimitiveType, _dwVertexTypeDesc, (SMY_D3DVERTEX3_T*) _pVertex, _piNbVertex, _dwFlags, pDynamicVertexBuffer_D3DVERTEX3_T); break; default: ARX_LOG_ERROR("FVF is not supported by ARX_DrawPrimitiveVB"); ARX_CHECK(false && "FVF is not supported by ARX_DrawPrimitiveVB"); } } return h_result; } //************************************************************************************* //************************************************************************************* void ApplyWaterFXToVertex(EERIE_3D * odtv,D3DTLVERTEX * dtv,float power) { power=power*0.05f; dtv->tu+=EEsin((WATEREFFECT+odtv->x))*power; dtv->tv+=EEcos((WATEREFFECT+odtv->z))*power; } void ApplyLavaGlowToVertex(EERIE_3D * odtv,D3DTLVERTEX * dtv,float power) { register float f; register long lr,lg,lb; power=1.f-(EEsin((WATEREFFECT+odtv->x+odtv->z))*0.05f)*power; f=(float)(long)((dtv->color>>16) & 255)*power; F2L(f,&lr); lr=clipByte(lr); f=(float)(long)((dtv->color>>8) & 255)*power; F2L(f,&lg); lg=clipByte(lg); f=(float)(long)((dtv->color) & 255)*power; F2L(f,&lb); lb=clipByte(lb); dtv->color=0xFF000000L | (lr << 16) | (lg << 8) | lb; } void ComputeFogVertex(D3DTLVERTEX *v) { float VertexDist=1.f/v->rhw; if(VertexDistspecular=0xFF000000; } else { if(VertexDist>fZFogEndWorld) { v->specular=0; } else { //LINEAR float fDist=(fZFogEndWorld-VertexDist)*255.f/(fZFogEndWorld-fZFogStartWorld); long lAlpha; F2L(fDist,&lAlpha); v->specular=((lAlpha)<<24); } } } void ComputeSingleFogVertex(D3DTLVERTEX *v) { if(bUSE_D3DFOG_INTER) return; ComputeFogVertex(v); } void ComputeFog(D3DTLVERTEX * v, long to) { if(bUSE_D3DFOG_INTER) return; for (long k=0;ktype & POLY_WATER) || (ep->type & POLY_LAVA) ) { for (long k=0;ktv[k].tu=ep->v[k].tu; ep->tv[k].tv=ep->v[k].tv; if (ep->type & POLY_LAVA) { ApplyWaterFXToVertex((EERIE_3D *)&ep->v[k], &ep->tv[k], 0.35f); ApplyLavaGlowToVertex((EERIE_3D *)&ep->v[k],&ep->tv[k],0.6f); if (rnd()>0.995f) { if (ep->type & POLY_FALL) { EERIE_3D pos; pos.x=ep->v[k].sx+ep->norm.x*20.f; pos.y=ep->v[k].sy+ep->norm.y*20.f; pos.z=ep->v[k].sz+ep->norm.z*20.f; } } } else ApplyWaterFXToVertex((EERIE_3D *)&ep->v[k],&ep->tv[k],0.35f); } } if (ep->type & POLY_FALL) { if (ep->type & POLY_LAVA) for (long k=0;ktv[k].tv-=(float)(tim)*DIV12000; } else for (long k=0;ktv[k].tv-=(float)(tim)*DIV1000; } } } void ManageWater_VertexBuffer(EERIEPOLY * ep, const long to, const unsigned long tim,SMY_D3DVERTEX *_pVertex) { for (long k=0;ktv[k].tu=ep->v[k].tu; ep->tv[k].tv=ep->v[k].tv; ApplyWaterFXToVertex((EERIE_3D *)&ep->v[k],&ep->tv[k],0.35f); if(ep->type&POLY_FALL) { ep->tv[k].tv-=(float)(tim)*DIV1000; } _pVertex[ep->uslInd[k]].tu=ep->tv[k].tu; _pVertex[ep->uslInd[k]].tv=ep->tv[k].tv; } } void ManageLava_VertexBuffer(EERIEPOLY * ep, const long to, const unsigned long tim,SMY_D3DVERTEX *_pVertex) { for (long k=0;ktv[k].tu=ep->v[k].tu; ep->tv[k].tv=ep->v[k].tv; ApplyWaterFXToVertex((EERIE_3D *)&ep->v[k],&ep->tv[k],0.35f); //0.25f ApplyLavaGlowToVertex((EERIE_3D *)&ep->v[k],&ep->tv[k],0.6f); if(ep->type&POLY_FALL) { ep->tv[k].tv-=(float)(tim)*DIV12000; } _pVertex[ep->uslInd[k]].tu=ep->tv[k].tu; _pVertex[ep->uslInd[k]].tv=ep->tv[k].tv; } } extern D3DMATRIX ProjectionMatrix; void specialEE_RTP2(D3DTLVERTEX *in,D3DTLVERTEX *out) { register EERIE_TRANSFORM * et=(EERIE_TRANSFORM *)&ACTIVECAM->transform; out->sx = in->sx - et->posx; out->sy = in->sy - et->posy; out->sz = in->sz - et->posz; register float temp =(out->sz*et->ycos) - (out->sx*et->ysin); out->sx = (out->sz*et->ysin) + (out->sx*et->ycos); out->sz = (out->sy*et->xsin) + (temp*et->xcos); out->sy = (out->sy*et->xcos) - (temp*et->xsin); float fZTemp = 1.f / out->sz; out->sz = fZTemp * ProjectionMatrix._33 + ProjectionMatrix._43; out->sx=out->sx*ProjectionMatrix._11*fZTemp+et->xmod; out->sy=out->sy*ProjectionMatrix._22*fZTemp+et->ymod; out->rhw=fZTemp; } __forceinline long EERIERTPPoly2(EERIEPOLY *ep) { specialEE_RTP2(&ep->v[0],&ep->tv[0]); specialEE_RTP2(&ep->v[1],&ep->tv[1]); specialEE_RTP2(&ep->v[2],&ep->tv[2]); if (ep->type & POLY_QUAD) specialEE_RTP2(&ep->v[3],&ep->tv[3]); else ep->tv[3].sz=1.f; if ((ep->tv[0].sz<=0.f) && (ep->tv[1].sz<=0.f) && (ep->tv[2].sz<=0.f) && (ep->tv[3].sz<=0.f) ) return 0; return 1; } BOOL IsSphereInFrustrum(float radius,EERIE_3D * point,EERIE_FRUSTRUM * frustrum); bool FrustrumsClipSphere(EERIE_FRUSTRUM_DATA * frustrums,EERIE_SPHERE * sphere) { float dists=sphere->origin.x*efpPlaneNear.a + sphere->origin.y*efpPlaneNear.b + sphere->origin.z*efpPlaneNear.c + efpPlaneNear.d; if (dists+sphere->radius>0) { for (long i=0;inb_frustrums;i++) { if (IsSphereInFrustrum(sphere->radius,(EERIE_3D *)&sphere->origin,&frustrums->frustrums[i])) return FALSE; } } return TRUE; } bool EEVisibleSphere(EERIE_3D * pos,float radius) { if (EEDistance3D(pos,&ACTIVECAM->pos)-radius>ACTIVECAM->cdepth*0.5f) return false; long room_num=ARX_PORTALS_GetRoomNumForPosition(pos); if (room_num>=0) { EERIE_SPHERE sphere; sphere.origin.x=pos->x; sphere.origin.y=pos->y; sphere.origin.z=pos->z; sphere.radius=radius; EERIE_FRUSTRUM_DATA * frustrums=&RoomDraw[room_num].frustrum; if (FrustrumsClipSphere(frustrums,&sphere)) return false; } return true; } bool VisibleSphere(float x,float y,float z,float radius) { EERIE_3D pos; pos.x=x; pos.y=y; pos.z=z; return EEVisibleSphere(&pos,radius); } BOOL IsInFrustrum(EERIE_3D * point,EERIE_FRUSTRUM * frustrum); BOOL IsBBoxInFrustrum(EERIE_3D_BBOX * bbox,EERIE_FRUSTRUM * frustrum) { EERIE_3D point; point.x=bbox->min.x; point.y=bbox->min.y; point.z=bbox->min.z; if (!IsInFrustrum(&point,frustrum)) { EERIE_3D point; point.x=bbox->max.x; point.y=bbox->min.y; point.z=bbox->min.z; if (!IsInFrustrum(&point,frustrum)) { EERIE_3D point; point.x=bbox->max.x; point.y=bbox->max.y; point.z=bbox->min.z; if (!IsInFrustrum(&point,frustrum)) { EERIE_3D point; point.x=bbox->min.x; point.y=bbox->max.y; point.z=bbox->min.z; if (!IsInFrustrum(&point,frustrum)) { EERIE_3D point; point.x=bbox->min.x; point.y=bbox->min.y; point.z=bbox->max.z; if (!IsInFrustrum(&point,frustrum)) { EERIE_3D point; point.x=bbox->max.x; point.y=bbox->min.y; point.z=bbox->max.z; if (!IsInFrustrum(&point,frustrum)) { EERIE_3D point; point.x=bbox->max.x; point.y=bbox->max.y; point.z=bbox->max.z; if (!IsInFrustrum(&point,frustrum)) { EERIE_3D point; point.x=bbox->min.x; point.y=bbox->max.y; point.z=bbox->max.z; if (!IsInFrustrum(&point,frustrum)) { return FALSE; } } } } } } } } return TRUE; } bool FrustrumsClipBBox3D(EERIE_FRUSTRUM_DATA * frustrums,EERIE_3D_BBOX * bbox) { for (long i=0;inb_frustrums;i++) { if (IsBBoxInFrustrum(bbox,&frustrums->frustrums[i])) return FALSE; } return FALSE; } PORTAL_ROOM_DRAW * RoomDraw=NULL; long NbRoomDraw=0; long * RoomDrawList=NULL; long NbRoomDrawList=0; long TotalRoomDrawList=0; BOOL ARX_SCENE_PORTAL_Basic_ClipIO(INTERACTIVE_OBJ * io) { if (EDITMODE) return FALSE; if (io==inter.iobj[0]) return FALSE; if ((io) && (io->ioflags & IO_FORCEDRAW)) return FALSE; if (USE_PORTALS && portals) { EERIE_3D posi; posi.x=io->pos.x; posi.y=io->pos.y-20; posi.z=io->pos.z; if (io->room_flags & 1) UpdateIORoom(io); long room_num = io->room; { if (room_num==-1) { posi.y=io->pos.y-120; room_num=ARX_PORTALS_GetRoomNumForPosition(&posi); } if ( (room_num>=0) && (RoomDraw) && (RoomDraw[room_num].count)) { switch (USE_PORTALS) { case 2: case 3: case 4: EERIE_SPHERE sphere; if (io->ioflags & IO_ITEM) { sphere.origin.x=io->pos.x; sphere.origin.y=io->pos.y-40.f; sphere.origin.z=io->pos.z; if (io->ioflags & IO_MOVABLE) sphere.radius=160.f; else sphere.radius = 75.f; } else if (io->ioflags & IO_FIX) { sphere.origin.x=io->pos.x; sphere.origin.y=io->pos.y-60.f; sphere.origin.z=io->pos.z; sphere.radius=340.f; } else if (io->ioflags & IO_NPC) { sphere.origin.x=io->pos.x; sphere.origin.y=io->pos.y-120.f; sphere.origin.z=io->pos.z; sphere.radius=120.f; } EERIE_FRUSTRUM_DATA * frustrums=&RoomDraw[room_num].frustrum; if (FrustrumsClipSphere(frustrums,&sphere)) { if (io) { io->bbox1.x=(short)-1; io->bbox2.x=(short)-1; io->bbox1.y=(short)-1; io->bbox2.y=(short)-1; } return TRUE; } } } else return FALSE; } } return FALSE; } //********************************************************************************************************************* // BOOL ARX_SCENE__PORTAL_ClipIO(INTERACTIVE_OBJ * io,EERIE_3DOBJ * eobj,EERIE_3D * position,EERIE_3D * bboxmin,EERIE_3D * bboxmax) //--------------------------------------------------------------------------------------------------------------------- // USAGE/FUNCTION // io can be NULL if io is valid io->bbox3D contains 3D world-bbox // bboxmin & bboxmax ARE in fact 2D-screen BBOXes using only (x,y). // RETURN: // return TRUE if IO cannot be seen, FALSE if visible //--------------------------------------------------------------------------------------------------------------------- // TODO: // Implement all Portal Methods // Return a reduced clipbox which can be used for polys clipping in the case of partial visibility //********************************************************************************************************************* BOOL ARX_SCENE_PORTAL_ClipIO(INTERACTIVE_OBJ * io,EERIE_3DOBJ * eobj,EERIE_3D * position,EERIE_3D * bboxmin,EERIE_3D * bboxmax) { if (EDITMODE) return FALSE; if (io==inter.iobj[0]) return FALSE; if ((io) && (io->ioflags & IO_FORCEDRAW)) return FALSE; if (USE_PORTALS && portals) { EERIE_3D posi; posi.x=position->x; posi.y=position->y-60; //20 posi.z=position->z; long room_num; if (io) { if (io->room_flags & 1) UpdateIORoom(io); room_num=io->room;// } else { room_num=ARX_PORTALS_GetRoomNumForPosition(&posi); } if (room_num==-1) { posi.y=position->y-120; room_num=ARX_PORTALS_GetRoomNumForPosition(&posi); } if ((room_num >= 0) && (RoomDraw)) { if (RoomDraw[room_num].count==0) { if (io) { io->bbox1.x=(short)-1; io->bbox2.x=(short)-1; io->bbox1.y=(short)-1; io->bbox2.y=(short)-1; } return TRUE; } switch (USE_PORTALS) { case 1: // 2D portal { EERIE_2D_BBOX * bbox=&RoomDraw[room_num].bbox; if ( bbox->min.x > BBOXMAX.x || BBOXMIN.x > bbox->max.x || bbox->min.y > BBOXMAX.y || BBOXMIN.y > bbox->max.y) { if (io) { io->bbox1.x=(short)-1; io->bbox2.x=(short)-1; io->bbox1.y=(short)-1; io->bbox2.y=(short)-1; } return TRUE; } } break; case 2: case 3: case 4: if (io) { EERIE_SPHERE sphere; sphere.origin.x=(io->bbox3D.min.x+io->bbox3D.max.x)*DIV2; sphere.origin.y=(io->bbox3D.min.y+io->bbox3D.max.y)*DIV2; sphere.origin.z=(io->bbox3D.min.z+io->bbox3D.max.z)*DIV2; sphere.radius=TRUEDistance3D(sphere.origin.x,sphere.origin.y,sphere.origin.z, io->bbox3D.min.x,io->bbox3D.min.y,io->bbox3D.min.z)+10.f; EERIE_FRUSTRUM_DATA * frustrums=&RoomDraw[room_num].frustrum; if (FrustrumsClipSphere(frustrums,&sphere)) { if (io) { io->bbox1.x=(short)-1; io->bbox2.x=(short)-1; io->bbox1.y=(short)-1; io->bbox2.y=(short)-1; } return TRUE; } if (FrustrumsClipBBox3D(frustrums,&io->bbox3D)) { if (io) { io->bbox1.x=(short)-1; io->bbox2.x=(short)-1; io->bbox1.y=(short)-1; io->bbox2.y=(short)-1; } return TRUE; } } break; } } } return FALSE; } long ARX_PORTALS_GetRoomNumForPosition2(EERIE_3D * pos,long flag,float * height) { EERIEPOLY * ep; if (flag & 1) { ep=CheckInPolyPrecis(pos->x,pos->y-150.f,pos->z); if (!ep) ep=CheckInPolyPrecis(pos->x,pos->y-1.f,pos->z); } else ep=CheckInPoly(pos->x,pos->y,pos->z); if ((ep) && (ep->room>-1)) { if (height) *height=ep->center.y; return ep->room; } // Security... ? ep=GetMinPoly(pos->x,pos->y,pos->z); if ((ep) && (ep->room>-1)) { if (height) *height=ep->center.y; return ep->room; } else if (!(flag & 1)) { ep=CheckInPolyPrecis(pos->x,pos->y,pos->z); if ((ep) && (ep->room>-1)) { if (height) *height=ep->center.y; return ep->room; } } if (flag & 2) { float off=20.f; ep=CheckInPolyPrecis(pos->x-off,pos->y-off,pos->z); if ((ep) && (ep->room>-1)) { if (height) *height=ep->center.y; return ep->room; } ep=CheckInPolyPrecis(pos->x-off,pos->y-20,pos->z-off); if ((ep) && (ep->room>-1)) { if (height) *height=ep->center.y; return ep->room; } ep=CheckInPolyPrecis(pos->x-off,pos->y-20,pos->z+off); if ((ep) && (ep->room>-1)) { if (height) *height=ep->center.y; return ep->room; } ep=CheckInPolyPrecis(pos->x+off,pos->y-20,pos->z); if ((ep) && (ep->room>-1)) { if (height) *height=ep->center.y; return ep->room; } ep=CheckInPolyPrecis(pos->x+off,pos->y-20,pos->z+off); if ((ep) && (ep->room>-1)) { if (height) *height=ep->center.y; return ep->room; } ep=CheckInPolyPrecis(pos->x+off,pos->y-20,pos->z-off); if ((ep) && (ep->room>-1)) { if (height) *height=ep->center.y; return ep->room; } } return -1; } long ARX_PORTALS_GetRoomNumForCamera(float * height) { EERIEPOLY * ep; ep=CheckInPolyPrecis(ACTIVECAM->pos.x,ACTIVECAM->pos.y,ACTIVECAM->pos.z); if ((ep) && (ep->room>-1)) { if (height) *height=ep->center.y; return ep->room; } ep=GetMinPoly(ACTIVECAM->pos.x,ACTIVECAM->pos.y,ACTIVECAM->pos.z); if ((ep) && (ep->room>-1)) { if (height) *height=ep->center.y; return ep->room; } float dist=0.f; while (dist<=20.f) { float vvv=DEG2RAD(ACTIVECAM->angle.b); ep=CheckInPolyPrecis( ACTIVECAM->pos.x+EEsin(vvv)*dist, ACTIVECAM->pos.y, ACTIVECAM->pos.z-EEcos(vvv)*dist); if ((ep) && (ep->room>-1)) { if (height) *height=ep->center.y; return ep->room; } dist+=5.f; } return -1; } // flag==1 for player long ARX_PORTALS_GetRoomNumForPosition(EERIE_3D * pos,long flag) { long num; float height; if (flag & 1) num=ARX_PORTALS_GetRoomNumForCamera(&height); else num=ARX_PORTALS_GetRoomNumForPosition2(pos,flag,&height); if (num > -1) { long nearest=-1; float nearest_dist=99999.f; for (long n=0;nnb_rooms;n++) { for (long lll=0;lllroom[n].nb_portals;lll++) { EERIE_PORTALS * po= &portals->portals[portals->room[n].portals[lll]]; EERIEPOLY * epp=&po->poly; if (PointIn2DPolyXZ(epp, pos->x, pos->z)) { float yy; if (GetTruePolyY(epp,pos,&yy)) { if (height>yy) { if ((yy>=pos->y) && (yy-pos->ynorm.y>0) nearest=po->room_2; else nearest=po->room_1; nearest_dist=yy-pos->y; } } } } } } if (nearest>-1) num=nearest; } return num; } void ARX_PORTALS_InitDrawnRooms() { if (!portals) return; EERIE_PORTALS *ep = &portals->portals[0]; for (long i=0;inb_total;i++) { ep->useportal=0; *ep++; } if ((RoomDraw==NULL) || (NbRoomDrawnb_rooms+1)) { RoomDraw=(PORTAL_ROOM_DRAW *)realloc(RoomDraw,sizeof(PORTAL_ROOM_DRAW)*(portals->nb_rooms+1)); if (RoomDraw) { NbRoomDraw=portals->nb_rooms+1; } } if (RoomDraw) { for (long i=0;iLock(DDLOCK_DISCARDCONTENTS); pDynamicVertexBuffer->UnLock(); pDynamicVertexBuffer->ussNbVertex=0; } if (pDynamicVertexBufferTransform) { pDynamicVertexBufferTransform->Lock(DDLOCK_DISCARDCONTENTS); pDynamicVertexBufferTransform->UnLock(); pDynamicVertexBufferTransform->ussNbVertex=0; } if (pDynamicVertexBuffer_TLVERTEX) { pDynamicVertexBuffer_TLVERTEX->Lock(DDLOCK_DISCARDCONTENTS); pDynamicVertexBuffer_TLVERTEX->UnLock(); pDynamicVertexBuffer_TLVERTEX->ussNbVertex=0; } if (pDynamicVertexBufferBump) { pDynamicVertexBufferBump->Lock(DDLOCK_DISCARDCONTENTS); pDynamicVertexBufferBump->UnLock(); pDynamicVertexBufferBump->ussNbVertex=0; } if (pDynamicVertexBuffer_D3DVERTEX3_T) { pDynamicVertexBuffer_D3DVERTEX3_T->Lock(DDLOCK_DISCARDCONTENTS); pDynamicVertexBuffer_D3DVERTEX3_T->UnLock(); pDynamicVertexBuffer_D3DVERTEX3_T->ussNbVertex=0; } } bool BBoxClipPoly(EERIE_2D_BBOX * bbox,EERIEPOLY * ep) { EERIE_2D_BBOX n_bbox; long nbv; if (ep->type & POLY_QUAD) nbv=4; else nbv=3; n_bbox.max.x=n_bbox.min.x=ep->tv[0].sx; n_bbox.max.y=n_bbox.min.y=ep->tv[0].sy; for (long i=1;itv[i].sx); n_bbox.min.y=__min(n_bbox.min.y , ep->tv[i].sy); n_bbox.max.x=__max(n_bbox.max.x , ep->tv[i].sx); n_bbox.max.y=__max(n_bbox.max.y , ep->tv[i].sy); } if ( bbox->min.x > n_bbox.max.x || n_bbox.min.x > bbox->max.x || bbox->min.y > n_bbox.max.y || n_bbox.min.y > bbox->max.y) return true; return false; } BOOL IsInFrustrum(EERIE_3D * point,EERIE_FRUSTRUM * frustrum) { if ( ((point->x*frustrum->plane[0].a + point->y*frustrum->plane[0].b + point->z*frustrum->plane[0].c + frustrum->plane[0].d)>0) && ((point->x*frustrum->plane[1].a + point->y*frustrum->plane[1].b + point->z*frustrum->plane[1].c + frustrum->plane[1].d)>0) && ((point->x*frustrum->plane[2].a + point->y*frustrum->plane[2].b + point->z*frustrum->plane[2].c + frustrum->plane[2].d)>0) && ((point->x*frustrum->plane[3].a + point->y*frustrum->plane[3].b + point->z*frustrum->plane[3].c + frustrum->plane[3].d)>0) ) return TRUE; return FALSE; } BOOL IsSphereInFrustrum(float radius,EERIE_3D * point,EERIE_FRUSTRUM * frustrum) { float dists[4]; dists[0]=point->x*frustrum->plane[0].a + point->y*frustrum->plane[0].b + point->z*frustrum->plane[0].c + frustrum->plane[0].d; dists[1]=point->x*frustrum->plane[1].a + point->y*frustrum->plane[1].b + point->z*frustrum->plane[1].c + frustrum->plane[1].d; dists[2]=point->x*frustrum->plane[2].a + point->y*frustrum->plane[2].b + point->z*frustrum->plane[2].c + frustrum->plane[2].d; dists[3]=point->x*frustrum->plane[3].a + point->y*frustrum->plane[3].b + point->z*frustrum->plane[3].c + frustrum->plane[3].d; if ( (dists[0]+radius>0) && (dists[1]+radius>0) && (dists[2]+radius>0) && (dists[3]+radius>0) ) return TRUE; return FALSE; } bool FrustrumsClipPoly(EERIE_FRUSTRUM_DATA * frustrums,EERIEPOLY * ep) { long nbv; if (ep->type & POLY_QUAD) nbv=4; else nbv=3; for (long i=0;inb_frustrums;i++) { if (IsSphereInFrustrum(ep->v[0].rhw,(EERIE_3D *)&ep->center,&frustrums->frustrums[i])) return FALSE; } return TRUE; } void ARX_PORTALS_BlendBBox(long room_num,EERIE_2D_BBOX * bbox) { if (RoomDraw[room_num].count==0) { RoomDraw[room_num].bbox.min.x=bbox->min.x; RoomDraw[room_num].bbox.min.y=bbox->min.y; RoomDraw[room_num].bbox.max.x=bbox->max.x; RoomDraw[room_num].bbox.max.y=bbox->max.y; } else { RoomDraw[room_num].bbox.min.x=__min(RoomDraw[room_num].bbox.min.x, bbox->min.x); RoomDraw[room_num].bbox.min.y=__min(RoomDraw[room_num].bbox.min.y, bbox->min.y); RoomDraw[room_num].bbox.max.x=__max(RoomDraw[room_num].bbox.max.x, bbox->max.x); RoomDraw[room_num].bbox.max.y=__max(RoomDraw[room_num].bbox.max.y, bbox->max.y); } } void Frustrum_Set(EERIE_FRUSTRUM * fr,long plane,float a,float b,float c,float d) { fr->plane[plane].a=a; fr->plane[plane].b=b; fr->plane[plane].c=c; fr->plane[plane].d=d; } void CreatePlane(EERIE_FRUSTRUM * frustrum,long numplane,EERIE_3D * orgn,EERIE_3D * pt1,EERIE_3D * pt2) { register float Ax,Ay,Az,Bx,By,Bz,epnlen; Ax=pt1->x-orgn->x; Ay=pt1->y-orgn->y; Az=pt1->z-orgn->z; Bx=pt2->x-orgn->x; By=pt2->y-orgn->y; Bz=pt2->z-orgn->z; frustrum->plane[numplane].a=Ay*Bz-Az*By; frustrum->plane[numplane].b=Az*Bx-Ax*Bz; frustrum->plane[numplane].c=Ax*By-Ay*Bx; epnlen = (float)sqrt( frustrum->plane[numplane].a * frustrum->plane[numplane].a + frustrum->plane[numplane].b * frustrum->plane[numplane].b + frustrum->plane[numplane].c * frustrum->plane[numplane].c ); epnlen=1.f/epnlen; frustrum->plane[numplane].a*=epnlen; frustrum->plane[numplane].b*=epnlen; frustrum->plane[numplane].c*=epnlen; frustrum->plane[numplane].d=-( orgn->x * frustrum->plane[numplane].a + orgn->y * frustrum->plane[numplane].b + orgn->z * frustrum->plane[numplane].c ); } void CreateScreenFrustrum(EERIE_FRUSTRUM * frustrum); void CreateFrustrum(EERIE_FRUSTRUM * frustrum,EERIEPOLY * ep,long cull) { long to; if (ep->type & POLY_QUAD) to=4; else to=3; if (cull) { CreatePlane(frustrum,0,&ACTIVECAM->pos,(EERIE_3D *)&ep->v[0],(EERIE_3D *)&ep->v[1]); CreatePlane(frustrum,1,&ACTIVECAM->pos,(EERIE_3D *)&ep->v[3],(EERIE_3D *)&ep->v[2]); CreatePlane(frustrum,2,&ACTIVECAM->pos,(EERIE_3D *)&ep->v[1],(EERIE_3D *)&ep->v[3]); CreatePlane(frustrum,3,&ACTIVECAM->pos,(EERIE_3D *)&ep->v[2],(EERIE_3D *)&ep->v[0]); } else { CreatePlane(frustrum,0,&ACTIVECAM->pos,(EERIE_3D *)&ep->v[1],(EERIE_3D *)&ep->v[0]); CreatePlane(frustrum,1,&ACTIVECAM->pos,(EERIE_3D *)&ep->v[2],(EERIE_3D *)&ep->v[3]); CreatePlane(frustrum,2,&ACTIVECAM->pos,(EERIE_3D *)&ep->v[3],(EERIE_3D *)&ep->v[1]); CreatePlane(frustrum,3,&ACTIVECAM->pos,(EERIE_3D *)&ep->v[0],(EERIE_3D *)&ep->v[2]); } frustrum->nb=to; } void CreateScreenFrustrum(EERIE_FRUSTRUM * frustrum) { D3DVECTOR vEyePt = D3DVECTOR( ACTIVECAM->pos.x , -ACTIVECAM->pos.y, ACTIVECAM->pos.z ); EERIE_3D target,tout; tout.x=0.f; tout.y=0.f; tout.z=10000.f; target.y =- (tout.z*ACTIVECAM->Xsin); target.z =-(tout.z*ACTIVECAM->Xcos); target.x= (target.z*ACTIVECAM->Ysin); target.z=-(target.z*ACTIVECAM->Ycos); target.x+=ACTIVECAM->pos.x; target.y-=ACTIVECAM->pos.y; target.z+=ACTIVECAM->pos.z; D3DVECTOR vLookatPt = D3DVECTOR(target.x,target.y,target.z); D3DVECTOR vUpVec = D3DVECTOR( 0.f, 1.f, 0.f ); // Set the app view matrix for normal viewing D3DMATRIX matView,matProj; D3DUtil_SetViewMatrix( matView, vEyePt, vLookatPt, vUpVec ); GDevice->SetTransform( D3DTRANSFORMSTATE_VIEW, &matView ); GDevice->GetTransform(D3DTRANSFORMSTATE_PROJECTION,&matProj); D3DMATRIX matres; MatrixMultiply((EERIEMATRIX *)&matres,(EERIEMATRIX *)&matView,(EERIEMATRIX *)&matProj); float a,b,c,d,n; a=matres._14-matres._11; b=matres._24-matres._21; c=matres._34-matres._31; d=matres._44-matres._41; b=-b; n = (float)(1.f /sqrt(a*a+b*b+c*c)); Frustrum_Set(frustrum,0,a*n,b*n,c*n,d*n); a=matres._14+matres._11; b=matres._24+matres._21; c=matres._34+matres._31; d=matres._44+matres._41; b=-b; n = (float)(1.f/sqrt(a*a+b*b+c*c)); Frustrum_Set(frustrum,1,a*n,b*n,c*n,d*n); a=matres._14-matres._12; b=matres._24-matres._22; c=matres._34-matres._32; d=matres._44-matres._42; b=-b; n = (float)(1.f/sqrt(a*a+b*b+c*c)); Frustrum_Set(frustrum,2,a*n,b*n,c*n,d*n); a=matres._14+matres._12; b=matres._24+matres._22; c=matres._34+matres._32; d=matres._44+matres._42; b=-b; n = (float)(1.f/sqrt(a*a+b*b+c*c)); Frustrum_Set(frustrum,3,a*n,b*n,c*n,d*n); frustrum->nb=4; //Ajout du plan Near & Far a=matres._14-matres._13; b=matres._24-matres._23; c=matres._34-matres._33; d=matres._44-matres._43; b=-b; n = (float)(1.f/sqrt(a*a+b*b+c*c)); efpPlaneFar.a=a*n; efpPlaneFar.b=b*n; efpPlaneFar.c=c*n; efpPlaneFar.d=d*n; a=matres._14+matres._13; b=matres._24+matres._23; c=matres._34+matres._33; d=matres._44+matres._43; b=-b; n = (float)(1.f/sqrt(a*a+b*b+c*c)); efpPlaneNear.a=a*n; efpPlaneNear.b=b*n; efpPlaneNear.c=c*n; efpPlaneNear.d=d*n; } void RoomDrawRelease() { if (RoomDrawList) free(RoomDrawList); RoomDrawList=NULL; if (RoomDraw) free(RoomDraw); RoomDraw=NULL; } void RoomDrawListAdd(long num) { if (TotalRoomDrawList<=NbRoomDrawList) { RoomDrawList=(long *)realloc(RoomDrawList,sizeof(long)*(NbRoomDrawList+1)); TotalRoomDrawList=NbRoomDrawList+1; } RoomDrawList[NbRoomDrawList]=num; NbRoomDrawList++; } void RoomFrustrumAdd(long num,EERIE_FRUSTRUM * fr) { if (RoomDraw[num].frustrum.nb_frustrumsSetRenderState(D3DRENDERSTATE_FOGCOLOR,0); GDevice->SetRenderState(D3DRENDERSTATE_ALPHABLENDENABLE,TRUE); SETCULL(GDevice,D3DCULL_NONE); SETZWRITE(GDevice,FALSE); for (long i=0;iwNbTextureSimultaneous>3) danaeApp.m_pDeviceInfo->wNbTextureSimultaneous=3; unsigned short iNbIndice = 0; int iNb=vPolyWater.size(); if(iNb) { int iOldNbVertex=pDynamicVertexBuffer->ussNbVertex; pDynamicVertexBuffer->ussNbIndice=0; SMY_D3DVERTEX3 *pVertex=(SMY_D3DVERTEX3*)pDynamicVertexBuffer->Lock(DDLOCK_NOOVERWRITE); pVertex+=iOldNbVertex; GDevice->SetRenderState( D3DRENDERSTATE_SRCBLEND, D3DBLEND_DESTCOLOR ); GDevice->SetRenderState( D3DRENDERSTATE_DESTBLEND, D3DBLEND_ONE ); SETTC(GDevice,enviro); int iNbTextureSim=danaeApp.m_pDeviceInfo->wNbTextureSimultaneous; switch(iNbTextureSim) { case 3: GDevice->SetTexture(2,enviro?enviro->m_pddsSurface?enviro->m_pddsSurface:NULL:NULL); case 2: GDevice->SetTexture(1,enviro?enviro->m_pddsSurface?enviro->m_pddsSurface:NULL:NULL); break; } unsigned short *pussInd=pDynamicVertexBuffer->pussIndice; while(iNb--) { EERIEPOLY *ep=vPolyWater[iNb]; unsigned short iNbVertex = (ep->type & POLY_QUAD) ? 4 : 3; pDynamicVertexBuffer->ussNbVertex += iNbVertex; if( pDynamicVertexBuffer->ussNbVertex > pDynamicVertexBuffer->ussMaxVertex ) { pDynamicVertexBuffer->UnLock(); pDynamicVertexBuffer->ussNbVertex-=iNbVertex; if(pDynamicVertexBuffer->ussNbIndice) { switch(iNbTextureSim) { case 1: GDevice->DrawIndexedPrimitiveVB( D3DPT_TRIANGLELIST, pDynamicVertexBuffer->pVertexBuffer, iOldNbVertex, pDynamicVertexBuffer->ussNbVertex-iOldNbVertex, pDynamicVertexBuffer->pussIndice, pDynamicVertexBuffer->ussNbIndice, 0 ); GDevice->SetTextureStageState(0,D3DTSS_TEXCOORDINDEX,1); GDevice->DrawIndexedPrimitiveVB( D3DPT_TRIANGLELIST, pDynamicVertexBuffer->pVertexBuffer, iOldNbVertex, pDynamicVertexBuffer->ussNbVertex-iOldNbVertex, pDynamicVertexBuffer->pussIndice, pDynamicVertexBuffer->ussNbIndice, 0 ); GDevice->SetTextureStageState(0,D3DTSS_TEXCOORDINDEX,2); GDevice->DrawIndexedPrimitiveVB( D3DPT_TRIANGLELIST, pDynamicVertexBuffer->pVertexBuffer, iOldNbVertex, pDynamicVertexBuffer->ussNbVertex-iOldNbVertex, pDynamicVertexBuffer->pussIndice, pDynamicVertexBuffer->ussNbIndice, 0 ); break; case 2: GDevice->SetTextureStageState(1,D3DTSS_TEXCOORDINDEX,1); GDevice->SetTextureStageState(1,D3DTSS_COLORARG1,D3DTA_TEXTURE); GDevice->SetTextureStageState(1,D3DTSS_COLORARG2,D3DTA_CURRENT); GDevice->SetTextureStageState(1,D3DTSS_COLOROP,D3DTOP_MODULATE4X); GDevice->SetTextureStageState(1,D3DTSS_ALPHAOP,D3DTOP_DISABLE); GDevice->SetTextureStageState(2,D3DTSS_COLOROP,D3DTOP_DISABLE); GDevice->DrawIndexedPrimitiveVB( D3DPT_TRIANGLELIST, pDynamicVertexBuffer->pVertexBuffer, iOldNbVertex, pDynamicVertexBuffer->ussNbVertex-iOldNbVertex, pDynamicVertexBuffer->pussIndice, pDynamicVertexBuffer->ussNbIndice, 0 ); GDevice->SetTextureStageState(0,D3DTSS_TEXCOORDINDEX,2); GDevice->SetTextureStageState(1,D3DTSS_COLOROP,D3DTOP_DISABLE); GDevice->DrawIndexedPrimitiveVB( D3DPT_TRIANGLELIST, pDynamicVertexBuffer->pVertexBuffer, iOldNbVertex, pDynamicVertexBuffer->ussNbVertex-iOldNbVertex, pDynamicVertexBuffer->pussIndice, pDynamicVertexBuffer->ussNbIndice, 0 ); break; case 3: GDevice->SetTextureStageState(1,D3DTSS_TEXCOORDINDEX,1); GDevice->SetTextureStageState(1,D3DTSS_COLORARG1,D3DTA_TEXTURE); GDevice->SetTextureStageState(1,D3DTSS_COLORARG2,D3DTA_CURRENT); GDevice->SetTextureStageState(1,D3DTSS_COLOROP,D3DTOP_MODULATE4X); GDevice->SetTextureStageState(1,D3DTSS_ALPHAOP,D3DTOP_DISABLE); GDevice->SetTextureStageState(2,D3DTSS_TEXCOORDINDEX,2); GDevice->SetTextureStageState(2,D3DTSS_COLORARG1,D3DTA_TEXTURE); GDevice->SetTextureStageState(2,D3DTSS_COLORARG2,D3DTA_CURRENT); GDevice->SetTextureStageState(2,D3DTSS_COLOROP,D3DTOP_MODULATE); GDevice->SetTextureStageState(2,D3DTSS_ALPHAOP,D3DTOP_DISABLE); GDevice->SetTextureStageState(3,D3DTSS_COLOROP,D3DTOP_DISABLE); GDevice->DrawIndexedPrimitiveVB( D3DPT_TRIANGLELIST, pDynamicVertexBuffer->pVertexBuffer, iOldNbVertex, pDynamicVertexBuffer->ussNbVertex-iOldNbVertex, pDynamicVertexBuffer->pussIndice, pDynamicVertexBuffer->ussNbIndice, 0 ); break; } GDevice->SetTextureStageState(0,D3DTSS_TEXCOORDINDEX,0); GDevice->SetTextureStageState(1,D3DTSS_COLOROP,D3DTOP_DISABLE); } pVertex=(SMY_D3DVERTEX3*)pDynamicVertexBuffer->Lock(DDLOCK_DISCARDCONTENTS); pDynamicVertexBuffer->ussNbVertex=iNbVertex; iOldNbVertex = iNbIndice = pDynamicVertexBuffer->ussNbIndice = 0; pussInd=pDynamicVertexBuffer->pussIndice; //iNbVertex = 3 or 4 but be sure to Assert in Debug if overflow ARX_CHECK( pDynamicVertexBuffer->ussNbVertex <= pDynamicVertexBuffer->ussMaxVertex ); } pVertex->x=ep->v[0].sx; pVertex->y=-ep->v[0].sy; pVertex->z=ep->v[0].sz; pVertex->color=0xFF505050; float fTu=ep->v[0].sx*DIV1000+EEsin((ep->v[0].sx)*DIV200+(float)FrameTime*DIV1000)*DIV32; float fTv=ep->v[0].sz*DIV1000+EEcos((ep->v[0].sz)*DIV200+(float)FrameTime*DIV1000)*DIV32; if(ep->type&POLY_FALL) fTv+=(float)FrameTime*DIV4000; pVertex->tu=fTu; pVertex->tv=fTv; fTu=(ep->v[0].sx+30.f)*DIV1000+EEsin((ep->v[0].sx+30)*DIV200+(float)FrameTime*DIV1000)*DIV28; fTv=(ep->v[0].sz+30.f)*DIV1000-EEcos((ep->v[0].sz+30)*DIV200+(float)FrameTime*DIV1000)*DIV28; if (ep->type & POLY_FALL) fTv+=(float)FrameTime*DIV4000; pVertex->tu2=fTu; pVertex->tv2=fTv; fTu=(ep->v[0].sx+60.f)*DIV1000-EEsin((ep->v[0].sx+60)*DIV200+(float)FrameTime*DIV1000)*DIV40; fTv=(ep->v[0].sz+60.f)*DIV1000-EEcos((ep->v[0].sz+60)*DIV200+(float)FrameTime*DIV1000)*DIV40; if (ep->type & POLY_FALL) fTv+=(float)FrameTime*DIV4000; pVertex->tu3=fTu; pVertex->tv3=fTv; pVertex++; pVertex->x=ep->v[1].sx; pVertex->y=-ep->v[1].sy; pVertex->z=ep->v[1].sz; pVertex->color=0xFF505050; fTu=ep->v[1].sx*DIV1000+EEsin((ep->v[1].sx)*DIV200+(float)FrameTime*DIV1000)*DIV32; fTv=ep->v[1].sz*DIV1000+EEcos((ep->v[1].sz)*DIV200+(float)FrameTime*DIV1000)*DIV32; if(ep->type&POLY_FALL) fTv+=(float)FrameTime*DIV4000; pVertex->tu=fTu; pVertex->tv=fTv; fTu=(ep->v[1].sx+30.f)*DIV1000+EEsin((ep->v[1].sx+30)*DIV200+(float)FrameTime*DIV1000)*DIV28; fTv=(ep->v[1].sz+30.f)*DIV1000-EEcos((ep->v[1].sz+30)*DIV200+(float)FrameTime*DIV1000)*DIV28; if (ep->type & POLY_FALL) fTv+=(float)FrameTime*DIV4000; pVertex->tu2=fTu; pVertex->tv2=fTv; fTu=(ep->v[1].sx+60.f)*DIV1000-EEsin((ep->v[1].sx+60)*DIV200+(float)FrameTime*DIV1000)*DIV40; fTv=(ep->v[1].sz+60.f)*DIV1000-EEcos((ep->v[1].sz+60)*DIV200+(float)FrameTime*DIV1000)*DIV40; if (ep->type & POLY_FALL) fTv+=(float)FrameTime*DIV4000; pVertex->tu3=fTu; pVertex->tv3=fTv; pVertex++; pVertex->x=ep->v[2].sx; pVertex->y=-ep->v[2].sy; pVertex->z=ep->v[2].sz; pVertex->color=0xFF505050; fTu=ep->v[2].sx*DIV1000+EEsin((ep->v[2].sx)*DIV200+(float)FrameTime*DIV1000)*DIV32; fTv=ep->v[2].sz*DIV1000+EEcos((ep->v[2].sz)*DIV200+(float)FrameTime*DIV1000)*DIV32; if(ep->type&POLY_FALL) fTv+=(float)FrameTime*DIV4000; pVertex->tu=fTu; pVertex->tv=fTv; fTu=(ep->v[2].sx+30.f)*DIV1000+EEsin((ep->v[2].sx+30)*DIV200+(float)FrameTime*DIV1000)*DIV28; fTv=(ep->v[2].sz+30.f)*DIV1000-EEcos((ep->v[2].sz+30)*DIV200+(float)FrameTime*DIV1000)*DIV28; if (ep->type & POLY_FALL) fTv+=(float)FrameTime*DIV4000; pVertex->tu2=fTu; pVertex->tv2=fTv; fTu=(ep->v[2].sx+60.f)*DIV1000-EEsin((ep->v[2].sx+60)*DIV200+(float)FrameTime*DIV1000)*DIV40; fTv=(ep->v[2].sz+60.f)*DIV1000-EEcos((ep->v[2].sz+60)*DIV200+(float)FrameTime*DIV1000)*DIV40; if (ep->type & POLY_FALL) fTv+=(float)FrameTime*DIV4000; pVertex->tu3=fTu; pVertex->tv3=fTv; pVertex++; *pussInd++ = iNbIndice++; *pussInd++ = iNbIndice++; *pussInd++ = iNbIndice++; pDynamicVertexBuffer->ussNbIndice+=3; if(iNbVertex&4) { pVertex->x=ep->v[3].sx; pVertex->y=-ep->v[3].sy; pVertex->z=ep->v[3].sz; pVertex->color=0xFF505050; fTu=ep->v[3].sx*DIV1000+EEsin((ep->v[3].sx)*DIV200+(float)FrameTime*DIV1000)*DIV32; fTv=ep->v[3].sz*DIV1000+EEcos((ep->v[3].sz)*DIV200+(float)FrameTime*DIV1000)*DIV32; if(ep->type&POLY_FALL) fTv+=(float)FrameTime*DIV4000; pVertex->tu=fTu; pVertex->tv=fTv; fTu=(ep->v[3].sx+30.f)*DIV1000+EEsin((ep->v[3].sx+30)*DIV200+(float)FrameTime*DIV1000)*DIV28; fTv=(ep->v[3].sz+30.f)*DIV1000-EEcos((ep->v[3].sz+30)*DIV200+(float)FrameTime*DIV1000)*DIV28; if (ep->type & POLY_FALL) fTv+=(float)FrameTime*DIV4000; pVertex->tu2=fTu; pVertex->tv2=fTv; fTu=(ep->v[3].sx+60.f)*DIV1000-EEsin((ep->v[3].sx+60)*DIV200+(float)FrameTime*DIV1000)*DIV40; fTv=(ep->v[3].sz+60.f)*DIV1000-EEcos((ep->v[3].sz+60)*DIV200+(float)FrameTime*DIV1000)*DIV40; if (ep->type & POLY_FALL) fTv+=(float)FrameTime*DIV4000; pVertex->tu3=fTu; pVertex->tv3=fTv; pVertex++; *pussInd++ = iNbIndice++; *pussInd++ = iNbIndice - 2; *pussInd++ = iNbIndice - 3; pDynamicVertexBuffer->ussNbIndice+=3; } } pDynamicVertexBuffer->UnLock(); if(pDynamicVertexBuffer->ussNbIndice) { switch(iNbTextureSim) { case 1: GDevice->DrawIndexedPrimitiveVB( D3DPT_TRIANGLELIST, pDynamicVertexBuffer->pVertexBuffer, iOldNbVertex, pDynamicVertexBuffer->ussNbVertex-iOldNbVertex, pDynamicVertexBuffer->pussIndice, pDynamicVertexBuffer->ussNbIndice, 0 ); GDevice->SetTextureStageState(0,D3DTSS_TEXCOORDINDEX,1); GDevice->DrawIndexedPrimitiveVB( D3DPT_TRIANGLELIST, pDynamicVertexBuffer->pVertexBuffer, iOldNbVertex, pDynamicVertexBuffer->ussNbVertex-iOldNbVertex, pDynamicVertexBuffer->pussIndice, pDynamicVertexBuffer->ussNbIndice, 0 ); GDevice->SetTextureStageState(0,D3DTSS_TEXCOORDINDEX,2); GDevice->DrawIndexedPrimitiveVB( D3DPT_TRIANGLELIST, pDynamicVertexBuffer->pVertexBuffer, iOldNbVertex, pDynamicVertexBuffer->ussNbVertex-iOldNbVertex, pDynamicVertexBuffer->pussIndice, pDynamicVertexBuffer->ussNbIndice, 0 ); break; case 2: GDevice->SetTextureStageState(1,D3DTSS_TEXCOORDINDEX,1); GDevice->SetTextureStageState(1,D3DTSS_COLORARG1,D3DTA_TEXTURE); GDevice->SetTextureStageState(1,D3DTSS_COLORARG2,D3DTA_CURRENT); GDevice->SetTextureStageState(1,D3DTSS_COLOROP,D3DTOP_MODULATE4X); GDevice->SetTextureStageState(1,D3DTSS_ALPHAOP,D3DTOP_DISABLE); GDevice->SetTextureStageState(2,D3DTSS_COLOROP,D3DTOP_DISABLE); GDevice->DrawIndexedPrimitiveVB( D3DPT_TRIANGLELIST, pDynamicVertexBuffer->pVertexBuffer, iOldNbVertex, pDynamicVertexBuffer->ussNbVertex-iOldNbVertex, pDynamicVertexBuffer->pussIndice, pDynamicVertexBuffer->ussNbIndice, 0 ); GDevice->SetTextureStageState(0,D3DTSS_TEXCOORDINDEX,2); GDevice->SetTextureStageState(1,D3DTSS_COLOROP,D3DTOP_DISABLE); GDevice->DrawIndexedPrimitiveVB( D3DPT_TRIANGLELIST, pDynamicVertexBuffer->pVertexBuffer, iOldNbVertex, pDynamicVertexBuffer->ussNbVertex-iOldNbVertex, pDynamicVertexBuffer->pussIndice, pDynamicVertexBuffer->ussNbIndice, 0 ); break; case 3: GDevice->SetTextureStageState(1,D3DTSS_TEXCOORDINDEX,1); GDevice->SetTextureStageState(1,D3DTSS_COLORARG1,D3DTA_TEXTURE); GDevice->SetTextureStageState(1,D3DTSS_COLORARG2,D3DTA_CURRENT); GDevice->SetTextureStageState(1,D3DTSS_COLOROP,D3DTOP_MODULATE4X); GDevice->SetTextureStageState(1,D3DTSS_ALPHAOP,D3DTOP_DISABLE); GDevice->SetTextureStageState(2,D3DTSS_TEXCOORDINDEX,2); GDevice->SetTextureStageState(2,D3DTSS_COLORARG1,D3DTA_TEXTURE); GDevice->SetTextureStageState(2,D3DTSS_COLORARG2,D3DTA_CURRENT); GDevice->SetTextureStageState(2,D3DTSS_COLOROP,D3DTOP_MODULATE); GDevice->SetTextureStageState(2,D3DTSS_ALPHAOP,D3DTOP_DISABLE); GDevice->SetTextureStageState(3,D3DTSS_COLOROP,D3DTOP_DISABLE); GDevice->DrawIndexedPrimitiveVB( D3DPT_TRIANGLELIST, pDynamicVertexBuffer->pVertexBuffer, iOldNbVertex, pDynamicVertexBuffer->ussNbVertex-iOldNbVertex, pDynamicVertexBuffer->pussIndice, pDynamicVertexBuffer->ussNbIndice, 0 ); break; } GDevice->SetTextureStageState(1,D3DTSS_COLOROP,D3DTOP_DISABLE); GDevice->SetTextureStageState(0,D3DTSS_TEXCOORDINDEX,0); } vPolyWater.clear(); } iNbIndice=0; iNb=vPolyLava.size(); if(iNb) { int iOldNbVertex=pDynamicVertexBuffer->ussNbVertex; pDynamicVertexBuffer->ussNbIndice=0; SMY_D3DVERTEX3 *pVertex=(SMY_D3DVERTEX3*)pDynamicVertexBuffer->Lock(DDLOCK_NOOVERWRITE); pVertex+=iOldNbVertex; GDevice->SetRenderState( D3DRENDERSTATE_SRCBLEND, D3DBLEND_DESTCOLOR ); GDevice->SetRenderState( D3DRENDERSTATE_DESTBLEND, D3DBLEND_ONE ); SETTC(GDevice,enviro); switch(danaeApp.m_pDeviceInfo->wNbTextureSimultaneous) { case 3: GDevice->SetTexture(2,enviro?enviro->m_pddsSurface?enviro->m_pddsSurface:NULL:NULL); case 2: GDevice->SetTexture(1,enviro?enviro->m_pddsSurface?enviro->m_pddsSurface:NULL:NULL); break; } unsigned short *pussInd=pDynamicVertexBuffer->pussIndice; while(iNb--) { EERIEPOLY *ep=vPolyLava[iNb]; unsigned short iNbVertex = (ep->type & POLY_QUAD) ? 4 : 3; pDynamicVertexBuffer->ussNbVertex+=iNbVertex; if(pDynamicVertexBuffer->ussNbVertex>pDynamicVertexBuffer->ussMaxVertex) { pDynamicVertexBuffer->UnLock(); pDynamicVertexBuffer->ussNbVertex-=iNbVertex; GDevice->SetRenderState( D3DRENDERSTATE_SRCBLEND, D3DBLEND_DESTCOLOR ); GDevice->SetRenderState( D3DRENDERSTATE_DESTBLEND, D3DBLEND_ONE ); GDevice->SetTextureStageState(0,D3DTSS_COLOROP,D3DTOP_MODULATE2X); if(pDynamicVertexBuffer->ussNbIndice) { switch(danaeApp.m_pDeviceInfo->wNbTextureSimultaneous) { case 1: GDevice->DrawIndexedPrimitiveVB( D3DPT_TRIANGLELIST, pDynamicVertexBuffer->pVertexBuffer, iOldNbVertex, pDynamicVertexBuffer->ussNbVertex-iOldNbVertex, pDynamicVertexBuffer->pussIndice, pDynamicVertexBuffer->ussNbIndice, 0 ); GDevice->SetTextureStageState(0,D3DTSS_TEXCOORDINDEX,1); GDevice->DrawIndexedPrimitiveVB( D3DPT_TRIANGLELIST, pDynamicVertexBuffer->pVertexBuffer, iOldNbVertex, pDynamicVertexBuffer->ussNbVertex-iOldNbVertex, pDynamicVertexBuffer->pussIndice, pDynamicVertexBuffer->ussNbIndice, 0 ); GDevice->SetTextureStageState(0,D3DTSS_TEXCOORDINDEX,2); GDevice->DrawIndexedPrimitiveVB( D3DPT_TRIANGLELIST, pDynamicVertexBuffer->pVertexBuffer, iOldNbVertex, pDynamicVertexBuffer->ussNbVertex-iOldNbVertex, pDynamicVertexBuffer->pussIndice, pDynamicVertexBuffer->ussNbIndice, 0 ); GDevice->SetRenderState( D3DRENDERSTATE_SRCBLEND, D3DBLEND_ZERO ); GDevice->SetRenderState( D3DRENDERSTATE_DESTBLEND, D3DBLEND_INVSRCCOLOR); GDevice->SetTextureStageState(0,D3DTSS_COLOROP,D3DTOP_MODULATE); GDevice->DrawIndexedPrimitiveVB( D3DPT_TRIANGLELIST, pDynamicVertexBuffer->pVertexBuffer, iOldNbVertex, pDynamicVertexBuffer->ussNbVertex-iOldNbVertex, pDynamicVertexBuffer->pussIndice, pDynamicVertexBuffer->ussNbIndice, 0 ); break; case 2: GDevice->SetTextureStageState(1,D3DTSS_TEXCOORDINDEX,1); GDevice->SetTextureStageState(1,D3DTSS_COLORARG1,D3DTA_TEXTURE); GDevice->SetTextureStageState(1,D3DTSS_COLORARG2,D3DTA_CURRENT); GDevice->SetTextureStageState(1,D3DTSS_COLOROP,D3DTOP_MODULATE4X); GDevice->SetTextureStageState(1,D3DTSS_ALPHAOP,D3DTOP_DISABLE); GDevice->SetTextureStageState(2,D3DTSS_COLOROP,D3DTOP_DISABLE); GDevice->DrawIndexedPrimitiveVB( D3DPT_TRIANGLELIST, pDynamicVertexBuffer->pVertexBuffer, iOldNbVertex, pDynamicVertexBuffer->ussNbVertex-iOldNbVertex, pDynamicVertexBuffer->pussIndice, pDynamicVertexBuffer->ussNbIndice, 0 ); GDevice->SetTextureStageState(0,D3DTSS_TEXCOORDINDEX,2); GDevice->SetTextureStageState(1,D3DTSS_COLOROP,D3DTOP_DISABLE); GDevice->DrawIndexedPrimitiveVB( D3DPT_TRIANGLELIST, pDynamicVertexBuffer->pVertexBuffer, iOldNbVertex, pDynamicVertexBuffer->ussNbVertex-iOldNbVertex, pDynamicVertexBuffer->pussIndice, pDynamicVertexBuffer->ussNbIndice, 0 ); GDevice->SetRenderState( D3DRENDERSTATE_SRCBLEND, D3DBLEND_ZERO ); GDevice->SetRenderState( D3DRENDERSTATE_DESTBLEND, D3DBLEND_INVSRCCOLOR); GDevice->SetTextureStageState(0,D3DTSS_COLOROP,D3DTOP_MODULATE); GDevice->DrawIndexedPrimitiveVB( D3DPT_TRIANGLELIST, pDynamicVertexBuffer->pVertexBuffer, iOldNbVertex, pDynamicVertexBuffer->ussNbVertex-iOldNbVertex, pDynamicVertexBuffer->pussIndice, pDynamicVertexBuffer->ussNbIndice, 0 ); break; case 3: GDevice->SetTextureStageState(1,D3DTSS_TEXCOORDINDEX,1); GDevice->SetTextureStageState(1,D3DTSS_COLORARG1,D3DTA_TEXTURE); GDevice->SetTextureStageState(1,D3DTSS_COLORARG2,D3DTA_CURRENT); GDevice->SetTextureStageState(1,D3DTSS_COLOROP,D3DTOP_MODULATE4X); GDevice->SetTextureStageState(1,D3DTSS_ALPHAOP,D3DTOP_DISABLE); GDevice->SetTextureStageState(2,D3DTSS_TEXCOORDINDEX,2); GDevice->SetTextureStageState(2,D3DTSS_COLORARG1,D3DTA_TEXTURE); GDevice->SetTextureStageState(2,D3DTSS_COLORARG2,D3DTA_CURRENT); GDevice->SetTextureStageState(2,D3DTSS_COLOROP,D3DTOP_MODULATE); GDevice->SetTextureStageState(2,D3DTSS_ALPHAOP,D3DTOP_DISABLE); GDevice->SetTextureStageState(3,D3DTSS_COLOROP,D3DTOP_DISABLE); GDevice->DrawIndexedPrimitiveVB( D3DPT_TRIANGLELIST, pDynamicVertexBuffer->pVertexBuffer, iOldNbVertex, pDynamicVertexBuffer->ussNbVertex-iOldNbVertex, pDynamicVertexBuffer->pussIndice, pDynamicVertexBuffer->ussNbIndice, 0 ); GDevice->SetRenderState( D3DRENDERSTATE_SRCBLEND, D3DBLEND_ZERO ); GDevice->SetRenderState( D3DRENDERSTATE_DESTBLEND, D3DBLEND_INVSRCCOLOR); GDevice->SetTextureStageState(0,D3DTSS_COLOROP,D3DTOP_MODULATE); GDevice->DrawIndexedPrimitiveVB( D3DPT_TRIANGLELIST, pDynamicVertexBuffer->pVertexBuffer, iOldNbVertex, pDynamicVertexBuffer->ussNbVertex-iOldNbVertex, pDynamicVertexBuffer->pussIndice, pDynamicVertexBuffer->ussNbIndice, 0 ); break; } GDevice->SetTextureStageState(1,D3DTSS_COLOROP,D3DTOP_DISABLE); GDevice->SetTextureStageState(0,D3DTSS_TEXCOORDINDEX,0); } pVertex=(SMY_D3DVERTEX3*)pDynamicVertexBuffer->Lock(DDLOCK_DISCARDCONTENTS); pDynamicVertexBuffer->ussNbVertex=iNbVertex; iOldNbVertex = iNbIndice = pDynamicVertexBuffer->ussNbIndice = 0; pussInd=pDynamicVertexBuffer->pussIndice; //iNbVertex = 3 or 4 but be sure to Assert in Debug if overflow ARX_CHECK( pDynamicVertexBuffer->ussNbVertex <= pDynamicVertexBuffer->ussMaxVertex ); } pVertex->x=ep->v[0].sx; pVertex->y=-ep->v[0].sy; pVertex->z=ep->v[0].sz; pVertex->color=0xFF666666; float fTu=ep->v[0].sx*DIV1000+EEsin((ep->v[0].sx)*DIV200+(float)FrameTime*DIV2000)*DIV20; float fTv=ep->v[0].sz*DIV1000+EEcos((ep->v[0].sz)*DIV200+(float)FrameTime*DIV2000)*DIV20; pVertex->tu=fTu; pVertex->tv=fTv; fTu=ep->v[0].sx*DIV1000+EEsin((ep->v[0].sx)*DIV100+(float)FrameTime*DIV2000)*DIV10; fTv=ep->v[0].sz*DIV1000+EEcos((ep->v[0].sz)*DIV100+(float)FrameTime*DIV2000)*DIV10; pVertex->tu2=fTu; pVertex->tv2=fTv; fTu=ep->v[0].sx*DIV600+EEsin((ep->v[0].sx)*DIV160+(float)FrameTime*DIV2000)*DIV11; fTv=ep->v[0].sz*DIV600+EEcos((ep->v[0].sz)*DIV160+(float)FrameTime*DIV2000)*DIV11; pVertex->tu3=fTu; pVertex->tv3=fTv; pVertex++; pVertex->x=ep->v[1].sx; pVertex->y=-ep->v[1].sy; pVertex->z=ep->v[1].sz; pVertex->color=0xFF666666; fTu=ep->v[1].sx*DIV1000+EEsin((ep->v[1].sx)*DIV200+(float)FrameTime*DIV2000)*DIV20; fTv=ep->v[1].sz*DIV1000+EEcos((ep->v[1].sz)*DIV200+(float)FrameTime*DIV2000)*DIV20; pVertex->tu=fTu; pVertex->tv=fTv; fTu=ep->v[1].sx*DIV1000+EEsin((ep->v[1].sx)*DIV100+(float)FrameTime*DIV2000)*DIV10; fTv=ep->v[1].sz*DIV1000+EEcos((ep->v[1].sz)*DIV100+(float)FrameTime*DIV2000)*DIV10; pVertex->tu2=fTu; pVertex->tv2=fTv; fTu=ep->v[1].sx*DIV600+EEsin((ep->v[1].sx)*DIV160+(float)FrameTime*DIV2000)*DIV11; fTv=ep->v[1].sz*DIV600+EEcos((ep->v[1].sz)*DIV160+(float)FrameTime*DIV2000)*DIV11; pVertex->tu3=fTu; pVertex->tv3=fTv; pVertex++; pVertex->x=ep->v[2].sx; pVertex->y=-ep->v[2].sy; pVertex->z=ep->v[2].sz; pVertex->color=0xFF666666; fTu=ep->v[2].sx*DIV1000+EEsin((ep->v[2].sx)*DIV200+(float)FrameTime*DIV2000)*DIV20; fTv=ep->v[2].sz*DIV1000+EEcos((ep->v[2].sz)*DIV200+(float)FrameTime*DIV2000)*DIV20; pVertex->tu=fTu; pVertex->tv=fTv; fTu=ep->v[2].sx*DIV1000+EEsin((ep->v[2].sx)*DIV100+(float)FrameTime*DIV2000)*DIV10; fTv=ep->v[2].sz*DIV1000+EEcos((ep->v[2].sz)*DIV100+(float)FrameTime*DIV2000)*DIV10; pVertex->tu2=fTu; pVertex->tv2=fTv; fTu=ep->v[2].sx*DIV600+EEsin((ep->v[2].sx)*DIV160+(float)FrameTime*DIV2000)*DIV11; fTv=ep->v[2].sz*DIV600+EEcos((ep->v[2].sz)*DIV160+(float)FrameTime*DIV2000)*DIV11; pVertex->tu3=fTu; pVertex->tv3=fTv; pVertex++; *pussInd++ = iNbIndice++; *pussInd++ = iNbIndice++; *pussInd++ = iNbIndice++; pDynamicVertexBuffer->ussNbIndice+=3; if(iNbVertex&4) { pVertex->x=ep->v[3].sx; pVertex->y=-ep->v[3].sy; pVertex->z=ep->v[3].sz; pVertex->color=0xFF666666; fTu=ep->v[3].sx*DIV1000+EEsin((ep->v[3].sx)*DIV200+(float)FrameTime*DIV2000)*DIV20; fTv=ep->v[3].sz*DIV1000+EEcos((ep->v[3].sz)*DIV200+(float)FrameTime*DIV2000)*DIV20; pVertex->tu=fTu; pVertex->tv=fTv; fTu=ep->v[3].sx*DIV1000+EEsin((ep->v[3].sx)*DIV100+(float)FrameTime*DIV2000)*DIV10; fTv=ep->v[3].sz*DIV1000+EEcos((ep->v[3].sz)*DIV100+(float)FrameTime*DIV2000)*DIV10; pVertex->tu2=fTu; pVertex->tv2=fTv; fTu=ep->v[3].sx*DIV600+EEsin((ep->v[3].sx)*DIV160+(float)FrameTime*DIV2000)*DIV11; fTv=ep->v[3].sz*DIV600+EEcos((ep->v[3].sz)*DIV160+(float)FrameTime*DIV2000)*DIV11; pVertex->tu3=fTu; pVertex->tv3=fTv; pVertex++; *pussInd++ = iNbIndice++; *pussInd++ = iNbIndice - 2; *pussInd++ = iNbIndice - 3; pDynamicVertexBuffer->ussNbIndice+=3; } } pDynamicVertexBuffer->UnLock(); if(pDynamicVertexBuffer->ussNbIndice) { GDevice->SetRenderState( D3DRENDERSTATE_SRCBLEND, D3DBLEND_DESTCOLOR ); GDevice->SetRenderState( D3DRENDERSTATE_DESTBLEND, D3DBLEND_ONE ); GDevice->SetTextureStageState(0,D3DTSS_COLOROP,D3DTOP_MODULATE2X); switch(danaeApp.m_pDeviceInfo->wNbTextureSimultaneous) { case 1: GDevice->DrawIndexedPrimitiveVB( D3DPT_TRIANGLELIST, pDynamicVertexBuffer->pVertexBuffer, iOldNbVertex, pDynamicVertexBuffer->ussNbVertex-iOldNbVertex, pDynamicVertexBuffer->pussIndice, pDynamicVertexBuffer->ussNbIndice, 0 ); GDevice->SetTextureStageState(0,D3DTSS_TEXCOORDINDEX,1); GDevice->DrawIndexedPrimitiveVB( D3DPT_TRIANGLELIST, pDynamicVertexBuffer->pVertexBuffer, iOldNbVertex, pDynamicVertexBuffer->ussNbVertex-iOldNbVertex, pDynamicVertexBuffer->pussIndice, pDynamicVertexBuffer->ussNbIndice, 0 ); GDevice->SetTextureStageState(0,D3DTSS_TEXCOORDINDEX,2); GDevice->DrawIndexedPrimitiveVB( D3DPT_TRIANGLELIST, pDynamicVertexBuffer->pVertexBuffer, iOldNbVertex, pDynamicVertexBuffer->ussNbVertex-iOldNbVertex, pDynamicVertexBuffer->pussIndice, pDynamicVertexBuffer->ussNbIndice, 0 ); GDevice->SetRenderState( D3DRENDERSTATE_SRCBLEND, D3DBLEND_ZERO ); GDevice->SetRenderState( D3DRENDERSTATE_DESTBLEND, D3DBLEND_INVSRCCOLOR); GDevice->SetTextureStageState(0,D3DTSS_COLOROP,D3DTOP_MODULATE); GDevice->DrawIndexedPrimitiveVB( D3DPT_TRIANGLELIST, pDynamicVertexBuffer->pVertexBuffer, iOldNbVertex, pDynamicVertexBuffer->ussNbVertex-iOldNbVertex, pDynamicVertexBuffer->pussIndice, pDynamicVertexBuffer->ussNbIndice, 0 ); break; case 2: GDevice->SetTextureStageState(1,D3DTSS_TEXCOORDINDEX,1); GDevice->SetTextureStageState(1,D3DTSS_COLORARG1,D3DTA_TEXTURE); GDevice->SetTextureStageState(1,D3DTSS_COLORARG2,D3DTA_CURRENT); GDevice->SetTextureStageState(1,D3DTSS_COLOROP,D3DTOP_MODULATE4X); GDevice->SetTextureStageState(1,D3DTSS_ALPHAOP,D3DTOP_DISABLE); GDevice->SetTextureStageState(2,D3DTSS_COLOROP,D3DTOP_DISABLE); GDevice->DrawIndexedPrimitiveVB( D3DPT_TRIANGLELIST, pDynamicVertexBuffer->pVertexBuffer, iOldNbVertex, pDynamicVertexBuffer->ussNbVertex-iOldNbVertex, pDynamicVertexBuffer->pussIndice, pDynamicVertexBuffer->ussNbIndice, 0 ); GDevice->SetTextureStageState(0,D3DTSS_TEXCOORDINDEX,2); GDevice->SetTextureStageState(1,D3DTSS_COLOROP,D3DTOP_DISABLE); GDevice->DrawIndexedPrimitiveVB( D3DPT_TRIANGLELIST, pDynamicVertexBuffer->pVertexBuffer, iOldNbVertex, pDynamicVertexBuffer->ussNbVertex-iOldNbVertex, pDynamicVertexBuffer->pussIndice, pDynamicVertexBuffer->ussNbIndice, 0 ); GDevice->SetRenderState( D3DRENDERSTATE_SRCBLEND, D3DBLEND_ZERO ); GDevice->SetRenderState( D3DRENDERSTATE_DESTBLEND, D3DBLEND_INVSRCCOLOR); GDevice->SetTextureStageState(0,D3DTSS_COLOROP,D3DTOP_MODULATE); GDevice->DrawIndexedPrimitiveVB( D3DPT_TRIANGLELIST, pDynamicVertexBuffer->pVertexBuffer, iOldNbVertex, pDynamicVertexBuffer->ussNbVertex-iOldNbVertex, pDynamicVertexBuffer->pussIndice, pDynamicVertexBuffer->ussNbIndice, 0 ); break; case 3: GDevice->SetTextureStageState(1,D3DTSS_TEXCOORDINDEX,1); GDevice->SetTextureStageState(1,D3DTSS_COLORARG1,D3DTA_TEXTURE); GDevice->SetTextureStageState(1,D3DTSS_COLORARG2,D3DTA_CURRENT); GDevice->SetTextureStageState(1,D3DTSS_COLOROP,D3DTOP_MODULATE4X); GDevice->SetTextureStageState(1,D3DTSS_ALPHAOP,D3DTOP_DISABLE); GDevice->SetTextureStageState(2,D3DTSS_TEXCOORDINDEX,2); GDevice->SetTextureStageState(2,D3DTSS_COLORARG1,D3DTA_TEXTURE); GDevice->SetTextureStageState(2,D3DTSS_COLORARG2,D3DTA_CURRENT); GDevice->SetTextureStageState(2,D3DTSS_COLOROP,D3DTOP_MODULATE); GDevice->SetTextureStageState(2,D3DTSS_ALPHAOP,D3DTOP_DISABLE); GDevice->SetTextureStageState(3,D3DTSS_COLOROP,D3DTOP_DISABLE); GDevice->DrawIndexedPrimitiveVB( D3DPT_TRIANGLELIST, pDynamicVertexBuffer->pVertexBuffer, iOldNbVertex, pDynamicVertexBuffer->ussNbVertex-iOldNbVertex, pDynamicVertexBuffer->pussIndice, pDynamicVertexBuffer->ussNbIndice, 0 ); GDevice->SetRenderState( D3DRENDERSTATE_SRCBLEND, D3DBLEND_ZERO ); GDevice->SetRenderState( D3DRENDERSTATE_DESTBLEND, D3DBLEND_INVSRCCOLOR); GDevice->SetTextureStageState(0,D3DTSS_COLOROP,D3DTOP_MODULATE); GDevice->DrawIndexedPrimitiveVB( D3DPT_TRIANGLELIST, pDynamicVertexBuffer->pVertexBuffer, iOldNbVertex, pDynamicVertexBuffer->ussNbVertex-iOldNbVertex, pDynamicVertexBuffer->pussIndice, pDynamicVertexBuffer->ussNbIndice, 0 ); break; } GDevice->SetTextureStageState(1,D3DTSS_COLOROP,D3DTOP_DISABLE); GDevice->SetTextureStageState(0,D3DTSS_TEXCOORDINDEX,0); } vPolyLava.clear(); } SetZBias(GDevice,0); GDevice->SetRenderState(D3DRENDERSTATE_FOGCOLOR,ulBKGColor); GDevice->SetTextureStageState(0,D3DTSS_COLOROP,D3DTOP_MODULATE); SETALPHABLEND(GDevice,FALSE); } void ARX_PORTALS_Frustrum_RenderRoomTCullSoft(long room_num,EERIE_FRUSTRUM_DATA * frustrums,long prec,long tim); void ARX_PORTALS_Frustrum_RenderRoomsTCullSoft(long prec,long tim) { GDevice->SetRenderState( D3DRENDERSTATE_SRCBLEND, D3DBLEND_ZERO ); GDevice->SetRenderState( D3DRENDERSTATE_DESTBLEND, D3DBLEND_INVSRCCOLOR ); for (long i=0;imin.x,bbox->min.y,bbox->max.x,bbox->max.y,0.0001f, 0xFF0000FF); for (long lll=0;lllroom[room_num].nb_polys;lll++) { FAST_BKG_DATA * feg; feg=&ACTIVEBKG->fastdata[portals->room[room_num].epdata[lll].px][portals->room[room_num].epdata[lll].py]; if (!feg->treat) continue; EERIEPOLY * ep=&feg->polydata[portals->room[room_num].epdata[lll].idx]; if (ep->type & (POLY_IGNORE | POLY_NODRAW)) continue; // GO for 3D Backface Culling if (ep->type & POLY_DOUBLESIDED) SETCULL( GDevice, D3DCULL_NONE ); else { EERIE_3D nrm; nrm.x=ep->v[2].sx-ACTIVECAM->pos.x; nrm.y=ep->v[2].sy-ACTIVECAM->pos.y; nrm.z=ep->v[2].sz-ACTIVECAM->pos.z; if ( ep->type & POLY_QUAD) { if ( (DOTPRODUCT( ep->norm , nrm )>0.f) && (DOTPRODUCT( ep->norm2 , nrm )>0.f) ) continue; } else if ( DOTPRODUCT( ep->norm , nrm )>0.f) continue; SETCULL( GDevice, D3DCULL_CW ); } if (!EERIERTPPoly(ep)) // RotTransProject Vertices continue; if (BBoxClipPoly(bbox,ep)) continue; long to; if ( ep->type & POLY_QUAD) { if (FRAME_COUNT<=0) ep->tv[3].color=ep->v[3].color; to=4; } else to=3; if (FRAME_COUNT<=0) { if(!USE_D3DFOG) ComputeFog(ep->tv,to); } if (ep->type & POLY_TRANS) { ManageLavaWater(ep,to,tim); TransPol[TRANSPOLYSPOS++]=ep; if (TRANSPOLYSPOS>=MAX_TRANSPOL) TRANSPOLYSPOS=MAX_TRANSPOL-1; if (ViewMode) { if (ViewMode & VIEWMODE_WIRE) EERIEPOLY_DrawWired(GDevice,ep); if (ViewMode & VIEWMODE_NORMALS) EERIEPOLY_DrawNormals(GDevice,ep); } continue; } if (!Project.improve) // Normal View... { if (ep->type & POLY_GLOW) ep->tv[0].color=ep->tv[1].color=ep->tv[2].color=ep->tv[3].color=0xFFFFFFFF; else { if (FRAME_COUNT<=0) { if (ModeLight & MODE_DYNAMICLIGHT) ApplyDynLight(ep); else { ep->tv[0].color=ep->v[0].color; ep->tv[1].color=ep->v[1].color; ep->tv[2].color=ep->v[2].color; } } } ManageLavaWater(ep,to,tim); Delayed_EERIEDRAWPRIM(ep); if (ViewMode) { if (ViewMode & VIEWMODE_WIRE) EERIEPOLY_DrawWired(GDevice,ep); if (ViewMode & VIEWMODE_NORMALS) EERIEPOLY_DrawNormals(GDevice,ep); } } else // Improve Vision Activated { if (FRAME_COUNT<=0) { if ( ModeLight & MODE_DYNAMICLIGHT ) ApplyDynLight(ep); else { ep->tv[0].color=ep->v[0].color; ep->tv[1].color=ep->v[1].color; ep->tv[2].color=ep->v[2].color; } for (long k=0;ktv[k].color>>16) & 255; float ffr=(float)(lr); float dd=(ep->tv[k].sz*prec); if (dd>1.f) dd=1.f; if (dd<0.f) dd=0.f; fb=((1.f-dd)*6.f + (EEfabs(ep->nrml[k].x)+EEfabs(ep->nrml[k].y)))*0.125f; fr=((0.6f-dd)*6.f + (EEfabs(ep->nrml[k].z)+EEfabs(ep->nrml[k].y)))*0.125f;//(1.f-dd); if (fr<0.f) fr=0.f; else fr=__max(ffr,fr*255.f); fb*=255.f; F2L(fr,&lfr); F2L(fb,&lfb); F2L(fr,&lfr); ep->tv[k].color=( 0xff001E00L | ( (lfr & 255) << 16) | (lfb & 255) ); //GG component locked at 0x1E } } Delayed_EERIEDRAWPRIM(ep); } } } } void ARX_PORTALS_Frustrum_RenderRoom(long room_num,EERIE_FRUSTRUM_DATA * frustrums,long prec,long tim) { if (RoomDraw[room_num].count) { for (long lll=0;lllroom[room_num].nb_polys;lll++) { FAST_BKG_DATA * feg; feg=&ACTIVEBKG->fastdata[portals->room[room_num].epdata[lll].px][portals->room[room_num].epdata[lll].py]; if (!feg->treat) continue; EERIEPOLY * ep=&feg->polydata[portals->room[room_num].epdata[lll].idx]; if (ep->type & (POLY_IGNORE | POLY_NODRAW)) continue; if (FrustrumsClipPoly(frustrums,ep)) continue; // GO for 3D Backface Culling if (ep->type & POLY_DOUBLESIDED) SETCULL( GDevice, D3DCULL_NONE ); else { EERIE_3D nrm; nrm.x=ep->v[2].sx-ACTIVECAM->pos.x; nrm.y=ep->v[2].sy-ACTIVECAM->pos.y; nrm.z=ep->v[2].sz-ACTIVECAM->pos.z; if ( ep->type & POLY_QUAD) { if ( (DOTPRODUCT( ep->norm , nrm )>0.f) && (DOTPRODUCT( ep->norm2 , nrm )>0.f) ) continue; } else if ( DOTPRODUCT( ep->norm , nrm )>0.f) continue; SETCULL( GDevice, D3DCULL_CW ); } if (!EERIERTPPoly(ep)) // RotTransProject Vertices continue; long to; if ( ep->type & POLY_QUAD) { if (FRAME_COUNT<=0) ep->tv[3].color=ep->v[3].color; to=4; } else to=3; if (FRAME_COUNT<=0) { if(!USE_D3DFOG) ComputeFog(ep->tv,to); } if (ep->type & POLY_TRANS) { ManageLavaWater(ep,to,tim); TransPol[TRANSPOLYSPOS++]=ep; if (TRANSPOLYSPOS>=MAX_TRANSPOL) TRANSPOLYSPOS=MAX_TRANSPOL-1; if (ViewMode) { if (ViewMode & VIEWMODE_WIRE) EERIEPOLY_DrawWired(GDevice,ep); if (ViewMode & VIEWMODE_NORMALS) EERIEPOLY_DrawNormals(GDevice,ep); } continue; } if (!Project.improve) // Normal View... { if (ep->type & POLY_GLOW) ep->tv[0].color=ep->tv[1].color=ep->tv[2].color=ep->tv[3].color=0xFFFFFFFF; else { if (FRAME_COUNT<=0) { if (ModeLight & MODE_DYNAMICLIGHT) ApplyDynLight(ep); else { ep->tv[0].color=ep->v[0].color; ep->tv[1].color=ep->v[1].color; ep->tv[2].color=ep->v[2].color; } } } ManageLavaWater(ep,to,tim); Delayed_EERIEDRAWPRIM(ep); if (ViewMode) { if (ViewMode & VIEWMODE_WIRE) EERIEPOLY_DrawWired(GDevice,ep); if (ViewMode & VIEWMODE_NORMALS) EERIEPOLY_DrawNormals(GDevice,ep); } } else // Improve Vision Activated { if (FRAME_COUNT<=0) { if ( ModeLight & MODE_DYNAMICLIGHT ) ApplyDynLight(ep); else { ep->tv[0].color=ep->v[0].color; ep->tv[1].color=ep->v[1].color; ep->tv[2].color=ep->v[2].color; } for (long k=0;ktv[k].color>>16) & 255; float ffr=(float)(lr); float dd=(ep->tv[k].sz*prec); if (dd>1.f) dd=1.f; if (dd<0.f) dd=0.f; fb=((1.f-dd)*6.f + (EEfabs(ep->nrml[k].x)+EEfabs(ep->nrml[k].y)))*0.125f; fr=((0.6f-dd)*6.f + (EEfabs(ep->nrml[k].z)+EEfabs(ep->nrml[k].y)))*0.125f;//(1.f-dd); if (fr<0.f) fr=0.f; else fr=__max(ffr,fr*255.f); fb*=255.f; F2L(fr,&lfr); F2L(fb,&lfb); F2L(fr,&lfr); ep->tv[k].color=( 0xff001E00L | ( (lfr & 255) << 16) | (lfb & 255) ); //GG component locked at 0x1E } } Delayed_EERIEDRAWPRIM(ep); } } } } void ApplyDynLight_VertexBuffer(EERIEPOLY *ep,SMY_D3DVERTEX *_pVertex,unsigned short _usInd0,unsigned short _usInd1,unsigned short _usInd2,unsigned short _usInd3); void ApplyDynLight_VertexBuffer_2(EERIEPOLY *ep,short x,short y,SMY_D3DVERTEX *_pVertex,unsigned short _usInd0,unsigned short _usInd1,unsigned short _usInd2,unsigned short _usInd3); //----------------------------------------------------------------------------- void ARX_PORTALS_Frustrum_RenderRoomT(long room_num,EERIE_FRUSTRUM_DATA * frustrums,long prec,long tim) { } //----------------------------------------------------------------------------- void ARX_PORTALS_Frustrum_RenderRoom_TransparencyT(long room_num) { } TILE_LIGHTS tilelights[MAX_BKGX][MAX_BKGZ]; void InitTileLights() { for (long j=0;jXdiv; float zz=((float)z+0.5f)*ACTIVEBKG->Zdiv; for (long i=0;ipos.x,PDL[i]->pos.z); if (d2dfallend+60.f) { if (tilelights[x][z].num>=tilelights[x][z].max) { tilelights[x][z].max++; tilelights[x][z].el=(EERIE_LIGHT **)realloc(tilelights[x][z].el,sizeof(EERIE_LIGHT *)*(tilelights[x][z].max)); } tilelights[x][z].el[tilelights[x][z].num]=PDL[i]; tilelights[x][z].num++; } } } void ClearTileLights() { for (long j=0;jbForceMetalTwoPass); if(!portals->room[room_num].pVertexBuffer) { char tTxt[256]; sprintf(tTxt,"portals %d - Zero Polys",room_num); MessageBox( NULL, tTxt, "Error Portals", MB_OK|MB_ICONERROR ); return; } if( FAILED( portals->room[room_num].pVertexBuffer->Lock( DDLOCK_WRITEONLY|DDLOCK_NOOVERWRITE/*|DDLOCK_WAIT*/ , (void**)&pMyVertex , NULL ) ) ) { ARX_LOG_ERROR("ARX_PORTALS_Frustrum_RenderRoomTCullSoft Render Error : Cannot Lock Buffer."); return; } unsigned short *pIndices=portals->room[room_num].pussIndice; FAST_BKG_DATA * feg; EERIEPOLY * ep; EP_DATA *pEPDATA = &portals->room[room_num].epdata[0]; float fDistBump=__min(__max(0.f,(ACTIVECAM->cdepth*fZFogStart)-200.f),MAX_DIST_BUMP); for (long lll=0; lllroom[room_num].nb_polys; lll++, *pEPDATA++) { feg = &ACTIVEBKG->fastdata[pEPDATA->px][pEPDATA->py]; if (!feg->treat) { long ix=__max(0,pEPDATA->px-1); long ax=__min(ACTIVEBKG->Xsize-1,pEPDATA->px+1); long iz=__max(0,pEPDATA->py-1); long az=__min(ACTIVEBKG->Zsize-1,pEPDATA->py+1); ARX_CHECK_SHORT(iz); ARX_CHECK_SHORT(ix); ARX_CHECK_SHORT(az); ARX_CHECK_SHORT(ax); for (long nz=iz;nz<=az;nz++) for (long nx=ix;nx<=ax;nx++) { FAST_BKG_DATA * feg2 = &ACTIVEBKG->fastdata[nx][nz]; if (!feg2->treat) { feg2->treat=1; if (USE_LIGHT_OPTIM) ComputeTileLights(ARX_CLEAN_WARN_CAST_SHORT(nx), ARX_CLEAN_WARN_CAST_SHORT(nz)); } } } ep=&feg->polydata[pEPDATA->idx]; if (!ep->tex) { continue; } if (ep->type & (POLY_IGNORE | POLY_NODRAW| POLY_HIDE)) { continue; } if (FrustrumsClipPoly(frustrums,ep)) { continue; } //Clipp ZNear + Distance pour les ZMapps et Bump!!! float fDist=(ep->center.x*efpPlaneNear.a + ep->center.y*efpPlaneNear.b + ep->center.z*efpPlaneNear.c + efpPlaneNear.d); if(ep->v[0].rhw<-fDist) { continue; } fDist-=ep->v[0].rhw; EERIE_3D nrm; nrm.x=ep->v[2].sx-ACTIVECAM->pos.x; nrm.y=ep->v[2].sy-ACTIVECAM->pos.y; nrm.z=ep->v[2].sz-ACTIVECAM->pos.z; int to; if(ep->type&POLY_QUAD) { if( (!(ep->type&POLY_DOUBLESIDED))&& (DOTPRODUCT( ep->norm , nrm )>0.f)&& (DOTPRODUCT( ep->norm2 , nrm )>0.f) ) { continue; } to=4; } else { if( (!(ep->type&POLY_DOUBLESIDED))&& (DOTPRODUCT( ep->norm , nrm )>0.f) ) { continue; } to=3; } unsigned short *pIndicesCurr; unsigned long *pNumIndices; if(ep->type&POLY_TRANS) { if(ep->transval>=2.f) //MULTIPLICATIVE { pIndicesCurr=pIndices+ep->tex->tMatRoom[room_num].uslStartCull_TMultiplicative+ep->tex->tMatRoom[room_num].uslNbIndiceCull_TMultiplicative; pNumIndices=&ep->tex->tMatRoom[room_num].uslNbIndiceCull_TMultiplicative; } else { if(ep->transval>=1.f) //ADDITIVE { pIndicesCurr=pIndices+ep->tex->tMatRoom[room_num].uslStartCull_TAdditive+ep->tex->tMatRoom[room_num].uslNbIndiceCull_TAdditive; pNumIndices=&ep->tex->tMatRoom[room_num].uslNbIndiceCull_TAdditive; } else { if(ep->transval>0.f) //NORMAL TRANS { pIndicesCurr=pIndices+ep->tex->tMatRoom[room_num].uslStartCull_TNormalTrans+ep->tex->tMatRoom[room_num].uslNbIndiceCull_TNormalTrans; pNumIndices=&ep->tex->tMatRoom[room_num].uslNbIndiceCull_TNormalTrans; } else { //SUBTRACTIVE pIndicesCurr=pIndices+ep->tex->tMatRoom[room_num].uslStartCull_TSubstractive+ep->tex->tMatRoom[room_num].uslNbIndiceCull_TSubstractive; pNumIndices=&ep->tex->tMatRoom[room_num].uslNbIndiceCull_TSubstractive; } } } } else { pIndicesCurr=pIndices+ep->tex->tMatRoom[room_num].uslStartCull+ep->tex->tMatRoom[room_num].uslNbIndiceCull; pNumIndices=&ep->tex->tMatRoom[room_num].uslNbIndiceCull; if(ZMAPMODE) { if((fDist<200)&&(ep->tex->TextureRefinement)) { ep->tex->TextureRefinement->vPolyZMap.push_back(ep); } } if( (bNoModulate2X)&& (ep->tex->userflags&POLY_METAL) ) { vPolyVoodooMetal.push_back(ep); } } SMY_D3DVERTEX *pMyVertexCurr; *pIndicesCurr++=ep->uslInd[0]; *pIndicesCurr++=ep->uslInd[1]; *pIndicesCurr++=ep->uslInd[2]; if(to&4) { *pIndicesCurr++=ep->uslInd[3]; *pIndicesCurr++=ep->uslInd[2]; *pIndicesCurr++=ep->uslInd[1]; *pNumIndices+=6; } else { *pNumIndices+=3; } pMyVertexCurr=&pMyVertex[ep->tex->tMatRoom[room_num].uslStartVertex]; if (!Project.improve) // Normal View... { if(ep->type&POLY_GLOW) { pMyVertexCurr[ep->uslInd[0]].color=pMyVertexCurr[ep->uslInd[1]].color=pMyVertexCurr[ep->uslInd[2]].color=0xFFFFFFFF; if(to&4) { pMyVertexCurr[ep->uslInd[3]].color=0xFFFFFFFF; } } else { if(ep->type&POLY_LAVA) { if((FRAME_COUNT<=0)&&(!(ep->type&POLY_TRANS))) { if(ModeLight & MODE_DYNAMICLIGHT) { ApplyDynLight(ep); } else { ep->tv[0].color=ep->v[0].color; ep->tv[1].color=ep->v[1].color; ep->tv[2].color=ep->v[2].color; if(to&4) { ep->tv[3].color=ep->v[3].color; } } } ManageLava_VertexBuffer(ep,to,tim,pMyVertexCurr); vPolyLava.push_back(ep); pMyVertexCurr[ep->uslInd[0]].color=ep->tv[0].color; pMyVertexCurr[ep->uslInd[1]].color=ep->tv[1].color; pMyVertexCurr[ep->uslInd[2]].color=ep->tv[2].color; if(to&4) { pMyVertexCurr[ep->uslInd[3]].color=ep->tv[3].color; } } else { if((FRAME_COUNT<=0)&&(!(ep->type&POLY_TRANS))) { if(ModeLight & MODE_DYNAMICLIGHT) { if (USE_LIGHT_OPTIM) ApplyDynLight_VertexBuffer_2( ep,pEPDATA->px,pEPDATA->py, pMyVertexCurr, ep->uslInd[0], ep->uslInd[1], ep->uslInd[2], ep->uslInd[3]); else ApplyDynLight_VertexBuffer( ep, pMyVertexCurr, ep->uslInd[0], ep->uslInd[1], ep->uslInd[2], ep->uslInd[3]); } else { pMyVertexCurr[ep->uslInd[0]].color=ep->v[0].color; pMyVertexCurr[ep->uslInd[1]].color=ep->v[1].color; pMyVertexCurr[ep->uslInd[2]].color=ep->v[2].color; if(to&4) { pMyVertexCurr[ep->uslInd[3]].color=ep->v[3].color; } } } if(ep->type&POLY_WATER) { ManageWater_VertexBuffer(ep,to,tim,pMyVertexCurr); vPolyWater.push_back(ep); } } } if ((ViewMode & VIEWMODE_WIRE)) { if (EERIERTPPoly(ep)) EERIEPOLY_DrawWired(GDevice,ep); } } else // Improve Vision Activated { //!!!!!!!!! NOT OPTIMIZED T&L !!!!!!!!!! if ((FRAME_COUNT<=0)&&(!(ep->type&POLY_TRANS))) { if (!EERIERTPPoly(ep)) // RotTransProject Vertices { continue; } if ( ModeLight & MODE_DYNAMICLIGHT ) ApplyDynLight(ep); else { ep->tv[0].color=ep->v[0].color; ep->tv[1].color=ep->v[1].color; ep->tv[2].color=ep->v[2].color; if(to&4) { ep->tv[3].color=ep->v[3].color; } } for (long k=0;ktv[k].color>>16) & 255; float ffr=(float)(lr); float dd=(ep->tv[k].rhw*prec); if (dd>1.f) dd=1.f; if (dd<0.f) dd=0.f; fb=((1.f-dd)*6.f + (EEfabs(ep->nrml[k].x)+EEfabs(ep->nrml[k].y)))*0.125f; fr = ((0.6f - dd) * 6.f + (EEfabs(ep->nrml[k].z) + EEfabs(ep->nrml[k].y))) * 0.125f; if (fr<0.f) fr=0.f; else fr=__max(ffr,fr*255.f); fr=__min(fr,255.f); fb*=255.f; fb=__min(fb,255.f); F2L(fr,&lfr); F2L(fb,&lfb); ep->tv[k].color=( 0xff001E00L | ( (lfr & 255) << 16) | (lfb & 255) ); } pMyVertexCurr[ep->uslInd[0]].color=ep->tv[0].color; pMyVertexCurr[ep->uslInd[1]].color=ep->tv[1].color; pMyVertexCurr[ep->uslInd[2]].color=ep->tv[2].color; if(to&4) { pMyVertexCurr[ep->uslInd[3]].color=ep->tv[3].color; } } } if( bALLOW_BUMP ) { if( ( fDist < fDistBump ) && ( ep->tex->m_pddsBumpMap ) ) { ep->tex->vPolyBump.push_back(ep); } } } portals->room[room_num].pVertexBuffer->Unlock(); //render opaque SETCULL(GDevice,D3DCULL_NONE); int iNbTex=portals->room[room_num].usNbTextures; TextureContainer **ppTexCurr=portals->room[room_num].ppTextureContainer; while(iNbTex--) { TextureContainer *pTexCurr=*ppTexCurr; if (ViewMode & VIEWMODE_FLAT) SETTC(GDevice,NULL); else SETTC(GDevice,pTexCurr); if( (pTexCurr->userflags&POLY_METAL)&& (!bNoModulate2X) ) { GDevice->SetTextureStageState(0,D3DTSS_COLOROP,D3DTOP_MODULATE2X); } else { GDevice->SetTextureStageState(0,D3DTSS_COLOROP,D3DTOP_MODULATE); } if(pTexCurr->tMatRoom[room_num].uslNbIndiceCull) { GDevice->DrawIndexedPrimitiveVB( D3DPT_TRIANGLELIST, portals->room[room_num].pVertexBuffer, pTexCurr->tMatRoom[room_num].uslStartVertex, pTexCurr->tMatRoom[room_num].uslNbVertex, &portals->room[room_num].pussIndice[pTexCurr->tMatRoom[room_num].uslStartCull], pTexCurr->tMatRoom[room_num].uslNbIndiceCull, 0 ); EERIEDrawnPolys+=pTexCurr->tMatRoom[room_num].uslNbIndiceCull; pTexCurr->tMatRoom[room_num].uslNbIndiceCull=0; } ppTexCurr++; } ////////////////////////////// //ZMapp GDevice->SetTextureStageState(0,D3DTSS_COLOROP,D3DTOP_MODULATE); GDevice->SetRenderState(D3DRENDERSTATE_ALPHABLENDENABLE,TRUE); GDevice->SetRenderState(D3DRENDERSTATE_ZWRITEENABLE,FALSE); iNbTex=portals->room[room_num].usNbTextures; ppTexCurr=portals->room[room_num].ppTextureContainer; if( bSoftRender ) { while(iNbTex--) { TextureContainer *pTexCurr=*ppTexCurr; if( (pTexCurr->TextureRefinement)&& (pTexCurr->TextureRefinement->vPolyZMap.size()) ) { SETTC( GDevice, pTexCurr->TextureRefinement ); SMY_D3DVERTEX3 pVertex[6]; vector::iterator it= pTexCurr->TextureRefinement->vPolyZMap.begin(); for ( ; it != pTexCurr->TextureRefinement->vPolyZMap.end() ; ++it ) { EERIEPOLY * ep = *it; unsigned short iNbVertex = (ep->type & POLY_QUAD) ? 4 : 3; //--------------------------------------------------------------------------- // CALCUL float tu[4]; float tv[4]; float _fTransp[4]; unsigned short nu, nuu; long nrm = 0; if ( (EEfabs( ep->nrml[0].y ) >= 0.9f ) || (EEfabs( ep->nrml[1].y ) >= 0.9f ) || (EEfabs( ep->nrml[2].y ) >= 0.9f ) ) nrm = 1; for ( nu = 0, nuu = iNbVertex - 1 ; nu < iNbVertex ; nuu = nu++ ) { if ( nrm ) { tu[nu] = (ep->v[nu].sx * DIV50); tv[nu] = (ep->v[nu].sz * DIV50); } else { tu[nu] = ep->v[nu].tu * 4.f; tv[nu] = ep->v[nu].tv * 4.f; } float t = __max( 10, EEDistance3D(&ACTIVECAM->pos, (EERIE_3D *)&ep->v[nu]) - 80.f ); _fTransp[nu] = (150.f - t) * 0.006666666f; if (_fTransp[nu] < 0.f) _fTransp[nu] = 0.f; // t cannot be greater than 1.f (b should be negative for that) } //--------------------------------------------------------------------------- // FILL DATA for ( int idx = 0 ; idx < iNbVertex ; ++idx ) { pVertex[idx].x = ep->v[idx].sx; pVertex[idx].y = - ep->v[idx].sy; pVertex[idx].z = ep->v[idx].sz; pVertex[idx].color = D3DRGB( _fTransp[idx], _fTransp[idx], _fTransp[idx]); pVertex[idx].tu = tu[idx]; pVertex[idx].tv = tv[idx]; } if ( iNbVertex & 4 ) { pVertex[4] = pVertex[2]; pVertex[5] = pVertex[1]; } //Draw current prim EERIEDRAWPRIM(GDevice, D3DPT_TRIANGLELIST, FVF_D3DVERTEX3, pVertex, (iNbVertex&4)?6:3, 0, EERIE_NOCOUNT ); } //--------------------------------------------------------------------------- // CLEAR CURRENT ZMAP pTexCurr->TextureRefinement->vPolyZMap.clear(); } //MAJ POINTER ------------------------------------------------------------------- ppTexCurr++; }//END while ( iNbTex-- ) ---------------------------------------------------------- } else { while ( iNbTex-- ) //For each tex in portals->room[room_num] { TextureContainer * pTexCurr = *ppTexCurr; if ( ( pTexCurr->TextureRefinement ) && ( pTexCurr->TextureRefinement->vPolyZMap.size() ) ) { //--------------------------------------------------------------------------- // INIT int iOldNbVertex=pDynamicVertexBuffer->ussNbVertex; pDynamicVertexBuffer->ussNbIndice=0; SMY_D3DVERTEX3 *pVertex=(SMY_D3DVERTEX3*)pDynamicVertexBuffer->Lock(DDLOCK_NOOVERWRITE); pVertex+=iOldNbVertex; SETTC(GDevice,pTexCurr->TextureRefinement); unsigned short *pussInd=pDynamicVertexBuffer->pussIndice; unsigned short iNbIndice = 0; vector::iterator it = pTexCurr->TextureRefinement->vPolyZMap.begin(); //--------------------------------------------------------------------------- // LOOP for (; it != pTexCurr->TextureRefinement->vPolyZMap.end(); ++it) { EERIEPOLY * ep = *it; unsigned short iNbVertex = (ep->type & POLY_QUAD) ? 4 : 3; pDynamicVertexBuffer->ussNbVertex+=iNbVertex; //----------------------------------------------------------------------- // FLUSH if(pDynamicVertexBuffer->ussNbVertex>pDynamicVertexBuffer->ussMaxVertex) { pDynamicVertexBuffer->UnLock(); pDynamicVertexBuffer->ussNbVertex-=iNbVertex; if(pDynamicVertexBuffer->ussNbIndice) { GDevice->DrawIndexedPrimitiveVB( D3DPT_TRIANGLELIST, pDynamicVertexBuffer->pVertexBuffer, iOldNbVertex, pDynamicVertexBuffer->ussNbVertex-iOldNbVertex, pDynamicVertexBuffer->pussIndice, pDynamicVertexBuffer->ussNbIndice, 0 ); } //INIT -------------------------------------------------------------- pVertex=(SMY_D3DVERTEX3*)pDynamicVertexBuffer->Lock(DDLOCK_DISCARDCONTENTS); pDynamicVertexBuffer->ussNbVertex=iNbVertex; iOldNbVertex = iNbIndice = pDynamicVertexBuffer->ussNbIndice = 0; pussInd=pDynamicVertexBuffer->pussIndice; //iNbVertex = 3 or 4 but be sure to Assert in Debug if overflow ARX_CHECK( pDynamicVertexBuffer->ussNbVertex <= pDynamicVertexBuffer->ussMaxVertex ); } //----------------------------------------------------------------------- // PRECALCUL float tu[4]; float tv[4]; float _fTransp[4]; unsigned short nu, nuu; long nrm=0; if ( (EEfabs(ep->nrml[0].y)>=0.9f) || (EEfabs(ep->nrml[1].y)>=0.9f) || (EEfabs(ep->nrml[2].y)>=0.9f) ) nrm=1; for (nu=0,nuu=iNbVertex-1;nuv[nu].sx*DIV50); tv[nu]=(ep->v[nu].sz*DIV50); } else { tu[nu]=ep->v[nu].tu*4.f; tv[nu]=ep->v[nu].tv*4.f; } float t = __max( 10, EEDistance3D(&ACTIVECAM->pos, (EERIE_3D *)&ep->v[nu]) - 80.f ); //if (t < 10.f) t = 10.f; _fTransp[nu] = (150.f - t) * 0.006666666f; if (_fTransp[nu] < 0.f) _fTransp[nu] = 0.f; // t cannot be greater than 1.f (b should be negative for that) } //----------------------------------------------------------------------- // FILL DATA for ( int idx = 0 ; idx < iNbVertex ; ++idx ) { pVertex->x = ep->v[idx].sx; pVertex->y = - ep->v[idx].sy; pVertex->z = ep->v[idx].sz; pVertex->color = D3DRGB( _fTransp[idx], _fTransp[idx], _fTransp[idx]); pVertex->tu = tu[idx]; pVertex->tv = tv[idx]; pVertex++; *pussInd++ = iNbIndice++; pDynamicVertexBuffer->ussNbIndice++; } if(iNbVertex&4) { *pussInd++=iNbIndice-2; *pussInd++=iNbIndice-3; pDynamicVertexBuffer->ussNbIndice += 2;//3; } } //--------------------------------------------------------------------------- // CLEAR CURRENT ZMAP pTexCurr->TextureRefinement->vPolyZMap.clear(); pDynamicVertexBuffer->UnLock(); if(pDynamicVertexBuffer->ussNbIndice) { GDevice->DrawIndexedPrimitiveVB( D3DPT_TRIANGLELIST, pDynamicVertexBuffer->pVertexBuffer, iOldNbVertex, pDynamicVertexBuffer->ussNbVertex-iOldNbVertex, pDynamicVertexBuffer->pussIndice, pDynamicVertexBuffer->ussNbIndice, 0 ); } } //MAJ POINTER ------------------------------------------------------------------- ppTexCurr++; }//END while ( iNbTex-- ) ---------------------------------------------------------- } //METAL(Voodoo grand gourou) if(vPolyVoodooMetal.size()) { GDevice->SetRenderState(D3DRENDERSTATE_FOGCOLOR,0); unsigned long ulMetalColor=0x00101010; GDevice->SetTexture(0,NULL); int iOldNbVertex=pDynamicVertexBuffer->ussNbVertex; pDynamicVertexBuffer->ussNbIndice=0; SMY_D3DVERTEX3 *pVertex=(SMY_D3DVERTEX3*)pDynamicVertexBuffer->Lock(DDLOCK_NOOVERWRITE); pVertex+=iOldNbVertex; unsigned short *pussInd=pDynamicVertexBuffer->pussIndice; unsigned short iNbIndice = 0; GDevice->SetRenderState(D3DRENDERSTATE_SRCBLEND,D3DBLEND_ONE); GDevice->SetRenderState(D3DRENDERSTATE_DESTBLEND,D3DBLEND_ONE); vector::iterator iT; for(iT=vPolyVoodooMetal.begin();iTtype & POLY_QUAD) ? 4 : 3; pDynamicVertexBuffer->ussNbVertex+=iNbVertex; if(pDynamicVertexBuffer->ussNbVertex>pDynamicVertexBuffer->ussMaxVertex) { pDynamicVertexBuffer->UnLock(); pDynamicVertexBuffer->ussNbVertex-=iNbVertex; if(pDynamicVertexBuffer->ussNbIndice) { GDevice->DrawIndexedPrimitiveVB( D3DPT_TRIANGLELIST, pDynamicVertexBuffer->pVertexBuffer, iOldNbVertex, pDynamicVertexBuffer->ussNbVertex-iOldNbVertex, pDynamicVertexBuffer->pussIndice, pDynamicVertexBuffer->ussNbIndice, 0 ); } pVertex=(SMY_D3DVERTEX3*)pDynamicVertexBuffer->Lock(DDLOCK_DISCARDCONTENTS); pDynamicVertexBuffer->ussNbVertex=iNbVertex; iOldNbVertex = iNbIndice = pDynamicVertexBuffer->ussNbIndice = 0; pussInd=pDynamicVertexBuffer->pussIndice; //iNbVertex = 3 or 4 but be sure to Assert in Debug if overflow ARX_CHECK( pDynamicVertexBuffer->ussNbVertex <= pDynamicVertexBuffer->ussMaxVertex ); } pVertex->x=pPoly->v[0].sx; pVertex->y=-pPoly->v[0].sy; pVertex->z=pPoly->v[0].sz; pVertex->color=ulMetalColor; pVertex++; pVertex->x=pPoly->v[1].sx; pVertex->y=-pPoly->v[1].sy; pVertex->z=pPoly->v[1].sz; pVertex->color=ulMetalColor; pVertex++; pVertex->x=pPoly->v[2].sx; pVertex->y=-pPoly->v[2].sy; pVertex->z=pPoly->v[2].sz; pVertex->color=ulMetalColor; pVertex++; *pussInd++=iNbIndice++; *pussInd++=iNbIndice++; *pussInd++=iNbIndice++; pDynamicVertexBuffer->ussNbIndice+=3; if(iNbVertex&4) { pVertex->x=pPoly->v[3].sx; pVertex->y=-pPoly->v[3].sy; pVertex->z=pPoly->v[3].sz; pVertex->color=ulMetalColor; pVertex++; *pussInd++=iNbIndice++; *pussInd++=iNbIndice-2; *pussInd++=iNbIndice-3; pDynamicVertexBuffer->ussNbIndice+=3; } } pDynamicVertexBuffer->UnLock(); if(pDynamicVertexBuffer->ussNbIndice) { GDevice->DrawIndexedPrimitiveVB( D3DPT_TRIANGLELIST, pDynamicVertexBuffer->pVertexBuffer, iOldNbVertex, pDynamicVertexBuffer->ussNbVertex-iOldNbVertex, pDynamicVertexBuffer->pussIndice, pDynamicVertexBuffer->ussNbIndice, 0 ); } GDevice->SetRenderState(D3DRENDERSTATE_FOGCOLOR,ulBKGColor); GDevice->SetRenderState( D3DRENDERSTATE_SRCBLEND, D3DBLEND_ZERO ); GDevice->SetRenderState( D3DRENDERSTATE_DESTBLEND, D3DBLEND_INVSRCCOLOR ); vPolyVoodooMetal.clear(); } GDevice->SetRenderState(D3DRENDERSTATE_ZWRITEENABLE,TRUE); GDevice->SetRenderState(D3DRENDERSTATE_ALPHABLENDENABLE,FALSE); } } void CalculTriangleBump( const D3DTLVERTEX& v0, const D3DTLVERTEX& v1, const D3DTLVERTEX& v2, float *du, float *dv ); //----------------------------------------------------------------------------- void ARX_PORTALS_Frustrum_RenderRoom_TransparencyTSoftCull(long room_num) { if (RoomDraw[room_num].count) { //render transparency int iNbTex=portals->room[room_num].usNbTextures; TextureContainer **ppTexCurr=portals->room[room_num].ppTextureContainer; while(iNbTex--) { TextureContainer *pTexCurr=*ppTexCurr; //BUMP if( ( bALLOW_BUMP ) && ( pTexCurr->vPolyBump.size() ) ) { //---------------------------------------------------------------------------------- // Initializing CMY_DYNAMIC_VERTEXBUFFER* pDVB = pDynamicVertexBufferBump; SetZBias( GDevice, 0 ); int iOldNbVertex = pDVB->ussNbVertex; pDVB->ussNbIndice = 0; SMY_D3DVERTEX3* pVertex = (SMY_D3DVERTEX3*)pDVB->Lock( DDLOCK_NOOVERWRITE ); pVertex += iOldNbVertex; unsigned short *pussInd = pDVB->pussIndice; unsigned short iNbIndice = 0; GDevice->SetRenderState( D3DRENDERSTATE_SRCBLEND, D3DBLEND_DESTCOLOR ); GDevice->SetRenderState( D3DRENDERSTATE_DESTBLEND, D3DBLEND_SRCCOLOR ); GDevice->SetTexture( 0, pTexCurr->m_pddsBumpMap ); int iSimultaneousTexture = danaeApp.m_pDeviceInfo->wNbTextureSimultaneous; switch( iSimultaneousTexture ) { default: GDevice->SetTexture( 1, pTexCurr->m_pddsBumpMap ); GDevice->SetTextureStageState( 1, D3DTSS_TEXCOORDINDEX, 1 ); if( bGATI8500 && !bSoftRender ) { GDevice->SetTextureStageState( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE | D3DTA_COMPLEMENT ); GDevice->SetTextureStageState(1, D3DTSS_COLORARG1, D3DTA_TEXTURE); } else { GDevice->SetTextureStageState( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE ); GDevice->SetTextureStageState( 1, D3DTSS_COLORARG1, D3DTA_TEXTURE | D3DTA_COMPLEMENT ); } GDevice->SetTextureStageState( 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1 ); GDevice->SetTextureStageState( 1, D3DTSS_COLORARG2, D3DTA_CURRENT ); GDevice->SetTextureStageState( 1, D3DTSS_COLOROP, D3DTOP_ADDSIGNED ); GDevice->SetTextureStageState( 1, D3DTSS_ALPHAOP, D3DTOP_DISABLE ); GDevice->SetTextureStageState( 2, D3DTSS_COLOROP, D3DTOP_DISABLE ); break; case 1: GDevice->SetTextureStageState( 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1 ); GDevice->SetTextureStageState( 0, D3DTSS_ALPHAOP, D3DTOP_DISABLE ); GDevice->SetTextureStageState( 1, D3DTSS_COLOROP, D3DTOP_DISABLE ); break; } //---------------------------------------------------------------------------------- // Loop for( vector::iterator iT = pTexCurr->vPolyBump.begin() ; iT < pTexCurr->vPolyBump.end() ; iT++ ) { EERIEPOLY *pPoly = *iT; if( !pPoly->tv[0].color && !pPoly->tv[1].color && !pPoly->tv[2].color) continue; float fDu,fDv; EERIERTPPoly(pPoly); CalculTriangleBump( pPoly->tv[0], pPoly->tv[1], pPoly->tv[2], &fDu, &fDv ); fDu *= .8f; fDv *= .8f; const unsigned short iNbVertex = ( pPoly->type & POLY_QUAD )?4:3; pDVB->ussNbVertex += iNbVertex; //---------------------------------------------------------------------------------- // Flushing if( pDVB->ussNbVertex > pDVB->ussMaxVertex ) { pDVB->UnLock(); pDVB->ussNbVertex -= iNbVertex; if( pDVB->ussNbIndice ) { switch (iSimultaneousTexture) { case 1: GDevice->SetTextureStageState( 0, D3DTSS_TEXCOORDINDEX, 0 ); GDevice->SetTextureStageState( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE ); GDevice->DrawIndexedPrimitiveVB( D3DPT_TRIANGLELIST, pDVB->pVertexBuffer, iOldNbVertex, pDVB->ussNbVertex - iOldNbVertex, pDVB->pussIndice, pDVB->ussNbIndice, 0 ); GDevice->SetTextureStageState( 0, D3DTSS_TEXCOORDINDEX, 1 ); GDevice->SetTextureStageState( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE | D3DTA_COMPLEMENT ); default: GDevice->DrawIndexedPrimitiveVB( D3DPT_TRIANGLELIST, pDVB->pVertexBuffer, iOldNbVertex, pDVB->ussNbVertex-iOldNbVertex, pDVB->pussIndice, pDVB->ussNbIndice, 0 ); break; } } pVertex = (SMY_D3DVERTEX3*)pDVB->Lock(DDLOCK_DISCARDCONTENTS); pDVB->ussNbVertex = iNbVertex; iOldNbVertex = iNbIndice = pDVB->ussNbIndice = 0; pussInd = pDVB->pussIndice; ARX_CHECK( pDVB->ussNbVertex <= pDVB->ussMaxVertex ); } //---------------------------------------------------------------------------------- // Filling VB //Add 3 Vertices for( short int idx = 0 ; idx < 3 ; ++idx ) { pVertex->x = pPoly->v[idx].sx; pVertex->y = -pPoly->v[idx].sy; pVertex->z = pPoly->v[idx].sz; pVertex->color = ARX_OPAQUE_WHITE; pVertex->tu = pPoly->v[idx].tu; pVertex->tv = pPoly->v[idx].tv; pVertex->tu2 = pPoly->v[idx].tu + fDu; pVertex->tv2 = pPoly->v[idx].tv + fDv; pVertex++; } //Add Triangle 0-1-2 in Indices Tab *pussInd++ = iNbIndice++; *pussInd++ = iNbIndice++; *pussInd++ = iNbIndice++; pDVB->ussNbIndice += 3; if(iNbVertex&4) { //Add vertex pVertex->x = pPoly->v[3].sx; pVertex->y = -pPoly->v[3].sy; pVertex->z = pPoly->v[3].sz; pVertex->color = ARX_OPAQUE_WHITE;//pPoly->tv[3].color; pVertex->tu = pPoly->v[3].tu; pVertex->tv = pPoly->v[3].tv; pVertex->tu2 = pPoly->v[3].tu + fDu; pVertex->tv2 = pPoly->v[3].tv + fDv; pVertex++; //Add 2nd triangle 1-2-3 *pussInd++=iNbIndice++; *pussInd++=iNbIndice-2; *pussInd++=iNbIndice-3; pDVB->ussNbIndice += 3; } } //---------------------------------------------------------------------------------- // Drawing pDVB->UnLock(); if( pDVB->ussNbIndice ) { switch( iSimultaneousTexture ) { case 1: GDevice->SetTextureStageState( 0, D3DTSS_TEXCOORDINDEX, 0 ); GDevice->SetTextureStageState( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE ); GDevice->DrawIndexedPrimitiveVB( D3DPT_TRIANGLELIST, pDVB->pVertexBuffer, iOldNbVertex, pDVB->ussNbVertex-iOldNbVertex, pDVB->pussIndice, pDVB->ussNbIndice, 0 ); GDevice->SetTextureStageState( 0, D3DTSS_TEXCOORDINDEX, 1 ); GDevice->SetTextureStageState( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE | D3DTA_COMPLEMENT ); default: GDevice->DrawIndexedPrimitiveVB( D3DPT_TRIANGLELIST, pDVB->pVertexBuffer, iOldNbVertex, pDVB->ussNbVertex-iOldNbVertex, pDVB->pussIndice, pDVB->ussNbIndice, 0 ); break; } } //---------------------------------------------------------------------------------- // Ending GDevice->SetTextureStageState( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE ); GDevice->SetTextureStageState( 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE ); GDevice->SetTextureStageState( 0, D3DTSS_COLOROP, D3DTOP_MODULATE ); GDevice->SetTextureStageState( 1, D3DTSS_COLOROP, D3DTOP_DISABLE ); GDevice->SetTextureStageState( 0, D3DTSS_TEXCOORDINDEX, 0 ); //Flushing vector pTexCurr->vPolyBump.clear(); } // END BUMP SETTC(GDevice,pTexCurr); //NORMAL TRANS if(pTexCurr->tMatRoom[room_num].uslNbIndiceCull_TNormalTrans) { SetZBias(GDevice,2); GDevice->SetRenderState( D3DRENDERSTATE_SRCBLEND, D3DBLEND_SRCCOLOR); GDevice->SetRenderState( D3DRENDERSTATE_DESTBLEND, D3DBLEND_DESTCOLOR); GDevice->DrawIndexedPrimitiveVB( D3DPT_TRIANGLELIST, portals->room[room_num].pVertexBuffer, pTexCurr->tMatRoom[room_num].uslStartVertex, pTexCurr->tMatRoom[room_num].uslNbVertex, &portals->room[room_num].pussIndice[pTexCurr->tMatRoom[room_num].uslStartCull_TNormalTrans], pTexCurr->tMatRoom[room_num].uslNbIndiceCull_TNormalTrans, 0 ); EERIEDrawnPolys+=pTexCurr->tMatRoom[room_num].uslNbIndiceCull_TNormalTrans; pTexCurr->tMatRoom[room_num].uslNbIndiceCull_TNormalTrans=0; } //MULTIPLICATIVE if(pTexCurr->tMatRoom[room_num].uslNbIndiceCull_TMultiplicative) { SetZBias(GDevice,2); GDevice->SetRenderState( D3DRENDERSTATE_SRCBLEND, D3DBLEND_ONE); GDevice->SetRenderState( D3DRENDERSTATE_DESTBLEND, D3DBLEND_ONE); GDevice->DrawIndexedPrimitiveVB( D3DPT_TRIANGLELIST, portals->room[room_num].pVertexBuffer, pTexCurr->tMatRoom[room_num].uslStartVertex, pTexCurr->tMatRoom[room_num].uslNbVertex, &portals->room[room_num].pussIndice[pTexCurr->tMatRoom[room_num].uslStartCull_TMultiplicative], pTexCurr->tMatRoom[room_num].uslNbIndiceCull_TMultiplicative, 0 ); EERIEDrawnPolys+=pTexCurr->tMatRoom[room_num].uslNbIndiceCull_TMultiplicative; pTexCurr->tMatRoom[room_num].uslNbIndiceCull_TMultiplicative=0; } //ADDITIVE if(pTexCurr->tMatRoom[room_num].uslNbIndiceCull_TAdditive) { SetZBias(GDevice,2); GDevice->SetRenderState( D3DRENDERSTATE_SRCBLEND, D3DBLEND_ONE); GDevice->SetRenderState( D3DRENDERSTATE_DESTBLEND, D3DBLEND_ONE); GDevice->DrawIndexedPrimitiveVB( D3DPT_TRIANGLELIST, portals->room[room_num].pVertexBuffer, pTexCurr->tMatRoom[room_num].uslStartVertex, pTexCurr->tMatRoom[room_num].uslNbVertex, &portals->room[room_num].pussIndice[pTexCurr->tMatRoom[room_num].uslStartCull_TAdditive], pTexCurr->tMatRoom[room_num].uslNbIndiceCull_TAdditive, 0 ); EERIEDrawnPolys+=pTexCurr->tMatRoom[room_num].uslNbIndiceCull_TAdditive; pTexCurr->tMatRoom[room_num].uslNbIndiceCull_TAdditive=0; } //SUBSTRACTIVE if(pTexCurr->tMatRoom[room_num].uslNbIndiceCull_TSubstractive) { if(danaeApp.m_pFramework->bitdepth==16) SetZBias(GDevice,1); else SetZBias(GDevice,8); GDevice->SetRenderState( D3DRENDERSTATE_SRCBLEND, D3DBLEND_ZERO); GDevice->SetRenderState( D3DRENDERSTATE_DESTBLEND, D3DBLEND_INVSRCCOLOR); GDevice->DrawIndexedPrimitiveVB( D3DPT_TRIANGLELIST, portals->room[room_num].pVertexBuffer, pTexCurr->tMatRoom[room_num].uslStartVertex, pTexCurr->tMatRoom[room_num].uslNbVertex, &portals->room[room_num].pussIndice[pTexCurr->tMatRoom[room_num].uslStartCull_TSubstractive], pTexCurr->tMatRoom[room_num].uslNbIndiceCull_TSubstractive, 0 ); EERIEDrawnPolys+=pTexCurr->tMatRoom[room_num].uslNbIndiceCull_TSubstractive; pTexCurr->tMatRoom[room_num].uslNbIndiceCull_TSubstractive=0; } ppTexCurr++; } } } void ARX_PORTALS_ComputeRoom(long room_num,EERIE_2D_BBOX * bbox,long prec,long tim) { if (portals==NULL) return; if (bbox->min.x>=DANAESIZX) return; if (bbox->min.y>=DANAESIZY) return; if (bbox->max.x<0) return; if (bbox->max.y<0) return; if (bbox->min.x>=bbox->max.x) return; if (bbox->min.y>=bbox->max.y) return; if (RoomDraw[room_num].count==0) RoomDrawListAdd(room_num); ARX_PORTALS_BlendBBox(room_num,bbox); RoomDraw[room_num].count++; // Now Checks For room Portals !!! for (long lll=0;lllroom[room_num].nb_portals;lll++) { if (portals->portals[portals->room[room_num].portals[lll]].useportal) continue; EERIE_PORTALS * po=&portals->portals[portals->room[room_num].portals[lll]]; EERIEPOLY * epp=&po->poly; float dist1=EEDistance3D(&ACTIVECAM->pos,(EERIE_3D *)&epp->v[0]); float dist2=EEDistance3D(&ACTIVECAM->pos,(EERIE_3D *)&epp->v[2]); float distc=EEDistance3D(&ACTIVECAM->pos,(EERIE_3D *)&epp->center); float threshold=ACTIVECAM->cdepth*fZFogEnd; if ( (dist1 > ACTIVECAM->cdepth-threshold) && (dist2 > ACTIVECAM->cdepth-threshold) && (distc > ACTIVECAM->cdepth-threshold) ) { portals->portals[portals->room[room_num].portals[lll]].useportal=2; continue; } if (!EERIERTPPoly2(epp)) continue; int Cull=BackFaceCull2D(epp->tv); EERIE_2D_BBOX n_bbox; n_bbox.max.x=n_bbox.min.x=epp->tv[0].sx; n_bbox.max.y=n_bbox.min.y=epp->tv[0].sy; long to; if (epp->type & POLY_QUAD) to=4; else to=3; float minz=epp->tv[0].sz; float maxz=epp->tv[0].sz; for (long nn=1;nntv[nn].sx); n_bbox.min.y=__min(n_bbox.min.y , epp->tv[nn].sy); n_bbox.max.x=__max(n_bbox.max.x , epp->tv[nn].sx); n_bbox.max.y=__max(n_bbox.max.y , epp->tv[nn].sy); minz=__min(minz,epp->tv[0].sz); maxz=__max(maxz,epp->tv[0].sz); } if (minz>0.5f) continue; if ( bbox->min.x > n_bbox.max.x || n_bbox.min.x > bbox->max.x || bbox->min.y > n_bbox.max.y || n_bbox.min.y > bbox->max.y) continue; if (Cull) EERIEPOLY_DrawWired(GDevice,epp,0xFFFF0000); else EERIEPOLY_DrawWired(GDevice,epp,0xFF00FF00); n_bbox.min.x=__max(n_bbox.min.x,bbox->min.x); n_bbox.min.y=__max(n_bbox.min.y,bbox->min.y); n_bbox.max.x=__min(n_bbox.max.x,bbox->max.x); n_bbox.max.y=__min(n_bbox.max.y,bbox->max.y); if (po->room_1==room_num) { if (!Cull) { portals->portals[portals->room[room_num].portals[lll]].useportal=1; ARX_PORTALS_ComputeRoom(po->room_2,&n_bbox,prec,tim); } } else if (po->room_2==room_num) { if (Cull) { portals->portals[portals->room[room_num].portals[lll]].useportal=1; ARX_PORTALS_ComputeRoom(po->room_1,&n_bbox,prec,tim); } } } } long ARX_PORTALS_Frustrum_ComputeRoom(long room_num,EERIE_FRUSTRUM * frustrum,long prec,long tim) { long portals_count=0; if (portals==NULL) return 0; if (RoomDraw[room_num].count==0) { RoomDrawListAdd(room_num); } RoomFrustrumAdd(room_num,frustrum); RoomDraw[room_num].count++; float fClippZFar=ACTIVECAM->cdepth*(fZFogEnd*1.1f); // Now Checks For room Portals !!! for (long lll=0;lllroom[room_num].nb_portals;lll++) { if (portals->portals[portals->room[room_num].portals[lll]].useportal) continue; EERIE_PORTALS * po=&portals->portals[portals->room[room_num].portals[lll]]; EERIEPOLY * epp=&po->poly; //clipp NEAR & FAR unsigned char ucVisibilityNear=0; unsigned char ucVisibilityFar=0; float fDist0=(efpPlaneNear.a*epp->v[0].sx)+(efpPlaneNear.b*epp->v[0].sy)+(efpPlaneNear.c*epp->v[0].sz)+efpPlaneNear.d; if(fDist0<0.f) ucVisibilityNear++; else { if(fDist0>fClippZFar) ucVisibilityFar++; } fDist0=(efpPlaneNear.a*epp->v[1].sx)+(efpPlaneNear.b*epp->v[1].sy)+(efpPlaneNear.c*epp->v[1].sz)+efpPlaneNear.d; if(fDist0<0.f) ucVisibilityNear++; else { if(fDist0>fClippZFar) ucVisibilityFar++; } fDist0=(efpPlaneNear.a*epp->v[2].sx)+(efpPlaneNear.b*epp->v[2].sy)+(efpPlaneNear.c*epp->v[2].sz)+efpPlaneNear.d; if(fDist0<0.f) ucVisibilityNear++; else { if(fDist0>fClippZFar) ucVisibilityFar++; } fDist0=(efpPlaneNear.a*epp->v[3].sx)+(efpPlaneNear.b*epp->v[3].sy)+(efpPlaneNear.c*epp->v[3].sz)+efpPlaneNear.d; if(fDist0<0.f) ucVisibilityNear++; else { if(fDist0>fClippZFar) ucVisibilityFar++; } if( (ucVisibilityFar&4)||(ucVisibilityNear&4) ) { portals->portals[portals->room[room_num].portals[lll]].useportal=2; continue; } EERIE_3D pos; pos.x=epp->center.x-ACTIVECAM->pos.x; pos.y=epp->center.y-ACTIVECAM->pos.y; pos.z=epp->center.z-ACTIVECAM->pos.z; float fRes = Vector_DotProduct(&pos, &epp->norm); long to; if (epp->type & POLY_QUAD) to=4; else to=3; long ret=1; if(IsSphereInFrustrum(epp->v[0].rhw,&epp->center,frustrum)) { ret=0; } if (ret) { EERIERTPPoly2(epp); if (NEED_TEST_TEXT) EERIEPOLY_DrawWired(GDevice,epp,0xFFFF00FF); continue; } portals_count++; EERIERTPPoly2(epp); int Cull; if (fRes<0.f) Cull=0; else Cull=1; EERIE_FRUSTRUM fd; CreateFrustrum(&fd,epp,Cull); if (NEED_TEST_TEXT) { if (Cull) EERIEPOLY_DrawWired(GDevice,epp,0xFFFF0000); else EERIEPOLY_DrawWired(GDevice,epp,0xFF00FF00); } if (po->room_1==room_num) { if (!Cull) { portals->portals[portals->room[room_num].portals[lll]].useportal=1; ARX_PORTALS_Frustrum_ComputeRoom(po->room_2,&fd,prec,tim); } } else if (po->room_2==room_num) { if (Cull) { portals->portals[portals->room[room_num].portals[lll]].useportal=1; ARX_PORTALS_Frustrum_ComputeRoom(po->room_1,&fd,prec,tim); } } } return portals_count; } BOOL Clip_Visible(const EERIE_3D * orgn, EERIE_3D * dest) { register float dx,dy,dz,adx,ady,adz,ix,iy,iz; register float x0,y0,z0; register float forr,temp; dx=(dest->x-orgn->x); adx=EEfabs(dx); dy=(dest->y-orgn->y); ady=EEfabs(dy); dz=(dest->z-orgn->z); adz=EEfabs(dz); x0=orgn->x; y0=orgn->y; z0=orgn->z; if ( (adx>=ady) && (adx>=adz)) { if (adx != dx) { ix = -1.f * PASS; } else { ix = 1.f * PASS; } forr=adx; temp=1.f/(adx/PASS); iy=dy*temp; iz=dz*temp; } else if ( (ady>=adx) && (ady>=adz)) { if (ady != dy) { iy = -1.f * PASS; } else { iy = 1.f * PASS; } forr=ady; temp=1.f/(ady/PASS); ix=dx*temp; iz=dz*temp; } else { if (adz != dz) { iz = -1.f * PASS; } else { iz = 1.f * PASS; } forr=adz; temp=1.f/(adz/PASS); ix=dx*temp; iy=dy*temp; } long curpixel; long tot; tot=0; long x,y; FAST_BKG_DATA * LAST_eg=NULL; curpixel=2; x0+=ix*2; y0+=iy*2; z0+=iz*2; forr-=PASS*2; while (forr>PASSS) { FAST_BKG_DATA * feg; F2L(x0*ACTIVEBKG->Xmul,&x); F2L(z0*ACTIVEBKG->Zmul,&y); feg=&ACTIVEBKG->fastdata[x][y]; if (feg!=LAST_eg) { LAST_eg=feg; if (feg->nothing) tot += 2; if (tot>MAX_OUT) return FALSE; } float v=(float)curpixel*DIV5; if (v<1.f) v=1.f; x0+=ix*v; y0+=iy*v; z0+=iz*v; forr-=PASS*v; } return TRUE;//hard; } BOOL spGetTruePolyY(const EERIEPOLY * ep, const EERIE_3D * pos, float * ret) { register EERIE_3D n,s21,s31; s21.x=ep->v[1].sx-ep->v[0].sx; s21.y=ep->v[1].sy-ep->v[0].sy; s21.z=ep->v[1].sz-ep->v[0].sz; s31.x=ep->v[2].sx-ep->v[0].sx; s31.y=ep->v[2].sy-ep->v[0].sy; s31.z=ep->v[2].sz-ep->v[0].sz; n.y=(s21.z*s31.x)-(s21.x*s31.z); n.x=(s21.y*s31.z)-(s21.z*s31.y); n.z=(s21.x*s31.y)-(s21.y*s31.x); // uses s21.x instead of d s21.x=ep->v[0].sx*n.x+ep->v[0].sy*n.y+ep->v[0].sz*n.z; s21.x=(s21.x-(n.x*pos->x)-(n.z*pos->z))/n.y; *ret=s21.x; return TRUE; } extern long SPECIAL_DRAGINTER_RENDER; long MAX_FRAME_COUNT=0; //************************************************************************************* // Main Background Rendering Proc. // ie: Big Mess //************************************************************************************* /////////////////////////////////////////////////////////// void ARX_SCENE_Render(LPDIRECT3DDEVICE7 pd3dDevice, long flag, long param) { FrameCount++; FRAME_COUNT++; if (FRAME_COUNT>MAX_FRAME_COUNT) FRAME_COUNT=0; if (!TESTMODE) FRAME_COUNT=0; if (EDITMODE) FRAME_COUNT=0; if ((player.Interface & INTER_MAP ) && (!(player.Interface & INTER_COMBATMODE))) FRAME_COUNT=0; if (D3DTRANSFORM) { ARX_HWTransform_Render(); return; } static EERIE_3D lastpos; static EERIE_3D lastangle; static float lastfocal; long to; static long x0=0; static long x1=0; static long z0=0; static long z1=0; long i,j,k; float xx,yy; float fr, fb, ffr; EERIEPOLY * ep; FAST_BKG_DATA * feg; long temp; float dd; long lr; unsigned long tim = ARXTimeUL(); WATEREFFECT+=0.0005f*_framedelay; // First if scene camera hasn't moved we set MODIF to 0 // This allows us not to Clip/Rotate/Translate/Project again the scene BOOL MODIF=TRUE; if (flag == 3) { lastpos.x = 0.f; return; } if ( (lastpos.x == ACTIVECAM->pos.x) && (lastpos.y == ACTIVECAM->pos.y) && (lastpos.z == ACTIVECAM->pos.z) && (lastangle.a == ACTIVECAM->angle.a) && (lastangle.b == ACTIVECAM->angle.b) && (lastangle.g == ACTIVECAM->angle.g) && (lastfocal == ACTIVECAM->focal ) ) MODIF=0; else { lastpos.x = ACTIVECAM->pos.x; lastpos.y = ACTIVECAM->pos.y; lastpos.z = ACTIVECAM->pos.z; lastangle.a = ACTIVECAM->angle.a; lastangle.b = ACTIVECAM->angle.b; lastangle.g = ACTIVECAM->angle.g; lastfocal = ACTIVECAM->focal; MODIF=1; } // If LightThread is running we suspend it to avoid too much performance // decrease and eventual interference if (LIGHTTHREAD) SuspendThread(LIGHTTHREAD); float cval=(float)ACTIVECAM->clip3D+4; long lcval; F2L(cval,&lcval); { PrepareActiveCamera(); xx=(float)(ACTIVECAM->pos.x*ACTIVEBKG->Xmul); yy=(float)(ACTIVECAM->pos.z*ACTIVEBKG->Zmul); F2L(xx,&ACTIVECAM->Xsnap); F2L(yy,&ACTIVECAM->Zsnap); FORCERANGE(ACTIVECAM->Xsnap,0,ACTIVEBKG->Xsize-1); FORCERANGE(ACTIVECAM->Zsnap,0,ACTIVEBKG->Zsize-1); x0=ACTIVECAM->Xsnap-lcval; x1=ACTIVECAM->Xsnap+lcval; z0=ACTIVECAM->Zsnap-lcval; z1=ACTIVECAM->Zsnap+lcval; FORCERANGE(x0,0,ACTIVEBKG->Xsize-1); FORCERANGE(x1,0,ACTIVEBKG->Xsize-1); FORCERANGE(z0,0,ACTIVEBKG->Zsize-2); FORCERANGE(z1,0,ACTIVEBKG->Xsize-2); ACTIVEBKG->Backg[ACTIVECAM->Xsnap+ACTIVECAM->Zsnap * ACTIVEBKG->Xsize].treat = 1; float prec = 1.f / (ACTIVECAM->cdepth * ACTIVECAM->Zmul); long lll; #ifdef USE_RTS { ResetWorlds(); CreatePWorld(x0,x1,z0,z1); ComputeSworld(); } #endif DRAWLATER_ReInit(); // Temporary Hack... long LAST_FC=FRAME_COUNT; FRAME_COUNT=0; if ((FRAME_COUNT<=0) && (ModeLight & MODE_DYNAMICLIGHT)) PrecalcDynamicLighting(x0,z0,x1,z1); float temp0=DEG2RAD(ACTIVECAM->angle.b); ACTIVECAM->norm.x=-(float)EEsin(temp0); ACTIVECAM->norm.y= (float)EEsin(DEG2RAD(ACTIVECAM->angle.a)); ACTIVECAM->norm.z= (float)EEcos(temp0); float dddd=1.f/EEsqrt(ACTIVECAM->norm.x*ACTIVECAM->norm.x+ACTIVECAM->norm.y*ACTIVECAM->norm.y+ACTIVECAM->norm.z*ACTIVECAM->norm.z); ACTIVECAM->norm.x*=dddd; ACTIVECAM->norm.y*=dddd; ACTIVECAM->norm.z*=dddd; // Go for a growing-square-spirallike-render around the camera position // (To maximize Z-Buffer efficiency) temp0=0; EERIE_3D nrm; long lfr,lfb; long zsnap=ACTIVECAM->Zsnap; zsnap=__min(zsnap,ACTIVEBKG->Zsize-1); zsnap=__max(zsnap,1); long xsnap=ACTIVECAM->Xsnap; xsnap=__min(xsnap,ACTIVEBKG->Xsize-1); xsnap=__max(xsnap,1); if (!USE_LIGHT_OPTIM) { for (j=0;jZsize;j++) { feg=&ACTIVEBKG->fastdata[0][j]; for (i=0; iXsize; i++, *feg++) { if (feg->treat) feg->treat=0; } } } else { for (j=z0;j<=z1;j++) { for (i=x0; ifastdata[i][j]; feg->treat=0; } } for (j=0;jZsize;j++) for (i=0; iXsize; i++) { if (tilelights[i][j].num) tilelights[i][j].num=0; } } if ((!HIDEANCHORS) || DEBUG_FRUSTRUM) for (long n=0;n<=lcval;n++) { temp0+=100.f; for (j=zsnap-n;j<=zsnap+n;j++) { for (i=xsnap-n;i<=xsnap+n;i++) { if ( (i!=xsnap-n) && (i!=xsnap+n) && (j!=zsnap-n) && (j!=zsnap+n) ) continue; if ( (i<0) || (j<0) || (i>=ACTIVEBKG->Xsize) || (j>=ACTIVEBKG->Zsize) ) continue; if (ix1) continue; feg = &ACTIVEBKG->fastdata[i][j]; if (!HIDEANCHORS) for (lll=0;lllnbianchors;lll++) { _ANCHOR_DATA * ad=&ACTIVEBKG->anchors[feg->ianchors[lll]]; ad->pos.y-=10; if (ad->nblinked==0) DebugSphere(ad->pos.x,ad->pos.y,ad->pos.z,3.f,90,0xFF00FF00); else { if (ad->flags & ANCHOR_FLAG_BLOCKED) DebugSphere(ad->pos.x,ad->pos.y,ad->pos.z,3.f,90,0xFF00FFFF); else if (ad->flags & 1) DebugSphere(ad->pos.x,ad->pos.y,ad->pos.z,3.f,90,0xFF00FF00); else DebugSphere(ad->pos.x,ad->pos.y,ad->pos.z,3.f,90,0xFFFF0000); } for (long k=0;knblinked;k++) { _ANCHOR_DATA * ad2=&ACTIVEBKG->anchors[ad->linked[k]]; ad2->pos.y-=10; if ((ad->flags & 1) && (ad2->flags & 1)) EERIEDrawTrue3DLine(pd3dDevice,&ad->pos,&ad2->pos,0xFF00FF00); else EERIEDrawTrue3DLine(pd3dDevice,&ad->pos,&ad2->pos,0xFFFF0000); ad2->pos.y+=10; } ad->pos.y+=10; if (DEBUGNPCMOVE) { EERIE_CYLINDER cyl; cyl.origin.x=ad->pos.x; cyl.origin.y=ad->pos.y; cyl.origin.z=ad->pos.z; cyl.radius=ad->radius; cyl.height=ad->height; EERIEDraw3DCylinderBase(GDevice,&cyl,0xFFFFFF00); } } if (DEBUG_FRUSTRUM) { DebugSphere(i*ACTIVEBKG->Xdiv+50.f,feg->frustrum_maxy,j*ACTIVEBKG->Zdiv+50.f,3.f,90,0xFFFF00FF); DebugSphere(i*ACTIVEBKG->Xdiv+50.f,feg->frustrum_miny,j*ACTIVEBKG->Zdiv+50.f,3.f,90,0xFFFFFF00); } } } } if (USE_PORTALS && portals) { long room_num=ARX_PORTALS_GetRoomNumForPosition(&ACTIVECAM->pos,1); LAST_ROOM=room_num; if (room_num>-1) { ARX_PORTALS_InitDrawnRooms(); ARX_CHECK_LONG( prec ); long lprec = ARX_CLEAN_WARN_CAST_LONG( prec ); switch (USE_PORTALS) { case 1: EERIE_2D_BBOX bbox; bbox.min.x=0; bbox.min.y=0; bbox.max.x = ARX_CLEAN_WARN_CAST_FLOAT( DANAESIZX ); bbox.max.y = ARX_CLEAN_WARN_CAST_FLOAT( DANAESIZY ); ARX_PORTALS_ComputeRoom(room_num,&bbox,lprec,tim); ARX_PORTALS_RenderRooms(lprec,tim); break; case 2: EERIE_FRUSTRUM frustrum; CreateScreenFrustrum(&frustrum); LAST_PORTALS_COUNT=ARX_PORTALS_Frustrum_ComputeRoom(room_num,&frustrum,lprec,tim); ARX_PORTALS_Frustrum_RenderRooms(lprec,tim); break; case 3: CreateScreenFrustrum(&frustrum); LAST_PORTALS_COUNT=ARX_PORTALS_Frustrum_ComputeRoom(room_num,&frustrum,lprec,tim); ARX_PORTALS_Frustrum_RenderRoomsT(lprec,tim); break; case 4: CreateScreenFrustrum(&frustrum); LAST_PORTALS_COUNT=ARX_PORTALS_Frustrum_ComputeRoom(room_num,&frustrum,lprec,tim); ARX_PORTALS_Frustrum_RenderRoomsTCullSoft(lprec,tim); break; break; } //ARX_SCENE_DilateBackground(); } } else { for (long n=0;n<=lcval;n++) { temp0+=100.f; for (j=zsnap-n;j<=zsnap+n;j++) { for (i=xsnap-n;i<=xsnap+n;i++) { if ( (i!=xsnap-n) && (i!=xsnap+n) && (j!=zsnap-n) && (j!=zsnap+n) ) { continue; } if ( (i<0) || (j<0) || (i>=ACTIVEBKG->Xsize) || (j>=ACTIVEBKG->Zsize) ) continue; if (ix1) continue; feg = &ACTIVEBKG->fastdata[i][j]; if (!feg->treat) continue; for ( lll=0;lllnbpoly;lll++) { //SPECIFIC INTEL COMPILER ep=&feg->polydata[lll]; if (ep->type & (POLY_IGNORE | POLY_NODRAW)) continue; if ((ep->min.y > feg->frustrum_maxy) || (ep->max.y < feg->frustrum_miny)) continue; // GO for 3D Backface Culling if (ep->type & POLY_DOUBLESIDED) SETCULL( pd3dDevice, D3DCULL_NONE ); else { nrm.x=ep->v[2].sx-ACTIVECAM->pos.x; nrm.y=ep->v[2].sy-ACTIVECAM->pos.y; nrm.z=ep->v[2].sz-ACTIVECAM->pos.z; if ( ep->type & POLY_QUAD) { if ( (DOTPRODUCT( ep->norm , nrm )>0.f) && (DOTPRODUCT( ep->norm2 , nrm )>0.f) ) continue; } else if ( DOTPRODUCT( ep->norm , nrm )>0.f) continue; SETCULL( pd3dDevice, D3DCULL_CW ); } if (!EERIERTPPoly(ep)) continue; if ( ep->type & POLY_QUAD) { if (FRAME_COUNT<=0) ep->tv[3].color=ep->v[3].color; to=4; } else to=3; if (FRAME_COUNT<=0) { if (!USE_D3DFOG) ComputeFog(ep->tv,to); } if (ep->type & POLY_TRANS) { ManageLavaWater(ep,to,tim); TransPol[TRANSPOLYSPOS++]=ep; if (TRANSPOLYSPOS>=MAX_TRANSPOL) TRANSPOLYSPOS=MAX_TRANSPOL-1; if (ViewMode) { if (ViewMode & VIEWMODE_WIRE) EERIEPOLY_DrawWired(pd3dDevice,ep); if (ViewMode & VIEWMODE_NORMALS) EERIEPOLY_DrawNormals(pd3dDevice,ep); } continue; } if (!Project.improve) // Normal View... { if (ep->type & POLY_GLOW) ep->tv[0].color=ep->tv[1].color=ep->tv[2].color=ep->tv[3].color=0xFFFFFFFF; else { if (FRAME_COUNT<=0) { if (ModeLight & MODE_DYNAMICLIGHT) ApplyDynLight(ep); else { ep->tv[0].color=ep->v[0].color; ep->tv[1].color=ep->v[1].color; ep->tv[2].color=ep->v[2].color; } } } ManageLavaWater(ep,to,tim); Delayed_EERIEDRAWPRIM(ep); if (ViewMode) { if (ViewMode & VIEWMODE_WIRE) EERIEPOLY_DrawWired(pd3dDevice,ep); if (ViewMode & VIEWMODE_NORMALS) EERIEPOLY_DrawNormals(pd3dDevice,ep); } } else // Improve Vision Activated { if (FRAME_COUNT<=0) { if ( ModeLight & MODE_DYNAMICLIGHT ) ApplyDynLight(ep); else { ep->tv[0].color=ep->v[0].color; ep->tv[1].color=ep->v[1].color; ep->tv[2].color=ep->v[2].color; } for (k=0;ktv[k].color>>16) & 255; ffr=(float)(lr); dd=(ep->tv[k].sz*prec); if (dd>1.f) dd=1.f; if (dd<0.f) dd=0.f; fb=((1.f-dd)*6.f + (EEfabs(ep->nrml[k].x)+EEfabs(ep->nrml[k].y)))*0.125f; fr=((0.6f-dd)*6.f + (EEfabs(ep->nrml[k].z)+EEfabs(ep->nrml[k].y)))*0.125f;//(1.f-dd); if (fr<0.f) fr=0.f; else fr=__max(ffr,fr*255.f); fb*=255.f; F2L(fr,&lfr); F2L(fb,&lfb); F2L(fr,&lfr); ep->tv[k].color=( 0xff001E00L | ( (lfr & 255) << 16) | (lfb & 255) ); //GG component locked at 0x1E } } Delayed_EERIEDRAWPRIM(ep); } } } } } } if(pGetInfoDirectInput->IsVirtualKeyPressedNowPressed(DIK_J)) bOLD_CLIPP=!bOLD_CLIPP; if ((SHOWSHADOWS) && (!Project.improve)) ARXDRAW_DrawInterShadows(pd3dDevice); FRAME_COUNT=LAST_FC; if(USE_PORTALS<3) Delayed_FlushAll(pd3dDevice); ARX_CHECK_ULONG(FrameDiff); ARX_THROWN_OBJECT_Manage(ARX_CLEAN_WARN_CAST_ULONG(FrameDiff)); VF_CLIP_IO=1; RenderInter(pd3dDevice, 0.f, 3200.f); VF_CLIP_IO=0; if (DRAGINTER) // To render Dragged objs { SPECIAL_DRAGINTER_RENDER=1; ARX_INTERFACE_RenderCursor(); if(USE_PORTALS<3) Delayed_FlushAll(pd3dDevice); SPECIAL_DRAGINTER_RENDER=0; } PopAllTriangleList(true); } if (EXTERNALVIEW) ARXDRAW_DrawExternalView(pd3dDevice); DRAWLATER_Render(pd3dDevice); if (DEBUGCODE) ForceSendConsole("RenderBackground - Boom",1,0,(HWND)1); if (ACTIVECAM->type!=CAM_TOPVIEW) { if ((eyeball.exist!=0) && eyeballobj) ARXDRAW_DrawEyeBall(pd3dDevice); SETZWRITE(pd3dDevice, FALSE ); if (BoomCount) ARXDRAW_DrawPolyBoom(pd3dDevice); if (INTERTRANSPOLYSPOS&&(!bRenderInterList)) ARXDRAW_DrawAllInterTransPolyPos(pd3dDevice); PopAllTriangleListTransparency(); if( (USE_PORTALS>2)&& (portals) ) { ARX_PORTALS_Frustrum_RenderRooms_TransparencyT(); } else { if (TRANSPOLYSPOS) ARXDRAW_DrawAllTransPolysPos(pd3dDevice,MODIF); } } if (HALOCUR>0) { SETTC(pd3dDevice,NULL); pd3dDevice->SetRenderState( D3DRENDERSTATE_SRCBLEND, D3DBLEND_SRCCOLOR ); pd3dDevice->SetRenderState( D3DRENDERSTATE_DESTBLEND, D3DBLEND_ONE ); SETALPHABLEND(pd3dDevice,TRUE); SETCULL(pd3dDevice,D3DCULL_NONE); SETZWRITE(pd3dDevice,FALSE); for (i=0;iSetRenderState( D3DRENDERSTATE_SRCBLEND, D3DBLEND_ZERO ); pd3dDevice->SetRenderState( D3DRENDERSTATE_DESTBLEND, D3DBLEND_INVSRCCOLOR ); vert[2].color =0xFF000000; EERIEDRAWPRIM(pd3dDevice,D3DPT_TRIANGLEFAN, D3DFVF_TLVERTEX| D3DFVF_DIFFUSE , vert, 4, 0, 0 );//>>> DO NOT USE EERIE_USEVB FOR HALO <<< pd3dDevice->SetRenderState( D3DRENDERSTATE_SRCBLEND, D3DBLEND_SRCCOLOR ); pd3dDevice->SetRenderState( D3DRENDERSTATE_DESTBLEND, D3DBLEND_ONE ); } else EERIEDRAWPRIM(pd3dDevice,D3DPT_TRIANGLEFAN, D3DFVF_TLVERTEX| D3DFVF_DIFFUSE , vert, 4, 0, 0 );//>>> DO NOT USE EERIE_USEVB FOR HALO <<< } HALOCUR = 0; SETALPHABLEND(pd3dDevice,FALSE); } SETCULL(pd3dDevice,D3DCULL_CCW); SETALPHABLEND(pd3dDevice,FALSE); SETZWRITE(pd3dDevice, TRUE ); if (EDITION==EDITION_LIGHTS) ARXDRAW_DrawAllLights(pd3dDevice,x0,z0,x1,z1); if (LIGHTTHREAD) ResumeThread(LIGHTTHREAD); }