HRESULT BMaxObject::Draw(SceneState * sceneState) { if (!m_pAnimatedMesh) return E_FAIL; if (GetPrimaryTechniqueHandle() < 0) { // try loading the asset if it has not been done before. m_pAnimatedMesh->LoadAsset(); if (m_pAnimatedMesh->IsLoaded()) { SetPrimaryTechniqueHandle(m_pAnimatedMesh->GetPrimaryTechniqueHandle()); UpdateGeometry(); } return E_FAIL; } if (!CGlobals::GetEffectManager()->IsCurrentEffectValid()) { return E_FAIL; } sceneState->SetCurrentSceneObject(this); int nIndex = (sceneState && sceneState->IsLODEnabled()) ? m_pAnimatedMesh->GetLodIndex(sceneState->GetCameraToCurObjectDistance()/*, GetScaling()*/) : 0; CParaXModel* pModel = m_pAnimatedMesh->GetModel(nIndex); if (pModel == NULL) return E_FAIL; int nRestoreSpecialTextures = -1; for (auto const & tex : mReplaceTextures) { if(pModel->specialTextures[tex.first] >= 0) pModel->replaceTextures[pModel->specialTextures[tex.first]] = tex.second; else { // if there is only one texture, we will force replace it even there is no special replaceable id redefined. if (pModel->GetObjectNum().nTextures <= 1 && nRestoreSpecialTextures<0) { nRestoreSpecialTextures = tex.first; pModel->specialTextures[tex.first] = tex.first; pModel->replaceTextures[pModel->specialTextures[tex.first]] = tex.second; break; } } } sceneState->SetCurrentSceneObject(this); SetFrameNumber(sceneState->m_nRenderCount); // get world transform matrix Matrix4 mxWorld; GetRenderMatrix(mxWorld); RenderDevicePtr pd3dDevice = sceneState->m_pd3dDevice; EffectManager* pEffectManager = CGlobals::GetEffectManager(); pEffectManager->applyObjectLocalLighting(this); CEffectFile* pEffectFile = pEffectManager->GetCurrentEffectFile(); CGlobals::GetWorldMatrixStack().push(mxWorld); ApplyBlockLighting(sceneState); CApplyObjectLevelParamBlock p(GetEffectParamBlock()); if (pEffectFile == 0) { // TODO: Fixed Function. } else { bool bUsePointTextureFilter = false; // apply block space lighting for object whose size is comparable to a single block size if (CheckAttribute(MESH_USE_LIGHT) && !(sceneState->IsShadowPass())) { BlockWorldClient* pBlockWorldClient = BlockWorldClient::GetInstance(); if (pBlockWorldClient && pBlockWorldClient->IsInBlockWorld()) { Vector3 vPos = GetPosition(); vPos.y += 0.1f; Uint16x3 blockId_ws(0, 0, 0); BlockCommon::ConvertToBlockIndex(vPos.x, vPos.y, vPos.z, blockId_ws.x, blockId_ws.y, blockId_ws.z); DWORD dwPositionHash = blockId_ws.GetHashCode(); uint8_t brightness[2]; pBlockWorldClient->GetBlockMeshBrightness(blockId_ws, brightness, 2); // block light float fBlockLightness = Math::Max(pBlockWorldClient->GetLightBrightnessLinearFloat(brightness[0]), 0.1f); sceneState->GetCurrentLightStrength().y = fBlockLightness; // sun light float fSunLightness = Math::Max(pBlockWorldClient->GetLightBrightnessLinearFloat(brightness[1]), 0.1f); sceneState->GetCurrentLightStrength().x = fSunLightness; float fLightness = Math::Max(fBlockLightness, fSunLightness*pBlockWorldClient->GetSunIntensity()); if (m_fLastBlockLight != fLightness) { float fMaxStep = (float)(sceneState->dTimeDelta*0.5f); if (dwPositionHash == m_dwLastBlockHash || m_dwLastBlockHash == 0) m_fLastBlockLight = fLightness; else Math::SmoothMoveFloat1(m_fLastBlockLight, fLightness, fMaxStep); fLightness = m_fLastBlockLight; } else { m_dwLastBlockHash = dwPositionHash; } sceneState->GetLocalMaterial().Ambient = (LinearColor(fLightness*0.7f, fLightness*0.7f, fLightness*0.7f, 1.f)); sceneState->GetLocalMaterial().Diffuse = (LinearColor(fLightness*0.4f, fLightness*0.4f, fLightness*0.4f, 1.f)); sceneState->EnableLocalMaterial(true); bUsePointTextureFilter = bUsePointTextureFilter || pBlockWorldClient->GetUsePointTextureFiltering(); } } if (bUsePointTextureFilter) { pEffectManager->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_POINT); pEffectManager->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_POINT); } else { pEffectManager->SetSamplerState(0, D3DSAMP_MINFILTER, pEffectManager->GetDefaultSamplerState(0, D3DSAMP_MINFILTER)); pEffectManager->SetSamplerState(0, D3DSAMP_MAGFILTER, pEffectManager->GetDefaultSamplerState(0, D3DSAMP_MAGFILTER)); } // just a single standing animation is supported now and looped. UpdateModel(sceneState); pModel->draw(sceneState, p.GetParamsBlock()); } if (nRestoreSpecialTextures >= 0) { pModel->specialTextures[nRestoreSpecialTextures] = -1; pModel->replaceTextures[nRestoreSpecialTextures] = nullptr; } CGlobals::GetWorldMatrixStack().pop(); return S_OK; }
void CMiniSceneGraph::Draw_Internal(float fDeltaTime) { PERF1("MiniSceneGraph_Draw"); SceneState& sceneState = m_sceneState; m_sceneState.m_pd3dDevice = CGlobals::GetRenderDevice(); RenderDevicePtr pd3dDevice = m_sceneState.m_pd3dDevice; EffectManager* pEffectManager = CGlobals::GetEffectManager(); bool old_IsLocalLightEnabled = pEffectManager->IsLocalLightingEnabled(); IScene * pOldScene = pEffectManager->GetScene(); pEffectManager->SetScene(this); ////////////////////////////////////////////////////////////////////////// // Set some initial states for the normal pipeline LinearColor fogColor = GetSunLight().ComputeFogColor(); fogColor.r *= GetFogColorFactor().r; fogColor.g *= GetFogColorFactor().g; fogColor.b *= GetFogColorFactor().b; SetFogColor(fogColor); pEffectManager->EnableFog(IsFogEnabled()); pEffectManager->SetD3DFogState(); #ifdef USE_DIRECTX_RENDERER pd3dDevice->SetMaterial((D3DMATERIAL9*)&(sceneState.GetGlobalMaterial())); #elif defined(USE_OPENGL_RENDERER) if (!IsSunLightEnabled()) { // sun light can not be disabled in shader, so we will fake it here. Remove this when shader support turn off global sun light. GetSunLight().SetSunAmbient(LinearColor::White); GetSunLight().SetSunDiffuse(LinearColor::Black); } #endif // disable local lights on bipeds if(old_IsLocalLightEnabled) pEffectManager->EnableLocalLighting(false); // end previous effects, since they may serve different IScene instance. pEffectManager->EndEffect(); // copy the main scene's state sceneState.m_pCurrentEffect = pEffectManager->GetCurrentEffectFile(); // rebuild scene state sceneState.dTimeDelta = fDeltaTime; PrepareRender(m_pCamera, &sceneState); { // all render code goes here /** All potentially visible scene objects in the scene state are put to three major post rendering lists for rendering. Each list is sorted according to object-to-camera distance. And then they will be rendered in the following order: - solid object list: sorted from front to back. In mesh report, it will display "F->B:%d". Their bounding boxes will be rendered as red boxes. - transparent object list: sorted from back to front. In mesh report, it will display "B->F:%d(%d1)". where %d is the total number of meshes rendered and that %d1 is the number of meshes that has been occluded during occlusion testing. Their bounding boxes will be rendered as blue boxes. - Biped list: sorted by primary asset. In mesh report, it will display "Biped:%d". Their bounding boxes will be rendered as green boxes. */ { // so that mesh and character that contains translucent faces are sorted and rendered later on. if(!sceneState.GetFaceGroups()->IsEmpty()) { sceneState.GetFaceGroups()->Clear(); } sceneState.m_bEnableTranslucentFaceSorting = true; // object num in potentially visible set from current view point int nPVSCount = 0; ////////////////////////////////////////////////////////////////////////// /// Draw SkyBox RenderSelection(RENDER_SKY_BOX); ////////////////////////////////////////////////////////////////////////// /// draw solid object rendering list from front to back. if(!sceneState.listPRSolidObject.empty()) { RenderSelection(RENDER_MESH_FRONT_TO_BACK); } ////////////////////////////////////////////////////////////////////////// // draw smaller object rendering list from back to front. if(!sceneState.listPRSmallObject.empty()) { nPVSCount = RenderSelection(RENDER_MESH_BACK_TO_FRONT); } ////////////////////////////////////////////////////////////////////////// /// Draw queued bipeds /// we draw biped after its shadow, because we do not want biped to cast shadows on its own if(!sceneState.listPRBiped.empty()) { RenderSelection(RENDER_CHARACTERS); } ////////////////////////////////////////////////////////////////////////// // draw transparent object rendering list from back to front.it is rendered after ocean to prevent the ocean color over the particles. if(!sceneState.listPRTransparentObject.empty()) { RenderSelection(RENDER_MESH_TRANSPARENT); } ////////////////////////////////////////////////////////////////////////// // render translucent face groups. if(!sceneState.GetFaceGroups()->IsEmpty()) { // translucent faces are ignored. RenderSelection(RENDER_TRANSLUCENT_FACE_GROUPS); sceneState.GetFaceGroups()->Clear(); } ////////////////////////////////////////////////////////////////////////// /// render all particle system instances after most of the scene have been rendered. /// it is rendered after ocean to prevent the ocean color over the particles. since all particles are z write disabled. { int nParticlesCount = RenderSelection(RENDER_PARTICLES, fDeltaTime); } ////////////////////////////////////////////////////////////////////////// // bounding box if(CGlobals::GetScene()->IsShowBoundingBox()) RenderSelection(RENDER_BOUNDINGBOX); ////////////////////////////////////////////////////////////////////////// // portal if(CGlobals::GetScene()->IsPortalSystemShown()) RenderSelection(RENDER_PORTAL_SYSTEM); } } #ifdef USE_DIRECTX_RENDERER if(m_pMask!=0 && pEffectManager->BeginEffect(TECH_GUI, &(m_sceneState.m_pCurrentEffect))) { /** draw the mask square in front of the screen. */ CEffectFile* pEffectFile = CGlobals::GetEffectManager()->GetCurrentEffectFile(); if(pEffectFile == 0) { ////////////////////////////////////////////////////////////////////////// // fixed programming pipeline float sx = (float)m_nTextureWidth,sy = (float)m_nTextureHeight; DXUT_SCREEN_VERTEX v[10]; v[0].x = 0; v[0].y = sy; v[0].tu = 0; v[0].tv = 1.0f; v[1].x = 0; v[1].y = 0; v[1].tu = 0; v[1].tv = 0; v[2].x = sx; v[2].y = sy; v[2].tu = 1.f; v[2].tv = 1.f; v[3].x = sx; v[3].y = 0; v[3].tu = 1.f; v[3].tv = 0; DWORD dwColor = LinearColor(1.f,1.f,1.f,1.f); int i; for(i=0;i<4;i++) { v[i].color = dwColor; v[i].z = 0; v[i].h = 1.0f; } //pd3dDevice->SetTextureStageState( 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1 ); // modulate operation //pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG2 ); // //pd3dDevice->SetRenderState( D3DRS_COLORWRITEENABLE, // D3DCOLORWRITEENABLE_RED | D3DCOLORWRITEENABLE_GREEN | // D3DCOLORWRITEENABLE_BLUE | D3DCOLORWRITEENABLE_ALPHA ); pd3dDevice->SetRenderState( D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_ALPHA ); pd3dDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE); pd3dDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_ZERO); pd3dDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_SRCALPHA); /*pd3dDevice->SetTextureStageState(0, D3DTSS_COLOROP,D3DTOP_SELECTARG2); pd3dDevice->SetTextureStageState(0, D3DTSS_COLORARG1,D3DTA_TEXTURE); pd3dDevice->SetTextureStageState(0, D3DTSS_COLORARG2,D3DTA_CURRENT); pd3dDevice->SetTextureStageState(0, D3DTSS_ALPHAOP,D3DTOP_SELECTARG1); pd3dDevice->SetTextureStageState(0, D3DTSS_ALPHAARG1,D3DTA_TEXTURE); pd3dDevice->SetTextureStageState(0, D3DTSS_ALPHAARG2,D3DTA_CURRENT);*/ pd3dDevice->SetTexture(0, m_pMask->GetTexture()); RenderDevice::DrawPrimitiveUP( pd3dDevice, RenderDevice::DRAW_PERF_TRIANGLES_MESH, D3DPT_TRIANGLESTRIP, 2, v, sizeof(DXUT_SCREEN_VERTEX) ); /*pd3dDevice->SetTextureStageState(0, D3DTSS_COLOROP,D3DTOP_MODULATE); pd3dDevice->SetTextureStageState(0, D3DTSS_COLORARG1,D3DTA_TEXTURE); pd3dDevice->SetTextureStageState(0, D3DTSS_COLORARG2,D3DTA_CURRENT); pd3dDevice->SetTextureStageState(0, D3DTSS_ALPHAOP,D3DTOP_SELECTARG1); pd3dDevice->SetTextureStageState(0, D3DTSS_ALPHAARG1,D3DTA_TEXTURE); pd3dDevice->SetTextureStageState(0, D3DTSS_ALPHAARG2,D3DTA_CURRENT);*/ pd3dDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA); pd3dDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA); pd3dDevice->SetRenderState( D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_RED | D3DCOLORWRITEENABLE_GREEN | D3DCOLORWRITEENABLE_BLUE | D3DCOLORWRITEENABLE_ALPHA ); } } #endif // draw the head on display GUI RenderHeadOnDisplay(); ////////////////////////////////////////////////////////////////////////// // Restore state for the normal pipeline pEffectManager->SetScene(pOldScene); // enable fog pEffectManager->EnableFog(CGlobals::GetScene()->IsFogEnabled()); // restore the main scene's state CGlobals::GetSceneState()->m_pCurrentEffect = sceneState.m_pCurrentEffect; if(old_IsLocalLightEnabled) pEffectManager->EnableLocalLighting(old_IsLocalLightEnabled); }
HRESULT CGlowEffect::Render(float fGlowThreshold, float fGlowAmount, bool bUseAlpha) { //#ifdef _DEBUG // bUseAlpha = true; //#endif HRESULT hr=S_OK; LPDIRECT3DDEVICE9 pd3dDevice = CGlobals::GetRenderDevice(); // get current render target m_pBackBuffer = CGlobals::GetDirectXEngine().GetRenderTarget(); if(FAILED(pd3dDevice->GetDepthStencilSurface(&m_pZBuffer))) return E_FAIL; if(!m_pBackBuffer || !m_pZBuffer) return E_FAIL; // Copy scene to lower resolution render target texture if( FAILED(hr = pd3dDevice->StretchRect( m_pBackBuffer, NULL, m_pRTHalfSizeSurface, NULL, D3DTEXF_LINEAR )) ) { OUTPUT_LOG("StretchRect() failed!\r\n"); return hr; } EffectManager* pEffectManager = CGlobals::GetEffectManager(); pEffectManager->BeginEffect(TECH_FULL_SCREEN_GLOW); CEffectFile* pEffectFile = pEffectManager->GetCurrentEffectFile(); if(pEffectFile != 0 && pEffectFile->begin(true, 0)) { // full screen glow effect is completed in four steps. assert(pEffectFile->totalPasses() == 4); mesh_vertex_plain quadVertices[4] = { {Vector3(-1,-1,0), Vector2(0,1)}, { Vector3(1, -1, 0), Vector2(1, 1) }, { Vector3(-1, 1, 0), Vector2(0, 0) }, { Vector3(1, 1, 0), Vector2(1, 0) }, }; // offset the texture coordinate by half texel in order to match texel to pixel. // This takes me hours to figure out. :-( float fhalfTexelWidth = 0.5f/m_glowtextureWidth; float fhalfTexelHeight = 0.5f/m_glowtextureHeight; for (int i=0;i<4;++i) { quadVertices[i].uv.x += fhalfTexelWidth; quadVertices[i].uv.y += fhalfTexelHeight; } // shader constants /* #ifdef TEST_GLOW static int i=0; ++i; if(i>30){ fGlowAmount = 1.0f; fGlowThreshold = 0.f; if(i>60) i=0; } else { fGlowAmount = 0.f; fGlowThreshold = 1.0f; } #endif*/ /* pEffectFile->setParameter(CEffectFile::k_ConstVector0, (const float*)&Vector4(1/m_glowtextureWidth, 1/m_glowtextureHeight, 0.0f, 0.0f)); LinearColor glowness = pEffectManager->GetGlowness(); glowness.a = fGlowThreshold; glowness.r *= fGlowAmount; glowness.g *= fGlowAmount; glowness.b *= fGlowAmount; pEffectFile->setParameter(CEffectFile::k_ConstVector1, (const float*)&glowness); */ bUseAlpha = true; if(bUseAlpha) { ////////////////////////////////////////////////////////////////////////// // make the glow source. Multiply texture alpha * RGB to get the glow sources pd3dDevice->SetRenderTarget( 0, m_pRTGlowSourceSurface); pd3dDevice->SetDepthStencilSurface( NULL ); if(pEffectFile->BeginPass(0)) { pEffectFile->setTexture(0, m_pRTHalfSizeTexture); LPD3DXEFFECT fx = pEffectFile->GetDXEffect(); fx->SetFloat(fx->GetParameterByName(NULL,"glowThreshold"),fGlowThreshold); pEffectFile->CommitChanges(); HRESULT hr = RenderDevice::DrawPrimitiveUP( pd3dDevice, RenderDevice::DRAW_PERF_TRIANGLES_MESH, D3DPT_TRIANGLESTRIP,2,quadVertices,sizeof(mesh_vertex_plain)); pEffectFile->EndPass(); } } ////////////////////////////////////////////////////////////////////////// // Blur glow sources in the horizontal axis pd3dDevice->SetRenderTarget( 0, m_pRTBlurHorizSurface ); pd3dDevice->SetDepthStencilSurface( NULL ); // no need to clear alpha channel? // pd3dDevice->Clear( 0, NULL, D3DCLEAR_TARGET, 0x00, 1.0f, 0 ); if(pEffectFile->BeginPass(1)) { SetBlurEffectParameters(1.0f / m_glowtextureWidth,0,fGlowAmount,pEffectFile); pEffectFile->setTexture(0, m_pRTGlowSourceTexture); pEffectFile->CommitChanges(); HRESULT hr = RenderDevice::DrawPrimitiveUP( pd3dDevice, RenderDevice::DRAW_PERF_TRIANGLES_MESH, D3DPT_TRIANGLESTRIP,2,quadVertices,sizeof(mesh_vertex_plain)); pEffectFile->EndPass(); } // set texture 0 to NULL so same texture is never simultaneously a source and render target pEffectFile->setTexture( 0, (LPDIRECT3DTEXTURE9)NULL ); ////////////////////////////////////////////////////////////////////////// // Blur the horizontal blur in the vertical direction pd3dDevice->SetRenderTarget( 0, m_pRTBlurVertSurface ); pd3dDevice->SetDepthStencilSurface( NULL ); // no need to clear alpha channel? // pd3dDevice->Clear( 0, NULL, D3DCLEAR_TARGET, 0x00, 1.0f, 0 ); //fGlowAmount = 2; if(pEffectFile->BeginPass(1)) { //pEffectFile->setTexture( 1, m_pRTBlurHorizTexture ); SetBlurEffectParameters(0,1.0f / m_glowtextureHeight,fGlowAmount,pEffectFile); pEffectFile->setTexture(0, m_pRTBlurHorizTexture ); //editor here!!! pEffectFile->CommitChanges(); HRESULT hr = RenderDevice::DrawPrimitiveUP( pd3dDevice, RenderDevice::DRAW_PERF_TRIANGLES_MESH, D3DPT_TRIANGLESTRIP,2,quadVertices,sizeof(mesh_vertex_plain)); pEffectFile->EndPass(); } // Set all textures to NULL to prevent RTT being bound as source and destination at the same time, pEffectFile->setTexture( 0,(LPDIRECT3DTEXTURE9)NULL ); ////////////////////////////////////////////////////////////////////////// // Add the final blur image to the back buffer pd3dDevice->SetRenderTarget( 0, m_pBackBuffer); pd3dDevice->SetDepthStencilSurface( NULL ); // no need to clear alpha channel? // pd3dDevice->Clear( 0, NULL, D3DCLEAR_TARGET, 0x00, 1.0f, 0 ); for (int i=0;i<4;++i) { quadVertices[i].uv.x -= fhalfTexelWidth * 0.5f; quadVertices[i].uv.y -= fhalfTexelHeight * 0.5f; } if(pEffectFile->BeginPass(3)) { pEffectFile->setTexture(0, m_pRTHalfSizeTexture ); pEffectFile->setTexture(1,m_pRTBlurVertTexture); Vector4 glowParam = pEffectManager->GetGlowness(); LPD3DXEFFECT fx = pEffectFile->GetDXEffect(); fx->SetVector(fx->GetParameterByName(NULL,"glowParams"), (const DeviceVector4*)&glowParam); pEffectFile->CommitChanges(); HRESULT hr = RenderDevice::DrawPrimitiveUP( pd3dDevice, RenderDevice::DRAW_PERF_TRIANGLES_MESH, D3DPT_TRIANGLESTRIP,2,quadVertices,sizeof(mesh_vertex_plain)); pEffectFile->EndPass(); pEffectFile->setTexture( 0, (LPDIRECT3DTEXTURE9)NULL ); pEffectFile->setTexture(1,(LPDIRECT3DTEXTURE9)NULL); } // restore depth stencil buffer pd3dDevice->SetDepthStencilSurface( m_pZBuffer ); pEffectFile->end(); } else { CGlobals::GetScene()->EnableFullScreenGlow(false); //Glow effect will not be load when graphics setting set to middle //so we just disable this warnning //OUTPUT_LOG("can not set full screen glow effect error \r\n"); } SAFE_RELEASE(m_pZBuffer); return hr; }
HRESULT ParaEngine::CLightObject::RenderMesh(SceneState * sceneState) { if (!m_pAnimatedMesh) return E_FAIL; if (GetPrimaryTechniqueHandle() < 0) { // try loading the asset if it has not been done before. m_pAnimatedMesh->LoadAsset(); if (m_pAnimatedMesh->IsLoaded()) { SetPrimaryTechniqueHandle(m_pAnimatedMesh->GetPrimaryTechniqueHandle()); UpdateGeometry(); } return E_FAIL; } if (!CGlobals::GetEffectManager()->IsCurrentEffectValid()) { return E_FAIL; } CParaXModel* pModel = m_pAnimatedMesh->GetModel(0); if (pModel == NULL) return E_FAIL; sceneState->SetCurrentSceneObject(this); SetFrameNumber(sceneState->m_nRenderCount); // get world transform matrix Matrix4 mxWorld; GetRenderMatrix(mxWorld); RenderDevicePtr pd3dDevice = sceneState->m_pd3dDevice; EffectManager* pEffectManager = CGlobals::GetEffectManager(); pEffectManager->applyObjectLocalLighting(this); CEffectFile* pEffectFile = pEffectManager->GetCurrentEffectFile(); CGlobals::GetWorldMatrixStack().push(mxWorld); if (pEffectFile == 0) { // TODO: Fixed Function. } else { // apply block space lighting for object whose size is comparable to a single block size BlockWorldClient* pBlockWorldClient = BlockWorldClient::GetInstance(); if (pBlockWorldClient && pBlockWorldClient->IsInBlockWorld()) { uint8_t brightness[2]; Uint16x3 blockId_ws(0, 0, 0); Vector3 vPos = GetPosition(); BlockCommon::ConvertToBlockIndex(vPos.x, vPos.y + 0.1f, vPos.z, blockId_ws.x, blockId_ws.y, blockId_ws.z); float fLightness; pBlockWorldClient->GetBlockMeshBrightness(blockId_ws, brightness); // block light float fBlockLightness = Math::Max(pBlockWorldClient->GetLightBrightnessFloat(brightness[0]), 0.1f); sceneState->GetCurrentLightStrength().y = fBlockLightness; // sun light fLightness = Math::Max(pBlockWorldClient->GetLightBrightnessFloat(brightness[1]), 0.1f); sceneState->GetCurrentLightStrength().x = fLightness; fLightness *= pBlockWorldClient->GetSunIntensity(); fLightness = Math::Max(fLightness, fBlockLightness); sceneState->GetLocalMaterial().Ambient = (LinearColor(fLightness*0.7f, fLightness*0.7f, fLightness*0.7f, 1.f)); sceneState->GetLocalMaterial().Diffuse = (LinearColor(fLightness*0.4f, fLightness*0.4f, fLightness*0.4f, 1.f)); sceneState->EnableLocalMaterial(true); } // just a single standing animation is supported now and looped. if (!m_CurrentAnim.IsValid()) m_CurrentAnim = pModel->GetAnimIndexByID(0); if (m_CurrentAnim.IsValid()) { int nAnimLength = std::max(1, m_CurrentAnim.nEndFrame - m_CurrentAnim.nStartFrame); int nToDoFrame = (m_CurrentAnim.nCurrentFrame + (int)(sceneState->dTimeDelta * 1000)) % nAnimLength; m_CurrentAnim.nCurrentFrame = nToDoFrame; } pModel->m_CurrentAnim = m_CurrentAnim; pModel->m_NextAnim.nIndex = 0; pModel->m_BlendingAnim.MakeInvalid(); pModel->blendingFactor = 0; pModel->animate(sceneState, NULL); // force CParaXModel::BMAX_MODEL? pModel->draw(sceneState, NULL); } CGlobals::GetWorldMatrixStack().pop(); return S_OK; }