348 lines
9.3 KiB
C++
348 lines
9.3 KiB
C++
#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<float>(m_spRes->GetSizeX() );
|
|
float fSizeY = static_cast<float>(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
|
|
}
|