Graphics/DirectX

Direct X - 2. 초기화와 기본처리

MOLOKINI 2014. 6. 1. 21:01

수정된 MDX.cs

 

 
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;   // 2강에서 추가된 네임스페이스
using System.Windows.Forms; // 메세지 박스
using System.Drawing;       // Color속성 사용

using Microsoft.DirectX;
using Microsoft.DirectX.Direct3D;   // 라이브러리 두개 추가

namespace ddrawexercise
{
    class MDX : IDisposable // 관리되지 않는 리소스 해제
    {
        private Form1 _form = null;
        private Device _device = null;  // Direct 3D 디바이스

        // 탑레벨 윈도우 : 모든 초기화가 OK면 true, 하나라도 실패하면 false를 리턴한다.
        // false를 리턴하게되면 자동으로 종료된다.
        public bool InitializeApplication(Form1 topLevFORM)
        {
            this._form = topLevFORM;    // 폼의 참조를 보관하고 유지한다.

            PresentParameters pp = new PresentParameters(); // 디바이스를 작성할 때 반드시 필요해!!
                                                            // 어떤 환경에서 디바이스를 사용하는지 설정한다.

            pp.Windowed = true; // 윈도우 모드면 true, 풀스크린 모드면 false!
            pp.SwapEffect = SwapEffect.Discard;     // 스왑효과 : 우선 discard.. 버려!
            pp.EnableAutoDepthStencil = false; // 3D에서 많이 사용돼
            pp.AutoDepthStencilFormat = DepthFormat.Unknown;

            pp.BackBufferWidth = 0;     // Direct3D 디바이스가 사용하는 백버퍼의 크기(해상도)
            pp.BackBufferHeight = 0;    // 0을 지정하면 자동적으로 디바이스 윈도우의 크기와 같아진다
                                        // 풀스크린에는 사이즈의 제한이 있으니 주의하자!

            pp.DeviceWindow = _form;    // 출력대상의 윈도우와 컨트롤
            pp.DeviceWindowHandle = _form.Handle;

            pp.BackBufferFormat = Format.Unknown;   // 백버퍼의 포맷, 윈도우면 unknown을 지정해도돼
            pp.BackBufferCount = 0;     // 백버퍼의 개수 (0은 1과 같다)

            pp.MultiSample = MultiSampleType.None;  // 멀티 샘플링의 레벨 안쓰면 none
            pp.MultiSampleQuality = 0;  // 멀티샘플의 품질레벨

            pp.FullScreenRefreshRateInHz = 0;   // 윈도우 모드에서는 0, 풀스크린이면 60, 75가 일반적
            pp.PresentationInterval = PresentInterval.Default;  // 윈도우모드에서는 디폴트나 immediate로 지정
                                                                // default는 일정한 간격으로 화면 갱신
                                                                // immediate는 기다리지 않고 바로 갱신
            pp.ForceNoMultiThreadedFlag = false;    // 프로그램이 멀티스레드를 사용할 지 결정
            pp.PresentFlag = PresentFlag.None;      // 제시 플래그, 몰라잉

            // 실제 디바이스 작성
            // 항상 최고의 퍼포먼스로 동작을 시도해 실패하면 하위 퍼포먼스로 동작시킨다.

            try
            {
                // 하드웨어의 정점처리, rasterize를 실시할거야, 최고의 퍼포먼스로 작동시키는데
                // 그래픽카드가 후지면 동작을 안할 수도있엉엉엉어유ㅠ
                this._device = new Device(0, DeviceType.Hardware, topLevFORM.Handle, CreateFlags.HardwareVertexProcessing, pp);
                // Device(어댑터, 디바이스 타입, 어떤 윈도우에 직어낼거냐, 하드웨어 정점처리, 디바이스 파라미터)
            }
            catch (DirectXException ex1)
            {
                Debug.WriteLine(ex1.ToString()); // 동작 실패의 경우, 디버그용 메시지 출력
                try
                {
                    // 소프트웨어의 정점 처리, rasterize를 실시, 퍼포먼스는 최하 but 거의 모든 처리를 할수있엉
                    this._device = new Device(0, DeviceType.Reference, topLevFORM.Handle, CreateFlags.SoftwareVertexProcessing, pp);
                }
                catch (DirectXException ex3)
                {
                    // 동작실패
                    MessageBox.Show(ex3.ToString(), "에러", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    return false;
                }
            }
            return true;
        }

        public void MainLoop()  // 메인루프
        {
            //화면을 파란색으로 클리어, 클리어하지 않으면 전에 출력된 내용이 남는다
            this._device.Clear(ClearFlags.Target, Color.DarkBlue, 1.0f, 0);
    		// flags : 클리어 하는 내용 지정, color : 클리어 할 색, 나머지는 z버퍼와 스탠실버퍼 통상 1.0과 0


            this._device.BeginScene();  
            // beginScene과 endScene사이에 그릴 내용을 코딩한다
            this._device.EndScene();

            this._device.Present(); // 실제 디바이스에 출력
        }

        public void Dispose()   // 자원의 파기
        {
            if (this._device != null)
            {
                this._device.Dispose();
            }   // Direct 3D 디바이스의 자원 해제
        }
    }
}
 
Direct 3D Device작성
this._device = new Device(0, DeviceType.Reference, topLevFORM.Handle, CreateFlags.SoftwareVertexProcessing, pp);
 
Device 구조체
- adapter : 물리 디바이스의 인덱스 통상 0, 복수의 물리 디바이스가 존재하면 1이나 2로
- deviceType : rasterize를 어떻게 실시할지 설정, 하드웨어로 디바이스의 동작을 시도해 실패하면 레퍼런스 rasterize를 지정하도록 하고 있어용
- renderWindowHandle : 출력 대상의 윈도우나 컨트롤을 반환, null을 지정하면 PresentParameter구조체의 DeviceWindow를 지정하거나 뒤에 나오는 Device .Present메서드로 컨트롤을 지정합니다.
- behaviorFlags : 디바이스의 작성 플래그, 통상 HardwareVertexProcessing을 지정한다. 실패하면 SoftwareVertexProcessing으로 작성을 시도합니다.
- PresentationParameter : 작성한 PresentationParameter를 건네준다.
지금 소스는 기본적으로 하드웨어로 작동하도록 되어있고, 실패하면 소프트웨어로 동작하게 되어있어요
 

 

this._device.Clear(ClearFlags.Target, Color.DarkBlue, 1.0f, 0);
Device.Clear 구조체
- flag : 클리어할 대상을 정한다.
- color : 클리어 할 색을 정한다.
- zdepth : z버퍼를 클리어하는 값이다, 통상 1.0이야^^
- stencil : 스탠실버퍼를 클리어하는 값이야, 이건 통상 0
아직 z버퍼와 스탠실 버퍼를 사용할 일이 없기 때문에 기본값으로 해두었다.
 
다각형들을 출력하게 될 때에는 BeginScene과 EndScene 사이에 코딩을 하게된다.