이것역시 크게 다를건 없다
기억이 안나면 키보드처리하는 9강을 참고하자,,
using System;
using Microsoft.DirectX;
using Microsoft.DirectX.Direct3D;
using System.Windows.Forms;
using System.Drawing;
namespace MDXSample
{
/// <summary>
/// 메인 샘플 클래스
/// </summary>
public partial class MainSample : IDisposable
{
/// <summary>
/// 정점 버퍼
/// </summary>
///
private Vector3 _trans = Vector3.Empty;
public bool InitializeApplication(MainForm topLevelForm)
{
// 폼의 참조를 보관 유지
this._form = topLevelForm;
PresentParameters pp = new PresentParameters();
pp.Windowed = true;
pp.SwapEffect = SwapEffect.Discard;
pp.EnableAutoDepthStencil = true;
pp.AutoDepthStencilFormat = DepthFormat.D16;
topLevelForm.MouseMove += new MouseEventHandler(this.form_MouseMove);
topLevelForm.KeyDown += new KeyEventHandler(this.form_KeyDown);
topLevelForm.KeyUp += new KeyEventHandler(this.form_KeyUp);
try
{
// Direct3D 디바이스 작성
this.CreateDevice(topLevelForm, pp);
// 폰트의 작성
this.CreateFont();
}
catch (DirectXException ex)
{
// 예외 발생
MessageBox.Show(ex.ToString(), "에러", MessageBoxButtons.OK, MessageBoxIcon.Error);
return false;
}
LoadXfile("01.x"); // 라이트까지 세팅되어있다.
return true;
}
/// <summary>
/// 메인 루프 처리
/// </summary>
public void MainLoop()
{
this.SettingCamera();
if (this._keys[(int)Keys.Left])
{
this._trans.X -= 0.3f;
}
if (this._keys[(int)Keys.Right])
{
this._trans.X += 0.3f;
}
if (this._keys[(int)Keys.Down])
{
this._trans.Y -= 0.3f;
}
if (this._keys[(int)Keys.Up])
{
this._trans.Y += 0.3f;
}
// 화면을 단색(파랑색)으로 클리어
this._device.Clear(ClearFlags.Target | ClearFlags.ZBuffer, Color.DarkBlue, 1.0f, 0);
// 「BeginScene」와「EndScene」의 사이에 화면에 출력할 내용을 코딩
this._device.BeginScene();
this._device.RenderState.Lighting = false;
this._device.SetTransform(TransformType.World, Matrix.Identity);
this._device.RenderState.Lighting = true;
this._device.SetTransform(TransformType.World, Matrix.Translation(this._trans));
this.RenderMesh();
this._font.DrawText(null, "θ:" + this._lensPosTheta, 0, 0, Color.White);
this._font.DrawText(null, "φ:" + this._lensPosPhi, 0, 12, Color.White);
this._font.DrawText(null, "마우스 위치:" + this._oldMousePoint, 0, 24, Color.White);
// 화면출력은 여기까지
this._device.EndScene();
// 실제의 디스플레이에 출력
this._device.Present();
}
/// <summary>
/// 자원의 파기
/// </summary>
public void Dispose()
{
if (this._textures != null)
{
foreach (Texture i in this._textures)
{
if (i != null)
{
i.Dispose();
}
}
}
if (this._mesh != null)
{
this._mesh.Dispose();
}
// 폰트 자원을 해제
if (this._font != null)
{
this._font.Dispose();
}
// Direct3D 디바이스의 자원 해제
if (this._device != null)
{
this._device.Dispose();
}
}
}
}
private Vector3 _trans = Vector3.Empty;
모델의 위치정보 저장, Vector3은 그대로 X, Y, Z의 값을 가지기 때문에, 3D공간의 임의의 위치에 배치 할 경우에 잘 적용된다
월드 좌표변화를 사용할건데, 초기 위치는 원점에 둘거니까 Empty로
if (this._keys[(int)Keys.Left])
{
this._trans.X -= 0.3f;
}
if (this._keys[(int)Keys.Right])
{
this._trans.X += 0.3f;
}
if (this._keys[(int)Keys.Down])
{
this._trans.Y -= 0.3f;
}
if (this._keys[(int)Keys.Up])
{
this._trans.Y += 0.3f;
}
키값 정의하는거는 9강에 있다,, 기억이 안나면 거기부터 일단 참고하시고요
this._device.RenderState.Lighting = false;
this._device.SetTransform(TransformType.World, Matrix.Identity);
모델을 3D 공간상에 배치하려면 이 메서드의 제 1 인수에 TransformType.World를 써주면 된다, 그리고 제 2 인수에 위치정보를 변환한 Matrix를 건네주면 끗
이것이 바로 월드 좌표변화
모델의 위치계산을 이 메서드로 하고나서 그대로 XYZ라인을 그려버리면 원점에 배치해야될 X, Y, Z라인이 모델의 위치에 중복되서 그려지는 현상이 생긴다(그래서 전 강의에서 한 XYZ라인 그리는 메서드를 지워버렸어, 이러면 이 두줄 안써도 그만)
그래서 XYZ라인 그리기 전에 Matrix.Identity를 하는 것
[1,0,0,0]
Matrix.Identity = [0,1,0,0]
[0,0,1,0]
[0,0,0,1]
DX는 기본적으로 4x4 매트릭스를 쓴다
this._device.RenderState.Lighting = true;
this._device.SetTransform(TransformType.World, Matrix.Translation(this._trans));
모델을 이동시키는 코드는 딱 요 한줄로 해결이 되는거야
방금과 다른건 제 2 인수의 파라미터가 다르지요?
모델을 지정 위치로 이동시키려면, Matrix.Translation메서드를 사용하면 된다,
요 상태로 모델을 출력하면 그 위치에 그리게 할 수 있다! 메쉬가 아니더라도 상관없다
요렇게 하면 되는데,,, 이게 왜 이렇게 이동되는지 우리 원리를 알아봅시다
Matrix.Translation 메서드는 아래와 같은 계산식으로 위치 벡터를 매트릭스 위에 옮겨놓구있엉, 여기에서는 위치 벡터를 (1.0, 0.0, 2.0)으로 할 것입니다
이 매트릭스로 모델이 어떻게 이동하는지 보자
아래같은 다각형이 있다구 치고, 바로 위(Y방향)에서 원점방향을 보고있다고 생각하시고
상하가 Z, 좌우가 X ㅇㅋ?... DX는 왼손좌표계를 쓰니까요
최초로 0번 정점을 보자(-1,0,1), 정점의 위치와 작성된 매트릭스를 아래와 같은 차례로 곱해, 곱하는 순서는 정해져있다! 이동용 위치 벡터는 (1.0, 0.0, 2.0) 위의 매트릭스 공식으로 xyz를 적용해보자, 소수점은 생략
정점의 위치가 4차원 벡터가 되어있지요? 이거는 그냥 매트릭스랑 곱하기 위해서 추가한거라구 생각해주시고요, 4x4랑 3차원 매트릭스는 곱할수없지요?
네번째 파라미터가 1이 되는건, 뭘 곱해도 그 숫자가 나오게 하기 위해서 입니다
이동용 위치 벡터행렬의 맨 아래 (1, 0, 2)가 바로 이동벡터
그럼 계산을 해보자
0번째 점 : (-1, 0, 1, 1) + (1, 0, 2, 1) = (0, 0, 3)
1번째 점 : (2, 0, 1, 1) + (1, 0, 2, 1) = (3, 0, 3)
2번째 점 : (-1, 0, -1, 1) + (1, 0, 2, 1) = (0, 0, 1)
3번째 점 : (2, 0, -1, 1) + (1, 0, 2, 1) = (3, 0, 1)
이해하기 쉬우라고, (x, y, z, 1) 이야
지금 보는 시점은 Y축에서 원점을 내려다보는 형태
그래서 y가 지금 0,, 그리구 Z가 상하좌표, X가 좌우좌표.. 아시겠지유?
끗
'Graphics > DirectX' 카테고리의 다른 글
Direct X - 19. 모델의 이동, 회전, 확대, 축소 (0) | 2014.06.09 |
---|---|
Direct X - 18. 모델 확대와 축소 (0) | 2014.06.09 |
Direct X - 16. X, Y, Z 좌표 그려넣기 (0) | 2014.06.09 |
Direct X - 15. 모델 데이터 불러오기 (.x 파일) (0) | 2014.06.09 |
Direct X - 14. 조명효과 사용하기 (0) | 2014.06.09 |