Graphics/DirectX

Direct X - 8. 3D 사각형 출력

MOLOKINI 2014. 6. 8. 20:52
사각형은 자주 사용하니까 연습을 해두는게 좋다고한다.

하지만 이 DirectX 에서는 그렇지 않다.
꼭지점이 여섯개인 도형이다, 무슨말이냐
삼각형 두개를 합친겁니다.
 
그렇다구 정점 수를 여섯개로 하느냐? 그건 또 아닙니다.
4강에서 했던 메서드 PrimitiveType.TriangleStrip 이것으로 하면 4개의 정점만으로 삼각형 두개를 붙인 효과, 즉 사각형을 만들어내는 효과를 낼 수 있지요
 

 

정점의 인덱스는 위 그림과 같은데, 항상 정해져 있는거니까 이 차례는 신경써야합니다, 그렇지 않으면 모양이 흐트러진다

 

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 _vertexBuffer = null;


        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;

            try
            {
                // Direct3D 디바이스 작성
                this.CreateDevice(topLevelForm, pp);
                // 폰트의 작성
                this.CreateFont();

            }
            catch (DirectXException ex)
            {
                // 예외 발생
                MessageBox.Show(ex.ToString(), "에러", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return false;
            }

            this.SettingCamera();

            // 사각형 다각형을 표시하기 위한 정점 버퍼를 작성
            this._vertexBuffer = new VertexBuffer(typeof(CustomVertex.PositionColored),
                4, this._device, Usage.None, CustomVertex.PositionColored.Format, Pool.Managed);

            // 4점의 정보를 보관하기 위한 메모리를 확보
            CustomVertex.PositionColored[] vertices = new CustomVertex.PositionColored[4];

            // 각 정점을 설정
            vertices[0] = new CustomVertex.PositionColored(-4.0f, 4.0f, 0.0f, Color.Red.ToArgb());
            vertices[1] = new CustomVertex.PositionColored(4.0f, 4.0f, 0.0f, Color.Blue.ToArgb());
            vertices[2] = new CustomVertex.PositionColored(-4.0f, -4.0f, 0.0f, Color.Green.ToArgb());
            vertices[3] = new CustomVertex.PositionColored(4.0f, -4.0f, 0.0f, Color.Yellow.ToArgb());

            // 정점 버퍼를 잠근다
            using (GraphicsStream data = this._vertexBuffer.Lock(0, 0, LockFlags.None))
            {
                // 정점 데이터를 정점 버퍼에 씁니다
                data.Write(vertices);
 
                // 정점 버퍼의 락을 해제합니다
                this._vertexBuffer.Unlock();
            }

            this._device.RenderState.Lighting = false;

            return true;
        }
 
        /// <summary>
        /// 메인 루프 처리
        /// </summary>
        public void MainLoop()
        {
            // 화면을 단색(파랑색)으로 클리어
            this._device.Clear(ClearFlags.Target | ClearFlags.ZBuffer, Color.DarkBlue, 1.0f, 0);

            // 「BeginScene」와「EndScene」의 사이에 화면에 출력할 내용을 코딩
            this._device.BeginScene();

            // 정점 버퍼를 디바이스의 데이터 스트림에 바인드
            this._device.SetStreamSource(0, this._vertexBuffer, 0);
 
            // 그릴려는 정점의 포맷을 세트
            this._device.VertexFormat = CustomVertex.PositionColored.Format;
 
            // 렌더링(그리기)
            this._device.DrawPrimitives(PrimitiveType.TriangleStrip, 0, 2);
                        
            // 좌표 x=0 y=0 의 위치에 흰색으로 출력
            this._font.DrawText(null, "사각형 다각형 출력", 0, 0, Color.White);
            
            // 화면출력은 여기까지
            this._device.EndScene();

            // 실제의 디스플레이에 출력
            this._device.Present();

        }
 
        /// <summary>
        /// 자원의 파기
        /// </summary>
        public void Dispose()
        {
            // 정점 버퍼를 해제
            if (this._vertexBuffer != null)
            {
                this._vertexBuffer.Dispose();
            }
 
            // 폰트 자원을 해제
            if (this._font != null)
            {
                this._font.Dispose();
            }
 
            // Direct3D 디바이스의 자원 해제
            if (this._device != null)
            {
                this._device.Dispose();
            }

        }
    }
}

 

        private VertexBuffer _vertexBuffer = null;
정점버퍼 클래스 선언.. 만약에 그리고자 하는 도형이 두개면 두개 선언해주면 된다
 
 
            pp.EnableAutoDepthStencil = true;
            pp.AutoDepthStencilFormat = DepthFormat.D16;
전에 나왔던거지만, 한번 더 되새김질 하기 위해서 다시한번 빨간줄을 쳐봤다.
EnableAutoDepthStencil = true : Z버퍼 사용하기.(심도 깊이축 사용)
AutoDepthStencilFormat = DepthFormat.D16 : 깊이가 어느정도 되는지, 어느 시스템이던 잘돌아가게 하려구 16으로 했는데 더 좋은 성능을 원한다면 24로 해도 좋다^^
 
 
            this.SettingCamera();
새로이 나온 메서드다, Partial 클래스에 들어가있는건데 내용은 메서드 이름에서 냄새가 나듯이, 카메라 기본정보를 담고있는 메서드다.
            this._device.Transform.View = Matrix.LookAtLH(new Vector3(0.0f, 0.0f, -10.0f),
                new Vector3(0.0f, 0.0f, 0.0f), new Vector3(0.0f, 1.0f, 0.0f));
 
            this._device.Transform.Projection = Matrix.PerspectiveFovLH(Geometry.DegreeToRadian(60.0f),
                (float)this._device.Viewport.Width / (float)this._device.Viewport.Height, 1.0f, 100.0f);
이 뷰와 투영좌표변형을 갖고있는 메서드다.
 
 
 this._vertexBuffer = new VertexBuffer(typeof(CustomVertex.PositionColored),
                4, this._device, Usage.None, CustomVertex.PositionColored.Format, Pool.Managed);
전과 같아, 말이필요없지만, 삼각형이 아니라 사각형이기 때문에 3대신 4가 들어갔다.
 
 
 CustomVertex.PositionColored[] vertices = new CustomVertex.PositionColored[4];
 
            vertices[0] = new CustomVertex.PositionColored(-4.0f, 4.0f, 0.0f, Color.Red.ToArgb());
            vertices[1] = new CustomVertex.PositionColored(4.0f, 4.0f, 0.0f, Color.Blue.ToArgb());
            vertices[2] = new CustomVertex.PositionColored(-4.0f, -4.0f, 0.0f, Color.Green.ToArgb());
            vertices[3] = new CustomVertex.PositionColored(4.0f, -4.0f, 0.0f, Color.Yellow.ToArgb());
정점의 수가 4개이기 때문에 당연히 배열이 하나가 늘어난 것 뿐 다른건 없다
 

            using (GraphicsStream data = this._vertexBuffer.Lock(0, 0, LockFlags.None))

            {
                data.Write(vertices);
                this._vertexBuffer.Unlock();
            }
            this._device.RenderState.Lighting = false;
정점버퍼 잠그기,, 전과 같은 내용
 
 
            this._device.SetStreamSource(0, this._vertexBuffer, 0);
            this._device.VertexFormat = CustomVertex.PositionColored.Format;
            this._device.DrawPrimitives(PrimitiveType.TriangleStrip, 0, 2);
다른건 바뀐게 없지만 맨 마지막줄!
Device.DrawPrimitives의 소스 타입을 PrimitiveType.TriangleStrip으로 지정하고, 삼각형 두개를 연결해야하니까 삼각형 객체가 두개가 있기 때문에 2를 지정해주면 된다!