Ok, I might have found something juicy, still reading through but this is located in CObjectManagerC.cpp
bool CObjectManager::DrawMesh ( sMesh* pMesh )
{
// get pointer to drawbuffers
sDrawBuffer* pDrawBuffer = pMesh->pDrawBuffer;
if ( pDrawBuffer==NULL )
return true;
// U75 - 070410 - can switch off fore color wipe if object flags it
bool bLocalOverrideAllTexturesAndEffects = m_RenderStates.bOverrideAllTexturesAndEffects;
if ( pMesh->pDrawBuffer->dwImmuneToForeColorWipe==1 )
bLocalOverrideAllTexturesAndEffects = false;
// skip if mesh is invisible
if ( pMesh->iMeshType==0 )
{
// regular mesh mode
if ( pMesh->bVisible==false )
return true;
}
if ( pMesh->iMeshType==1 )
{
// terrain mesh mode (scene culling system)
if ( g_pGlob->dwRenderCameraID==0 )
if ( pMesh->bVisible==false )
return true;
}
// call the renderstate function
if ( !SetMeshRenderStates ( pMesh ) )
return false;
// set the input streams
if ( !SetInputStreams ( pMesh ) )
return false;
// set the vertex shader
if ( !SetVertexShader ( pMesh ) )
return false;
// This POINTLIST code is not used by CORE PARTICLES (uses own renderer)
// nor is it used by CLOTH&PARTICLES (uses quad based rendered meshes)
// this is actuall used by the PHYSX PLUGIN FOR FLUID PARTICLES
if ( pMesh->iPrimitiveType == D3DPT_POINTLIST )
{
// set a default - mike needs to do this in ANYTHING that creates a pointlist object
if ( pMesh->Collision.fRadius==0.0f ) pMesh->Collision.fRadius = 50.0f;
// handle point sprite for distance scaling and default mesh point sprite size
m_pD3D->SetRenderState( D3DRS_POINTSCALEENABLE, TRUE );
m_pD3D->SetRenderState( D3DRS_POINTSIZE, FtoDW(pMesh->Collision.fRadius/100.0f) );
m_pD3D->SetRenderState( D3DRS_POINTSIZE_MIN, FtoDW(0.0f) );
m_pD3D->SetRenderState( D3DRS_POINTSIZE_MAX, FtoDW(pMesh->Collision.fRadius) );
m_pD3D->SetRenderState( D3DRS_POINTSCALE_A, FtoDW(0.0f) );
m_pD3D->SetRenderState( D3DRS_POINTSCALE_B, FtoDW(0.0f) );
m_pD3D->SetRenderState( D3DRS_POINTSCALE_C, FtoDW(2.0f) );
// force a basic texture render state
m_pD3D->SetRenderState( D3DRS_POINTSPRITEENABLE, TRUE );
}
// set effect shader (if any)
UINT uPasses = 1;
bool bEffectRendering=false;
if ( pMesh->pVertexShaderEffect && bLocalOverrideAllTexturesAndEffects==false )
{
// use an effect
D3DXMATRIX matWorld;
m_pD3D->GetTransform ( D3DTS_WORLD, &matWorld );
uPasses = pMesh->pVertexShaderEffect->Start ( pMesh, matWorld );
// if FX effect, flag effect code
if ( pMesh->pVertexShaderEffect->m_pEffect )
{
// effect shall be used
bEffectRendering=true;
// U74 - BETA9 - 100709 - set states prior to shader begin pass
if ( pMesh->pTextures )
{
for ( DWORD dwTextureIndex = 0; dwTextureIndex < pMesh->dwTextureCount; dwTextureIndex++ )
{
DWORD dwTextureStage = pMesh->pTextures [ dwTextureIndex ].dwStage;
if ( dwTextureStage < 16 )
{
// so the object states to do overwrite any shader states that begin pass will set
sTexture* pTexture = &pMesh->pTextures [ dwTextureIndex ];
if ( pTexture )
{
m_pD3D->SetSamplerState ( dwTextureStage, D3DSAMP_ADDRESSU, pTexture->dwAddressU );
m_pD3D->SetSamplerState ( dwTextureStage, D3DSAMP_ADDRESSV, pTexture->dwAddressV );
m_pD3D->SetSamplerState ( dwTextureStage, D3DSAMP_MAGFILTER, pTexture->dwMagState );
m_pD3D->SetSamplerState ( dwTextureStage, D3DSAMP_MINFILTER, pTexture->dwMinState );
m_pD3D->SetSamplerState ( dwTextureStage, D3DSAMP_MIPFILTER, pTexture->dwMipState );
}
}
}
}
}
}
// U75 - 200310 - if using RT, store current render target
IDirect3DSurface9 *pCurrentRenderTarget = NULL;
if ( pMesh->pVertexShaderEffect )
if ( pMesh->pVertexShaderEffect->m_bUsesAtLeastOneRT==true )
m_pD3D->GetRenderTarget( 0, &pCurrentRenderTarget );
// if rendering with an effect
if ( bEffectRendering )
{
// FF affects HLSL pipeline (and vice versa), so switch off
// the automated clipping plane (FF will stop clipping for HLSLs)
if ( m_RenderStates.bOverriddenClipPlaneforHLSL==false )
{
m_pD3D->SetRenderState ( D3DRS_CLIPPLANEENABLE, 0x00 );
m_RenderStates.bOverriddenClipPlaneforHLSL = true;
}
}
// each mesh can have several render passes
for(UINT uPass = 0; uPass < uPasses; uPass++)
{
// U75 - 070410 - override every texture and effect with single color
// useful for advanced post-processing effects like depthoffield/heathaze
if ( bLocalOverrideAllTexturesAndEffects==true )
{
// no texture, no effect, just plane color
m_pD3D->SetTexture ( 0, NULL );
m_pD3D->SetTextureStageState ( 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1 );
m_pD3D->SetTextureStageState ( 0, D3DTSS_COLORARG1, D3DTA_TFACTOR );
m_pD3D->SetTextureStageState ( 0, D3DTSS_ALPHAOP, D3DTOP_DISABLE );
for ( int t=1; t<=7; t++ )
{
m_pD3D->SetTexture ( t, NULL );
m_pD3D->SetTextureStageState ( t, D3DTSS_COLOROP, D3DTOP_DISABLE );
m_pD3D->SetTextureStageState ( t, D3DTSS_ALPHAOP, D3DTOP_DISABLE );
}
m_pD3D->SetRenderState ( D3DRS_TEXTUREFACTOR, m_RenderStates.dwOverrideAllWithColor );
m_pD3D->SetRenderState ( D3DRS_FOGCOLOR, m_RenderStates.dwFogColor );
}
else
{
// U75 - 200310 - if using RT, determine if should switch to RT or final render target (current)
if ( bEffectRendering )
{
// commit var
LPD3DXEFFECT pEffect = pMesh->pVertexShaderEffect->m_pEffect;
bool bMustCommit = false;
// only if RT flagged (saves performance)
if ( pMesh->pVertexShaderEffect->m_bUsesAtLeastOneRT==true )
{
// ensure technique exists
D3DXHANDLE hTech = pEffect->GetTechnique(0);//this may mess up multi-technique shaders??
// get rendercolortarget string from this pass
D3DXHANDLE hPass = pEffect->GetPass( hTech, uPass );
D3DXHANDLE hRT = pEffect->GetAnnotationByName( hPass, "RenderColorTarget" );
const char* szRT = 0;
if ( hRT ) pEffect->GetString( hRT, &szRT );
// check if RT string has contents
if ( hRT && strcmp( szRT, "" ) != 0 )
{
// yes, now get handle to texture param we want to re-direct our render to
D3DXHANDLE hTexParamWant = pEffect->GetParameterByName( NULL, szRT );
// go through all textures recorded during the shader parse
for ( DWORD t = 0; t < pMesh->pVertexShaderEffect->m_dwTextureCount; t++ )
{
// only consider RT textures that are flagged in bitmask
DWORD dwThisTextureBit = 1 << t;
if ( pMesh->pVertexShaderEffect->m_dwCreatedRTTextureMask & dwThisTextureBit )
{
// get the param handle of each texture in shader
int iParam = pMesh->pVertexShaderEffect->m_iParamOfTexture [ t ];
D3DXHANDLE hTexParam = pEffect->GetParameter( NULL, iParam );
// if it matches the one we want
if ( hTexParam == hTexParamWant )
{
// get texture ptr from effect
IDirect3DBaseTexture9* pRTTex = NULL;
pEffect->GetTexture( hTexParam, &pRTTex );
// switch render target to internal shader RT
IDirect3DSurface9 *pSurface;
((IDirect3DTexture9*)pRTTex)->GetSurfaceLevel( 0, &pSurface );
m_pD3D->SetRenderTarget( 0, pSurface );
if ( pSurface ) pSurface->Release( );
// put RT textures width and height into ViewSize
D3DXHANDLE hViewSize = pEffect->GetParameterBySemantic( NULL, "ViewSize" );
if ( hViewSize )
{
D3DSURFACE_DESC desc;
pCurrentRenderTarget->GetDesc( &desc );
int width = desc.Width, height = desc.Height;
D3DXHANDLE hWidth = pEffect->GetAnnotationByName( hTexParam, "width" );
D3DXHANDLE hHeight = pEffect->GetAnnotationByName( hTexParam, "height" );
if ( hWidth ) pEffect->GetInt( hWidth, &width );
if ( hHeight ) pEffect->GetInt( hWidth, &height );
D3DXVECTOR4 vec( (float) width, (float) height, 0, 0 );
pEffect->SetVector( hViewSize, &vec );
}
}
}
}
}
else
{
// no, we render to current as normal
m_pD3D->SetRenderTarget( 0, pCurrentRenderTarget );
// set the Viewsize to match the width and height of the RT passed in
D3DXHANDLE hViewSize = pEffect->GetParameterBySemantic( NULL, "ViewSize" );
if ( hViewSize )
{
D3DSURFACE_DESC desc;
pCurrentRenderTarget->GetDesc( &desc );
D3DXVECTOR4 vec( (float) desc.Width, (float) desc.Height, 0, 0 );
pEffect->SetVector( hViewSize, &vec );
}
}
// once textures established, commit effect state changes and begin this pass
bMustCommit = true;
}
// U77 - 270111 - pass clipping data to shader (automatic)
if ( pMesh->pVertexShaderEffect->m_VecClipPlaneEffectHandle )
{
tagCameraData* m_Camera_Ptr = (tagCameraData*)g_Camera3D_GetInternalData ( g_pGlob->dwRenderCameraID );
if ( m_Camera_Ptr->iClipPlaneOn==1 )
{
// special mode which creates plane but does not use RenderState to set clip
// as you cannot mix FF clip and HLSL clip in same scene (artefacts)
D3DXVECTOR4 vec = (D3DXVECTOR4)m_Camera_Ptr->planeClip;
pEffect->SetVector( pMesh->pVertexShaderEffect->m_VecClipPlaneEffectHandle, &vec );
}
else
{
// ensure shader stops using clip plane when not being clipped!
D3DXVECTOR4 vec = D3DXVECTOR4( 0.0f, 1.0f, 0.0f, 99999.0f );
pEffect->SetVector( pMesh->pVertexShaderEffect->m_VecClipPlaneEffectHandle, &vec );
}
bMustCommit = true;
}
// when flagged, we must update effect with changes we made
if ( bMustCommit==true )
{
// commit effect state changes to begin this pass
pEffect->CommitChanges( );
}
}
// FX Effect or Regular
if ( bEffectRendering )
{
// mike - 300905 - disable fog for shaders
m_pD3D->SetRenderState ( D3DRS_FOGENABLE, FALSE );
// m_RenderStates.bFog = false;
// begin effect rendernig
pMesh->pVertexShaderEffect->m_pEffect->BeginPass ( uPass );
}
// old FF texturing code (some effects do not do any texturing stuff)
// leefixback - 010405 - this allowed non PS shader to use DBP textures
// but it killed shader ability to use DBP textures that HAD PS code!
// if ( bEffectWillUseFFTexturing==true && uPass==0 )
if ( bEffectRendering )
{
// SHADER EFFECT
// u64 - 180107 - effects CAN use 'texture object' textures if the effect
// did not assign a specfic texture to them (paul request for DarkSHADER)
if ( pMesh->pTextures )
{
for ( DWORD dwTextureIndex = 0; dwTextureIndex < pMesh->dwTextureCount; dwTextureIndex++ )
{
DWORD dwTextureStage = pMesh->pTextures [ dwTextureIndex ].dwStage;
if ( dwTextureStage < 16 )
{
// get texture ptr
sTexture* pTexture = &pMesh->pTextures [ dwTextureIndex ];
// m_dwUseDynamicTextureMask holds a mask of 32 bits, 1=use dynamic texture form texture object command
int iUseDyntex = ( ( pMesh->pVertexShaderEffect->m_dwUseDynamicTextureMask >> dwTextureStage ) & 1 );
if ( iUseDyntex==1 )
{
// when in effect, only if texture in effect is NULL should this be allowed
if ( pTexture->pTexturesRef )
{
m_pD3D->SetTexture ( dwTextureStage, pTexture->pTexturesRef );
}
else
{
if ( pMesh->pTextures [ dwTextureIndex ].pCubeTexture )
m_pD3D->SetTexture ( dwTextureStage, pTexture->pCubeTexture );
else
m_pD3D->SetTexture ( dwTextureStage, NULL);
}
}
}
}
}
}
else
{
// FIXED FUNCTION TEXTURING
// FF affects HLSL pipeline (and vice versa), so switch on
// the automated clipping plane if end of override
if ( m_RenderStates.bOverriddenClipPlaneforHLSL==true )
{
tagCameraData* m_Camera_Ptr = (tagCameraData*)g_Camera3D_GetInternalData ( g_pGlob->dwRenderCameraID );
if ( m_Camera_Ptr->iClipPlaneOn!=0 )
m_pD3D->SetRenderState ( D3DRS_CLIPPLANEENABLE, D3DCLIPPLANE0 );
else
m_pD3D->SetRenderState ( D3DRS_CLIPPLANEENABLE, 0x00 );
m_RenderStates.bOverriddenClipPlaneforHLSL = false;
}
// call the texturestate function
if ( !SetMeshTextureStates ( pMesh ) )
return false;
// is there a texture
if ( pMesh->pTextures )
{
// store the current texture
m_iCurrentTexture = pMesh->pTextures [ 0 ].iImageID;
// is it different to the last texture we set (leefix-040803-and only if single texture otherwise lightmaps might be used)
if ( m_iCurrentTexture != m_iLastTexture || pMesh->dwTextureCount>1 )
{
// set the new texture - along with related stage textures
for ( DWORD dwTextureIndex = 0; dwTextureIndex < pMesh->dwTextureCount; dwTextureIndex++ )
{
// Determine texture stage to write to
DWORD dwTextureStage = pMesh->pTextures [ dwTextureIndex ].dwStage;
// Determine texture data ptr
sTexture* pTexture = &pMesh->pTextures [ dwTextureIndex ];
if ( pTexture->pTexturesRef )
{
// set regular texture
if ( FAILED ( m_pD3D->SetTexture ( dwTextureStage, pTexture->pTexturesRef ) ) )
break;
}
else
{
if ( pMesh->pTextures [ dwTextureIndex ].pCubeTexture )
{
// set cube texture
if ( FAILED ( m_pD3D->SetTexture ( dwTextureStage, pTexture->pCubeTexture ) ) )
break;
}
else
{
// set no texture
if ( FAILED ( m_pD3D->SetTexture ( dwTextureStage, NULL) ) )
break;
}
}
}
// now store the current texture
m_iLastTexture = m_iCurrentTexture;
}
}
else
{
// default zero texture
m_pD3D->SetTexture ( 0, NULL );
m_iLastTexture = 0;
}
}
}
// see if we have an index buffer
if ( pMesh->pIndices )
{
// if multimaterial mesh
if ( pMesh->bUseMultiMaterial && bLocalOverrideAllTexturesAndEffects==false )
{
// draw several indexed primitives (one for each material)
sMultiMaterial* pMultiMaterial = pMesh->pMultiMaterial;
for ( DWORD dwMaterialIndex=0; dwMaterialIndex<pMesh->dwMultiMaterialCount; dwMaterialIndex++ )
{
// set mesh-part texture
m_pD3D->SetTexture ( 0, pMultiMaterial [ dwMaterialIndex ].pTexturesRef );
// set mesh-part material and render state
SetMeshMaterial ( pMesh, &pMultiMaterial [ dwMaterialIndex ].mMaterial );
// draw mesh-part
if ( pMultiMaterial [ dwMaterialIndex ].dwPolyCount > 0 )
{
if ( FAILED ( m_pD3D->DrawIndexedPrimitive ( pDrawBuffer->dwPrimType,
pDrawBuffer->dwBaseVertexIndex,
pDrawBuffer->dwVertexStart,
pDrawBuffer->dwVertexCount,
pDrawBuffer->dwIndexStart + pMultiMaterial [ dwMaterialIndex ].dwIndexStart,
pMultiMaterial [ dwMaterialIndex ].dwPolyCount ) ) )
{
uPass=uPasses;
break;
}
}
// add to polycount
if ( g_pGlob ) g_pGlob->dwNumberOfPolygonsDrawn += pMultiMaterial [ dwMaterialIndex ].dwPolyCount;
if ( g_pGlob ) g_pGlob->dwNumberOfPrimCalls++;
}
// restore texture settings next cycle
m_iLastTexture=-9999999;
}
else
{
// draw an indexed primitive
if ( FAILED ( m_pD3D->DrawIndexedPrimitive ( pDrawBuffer->dwPrimType,
pDrawBuffer->dwBaseVertexIndex,
pDrawBuffer->dwVertexStart,
pDrawBuffer->dwVertexCount,
pDrawBuffer->dwIndexStart,
pDrawBuffer->dwPrimitiveCount ) ) )
break;
// add to polycount
if ( g_pGlob ) g_pGlob->dwNumberOfPolygonsDrawn += pDrawBuffer->dwPrimitiveCount;
if ( g_pGlob ) g_pGlob->dwNumberOfPrimCalls++;
}
}
else
{
// draw a standard primitive
if ( FAILED ( m_pD3D->DrawPrimitive ( pDrawBuffer->dwPrimType,
pDrawBuffer->dwVertexStart,
pDrawBuffer->dwPrimitiveCount ) ) )
{
// leehack-040803-if fail to render, try smaller batches of primitives until we figure it out!
DWORD dwHowManyLeft = pDrawBuffer->dwPrimitiveCount;
DWORD dwVertexBeginData = pDrawBuffer->dwVertexStart;
DWORD dwPrimCountBatch=65535/3;//leehack-040803-seems some cards report 65535 but can only handle a third of that?!?
for ( DWORD dwI=0; dwI<=(pDrawBuffer->dwPrimitiveCount/dwPrimCountBatch); dwI++ )
{
DWORD dwHowManyToRender = dwPrimCountBatch;
if ( dwHowManyLeft < dwPrimCountBatch )
dwHowManyToRender = dwHowManyLeft;
if ( FAILED ( m_pD3D->DrawPrimitive ( pDrawBuffer->dwPrimType,
dwVertexBeginData,
dwHowManyToRender ) ) )
break;
// next batch of vertex data
dwVertexBeginData+=dwHowManyToRender*3;
dwHowManyLeft -= dwPrimCountBatch;
}
}
// add to polycount
if ( g_pGlob ) g_pGlob->dwNumberOfPolygonsDrawn += pDrawBuffer->dwPrimitiveCount;
if ( g_pGlob ) g_pGlob->dwNumberOfPrimCalls++;
}
// End FX Effect
if ( bEffectRendering ) pMesh->pVertexShaderEffect->m_pEffect->EndPass();
}
// mike - 300905 - enable fog after being disabled for shaders
if ( m_RenderStates.bFog )
m_pD3D->SetRenderState ( D3DRS_FOGENABLE, TRUE );
// U75 - 200310 - if using RT, restore current render target
if ( pCurrentRenderTarget )
if ( pMesh->pVertexShaderEffect )
if ( pMesh->pVertexShaderEffect->m_bUsesAtLeastOneRT==true )
m_pD3D->SetRenderTarget( 0, pCurrentRenderTarget );
// Run any end code for any effect used
if ( pMesh->pVertexShaderEffect )
pMesh->pVertexShaderEffect->End();
// leeadd - 310506 - u62 - end pointlist session (used by PhysX plugin HW fluids)
if ( pMesh->iPrimitiveType == D3DPT_POINTLIST )
{
// end pointlist states
m_pD3D->SetRenderState( D3DRS_POINTSPRITEENABLE, FALSE );
}
// okay
return true;
}
bool CObjectManager::DrawObject ( sObject* pObject )
{
// check the object and array index value
SAFE_MEMORY ( pObject );
// leefix - some TPC can call FASTSYNC after object removed
// if resource destroyed, quit now
if ( pObject->dwObjectNumber > 0 )
if ( g_ObjectList [ pObject->dwObjectNumber ]==NULL )
return true;
// setup the world matrix for the object
CalcObjectWorld ( pObject );
// skip if object is invisible
if ( pObject->bVisible==false
|| pObject->bNoMeshesInObject==true
|| pObject->bUniverseVisible==false )
return true;
///////////////////////////////////////////////
///////////////////////////////////////////////
// MIKE : add 05/02/03
// for linked objects
// need to neaten this up lee at some point..
D3DXMATRIX matSavedWorld;
D3DXMATRIX matNewWorld;
// mike - 050803 - external DLLs can disable transform it they want
if ( !pObject->bDisableTransform )
{
m_pD3D->SetTransform ( D3DTS_WORLD, &pObject->position.matWorld );
}
else
{
D3DXMATRIX matTranslation,
matScale,
matObject;
// World Transform
D3DXMatrixTranslation ( &matTranslation, 0.0f, 0.0f, 0.0f );
D3DXMatrixScaling ( &matScale, 1.0f, 1.0f, 1.0f );
matObject = matScale * matTranslation;
m_pD3D->SetTransform ( D3DTS_WORLD, &matObject );
}
///////////////////////////////////////////////
///////////////////////////////////////////////
// leeadd - 140304 - an object can control its own FOV for rendering
if ( pObject->bLockedObject==false )
{
if ( pObject->fFOV != m_RenderStates.fObjectFOV )
{
if ( pObject->fFOV == 0.0f )
g_Camera3D_SetFOV ( m_RenderStates.fStoreCameraFOV );
else
g_Camera3D_SetFOV ( pObject->fFOV );
m_RenderStates.fObjectFOV = pObject->fFOV;
}
}
// get LOD flag from core object
int iUsingWhichLOD = pObject->iUsingWhichLOD;
// actual object or instance of object
sObject* pActualObject = pObject;
if ( pActualObject->pInstanceOfObject )
{
// get actual object via instance ptr
pActualObject=pActualObject->pInstanceOfObject;
// /* U72 - 100109 - whole lot moved until AFTER the LOD alpha changes so it can be per-instance too!
// if instance uses alpha factor, apply to object
if ( pObject->bInstanceAlphaOverride )
{
// mike - 011005 - change render settings so instanced objects can have their own alpha
// - settings and keep transparency
/* U72 - 100109 - not sure if this was my DBP code or Mikes GDK DTSP code..but will leave it commented out as it was in U71
// set alpha factor and render states here
m_pD3D->SetRenderState ( D3DRS_ALPHABLENDENABLE, true );
m_pD3D->SetRenderState ( D3DRS_SRCBLEND, D3DBLEND_SRCALPHA );
m_pD3D->SetRenderState ( D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA );
m_pD3D->SetRenderState ( D3DRS_ALPHATESTENABLE, true );
m_pD3D->SetRenderState ( D3DRS_ALPHAFUNC, D3DCMP_GREATER );
m_pD3D->SetRenderState ( D3DRS_ALPHAREF, 0x00000000 );
// set alpha factor and texture stage
m_pD3D->SetTextureStageState ( 0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1 );
m_pD3D->SetTextureStageState ( 0, D3DTSS_ALPHAARG1, D3DTA_TFACTOR );
m_pD3D->SetRenderState( D3DRS_TEXTUREFACTOR, pObject->dwInstanceAlphaOverride );
*/
// if mesh exists with blending and argument mode, set the individual instance alpha value
if ( pActualObject->iMeshCount > 0 )
{
sMesh* pMesh = pActualObject->ppMeshList [ 0 ];
if ( pMesh->dwTextureCount > 0 )
{
m_pD3D->SetTextureStageState ( 0, D3DTSS_ALPHAOP, pMesh->pTextures [ 0 ].dwBlendMode );
m_pD3D->SetTextureStageState ( 0, D3DTSS_ALPHAARG2, pMesh->pTextures [ 0 ].dwBlendArg1 );
m_pD3D->SetTextureStageState ( 0, D3DTSS_ALPHAARG1, D3DTA_TFACTOR );
m_pD3D->SetRenderState( D3DRS_TEXTUREFACTOR, pObject->dwInstanceAlphaOverride );
}
}
m_RenderStates.bNoMeshAlphaFactor = true;
}
// U72 - 100109 - commented this out as it was probably from GDK for DTSP (too hidden for my liking)
// // if instance has a diffuse other than zero, it can override current ARGUMENT2 arrangment
// if ( pObject->pCustomData )
// {
// // use diffuse from material (if present)
// m_pD3D->SetRenderState ( D3DRS_TEXTUREFACTOR, *(DWORD*)pObject->pCustomData );
// m_RenderStates.bIgnoreDiffuse = true;
// }
}
// run through all of the frames within the object
for ( int iFrame = 0; iFrame < pActualObject->iFrameCount; iFrame++ )
{
// if instance limb visibility hidden, skip now
if ( pObject->pInstanceMeshVisible )
{
// if limb in instance hidden, skip
if ( pObject->pInstanceMeshVisible [ iFrame ]==false )
continue;
}
// get a pointer to the frame
sFrame* pFrame = pActualObject->ppFrameList [ iFrame ];
// 301007 - new limb excluder
if ( pFrame==NULL ) continue;
if ( pFrame->bExcluded==true ) continue;
// get mesh from frame
sMesh* pMesh = pFrame->pMesh;
// calculate correct absolute world matrix
CalculateAbsoluteWorldMatrix ( pObject, pFrame, pMesh );
// draw mesh
if ( pMesh )
{
// apply the final transform
if ( !pMesh->bLinked )
{
// mike 170505 - new matrix for completely custom, physics needs this for implementing it's own matrix
if ( pFrame->bOverride )
{
if ( FAILED ( m_pD3D->SetTransform ( D3DTS_WORLD, ( D3DXMATRIX* ) &pFrame->matOverride ) ) )
return false;
}
else if ( !pObject->bDisableTransform )
{
// mike - 140803
if ( FAILED ( m_pD3D->SetTransform ( D3DTS_WORLD, ( D3DXMATRIX* ) &pFrame->matAbsoluteWorld ) ) )
return false;
}
}
// update world transform for LOD quad (always faces camera)
D3DXMATRIX matQuadRotation;
// u74b7 - moved to UpdateLayer
// tagCameraData* m_Camera_Ptr = (tagCameraData*)g_Camera3D_GetInternalData ( g_pGlob->dwRenderCameraID );
if ( (pObject->iUsingOldLOD==3 || pObject->iUsingWhichLOD==3) && m_pCamera )
{
float dx = pObject->position.vecPosition.x - m_pCamera->vecPosition.x;
float dz = pObject->position.vecPosition.z - m_pCamera->vecPosition.z;
float theangle = atan2 ( dx, dz );
D3DXMatrixRotationY(&matQuadRotation, theangle );
matQuadRotation._41 = pFrame->matAbsoluteWorld._41;
matQuadRotation._42 = pFrame->matAbsoluteWorld._42;
matQuadRotation._43 = pFrame->matAbsoluteWorld._43;
}
// leeadd - U71 - determine LOD meshes (current and old (transition) if applicable)
sMesh* pCurrentLOD = pMesh;
if ( iUsingWhichLOD==1 && pFrame->pLOD[0] ) pCurrentLOD = pFrame->pLOD[0];
if ( iUsingWhichLOD==2 && pFrame->pLOD[1] ) pCurrentLOD = pFrame->pLOD[1];
if ( iUsingWhichLOD==3 && pFrame->pLODForQUAD ) pCurrentLOD = pFrame->pLODForQUAD;
sMesh* pOldLOD = NULL;
if ( pObject->iUsingOldLOD != -1 )
{
// the old lod mesh
if ( pObject->iUsingOldLOD==0 ) pOldLOD = pMesh;
if ( pObject->iUsingOldLOD==1 && pFrame->pLOD[0] ) pOldLOD = pFrame->pLOD[0];
if ( pObject->iUsingOldLOD==2 && pFrame->pLOD[1] ) pOldLOD = pFrame->pLOD[1];
if ( pObject->iUsingOldLOD==3 && pFrame->pLODForQUAD ) pOldLOD = pFrame->pLODForQUAD;
// transition in progress from OLD to CURRENT
pObject->fLODTransition += 0.03f;
if ( pObject->fLODTransition >= 2.0f )
{
// end transition and restore alpha states
pObject->fLODTransition = 0.0f;
pObject->iUsingOldLOD = -1;
D3DCOLOR dwAlphaValueOnly = D3DCOLOR_ARGB ( 255, 0, 0, 0 );
pCurrentLOD->dwAlphaOverride = dwAlphaValueOnly;
pCurrentLOD->bAlphaOverride = false;
pCurrentLOD->bZWrite = true;
pCurrentLOD->bZBiasActive = false; // U74 - 120409 - refresh each cycle for each instance
pCurrentLOD->fZBiasDepth = 0.0f; // U74 - 120409 - refresh each cycle for each instance
pOldLOD->dwAlphaOverride = dwAlphaValueOnly;
pOldLOD->bAlphaOverride = false;
pOldLOD->bZWrite = true;
pOldLOD->bZBiasActive = false;
pOldLOD->fZBiasDepth = 0.0f;
pOldLOD = NULL;
// U72 - 100109 - record alpha state of this mesh (for when instance is not being calculated, i.e. updated in actual mesh for render state change)
if ( pObject->pInstanceOfObject ) pObject->dwInstanceAlphaOverride = dwAlphaValueOnly;
}
else
{
// change alpha level of meshes involved in transition
if ( pObject->fLODTransition<=1.0f )
{
// FIRST fade in current LOD mesh
DWORD dwAlpha = (DWORD)(pObject->fLODTransition*255);
D3DCOLOR dwAlphaValueOnly = D3DCOLOR_ARGB ( dwAlpha, 0, 0, 0 );
pCurrentLOD->dwAlphaOverride = dwAlphaValueOnly;
pCurrentLOD->bAlphaOverride = true;
pCurrentLOD->bTransparency = true;
// AND first bit of fade in switch off Zwrite so the 'appearing' image goes not clip the
// new current mesh and other objects in the area (causing the background to come through)
if ( pObject->iUsingWhichLOD!=3 )
{
if ( pObject->fLODTransition < 0.5f )
pCurrentLOD->bZWrite = false;
else
pCurrentLOD->bZWrite = true;
pCurrentLOD->bZBiasActive = false;
pCurrentLOD->fZBiasDepth = 0.0f;
}
else
{
// last LODQUAD mesh is a plane, so can adjust bias ahead to ensure it is rendered ABOVE everything
pCurrentLOD->bZWrite = false;
pCurrentLOD->fZBiasDepth = -g_fZBiasEpsilon;
pCurrentLOD->bZBiasActive = true;
}
// and OLD LOD must stay as reset
if ( pOldLOD )
{
pOldLOD->dwAlphaOverride = D3DCOLOR_ARGB ( 255, 0, 0, 0 );
pOldLOD->bAlphaOverride = false;
pOldLOD->bZWrite = true;
pOldLOD->bZBiasActive = false;
pOldLOD->fZBiasDepth = 0.0f;
}
}
else
{
// Ensure current LOD mesh is default (writing Z and no bias)
pCurrentLOD->dwAlphaOverride = D3DCOLOR_ARGB ( 255, 0, 0, 0 );
pCurrentLOD->bAlphaOverride = false;
pCurrentLOD->bZWrite = true;
pCurrentLOD->bZBiasActive = false;
pCurrentLOD->fZBiasDepth = 0.0f;
// AND now as OLD one fades away, push zbias so NEW/CURRENT mesh has all of Z buffer opportunity
if ( pObject->iUsingOldLOD!=3 )
{
// except the last LODQUAD, which needs zbias as is to do proper fade out
pOldLOD->fZBiasDepth = g_fZBiasEpsilon * (pObject->fLODTransition-1.0f);
pOldLOD->bZBiasActive = true;
// AND last bit of fade out switch off Zwrite so the 'almost gone' image goes not clip the
// new current mesh and other objects in the area (causing the background to come through)
if ( pObject->fLODTransition > 1.5f )
pOldLOD->bZWrite = false;
else
pOldLOD->bZWrite = true; // U74 - 120409 - refresh each cycle for each instance
}
else
{
// For the last LOD QUAD, make the decal fade out slower (to avoid the flick against the sky)
pObject->fLODTransition -= 0.01f;
// U74 - 120409 - no zbias effect
pOldLOD->bZBiasActive = false;
pOldLOD->fZBiasDepth = 0.0f;
// also disable ALL zwrites from LODQUAD to avoid artefacts
pOldLOD->bZWrite = false;
}
// THEN fade out old LOD mesh
DWORD dwAlpha = (DWORD)((2.0f-pObject->fLODTransition)*255);
D3DCOLOR dwAlphaValueOnly = D3DCOLOR_ARGB ( dwAlpha, 0, 0, 0 );
pOldLOD->dwAlphaOverride = dwAlphaValueOnly;
pOldLOD->bAlphaOverride = true;
pOldLOD->bTransparency = true;
}
}
}
else
{
// U72 - 100109 - mesh not in transition, but still need the alpha state if this is an instanced object
if ( pObject->pInstanceOfObject && pCurrentLOD )
{
pCurrentLOD->dwAlphaOverride = pObject->dwInstanceAlphaOverride;
pCurrentLOD->bAlphaOverride = false;
pCurrentLOD->bZWrite = true;
pCurrentLOD->bZBiasActive = false;
pCurrentLOD->fZBiasDepth = 0.0f;
}
}
/* U72 - 110109 - use only ONE quad image (rotating them creates jumps and adds to performance cost)
// also update QUAD UV image to reflect current angle between camera and this object
// DUPLICATED BELOW FOR OLD MESH AS WELL! This needs improving!!
if ( pCurrentLOD )
{
if ( pObject->iUsingWhichLOD==3 && m_Camera_Ptr )
{
// angle between this object and camera view
float dx = m_Camera_Ptr->vecPosition.x - pObject->position.vecPosition.x;
float dz = pObject->position.vecPosition.z - m_Camera_Ptr->vecPosition.z;
float theangle = D3DXToDegree(atan2(dx,dz)) - 90.0f + 12.5f;
theangle=theangle/(360/16);
if ( theangle > 15 ) theangle -= 16;
if ( theangle < 00 ) theangle += 16;
// try same decal (reduce popping?)
theangle = 0;
int tv=theangle/4;
int tu=theangle-(tv*4);
float fS=1.0/4.0;
float fU=fS*tu;
float fV=fS*tv;
// current LOD mesh needs UV editing to get right image-direction
SetUVData ( pCurrentLOD, 0, fU+fS, fV );
SetUVData ( pCurrentLOD, 1, fU, fV );
SetUVData ( pCurrentLOD, 2, fU+fS, fV+fS );
SetUVData ( pCurrentLOD, 3, fU, fV );
SetUVData ( pCurrentLOD, 4, fU, fV+fS );
SetUVData ( pCurrentLOD, 5, fU+fS, fV+fS );
// instruct engine to update this mesh in the buffer IMMEDIATELY
// pCurrentLOD->bVBRefreshRequired = true;
UpdateObjectMeshInBuffer ( pCurrentLOD );
pCurrentLOD->bVBRefreshRequired=false;
// slow way, should find another way WITHOUT HAVING TO LOCK VERTEX DATA IN RENDER LOOP!!!
sVertexData* pVertexData = (sVertexData*)pCurrentLOD->pDrawBuffer->pVBListEntryRef;
if ( pVertexData->bBufferLocked==true )
{
// unlock and restore flag
pVertexData->pVB->Unlock ( );
pVertexData->bBufferLocked=false;
}
}
}
// also update QUAD UV image to reflect current angle between camera and this object
if ( pOldLOD )
{
if ( pObject->iUsingOldLOD==3 && m_Camera_Ptr )
{
// angle between this object and camera view
float dx = m_Camera_Ptr->vecPosition.x - pObject->position.vecPosition.x;
float dz = pObject->position.vecPosition.z - m_Camera_Ptr->vecPosition.z;
float theangle = D3DXToDegree(atan2(dx,dz)) - 90.0f + 12.5f;
theangle=theangle/(360/16);
if ( theangle > 15 ) theangle -= 16;
if ( theangle < 00 ) theangle += 16;
// try same decal (reduce popping?)
theangle = 0;
int tv=theangle/4;
int tu=theangle-(tv*4);
float fS=1.0/4.0;
float fU=fS*tu;
float fV=fS*tv;
// current LOD mesh needs UV editing to get right image-direction
SetUVData ( pOldLOD, 0, fU+fS, fV );
SetUVData ( pOldLOD, 1, fU, fV );
SetUVData ( pOldLOD, 2, fU+fS, fV+fS );
SetUVData ( pOldLOD, 3, fU, fV );
SetUVData ( pOldLOD, 4, fU, fV+fS );
SetUVData ( pOldLOD, 5, fU+fS, fV+fS );
// instruct engine to update this mesh in the buffer IMMEDIATELY
// pCurrentLOD->bVBRefreshRequired = true;
UpdateObjectMeshInBuffer ( pOldLOD );
pOldLOD->bVBRefreshRequired=false;
// slow way, should find another way WITHOUT HAVING TO LOCK VERTEX DATA IN RENDER LOOP!!!
sVertexData* pVertexData = (sVertexData*)pOldLOD->pDrawBuffer->pVBListEntryRef;
if ( pVertexData->bBufferLocked==true )
{
// unlock and restore flag
pVertexData->pVB->Unlock ( );
pVertexData->bBufferLocked=false;
}
}
}
*/
// leeadd - U71 - if in transition, draw OLD first
if ( pOldLOD )
{
// shader work
// pObject->pFrame->matAbsoluteWorld._43 += 450.0f;
if ( pObject->iUsingOldLOD==3 )
m_pD3D->SetTransform ( D3DTS_WORLD, ( D3DXMATRIX* ) &matQuadRotation );
else
m_pD3D->SetTransform ( D3DTS_WORLD, ( D3DXMATRIX* ) &pFrame->matAbsoluteWorld );
// shader work
// pObject->pFrame->matAbsoluteWorld._43 -= 450.0f;
// ensure this is drawn behind the current one by shifting projection Z range (alternative to DEPTHBIAS which does not work on shaders)
// shader work
// D3DXMATRIX matBiasProj = m_Camera_Ptr->matProjection;
// float fNear = 0.0f;
// float fFar = 4900.0f;
// D3DXMatrixPerspectiveFovLH ( &matBiasProj, D3DXToRadian(m_Camera_Ptr->fFOV), m_Camera_Ptr->fAspect, fNear, fFar );
// m_pD3D->SetTransform ( D3DTS_PROJECTION, &matBiasProj );
// draw old LOD mesh
if ( !DrawMesh ( pOldLOD ) )
return false;
// restore projection matrix
// shader work
// m_pD3D->SetTransform ( D3DTS_PROJECTION, &m_Camera_Ptr->matProjection );
if ( pObject->iUsingWhichLOD!=3 )
m_pD3D->SetTransform ( D3DTS_WORLD, ( D3DXMATRIX* ) &pFrame->matAbsoluteWorld );
}
// update world transform for LOD quad (always faces camera)
if ( pObject->iUsingWhichLOD==3 )
m_pD3D->SetTransform ( D3DTS_WORLD, ( D3DXMATRIX* ) &matQuadRotation );
// draw the current mesh
if ( !DrawMesh ( pCurrentLOD ) )
return false;
// render any bound meshes
// mike 160505 - changed this line so a mesh can draw it's bounds
if ( pObject->bDrawBounds || pMesh->bDrawBounds )
{
if ( pFrame->pBoundBox ) DrawMesh ( pFrame->pBoundBox );
if ( pFrame->pBoundSphere ) DrawMesh ( pFrame->pBoundSphere );
}
// for linked objects
if ( pMesh->bLinked )
{
// mike - 140803
if ( !pObject->bDisableTransform )
{
m_pD3D->GetTransform ( D3DTS_WORLD, &matSavedWorld );
matNewWorld = pFrame->matOriginal * matSavedWorld;
m_pD3D->SetTransform ( D3DTS_WORLD, &matNewWorld );
}
}
}
}
// if instance uses alpha factor, apply to object
// if ( pObject->bInstanceAlphaOverride )
// lee - 240206 - u60 - ALWAYS back to normal - use mesh based alpha factor after override
m_RenderStates.bNoMeshAlphaFactor = false;
m_RenderStates.bIgnoreDiffuse = false;
// sorted, return back
return true;
}
EDIT: I have found something useful in the
bool CObjectManager::DrawObject
portion of code
// run through all of the frames within the object
for ( int iFrame = 0; iFrame < pActualObject->iFrameCount; iFrame++ )
{
This could be leading us right to our answer!
EDIT: After searching around some more, I believe the issue that we are having is not within the actual rendering code as I disabled object rendering and it still was slowdown, I think it is related to determining if the object is in screen and if so to render it code, that seems to be the plausible culprit!
Making dreams possible, one line at a time...