void MBitmapR2::DrawEx(float tx1, float ty1, float tx2, float ty2, float tx3, float ty3, float tx4, float ty4, DWORD dwColor, MDrawEffect effect) { float ftw = (float)m_pTexture->GetWidth(); float fth = (float)m_pTexture->GetHeight(); float fuv[8] = { 0.f,0.f, 1.f,0.f, 1.f,1.f, 0.f,1.f }; CheckDrawMode(fuv); CUSTOMVERTEX Sprite[4] = { #define ADJUST_SIZE 0.5f #define ADJUST_SIZE2 0.0f {tx1-ADJUST_SIZE, ty1-ADJUST_SIZE, 0, 1.0f, dwColor, fuv[0], fuv[1]}, {tx2-ADJUST_SIZE2, ty2-ADJUST_SIZE, 0, 1.0f, dwColor, fuv[2], fuv[3]}, {tx4-ADJUST_SIZE2, ty4-ADJUST_SIZE2, 0, 1.0f, dwColor, fuv[4], fuv[5]}, {tx3-ADJUST_SIZE, ty3-ADJUST_SIZE2, 0, 1.0f, dwColor, fuv[6], fuv[7]}, }; m_pd3dDevice->SetFVF(D3DFVF_CUSTOMVERTEX); m_pd3dDevice->SetPixelShader(NULL); m_pd3dDevice->SetTexture(0, m_pTexture->GetTexture()); BeginState(effect); m_pd3dDevice->DrawPrimitiveUP(D3DPT_TRIANGLEFAN, 2, Sprite, sizeof(CUSTOMVERTEX)); EndState(); }
void MBitmapR2::DrawEx(float tx1, float ty1, float tx2, float ty2, float tx3, float ty3, float tx4, float ty4, DWORD dwColor, MDrawEffect effect) { if (!m_pTexture) return; // 임시로 메모리에서 내린 상태라면 복구해준다 if(m_bUnloadedTemporarily) { m_pTexture->OnRestore(); m_bUnloadedTemporarily = false; } float ftw = (float)m_pTexture->GetWidth(); float fth = (float)m_pTexture->GetHeight(); float fuv[8] = { 0.f,0.f, 1.f,0.f, 1.f,1.f, 0.f,1.f }; CheckDrawMode(fuv); CUSTOMVERTEX Sprite[4] = { #define ADJUST_SIZE 0.5f #define ADJUST_SIZE2 0.0f {tx1-ADJUST_SIZE, ty1-ADJUST_SIZE, 0, 1.0f, dwColor, fuv[0], fuv[1]}, {tx2-ADJUST_SIZE2, ty2-ADJUST_SIZE, 0, 1.0f, dwColor, fuv[2], fuv[3]}, {tx4-ADJUST_SIZE2, ty4-ADJUST_SIZE2, 0, 1.0f, dwColor, fuv[4], fuv[5]}, {tx3-ADJUST_SIZE, ty3-ADJUST_SIZE2, 0, 1.0f, dwColor, fuv[6], fuv[7]}, }; m_pd3dDevice->SetFVF(D3DFVF_CUSTOMVERTEX); m_pd3dDevice->SetPixelShader(NULL); m_pd3dDevice->SetTexture(0, m_pTexture->GetTexture()); BeginState(effect); HRESULT hr = m_pd3dDevice->DrawPrimitiveUP(D3DPT_TRIANGLEFAN, 2, Sprite, sizeof(CUSTOMVERTEX)); _ASSERT(hr==D3D_OK); EndState(); }
void MBitmapR2::Draw(float x, float y, float w, float h, float sx, float sy, float sw, float sh, DWORD dwColor, MDrawEffect effect) { /* float ftw = (float)Floorer2PowerSize(m_Info.Width); float fth = (float)Floorer2PowerSize(m_Info.Height); */ float ftw = (float)m_pTexture->GetWidth(); float fth = (float)m_pTexture->GetHeight(); float fuv[8] = { (sx)/ftw ,(sy)/fth, (sx+sw)/ftw ,(sy)/fth, (sx+sw)/ftw ,(sy+sh)/fth, (sx)/ftw ,(sy+sh)/fth }; CheckDrawMode(fuv); CUSTOMVERTEX Sprite[4] = { #define ADJUST_SIZE 0.5f #define ADJUST_SIZE2 0.0f {x-ADJUST_SIZE, y-ADJUST_SIZE, 0, 1.0f, dwColor, fuv[0], fuv[1]}, {x+w-ADJUST_SIZE2, y-ADJUST_SIZE, 0, 1.0f, dwColor, fuv[2], fuv[3]}, {x+w-ADJUST_SIZE2, y+h-ADJUST_SIZE2, 0, 1.0f, dwColor, fuv[4], fuv[5]}, {x-ADJUST_SIZE, y+h-ADJUST_SIZE2, 0, 1.0f, dwColor, fuv[6], fuv[7]}, }; m_pd3dDevice->SetFVF(D3DFVF_CUSTOMVERTEX); m_pd3dDevice->SetPixelShader(NULL); m_pd3dDevice->SetTexture(0, m_pTexture->GetTexture()); BeginState(effect); m_pd3dDevice->DrawPrimitiveUP(D3DPT_TRIANGLEFAN, 2, Sprite, sizeof(CUSTOMVERTEX)); EndState(); }
bool ZEffectShadowList::Draw() { if(!m_pVB) return false; if( empty() ) return true; BeginState(); HRESULT hr; DWORD dwRemainNum = (DWORD)size(); iterator itr=begin(); while(dwRemainNum) { if(m_dwBase >= EFFECTBASE_DISCARD_COUNT) m_dwBase = 0; DWORD dwThisNum = min( dwRemainNum , BILLBOARD_FLUSH_COUNT ); dwThisNum = min( dwThisNum , EFFECTBASE_DISCARD_COUNT - m_dwBase ); BYTE* pVertices; if( FAILED( hr = m_pVB->Lock( m_dwBase * sizeof(ZEFFECTCUSTOMVERTEX) * 4, dwThisNum * sizeof(ZEFFECTCUSTOMVERTEX) * 4, (VOID**)&pVertices, m_dwBase ? D3DLOCK_NOOVERWRITE : D3DLOCK_DISCARD ) ) ) { return false; } BYTE *pInd; if( FAILED( hr = m_pIB->Lock( m_dwBase * sizeof(WORD) * 6, dwThisNum * sizeof(WORD) * 6, (VOID**)&pInd, m_dwBase ? D3DLOCK_NOOVERWRITE : D3DLOCK_DISCARD ) ) ) { return false; } for(DWORD j=0;j<dwThisNum;j++) { ZEFFECTSHADOWITEM *p = (ZEFFECTSHADOWITEM*)*itr; static ZEFFECTCUSTOMVERTEX v[] = { {-0.5f, -0.5f, 0.f, 0xFFFFFFFF, 0.f, 0.f}, { 0.5f, -0.5f, 0.f, 0xFFFFFFFF, 1.f, 0.f}, {-0.5f, 0.5f, 0.f, 0xFFFFFFFF, 0.f, 1.f}, { 0.5f, 0.5f, 0.f, 0xFFFFFFFF, 1.f, 1.f}, }; static rvector sv[4] = { rvector(-0.5f,-0.5f , 0.f) , rvector( 0.5f,-0.5f , 0.f) , rvector(-0.5f, 0.5f , 0.f) , rvector( 0.5f, 0.5f , 0.f) , }; // 좋은코드는 아니지만 버텍스 카피를 줄이기위해 타입캐스팅했다. D3DXVec3TransformCoord((D3DXVECTOR3*)&v[0].x,sv ,&p->worldmat); D3DXVec3TransformCoord((D3DXVECTOR3*)&v[1].x,sv+1,&p->worldmat); D3DXVec3TransformCoord((D3DXVECTOR3*)&v[2].x,sv+2,&p->worldmat); D3DXVec3TransformCoord((D3DXVECTOR3*)&v[3].x,sv+3,&p->worldmat); v[0].color=v[1].color=v[2].color=v[3].color=p->dwColor; memcpy(pVertices,v,sizeof(ZEFFECTCUSTOMVERTEX)*4); pVertices+=sizeof(ZEFFECTCUSTOMVERTEX)*4; WORD inds[] = { 0,1,2,2,1,3 }; for(int k=0;k<6;k++) { inds[k]+=(m_dwBase+j)*4; } memcpy(pInd,inds,sizeof(inds)); pInd+=sizeof(inds); itr++; } m_pVB->Unlock(); m_pIB->Unlock(); if(FAILED( hr = RGetDevice()->DrawIndexedPrimitive(D3DPT_TRIANGLELIST,0,m_dwBase*4,dwThisNum*4,m_dwBase*6,dwThisNum*2) )) // if(FAILED( hr = RGetDevice()->DrawIndexedPrimitive(D3DPT_TRIANGLESTRIP,0,m_dwBase*4,dwThisNum*4,m_dwBase*6,dwThisNum*2) )) return false; m_dwBase+=dwThisNum; dwRemainNum-=dwThisNum; } RGetDevice()->SetStreamSource( 0, NULL , 0,0 ); RGetDevice()->SetIndices(NULL); EndState(); Clear(); return true; }
bool ZEffectBillboardTexAniList::Draw() { if(!m_pVB) return false; if( size()==0 ) return true; BeginState(); RSetFog(FALSE); HRESULT hr; DWORD dwRemainNum = (DWORD)size(); iterator itr = begin(); while(dwRemainNum) { if(m_dwBase >= EFFECTBASE_DISCARD_COUNT) m_dwBase = 0; DWORD dwThisNum = min( dwRemainNum , BILLBOARD_FLUSH_COUNT ); dwThisNum = min( dwThisNum , EFFECTBASE_DISCARD_COUNT - m_dwBase ); BYTE *pVertices; if( FAILED( hr = m_pVB->Lock( m_dwBase * sizeof(ZEFFECTCUSTOMVERTEX) * 4, dwThisNum * sizeof(ZEFFECTCUSTOMVERTEX) * 4, (VOID**)&pVertices, m_dwBase ? D3DLOCK_NOOVERWRITE : D3DLOCK_DISCARD ) ) ) { return false; } BYTE *pInd; if( FAILED( hr = m_pIB->Lock( m_dwBase * sizeof(WORD) * 6, dwThisNum * sizeof(WORD) * 6, (VOID**)&pInd, m_dwBase ? D3DLOCK_NOOVERWRITE : D3DLOCK_DISCARD ) ) ) { return false; } int nRenderCnt = 0; ZCharacter* pChar = NULL; for(DWORD j=0;j<dwThisNum;j++) { ZEFFECTBILLBOARDTEXANIITEM *p = (ZEFFECTBILLBOARDTEXANIITEM*)*itr; if(p->fElapsedTime < p->fAddTime ) { itr++; continue; } pChar = ZGetCharacterManager()->Find(p->CharUID); if( pChar ) { if( pChar->m_pVMesh ) { if( pChar->m_pVMesh->m_bIsRender==false) {//부모가 안그려졌으면 skip... itr++; continue; } } } nRenderCnt++; // Transform rmatrix matTranslation; rmatrix matScaling; rmatrix matWorld; rvector dir = p->normal; rvector up=p->up; rvector right; if(IS_EQ(dir.z,1.f)) up=rvector(1,0,0); D3DXVec3Cross(&right, &up, &dir); D3DXVec3Normalize(&right, &right); D3DXVec3Cross(&up, &right, &dir); D3DXVec3Normalize(&up, &up); rmatrix mat; D3DXMatrixIdentity(&mat); mat._11=right.x;mat._12=right.y;mat._13=right.z; mat._21=up.x;mat._22=up.y;mat._23=up.z; mat._31=dir.x;mat._32=dir.y;mat._33=dir.z; rvector pos=p->position; // float fScale=p->fStartSize * p->fOpacity + p->fEndSize * (1.f - p->fOpacity); float fInt = min(1,max(0,(p->fLifeTime - p->fElapsedTime)/p->fLifeTime)); float fScale=p->fStartSize * fInt + p->fEndSize * (1.f - fInt); D3DXMatrixScaling(&matScaling,fScale*m_Scale.x,fScale*m_Scale.y,fScale*m_Scale.z); D3DXMatrixTranslation(&matTranslation, pos.x, pos.y, pos.z); D3DXMatrixMultiply(&matWorld, &matScaling, &mat); D3DXMatrixMultiply(&matWorld, &matWorld, &matTranslation); DWORD color = ((DWORD)(p->fOpacity * 255))<<24 | p->dwColor; static ZEFFECTCUSTOMVERTEX v[] = { {-1, -1, 0, 0xFFFFFFFF, 1, 0}, {-1, 1, 0, 0xFFFFFFFF, 1, 1}, { 1, 1, 0, 0xFFFFFFFF, 0, 1}, { 1, -1, 0, 0xFFFFFFFF, 0, 0}, }; static rvector sv[4] = { rvector(-1,-1,0) , rvector(-1,1,0) , rvector(1,1,0) , rvector(1,-1,0) }; GetFrameUV( min( p->frame,m_nMaxFrame-1) ); v[0].tu = m_fUV[0]; v[0].tv = m_fUV[1]; v[1].tu = m_fUV[2]; v[1].tv = m_fUV[3]; v[2].tu = m_fUV[4]; v[2].tv = m_fUV[5]; v[3].tu = m_fUV[6]; v[3].tv = m_fUV[7]; // 좋은코드는 아니지만 버텍스 카피를 줄이기위해 타입캐스팅했다. D3DXVec3TransformCoord((D3DXVECTOR3*)&v[0].x,sv+0,&matWorld); D3DXVec3TransformCoord((D3DXVECTOR3*)&v[1].x,sv+1,&matWorld); D3DXVec3TransformCoord((D3DXVECTOR3*)&v[2].x,sv+2,&matWorld); D3DXVec3TransformCoord((D3DXVECTOR3*)&v[3].x,sv+3,&matWorld); v[0].color=v[1].color=v[2].color=v[3].color=color; memcpy(pVertices,v,sizeof(ZEFFECTCUSTOMVERTEX)*4); pVertices+=sizeof(ZEFFECTCUSTOMVERTEX)*4; WORD inds[] = { 0,1,2,0,2,3 }; for(int k=0;k<6;k++) { inds[k]+=(m_dwBase+j)*4; } memcpy(pInd,inds,sizeof(inds)); pInd+=sizeof(inds); itr++; } m_pVB->Unlock(); m_pIB->Unlock(); if(FAILED( hr = RGetDevice()->DrawIndexedPrimitive(D3DPT_TRIANGLELIST,0,m_dwBase*4,nRenderCnt*4,m_dwBase*6,nRenderCnt*2) )) return false; m_dwBase+=dwThisNum; dwRemainNum-=dwThisNum; } RGetDevice()->SetStreamSource( 0, NULL , 0,0 ); RGetDevice()->SetIndices(NULL); if(ZGetWorld()) { ZGetWorld()->SetFog(true);// 게임 설정에 따라서 } EndState(); return true; }
bool ZEffectBillboardList::Draw() { if(!m_pVB) return false; if( size()==0 ) return true; BeginState(); HRESULT hr; DWORD dwRemainNum = (DWORD)size(); iterator itr=begin(); while(dwRemainNum) { if(m_dwBase >= EFFECTBASE_DISCARD_COUNT) m_dwBase = 0; // 갯수가 BILLBOARD_FLUSH_COUNT 를 넘어가면 BILLBOARD_FLUSH_COUNT 씩 찍는다 DWORD dwThisNum = min( dwRemainNum , BILLBOARD_FLUSH_COUNT ); // 버퍼의 크기를 넘어가면 개수를 줄여서 크기만큼만 찍는다 dwThisNum = min( dwThisNum , EFFECTBASE_DISCARD_COUNT - m_dwBase ); BYTE *pVertices; if( FAILED( hr = m_pVB->Lock( m_dwBase * sizeof(ZEFFECTCUSTOMVERTEX) * 4, dwThisNum * sizeof(ZEFFECTCUSTOMVERTEX) * 4, (VOID**)&pVertices, m_dwBase ? D3DLOCK_NOOVERWRITE : D3DLOCK_DISCARD ) ) ) { return false; } BYTE *pInd; if( FAILED( hr = m_pIB->Lock( m_dwBase * sizeof(WORD) * 6, dwThisNum * sizeof(WORD) * 6, (VOID**)&pInd, m_dwBase ? D3DLOCK_NOOVERWRITE : D3DLOCK_DISCARD ) ) ) { return false; } for(DWORD j=0;j<dwThisNum;j++) { ZEFFECTBILLBOARDITEM *p = (ZEFFECTBILLBOARDITEM*)*itr; // Transform rmatrix matTranslation; rmatrix matScaling; rmatrix matWorld; rvector dir = p->normal; rvector up=p->up; rvector right; if(IS_EQ(dir.z,1.f)) up=rvector(1,0,0); D3DXVec3Cross(&right, &up, &dir); D3DXVec3Normalize(&right, &right); D3DXVec3Cross(&up, &right, &dir); D3DXVec3Normalize(&up, &up); rmatrix mat; D3DXMatrixIdentity(&mat); mat._11=right.x;mat._12=right.y;mat._13=right.z; mat._21=up.x;mat._22=up.y;mat._23=up.z; mat._31=dir.x;mat._32=dir.y;mat._33=dir.z; rvector pos=p->position; // float fScale=p->fStartSize * p->fOpacity + p->fEndSize * (1.f - p->fOpacity); float fInt = min(1,max(0,(p->fLifeTime - p->fElapsedTime)/p->fLifeTime)); float fScale=p->fStartSize * fInt + p->fEndSize * (1.f - fInt); if( p->bUseTrainSmoke ) { float fRatio = GetLifeRatio(p); float fAddScale = (p->fEndSize - p->fStartSize) / p->fLifeTime; if(fRatio < 0.1f ) { fAddScale *= 0.001f; } else if(fRatio < 0.4) { fAddScale *= 0.02f; } else { fAddScale *= 0.05f; } p->fCurScale += fAddScale; if(p->fCurScale > p->fEndSize) p->fCurScale = p->fEndSize; fScale = p->fCurScale; } D3DXMatrixScaling(&matScaling,fScale*m_Scale.x,fScale*m_Scale.y,fScale*m_Scale.z); D3DXMatrixTranslation(&matTranslation, pos.x, pos.y, pos.z); D3DXMatrixMultiply(&matWorld, &matScaling, &mat); D3DXMatrixMultiply(&matWorld, &matWorld, &matTranslation); // D3DXMatrixMultiply(&matWorld, &mat, &matTranslation); DWORD color = ((DWORD)(p->fOpacity * 255))<<24 | p->dwColor; static ZEFFECTCUSTOMVERTEX v[] = { {-1, -1, 0, 0xFFFFFFFF, 1, 0}, {-1, 1, 0, 0xFFFFFFFF, 1, 1}, { 1, 1, 0, 0xFFFFFFFF, 0, 1}, { 1, -1, 0, 0xFFFFFFFF, 0, 0}, }; static rvector sv[4] = { rvector(-1,-1,0) , rvector(-1,1,0) , rvector(1,1,0) , rvector(1,-1,0) }; // 좋은코드는 아니지만 버텍스 카피를 줄이기위해 타입캐스팅했다. D3DXVec3TransformCoord((D3DXVECTOR3*)&v[0].x,sv+0,&matWorld); D3DXVec3TransformCoord((D3DXVECTOR3*)&v[1].x,sv+1,&matWorld); D3DXVec3TransformCoord((D3DXVECTOR3*)&v[2].x,sv+2,&matWorld); D3DXVec3TransformCoord((D3DXVECTOR3*)&v[3].x,sv+3,&matWorld); v[0].color=v[1].color=v[2].color=v[3].color=color; memcpy(pVertices,v,sizeof(ZEFFECTCUSTOMVERTEX)*4); pVertices+=sizeof(ZEFFECTCUSTOMVERTEX)*4; WORD inds[] = { 0,1,2,0,2,3 }; for(int k=0;k<6;k++) { inds[k]+=(m_dwBase+j)*4; } memcpy(pInd,inds,sizeof(inds)); pInd+=sizeof(inds); itr++; } m_pVB->Unlock(); m_pIB->Unlock(); if(FAILED( hr = RGetDevice()->DrawIndexedPrimitive(D3DPT_TRIANGLELIST,0,m_dwBase*4,dwThisNum*4,m_dwBase*6,dwThisNum*2) )) return false; m_dwBase+=dwThisNum; dwRemainNum-=dwThisNum; } RGetDevice()->SetStreamSource( 0, NULL , 0,0 ); RGetDevice()->SetIndices(NULL); EndState(); return true; }
void MBitmapR2::Draw(float x, float y, float w, float h, float sx, float sy, float sw, float sh, DWORD dwColor, MDrawEffect effect, bool bMirrorX, bool bMirrorY) { /* float ftw = (float)Floorer2PowerSize(m_Info.Width); float fth = (float)Floorer2PowerSize(m_Info.Height); */ if(m_pTexture==NULL) return; // 임시로 메모리에서 내린 상태라면 복구해준다 if(m_bUnloadedTemporarily) { m_pTexture->OnRestore(); m_bUnloadedTemporarily = false; } float ftw = (float)m_pTexture->GetWidth(); float fth = (float)m_pTexture->GetHeight(); // 인버스 작업 float fuv[8]; // X축 인버스 if (!bMirrorX) { fuv[0] = (sx)/ftw; fuv[2] = (sx+sw)/ftw; fuv[4] = (sx+sw)/ftw; fuv[6] = (sx)/ftw; } else { fuv[2] = (sx)/ftw; fuv[0] = (sx+sw)/ftw; fuv[6] = (sx+sw)/ftw; fuv[4] = (sx)/ftw; } // Y축 인버스 if (!bMirrorY) { fuv[1] = (sy)/fth; fuv[3] = (sy)/fth; fuv[5] = (sy+sh)/fth; fuv[7] = (sy+sh)/fth; } else { fuv[7] = (sy)/fth; fuv[5] = (sy)/fth; fuv[3] = (sy+sh)/fth; fuv[1] = (sy+sh)/fth; } CheckDrawMode(fuv); CUSTOMVERTEX Sprite[4] = { #define ADJUST_SIZE 0.5f #define ADJUST_SIZE2 0.0f {x-ADJUST_SIZE, y-ADJUST_SIZE, 0, 1.0f, dwColor, fuv[0], fuv[1]}, {x+w-ADJUST_SIZE2, y-ADJUST_SIZE, 0, 1.0f, dwColor, fuv[2], fuv[3]}, {x+w-ADJUST_SIZE2, y+h-ADJUST_SIZE2, 0, 1.0f, dwColor, fuv[4], fuv[5]}, {x-ADJUST_SIZE, y+h-ADJUST_SIZE2, 0, 1.0f, dwColor, fuv[6], fuv[7]}, }; m_pd3dDevice->SetFVF(D3DFVF_CUSTOMVERTEX); m_pd3dDevice->SetPixelShader(NULL); m_pd3dDevice->SetTexture(0, m_pTexture->GetTexture()); BeginState(effect); HRESULT hr = m_pd3dDevice->DrawPrimitiveUP(D3DPT_TRIANGLEFAN, 2, Sprite, sizeof(CUSTOMVERTEX)); _ASSERT(hr==D3D_OK); EndState(); }
bool ZEffectBillboardTexAniList::Draw() { if(!m_pVB) return false; if( size()==0 ) return true; BeginState(); RSetFog(FALSE); HRESULT hr; DWORD dwRemainNum = (DWORD)size(); iterator itr = begin(); while(dwRemainNum) { if(m_dwBase >= EFFECTBASE_DISCARD_COUNT) m_dwBase = 0; DWORD dwThisNum = min( dwRemainNum , static_cast<DWORD>(BILLBOARD_FLUSH_COUNT) ); dwThisNum = min( dwThisNum , EFFECTBASE_DISCARD_COUNT - m_dwBase ); BYTE *pVertices; if( FAILED( hr = m_pVB->Lock( m_dwBase * sizeof(ZEFFECTCUSTOMVERTEX) * 4, dwThisNum * sizeof(ZEFFECTCUSTOMVERTEX) * 4, (VOID**)&pVertices, m_dwBase ? D3DLOCK_NOOVERWRITE : D3DLOCK_DISCARD ) ) ) { return false; } BYTE *pInd; if( FAILED( hr = m_pIB->Lock( m_dwBase * sizeof(WORD) * 6, dwThisNum * sizeof(WORD) * 6, (VOID**)&pInd, m_dwBase ? D3DLOCK_NOOVERWRITE : D3DLOCK_DISCARD ) ) ) { return false; } int nRenderCnt = 0; ZCharacter* pChar = NULL; for(DWORD j=0;j<dwThisNum;j++) { ZEFFECTBILLBOARDTEXANIITEM *p = (ZEFFECTBILLBOARDTEXANIITEM*)*itr; if(p->fElapsedTime < p->fAddTime ) { itr++; continue; } pChar = ZGetCharacterManager()->Find(p->CharUID); if( pChar ) { if( pChar->m_pVMesh ) { if( pChar->m_pVMesh->m_bIsRender==false) { itr++; continue; } } } nRenderCnt++; // Transform rmatrix matTranslation; rmatrix matScaling; rmatrix matWorld; rvector dir = p->normal; rvector up = p->up; rvector right; if (IS_EQ(dir.z, 1.f)) up = rvector(1, 0, 0); right = Normalized(CrossProduct(up, dir)); up = Normalized(CrossProduct(right, dir)); rmatrix mat; GetIdentityMatrix(mat); mat._11 = right.x; mat._12 = right.y; mat._13 = right.z; mat._21 = up.x; mat._22 = up.y; mat._23 = up.z; mat._31 = dir.x; mat._32 = dir.y; mat._33 = dir.z; rvector pos = p->position; float fInt = min(1.f, max(0.f, (p->fLifeTime - p->fElapsedTime) / p->fLifeTime)); float fScale=p->fStartSize * fInt + p->fEndSize * (1.f - fInt); matScaling = ScalingMatrix(fScale * m_Scale); matTranslation = TranslationMatrix(pos); matWorld = matScaling * mat; matWorld *= matTranslation; DWORD color = ((DWORD)(p->fOpacity * 255))<<24 | p->dwColor; static ZEFFECTCUSTOMVERTEX v[] = { {{-1, -1, 0}, 0xFFFFFFFF, 1, 0 }, {{-1, 1, 0}, 0xFFFFFFFF, 1, 1}, {{ 1, 1, 0}, 0xFFFFFFFF, 0, 1}, {{ 1, -1, 0}, 0xFFFFFFFF, 0, 0}, }; static rvector sv[4] = { rvector(-1,-1,0) , rvector(-1,1,0) , rvector(1,1,0) , rvector(1,-1,0) }; GetFrameUV( min( p->frame,m_nMaxFrame-1) ); v[0].tu = m_fUV[0]; v[0].tv = m_fUV[1]; v[1].tu = m_fUV[2]; v[1].tv = m_fUV[3]; v[2].tu = m_fUV[4]; v[2].tv = m_fUV[5]; v[3].tu = m_fUV[6]; v[3].tv = m_fUV[7]; for (size_t i{}; i < 4; ++i) v[i].pos = TransformCoord(sv[i], matWorld); v[0].color=v[1].color=v[2].color=v[3].color=color; memcpy(pVertices,v,sizeof(ZEFFECTCUSTOMVERTEX)*4); pVertices+=sizeof(ZEFFECTCUSTOMVERTEX)*4; WORD inds[] = { 0,1,2,0,2,3 }; for(int k=0;k<6;k++) { inds[k]+=(m_dwBase+j)*4; } memcpy(pInd,inds,sizeof(inds)); pInd+=sizeof(inds); itr++; } m_pVB->Unlock(); m_pIB->Unlock(); if(FAILED( hr = RGetDevice()->DrawIndexedPrimitive(D3DPT_TRIANGLELIST,0,m_dwBase*4,nRenderCnt*4,m_dwBase*6,nRenderCnt*2) )) return false; m_dwBase+=dwThisNum; dwRemainNum-=dwThisNum; } RGetDevice()->SetStreamSource( 0, NULL , 0,0 ); RGetDevice()->SetIndices(NULL); if(ZGetWorld()) { ZGetWorld()->SetFog(true); } EndState(); return true; }
bool ZEffectBillboardList::Draw() { if(!m_pVB) return false; if( size()==0 ) return true; BeginState(); HRESULT hr; DWORD dwRemainNum = (DWORD)size(); iterator itr=begin(); while(dwRemainNum) { if(m_dwBase >= EFFECTBASE_DISCARD_COUNT) m_dwBase = 0; DWORD dwThisNum = min( dwRemainNum , static_cast<DWORD>(BILLBOARD_FLUSH_COUNT) ); dwThisNum = min( dwThisNum , EFFECTBASE_DISCARD_COUNT - m_dwBase ); BYTE *pVertices; if( FAILED( hr = m_pVB->Lock( m_dwBase * sizeof(ZEFFECTCUSTOMVERTEX) * 4, dwThisNum * sizeof(ZEFFECTCUSTOMVERTEX) * 4, (VOID**)&pVertices, m_dwBase ? D3DLOCK_NOOVERWRITE : D3DLOCK_DISCARD ) ) ) { return false; } BYTE *pInd; if( FAILED( hr = m_pIB->Lock( m_dwBase * sizeof(WORD) * 6, dwThisNum * sizeof(WORD) * 6, (VOID**)&pInd, m_dwBase ? D3DLOCK_NOOVERWRITE : D3DLOCK_DISCARD ) ) ) { return false; } for(DWORD j=0;j<dwThisNum;j++) { ZEFFECTBILLBOARDITEM *p = (ZEFFECTBILLBOARDITEM*)*itr; // Transform rmatrix matTranslation; rmatrix matScaling; rmatrix matWorld; rvector dir = p->normal; rvector up=p->up; rvector right; if(IS_EQ(dir.z,1.f)) up=rvector(1,0,0); right = Normalized(CrossProduct(up, dir)); up = Normalized(CrossProduct(right, dir)); rmatrix mat; GetIdentityMatrix(mat); mat._11=right.x;mat._12=right.y;mat._13=right.z; mat._21=up.x;mat._22=up.y;mat._23=up.z; mat._31=dir.x;mat._32=dir.y;mat._33=dir.z; rvector pos=p->position; float fInt = min(1.f, max(0.f, (p->fLifeTime - p->fElapsedTime) / p->fLifeTime)); float fScale=p->fStartSize * fInt + p->fEndSize * (1.f - fInt); if( p->bUseTrainSmoke ) { float fRatio = GetLifeRatio(p); float fAddScale = (p->fEndSize - p->fStartSize) / p->fLifeTime; if(fRatio < 0.1f ) { fAddScale *= 0.001f; } else if(fRatio < 0.4) { fAddScale *= 0.02f; } else { fAddScale *= 0.05f; } p->fCurScale += fAddScale; if(p->fCurScale > p->fEndSize) p->fCurScale = p->fEndSize; fScale = p->fCurScale; } matScaling = ScalingMatrix(fScale * m_Scale); matTranslation = TranslationMatrix(pos); matWorld = matScaling * mat; matWorld *= matTranslation; DWORD color = ((DWORD)(p->fOpacity * 255))<<24 | p->dwColor; static ZEFFECTCUSTOMVERTEX v[] = { {{-1, -1, 0}, 0xFFFFFFFF, 1, 0 }, {{-1, 1, 0}, 0xFFFFFFFF, 1, 1 }, {{ 1, 1, 0 }, 0xFFFFFFFF, 0, 1}, { { 1, -1, 0}, 0xFFFFFFFF, 0, 0 }, }; static const rvector sv[4] = { rvector(-1,-1,0) , rvector(-1,1,0) , rvector(1,1,0) , rvector(1,-1,0) }; for (size_t i{}; i < 4; ++i) v[i].pos = TransformCoord(sv[i], matWorld); v[0].color=v[1].color=v[2].color=v[3].color=color; memcpy(pVertices,v,sizeof(ZEFFECTCUSTOMVERTEX)*4); pVertices+=sizeof(ZEFFECTCUSTOMVERTEX)*4; WORD inds[] = { 0,1,2,0,2,3 }; for(int k=0;k<6;k++) { inds[k]+=(m_dwBase+j)*4; } memcpy(pInd,inds,sizeof(inds)); pInd+=sizeof(inds); itr++; } m_pVB->Unlock(); m_pIB->Unlock(); if(FAILED( hr = RGetDevice()->DrawIndexedPrimitive(D3DPT_TRIANGLELIST,0,m_dwBase*4,dwThisNum*4,m_dwBase*6,dwThisNum*2) )) return false; m_dwBase+=dwThisNum; dwRemainNum-=dwThisNum; } RGetDevice()->SetStreamSource( 0, NULL , 0,0 ); RGetDevice()->SetIndices(NULL); EndState(); return true; }