I try apply software rendering to draw simple cube. I have matrix World, View, Projection:
My3DMatrix4x4 mWorld(
1, 0, 0, 0,
0, 1, 0, 0,
0, 0, 1, 0,
0, 0, 0, 1);
My3DMatrix4x4 mView = m_pCamera->GetViewMatrix();
float fFov = 3.1415926f/4.0f;
float fAspect = 4.0f/3.0f;
float fZFar = 500.0;
float fZNear = 5.0f;
float h, w, Q;
w = (1.0f/tan(fFov*0.5f))/fAspect;
h = 1.0f/tan(fFov*0.5f);
Q = fZFar/(fZFar - fZNear);
My3DMatrix4x4 mProj(
w, 0, 0, 0,
0, h, 0, 0,
0, 0, Q, 1,
0, 0, -Q*fZNear, 0);
Then I muptiply all this matrix and multiply all vert of my cube on this result matrix. For multiplication matrix I use DirectX func, and for vertices I use DirectX func D3DXTransformNormal(). Also my camera class use DirectX func for calculation and under original DirectX program my camera class works fine. In normal state my program rendering 3D cube.
Problem appears when I move camera closer to cube and try rotate camera left, right, up, down - error occur when angle > 45 degree. When I have distant from cube and rotate camera - all fine. But when I move camera closer to cube and try rotate it more then 45 degree - program fault. Sorry my English.
This is screenshot #1 when I rotate cube left:
This is scrennshot #2 when cube had rotatet more that 45 degree:
Also I am use back face culling and frustum clipping (its works fine in my native DirectX program).
My camera class works fine in native DirectX program:
void CFirstPersonCamera::FrameMove(float fTime, int delta)
{
POINT mousePos;
GetCursorPos(&mousePos);
SetCursorPos(nScreenWidth/2, nScreenHeight/2);
int nDeltaX=nScreenWidth/2-mousePos.x;
int nDeltaY=nScreenHeight/2-mousePos.y;
float m_fRotationScalerX = 0.04f;
float m_fRotationScalerY = 0.04f;
/*
if(nDeltaY<0) m_fRotationScalerY = m_fRotationScalerY;
else if(nDeltaY>0) m_fRotationScalerY = -m_fRotationScalerY;
else if(nDeltaY==0) m_fRotationScalerY = 0;
My3DMatrix4x4 matRotRight = My3DMatrixRotationAxis(vRight , m_fRotationScalerY);
//My3DMatrix4x4 matRotY = My3DMatrixRotationX(m_fRotationScalerY);
vRight = My3DVec3TransformNormal(vRight, matRotRight);
vUp = My3DVec3TransformNormal(vUp, matRotRight);
vLook = My3DVec3TransformNormal(vLook, matRotRight);
*/
if(nDeltaX<0) m_fRotationScalerX = m_fRotationScalerX;
else if(nDeltaX>0) m_fRotationScalerX = -m_fRotationScalerX;
else if(nDeltaX==0) m_fRotationScalerX = 0;
/*
//My3DVector3 vUpTemp = My3DVector3( 0.0f, 1.0f, 0.0f );
//My3DMatrix4x4 matRotUp = My3DMatrixRotationAxis(vUpTemp , m_fRotationScalerX);
My3DMatrix4x4 matRotUp = My3DMatrixRotationY(m_fRotationScalerX);
vRight = My3DVec3TransformNormal(vRight, matRotUp);
vUp = My3DVec3TransformNormal(vUp, matRotUp);
vLook = My3DVec3TransformNormal(vLook, matRotUp);
*/
D3DXMATRIX matRotUp;
D3DXMatrixRotationY(&matRotUp, m_fRotationScalerX);
D3DXVECTOR3 vR, vU, vL;
vR = D3DXVECTOR3(vRight.x, vRight.y, vRight.z);
vU = D3DXVECTOR3(vUp.x, vUp.y, vUp.z);
vL = D3DXVECTOR3(vLook.x, vLook.y, vLook.z);
D3DXVECTOR3 vOutR, vOutU, vOutL;
D3DXVec3TransformNormal(&vOutR, &vR, &matRotUp);
D3DXVec3TransformNormal(&vOutU, &vU, &matRotUp);
D3DXVec3TransformNormal(&vOutL, &vL, &matRotUp);
vRight = My3DVector3(vOutR.x, vOutR.y, vOutR.z);
vUp = My3DVector3(vOutU.x, vOutU.y, vOutU.z);
vLook = My3DVector3(vOutL.x, vOutL.y, vOutL.z);
float ratioMove = 150;
My3DVector3 temp = My3DVector3(0,0,0);;
My3DVector3 vAccel = My3DVector3(0,0,0);
if(GetAsyncKeyState('W')& 0xFF00)
{
temp = My3DVector3(vLook.x,0,vLook.z);
temp = My3DVec3Dot(temp, ratioMove);
vAccel = My3DVec3Dot(temp, fTime);
vAccel.y = 0.0;
}
if(GetAsyncKeyState('S')& 0xFF00)
{
temp = My3DVector3(vLook.x,0,vLook.z);
temp = My3DVec3Dot(temp, -ratioMove);
vAccel = My3DVec3Dot(temp, fTime);
}
if(GetAsyncKeyState('D')& 0xFF00)
{
temp = My3DVector3(vRight.x,0,vRight.z);
temp = My3DVec3Dot(temp, ratioMove);
vAccel = My3DVec3Dot(temp, fTime);
}
if(GetAsyncKeyState('A')& 0xFF00)
{
temp = My3DVector3(vRight.x,0,vRight.z);
temp = My3DVec3Dot(temp, -ratioMove);
vAccel = My3DVec3Dot(temp, fTime);
}
vAccel.y = 0.0;
vPos = My3DVec3Add(vPos,vAccel);
vRight = My3DVec3Normalize(vRight);
vLook = My3DVec3Normalize(vLook);
vUp = My3DVec3Cross(vLook,vRight);
vUp = My3DVec3Normalize(vUp);
vRight = My3DVec3Cross(vUp,vLook);
vRight = My3DVec3Normalize(vRight);
matView.r1c1 = vRight.x;
matView.r2c1 = vRight.y;
matView.r3c1 = vRight.z;
matView.r1c2 = vUp.x;
matView.r2c2 = vUp.y;
matView.r3c2 = vUp.z;
matView.r1c3 = vLook.x;
matView.r2c3 = vLook.y;
matView.r3c3 = vLook.z;
matView.r1c4 = 0.0;
matView.r2c4 = 0.0;
matView.r3c4 = 0.0;
matView.r4c1 =- My3DVec3Dot( vPos, vRight );
matView.r4c2 =- My3DVec3Dot( vPos, vUp );
matView.r4c3 =- My3DVec3Dot( vPos, vLook );
matView.r4c4 = 1.0;
}
My3DMatrix4x4 mRes(
1, 0, 0, 0,
0, 1, 0, 0,
0, 0, 1, 0,
0, 0, 0, 1);
mRes = My3DMatrixMultiply(mRes, mView);
mRes = My3DMatrixMultiply(mRes, mProj);
for( int i = 0; i < 12; i++)
{
pMy3DTriangle_Transformed.v1.tu = pMy3DTriangle_Original.v1.tu;
pMy3DTriangle_Transformed.v1.tv = pMy3DTriangle_Original.v1.tv;
pMy3DTriangle_Transformed.v2.tu = pMy3DTriangle_Original.v2.tu;
pMy3DTriangle_Transformed.v2.tv = pMy3DTriangle_Original.v2.tv;
pMy3DTriangle_Transformed.v3.tu = pMy3DTriangle_Original.v3.tu;
pMy3DTriangle_Transformed.v3.tv = pMy3DTriangle_Original.v3.tv;
D3DXMATRIX mResDX = D3DXMATRIX(mRes.r1c1, mRes.r1c2,mRes.r1c3,mRes.r1c4,
mRes.r2c1, mRes.r2c2,mRes.r2c3,mRes.r2c4,
mRes.r3c1, mRes.r3c2,mRes.r3c3,mRes.r3c4,
mRes.r4c1, mRes.r4c2,mRes.r4c3,mRes.r4c4);
D3DXVECTOR3 vt1 = D3DXVECTOR3(pMy3DTriangle_Original.v1.x, pMy3DTriangle_Original.v1.y, pMy3DTriangle_Original.v1.z);
D3DXVECTOR3 vt1_Out;
D3DXVec3TransformNormal(&vt1_Out, &vt1, &mResDX);
D3DXVECTOR3 vt2 = D3DXVECTOR3(pMy3DTriangle_Original.v2.x, pMy3DTriangle_Original.v2.y, pMy3DTriangle_Original.v2.z);
D3DXVECTOR3 vt2_Out;
D3DXVec3TransformNormal(&vt2_Out, &vt2, &mResDX);
D3DXVECTOR3 vt3 = D3DXVECTOR3(pMy3DTriangle_Original.v3.x, pMy3DTriangle_Original.v3.y, pMy3DTriangle_Original.v3.z);
D3DXVECTOR3 vt3_Out;
D3DXVec3TransformNormal(&vt3_Out, &vt3, &mResDX);
pMy3DTriangle_Transformed.v1.x = vt1_Out.x / vt1_Out.z;
pMy3DTriangle_Transformed.v1.y = vt1_Out.y / vt1_Out.z;
pMy3DTriangle_Transformed.v1.z = vt1_Out.z;
pMy3DTriangle_Transformed.v2.x = vt2_Out.x / vt2_Out.z;
pMy3DTriangle_Transformed.v2.y = vt2_Out.y / vt2_Out.z;
pMy3DTriangle_Transformed.v2.z = vt2_Out.z;
pMy3DTriangle_Transformed.v3.x = vt3_Out.x / vt3_Out.z;
pMy3DTriangle_Transformed.v3.y = vt3_Out.y / vt3_Out.z;
pMy3DTriangle_Transformed.v3.z = vt3_Out.z;
}
Please assist me. Thanks in advance.