#include "stdafx.h" #include "KResource.h" #include "KPrimitiveSprite.h" #include "KRenderDevice.h" #include "KPrimitiveSpriteMng.h" ///////////////////////////////////////////////////////////////////////////////////////////////////////////////// // KSpritePrimitive Implement ///////////////////////////////////////////////////////////////////////////////////////////////////////////////// int g_Debug = 0; const float KSpritePrimitive::s_fLayerDevider = 100.f; int KSpritePrimitive::s_nVertexStride = K3DVertexBuffer::CalcVertexStride( K3DFVF_XYZRHW | K3DFVF_DIFFUSE | K3DFVF_TEX1 ); KSpritePrimitive::KSpritePrimitive( bool bIsMng/* = true*/ ) : m_fResVisibility(1.0f), m_fVisibility(1.0f), m_colSprite(255,255,255,255), m_bUseAdditiveRender(false), m_pClipRect(NULL),m_bMirrorH(false), m_bMirrorV(false),m_bCCWRotation(false),m_bCWRotation(false), m_bModify(true), m_fDepthOrder(0.1f), m_bRenderValidate(true), m_bRenderEnable(true) #ifdef _KUI_INVALIDATION // { [sonador] , m_vRenderOffset( 0, 0, 0 ) // } #endif { m_bIsMng = bIsMng; if( m_bIsMng ) KPrimitiveSpriteMng::GetManager()->Add( this ); m_type = KPRIMITIVE_SPRITE; K3DMatrixIdentity(m_matTransform); m_bIsUse = false; } KSpritePrimitive::~KSpritePrimitive() { if( m_bIsMng ) KPrimitiveSpriteMng::GetManager()->Del( this ); Clear(); } void KSpritePrimitive::Clear() { } void KSpritePrimitive::SetRenderEnable(bool bEnable) { m_bRenderEnable = bEnable; } void KSpritePrimitive::SetClipRect( KRect *cliprect ) { m_pClipRect = cliprect; m_bModify = true; } void KSpritePrimitive::SetTransform( const K3DMatrix &transform ) { m_matTransform = transform; m_bModify = true; } void KSpritePrimitive::SetVisibility( float vis ) { m_fVisibility = vis; m_colSprite.a = (unsigned char)(m_fResVisibility * m_fVisibility * 255); m_bModify = true; } void KSpritePrimitive::SetResVisibility(float vis ) { m_fResVisibility = vis; m_colSprite.a = (unsigned char)(m_fResVisibility * m_fVisibility * 255); m_bModify = true; } K3DVector KSpritePrimitive::GetPosition() { K3DVector ret; K3DMatrixGetPosVector(ret, m_matTransform); return ret; } void KSpritePrimitive::SetZPosition(float fZPos) { m_matTransform._43 = fZPos; m_bModify = true; } #ifdef _KUI_INVALIDATION // { [sonador] void KSpritePrimitive::SetRenderOffset( const K3DVector& vRenderOffset ) { m_vRenderOffset = vRenderOffset; } // } #endif void KSpritePrimitive::SetRes( KResSprite *pRes ) { m_spRes = pRes; if(m_spRes == NULL) { m_bIsUse = false; return; } SetMirror( m_spRes->IsMirrorHori(), m_spRes->IsMirrorVert() ); SetCWRotation(m_spRes->IsCWRotate()); SetCCWRotation(m_spRes->IsCCWRotate()); SetAdditiveRenderMode( m_spRes->IsAdditiveRenderMode() ); SetResVisibility( m_spRes->GetVisibility() ); m_spRes->GetSourceUVRect(m_fLeft,m_fTop, m_fRight, m_fBottom); m_fTargetWidth = m_spRes->GetSizeX(); m_fTargetHeight = m_spRes->GetSizeY(); m_bModify = true; m_bIsUse = true; } void KSpritePrimitive::SetSourceRect(const KRect& rcRect) { m_spRes->GetSourceUVRect( m_fLeft, m_fTop, m_fRight, m_fBottom); float fSizeX = static_cast(m_spRes->GetSizeX() ); float fSizeY = static_cast(m_spRes->GetSizeY() ); float fUVWidth = m_fRight - m_fLeft; float fUVHeight = m_fBottom - m_fTop; m_fLeft += ( (float)rcRect.left / fSizeX * fUVWidth ); m_fTop += ( (float)rcRect.top / fSizeY * fUVHeight ); m_fRight += (rcRect.right - fSizeX) / fSizeX * fUVWidth; m_fBottom += (rcRect.bottom - fSizeY) / fSizeX * fUVWidth; m_bModify = true; } void KSpritePrimitive::SetSourceRectRatio(float fLeft, float fTop, float fRight ,float fBottom) { m_spRes->GetSourceUVRect( m_fLeft, m_fTop, m_fRight, m_fBottom); float fUVWidth = m_fRight - m_fLeft; float fUVHeight = m_fBottom - m_fTop; m_fLeft += fLeft * fUVWidth; m_fTop += fTop * fUVHeight; m_fRight += ( fRight - 1.0f) * fUVWidth; m_fBottom += ( fBottom - 1.0f) * fUVHeight; m_bModify = true; } void KSpritePrimitive::UpdateSprite() { if(m_spRes == NULL || m_spRes->GetTexture() == NULL ) return; K3DMatrix matLocal = m_spRes->GetTransform(); K3DVector posParent, posLocal; K3DMatrixGetPosVector( posParent, m_matTransform ); K3DMatrixGetPosVector( posLocal, matLocal); K3DVector pos; pos = posParent + posLocal; float sprtx,sprty; sprtx = pos.x + m_fTargetWidth; sprty = pos.y + m_fTargetHeight; K3DVector center; center.x = pos.x + m_fTargetWidth / 2.f; center.y = pos.y + m_fTargetHeight / 2.f; float l = m_fLeft, t = m_fTop, r = m_fRight, b = m_fBottom; // clipping 처리 if(m_pClipRect) { // No need to draw. if ( m_pClipRect->left >= sprtx || m_pClipRect->top >= sprty || m_pClipRect->right <= pos.x || m_pClipRect->bottom <= pos.y ) { m_bRenderValidate = false; return; } KRect rect; float uvwidth, uvheight; uvwidth = r - l; uvheight = b - t; int texw = m_spRes->GetTexture()->GetWidth(); int texh = m_spRes->GetTexture()->GetHeight(); float actualw = texw * uvwidth; float actualh = texh * uvheight; float scalew = m_fTargetWidth / actualw; float scaleh = m_fTargetHeight / actualh; if ( m_pClipRect->left > pos.x ) { rect.left = m_pClipRect->left; int d = int(rect.left - pos.x); l += uvwidth * (float(d)/m_spRes->GetSizeX()) / scalew; } else rect.left = int(pos.x); if ( m_pClipRect->top > pos.y ) { rect.top = m_pClipRect->top; int d = int(rect.top - pos.y); t += uvheight * (float(d)/m_spRes->GetSizeY()) / scaleh; } else rect.top = int(pos.y); if ( m_pClipRect->right < sprtx ) { rect.right = m_pClipRect->right; int d = int(sprtx - rect.right); r -= uvwidth * (float(d)/m_spRes->GetSizeX()) / scalew; } else rect.right = int(sprtx); if ( m_pClipRect->bottom < sprty ) { rect.bottom = m_pClipRect->bottom; int d = int(sprty - rect.bottom); b -= uvheight * (float(d)/m_spRes->GetSizeY()) / scaleh; } else rect.bottom = int(sprty); pos.x = (float)rect.left; pos.y = (float)rect.top; sprtx = (float)rect.right; sprty = (float)rect.bottom; center.x = pos.x + ((sprtx - pos.x)/2.f); center.y = pos.y + ((sprty - pos.y)/2.f); } // For rotating around center of the sprite. pos.x -= center.x; pos.y -= center.y; sprtx -= center.x; sprty -= center.y; float fZPos = pos.z / s_fLayerDevider; if(m_bMirrorH) std::swap(l,r); if(m_bMirrorV) std::swap(t,b); m_VtxBuf[0].x = pos.x; m_VtxBuf[1].x = sprtx; m_VtxBuf[0].y = pos.y; m_VtxBuf[1].y = pos.y; m_VtxBuf[0].z = fZPos; m_VtxBuf[1].z = fZPos; m_VtxBuf[0].w = 1; m_VtxBuf[1].w = 1; m_VtxBuf[0].u = l; m_VtxBuf[1].u = r; m_VtxBuf[0].v = t; m_VtxBuf[1].v = t; m_VtxBuf[0].color = m_colSprite; m_VtxBuf[1].color = m_colSprite; m_VtxBuf[2].x = pos.x; m_VtxBuf[3].x = sprtx; m_VtxBuf[2].y = sprty; m_VtxBuf[3].y = sprty; m_VtxBuf[2].z = fZPos; m_VtxBuf[3].z = fZPos; m_VtxBuf[2].w = 1; m_VtxBuf[3].w = 1; m_VtxBuf[2].u = l; m_VtxBuf[3].u = r; m_VtxBuf[2].v = b; m_VtxBuf[3].v = b; m_VtxBuf[2].color = m_colSprite; m_VtxBuf[3].color = m_colSprite; // Rotate static float fMatRot[2][2]; fMatRot[0][0] = m_matTransform._11 * matLocal._11 + m_matTransform._12 * matLocal._21; fMatRot[0][1] = m_matTransform._11 * matLocal._12 + m_matTransform._12 * matLocal._22; fMatRot[1][0] = m_matTransform._21 * matLocal._11 + m_matTransform._22 * matLocal._21; fMatRot[1][1] = m_matTransform._21 * matLocal._12 + m_matTransform._22 * matLocal._22; for(int i = 0; i < 4; ++i) { float xOrg = m_VtxBuf[i].x; // See DX Help - Directly Mapping Texels to Pixels m_VtxBuf[i].x = xOrg * fMatRot[0][0] + m_VtxBuf[i].y * fMatRot[1][0] + center.x - 0.5f; m_VtxBuf[i].y = xOrg * fMatRot[0][1] + m_VtxBuf[i].y * fMatRot[1][1] + center.y - 0.5f; #ifdef _KUI_INVALIDATION // { [sonador] m_VtxBuf[i].x -= m_vRenderOffset.x; m_VtxBuf[i].y -= m_vRenderOffset.y; // } #endif } m_bRenderValidate = true; } /// 2011.01.18 - prodongi void KSpritePrimitive::initScroll(bool is, DWORD type, float v, float margin) { m_scroll.initialize(is, type, v, margin, (void const*)m_VtxBuf); } /// 2011.02.23 - prodongi void KSpritePrimitive::setScrollImgUv(int width, int height) { float u = (float)width/(float)m_spRes->GetTexture()->GetWidth(); float v = (float)height/(float)m_spRes->GetTexture()->GetHeight(); m_scroll.setImgUv(u, v); } void KSpritePrimitive::DeviceLost() { if(m_spRes != NULL) { m_spRes->GetSourceUVRect(m_fLeft,m_fTop, m_fRight, m_fBottom); UpdateSprite(); } } void KSpritePrimitive::Render( KViewportObject *viewport, class K3DRenderDevice *dev, bool bUseAccum ) { if(m_bModify && m_bRenderEnable) { UpdateSprite(); m_bModify = false; } if(m_bRenderValidate && m_bRenderEnable && m_spRes != NULL) { m_scroll.update(m_VtxBuf); /// 2011.01.18 - prodongi m_scroll.setTextureAddressMode(dev); dev->SetTexture( 0, m_spRes->GetTexture() ); dev->DrawTriangleStrip( K3DFVF_XYZRHW | K3DFVF_DIFFUSE | K3DFVF_TEX1, m_VtxBuf, 4, s_nVertexStride); m_scroll.restoreTextureAddressMode(dev); /// 2011.01.18 - prodongi } #ifdef _DEBUG //그려지는 스프라이트 파일로 저장 static bool bFlag = false; if( bFlag ) { K3DTexture* pTex = m_spRes->GetTexture(); if( pTex ) pTex->SaveToFile("c:\\test.dds"); bFlag = false; } #endif }