Exemple #1
0
HRESULT CPainter::DrawSprite(GUITextureElement* pElement, RECT *prcDest, float depth)
{
	// no need to draw complete transparent element
	if (pElement == NULL || pElement->TextureColor.a == 0)
		return S_OK;
	HRESULT hr = S_OK;

	TextureEntity* pTexture = pElement->GetTexture();
	if (pTexture == NULL)
		return E_FAIL;

	RECT rcTexture;
	pElement->GetRect(&rcTexture);

	RECT rcScreen = *prcDest;

	if (pTexture->SurfaceType == TextureEntity::SysMemoryTexture)
	{
//#ifdef USE_DIRECTX_RENDERER
//		POINT pt = { rcScreen.left, rcScreen.top };
//		hr = CGlobals::GetRenderDevice()->UpdateSurface(((TextureEntityDirectX*)pTexture)->GetSurface(), &rcTexture, guiroot->GetGUIState().pBackSurface, &pt);
//#endif
	}
	else
	{
		if (pTexture->GetTexture() != 0)
		{
			if (RectWidth(rcTexture) != 0 || RectHeight(rcTexture) != 0)
			{
				float fScaleX = Math::Abs((float)RectWidth(rcScreen) / (RectWidth(rcTexture)));
				float fScaleY = Math::Abs((float)RectHeight(rcScreen) / (RectHeight(rcTexture)));

				Matrix4 matTransform(Matrix4::IDENTITY);
				matTransform.setScale(Vector3(fScaleX, fScaleY, 0.f));
				matTransform._43 = depth;
				SetSpriteTransform(&matTransform);

				Vector3 vPos((float)rcScreen.left, (float)rcScreen.top, 0.f);

				vPos.x /= fScaleX;
				vPos.y /= fScaleY;
				
				hr = engine->DrawQuad(pTexture, &rcTexture, NULL, &vPos, pElement->TextureColor);
			}
			else
				hr = E_FAIL;
		}
		else
		{
			if (pTexture->IsPending() && state)
				state->AddPendingAsset(1);
		}
	}

	return hr;
}
Exemple #2
0
HRESULT CPainter::DrawSprite(GUITextureElement* pElement, RECT *prcDest, Matrix4 matTransform, float depth)
{
	// no need to draw complete transparent element
	if (pElement == NULL || pElement->TextureColor.a == 0)
		return S_OK;

	TextureEntity* pTexture = pElement->GetTexture();
	if (pTexture == NULL)
		return E_FAIL;

	RECT rcTexture;
	pElement->GetRect(&rcTexture);

	RECT rcScreen = *prcDest;

	if (pTexture->SurfaceType == TextureEntity::SysMemoryTexture)
	{
		return DrawSprite(pElement, prcDest, depth);
	}

	if (pTexture->GetTexture() != 0)
	{
		if (RectWidth(rcTexture) != 0 || RectHeight(rcTexture) != 0)
		{
			float fScaleX = Math::Abs((float)RectWidth(rcScreen) / (RectWidth(rcTexture)));
			float fScaleY = Math::Abs((float)RectHeight(rcScreen) / (RectHeight(rcTexture)));

			matTransform._11 *= fScaleX;
			matTransform._22 *= fScaleY;
			matTransform._43 = depth;

			SetSpriteTransform(&matTransform);

			Vector3 vPos((float)rcScreen.left, (float)rcScreen.top, 0.f);

			vPos.x /= fScaleX;
			vPos.y /= fScaleY;
			return engine->DrawQuad(pTexture, &rcTexture, NULL, &vPos, pElement->TextureColor);
		}
		else
			return E_FAIL;
	}
	else
	{
		if (pTexture->IsPending() && state)
			state->AddPendingAsset(1);
	}
	return S_OK;
}
bool ModelRenderPass::init_FX(CParaXModel *m, SceneState* pSceneState,CParameterBlock* pMaterialParams)
{
	if(m->showGeosets[geoset] == false || indexCount == 0)
		return false;
	Vector4 ocol(1,1,1,m->m_trans);
	Vector4 ecol(0,0,0,0);

	// Emissive colors
	if (color!=-1) {
		// TODO: non-local provider?
		Vector3 c = m->colors[color].color.getValue(m->m_CurrentAnim);
		float o = m->colors[color].opacity.getValue(m->m_CurrentAnim);
		ocol.w *= o;
		if (unlit) {
			ocol.x = c.x; ocol.y = c.y; ocol.z = c.z;
		} else {
			ocol.x = ocol.y = ocol.z = 0;
		}
		ecol = Vector4(c, ocol.w);
	}


	// opacity
	if (opacity!=-1) {
		ocol.w *= m->transparency[opacity].trans.getValue(m->m_CurrentAnim);
	}

	float materialAlpha = 1.f;
	bool nozwrite_ = nozwrite;
	if(pMaterialParams != NULL)
	{
		CParameter* pParams = pMaterialParams->GetParameter("g_opacity");
		if(pParams)
			materialAlpha = (float)(*pParams);
		pParams = pMaterialParams->GetParameter("zwrite");
		if (pParams && (bool)(*pParams) == false)
			nozwrite_ = true;
	}
	ocol.w *= materialAlpha;

	// if the opacity or Emissive color is 0, we should not draw this pass. 
	if(( (ocol.w > 0) && (color==-1 || (ecol.w > 0)) ) == false)
		return false;

	/// Set the texture
	TextureEntity* bindtex = NULL;
	if (m->specialTextures[tex]==-1) 
		bindtex = m->textures[tex].get();
	else 
	{
		bindtex = m->replaceTextures[m->specialTextures[tex]];
		// use default texture if replaceable texture is not specified. 
		if(bindtex == 0)
			bindtex = m->textures[tex].get();
	}

	// do not render for NULL textures, possibly because the texture is not fully loaded. 
	if (!bindtex || bindtex->GetTexture() == 0)
		return false;

	if(pSceneState->IsIgnoreTransparent() && (blendmode == BM_ADDITIVE || blendmode == BM_ALPHA_BLEND || blendmode == BM_ADDITIVE_ALPHA
		|| materialAlpha < 1))
	{
		return false;
	}

	RenderDevicePtr pd3dDevice = CGlobals::GetRenderDevice();
	CEffectFile* pEffect = CGlobals::GetEffectManager()->GetCurrentEffectFile();
	PE_ASSERT(pEffect!=0);
	if (!pSceneState->IsShadowPass())
	{
		// blend mode
		switch (blendmode) {
		case BM_TRANSPARENT: // 1
			pEffect->EnableAlphaTesting(true);
			break;
		case BM_ALPHA_BLEND: // 2
			pEffect->EnableAlphaBlending(true);
			break;
		case BM_ADDITIVE: // 3
			pEffect->EnableAlphaBlending(true);
			pd3dDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_ONE);
			pd3dDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_ONE);
			break;
		case BM_ADDITIVE_ALPHA: // 4
			pEffect->EnableAlphaBlending(true);
			pd3dDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
			pd3dDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_ONE);
			break;
		default: // BM_OPAQUE
			// default to OPAQUE
			// Note 2009.8.9: enable alpha test is enabled even for opaque character
			// pEffect->EnableAlphaBlending(false);
			// pEffect->EnableAlphaTesting(false);
			break;
		}

		if (nozwrite_) {
			CGlobals::GetEffectManager()->EnableZWrite(false);
		}

		if (!cull) {
			CGlobals::GetEffectManager()->SetCullingMode(false);
		}

		/*
		if(opacity != -1)
		{
		pEffect->setFloat(CEffectFile::k_opacity, ocol.w);
		}
		*/

		// color
		if (blendmode <= 1 && ocol.w<0.999f)
		{
			blendmode |= BM_TEMP_FORCEALPHABLEND;
			pEffect->EnableAlphaBlending(true);
			pEffect->setFloat(CEffectFile::k_opacity, ocol.w);
		}
		else if (opacity != -1)
		{
			pEffect->setFloat(CEffectFile::k_opacity, ocol.w);
		}

		if (color != -1)
		{
			Vector3 color_(ecol.x, ecol.y, ecol.z);
			pEffect->setParameter(CEffectFile::k_emissiveMaterialColor, &color_);
		}

		if (unlit) {
			pEffect->EnableSunLight(false);
		}

		if (texanim != -1) {

			//if(m->animTexRGB)
			//pEffect->setParameter(CEffectFile::k_bBoolean7,(const float*)&Vector4(1,0,0,0));

			const TextureAnim& texAnim = m->texanims[texanim];
			//OUTPUT_LOG("UV off: %f  %f\n", texAnim.tval.x, texAnim.tval.y);
			// it will interpolate between interval 1/30 second, hence when implementing blinking eye animation, make sure that the animation is still all right with intepolation on 1/30 texture UV animation. 
			Vector4 v(texAnim.tval.x, texAnim.tval.y, 0.f, 0.f);
			pEffect->setParameter(CEffectFile::k_ConstVector0, &v);
			//pEffect->setParameter(CEffectFile::k_ConstVector0, (const float*)&Vector4(0.00000f,0.242f, 0.f, 0.f));
		}

		if (GetCategoryId() > 0)
		{
			Vector4 v((float)GetCategoryId(), 0.f, 0.f, 0.f);
			pEffect->setParameter(CEffectFile::k_ConstVector1, &v);
		}

		if (pEffect->isParameterUsed(CEffectFile::k_transitionFactor) && pMaterialParams != NULL)
		{

			CParameter* pParams = pMaterialParams->GetParameter("transitionFactor");
			if (pParams)
				pEffect->setFloat(CEffectFile::k_transitionFactor, (float)(*pParams));
		}
	}
	else
	{
		if (blendmode == BM_TRANSPARENT)
			pEffect->EnableAlphaTesting(true);
	}
	
	/// Set the texture
	pEffect->setTexture(0, bindtex);

	if(is_rigid_body)
	{
		Matrix4 mat, mat1;
		mat1 = m->bones[(m->m_origVertices[m->m_indices[m_nIndexStart]+GetVertexStart(m)]).bones[0]].mat;
		mat = mat1 * CGlobals::GetWorldMatrixStack().SafeGetTop();
		CGlobals::GetWorldMatrixStack().push(mat);
		pEffect->applyWorldMatrices();
	}

	return true;
}
bool ModelRenderPass::init(CParaXModel *m, SceneState* pSceneState)
{
	if(m->showGeosets[geoset] == false)
		return false;
	Vector4 ocol(1,1,1,m->m_trans);
	Vector4 ecol(0,0,0,0);

	// Emissive colors
	if (color!=-1) {
		// TODO: non-local provider?
		Vector3 c = m->colors[color].color.getValue(m->m_CurrentAnim);
		float o = m->colors[color].opacity.getValue(m->m_CurrentAnim);
		ocol.w *= o;
		if (unlit) {
			ocol.x = c.x; ocol.y = c.y; ocol.z = c.z;
		} else {
			ocol.x = ocol.y = ocol.z = 0;
		}
		ecol = Vector4(c, ocol.w);
	}

	// opacity
	if (opacity!=-1) {
		// TODO: non-local provider?
		ocol.w *= m->transparency[opacity].trans.getValue(m->m_CurrentAnim);
	}

	if(( (ocol.w > 0) && (color==-1 || (ecol.w > 0)) ) == false)
		return false;

	/// Set the texture
	TextureEntity* bindtex = NULL;
	if (m->specialTextures[tex]==-1) 
		bindtex = m->textures[tex].get();
	else 
	{
		bindtex = m->replaceTextures[m->specialTextures[tex]];
		// use default texture if replaceable texture is not specified. 
		if(bindtex == 0)
			bindtex = m->textures[tex].get();
	}
#ifdef USE_DIRECTX_RENDERER
	LPDIRECT3DTEXTURE9 pTex = NULL;
	if(bindtex)
		pTex = bindtex->GetTexture();

	// do not render for NULL textures, possibly because the texture is not fully loaded. 
	if(pTex==NULL)
		return false;

	if(pSceneState->IsIgnoreTransparent() && (blendmode == BM_ADDITIVE || blendmode == BM_ALPHA_BLEND || blendmode == BM_ADDITIVE_ALPHA))
	{
		return false;
	}

	LPDIRECT3DDEVICE9 pd3dDevice = CGlobals::GetRenderDevice();
	// blend mode
	switch (blendmode) {
	case BM_TRANSPARENT: // 1
		pd3dDevice->SetRenderState(D3DRS_ALPHATESTENABLE, TRUE);
		break;
	case BM_ALPHA_BLEND: // 2
		pd3dDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
		break;
	case BM_ADDITIVE: // 3
		pd3dDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);	
		pd3dDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_ONE);
		pd3dDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_ONE);
		break;
	case BM_ADDITIVE_ALPHA: // 4
		pd3dDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);	
		pd3dDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
		pd3dDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_ONE);
		break;
	default: // BM_OPAQUE
		// default to OPAQUE
		//pd3dDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE);
		//pd3dDevice->SetRenderState(D3DRS_ALPHATESTENABLE, FALSE); 
		break;
	}

	if (nozwrite) {
		CGlobals::GetEffectManager()->EnableZWrite(false);
	}

	if (!cull) {
		CGlobals::GetEffectManager()->SetCullingMode(false);
	}

	pd3dDevice->SetTexture(0, pTex);

	if (unlit) {
		pd3dDevice->SetRenderState( D3DRS_LIGHTING, FALSE );
	}

	if (texanim!=-1) {
		// it will interpolate between interval 1/30 second, hence when implementing blinking eye animation, make sure that the animation is still all right with interpolation on 1/30 texture UV animation. 
		//// Set up the matrix for the desired transformation.
		Matrix4 texMat;
		const TextureAnim& texAnim = m->texanims[texanim];
		
		// interesting that it uses _31 and _32 instead of _41, _42 for the UV translation.
		texMat = Matrix4::IDENTITY;
		texMat._31 = texAnim.tval.x;
		texMat._32 = texAnim.tval.y;
		pd3dDevice->SetTextureStageState( 0, D3DTSS_TEXTURETRANSFORMFLAGS, 	D3DTTFF_COUNT2);
		pd3dDevice->SetTransform( D3DTS_TEXTURE0, texMat.GetConstPointer() );
		//pd3dDevice->SetTextureStageState( 0, D3DTSS_TEXCOORDINDEX, D3DTSS_TCI_PASSTHRU );
	}

	// color
	if (blendmode<=1 && ocol.w<0.99f) 
	{
		pd3dDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
	}

	// TODO: how to programmatically set alpha to ocol.w in fixed function ? right now, it is either on or off. 
	//if(opacity != -1)
	//{
	//	/*pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAOP, D3DTOP_BLENDFACTORALPHA );
	//	pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE );
	//	pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE );
	//	
	//	pd3dDevice->SetRenderState(D3DRS_TEXTUREFACTOR, (DWORD)(LinearColor(1.f, 1.f, 1.f, ocol.w)));*/

	//	ParaMaterial mtrl;
	//	ZeroMemory( &mtrl, sizeof(mtrl) );

	//	// if a material is used, SetRenderState must be used
	//	// vertex color = light diffuse color * material diffuse color
	//	mtrl.Diffuse.r = 1.f;
	//	mtrl.Diffuse.g = 1.f;
	//	mtrl.Diffuse.b = 1.f;
	//	mtrl.Diffuse.a = ocol.w;

	//	/*mtrl.Emissive.r = 1.0f;
	//	mtrl.Emissive.g = 1.0f;
	//	mtrl.Emissive.b = 1.0f;*/
	//	
	//	pd3dDevice->SetMaterial( &mtrl );

	//	pd3dDevice->SetRenderState(D3DRS_COLORVERTEX, TRUE);
	//	
	//	pd3dDevice->SetRenderState(D3DRS_DIFFUSEMATERIALSOURCE, D3DMCS_MATERIAL);
	//	pd3dDevice->SetRenderState(D3DRS_EMISSIVEMATERIALSOURCE, D3DMCS_MATERIAL);

	//	//pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1 );
	//	// pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAARG1, D3DTA_DIFFUSE );
	//}

#ifdef TODO
	/// TODO: set texture addressing
	if (swrap) {

	}
	if (twrap) {

	}
	if (useenvmap) {
		// environment mapping
		// TODO: this is not implemented yet.
	}
#endif

	if(is_rigid_body)
	{
		Matrix4 mat, mat1;
		mat1 = m->bones[(m->m_origVertices[m->m_indices[m_nIndexStart]+GetVertexStart(m)]).bones[0]].mat;
		mat = mat1 * CGlobals::GetWorldMatrixStack().SafeGetTop();
		CGlobals::GetWorldMatrixStack().push(mat);
		pd3dDevice->SetTransform(D3DTS_WORLD, mat.GetConstPointer());
	}
#endif
	return true;
}
Exemple #5
0
HRESULT CPainter::DrawSprite(GUITextureElement* pElement, RECT *prcDest, int n, float depth)
{
	// no need to draw complete transparent element
	if (pElement == NULL || pElement->TextureColor.a == 0)
		return S_OK;
	n = n % 4;

	TextureEntity* pTexture = pElement->GetTexture();
	if (pTexture == NULL)
		return E_FAIL;

	RECT rcTexture;
	pElement->GetRect(&rcTexture);

	RECT rcScreen = *prcDest;

	if (pTexture->SurfaceType == TextureEntity::SysMemoryTexture)
	{
		return DrawSprite(pElement, prcDest, depth);
	}

	if (pTexture->GetTexture() != 0)
	{
		if (RectWidth(rcTexture) != 0 || RectHeight(rcTexture) != 0)
		{
			float fScaleX;
			float fScaleY;
			Vector3 vCenter((float)RectWidth(rcTexture) / 2, (float)RectHeight(rcTexture) / 2, 0.f);
			Matrix4 matTransform;
			switch (n) {
			case 0:
				fScaleX = (float)RectWidth(rcScreen) / RectWidth(rcTexture);
				fScaleY = (float)RectHeight(rcScreen) / RectHeight(rcTexture);
				matTransform = Matrix4::IDENTITY;
				break;
			case 1:
			case -3:
				fScaleX = (float)RectWidth(rcScreen) / RectHeight(rcTexture);
				fScaleY = (float)RectHeight(rcScreen) / RectWidth(rcTexture);
				ParaMatrixRotationZ(&matTransform, (float)3.1415926536 / 2);
				break;
			case 2:
			case -2:
				fScaleX = (float)RectWidth(rcScreen) / RectWidth(rcTexture);
				fScaleY = (float)RectHeight(rcScreen) / RectHeight(rcTexture);
				ParaMatrixRotationZ(&matTransform, (float)3.1415926536 / 2);
				break;
			case 3:
			case -1:
				fScaleX = (float)RectWidth(rcScreen) / RectHeight(rcTexture);
				fScaleY = (float)RectHeight(rcScreen) / RectWidth(rcTexture);
				ParaMatrixRotationZ(&matTransform, (float)-3.1415926536 / 2);
				break;
			}
			fScaleX = Math::Abs(fScaleX);
			fScaleY = Math::Abs(fScaleY);
			matTransform._41 = (float)rcScreen.left + (float)RectWidth(rcScreen) / 2; matTransform._42 = (float)rcScreen.top + (float)RectHeight(rcScreen) / 2;
			matTransform._11 *= fScaleX;
			matTransform._21 *= fScaleX;
			matTransform._22 *= fScaleY;
			matTransform._12 *= fScaleY;
			matTransform._43 = depth;

			SetSpriteTransform(&matTransform);

			return engine->DrawQuad(pTexture, &rcTexture, &vCenter, NULL, pElement->TextureColor);
		}
		else
			return E_FAIL;
	}
	else
	{
		if (pTexture->IsPending() && state)
			state->AddPendingAsset(1);
	}
	return S_OK;
}
Exemple #6
0
HRESULT CPainter::DrawSprite(GUITextureElement* pElement, RECT *prcDest, const Vector2& vRotOrigin, float fRadian, const Vector2* vScaling, const Vector2* vTranslation, const DWORD* dwColorMask, float depth)
{
	// no need to draw complete transparent element
	if (pElement == NULL || pElement->TextureColor.a == 0)
		return S_OK;
	HRESULT hr = S_OK;

	TextureEntity* pTexture = pElement->GetTexture();
	if (pTexture == NULL)
		return E_FAIL;

	RECT rcTexture;
	pElement->GetRect(&rcTexture);

	RECT rcScreen = *prcDest;

	if (pTexture->SurfaceType == TextureEntity::SysMemoryTexture)
	{
//#ifdef USE_DIRECTX_RENDERER
//		POINT pt = { rcScreen.left, rcScreen.top };
//		hr = guiroot->m_stateGUI.pd3dDevice->UpdateSurface(((TextureEntityDirectX*)pTexture)->GetSurface(), &rcTexture, guiroot->GetGUIState().pBackSurface, &pt);
//#endif
	}
	else
	{
		if (pTexture->GetTexture() != 0)
		{
			if (RectWidth(rcTexture) != 0 || RectHeight(rcTexture) != 0)
			{
				float fScaleX = Math::Abs((float)RectWidth(rcScreen) / RectWidth(rcTexture));
				float fScaleY = Math::Abs((float)RectHeight(rcScreen) / RectHeight(rcTexture));
				if (vScaling)
				{
					fScaleX *= vScaling->x;
					fScaleY *= vScaling->y;
				}

				//////////////////////////////////////////
				// the following code can do rotation: LiXizhi 2007.9.28
				//////////////////////////////////////////
				Matrix4 matTransform;
				Vector2 vPos((float)rcScreen.left, (float)rcScreen.top);
				if (vScaling || vTranslation || fRadian != 0.f)
				{
					vPos -= vRotOrigin;
					ParaMatrixTransformation2D(&matTransform, NULL, 0.0, vScaling, NULL, fRadian, vTranslation);
					vPos = vPos * matTransform;
					vPos += vRotOrigin;
				}

				// out, scaling center, scaling rotation, scaling, rotation center, rotation, translation
				Vector2 vScale(fScaleX, fScaleY);
				ParaMatrixTransformation2D(&matTransform, NULL, 0.0, &vScale, NULL, fRadian, &vPos);
				matTransform._43 = depth;

				SetSpriteTransform(&matTransform);
				Color dwColor;
				if (dwColorMask == 0)
					dwColor = pElement->TextureColor;
				else
				{
					LinearColor colorMask(*dwColorMask);
					colorMask.a *= pElement->TextureColor.a;
					colorMask.r *= pElement->TextureColor.r;
					colorMask.g *= pElement->TextureColor.g;
					colorMask.b *= pElement->TextureColor.b;
					dwColor = colorMask;
				}
				
				hr = engine->DrawQuad(pTexture, &rcTexture, NULL, NULL, dwColor);
			}
			else
				hr = E_FAIL;
		}
		else
		{
			if (pTexture->IsPending() && state)
				state->AddPendingAsset(1);
		}
	}
	return hr;
}