Revision 1342 of "कंप्यूटर ग्राफिक्स/2013-14/प्रयोगशाला 14" on hiwikiversity

{{कंप्यूटर ग्राफिक्स -- 2013-2014 -- info.uvt.ro/पेज हैडर}}

== डायरेक्टएक्स9 में संक्षिप्त परिचय ==
=== अवलोकन ===
इस प्रयोगशाला में हम डायरेक्टएक्स में सरल दृश्य के बनाने और इसे के अंदर कुछ तत्वों के साथ ड्रा के विषय में कुछ सामान्य मुद्दों पर चर्चा करेंगे। कोड सी# में लिखे जाएँगे। यह बारीकी से जावा जैसा दिखता हैं।

=== साधारण हैलो वर्ल्ड एप्लीकेशन बनाना ===

<source lang="csharp">
[...]
using Microsoft.DirectX;
using Microsoft.DirectX.Direct3D;
using Direct3D = Microsoft.DirectX.Direct3D;

namespace FirstDirectX
{

    public class HelloDirectX : System.Windows.Forms.Form
    {
        static void Main()
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(true);
            
            HelloDirectX frm = new     HelloDirectX();
            frm.Show();

            Application.run(frm);
        }

        [...]
    }
}
</source>

हर प्रबंधित डायरेक्टएक्स एप्लीकेशन में मूल रूप से आवश्यक:
* '''आरंभीकरण (initialization)''' विधि जहां Direct3D.Device वस्तु को जोड़ने पूरा किया हैं। (ओजीएल ''Init'' फ़ंक्शन के समान)
* '''रेंडरिंग (rendering)''' विधि जो दृश्य हैंडलिंग करता हैं। (ओजीएल डिस्प्ले फ़ंक्शन समान)
* एक '''डिवाइस रीसेट''' हैंडलिंग विधि। इसका उदाहरण है जब खिड़की विंडो के साइज में परिवर्तन (resize) किया जाता हैं। तभ ऐसी घटना पर यह हैंडलिंग विधि शुरू हो जाती हैं।

इसके अलावा हम माउस, कीबोर्ड, जॉयस्टिक आदि का उपयोग के लिये कुछ '''यूजर इंटरेक्शन (user interaction)''' की आवश्यकता होती हैं।

==== डायरेक्टएक्स डिवाइस के आरंभीकरण (Initialization) ====
डायरेक्टएक्स डिवाइस के आरंभीकरण में आम तौर पर एक कस्टम विधि के अंदर किया जाता हैं। जिसे दृश्य रेंडरिंग से पहले कॉल(Call) करने की जरूरत होती हैं। कोड के अगले खंड से पता चलता है कि हम यह कैसे प्राप्त कर सकते हैं:

<source lang="csharp">
[...]
using Microsoft.DirectX;
using Microsoft.DirectX.Direct3D;
using Direct3D = Microsoft.DirectX.Direct3D;

namespace FirstDirectX
{

    public class HelloDirectX : System.Windows.Forms.Form
    {
        private Direct3D.Device device = null;

        static void Main()
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(true);
            
            HelloDirectX frm = new HelloDirectX();
            // डिवाइस को प्रारंभ करें
            frm.Init();
            // फॉर्म दिखाएं
            frm.Show();

            Application.run(frm);
        }

        public void Init()
        {
            //क्या हम हार्डवेयर वर्टेक्स प्रसंस्करण का समर्थन करते हैं? यदि हां, तो इसका इस्तेमाल करें 
            // यदि नहीं, तो सॉफ्टवेयर में डाउनग्रेड करें
            Caps caps = Direct3D.Manager.GetDeviceCaps(Direct3D.Manager.Adapters.Default.Adapter,
                    Direct3D.DeviceType.Hardware);
            CreateFlags flags;

            if (caps.DeviceCaps.SupportsHardwareTransformAndLight)
                flags = CreateFlags.HardwareVertexProcessing;
            else
                flags = CreateFlags.SoftwareVertexProcessing;

            // सब कुछ जांचता है - तो एक सरल, विंडोड डिवाइस बनाएं
            PresentParameters d3dpp = new PresentParameters();

            d3dpp.BackBufferFormat = Format.Unknown;
            d3dpp.SwapEffect = SwapEffect.Discard;
            d3dpp.Windowed = true;
            d3dpp.EnableAutoDepthStencil = true;
            d3dpp.AutoDepthStencilFormat = DepthFormat.D16;
            d3dpp.PresentationInterval = PresentInterval.Immediate;

            device = new Direct3D.Device(0, Direct3D.DeviceType.Hardware, this, flags, 
                    d3dpp);            
        }

        [...]
    }
}
</source>

==== रेंडरिंग (Rendering) ====
डायरेक्टएक्स दृश्य रेंडरिंग के लिए '' 'OnPaint' '' विधि अधिभावी(overriding) आवश्यक है:

<source lang="csharp">
[...]
using Microsoft.DirectX;
using Microsoft.DirectX.Direct3D;
using Direct3D = Microsoft.DirectX.Direct3D;

namespace FirstDirectX
{

    public class HelloDirectX : System.Windows.Forms.Form
    {
        private Direct3D.Device device = null;

        static void Main()
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(true);
            
            HelloDirectX frm = new HelloDirectX();
            // डिवाइस को प्रारंभ करें
            frm.Init();
            // फॉर्म दिखाएं
            frm.Show();

            Application.run(frm);
        }

        public void Init()
        {
            [...]        
        }

        private void Render()
        {
            // अब हम बफर के काले भाग को व्युपोर्ट का भाग साफ़ कर सकते हैं
            device.Clear(ClearFlags.Target | ClearFlags.ZBuffer,
                    Color.FromArgb(255, 0, 0, 0), 1.0f, 0);

            device.BeginScene();
                // अपना कोड यहां रखें
            device.EndScene();

            try
            {
                device.Present();
            }
            catch (DeviceLostException)
            {
                device.Reset(device.PresentationParameters);
            }
        }

        // हमें इस पद्धति को ओवरराइड करने की आवश्यकता है ताकि हम स्क्रीन पर खींची गई चीज़ों को नियंत्रित कर सकें।
        protected override void OnPaint(System.Windows.Forms.PaintEventArgs e)
        {
            this.Render();
        }

        [...]
    }
}
</source>

==== डिवाइस रीसेट (Device resetting) ====
'''OnResetDevice''' ईवेंट हैंडलर किसी भी Direct3D संबंधित वस्तुओं को बनाने और इनिशियलाइज़ करने के लिए एक अच्छी जगह हैं। जो डिवाइस रीसेट के दौरान अमान्य(invalid) हो सकता है:
<source lang="csharp">
[...]
using Microsoft.DirectX;
using Microsoft.DirectX.Direct3D;
using Direct3D = Microsoft.DirectX.Direct3D;

namespace FirstDirectX
{

    public class HelloDirectX : System.Windows.Forms.Form
    {
        private Direct3D.Device device = null;

        static void Main()
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(true);
            
            HelloDirectX frm = new HelloDirectX();
            // डिवाइस को प्रारंभ करें
            frm.Init();
            // फॉर्म दिखाएं
            frm.Show();

            Application.run(frm);
        }

        public void Init()
        {
            [...]        
        }

        private void Render()
        {
            [...]        
        }

        //हमें इस पद्धति को ओवरराइड करने की आवश्यकता है ताकि हम स्क्रीन पर खींची गई चीज़ों को नियंत्रित कर सकें।
        protected override void OnPaint(System.Windows.Forms.PaintEventArgs e)
        {
            this.Render();
        }

        // डिवाइस रीसेट इनटेन्स को प्रबंधित करने के लिए ईवेंट हैंडलर
        public void OnResetDevice(object sender, EventArgs e)
        {
            // डीएक्स डिवाइस को दोबारा शुरू करें
            Direct3D.Device device = (Direct3D.Device)sender;

            // कुछ पेरामीटर को दोबारा शुरू करें:
            device.RenderState.CullMode = Cull.None;
            device.RenderState.FillMode = FillMode.Solid;
            device.RenderState.Lighting = true;
        }
        [...]
    }
}
</source>

=== डायरेक्टएक्स में प्रोजेक्शन और मॉडलव्यू ===

<source lang="csharp">
[...]
using Microsoft.DirectX;
using Microsoft.DirectX.Direct3D;
using Direct3D = Microsoft.DirectX.Direct3D;

namespace FirstDirectX
{

    public class HelloDirectX : System.Windows.Forms.Form
    {
        private Direct3D.Device device = null;

        static void Main()
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(true);
            
            HelloDirectX frm = new HelloDirectX();
            //डिवाइस को प्रारंभ करें
            frm.Init();
            // फॉर्म दिखाएं
            frm.Show();

            Application.run(frm);
        }

        public void Init()
        {
            [...]        
        }

        private void Render()
        {
            // प्रोजेक्शन को पर्सपेक्टिव में सेट करें
            device.Transform.Projection = Matrix.PerspectiveFovLH((float)Math.PI/4,
                    this.Width/this.Height, 1f, 50f);
            // ओरिएंट कैमरा
            device.Transform.View = Matrix.LookAtLH(new Vector3(0,0,-30), new Vector3(0,0,0), 
                    new Vector3(0,1,0));
            // Reset the world matrix to Identity.
            device.Transform.World = Matrix.Identity;
            [...]        
        }

        //हमें इस पद्धति को ओवरराइड करने की आवश्यकता है ताकि हम स्क्रीन पर खींची गई चीज़ों को नियंत्रित कर सकें।
        protected override void OnPaint(System.Windows.Forms.PaintEventArgs e)
        {
            this.Render();
        }

        // डिवाइस रीसेट इनसेन्स को प्रबंधित करने के लिए ईवेंट हैंडलर
        public void OnResetDevice(object sender, EventArgs e)
        {
            [...]
        }
        [...]
    }
}
</source>


<source lang="csharp">
[...]
using Microsoft.DirectX;
using Microsoft.DirectX.Direct3D;
using Direct3D = Microsoft.DirectX.Direct3D;

namespace FirstDirectX
{

    public class HelloDirectX : System.Windows.Forms.Form
    {
        private Direct3D.Device device = null;

        static void Main()
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(true);
            
            HelloDirectX frm = new HelloDirectX();
            // डिवाइस को प्रारंभ करें
            frm.Init();
            //फॉर्म दिखाएं
            frm.Show();

            Application.run(frm);
        }

        public void Init()
        {
            [...]        
        }

        private void Render()
        {
            // प्रोजेकशन को पर्सपेक्टिव में सेट करें
            device.Transform.Projection = Matrix.PerspectiveFovLH((float)Math.PI/4,
                    this.Width/this.Height, 1f, 50f);
            // ओरिएंट कैमरा
            device.Transform.View = Matrix.LookAtLH(new Vector3(0,0,-30), new Vector3(0,0,0), 
                    new Vector3(0,1,0));
            // आइडेन्टिटि के लिए वल्ड मैट्रिक्स को रीसेट करें।
            device.Transform.World = Matrix.Identity;

            // एक नया मैट्रिक्स बनाएं जो हमारे परिवर्तनों को संग्रहित करे।
            Matrix customMatrix = Matrix.Identity;
            // हमारे मैट्रिक्स में एक ट्रान्सलेशन लागू करें
            Matrix translation = Matrix.Translation(10, 10, 10);
            // OX अक्ष पर रोटेशन लागू करें             
            Matrix rotation = Matrix.RotationX(45);
            // स्केलिंग लागू करें               
            Matrix scaling = Matrix.Scaling(0.5f, 0.5f, 0.5f);
            // कम्पोजिट मैट्रिक्स बनाएं
            customMatrix = translation * rotation * scaling;

            // हमारे नए कस्टम मैट्रिक्स होने के लिए वल्ड मैट्रिक्स सेट करें
            device.Transform.World = customMatrix;
            [...]        
        }

        //हमें इस पद्धति को ओवरराइड करने की आवश्यकता है ताकि हम स्क्रीन पर खींची गई चीज़ों को नियंत्रित कर सकें।
        protected override void OnPaint(System.Windows.Forms.PaintEventArgs e)
        {
            this.Render();
        }

        // डिवाइस रीसेट इनसेन्स को प्रबंधित करने के लिए ईवेंट हैंडलर
        public void OnResetDevice(object sender, EventArgs e)
        {
            [...]
        }
        [...]
    }
}
</source>

=== वर्टिस (Vertices) का प्रयोग ===

<source lang="csharp">
[...]
using Microsoft.DirectX;
using Microsoft.DirectX.Direct3D;
using Direct3D = Microsoft.DirectX.Direct3D;

namespace FirstDirectX
{

    public class HelloDirectX : System.Windows.Forms.Form
    {
        private Direct3D.Device device = null;

        static void Main()
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(true);
            
            HelloDirectX frm = new HelloDirectX();
            // Initialize the device.
            frm.Init();
            // Show the form.
            frm.Show();

            Application.run(frm);
        }

        public void Init()
        {
            [...]        
        }

        private void Render()
        {
            [...]
            // Create a list of PositionColored vertices and define their position and color.
            CustomVertex.PositionColored[] vertices = new CustomVertex.PositionColored[3];
            vertices[0].Position = new Vector3(0f, 0f, 0f);
            vertices[0].Color = Color.Red.ToArgb();
            vertices[1].Position = new Vector3(10f, 0f, 0f);
            vertices[1].Color = Color.Green.ToArgb();
            vertices[2].Position = new Vector3(5f, 10f, 0f);
            vertices[2].Color = Color.Yellow.ToArgb();

            // Now we can clear just view-port's portion of the buffer to black
            device.Clear(ClearFlags.Target | ClearFlags.ZBuffer,
                    Color.FromArgb(255, 0, 0, 0), 1.0f, 0);

            device.BeginScene();
                // Let the device know your format has changed.
                device.VertexFormat = CustomVertex.PositionColored.Format;
                // Draw the triangle.
                device.DrawUserPrimitives(PrimitiveType.TriangleList, 1, vertices);
            device.EndScene();
            [...]
        }

        // We need to override this method so that we can control what is being drawn on the screen.
        protected override void OnPaint(System.Windows.Forms.PaintEventArgs e)
        {
            this.Render();
        }

        // Event handler for managing the device reset instance.
        public void OnResetDevice(object sender, EventArgs e)
        {
            [...]
        }
        [...]
    }
}
</source>

<source lang="csharp">
[...]
using Microsoft.DirectX;
using Microsoft.DirectX.Direct3D;
using Direct3D = Microsoft.DirectX.Direct3D;

namespace FirstDirectX
{

    public class HelloDirectX : System.Windows.Forms.Form
    {
        private Direct3D.Device device = null;

        static void Main()
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(true);
            
            HelloDirectX frm = new HelloDirectX();
            // Initialize the device.
            frm.Init();
            // Show the form.
            frm.Show();

            Application.run(frm);
        }

        public void Init()
        {
            [...]        
        }

        private void Render()
        {
            [...]
        }

        // We need to override this method so that we can control what is being drawn on the screen.
        protected override void OnPaint(System.Windows.Forms.PaintEventArgs e)
        {
            this.Render();
        }

        // Event handler for managing the device reset instance.
        public void OnResetDevice(object sender, EventArgs e)
        {
            [...]
        }

        private VertexBuffer vb = null;
        private CustomVertex.PositionColored[] vertices;

        private void CreateVertexBuffer(Direct3D.Device device, int noVertices)
        {
            vb = new VertexBuffer(typeof(CustomVertex.PositionColored),
                 noVertices, device, Usage.Dynamic | Usage.WriteOnly,
                 CustomVertex.PositionColored.Format, Pool.Default);
            vertices = new CustomVertex.PositionColored[noVertices];
            for (int i=0; i<noVertices; i++)
            {
                vertices[0].Position = new Vector3(i, i, i);
                vertices[0].Color = Color.Red.ToArgb();
            }
            vb.SetData(vertices, 0, LockFlags.None);
        }

        private void UseVertexBuffer(Direct3D.Device device, int noVertices)
        {
            device.SetStreamSource(0, vb, 0);
            device.VertexFormat = CustomVertex.PositionColored.Format;
            device.DrawUserPrimitives(PrimitiveType.LineList, noVertices/2 
                /*primitive count - 2 vertice per line implies a noVertices/2 primitives*/, 
                vertices);
        }
        [...]
    }
}
</source>




=== लाइट्स, मैटेरियल्स और टेक्सचर्स ===
<source lang="csharp">
[...]
using Microsoft.DirectX;
using Microsoft.DirectX.Direct3D;
using Direct3D = Microsoft.DirectX.Direct3D;

namespace FirstDirectX
{

    public class HelloDirectX : System.Windows.Forms.Form
    {
        private Direct3D.Device device = null;

        static void Main()
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(true);
            
            HelloDirectX frm = new HelloDirectX();
            // Initialize the device.
            frm.Init();
            // Show the form.
            frm.Show();

            Application.run(frm);
        }

        public void Init()
        {
            [...]
            this.SetUpMaterial(device);
            this.SetUpTexture(device);
            this.SetUpLights(device);
            [...]
        }

        private void Render()
        {
            [...]
            device.Transform.World = customMatrix;
            // Select material to be applied.
            device.Material = material;
            // Select texture to be applied.
            device.SetTexture(0, texture);

            // Draw object.
            [...]
        }

        // We need to override this method so that we can control what is being drawn on the screen.
        protected override void OnPaint(System.Windows.Forms.PaintEventArgs e)
        {
            this.Render();
        }

        // Event handler for managing the device reset instance.
        public void OnResetDevice(object sender, EventArgs e)
        {
            [...]
        }

        private void SetUpLights(Direct3D.Device device)
        {
            device.Lights[0].Type = LightType.Point; // LightType.Directional; LightType.Spot;
            // device.Lights[0].Ambient = Color.White;
            device.Lights[0].Specular = Color.White;
            device.Lights[0].Diffuse = Color.White;
            device.Lights[0].Position = new Vector3(x, y, z);
            // device.Lights[0].Direction = new Vector3(x, y, z);
            device.Lights[0].Attenuation1 = 0.001f;
            device.Lights[0].Range = 10000f;
            device.Lights[0].Enabled = true;
        }

                private Material material = null;

        private void SetUpMaterial(Direct3D.Device device, String fileName)
        {
            material = new Material();
            material.Ambient = Color.White;
            material.Diffuse = Color.White;
            material.Specular = Color.White;
        }

        private Texture texture = null;
        
        private void SetUpTexture(Direct3D.Device device)
        {
            texture = TextureLoader.FromFile(device, fileName);
        }
    }
}
</source>


=== दृश्य गोला गोले(spheres) को जोड़ना ===

<source lang="csharp">
[...]
using Microsoft.DirectX;
using Microsoft.DirectX.Direct3D;
using Direct3D = Microsoft.DirectX.Direct3D;

namespace FirstDirectX
{

    public class HelloDirectX : System.Windows.Forms.Form
    {
        private Direct3D.Device device = null;

        static void Main()
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(true);
            
            HelloDirectX frm = new HelloDirectX();
            // Initialize the device.
            frm.Init();
            // Show the form.
            frm.Show();

            Application.run(frm);
        }

        private Mesh myMesh = null;

        public void Init()
        {
            [...]
            this.SetUpMaterial(device);
            this.SetUpTexture(device);
            this.SetUpLights(device);
            // Create a sphere mesh.
            myMesh = Mesh.Sphere(device, 3.0f, 60, 20);
            [...]
        }

        private void Render()
        {
            [...]
            device.Transform.World = customMatrix;
            // Select material to be applied.
            device.Material = material;

            // Apply texture on the sphere.

            // Draw the sphere mesh.
            myMesh.DrawSubset(0);

            [...]
        }

        // We need to override this method so that we can control what is being drawn on the screen.
        protected override void OnPaint(System.Windows.Forms.PaintEventArgs e)
        {
            this.Render();
        }

        // Event handler for managing the device reset instance.
        public void OnResetDevice(object sender, EventArgs e)
        {
            [...]
        }
    }
}
</source>


=== ब्लेंडिंग (Blending) ===

<source lang="csharp">
[...]
using Microsoft.DirectX;
using Microsoft.DirectX.Direct3D;
using Direct3D = Microsoft.DirectX.Direct3D;

namespace FirstDirectX
{

    public class HelloDirectX : System.Windows.Forms.Form
    {
        private Direct3D.Device device = null;

        static void Main()
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(true);
            
            HelloDirectX frm = new HelloDirectX();
            // Initialize the device.
            frm.Init();
            // Show the form.
            frm.Show();

            Application.run(frm);
        }

        private Mesh myMesh = null;

        public void Init()
        {
            [...]
            this.SetUpMaterial(device);
            this.SetUpTexture(device);
            this.SetUpLights(device);
            // Create a sphere mesh.
            myMesh = Mesh.Sphere(device, 3.0f, 60, 20);
            [...]
        }

        private void Render()
        {
            [...]
            device.Transform.World = customMatrix;
            // Select material to be applied.
            device.Material = material;

            // Enable alpha blending test.
            device.RenderState.AlphaBlendEnable = true;
            device.RenderState.AlphaTestEnable = true;
            device.RenderState.SourceBlend = Blend.SourceAlpha;
            device.RenderState.DestinationBlend = Blend.DestinationAlpha;

            device.RenderState.ReferenceAlpha = 0x08;
            device.RenderState.AlphaFunction = Compare.GreaterEqual;

            // Select texture to be applied.
            device.SetTexture(0, texture);
            // Draw the sphere mesh.
            myMesh.DrawSubset(0);

            // Disable alpha blending test.
            device.RenderState.AlphaBlendEnable = false;
            device.RenderState.AlphaTestEnable = false;

            [...]
        }

        // We need to override this method so that we can control what is being drawn on the screen.
        protected override void OnPaint(System.Windows.Forms.PaintEventArgs e)
        {
            this.Render();
        }

        // Event handler for managing the device reset instance.
        public void OnResetDevice(object sender, EventArgs e)
        {
            [...]
        }
    }
}
</source>

== लिंक ==
* [http://www.riemers.net/eng/Tutorials/DirectX/Csharp/series1.php प्रबंधित डायरेक्टएक्स9 ट्यूटोरियल]

[[Category:वैकल्पिक HI]]
[[Category:कंप्यूटर ग्राफिक्स]]
[[Category:ग्राफिक्स]]