이 모델 확대와 축소를 이용하면,, 폭발하는듯한 애니메이션을 만드는데 응용이 가능하다
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 VertexBuffer _xyzLineBuffer = null;
private Vector3 _scale = new Vector3(1.0f, 1.0f, 1.0f);
public bool InitializeApplication(MainForm topLevelForm)
{
// 폼의 참조를 보관 유지
this._form = topLevelForm;
PresentParameters pp = new PresentParameters();
try
{
// Direct3D 디바이스 작성
this.CreateDevice(topLevelForm, pp);
// 폰트의 작성
this.CreateFont();
}
catch (DirectXException ex)
{
// 예외 발생
MessageBox.Show(ex.ToString(), "에러", MessageBoxButtons.OK, MessageBoxIcon.Error);
return false;
}
LoadXfile("01.x"); // 라이트까지 세팅되어있다.
createXYZLine();
this._device.RenderState.NormalizeNormals = true;
return true;
}
/// <summary>
/// 메인 루프 처리
/// </summary>
public void MainLoop()
{
this.SettingCamera();
if (this._keys[(int)Keys.Left])
{
this._scale.X /= 1.01f;
}
if (this._keys[(int)Keys.Right])
{
this._scale.X *= 1.01f;
}
if (this._keys[(int)Keys.Up])
{
this._scale.Y /= 1.01f;
}
if (this._keys[(int)Keys.Down])
{
this._scale.Y *= 1.01f;
}
// 화면을 단색(파랑색)으로 클리어
this._device.Clear(ClearFlags.Target | ClearFlags.ZBuffer, Color.DarkBlue, 1.0f, 0);
// 「BeginScene」와「EndScene」의 사이에 화면에 출력할 내용을 코딩
this._device.BeginScene();
this.RenderXYZ();
this._device.RenderState.Lighting = true;
this._device.SetTransform(TransformType.World, Matrix.Scaling(this._scale));
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();
}
private void form_MouseMove(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
this._lensPosTheta -= e.Location.X - this._oldMousePoint.X;
this._lensPosPhi += e.Location.Y - this._oldMousePoint.Y;
}
this._oldMousePoint = e.Location;
}
/// <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 _scale = new Vector3(1.0f, 1.0f, 1.0f);
XYZ방향으로 모델을 확대하기 위해, Vector3 파라미터를 준비한다.
확대축소의 값은 원형의 배율이니 1.0으로 초기화한다. Vector3.Empty로 지정해버리면 모델이 표시가 되지 않으니 주의해주세요
this._device.RenderState.NormalizeNormals = true;
모델을 확대하면 법선의 계산이 바뀌니까 좌표변화 이후 법선을 정규화하도록 지정한다.
if (this._keys[(int)Keys.Left])
{
this._scale.X /= 1.01f;
}
if (this._keys[(int)Keys.Right])
{
this._scale.X *= 1.01f;
}
if (this._keys[(int)Keys.Up])
{
this._scale.Y /= 1.01f;
}
if (this._keys[(int)Keys.Down])
{
this._scale.Y *= 1.01f;
}
모델의 확대와 축소가 자연스럽게 보이도록, 원래의 값에 1.01을 곱하거나 나누고있어요
더하거나 빼면 커지고작아지는게 무지하게 빨라져요
this._device.RenderState.Lighting = true;
this._device.SetTransform(TransformType.World, Matrix.Scaling(this._scale));
this.RenderMesh();
이번 확대 축소에 사용되는 메서드는 Matrix.Scaling
값을 세트한 Vector3을 건네주면 그대로 확대 축소합니다
메쉬그리고하는건 17강이랑 똑같으니까 생각안나면 17강을 참고하세요
Matrix.Scaling 메서드 동작방법
Matrix.Scaling은 건네받은 값을 아래와 같은 매트릭스로 변환하고 있습니다
사실 이것만봐서는 잘 모르겠죠?
그럼 다각형을 이용해서 설명해볼테니 이해해봅시다
이번에는 다각형의 배율을(1.5, 1.0, 2.0)으로 합니다.
이 그림 역시 Y축에서 아래를 내려다 본 그림
위 그림의 0번 정점을 먼저 계산해봅시다
나머지 정점은 다음과 같은 결과가 나온다
0번 정점 : (-1.5, 0, 2)
1번 정점 : (3, 0, 2)
2번 정점 : (-1.5, 0, -2)
3번 정점 : (3, 0, -2)
요로코롬 된다는거죠
'Graphics > DirectX' 카테고리의 다른 글
Direct X - 기초용어와 이론 (0) | 2014.06.19 |
---|---|
Direct X - 19. 모델의 이동, 회전, 확대, 축소 (0) | 2014.06.09 |
Direct X - 17. 키보드와 마우스를 이용한 모델 이동 (0) | 2014.06.09 |
Direct X - 16. X, Y, Z 좌표 그려넣기 (0) | 2014.06.09 |
Direct X - 15. 모델 데이터 불러오기 (.x 파일) (0) | 2014.06.09 |