📄 zfxd3d_misc.cpp
字号:
float X = m_fNear/(m_fNear-m_fFar);
m_mProjO[0]._33 = m_mProjO[1]._33 = Q;
m_mProjO[2]._33 = m_mProjO[3]._33 = Q;
m_mProjO[0]._43 = m_mProjO[1]._43 = X;
m_mProjO[2]._43 = m_mProjO[3]._43 = X;
// change perspective projection
Q *= m_fFar;
X = -Q * m_fNear;
m_mProjP[0]._33 = m_mProjP[1]._33 = Q;
m_mProjP[2]._33 = m_mProjP[3]._33 = Q;
m_mProjP[0]._43 = m_mProjP[1]._43 = X;
m_mProjP[2]._43 = m_mProjP[3]._43 = X;
} // SetClippingPlanes
/*----------------------------------------------------------------*/
/**
* Call this prior to but not instead of SetMode(ORTHO,n)
*/
void ZFXD3D::SetOrthoScale(float fScale, int n) {
float fW = ((float)m_dwWidth)/m_dwHeight * fScale;
float fH = fScale;
memset(&m_mProjO[n], 0, sizeof(D3DMATRIX));
m_mProjO[n]._11 = 2.0f / fW;
m_mProjO[n]._22 = 2.0f / fH;
m_mProjO[n]._33 = 1.0f / (m_fFar-m_fNear);
m_mProjO[n]._43 = m_fNear / (m_fNear-m_fFar);
m_mProjO[n]._44 = 1.0f;
} // SetOrthoScale
/*----------------------------------------------------------------*/
/**
* Calculate orthogonal projection and view matrix to render
* vertices who's world-coordinates are given in screen space.
*/
void ZFXD3D::Prepare2D(void) {
// set matrices to identity
memset(&m_mProj2D, 0, sizeof(float)*16);
memset(&m_mView2D, 0, sizeof(float)*16);
m_mView2D._11 = m_mView2D._33 = m_mView2D._44 = 1.0f;
// orthogonal projection matrix
m_mProj2D._11 = 2.0f/(float)m_dwWidth;
m_mProj2D._22 = 2.0f/(float)m_dwHeight;
m_mProj2D._33 = 1.0f/(m_fFar-m_fNear);
m_mProj2D._43 = -m_fNear*(1.0f/(m_fFar-m_fNear));
m_mProj2D._44 = 1.0f;
// 2D view matrix
float tx, ty, tz;
tx = -((int)m_dwWidth) + m_dwWidth * 0.5f;
ty = m_dwHeight - m_dwHeight * 0.5f;
tz = m_fNear + 0.1f;
m_mView2D._22 = -1.0f;
m_mView2D._41 = tx;
m_mView2D._42 = ty;
m_mView2D._43 = tz;
}// Prepare2D
/*----------------------------------------------------------------*/
/**
* Retrieve active frustrum planes, normals pointing outwards.
* -> IN: ZFXPlane* - address to store 6 planes
*/
HRESULT ZFXD3D::GetFrustrum(ZFXPlane *p) {
// left plane
p[0].m_vcN.x = -(m_mViewProj._14 + m_mViewProj._11);
p[0].m_vcN.y = -(m_mViewProj._24 + m_mViewProj._21);
p[0].m_vcN.z = -(m_mViewProj._34 + m_mViewProj._31);
p[0].m_fD = -(m_mViewProj._44 + m_mViewProj._41);
// right plane
p[1].m_vcN.x = -(m_mViewProj._14 - m_mViewProj._11);
p[1].m_vcN.y = -(m_mViewProj._24 - m_mViewProj._21);
p[1].m_vcN.z = -(m_mViewProj._34 - m_mViewProj._31);
p[1].m_fD = -(m_mViewProj._44 - m_mViewProj._41);
// top plane
p[2].m_vcN.x = -(m_mViewProj._14 - m_mViewProj._12);
p[2].m_vcN.y = -(m_mViewProj._24 - m_mViewProj._22);
p[2].m_vcN.z = -(m_mViewProj._34 - m_mViewProj._32);
p[2].m_fD = -(m_mViewProj._44 - m_mViewProj._42);
// bottom plane
p[3].m_vcN.x = -(m_mViewProj._14 + m_mViewProj._12);
p[3].m_vcN.y = -(m_mViewProj._24 + m_mViewProj._22);
p[3].m_vcN.z = -(m_mViewProj._34 + m_mViewProj._32);
p[3].m_fD = -(m_mViewProj._44 + m_mViewProj._42);
// near plane
p[4].m_vcN.x = -m_mViewProj._13;
p[4].m_vcN.y = -m_mViewProj._23;
p[4].m_vcN.z = -m_mViewProj._33;
p[4].m_fD = -m_mViewProj._43;
// far plane
p[5].m_vcN.x = -(m_mViewProj._14 - m_mViewProj._13);
p[5].m_vcN.y = -(m_mViewProj._24 - m_mViewProj._23);
p[5].m_vcN.z = -(m_mViewProj._34 - m_mViewProj._33);
p[5].m_fD = -(m_mViewProj._44 - m_mViewProj._43);
// normalize frustrum normals
for (int i=0;i<6;i++) {
float fL = p[i].m_vcN.GetLength();
p[i].m_vcN /= fL;
p[i].m_fD /= fL;
}
return ZFX_OK;
}
/*----------------------------------------------------------------*/
/**
* Cast a world ray from a given position on screen.
* -> IN: POINT - point in screen coordinates
* -> OUT: ZFXVector* - to fill with 4 floats for origin vextor
* ZFXVector* - to fill with 4 floats for ray direction
*/
void ZFXD3D::Transform2Dto3D(const POINT &pt,
ZFXVector *vcOrig,
ZFXVector *vcDir) {
D3DMATRIX *pView=NULL, *pProj=NULL;
ZFXMatrix mInvView;
ZFXVector vcS;
DWORD dwWidth,
dwHeight;
// if 2D mode
if (m_Mode == EMD_TWOD) {
dwWidth = m_dwWidth;
dwHeight = m_dwHeight;
pView = &m_mView2D;
}
// else ortho or perspective projection
else {
dwWidth = m_VP[m_nStage].Width,
dwHeight = m_VP[m_nStage].Height;
pView = &m_mView3D;
if (m_Mode == EMD_PERSPECTIVE)
pProj = &m_mProjP[m_nStage];
else
pProj = &m_mProjO[m_nStage];
}
// resize to viewportspace [-1,1] -> projection
vcS.x = ( ((pt.x*2.0f) / dwWidth) -1.0f) / m_mProjP[m_nStage]._11;
vcS.y = -( ((pt.y*2.0f) / dwHeight)-1.0f) / m_mProjP[m_nStage]._22;
vcS.z = 1.0f;
// invert view matrix
mInvView.InverseOf(*((ZFXMatrix*)&m_mView3D._11));
// ray from screen to worldspace
(*vcDir).x = (vcS.x * mInvView._11)
+ (vcS.y * mInvView._21)
+ (vcS.z * mInvView._31);
(*vcDir).y = (vcS.x * mInvView._12)
+ (vcS.y * mInvView._22)
+ (vcS.z * mInvView._32);
(*vcDir).z = (vcS.x * mInvView._13)
+ (vcS.y * mInvView._23)
+ (vcS.z * mInvView._33);
// inverse translation.
(*vcOrig).x = mInvView._41;
(*vcOrig).y = mInvView._42;
(*vcOrig).z = mInvView._43;
// normalize
(*vcOrig).Normalize();
}
/*----------------------------------------------------------------*/
/**
* Cast given point from world space to screen space.
* -> IN: ZFXVector - vector to position in 3d space
* -> RETURN: POINT - corresponding point in 2d screen space
*/
POINT ZFXD3D::Transform3Dto2D(const ZFXVector &vcPoint) {
POINT pt;
float fClip_x, fClip_y;
float fXp, fYp, fWp;
DWORD dwWidth, dwHeight;
// if 2D mode use whole screen
if (m_Mode == EMD_TWOD) {
dwWidth = m_dwWidth;
dwHeight = m_dwHeight;
}
// else take viewport dimensions
else {
dwWidth = m_VP[m_nStage].Width,
dwHeight = m_VP[m_nStage].Height;
}
fClip_x = (float)(dwWidth >> 1);
fClip_y = (float)(dwHeight >> 1);
fXp = (m_mViewProj._11*vcPoint.x) + (m_mViewProj._21*vcPoint.y)
+ (m_mViewProj._31*vcPoint.z) + m_mViewProj._41;
fYp = (m_mViewProj._12*vcPoint.x) + (m_mViewProj._22*vcPoint.y)
+ (m_mViewProj._32*vcPoint.z) + m_mViewProj._42;
fWp = (m_mViewProj._14*vcPoint.x) + (m_mViewProj._24*vcPoint.y)
+ (m_mViewProj._34*vcPoint.z) + m_mViewProj._44;
float fWpInv = 1.0f / fWp;
// transform from [-1,1] to actual viewport dimensions
pt.x = (LONG)( (1.0f + (fXp * fWpInv)) * fClip_x );
pt.y = (LONG)( (1.0f + (fYp * fWpInv)) * fClip_y );
return pt;
}
/*----------------------------------------------------------------*/
/**
* Cast the current cursor position to world coordinates in ortho
* views. User has to take care of third coordinate.
*/
ZFXVector ZFXD3D::Transform2Dto2D(UINT nHwnd, float fScale,
const POINT *pPt, ZFXAXIS axis) {
ZFXVector vcResult(0,0,0);
POINT ptC = { -1, -1 };
RECT rect;
if (!m_d3dpp.Windowed) return vcResult;
else if (m_pChain[nHwnd]==NULL) return vcResult;
GetClientRect(m_hWnd[nHwnd], &rect);
if (!pPt) {
GetCursorPos(&ptC);
ScreenToClient(m_hWnd[nHwnd], &ptC);
}
else memcpy(&ptC, pPt, sizeof(POINT));
ptC.x -= long( ((float)rect.right) /2.0f );
ptC.y -= long( ((float)rect.bottom)/2.0f );
// use buttom for both as horizontal view angle is not known
if (axis == Z_AXIS) {
vcResult.x = ((float)ptC.x)/rect.bottom * fScale;
vcResult.y = -((float)ptC.y)/rect.bottom * fScale;
vcResult.z = 0.0f;
}
else if (axis == X_AXIS) {
vcResult.x = 0.0f;
vcResult.y = -((float)ptC.y)/rect.bottom * fScale;
vcResult.z = ((float)ptC.x)/rect.bottom * fScale;
}
else if (axis == Y_AXIS) {
vcResult.x = ((float)ptC.x)/rect.bottom * fScale;
vcResult.y = 0.0f;
vcResult.z = -((float)ptC.y)/rect.bottom * fScale;
}
return vcResult;
} // Transform2Dto2D
/*----------------------------------------------------------------*/
/**
* This functions evaluates shader support and initializes everything
* we need to use shaders if they are available.
*/
void ZFXD3D::PrepareShaderStuff(void) {
D3DCAPS9 d3dCaps;
if (FAILED(m_pDevice->GetDeviceCaps(&d3dCaps))) {
Log("error: GetDeviceCaps() in PrepareShaderStuff failed");
m_bCanDoShaders = false;
return;
}
if (d3dCaps.VertexShaderVersion < D3DVS_VERSION(1,1) ) {
Log("warning: Vertex Shader Version < 1.1 => no support");
m_bCanDoShaders = false;
return;
}
if (d3dCaps.PixelShaderVersion < D3DPS_VERSION(1,1) ) {
Log("warning: Pixel Shader Version < 1.1 => no support");
m_bCanDoShaders = false;
return;
}
// vertex declarations needed for shaders
D3DVERTEXELEMENT9 declPVertex[] =
{
{ 0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
D3DDECL_END()
};
D3DVERTEXELEMENT9 declVertex[] =
{
{ 0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
{ 0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL, 0},
{ 0, 24, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
D3DDECL_END()
};
D3DVERTEXELEMENT9 declLVertex[] =
{
{ 0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
{ 0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
{ 0, 16, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
D3DDECL_END()
};
D3DVERTEXELEMENT9 declCVertex[] =
{
{ 0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
{ 0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL, 0},
{ 0, 24, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
{ 0, 32, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
D3DDECL_END()
};
D3DVERTEXELEMENT9 decl3TVertex[] =
{
{ 0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
{ 0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL, 0},
{ 0, 24, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
{ 0, 32, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
{ 0, 40, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 2},
D3DDECL_END()
};
D3DVERTEXELEMENT9 declTVertex[] =
{
{ 0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
{ 0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL, 0},
{ 0, 24, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
{ 0, 32, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TANGENT, 0},
D3DDECL_END()
};
// create the declarations
m_pDevice->CreateVertexDeclaration(declVertex, &m_pDeclVertex);
m_pDevice->CreateVertexDeclaration(declPVertex, &m_pDeclPVertex);
m_pDevice->CreateVertexDeclaration(declLVertex, &m_pDeclLVertex);
m_pDevice->CreateVertexDeclaration(declCVertex, &m_pDeclCVertex);
m_pDevice->CreateVertexDeclaration(decl3TVertex, &m_pDecl3TVertex);
m_pDevice->CreateVertexDeclaration(declTVertex, &m_pDeclTVertex);
m_pDevice->SetFVF(NULL);
m_bCanDoShaders = true;
Log("use of shaders activated (VS 1.1, PS 1.1)");
} // PrepareShaderStuff
/*----------------------------------------------------------------*/
/**
* Switch use of shaders on and off if shaders are possible.
*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -