Visualizzazione post con etichetta DirectX. Mostra tutti i post
Visualizzazione post con etichetta DirectX. Mostra tutti i post

venerdì 26 dicembre 2014

Disegnare triangoli in Direct3D senza VertexBuffer

Disegno triangoli soltanto definendo un array di vertici.
Questo è il codice che definisce i vertici.
public void CreaVertici()
        {
            vertices = new CustomVertex.PositionColored[9];
            vertices[0].Position = new Vector3(0f, 0f, 0f);
            vertices[0].Color = Color.Blue.ToArgb();
            vertices[1].Position = new Vector3(0f, 10f, 0f);
            vertices[1].Color = Color.Blue.ToArgb();
            vertices[2].Position = new Vector3(10f, 0f, 0f);
            vertices[2].Color = Color.Blue.ToArgb();
            vertices[3].Position = new Vector3(5f, 0f, 0f);
            vertices[3].Color = Color.Green.ToArgb();
            vertices[4].Position = new Vector3(5f, 15f, 0f);
            vertices[4].Color = Color.Green.ToArgb();
            vertices[5].Position = new Vector3(15f, 0f, 0f);
            vertices[5].Color = Color.Green.ToArgb();
            vertices[6].Position = new Vector3(0f, -10f, 0f);
            vertices[6].Color = Color.Red.ToArgb();
            vertices[7].Position = new Vector3(18f, -15f, 0f);
            vertices[7].Color = Color.Red.ToArgb();
            vertices[8].Position = new Vector3(15f, 8f, 0f);
            vertices[8].Color = Color.Red.ToArgb();
        }
Il numero evidenziato in rosso su giallo è il numero di vertici compresi nell'array,

Se non si usa vertexBuffer bisogna specificare i vertici uno dopo l'altro anche se sono uguali.
Una volta specificati i vertici, di tipo CustomVertex.PositionColored, si usa il comando che li stampa:
        private void render()
        {
            device.Clear(ClearFlags.Target, System.Drawing.Color.Black, 1.0f, 0);
            device.BeginScene();
            device.VertexFormat = CustomVertex.PositionColored.Format;
            device.DrawUserPrimitives(PrimitiveType.TriangleList, 3, vertices);
            device.EndScene();
            device.Present();
        }
Ecco, quello marcato in rosso è il comando fondamentale, che stampa i triangoli specificando:
  • Il tipo di primitiva
  • Il numero di primitive
  • l'array di vertici da usare.
Il numero di primitive è importante! Se non si specifica il numero giusto non vengono disegnate tutte le primitive.
Ecco l'immagine:



Ma se io uso device.DrawUserPrimitives specificando un numero inferiore di primitive:
        private void render()
        {
            device.Clear(ClearFlags.Target, System.Drawing.Color.Black, 1.0f, 0);
            device.BeginScene();
            device.VertexFormat = CustomVertex.PositionColored.Format;
            device.DrawUserPrimitives(PrimitiveType.TriangleList, 2, vertices);
            device.EndScene();
            device.Present();
        }
Ottengo questa immagine:

domenica 21 dicembre 2014

DirectX

Codice che ho ricavato finora:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using Microsoft.DirectX.Direct3D;
using Microsoft.DirectX;

namespace DirectXProject
{
    public partial class mioForm : Form

    {
        
        public Device device;
        private float angle = 0f;
        CustomVertex.PositionColored[] vertices;
       
        public mioForm()
        {
            InitializeComponent();
            
        }

        public void InitializeDevice()
        {
            
            PresentParameters presentParams = new PresentParameters();
            presentParams.BackBufferCount = 1;
            presentParams.BackBufferFormat = Manager.Adapters[0].CurrentDisplayMode.Format;
            presentParams.BackBufferWidth =1366;
            presentParams.BackBufferHeight =768;
            
            presentParams.Windowed = false;
            presentParams.FullScreenRefreshRateInHz = Manager.Adapters[0].CurrentDisplayMode.RefreshRate;
            presentParams.SwapEffect = SwapEffect.Discard;

            device = new Device(0, DeviceType.Hardware, this, CreateFlags.SoftwareVertexProcessing, presentParams);
        }

        public void CreaVertici()
        {
            vertices= new CustomVertex.PositionColored[3];
            vertices[0].Position = new Vector3(0f, 0f, 0f);
            vertices[0].Color = Color.Red.ToArgb();
            vertices[1].Position = new Vector3(0f, 10f, 0f);
            vertices[1].Color = Color.Red.ToArgb();
            vertices[2].Position = new Vector3(10f, 0f, 0f);
            vertices[2].Color = Color.Red.ToArgb();
           
        }
        public void Camera()
        {
            device.Transform.Projection = Matrix.PerspectiveFovLH((float)Math.PI / 4, this.Width / this.Height, 1f, 100f);
             
            device.Transform.View = Matrix.LookAtLH(new Vector3(0, 0, -50), new Vector3(0, 0, 0), new Vector3(0, 1, 0));
            device.RenderState.Lighting = false;
            device.RenderState.CullMode = Cull.None;
        }

        private void render()
        {
            device.Clear(ClearFlags.Target, System.Drawing.Color.Black, 1.0f, 0);
            device.BeginScene();
            device.VertexFormat = CustomVertex.PositionColored.Format;
            device.Transform.World = Matrix.RotationX(angle) * Matrix.RotationZ(angle);
            device.DrawUserPrimitives(PrimitiveType.TriangleList,1,vertices);
            device.EndScene();
            device.Present();
            angle += 0.1f;

        }
       
        public static void Main()
        {


                mioForm frm = new mioForm();
                frm.WindowState = FormWindowState.Maximized;
                frm.InitializeDevice();
                frm.CreaVertici();
                frm.Camera();
                frm.Show();
                while (frm.Created)
                {
                    frm.render();
                    Application.DoEvents();
                }
            

        }
        

        private void mioForm_Load(object sender, EventArgs e)
        {

        }

        private void mioForm_Click(object sender, EventArgs e)
        {
            Application.Exit();
        }
        
    }
}
A parte l'effetto ameno di un triangolo rosso che ruota in modo un po' pazzoide, cerchiamo di analizzare il codice...

Nel costruttore viene chiamata solo InitializeComponent, che si trova nell'altro mezzo modulo con la mezza classe form...

Poi ho marcato in colori diversi i metodi fondamentali dell'oggetto che mi servono.
Sono quattro:
  • Uno che crea il Device
  • Uno che crea i Vertici
  • Uno che setta la Telecamera
  • Uno che dà l'avvio al disegno.
Così dovrebbe essere più chiaro.
I quattro vengono richiamati nel metodo Main()

domenica 14 dicembre 2014

Esercizio elementare di moltiplicazione di matrici relative alle coordinate di un punto.

Dunque proviamo a moltiplicare le due semplici matrici:
x         2  0
y         0  2
Le dimensiohni sono (2 x 1) e (2 x 2).
Dobbiamo invertirle:
2  0      x  
0  2      y
Adesso abbiamo (2 x 2) e (2 x 1), quindi sono moltiplicabili e ne verrà fuori una matrice di dimensioni (2 x 1).
2x + 0y = 2x
0x + 2y = 2y
La matrice risultante sarà quindi
2x
2y
Ed ecco che il valore raddoppia.

Moltiplicazione fra matrici

Le dimensioni delle matrici si descriverebbero con il numero di righe seguito dal numero di colonne.
 2  1 -1            1  1  2  2
-2  3  4            2 -3  1  3
                   -1 -1  5  2


Le dimensioni della prima matrice sono (2 x 3) e (3 x 4).
I numeri interni sono uguali, e quindi le due matrici sono moltiplicabili.
La matrice prodotto sarà uguale a (2 x 4).
Ogni riga si moltiplica per ogni colonna.
2*1 + 1*2 + (-1)*(-1) = 2 + 2 + 1 = 5;

2*1 + 1*(-3)+ (-1)*(-1) = 2 -3 +1 = 0;

2*2 + 1*1 + (-1)*5 = 4 + 1 -5 = 0;

2*2 + 1*3 + (-1)*2 = 4 +3 -2 = 5:


(-2)*1 + 3*2 + 4*(-1) = -2 + 6 -4 = 0;

(-2)*1 + 3*(-3) + 4*(-1) = -2 -9 -4 = -15;

(-2)*2 + 3*1 + 4*5 = -4 +3 +20 = 19;

(-2)*2 + 3*3 + 4*2 = -4 +9 +8 = 13;


Risultato:
5   0   0   5
0 -15  19  13
Corrisponde all'esempio trovato.