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; }
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; }
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; }
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; }