예제 #1
0
	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;
	}
예제 #2
0
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;
}