// Z3DAttachment.cpp: implementation of the CZ3DAttachment class. // ////////////////////////////////////////////////////////////////////// #include "Z3DAttachment.h" #include "RenderOption.h" #include "ShaderConstants.h" #include "SceneManager.h" #include "Texture.h" #include "Shader_IndexHeader.h" #include "ShaderScene.h" #include "SceneStateMgr.h" #define Z3D_ATTACHMENT_BANK_SIZE 100 ////////////////////////////////////////////////////////////////////// // Construction/Destruction ////////////////////////////////////////////////////////////////////// /*CZ3DAttachment::CZ3DAttachment( const char* szMesh, const char* szTex, const vector3 tm_pos, const quaternion tm_dir ) : CZ3DRenderable(true) { Set(szMesh, szTex); m_Pos = tm_pos; m_Dir = tm_dir; m_vPivotPos.Identity(); m_fScaleFactor = 1.0f; }*/ CZ3DAttachment::~CZ3DAttachment() { UnLink(); SAFE_RELEASE( m_pVertexBuffer ); SAFE_RELEASE( m_pIndexBuffer ); SAFE_DELETEA( m_pSTVectors ); SAFE_RELEASE( m_pSTVertexBuffer ); if( NULL != m_tagAMesh.GetObject() ) { m_tagAMesh.Release(); } if( NULL != m_tagTexture.GetObject() ) { m_tagTexture.Release(); } if( NULL != m_tagTexture2.GetObject() ) { m_tagTexture2.Release(); } if( NULL != m_tagSpecTexture.GetObject() ) { m_tagSpecTexture.Release(); } } bool CZ3DAttachment::Set( const char* szMesh, const char* szTex, const char* szTex2, const char* szSpecTex ) { if( NULL != m_tagAMesh.GetObject() ) { m_tagAMesh.Release(); } if( NULL != m_tagTexture.GetObject() ) { m_tagTexture.Release(); } if( NULL != m_tagTexture2.GetObject() ) { m_tagTexture2.Release(); } if( NULL != m_tagSpecTexture.GetObject() ) { m_tagSpecTexture.Release(); } g_ContAMesh.GetObject( m_tagAMesh, szMesh ); g_ContTexture.SetFilePath( WORLDCHRDIFF); g_ContTexture.GetObject( m_tagTexture, szTex ); // Bump ÁöÁ¤ g_ContTexture.SetFilePath( WORLDCHRBUM); g_ContTexture.GetObject( m_tagTexture2, szTex2 ); g_ContTexture.SetFilePath( WORLDCHRENV); g_ContTexture.GetObject( m_tagSpecTexture, szSpecTex ); m_pTexture = *(m_tagTexture.GetObject()); _ASSERT(m_pTexture); //SAFE_DELETEA( m_pVertices ); //m_pVertices = new BumpVertex[m_tagAMesh.GetObject()->m_wVertexCount]; // Create vertex buffer if( m_lVertexCount < m_tagAMesh.GetObject()->m_wVertexCount ) { m_lVertexCount = GetSizeByBank( m_tagAMesh.GetObject()->m_wVertexCount, Z3D_ATTACHMENT_BANK_SIZE ); SAFE_RELEASE( m_pVertexBuffer ); if(CRenderOption::m_CharacterPerPixelLighting) { GetDevice()->CreateVertexBuffer( m_lVertexCount*sizeof(BumpVertex), D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY, 0, D3DPOOL_DEFAULT, &m_pVertexBuffer ); } else { GetDevice()->CreateVertexBuffer( m_lVertexCount*sizeof(D3DVERTEX), D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY, D3DFVF_VERTEX, D3DPOOL_DEFAULT, &m_pVertexBuffer ); } } // Create index buffer if( m_lIndexCount < m_tagAMesh.GetObject()->m_wIndexCount ) { m_lIndexCount = GetSizeByBank( m_tagAMesh.GetObject()->m_wIndexCount, Z3D_ATTACHMENT_BANK_SIZE*4 ); SAFE_RELEASE( m_pIndexBuffer ); GetDevice()->CreateIndexBuffer( m_lIndexCount * sizeof(WORD), D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY, D3DFMT_INDEX16, D3DPOOL_DEFAULT, &m_pIndexBuffer ); } // Fill up index data WORD* pIndex; m_pIndexBuffer->Lock( 0, 0, (BYTE**)(&pIndex), D3DLOCK_DISCARD ); for( int i = 0; i < m_tagAMesh.GetObject()->m_wIndexCount; i++ ) { pIndex[i] = m_tagAMesh.GetObject()->m_pIndices[i]; } m_pIndexBuffer->Unlock(); return true; } void CZ3DAttachment::ApplyTransform() { matrix m; m._11 = m_TM._11 * m_fScaleFactor; m._12 = m_TM._12 * m_fScaleFactor; m._13 = m_TM._13 * m_fScaleFactor; m._14 = 0.0f; m._21 = m_TM._21 * m_fScaleFactor; m._22 = m_TM._22 * m_fScaleFactor; m._23 = m_TM._23 * m_fScaleFactor; m._24 = 0.0f; m._31 = m_TM._31 * m_fScaleFactor; m._32 = m_TM._32 * m_fScaleFactor; m._33 = m_TM._33 * m_fScaleFactor; m._34 = 0.0f; m._41 = m_TM._41 * m_fScaleFactor; m._42 = m_TM._42 * m_fScaleFactor; m._43 = m_TM._43 * m_fScaleFactor; m._44 = 1.0f; if( CRenderOption::m_CharacterPerPixelLighting ) { if( m_bSTVertexMode ) { BumpVertex* pMeshVertex = m_tagAMesh.GetObject()->m_pVertices; BumpVertexST* pVertices; m_pSTVertexBuffer->Lock( 0, 0, (BYTE**)(&pVertices), 0 ); for( int i = 0; i < m_tagAMesh.GetObject()->m_wVertexCount; ++i ) { pVertices[i].v.x = pMeshVertex[i].v.x*m._11 + pMeshVertex[i].v.y*m._21 + pMeshVertex[i].v.z*m._31 + m._41; pVertices[i].v.y = pMeshVertex[i].v.x*m._12 + pMeshVertex[i].v.y*m._22 + pMeshVertex[i].v.z*m._32 + m._42; pVertices[i].v.z = pMeshVertex[i].v.x*m._13 + pMeshVertex[i].v.y*m._23 + pMeshVertex[i].v.z*m._33 + m._43; pVertices[i].n.x = pMeshVertex[i].n.x*m._11 + pMeshVertex[i].n.y*m._21 + pMeshVertex[i].n.z*m._31; pVertices[i].n.y = pMeshVertex[i].n.x*m._12 + pMeshVertex[i].n.y*m._22 + pMeshVertex[i].n.z*m._32; pVertices[i].n.z = pMeshVertex[i].n.x*m._13 + pMeshVertex[i].n.y*m._23 + pMeshVertex[i].n.z*m._33; pVertices[i].tu = pMeshVertex[i].tu; pVertices[i].tv = pMeshVertex[i].tv; pVertices[i].s.x = m_pSTVectors[i].s.x*m._11 + m_pSTVectors[i].s.y*m._21 + m_pSTVectors[i].s.z*m._31; pVertices[i].s.y = m_pSTVectors[i].s.x*m._12 + m_pSTVectors[i].s.y*m._22 + m_pSTVectors[i].s.z*m._32; pVertices[i].s.z = m_pSTVectors[i].s.x*m._13 + m_pSTVectors[i].s.y*m._23 + m_pSTVectors[i].s.z*m._33; pVertices[i].t.x = m_pSTVectors[i].t.x*m._11 + m_pSTVectors[i].t.y*m._21 + m_pSTVectors[i].t.z*m._31; pVertices[i].t.y = m_pSTVectors[i].t.x*m._12 + m_pSTVectors[i].t.y*m._22 + m_pSTVectors[i].t.z*m._32; pVertices[i].t.z = m_pSTVectors[i].t.x*m._13 + m_pSTVectors[i].t.y*m._23 + m_pSTVectors[i].t.z*m._33; } m_pSTVertexBuffer->Unlock(); } else { BumpVertex* pMeshVertex = m_tagAMesh.GetObject()->m_pVertices; BumpVertex* pVertices; m_pVertexBuffer->Lock( 0, 0, (BYTE**)(&pVertices), D3DLOCK_DISCARD ); for( int i = 0; i < m_tagAMesh.GetObject()->m_wVertexCount; ++i ) { pVertices[i].v.x = pMeshVertex[i].v.x*m._11 + pMeshVertex[i].v.y*m._21 + pMeshVertex[i].v.z*m._31 + m._41; pVertices[i].v.y = pMeshVertex[i].v.x*m._12 + pMeshVertex[i].v.y*m._22 + pMeshVertex[i].v.z*m._32 + m._42; pVertices[i].v.z = pMeshVertex[i].v.x*m._13 + pMeshVertex[i].v.y*m._23 + pMeshVertex[i].v.z*m._33 + m._43; pVertices[i].n.x = pMeshVertex[i].n.x*m._11 + pMeshVertex[i].n.y*m._21 + pMeshVertex[i].n.z*m._31; pVertices[i].n.y = pMeshVertex[i].n.x*m._12 + pMeshVertex[i].n.y*m._22 + pMeshVertex[i].n.z*m._32; pVertices[i].n.z = pMeshVertex[i].n.x*m._13 + pMeshVertex[i].n.y*m._23 + pMeshVertex[i].n.z*m._33; pVertices[i].tu = pMeshVertex[i].tu; pVertices[i].tv = pMeshVertex[i].tv; pVertices[i].u.x = pMeshVertex[i].u.x*m._11 + pMeshVertex[i].u.y*m._21 + pMeshVertex[i].u.z*m._31; pVertices[i].u.y = pMeshVertex[i].u.x*m._12 + pMeshVertex[i].u.y*m._22 + pMeshVertex[i].u.z*m._32; pVertices[i].u.z = pMeshVertex[i].u.x*m._13 + pMeshVertex[i].u.y*m._23 + pMeshVertex[i].u.z*m._33; } m_pVertexBuffer->Unlock(); } } else { BumpVertex* pMeshVertex = m_tagAMesh.GetObject()->m_pVertices; D3DVERTEX* pVertices; m_pVertexBuffer->Lock( 0, 0, (BYTE**)(&pVertices), D3DLOCK_DISCARD ); for( int i = 0; i < m_tagAMesh.GetObject()->m_wVertexCount; ++i ) { pVertices[i].x = pMeshVertex[i].v.x*m._11 + pMeshVertex[i].v.y*m._21 + pMeshVertex[i].v.z*m._31 + m._41; pVertices[i].y = pMeshVertex[i].v.x*m._12 + pMeshVertex[i].v.y*m._22 + pMeshVertex[i].v.z*m._32 + m._42; pVertices[i].z = pMeshVertex[i].v.x*m._13 + pMeshVertex[i].v.y*m._23 + pMeshVertex[i].v.z*m._33 + m._43; pVertices[i].nx = pMeshVertex[i].n.x*m._11 + pMeshVertex[i].n.y*m._21 + pMeshVertex[i].n.z*m._31; pVertices[i].ny = pMeshVertex[i].n.x*m._12 + pMeshVertex[i].n.y*m._22 + pMeshVertex[i].n.z*m._32; pVertices[i].nz = pMeshVertex[i].n.x*m._13 + pMeshVertex[i].n.y*m._23 + pMeshVertex[i].n.z*m._33; pVertices[i].tu = pMeshVertex[i].tu; pVertices[i].tv = pMeshVertex[i].tv; } m_pVertexBuffer->Unlock(); } } void CZ3DAttachment::Render() { _ASSERT( m_tagAMesh.GetObject() ); _ASSERT( m_tagAMesh.GetObject()->m_pVertices ); _ASSERT( m_tagAMesh.GetObject()->m_pIndices ); if(m_pEnvMap == NULL) { m_pEnvMap = new CTexture; CTexture::SetPath(EFFECTTEXTUREPATH); m_pEnvMap->Load("cube.dds"); } if(CRenderOption::m_CharacterPerPixelLighting) { //GetDevice()->SetVertexShader( BUMPVERTEXFVF ); } else { GetDevice()->SetVertexShader( D3DFVF_VERTEX ); } matrix m; m.MakeIdent(); m._41 = m_vPivotPos.x; m._42 = m_vPivotPos.y; m._43 = m_vPivotPos.z; GetDevice()->SetTransform( D3DTS_WORLD, m ); //////////// ////////////// Bump Spec Shader Constant Setting /////////////// LPDIRECT3DDEVICE8 lpDevice = GetDevice(); if(CRenderOption::m_CharacterPerPixelLighting) { /*************/ // Set BumpScale lpDevice->SetVertexShaderConstant(CV_BUMP_SCALE, D3DXVECTOR4(0.0f, 0.0f, 0.0f, 1.0f), 1); // lpDevice->SetVertexShaderConstant(21, D3DXVECTOR4(1.0f,1.0f,1.0f,0.0f), 1); //////////////* **************/ //Ãß°¡ lpDevice->SetVertexShaderConstant(CV_ZERO, D3DXVECTOR4(0.0f, 0.0f, 0.0f, 0.0f), 1); lpDevice->SetVertexShaderConstant(CV_ONE, D3DXVECTOR4(1.0f, 1.0f, 1.0f, 1.0f), 1); lpDevice->SetVertexShaderConstant(CV_HALF, D3DXVECTOR4(0.5f, 0.5f, 0.5f, 0.5f), 1); // Matrix Set D3DXMATRIX matWorld,matView,matProject; lpDevice->GetTransform(D3DTS_WORLD,&matWorld); lpDevice->GetTransform(D3DTS_VIEW,&matView); lpDevice->GetTransform(D3DTS_PROJECTION,&matProject); D3DXMATRIX matTemp; D3DXMATRIX matWorldView; D3DXMATRIX matInvWorldView; D3DXMATRIX matWorldViewProj; D3DXMATRIX matInvWorld; D3DXMatrixMultiply(&matTemp, &matWorld, &matView); D3DXMatrixMultiply(&matWorldViewProj, &matTemp, &matProject); D3DXMatrixMultiply(&matWorldView, &matWorld, &matView); D3DXMatrixInverse(&matInvWorld, NULL, &matWorld); D3DXMatrixInverse(&matInvWorldView, NULL, &matWorldView); // Set World Camera Pos D3DXMATRIX pmatPos; lpDevice->GetTransform(D3DTS_VIEW,&pmatPos); D3DXMatrixInverse(&pmatPos, NULL, &pmatPos); D3DXVECTOR3 vecCamera3 = D3DXVECTOR3(pmatPos._41,pmatPos._42,pmatPos._43); D3DXVECTOR4 vecCamera4 = D3DXVECTOR4(vecCamera3.x,vecCamera3.y,vecCamera3.z,0.0f); lpDevice->SetVertexShaderConstant(CV_EYE_POS_WORLD, vecCamera4, 1); // Projection to clip space D3DXMatrixTranspose(&matWorldViewProj, &matWorldViewProj); lpDevice->SetVertexShaderConstant(CV_WORLDVIEWPROJ_0, &matWorldViewProj(0, 0), 4); D3DXMatrixTranspose(&matWorldViewProj, &matWorldViewProj); // Transform to eye space D3DXMatrixTranspose(&matWorldView, &matWorldView); lpDevice->SetVertexShaderConstant(CV_WORLDVIEW_0, &matWorldView(0, 0), 4); D3DXMatrixTranspose(&matWorldView, &matWorldView); // Transform to world space D3DXMatrixTranspose(&matWorld, &matWorld); lpDevice->SetVertexShaderConstant(CV_WORLD_0, &matWorld(0, 0), 4); D3DXMatrixTranspose(&matWorld, &matWorld); // Transform for normals lpDevice->SetVertexShaderConstant(CV_WORLDVIEWIT_0, &matInvWorldView(0, 0), 1); lpDevice->SetVertexShaderConstant(CV_WORLDVIEWIT_1, &matInvWorldView(1, 0), 1); lpDevice->SetVertexShaderConstant(CV_WORLDVIEWIT_2, &matInvWorldView(2, 0), 1); // Set BumpScale // lpDevice->SetVertexShaderConstant(CV_BUMP_SCALE, D3DXVECTOR4(0.0f, 0.0f, 0.0f, 1.0f), 1); } /////////////////////////////////////////////////////////////////// //////////// if( m_tagTexture2.GetObject() ) { GetDevice()->SetTexture( 1, *(m_tagTexture2.GetObject()) ); } else { GetDevice()->SetTexture( 1, NULL ); } //CSceneStateMgr::_SetD3DTextureStageState( 1, D3DTSS_TEXCOORDINDEX, 0); if(CRenderOption::m_CharacterPerPixelLighting) { if( m_bSTVertexMode ) { GetDevice()->SetStreamSource( 0, m_pSTVertexBuffer, sizeof(BumpVertexST) ); } else { GetDevice()->SetStreamSource( 0, m_pVertexBuffer, sizeof(BumpVertex) ); } } else { GetDevice()->SetStreamSource( 0, m_pVertexBuffer, sizeof(D3DVERTEX) ); } GetDevice()->SetIndices( m_pIndexBuffer, 0 ); //////////// Bump Setting ///////////////// if(CRenderOption::m_CharacterPerPixelLighting) { if(CRenderOption::m_bRain) { if(CRenderOption::m_CharacterPerPixelLighting) { /*************/ // Set BumpScale lpDevice->SetVertexShaderConstant(CV_BUMP_SCALE, D3DXVECTOR4(0.0f, 0.0f, 0.0f, 1.0f), 1); // lpDevice->SetVertexShaderConstant(21, D3DXVECTOR4(1.0f,1.0f,1.0f,0.0f), 1); //////////////* **************/ //Ãß°¡ lpDevice->SetVertexShaderConstant(CV_ZERO, D3DXVECTOR4(0.0f, 0.0f, 0.0f, 0.0f), 1); lpDevice->SetVertexShaderConstant(CV_ONE, D3DXVECTOR4(1.0f, 1.0f, 1.0f, 1.0f), 1); lpDevice->SetVertexShaderConstant(CV_HALF, D3DXVECTOR4(0.5f, 0.5f, 0.5f, 0.5f), 1); // Matrix Set D3DXMATRIX matWorld,matView,matProject; lpDevice->GetTransform(D3DTS_WORLD,&matWorld); lpDevice->GetTransform(D3DTS_VIEW,&matView); lpDevice->GetTransform(D3DTS_PROJECTION,&matProject); D3DXMATRIX matTemp; D3DXMATRIX matWorldView; D3DXMATRIX matInvWorldView; D3DXMATRIX matWorldViewProj; D3DXMATRIX matInvWorld; D3DXMatrixMultiply(&matTemp, &matWorld, &matView); D3DXMatrixMultiply(&matWorldViewProj, &matTemp, &matProject); D3DXMatrixMultiply(&matWorldView, &matWorld, &matView); D3DXMatrixInverse(&matInvWorld, NULL, &matWorld); D3DXMatrixInverse(&matInvWorldView, NULL, &matWorldView); // Set World Camera Pos D3DXMATRIX pmatPos; lpDevice->GetTransform(D3DTS_VIEW,&pmatPos); D3DXMatrixInverse(&pmatPos, NULL, &pmatPos); D3DXVECTOR3 vecCamera3 = D3DXVECTOR3(pmatPos._41,pmatPos._42,pmatPos._43); D3DXVECTOR4 vecCamera4 = D3DXVECTOR4(vecCamera3.x,vecCamera3.y,vecCamera3.z,0.0f); lpDevice->SetVertexShaderConstant(CV_EYE_POS_WORLD, vecCamera4, 1); // Projection to clip space D3DXMatrixTranspose(&matWorldViewProj, &matWorldViewProj); lpDevice->SetVertexShaderConstant(CV_WORLDVIEWPROJ_0, &matWorldViewProj(0, 0), 4); D3DXMatrixTranspose(&matWorldViewProj, &matWorldViewProj); // Transform to eye space D3DXMatrixTranspose(&matWorldView, &matWorldView); lpDevice->SetVertexShaderConstant(CV_WORLDVIEW_0, &matWorldView(0, 0), 4); D3DXMatrixTranspose(&matWorldView, &matWorldView); // Transform to world space D3DXMatrixTranspose(&matWorld, &matWorld); lpDevice->SetVertexShaderConstant(CV_WORLD_0, &matWorld(0, 0), 4); D3DXMatrixTranspose(&matWorld, &matWorld); // Transform for normals lpDevice->SetVertexShaderConstant(CV_WORLDVIEWIT_0, &matInvWorldView(0, 0), 1); lpDevice->SetVertexShaderConstant(CV_WORLDVIEWIT_1, &matInvWorldView(1, 0), 1); lpDevice->SetVertexShaderConstant(CV_WORLDVIEWIT_2, &matInvWorldView(2, 0), 1); // Set BumpScale // lpDevice->SetVertexShaderConstant(CV_BUMP_SCALE, D3DXVECTOR4(0.0f, 0.0f, 0.0f, 1.0f), 1); } } int iShaderIndex = CSceneManager::m_ShaderManager.GetShader((char *)SHADER_STR_BUMPDIFFSPEC); CSceneManager::m_ShaderManager.Apply(iShaderIndex); } ///////////////// CSceneStateMgr::_SetD3DRenderState(D3DRS_ZBIAS ,0); GetDevice()->DrawIndexedPrimitive( D3DPT_TRIANGLELIST, 0, m_tagAMesh.GetObject()->m_wVertexCount, 0, m_tagAMesh.GetObject()->m_wIndexCount/3 ); if((CRenderOption::m_CharacterPerPixelLighting) && (CSceneManager::m_bEnv)) { // ȯ°æ mapping if(CRenderOption::m_CharacterPerPixelLighting) { GetDevice()->SetVertexShader(NULL); GetDevice()->SetPixelShader(NULL); } GetDevice()->SetVertexShader(NULL); //GetDevice()->SetVertexShader( D3DFVF_VERTEX ); GetDevice()->SetVertexShader( BUMPVERTEXFVF ); GetDevice()->SetPixelShader(NULL); if( m_tagSpecTexture.GetObject() ) { GetDevice()->SetTexture( 0, *(m_tagSpecTexture.GetObject()) ); } else { GetDevice()->SetTexture( 0, NULL ); } GetDevice()->SetTexture(1, m_pEnvMap->GetTexture()); CSceneStateMgr::_SetD3DTextureStageState(1, D3DTSS_MAGFILTER, D3DTEXF_LINEAR ); CSceneStateMgr::_SetD3DTextureStageState(1, D3DTSS_MINFILTER, D3DTEXF_LINEAR ); CSceneStateMgr::_SetD3DTextureStageState(1, D3DTSS_ADDRESSU, D3DTADDRESS_CLAMP); CSceneStateMgr::_SetD3DTextureStageState(1, D3DTSS_ADDRESSV, D3DTADDRESS_CLAMP); CSceneStateMgr::_SetD3DTextureStageState(1, D3DTSS_ADDRESSW, D3DTADDRESS_CLAMP); CSceneStateMgr::_SetD3DRenderState(D3DRS_ALPHABLENDENABLE,TRUE); CSceneStateMgr::_SetD3DRenderState( D3DRS_SRCBLEND, D3DBLEND_SRCALPHA ); CSceneStateMgr::_SetD3DRenderState( D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA ); CSceneStateMgr::_SetD3DRenderState(D3DRS_TEXTUREFACTOR,0x80555555); CSceneStateMgr::_SetD3DTextureStageState(0, D3DTSS_COLORARG1,D3DTA_CURRENT); CSceneStateMgr::_SetD3DTextureStageState(0, D3DTSS_COLORARG2,D3DTA_TEXTURE); //CSceneStateMgr::_SetD3DTextureStageState(0, D3DTSS_COLORARG2,D3DTA_TFACTOR); CSceneStateMgr::_SetD3DTextureStageState(0, D3DTSS_COLOROP,D3DTOP_MODULATE); CSceneStateMgr::_SetD3DTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TFACTOR); CSceneStateMgr::_SetD3DTextureStageState(0, D3DTSS_ALPHAARG2, D3DTA_TEXTURE); CSceneStateMgr::_SetD3DTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_MODULATE); CSceneStateMgr::_SetD3DTextureStageState(1, D3DTSS_COLORARG1,D3DTA_CURRENT); CSceneStateMgr::_SetD3DTextureStageState(1, D3DTSS_COLORARG2,D3DTA_TEXTURE); CSceneStateMgr::_SetD3DTextureStageState(1, D3DTSS_COLOROP,D3DTOP_MODULATEALPHA_ADDCOLOR); CSceneStateMgr::_SetD3DTextureStageState(1, D3DTSS_ALPHAARG1,D3DTA_CURRENT); CSceneStateMgr::_SetD3DTextureStageState(1, D3DTSS_ALPHAARG2,D3DTA_TFACTOR); CSceneStateMgr::_SetD3DTextureStageState(1, D3DTSS_ALPHAOP,D3DTOP_SELECTARG1); CSceneStateMgr::_SetD3DTextureStageState(2, D3DTSS_COLOROP,D3DTOP_DISABLE); CSceneStateMgr::_SetD3DTextureStageState(2, D3DTSS_ALPHAOP,D3DTOP_DISABLE); CSceneStateMgr::_SetD3DTextureStageState(3, D3DTSS_COLOROP,D3DTOP_DISABLE); CSceneStateMgr::_SetD3DTextureStageState(3, D3DTSS_ALPHAOP,D3DTOP_DISABLE); CSceneStateMgr::_SetD3DTextureStageState(1, D3DTSS_TEXCOORDINDEX,D3DTSS_TCI_CAMERASPACEREFLECTIONVECTOR); CSceneStateMgr::_SetD3DTextureStageState(1,D3DTSS_TEXTURETRANSFORMFLAGS,D3DTTFF_COUNT3); CSceneStateMgr::_SetD3DRenderState(D3DRS_ZBIAS ,13); GetDevice()->DrawIndexedPrimitive( D3DPT_TRIANGLELIST, 0, m_tagAMesh.GetObject()->m_wVertexCount, 0, m_tagAMesh.GetObject()->m_wIndexCount/3 ); CSceneStateMgr::_SetD3DTextureStageState(1,D3DTSS_TEXTURETRANSFORMFLAGS,D3DTTFF_DISABLE); CSceneStateMgr::_SetD3DTextureStageState(1,D3DTSS_TEXTURETRANSFORMFLAGS,D3DTSS_TCI_PASSTHRU); CSceneStateMgr::_SetD3DTextureStageState(1, D3DTSS_ADDRESSU, D3DTADDRESS_WRAP); CSceneStateMgr::_SetD3DTextureStageState(1, D3DTSS_ADDRESSV, D3DTADDRESS_WRAP); CSceneStateMgr::_SetD3DTextureStageState(1, D3DTSS_ADDRESSW, D3DTADDRESS_WRAP); CSceneStateMgr::_SetD3DRenderState(D3DRS_ALPHABLENDENABLE,FALSE); } //CSceneStateMgr::_SetD3DTextureStageState( 1, D3DTSS_TEXCOORDINDEX, 1); } void CZ3DAttachment::RenderShadow( DWORD vertexShader ) { _ASSERT( m_tagAMesh.GetObject() ); _ASSERT( m_tagAMesh.GetObject()->m_pVertices ); _ASSERT( m_tagAMesh.GetObject()->m_pIndices ); if( NULL != vertexShader ) { if( 0xFFFFFFFF == vertexShader ) { if(CRenderOption::m_CharacterPerPixelLighting) { if( m_bSTVertexMode ) { GetDevice()->SetVertexShader( BUMPVERTEXSTFVF ); } else { GetDevice()->SetVertexShader( BUMPVERTEXFVF ); } } else { GetDevice()->SetVertexShader( D3DFVF_VERTEX ); } } else { GetDevice()->SetVertexShader( vertexShader ); } } matrix m; m.MakeIdent(); m._41 = m_vPivotPos.x; m._42 = m_vPivotPos.y; m._43 = m_vPivotPos.z; GetDevice()->SetTransform( D3DTS_WORLD, m ); if(CRenderOption::m_CharacterPerPixelLighting) { if( m_bSTVertexMode ) { GetDevice()->SetStreamSource( 0, m_pSTVertexBuffer, sizeof(BumpVertexST) ); } else { GetDevice()->SetStreamSource( 0, m_pVertexBuffer, sizeof(BumpVertex) ); } } else { GetDevice()->SetStreamSource( 0, m_pVertexBuffer, sizeof(D3DVERTEX) ); } GetDevice()->SetIndices( m_pIndexBuffer, 0 ); GetDevice()->DrawIndexedPrimitive( D3DPT_TRIANGLELIST, 0, m_tagAMesh.GetObject()->m_wVertexCount, 0, m_tagAMesh.GetObject()->m_wIndexCount/3 ); } void CZ3DAttachment::RenderSpecular( DWORD vertexShader ) { _ASSERT( m_tagAMesh.GetObject() ); _ASSERT( m_tagAMesh.GetObject()->m_pVertices ); _ASSERT( m_tagAMesh.GetObject()->m_pIndices ); if(m_pEnvMap == NULL) { m_pEnvMap = new CTexture; CTexture::SetPath(EFFECTTEXTUREPATH); m_pEnvMap->Load("cube.dds"); } if(CRenderOption::m_CharacterPerPixelLighting) { //GetDevice()->SetVertexShader( BUMPVERTEXFVF ); } else { GetDevice()->SetVertexShader( D3DFVF_VERTEX ); } matrix m; m.MakeIdent(); m._41 = m_vPivotPos.x; m._42 = m_vPivotPos.y; m._43 = m_vPivotPos.z; GetDevice()->SetTransform( D3DTS_WORLD, m ); //////////// ////////////// Bump Spec Shader Constant Setting /////////////// LPDIRECT3DDEVICE8 lpDevice = GetDevice(); if(CRenderOption::m_CharacterPerPixelLighting) { /*************/ // Set BumpScale lpDevice->SetVertexShaderConstant(CV_BUMP_SCALE, D3DXVECTOR4(0.0f, 0.0f, 0.0f, 1.0f), 1); // lpDevice->SetVertexShaderConstant(21, D3DXVECTOR4(1.0f,1.0f,1.0f,0.0f), 1); //////////////* **************/ //Ãß°¡ lpDevice->SetVertexShaderConstant(CV_ZERO, D3DXVECTOR4(0.0f, 0.0f, 0.0f, 0.0f), 1); lpDevice->SetVertexShaderConstant(CV_ONE, D3DXVECTOR4(1.0f, 1.0f, 1.0f, 1.0f), 1); lpDevice->SetVertexShaderConstant(CV_HALF, D3DXVECTOR4(0.5f, 0.5f, 0.5f, 0.5f), 1); // Matrix Set D3DXMATRIX matWorld,matView,matProject; lpDevice->GetTransform(D3DTS_WORLD,&matWorld); lpDevice->GetTransform(D3DTS_VIEW,&matView); lpDevice->GetTransform(D3DTS_PROJECTION,&matProject); D3DXMATRIX matTemp; D3DXMATRIX matWorldView; D3DXMATRIX matInvWorldView; D3DXMATRIX matWorldViewProj; D3DXMATRIX matInvWorld; D3DXMatrixMultiply(&matTemp, &matWorld, &matView); D3DXMatrixMultiply(&matWorldViewProj, &matTemp, &matProject); D3DXMatrixMultiply(&matWorldView, &matWorld, &matView); D3DXMatrixInverse(&matInvWorld, NULL, &matWorld); D3DXMatrixInverse(&matInvWorldView, NULL, &matWorldView); // Set World Camera Pos D3DXMATRIX pmatPos; lpDevice->GetTransform(D3DTS_VIEW,&pmatPos); D3DXMatrixInverse(&pmatPos, NULL, &pmatPos); D3DXVECTOR3 vecCamera3 = D3DXVECTOR3(pmatPos._41,pmatPos._42,pmatPos._43); D3DXVECTOR4 vecCamera4 = D3DXVECTOR4(vecCamera3.x,vecCamera3.y,vecCamera3.z,0.0f); lpDevice->SetVertexShaderConstant(CV_EYE_POS_WORLD, vecCamera4, 1); // Projection to clip space D3DXMatrixTranspose(&matWorldViewProj, &matWorldViewProj); lpDevice->SetVertexShaderConstant(CV_WORLDVIEWPROJ_0, &matWorldViewProj(0, 0), 4); D3DXMatrixTranspose(&matWorldViewProj, &matWorldViewProj); // Transform to eye space D3DXMatrixTranspose(&matWorldView, &matWorldView); lpDevice->SetVertexShaderConstant(CV_WORLDVIEW_0, &matWorldView(0, 0), 4); D3DXMatrixTranspose(&matWorldView, &matWorldView); // Transform to world space D3DXMatrixTranspose(&matWorld, &matWorld); lpDevice->SetVertexShaderConstant(CV_WORLD_0, &matWorld(0, 0), 4); D3DXMatrixTranspose(&matWorld, &matWorld); // Transform for normals lpDevice->SetVertexShaderConstant(CV_WORLDVIEWIT_0, &matInvWorldView(0, 0), 1); lpDevice->SetVertexShaderConstant(CV_WORLDVIEWIT_1, &matInvWorldView(1, 0), 1); lpDevice->SetVertexShaderConstant(CV_WORLDVIEWIT_2, &matInvWorldView(2, 0), 1); // Set BumpScale // lpDevice->SetVertexShaderConstant(CV_BUMP_SCALE, D3DXVECTOR4(0.0f, 0.0f, 0.0f, 1.0f), 1); } /////////////////////////////////////////////////////////////////// //////////// if( m_tagTexture2.GetObject() ) { GetDevice()->SetTexture( 1, *(m_tagTexture2.GetObject()) ); } else { GetDevice()->SetTexture( 1, NULL ); } //CSceneStateMgr::_SetD3DTextureStageState( 1, D3DTSS_TEXCOORDINDEX, 0); if(CRenderOption::m_CharacterPerPixelLighting) { if( m_bSTVertexMode ) { GetDevice()->SetStreamSource( 0, m_pSTVertexBuffer, sizeof(BumpVertexST) ); } else { GetDevice()->SetStreamSource( 0, m_pVertexBuffer, sizeof(BumpVertex) ); } } else { GetDevice()->SetStreamSource( 0, m_pVertexBuffer, sizeof(D3DVERTEX) ); } GetDevice()->SetIndices( m_pIndexBuffer, 0 ); //////////// Bump Setting ///////////////// if(CRenderOption::m_CharacterPerPixelLighting) { if(CRenderOption::m_bRain) { if(CRenderOption::m_CharacterPerPixelLighting) { /*************/ // Set BumpScale lpDevice->SetVertexShaderConstant(CV_BUMP_SCALE, D3DXVECTOR4(0.0f, 0.0f, 0.0f, 1.0f), 1); // lpDevice->SetVertexShaderConstant(21, D3DXVECTOR4(1.0f,1.0f,1.0f,0.0f), 1); //////////////* **************/ //Ãß°¡ lpDevice->SetVertexShaderConstant(CV_ZERO, D3DXVECTOR4(0.0f, 0.0f, 0.0f, 0.0f), 1); lpDevice->SetVertexShaderConstant(CV_ONE, D3DXVECTOR4(1.0f, 1.0f, 1.0f, 1.0f), 1); lpDevice->SetVertexShaderConstant(CV_HALF, D3DXVECTOR4(0.5f, 0.5f, 0.5f, 0.5f), 1); // Matrix Set D3DXMATRIX matWorld,matView,matProject; lpDevice->GetTransform(D3DTS_WORLD,&matWorld); lpDevice->GetTransform(D3DTS_VIEW,&matView); lpDevice->GetTransform(D3DTS_PROJECTION,&matProject); D3DXMATRIX matTemp; D3DXMATRIX matWorldView; D3DXMATRIX matInvWorldView; D3DXMATRIX matWorldViewProj; D3DXMATRIX matInvWorld; D3DXMatrixMultiply(&matTemp, &matWorld, &matView); D3DXMatrixMultiply(&matWorldViewProj, &matTemp, &matProject); D3DXMatrixMultiply(&matWorldView, &matWorld, &matView); D3DXMatrixInverse(&matInvWorld, NULL, &matWorld); D3DXMatrixInverse(&matInvWorldView, NULL, &matWorldView); // Set World Camera Pos D3DXMATRIX pmatPos; lpDevice->GetTransform(D3DTS_VIEW,&pmatPos); D3DXMatrixInverse(&pmatPos, NULL, &pmatPos); D3DXVECTOR3 vecCamera3 = D3DXVECTOR3(pmatPos._41,pmatPos._42,pmatPos._43); D3DXVECTOR4 vecCamera4 = D3DXVECTOR4(vecCamera3.x,vecCamera3.y,vecCamera3.z,0.0f); lpDevice->SetVertexShaderConstant(CV_EYE_POS_WORLD, vecCamera4, 1); // Projection to clip space D3DXMatrixTranspose(&matWorldViewProj, &matWorldViewProj); lpDevice->SetVertexShaderConstant(CV_WORLDVIEWPROJ_0, &matWorldViewProj(0, 0), 4); D3DXMatrixTranspose(&matWorldViewProj, &matWorldViewProj); // Transform to eye space D3DXMatrixTranspose(&matWorldView, &matWorldView); lpDevice->SetVertexShaderConstant(CV_WORLDVIEW_0, &matWorldView(0, 0), 4); D3DXMatrixTranspose(&matWorldView, &matWorldView); // Transform to world space D3DXMatrixTranspose(&matWorld, &matWorld); lpDevice->SetVertexShaderConstant(CV_WORLD_0, &matWorld(0, 0), 4); D3DXMatrixTranspose(&matWorld, &matWorld); // Transform for normals lpDevice->SetVertexShaderConstant(CV_WORLDVIEWIT_0, &matInvWorldView(0, 0), 1); lpDevice->SetVertexShaderConstant(CV_WORLDVIEWIT_1, &matInvWorldView(1, 0), 1); lpDevice->SetVertexShaderConstant(CV_WORLDVIEWIT_2, &matInvWorldView(2, 0), 1); // Set BumpScale // lpDevice->SetVertexShaderConstant(CV_BUMP_SCALE, D3DXVECTOR4(0.0f, 0.0f, 0.0f, 1.0f), 1); } } int iShaderIndex = CSceneManager::m_ShaderManager.GetShader((char *)SHADER_STR_GLARE); CSceneManager::m_ShaderManager.Apply(iShaderIndex); } ///////////////// CSceneStateMgr::_SetD3DRenderState(D3DRS_ZBIAS ,0); GetDevice()->DrawIndexedPrimitive( D3DPT_TRIANGLELIST, 0, m_tagAMesh.GetObject()->m_wVertexCount, 0, m_tagAMesh.GetObject()->m_wIndexCount/3 ); if((CRenderOption::m_CharacterPerPixelLighting) && (CSceneManager::m_bEnv)) { // ȯ°æ mapping if(CRenderOption::m_CharacterPerPixelLighting) { GetDevice()->SetVertexShader(NULL); GetDevice()->SetPixelShader(NULL); } GetDevice()->SetVertexShader(NULL); //GetDevice()->SetVertexShader( D3DFVF_VERTEX ); GetDevice()->SetVertexShader( BUMPVERTEXFVF ); GetDevice()->SetPixelShader(NULL); GetDevice()->SetTexture(1, m_pEnvMap->GetTexture()); CSceneStateMgr::_SetD3DTextureStageState(1, D3DTSS_MAGFILTER, D3DTEXF_LINEAR ); CSceneStateMgr::_SetD3DTextureStageState(1, D3DTSS_MINFILTER, D3DTEXF_LINEAR ); CSceneStateMgr::_SetD3DTextureStageState(1, D3DTSS_ADDRESSU, D3DTADDRESS_CLAMP); CSceneStateMgr::_SetD3DTextureStageState(1, D3DTSS_ADDRESSV, D3DTADDRESS_CLAMP); CSceneStateMgr::_SetD3DTextureStageState(1, D3DTSS_ADDRESSW, D3DTADDRESS_CLAMP); CSceneStateMgr::_SetD3DRenderState(D3DRS_ALPHABLENDENABLE,TRUE); CSceneStateMgr::_SetD3DRenderState( D3DRS_SRCBLEND, D3DBLEND_SRCALPHA ); CSceneStateMgr::_SetD3DRenderState( D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA ); CSceneStateMgr::_SetD3DRenderState(D3DRS_TEXTUREFACTOR,0x80555555); CSceneStateMgr::_SetD3DTextureStageState(0, D3DTSS_COLORARG1,D3DTA_CURRENT); CSceneStateMgr::_SetD3DTextureStageState(0, D3DTSS_COLORARG2,D3DTA_TEXTURE); //CSceneStateMgr::_SetD3DTextureStageState(0, D3DTSS_COLORARG2,D3DTA_TFACTOR); CSceneStateMgr::_SetD3DTextureStageState(0, D3DTSS_COLOROP,D3DTOP_MODULATE); CSceneStateMgr::_SetD3DTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TFACTOR); CSceneStateMgr::_SetD3DTextureStageState(0, D3DTSS_ALPHAARG2, D3DTA_TEXTURE); CSceneStateMgr::_SetD3DTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_MODULATE); CSceneStateMgr::_SetD3DTextureStageState(1, D3DTSS_COLORARG1,D3DTA_CURRENT); CSceneStateMgr::_SetD3DTextureStageState(1, D3DTSS_COLORARG2,D3DTA_TEXTURE); CSceneStateMgr::_SetD3DTextureStageState(1, D3DTSS_COLOROP,D3DTOP_MODULATEALPHA_ADDCOLOR); CSceneStateMgr::_SetD3DTextureStageState(1, D3DTSS_ALPHAARG1,D3DTA_CURRENT); CSceneStateMgr::_SetD3DTextureStageState(1, D3DTSS_ALPHAARG2,D3DTA_TFACTOR); CSceneStateMgr::_SetD3DTextureStageState(1, D3DTSS_ALPHAOP,D3DTOP_SELECTARG1); CSceneStateMgr::_SetD3DTextureStageState(2, D3DTSS_COLOROP,D3DTOP_DISABLE); CSceneStateMgr::_SetD3DTextureStageState(2, D3DTSS_ALPHAOP,D3DTOP_DISABLE); CSceneStateMgr::_SetD3DTextureStageState(3, D3DTSS_COLOROP,D3DTOP_DISABLE); CSceneStateMgr::_SetD3DTextureStageState(3, D3DTSS_ALPHAOP,D3DTOP_DISABLE); CSceneStateMgr::_SetD3DTextureStageState(1, D3DTSS_TEXCOORDINDEX,D3DTSS_TCI_CAMERASPACEREFLECTIONVECTOR); CSceneStateMgr::_SetD3DTextureStageState(1,D3DTSS_TEXTURETRANSFORMFLAGS,D3DTTFF_COUNT3); CSceneStateMgr::_SetD3DRenderState(D3DRS_ZBIAS ,13); GetDevice()->DrawIndexedPrimitive( D3DPT_TRIANGLELIST, 0, m_tagAMesh.GetObject()->m_wVertexCount, 0, m_tagAMesh.GetObject()->m_wIndexCount/3 ); CSceneStateMgr::_SetD3DTextureStageState(1,D3DTSS_TEXTURETRANSFORMFLAGS,D3DTTFF_DISABLE); CSceneStateMgr::_SetD3DTextureStageState(1,D3DTSS_TEXTURETRANSFORMFLAGS,D3DTSS_TCI_PASSTHRU); CSceneStateMgr::_SetD3DTextureStageState(1, D3DTSS_ADDRESSU, D3DTADDRESS_WRAP); CSceneStateMgr::_SetD3DTextureStageState(1, D3DTSS_ADDRESSV, D3DTADDRESS_WRAP); CSceneStateMgr::_SetD3DTextureStageState(1, D3DTSS_ADDRESSW, D3DTADDRESS_WRAP); CSceneStateMgr::_SetD3DRenderState(D3DRS_ALPHABLENDENABLE,FALSE); } //CSceneStateMgr::_SetD3DTextureStageState( 1, D3DTSS_TEXCOORDINDEX, 1); } /* void CZ3DAttachment::RenderSpecular( DWORD vertexShader ) { _ASSERT( m_tagAMesh.GetObject() ); _ASSERT( m_tagAMesh.GetObject()->m_pVertices ); _ASSERT( m_tagAMesh.GetObject()->m_pIndices ); if( NULL != vertexShader ) { if( 0xFFFFFFFF == vertexShader ) { if(CRenderOption::m_CharacterPerPixelLighting) { if( m_bSTVertexMode ) { GetDevice()->SetVertexShader( BUMPVERTEXSTFVF ); } else { GetDevice()->SetVertexShader( BUMPVERTEXFVF ); } } else { GetDevice()->SetVertexShader( D3DFVF_VERTEX ); } } else { GetDevice()->SetVertexShader( vertexShader ); } } matrix m; m.MakeIdent(); m._41 = m_vPivotPos.x; m._42 = m_vPivotPos.y; m._43 = m_vPivotPos.z; GetDevice()->SetTransform( D3DTS_WORLD, m ); if( m_tagSpecTexture.GetObject() ) { GetDevice()->SetTexture( 0, *(m_tagSpecTexture.GetObject()) ); } else { GetDevice()->SetTexture( 0, NULL ); } if(CRenderOption::m_CharacterPerPixelLighting) { if( m_bSTVertexMode ) { GetDevice()->SetStreamSource( 0, m_pSTVertexBuffer, sizeof(BumpVertexST) ); } else { GetDevice()->SetStreamSource( 0, m_pVertexBuffer, sizeof(BumpVertex) ); } } else { GetDevice()->SetStreamSource( 0, m_pVertexBuffer, sizeof(D3DVERTEX) ); } GetDevice()->SetIndices( m_pIndexBuffer, 0 ); GetDevice()->DrawIndexedPrimitive( D3DPT_TRIANGLELIST, 0, m_tagAMesh.GetObject()->m_wVertexCount, 0, m_tagAMesh.GetObject()->m_wIndexCount/3 ); }*/ void CZ3DAttachment::ApplySTMode() { int i; if( !CRenderOption::m_CharacterPerPixelLighting ) return; Z3DAMesh* pMesh = m_tagAMesh.GetObject(); if( NULL == pMesh ) { return; } SAFE_RELEASE( m_pSTVertexBuffer ); SAFE_DELETEA( m_pSTVectors ); if( FAILED( GetDevice()->CreateVertexBuffer( pMesh->m_wVertexCount*sizeof(BumpVertexST), D3DUSAGE_DYNAMIC, 0, D3DPOOL_DEFAULT, &m_pSTVertexBuffer ) ) ) { return; } m_pSTVectors = new STVectorStorageA[pMesh->m_wVertexCount]; BumpVertexST* pST; m_pSTVertexBuffer->Lock( 0, 0, (BYTE**)&pST, 0 ); for( i = 0; i < pMesh->m_wVertexCount; ++i ) { pST[i].v = pMesh->m_pVertices[i].v; pST[i].n = pMesh->m_pVertices[i].n; pST[i].tu = pMesh->m_pVertices[i].tu; pST[i].tv = pMesh->m_pVertices[i].tv; } for( i = 0; i < pMesh->m_wIndexCount; i += 3 ) { WORD i1, i2, i3; i1 = pMesh->m_pIndices[i]; i2 = pMesh->m_pIndices[i+1]; i3 = pMesh->m_pIndices[i+2]; // st °ª¸¸À» °è»êÇØ ÀúÀå ComputeST( pMesh->m_pVertices[i1], pMesh->m_pVertices[i2], pMesh->m_pVertices[i3], m_pSTVectors[i1], m_pSTVectors[i2], m_pSTVectors[i3] ); // ComputeST( pST[i1], pST[i2], pST[i3] ); } for( i = 0; i < pMesh->m_wVertexCount; ++i ) { m_pSTVectors[i].s.Normalize(); pST[i].s.Normalize(); m_pSTVectors[i].t.Normalize(); pST[i].t.Normalize(); } m_bSTVertexMode = true; } void CZ3DAttachment::ComputeST( BumpVertex &rv0, BumpVertex &rv1, BumpVertex &rv2, // BumpVertexST &rv0, BumpVertexST &rv1, BumpVertexST &rv2) STVectorStorageA st0, STVectorStorageA st1, STVectorStorageA st2 ) { // static float F_TEMP_EPSILON = 1e-6f; float F_TEMP_EPSILON = 0.00001f; vector3 vEdge1, vEdge2, vCross; vector3 vecDumyS1(0.0f,0.0f,0.0f),vecDumyT1(0.0f,0.0f,0.0f); vector3 vecDumyS2(0.0f,0.0f,0.0f),vecDumyT2(0.0f,0.0f,0.0f); vector3 vecDumyS3(0.0f,0.0f,0.0f),vecDumyT3(0.0f,0.0f,0.0f); //// // x vector3 vecTangentS[3], vecTangentT[3]; vEdge1.x = rv1.v.x - rv0.v.x; vEdge1.y = rv1.tu - rv0.tu; vEdge1.z = rv1.tv - rv0.tv; vEdge2.x = rv2.v.x - rv0.v.x; vEdge2.y = rv2.tu - rv0.tu; vEdge2.z = rv2.tv - rv0.tv; vCross = vEdge1 ^ vEdge2; vCross.Normalize(); if( fabs(vCross.x) > F_TEMP_EPSILON ) { vecTangentS[0].x = -vCross.y/vCross.x; vecTangentT[0].x = -vCross.z/vCross.x; vecTangentS[1].x = -vCross.y/vCross.x; vecTangentT[1].x = -vCross.z/vCross.x; vecTangentS[2].x = -vCross.y/vCross.x; vecTangentT[2].x = -vCross.z/vCross.x; } // y vEdge1.x = rv1.v.y - rv0.v.y; vEdge1.y = rv1.tu - rv0.tu; vEdge1.z = rv1.tv - rv0.tv; vEdge2.x = rv2.v.y - rv0.v.y; vEdge2.y = rv2.tu - rv0.tu; vEdge2.z = rv2.tv - rv0.tv; vCross = vEdge1 ^ vEdge2; vCross.Normalize(); if( fabs(vCross.x) > F_TEMP_EPSILON ) { vecTangentS[0].y = -vCross.y/vCross.x; vecTangentT[0].y = -vCross.z/vCross.x; vecTangentS[1].y = -vCross.y/vCross.x; vecTangentT[1].y = -vCross.z/vCross.x; vecTangentS[2].y = -vCross.y/vCross.x; vecTangentT[2].y = -vCross.z/vCross.x; } // z vEdge1.x = rv1.v.z - rv0.v.z; vEdge1.y = rv1.tu - rv0.tu; vEdge1.z = rv1.tv - rv0.tv; vEdge2.x = rv2.v.z - rv0.v.z; vEdge2.y = rv2.tu - rv0.tu; vEdge2.z = rv2.tv - rv0.tv; vCross = vEdge1 ^ vEdge2; vCross.Normalize(); if( fabs(vCross.x) > F_TEMP_EPSILON ) { vecTangentS[0].z = -vCross.y/vCross.x; vecTangentT[0].z = -vCross.z/vCross.x; vecTangentS[1].z = -vCross.y/vCross.x; vecTangentT[1].z = -vCross.z/vCross.x; vecTangentS[2].z = -vCross.y/vCross.x; vecTangentT[2].z = -vCross.z/vCross.x; } vecTangentS[0].Normalize(); vecTangentT[0].Normalize(); vecTangentS[1].Normalize(); vecTangentT[1].Normalize(); vecTangentS[2].Normalize(); vecTangentT[2].Normalize(); st0.s += vecTangentS[0]; st0.t += vecTangentT[0]; st1.s += vecTangentS[1]; st1.t += vecTangentT[1]; st2.s += vecTangentS[2]; st2.t += vecTangentT[2]; }