0
\$\begingroup\$

I had a lot of problems to draw a line in a 3D and had a weird results.. The 3D Lines are projects in 2D and that's so weird. They only work with that view matrix configuration:

XMVECTOR Eye = XMVectorSet(0.0f, 3.0f, -6.0f, 0.0f);
XMVECTOR At = XMVectorSet(0.0f, 1.0f, 0.0f, 0.0f);
XMVECTOR Up = XMVectorSet(0.0f, 1.0f, 0.0f, 0.0f);
XMMATRIX g_View = XMMatrixLookAtLH(Eye, At, Up);


basicEffect->SetView(g_View);

but when I use my camera view matrix they get projected in 2D.. however I have my terrain rendered correctly and other things..

Here is my Camera class:

void cCamera::Initialize()
{
Reset();
}


void cCamera::Reset()
{
// config for left hand camera system
m_Position = XMFLOAT3(0.0f, 0.0f, 0.0f);
m_Forward = XMFLOAT3(0.0f, 0.0f, 1.0f);
m_Up = XMFLOAT3(0.0f, 1.0f, 0.0f);
m_Right = XMFLOAT3(1.0f, 0.0f, 0.0f);

UpdateViewMatrix();
}

const XMFLOAT3& cCamera::Position() const
{
return m_Position;
}

const XMFLOAT3& cCamera::Forward() const
{
return m_Forward;
}

const XMFLOAT3& cCamera::Up() const
{
return m_Up;
}

const XMFLOAT3& cCamera::Right() const
{
return m_Right;
}

float cCamera::AspectRatio() const
{
return m_AspectRatio;
}

float cCamera::FieldOfView() const
{
return m_FieldOfView;
}

float cCamera::NearPlaneDistance() const
{
return m_NearPlaneDistance;
}

float cCamera::FarPlaneDistance() const
{
return m_FarPlaneDistance;
}

XMMATRIX cCamera::ViewMatrix()
{
return XMLoadFloat4x4(&m_ViewMatrix);
}

XMMATRIX cCamera::ProjectionMatrix()
{
return XMLoadFloat4x4(&m_ProjectionMatrix);
}

XMMATRIX cCamera::ViewProjectionMatrix()
{
XMMATRIX viewMatrix = XMLoadFloat4x4(&m_ViewMatrix);
XMMATRIX projectionMatrix = XMLoadFloat4x4(&m_ProjectionMatrix);

return XMMatrixMultiply(viewMatrix, projectionMatrix);
}


void cCamera::SetPosition(const XMFLOAT3& position)
{
m_Position = position;
}

void cCamera::SetPerspective(float fov, float aspect, float nearPlane, float farPlane)
{
m_FieldOfView = fov;
m_AspectRatio = aspect;
m_NearPlaneDistance = nearPlane;
m_FarPlaneDistance = farPlane;

XMMATRIX projectionMatrix = XMMatrixPerspectiveFovLH(m_FieldOfView, m_AspectRatio, m_NearPlaneDistance, m_FarPlaneDistance);
XMStoreFloat4x4(&m_ProjectionMatrix, projectionMatrix);
}
void cCamera::SetOrthographic(float viewWidth, float viewHeight, float zn, float zf)
{
XMMATRIX projectionMatrix = XMMatrixOrthographicLH(viewWidth, viewHeight, zn, zf);
XMStoreFloat4x4(&m_ProjectionMatrix, projectionMatrix);
}
void cCamera::LookAt(const XMVECTOR &target)
{
XMVECTOR p = XMLoadFloat3(&m_Position);
XMVECTOR look = target - p;
XMStoreFloat3(&m_Forward, look);
}

void cCamera::UpdateViewMatrix()
{
XMVECTOR eyePosition = XMLoadFloat3(&m_Position);
XMVECTOR direction = XMLoadFloat3(&m_Forward);
XMVECTOR upDirection = XMLoadFloat3(&m_Up);

XMMATRIX viewMatrix = XMMatrixLookToLH(eyePosition, direction, upDirection);
XMStoreFloat4x4(&m_ViewMatrix, viewMatrix);
}


void cCamera::Update(float dt)
{
if (GetAsyncKeyState('W') & 0x8000)
    Walk(45 * dt);

if (GetAsyncKeyState('S') & 0x8000)
    Walk(-45 * dt);

if (GetAsyncKeyState('A') & 0x8000)
    Strafe(-45 * dt);

if (GetAsyncKeyState('D') & 0x8000)
    Strafe(45 * dt);

if (GetAsyncKeyState('Z') & 0x8000)
    MoveUp(-45 * dt);

if (GetAsyncKeyState('X') & 0x8000)
    MoveUp(45 * dt);

UpdateViewMatrix();
}

void cCamera::MoveUp(float d)
{
// mPosition += d*Up
XMVECTOR s = XMVectorReplicate(d);
XMVECTOR u = XMLoadFloat3(&m_Up);
XMVECTOR p = XMLoadFloat3(&m_Position);
XMStoreFloat3(&m_Position, XMVectorMultiplyAdd(s, u, p));
}

void cCamera::Strafe(float d)
{
// mPosition += d*Right
XMVECTOR s = XMVectorReplicate(d);
XMVECTOR r = XMLoadFloat3(&m_Right);
XMVECTOR p = XMLoadFloat3(&m_Position);
XMStoreFloat3(&m_Position, XMVectorMultiplyAdd(s, r, p));
}

void cCamera::Walk(float d)
{
// mPosition += d*Forward
XMVECTOR s = XMVectorReplicate(d);
XMVECTOR l = XMLoadFloat3(&m_Forward);
XMVECTOR p = XMLoadFloat3(&m_Position);
XMStoreFloat3(&m_Position, XMVectorMultiplyAdd(s, l, p));
}

void cCamera::Pitch(float angle)
{
// Rotate up and forward vector about the right vector.

XMMATRIX R = XMMatrixRotationAxis(XMLoadFloat3(&m_Right), angle);

XMStoreFloat3(&m_Up, XMVector3TransformNormal(XMLoadFloat3(&m_Up), R));
XMStoreFloat3(&m_Forward, XMVector3TransformNormal(XMLoadFloat3(&m_Forward), R));
}

void cCamera::RotateY(float angle)
{
// Rotate the basis vectors about the world y-axis.

XMMATRIX R = XMMatrixRotationY(angle);

XMStoreFloat3(&m_Right, XMVector3TransformNormal(XMLoadFloat3(&m_Right), R));
XMStoreFloat3(&m_Up, XMVector3TransformNormal(XMLoadFloat3(&m_Up), R));
XMStoreFloat3(&m_Forward, XMVector3TransformNormal(XMLoadFloat3(&m_Forward), R));
}

That's the result of a drawing a line in 3D Cords

enter image description here

\$\endgroup\$
  • \$\begingroup\$ What do you mean by "The 3D Lines are projects in 2D and that's so weird"? How is the rendered line you showed not correct? \$\endgroup\$ – Jannie Dec 11 '14 at 8:48
  • 1
    \$\begingroup\$ i think he means that the line looks to be renderd in 2d. If you render a line in 3d it will look 2d, because there is nothing to define it, there is no width in it, you would have to render a thicker line to get any sort of 3d illusions with it. imagine looking straight trough the line, you would not see anything because it´s just one pixel wide. \$\endgroup\$ – Tordin Dec 11 '14 at 9:01
  • \$\begingroup\$ I'm trying to render wireframe lines(grid) or any other lines of a wireframe box, the result is just lines with no depth at all. \$\endgroup\$ – Ahmed Saleh Dec 11 '14 at 9:02
  • \$\begingroup\$ @Tordin The problem is when I let the shader use the view matrix that I showed above, it work very correctly(I tested it by rendering a grid of lines), but when I use my own camera view matrix, the result is a line that is rendered in 2D \$\endgroup\$ – Ahmed Saleh Dec 11 '14 at 9:03
  • \$\begingroup\$ code.msdn.microsoft.com/DirectXTK-Simple-Win32-23db418a The At and Up is copied from the above sample which uses a grid of lines and they are rendered correctly :S \$\endgroup\$ – Ahmed Saleh Dec 11 '14 at 11:30
1
\$\begingroup\$

Your problem is the difference between XMMatrixLookToLH and XMMatrixLookAtLH.

The DirectX TK SimpleSample is using XMMatrixLookAtLH which is computing:

XMVECTOR Eye = XMVectorSet(0.0f, 3.0f, -6.0f, 0.0f);
XMVECTOR At = XMVectorSet(0.0f, 1.0f, 0.0f, 0.0f);
XMVECTOR Up = XMVectorSet(0.0f, 1.0f, 0.0f, 0.0f);
XMMATRIX g_View = XMMatrixLookAtLH(Eye, At, Up);

Here "At" is the position 0, 1, 0 and is used as the focus position (i.e. it computes the eye direction from Eye and At).

Your camera code is using XMMatrixLookToLH, which is failing to get the right result because you are passing (0,1,0) as the EyeDirection and UpDirection which naturally fails.

\$\endgroup\$
  • \$\begingroup\$ If I want to use XMMatrixLookToLH what should I change? \$\endgroup\$ – Ahmed Saleh Dec 13 '14 at 0:58
  • \$\begingroup\$ Set At to (0,0,1). \$\endgroup\$ – Chuck Walbourn Dec 13 '14 at 6:27

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.