// Z3DMultipartPortion.cpp: implementation of the Z3DMultipartPortion class. // ////////////////////////////////////////////////////////////////////// #include "Z3DMultipartPortion.h" #include "Vertex.h" #include "RenderOption.h" #include "Shader_Rain.h" #include "TextureUtils.h" const long Z3DMultipartPortion::ms_lMaxVBCacheCount = 20; long Z3DMultipartPortion::ms_lVBCacheCount = 0; Z3DVBCacheNode* Z3DMultipartPortion::ms_pVBCacheChainHeader = NULL; const long Z3DMultipartPortion::ms_alMaxIBCacheCount[Z3D_LOD_LEVEL] = { 20, 20, 20, 20 }; long Z3DMultipartPortion::ms_alIBCacheCount[Z3D_LOD_LEVEL] = { 0, 0, 0, 0 }; Z3DIBCacheNode* Z3DMultipartPortion::ms_apIBCacheChainHeader[Z3D_LOD_LEVEL] = { NULL, NULL, NULL, NULL }; // ½ÇÁ¦·Î´Â LOD´Ü°èº° indexÀÚ·á ¼³Á¤¹× vertex¸¦ À§ÇÑ °ø°£ÇÒ´ç void Z3DMultipartPortion::BuildMesh( IDirect3DDevice8* pDevice ) { std::map::iterator it, itToBeLast; int i, j, k; // clear previous set m_vec_pMesh.clear(); m_vecBumpTexture.clear(); m_vecDiffuseTexture.clear(); m_vec_pTexture.clear(); m_vec_pTexture2.clear(); m_vec_pSpecTexture.clear(); m_lVertexCount = 0; for( i = 0; i < Z3D_LOD_LEVEL; i++ ) { m_alIndexCount[i] = 0; } Z3DLODMesh* pMesh; // sum index count for each LOD level // ±×¸®°í °¢ ÆÄÆ®ÀÇ ´©Àû¼ø¼­(=·»´õ¸µ¼ø¼­) ¸®½ºÆ®µµ ¸¸µç´Ù. itToBeLast = m_map_IdMeshTag.end(); // ¸¶Áö¸·À¸·Î µ¹·Á¾ßµÉ ÆÄÆ®ÀÇ id for( it = m_map_IdMeshTag.begin(); it != m_map_IdMeshTag.end(); it++ ) { pMesh = (it->second).GetObject(); _ASSERT( pMesh ); for( i = 0; i < Z3D_LOD_LEVEL; i++ ) { m_alIndexCount[i] += pMesh->aIndex[i].lIndexCount; } // ¸Ó¸®Ä«¶ô ÆÄÆ®ÀÏ °æ¿ì, À妽º ÇÕ °è»êÀº À§¿¡¼­ Çϰí // ¸®½ºÆ®¿¡´Â ¸¶Áö¸·¿¡ ³Ö±âÀ§ÇØ ºüÁü /* if( Z3D_MPID_EAR == it->first ) { itToBeLast = it; continue; } */ m_vec_pMesh.push_back( pMesh ); if( Z3D_MPT_TEXTURE == m_MPT ) { m_vec_pTexture.push_back( (m_map_IdTextureTag[it->first]).GetObject() ); if( m_map_IdTextureTag2.end() == m_map_IdTextureTag2.find( it->first ) ) { m_vec_pTexture2.push_back( NULL ); } else { m_vec_pTexture2.push_back( (m_map_IdTextureTag2[it->first]).GetObject() ); } if( m_map_IdSpecTextureTag.end() == m_map_IdSpecTextureTag.find( it->first ) ) { m_vec_pSpecTexture.push_back( NULL ); } else { m_vec_pSpecTexture.push_back( (m_map_IdSpecTextureTag[it->first]).GetObject() ); } if((m_map_IdTextureTag[it->first]).GetObject()) { Z3DTexture *pTex = (m_map_IdTextureTag[it->first]).GetObject(); char strName[256]; char strTarName[256]; char strTarName2[256]; char strTarName3[256]; strcpy(strName,pTex->m_strName); strcpy(strTarName,strName); strcpy(strTarName2,strName); strcpy(strTarName3,strName); char *ptr = strchr(strTarName,'.'); *(ptr) = '_'; ptr++; *(ptr) = 's'; ptr++; *(ptr) = '.'; ptr++; *(ptr) = 'b'; ptr++; *(ptr) = 'm'; ptr++; *(ptr) = 'p'; ptr++; *(ptr) = '\0'; ptr = strchr(strTarName2,'.'); *(ptr) = '_'; ptr++; *(ptr) = 'b'; ptr++; *(ptr) = '.'; ptr++; *(ptr) = 'b'; ptr++; *(ptr) = 'm'; ptr++; *(ptr) = 'p'; ptr++; *(ptr) = '\0'; ptr = strchr(strTarName3,'.'); *(ptr) = '_'; ptr++; *(ptr) = 'g'; ptr++; *(ptr) = '.'; ptr++; *(ptr) = 'b'; ptr++; *(ptr) = 'm'; ptr++; *(ptr) = 'p'; ptr++; *(ptr) = '\0'; LPDIRECT3DTEXTURE8 lpDiffuse; LPDIRECT3DTEXTURE8 lpBump; FILE *fp1 = fopen(strName,"rb"); FILE *fp2 = fopen(strTarName,"rb"); FILE *fp3 = fopen(strTarName2,"rb"); FILE *fp4 = fopen(strTarName3,"rb"); if(fp1 == NULL || fp2 == NULL) { lpDiffuse = TextureUtils::CreateTextureAlpha("c:/mp-project/texture/shader/ssDiffuseMap.tga","c:/mp-project/texture/shader/dumyspec.bmp",pDevice); //lpDiffuse = TextureUtils::CreateTextureAlpha("c:/mp-project/texture/shader/m_Sacred_armor.dds","c:/mp-project/texture/shader/m_Sacred_armor_a.dds",pDevice); } else lpDiffuse = TextureUtils::CreateTextureAlpha(strName,strTarName,pDevice); m_vecDiffuseTexture.push_back(lpDiffuse); if(fp3 == NULL || fp4 == NULL) { //lpBump = TextureUtils::CreateNormalMapAlpha(10.0f,"c:/mp-project/texture/shader/m_Sacred_armor_b.dds","c:/mp-project/texture/shader/m_Sacred_armor_l.dds",pDevice);; D3DXIMAGE_INFO imageinfo; D3DXIMAGE_INFO imageinfo2; D3DXGetImageInfoFromFile( "c:/mp-project/texture/shader/ssNormalsMap.tga", &imageinfo ); D3DXCreateTextureFromFileEx( pDevice,"c:/mp-project/texture/shader/ssNormalsMap.tga" , imageinfo.Width, imageinfo.Height, imageinfo.MipLevels, 0, imageinfo.Format, D3DPOOL_MANAGED, D3DX_FILTER_NONE, D3DX_FILTER_NONE, 0, &imageinfo2, NULL, (LPDIRECT3DTEXTURE8*)&lpBump ); } else lpBump = TextureUtils::CreateNormalMapAlpha(CRenderOption::m_fBumpScale,strTarName2,strTarName3,pDevice); m_vecBumpTexture.push_back(lpBump); if(fp1) fclose(fp1); if(fp2) fclose(fp2); if(fp3) fclose(fp3); if(fp4) fclose(fp4); } else { LPDIRECT3DTEXTURE8 lpDiffuse = NULL; LPDIRECT3DTEXTURE8 lpBump = NULL; m_vecDiffuseTexture.push_back(lpDiffuse); m_vecBumpTexture.push_back(lpBump); } } } // ¸¶Áö¸·À¸·Î µ¹·Á¾ß µÉ ÆÄÆ®°¡ ÀÖÀ¸¸é..( itToBeLastÀÇ °ªÀÌ ¹Ù²î¾ú´Ù¸é) /* if( m_map_IdMeshTag.end() != itToBeLast ) { // ¸®½ºÆ®¿¡ ¸¶Àú Áý¾î³Ö¾îÁÖÁö·Õ(ÇÕÀº ·çÇÁ¾È¿¡¼­ ÀÌ¹Ì ±¸ÇØÁ®ÀÖ´Ù) m_vec_pMesh.push_back( (itToBeLast->second).GetObject() ); } */ if( 0 == m_vec_pMesh.size() ) { return; } // alloc. index buffer space for( i = 0; i < Z3D_LOD_LEVEL; i++ ) { if( m_alIndexBufferIndexCount[i] < m_alIndexCount[i] ) { m_alIndexBufferIndexCount[i] = GetSizeByBank( m_alIndexCount[i], Z3D_PORTION_BUFFER_BANK_SIZE*4 ); _ReleaseIndexBufferInterface( i, m_apIndexBuffer[i] ); m_apIndexBuffer[i] = _GetIndexBufferInterface( i, pDevice, m_alIndexBufferIndexCount[i] ); } } // fill up data int nCount[Z3D_LOD_LEVEL] = { 0, }; WORD* apIndices[Z3D_LOD_LEVEL] = { NULL, }; for( i = 0; i < Z3D_LOD_LEVEL; ++i ) { m_apIndexBuffer[i]->Lock( 0, 0, (BYTE**)(&apIndices[i]), D3DLOCK_DISCARD ); } for( k = 0; k < (int)m_vec_pMesh.size(); k++ ) { pMesh = m_vec_pMesh[k]; for( i = 0; i < Z3D_LOD_LEVEL; i++ ) { for( j = 0; j < pMesh->aIndex[i].lIndexCount; j++ ) { apIndices[i][nCount[i]] = pMesh->aIndex[i].pIndices[j] + (WORD)m_lVertexCount; (nCount[i])++; } } m_lVertexCount += pMesh->lVertexCount; } for( i = 0; i < Z3D_LOD_LEVEL; ++i ) { m_apIndexBuffer[i]->Unlock(); } // vertex buffer Å©±âºÎÁ·½Ã È®ÀåÀçÇÒ´ç if( m_lVertexBufferVertexCount < m_lVertexCount ) { m_lVertexBufferVertexCount = GetSizeByBank( m_lVertexCount, Z3D_PORTION_BUFFER_BANK_SIZE ); _ReleaseVertexBufferInterface( m_pVertexBuffer ); m_pVertexBuffer = _GetVertexBufferInterface( pDevice, m_lVertexBufferVertexCount ); } m_bSTVertexMode = false; SAFE_RELEASE( m_pSTVertexBuffer ); for( i = 0; i < m_vecpSTVectors.size(); ++i ) { SAFE_DELETEA( m_vecpSTVectors[i] ); } m_vecpSTVectors.clear(); //Rain SAFE_RELEASE( m_lpRainVertexBuffer ); } static void ComputeST( Z3DBlend2Vertex &rv0, Z3DBlend2Vertex &rv1, Z3DBlend2Vertex &rv2, STVectorStorage &st0, STVectorStorage &st1, STVectorStorage &st2 ) { // static float F_TEMP_EPSILON = 1e-6f; static 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 STVectorStorage vecTangent[3]; vEdge1.x = rv1.pos.x - rv0.pos.x; vEdge1.y = rv1.tu - rv0.tu; vEdge1.z = rv1.tv - rv0.tv; vEdge2.x = rv2.pos.x - rv0.pos.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 ) { vecTangent[0].s.x = -vCross.y/vCross.x; vecTangent[0].t.x = -vCross.z/vCross.x; vecTangent[1].s.x = -vCross.y/vCross.x; vecTangent[1].t.x = -vCross.z/vCross.x; vecTangent[2].s.x = -vCross.y/vCross.x; vecTangent[2].t.x = -vCross.z/vCross.x; } // y vEdge1.x = rv1.pos.y - rv0.pos.y; vEdge1.y = rv1.tu - rv0.tu; vEdge1.z = rv1.tv - rv0.tv; vEdge2.x = rv2.pos.y - rv0.pos.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 ) { vecTangent[0].s.y = -vCross.y/vCross.x; vecTangent[0].t.y = -vCross.z/vCross.x; vecTangent[1].s.y = -vCross.y/vCross.x; vecTangent[1].t.y = -vCross.z/vCross.x; vecTangent[2].s.y = -vCross.y/vCross.x; vecTangent[2].t.y = -vCross.z/vCross.x; } // z vEdge1.x = rv1.pos.z - rv0.pos.z; vEdge1.y = rv1.tu - rv0.tu; vEdge1.z = rv1.tv - rv0.tv; vEdge2.x = rv2.pos.z - rv0.pos.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 ) { vecTangent[0].s.z = -vCross.y/vCross.x; vecTangent[0].t.z = -vCross.z/vCross.x; vecTangent[1].s.z = -vCross.y/vCross.x; vecTangent[1].t.z = -vCross.z/vCross.x; vecTangent[2].s.z = -vCross.y/vCross.x; vecTangent[2].t.z = -vCross.z/vCross.x; } vecTangent[0].s.Normalize(); vecTangent[0].t.Normalize(); vecTangent[1].s.Normalize(); vecTangent[1].t.Normalize(); vecTangent[2].s.Normalize(); vecTangent[2].t.Normalize(); st0.s += vecTangent[0].s; st0.t += vecTangent[0].t; st1.s += vecTangent[1].s; st1.t += vecTangent[1].t; st2.s += vecTangent[2].s; st2.t += vecTangent[2].t; /* vEdge1.x = rv1.pos.x - rv0.pos.x; vEdge1.y = rv1.pos.y - rv0.pos.y; vEdge1.z = rv1.pos.z - rv0.pos.z; vEdge2.x = rv2.pos.x - rv0.pos.x; vEdge2.y = rv2.pos.y - rv0.pos.y; vEdge2.z = rv2.pos.z - rv0.pos.z; float DeltaU1 = rv1.tu - rv0.tu; float DeltaU2 = rv2.tu - rv0.tu; vector3 vecV,vecU,vecW; vecV = DeltaU2 * vEdge1 - DeltaU1 * vEdge2; vecV.Normalize(); st0.s += vecV; st1.s += vecV; st2.s += vecV; vecU = vecV ^ rv0.normal; vecU.Normalize(); st0.t += vecU; vecU = vecV ^ rv1.normal; vecU.Normalize(); st1.t += vecU; vecU = vecV ^ rv2.normal; vecU.Normalize(); st2.t += vecU;*/ /* // Compute edge vectors. D3DXVECTOR3 vecNormal,vecEdge1,vecEdge2; D3DXVECTOR2 vecTv1,vecTv2; vEdge1.x = rv1.pos.x - rv0.pos.x; vEdge1.y = rv1.pos.y - rv0.pos.y; vEdge1.z = rv1.pos.z - rv0.pos.z; vEdge2.x = rv2.pos.x - rv0.pos.x; vEdge2.y = rv2.pos.y - rv0.pos.y; vEdge2.z = rv2.pos.z - rv0.pos.z; vecEdge1 = D3DXVECTOR3(vEdge1.x,vEdge1.y,vEdge1.z); vecEdge2 = D3DXVECTOR3(vEdge2.x,vEdge2.y,vEdge2.z); D3DXVec3Cross(&vecNormal,&vecEdge1,&vecEdge2); D3DXVec3Normalize(&vecNormal,&vecNormal); vecTv1.x = rv1.tu - rv0.tu; vecTv1.y = rv1.tv - rv0.tv; vecTv2.x = rv2.tu - rv0.tu; vecTv2.y = rv2.tv - rv0.tv; float a = vecTv1.x - vecTv1.y * vecTv2.x / vecTv2.y; if (a != 0.0) a = 1.0f/a; float b = vecTv2.x - vecTv2.y * vecTv2.x / vecTv1.y; if (b != 0.0) b = 1.0f/b; D3DXVECTOR3 vecUTmp; vecUTmp.x = a * vEdge1.x + b * vEdge2.x; vecUTmp.y = a * vEdge1.y + b * vEdge2.y; vecUTmp.z = a * vEdge1.z + b * vEdge2.z; D3DXVec3Normalize(&vecUTmp,&vecUTmp); // Calculate v vector a = vecTv1.y - vecTv1.x * vecTv2.y / vecTv2.x; if (a != 0.0) a = 1.0f/a; b = vecTv2.y- vecTv2.x * vecTv1.y / vecTv1.x; if (b != 0.0) b = 1.0f/b; D3DXVECTOR3 vecVTmp; vecVTmp.x = a * vEdge1.x + b * vEdge2.x; vecVTmp.y = a * vEdge1.y + b * vEdge2.y; vecVTmp.z = a * vEdge1.z + b * vEdge2.z; D3DXVec3Normalize(&vecUTmp,&vecUTmp); D3DXVECTOR3 vecVertexN = D3DXVECTOR3(rv0.normal.x,rv0.normal.y,rv0.normal.z); float fTmp = (vecUTmp.x * vecVertexN.x) + (vecUTmp.y * vecVertexN.y) + (vecUTmp.z * vecVertexN.z); st0.s.x += vecUTmp.x - (fTmp * vecVertexN.x); st0.s.y += vecUTmp.y - (fTmp * vecVertexN.y); st0.s.z += vecUTmp.z - (fTmp * vecVertexN.z); // st0.s.Normalize(); fTmp = (vecVTmp.x * vecVertexN.x) + (vecVTmp.y * vecVertexN.y) + (vecVTmp.z * vecVertexN.z); st0.t.x += vecVTmp.x - (fTmp * vecVertexN.x); st0.t.y += vecVTmp.y - (fTmp * vecVertexN.y); st0.t.z += vecVTmp.z - (fTmp * vecVertexN.z); // st0.t.Normalize(); vecVertexN = D3DXVECTOR3(rv1.normal.x,rv1.normal.y,rv1.normal.z); fTmp = (vecUTmp.x * vecVertexN.x) + (vecUTmp.y * vecVertexN.y) + (vecUTmp.z * vecVertexN.z); st1.s.x += vecUTmp.x - (fTmp * vecVertexN.x); st1.s.y += vecUTmp.y - (fTmp * vecVertexN.y); st1.s.z += vecUTmp.z - (fTmp * vecVertexN.z); // st1.s.Normalize(); fTmp = (vecVTmp.x * vecVertexN.x) + (vecVTmp.y * vecVertexN.y) + (vecVTmp.z * vecVertexN.z); st1.t.x += vecVTmp.x - (fTmp * vecVertexN.x); st1.t.y += vecVTmp.y - (fTmp * vecVertexN.y); st1.t.z += vecVTmp.z - (fTmp * vecVertexN.z); // st1.t.Normalize(); vecVertexN = D3DXVECTOR3(rv2.normal.x,rv2.normal.y,rv2.normal.z); fTmp = (vecUTmp.x * vecVertexN.x) + (vecUTmp.y * vecVertexN.y) + (vecUTmp.z * vecVertexN.z); st2.s.x += vecUTmp.x - (fTmp * vecVertexN.x); st2.s.y += vecUTmp.y - (fTmp * vecVertexN.y); st2.s.z += vecUTmp.z - (fTmp * vecVertexN.z); // st2.s.Normalize(); fTmp = (vecVTmp.x * vecVertexN.x) + (vecVTmp.y * vecVertexN.y) + (vecVTmp.z * vecVertexN.z); st2.t.x += vecVTmp.x - (fTmp * vecVertexN.x); st2.t.y += vecVTmp.y - (fTmp * vecVertexN.y); st2.t.z += vecVTmp.z - (fTmp * vecVertexN.z); // st2.t.Normalize(); */ } struct BasisFixVCST // V = pos, C = count, ST = s and t vector { vector3 v; long c; vector3 s; vector3 t; }; static long FindSamePositionIndexInBucket( vector3 &rv, STVectorStorage &rsts, std::vector &rvecVCST ) { //static float F_TEMP_EPSILON = 1e-6f; static float F_TEMP_EPSILON = 0.0001f; float fx, fy, fz, fDist; for( int i = 0; i < rvecVCST.size(); ++i ) { fx = rvecVCST[i].v.x - rv.x; fy = rvecVCST[i].v.y - rv.y; fz = rvecVCST[i].v.z - rv.z; fDist = fx*fx + fy*fy + fz*fz; if( fDist < F_TEMP_EPSILON ) { rvecVCST[i].c++; rvecVCST[i].s += rsts.s; rvecVCST[i].t += rsts.t; return i; } } // no same-positioned vertex in. add new one. BasisFixVCST vcst; vcst.v = rv; vcst.c = 1; vcst.s = rsts.s; vcst.t = rsts.t; rvecVCST.push_back( vcst ); return rvecVCST.size()-1; } static void FixVertexBasis( Z3DBlend2Vertex* pVertices, STVectorStorage* pST, long lVertexCount ) { long* pIndex2Bucket; pIndex2Bucket = new long[lVertexCount]; std::vector vecVCST; for( int i = 0; i < lVertexCount; ++i ) { pIndex2Bucket[i] = FindSamePositionIndexInBucket( pVertices[i].pos, pST[i], vecVCST ); } for( i = 0; i < vecVCST.size(); ++i ) { vecVCST[i].s.Normalize(); vecVCST[i].t.Normalize(); } for( i = 0; i < lVertexCount; ++i ) { pST[i].s = vecVCST[pIndex2Bucket[i]].s; pST[i].t = vecVCST[pIndex2Bucket[i]].t; } SAFE_DELETEA( pIndex2Bucket ); } void Z3DMultipartPortion::BuildSTVertex( IDirect3DDevice8* pDevice ) { int i, j; if( !CRenderOption::m_CharacterPerPixelLighting ) return; //Rain SAFE_RELEASE( m_lpRainVertexBuffer); // SAFE_RELEASE( m_pSTVertexBuffer ); for( i = 0; i < m_vecpSTVectors.size(); ++i ) { SAFE_DELETEA( m_vecpSTVectors[i] ); } m_vecpSTVectors.clear(); // st vector °ª¸¸ ÀúÀåÇØµÎ´Â ¹öÆÛ ÇÒ´ç STVectorStorage* pST; for( i = 0; i < m_vec_pMesh.size(); ++i ) { pST = new STVectorStorage[m_vec_pMesh[i]->lVertexCount]; for( j = 0; j < m_vec_pMesh[i]->lVertexCount; ++j ) { pST[j].s.x = pST[j].s.y = pST[j].s.z = 0.0f; pST[j].t.x = pST[j].t.y = pST[j].t.z = 0.0f; } m_vecpSTVectors.push_back(pST); } Z3DBlend2Vertex* pVertices; WORD* pIndices; long lTotalCount = 0; for( i = 0; i < m_vec_pMesh.size(); ++i ) { pVertices = m_vec_pMesh[i]->pVertices; pST = m_vecpSTVectors[i]; pIndices = m_vec_pMesh[i]->aIndex[0].pIndices; for( j = 0; j < m_vec_pMesh[i]->aIndex[0].lIndexCount; j += 3 ) { WORD i1, i2, i3; i1 = pIndices[j]; i2 = pIndices[j+1]; i3 = pIndices[j+2]; // st °ª¸¸À» °è»êÇØ ÀúÀå ComputeST( pVertices[i1], pVertices[i2], pVertices[i3], pST[i1], pST[i2], pST[i3] ); } for( j = 0; j < m_vec_pMesh[i]->lVertexCount; ++j ) { pST[j].s.Normalize(); pST[j].t.Normalize(); } FixVertexBasis( pVertices, pST, m_vec_pMesh[i]->lVertexCount ); } if( FAILED( pDevice->CreateVertexBuffer( m_lVertexCount*sizeof(BumpVertexST), D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY, 0, D3DPOOL_DEFAULT, &m_pSTVertexBuffer ) ) ) { return; } m_bSTVertexMode = true; //Rain if( FAILED( pDevice->CreateVertexBuffer( m_lVertexCount*sizeof(RainVertex), D3DUSAGE_WRITEONLY, 0, D3DPOOL_DEFAULT, &m_lpRainVertexBuffer ) ) ) { return; } m_dwRainVertexsNum = m_lVertexCount; } bool Z3DMultipartPortion::SetMesh( const int nPartId, H3DMeshTag tagMesh ) { std::map::iterator it_m; it_m = m_map_IdMeshTag.find( nPartId ); if( m_map_IdMeshTag.end() != it_m ) { // ½½·Ô¿¡ ¼¼ÆÃµÉ ¸Þ½Ã°¡ ÀÌÀü¿¡ ¼¼ÆÃµÇ¾îÀÖ´ø ¸Þ½Ã¿Í °°Àº°¡? if( (it_m->second) == tagMesh ) { // Áߺ¹À̹ǷΠÇöÀç ºÒ·¯¿Â ¸Þ½Ã release tagMesh.Release(); // ¸Þ½Ã°¡ ¹Ù²îÁö ¾Ê¾ÒÀ¸¹Ç·Î, blendingÀç°è»ê Çʿ䰡 ¾øÀ¸¹Ç·Î false¹Ýȯ return false; } // ÀÌÀü¿¡ ¼¼ÆÃµÈ mesh release else { it_m->second.Release(); } } // setting m_map_IdMeshTag[nPartId] = tagMesh; return true; } bool Z3DMultipartPortion::DeleteMesh( const int nPartId ) { std::map::iterator it_m; it_m = m_map_IdMeshTag.find( nPartId ); if( m_map_IdMeshTag.end() == it_m ) { return false; // id¿¡ ÇØ´çÇÏ´Â mesh°¡ ¼¼ÆÃµÇ¾îÀÖÁö ¾Ê´Ù. } // deleting it_m->second.Release(); m_map_IdMeshTag.erase(it_m); return true; } bool Z3DMultipartPortion::SetTexPiece( const int nPartId, H3DTexPieceTag tagTexpiece ) { std::map::iterator it_t; it_t = m_map_IdTexPieceTag.find( nPartId ); if( m_map_IdTexPieceTag.end() != it_t ) { // same as previous if( (it_t->second) == tagTexpiece ) { tagTexpiece.Release(); return false; } // ÀÌÀü¿¡ ¼¼ÆÃµÈ texpiece container instance¸¦ releaseÇØÁØ´Ù else { it_t->second.Release(); } } // setting m_map_IdTexPieceTag[nPartId] = tagTexpiece; return true; } bool Z3DMultipartPortion::SetTexPiece2( const int nPartId, H3DTexPieceTag tagTexpiece ) { std::map::iterator it_t; it_t = m_map_IdTexPieceTag2.find( nPartId ); if( m_map_IdTexPieceTag2.end() != it_t ) { // same as previous if( (it_t->second) == tagTexpiece ) { tagTexpiece.Release(); return false; } // ÀÌÀü¿¡ ¼¼ÆÃµÈ texpiece container instance¸¦ releaseÇØÁØ´Ù else { it_t->second.Release(); } } // setting m_map_IdTexPieceTag2[nPartId] = tagTexpiece; return true; } bool Z3DMultipartPortion::DeleteTexPiece( const int nPartId ) { std::map::iterator it_t; it_t = m_map_IdTexPieceTag.find( nPartId ); if( m_map_IdTexPieceTag.end() == it_t ) { return false; // id¿¡ ÇØ´çÇÏ´Â texpiece¼¼ÆÃÀÌ µÇ¾îÀÖÁö ¾Ê´Ù. } it_t->second.Release(); m_map_IdTexPieceTag.erase(it_t); return true; } bool Z3DMultipartPortion::SetTexture( const int nPartId, H3DTextureTag tagTexture ) { std::map::iterator it_t; it_t = m_map_IdTextureTag.find( nPartId ); if( m_map_IdTextureTag.end() != it_t ) { // same as previous if( (it_t->second) == tagTexture ) { tagTexture.Release(); return false; } // ÀÌÀü¿¡ ¼¼ÆÃµÈ texpiece container instance¸¦ releaseÇØÁØ´Ù else { it_t->second.Release(); } } // setting m_map_IdTextureTag[nPartId] = tagTexture; return true; } bool Z3DMultipartPortion::SetTexture2( const int nPartId, H3DTextureTag tagTexture ) { std::map::iterator it_t; it_t = m_map_IdTextureTag2.find( nPartId ); if( m_map_IdTextureTag2.end() != it_t ) { // same as previous if( (it_t->second) == tagTexture ) { tagTexture.Release(); return false; } // ÀÌÀü¿¡ ¼¼ÆÃµÈ texpiece container instance¸¦ releaseÇØÁØ´Ù else { it_t->second.Release(); } } // setting m_map_IdTextureTag2[nPartId] = tagTexture; return true; } bool Z3DMultipartPortion::SetSpecTexture( const int nPartId, H3DTextureTag tagTexture ) { std::map::iterator it_t; it_t = m_map_IdSpecTextureTag.find( nPartId ); if( m_map_IdSpecTextureTag.end() != it_t ) { // same as previous if( (it_t->second) == tagTexture ) { tagTexture.Release(); return false; } // ÀÌÀü¿¡ ¼¼ÆÃµÈ texpiece container instance¸¦ releaseÇØÁØ´Ù else { it_t->second.Release(); } } // setting m_map_IdSpecTextureTag[nPartId] = tagTexture; return true; } bool Z3DMultipartPortion::DeleteTexture( const int nPartId ) { std::map::iterator it_t; it_t = m_map_IdTextureTag.find( nPartId ); if( m_map_IdTextureTag.end() != it_t ) { it_t->second.Release(); m_map_IdTextureTag.erase( it_t ); } return true; } bool Z3DMultipartPortion::DeleteTexture2( const int nPartId ) { std::map::iterator it_t; it_t = m_map_IdTextureTag2.find( nPartId ); if( m_map_IdTextureTag2.end() != it_t ) { it_t->second.Release(); m_map_IdTextureTag2.erase( it_t ); } return true; } bool Z3DMultipartPortion::DeleteSpecTexture( const int nPartId ) { std::map::iterator it_t; it_t = m_map_IdSpecTextureTag.find( nPartId ); if( m_map_IdSpecTextureTag.end() != it_t ) { it_t->second.Release(); m_map_IdSpecTextureTag.erase( it_t ); } return true; } bool Z3DMultipartPortion::BatchOpen() { /*map::iterator it_m; for( it_m = m_map_IdMeshTag.begin(); it_m != m_map_IdMeshTag.end(); it_m++ ) { g_ContLODMesh.Release(it_m->second); } m_map_IdMeshTag.clear();*/ /*map::iterator it_t; for( it_t = m_map_IdTexPieceTag.begin(); it_t != m_map_IdTexPieceTag.end(); it_t++ ) { g_ContTexturePiece.Release(it_t->second); } m_map_IdTexPieceTag.clear();*/ /*m_vec_pMesh.clear(); m_lVertexCount = 0; SAFE_DELETEA( m_pVertices ); for( int i = 0; i < Z3D_LOD_LEVEL; i++ ) { m_aIndices[i].lIndexCount = 0; SAFE_DELETEA( m_aIndices[i].pIndices ); }*/ return true; } bool Z3DMultipartPortion::BatchClose( IDirect3DDevice8* pDevice ) { BuildMesh( pDevice ); std::map::iterator it_t; for( it_t = m_map_IdTexPieceTag.begin(); it_t != m_map_IdTexPieceTag.end(); it_t++ ) { (it_t->second).GetObject()->Blt2Texture( *m_pTexture ); } for( it_t = m_map_IdTexPieceTag2.begin(); it_t != m_map_IdTexPieceTag2.end(); it_t++ ) { (it_t->second).GetObject()->Blt2Texture( *m_pTexture2 ); } return true; } IDirect3DVertexBuffer8* Z3DMultipartPortion::_GetVertexBufferInterface( IDirect3DDevice8* pDevice, long& rlVertexCount ) { IDirect3DVertexBuffer8* pVB = NULL; Z3DVBCacheNode* pChainNode = ms_pVBCacheChainHeader; Z3DVBCacheNode* pPrevNode = NULL; while( pChainNode ) { if( rlVertexCount <= pChainNode->lVertexCount ) { pVB = pChainNode->pVB; rlVertexCount = pChainNode->lVertexCount; // »èÁ¦µÉ ³ëµåÀÇ ¾Õ-µÚ ³ëµå°£ ¿¬°á ¼³Á¤ if( pPrevNode ) { pPrevNode->pNext = pChainNode->pNext; } // »èÁ¦µÉ ³ëµå°¡ headÀϰæ¿ì head pointer Á¶Á¤ if( ms_pVBCacheChainHeader == pChainNode ) { ms_pVBCacheChainHeader = pChainNode->pNext; } // ³ëµå »èÁ¦ SAFE_DELETE( pChainNode ); --ms_lVBCacheCount; break; } pPrevNode = pChainNode; pChainNode = pChainNode->pNext; } if( pVB ) { return pVB; } if(CRenderOption::m_CharacterPerPixelLighting) { if( FAILED( pDevice->CreateVertexBuffer( rlVertexCount*sizeof(BumpVertex), D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY, 0, D3DPOOL_DEFAULT, &pVB ) ) ) { return NULL; } } else { if( FAILED( pDevice->CreateVertexBuffer( rlVertexCount*sizeof(D3DVERTEX), D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY, D3DFVF_VERTEX, D3DPOOL_DEFAULT, &pVB ) ) ) { return NULL; } } return pVB; } void Z3DMultipartPortion::_ReleaseVertexBufferInterface( IDirect3DVertexBuffer8* pVB ) { if( NULL == pVB ) { return; } Z3DVBCacheNode* pNode; Z3DVBCacheNode* pPrev = NULL; // ij½Ã ¿À¹öÇ÷νà °¡Àå ¿À·¡µÈ ³ëµå »èÁ¦ if( ms_lVBCacheCount == ms_lMaxVBCacheCount ) { pNode = ms_pVBCacheChainHeader; while( pNode->pNext ) { pPrev = pNode; pNode = pNode->pNext; } SAFE_RELEASE( pNode->pVB ); SAFE_DELETE( pNode ); if( pPrev ) { pPrev->pNext = NULL; } --ms_lVBCacheCount; } pNode = new Z3DVBCacheNode; D3DVERTEXBUFFER_DESC d3dvbd; pVB->GetDesc( &d3dvbd ); pNode->lVertexCount = d3dvbd.Size / ((CRenderOption::m_CharacterPerPixelLighting) ? sizeof(BumpVertex) : sizeof(D3DVERTEX) ); pNode->pVB = pVB; pNode->pNext = ms_pVBCacheChainHeader; ms_pVBCacheChainHeader = pNode; ++ms_lVBCacheCount; } IDirect3DIndexBuffer8* Z3DMultipartPortion::_GetIndexBufferInterface( long lLODIndex, IDirect3DDevice8* pDevice, long rlIndexCount ) { IDirect3DIndexBuffer8* pIB = NULL; Z3DIBCacheNode* pChainNode = ms_apIBCacheChainHeader[lLODIndex]; Z3DIBCacheNode* pPrevNode = NULL; while( pChainNode ) { if( rlIndexCount <= pChainNode->lIndexCount ) { pIB = pChainNode->pIB; rlIndexCount = pChainNode->lIndexCount; // »èÁ¦µÉ ³ëµåÀÇ ¾Õ-µÚ ³ëµå°£ ¿¬°á ¼³Á¤ if( pPrevNode ) { pPrevNode->pNext = pChainNode->pNext; } // »èÁ¦µÉ ³ëµå°¡ headÀϰæ¿ì head pointer Á¶Á¤ if( ms_apIBCacheChainHeader[lLODIndex] == pChainNode ) { ms_apIBCacheChainHeader[lLODIndex] = pChainNode->pNext; } // ³ëµå »èÁ¦ SAFE_DELETE( pChainNode ); --ms_alIBCacheCount[lLODIndex]; break; } pPrevNode = pChainNode; pChainNode = pChainNode->pNext; } if( pIB ) { return pIB; } if( FAILED( pDevice->CreateIndexBuffer( rlIndexCount * sizeof(WORD), D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY, D3DFMT_INDEX16, D3DPOOL_DEFAULT, &(pIB) ) ) ) { return NULL; } return pIB; } void Z3DMultipartPortion::_ReleaseIndexBufferInterface( long lLODIndex, IDirect3DIndexBuffer8* pIB ) { if( NULL == pIB ) { return; } Z3DIBCacheNode* pNode; Z3DIBCacheNode* pPrev = NULL; // ij½Ã ¿À¹öÇ÷νà °¡Àå ¿À·¡µÈ ³ëµå »èÁ¦ if( ms_alIBCacheCount[lLODIndex] == ms_alMaxIBCacheCount[lLODIndex] ) { pNode = ms_apIBCacheChainHeader[lLODIndex]; while( pNode->pNext ) { pPrev = pNode; pNode = pNode->pNext; } SAFE_RELEASE( pNode->pIB ); SAFE_DELETE( pNode ); if( pPrev ) { pPrev->pNext = NULL; } --ms_alIBCacheCount[lLODIndex]; } pNode = new Z3DIBCacheNode; D3DINDEXBUFFER_DESC d3dibd; pIB->GetDesc( &d3dibd ); pNode->lIndexCount = d3dibd.Size / sizeof(WORD); pNode->pIB = pIB; pNode->pNext = ms_apIBCacheChainHeader[lLODIndex]; ms_apIBCacheChainHeader[lLODIndex] = pNode; ++ms_alIBCacheCount[lLODIndex]; } void Z3DMultipartPortion::_Close() { Z3DVBCacheNode* pVBChainNode = ms_pVBCacheChainHeader; Z3DVBCacheNode* pVBTmp; while( pVBChainNode ) { pVBTmp = pVBChainNode; pVBChainNode = pVBChainNode->pNext; SAFE_RELEASE( pVBTmp->pVB ); SAFE_DELETE( pVBTmp ); } Z3DIBCacheNode* pIBChainNode; Z3DIBCacheNode* pIBTmp; for( int i = 0; i < Z3D_LOD_LEVEL; ++i ) { pIBChainNode = ms_apIBCacheChainHeader[i]; while( pIBChainNode ) { pIBTmp = pIBChainNode; pIBChainNode = pIBChainNode->pNext; SAFE_RELEASE( pIBTmp->pIB ); SAFE_DELETE( pIBTmp ); } } }