Avatar billede bjering Nybegynder
21. marts 2007 - 18:28 Der er 14 kommentarer og
1 løsning

DirectX managed, 3D Grid

Hejsa Eksperter.

Ved ikke lige om det er det rigtige sted at spørge, men..

Jeg har en app. som jeg er ved at lave til en bane editor, og i den har jeg en picture box som jeg renderer på, og et kamera i scenen (isometric view).

nu er det så sådan at jeg gerne vil tegne et 3d grid i scenen, men jeg kan ikke rigtig finde nogle gode løsninger på det.

nogen der har prøvet at lavet dette ? eller ved hvordan man lige kan bære sig an ?.

På forhånd tak :)
Avatar billede crazysnap Seniormester
22. marts 2007 - 12:48 #1
Hej bjering,


Jeg bruger normalt OpenGL som API til at rendere 3D grafik, men jeg kan dog også i nødstilfælde lave applikationer i Direct3D. Hvis du bare vil have tegnet en 3D grid, altså dele rummet ind i uniform boxes kan du gøre det via 3 løkker. Jeg har lavet et lille eksempel til dig nedenfor som læser et 3DGrid ind i et vertexbuffer klar til rendering:


private void intitalizeGrid(Direct3D.Device device, int intGridLength, int intGridSpace)
{
    m_lst = new System.Collections.Generic.List<CustomVertex.PositionColored>();

    CustomVertex.PositionColored v;
    int step = intGridSpace;

    for (int j = 0; j <= intGridLength * 2; j += step)
    {
        for (int i = 0; i <= intGridLength * 2; i += step)
        {
            for (int k = 0; k <= intGridLength * 2; k += step)
            {
                //Draw X-lines
                v = new CustomVertex.PositionColored();
                v.Position = new Vector3(-intGridLength, -intGridLength + i, -intGridLength + j);
                v.Color = Color.Red.ToArgb();
                m_lst.Add(v);
                v = new CustomVertex.PositionColored();
                v.Position = new Vector3(intGridLength, -intGridLength + i, -intGridLength + j);
                v.Color = Color.Red.ToArgb();
                m_lst.Add(v);

                //Draw Y-lines
                v = new CustomVertex.PositionColored();
                v.Position = new Vector3(-intGridLength + k, -intGridLength, -intGridLength + j);
                v.Color = Color.Red.ToArgb();
                m_lst.Add(v);
                v = new CustomVertex.PositionColored();
                v.Position = new Vector3(-intGridLength + k, intGridLength, -intGridLength + j);
                v.Color = Color.Red.ToArgb();
                m_lst.Add(v);

                //Draw Z-lines
                v = new CustomVertex.PositionColored();
                v.Position = new Vector3(-intGridLength + k, -intGridLength + i, -intGridLength);
                v.Color = Color.Red.ToArgb();
                m_lst.Add(v);
                v = new CustomVertex.PositionColored();
                v.Position = new Vector3(-intGridLength + k, -intGridLength + i, intGridLength);
                v.Color = Color.Red.ToArgb();
                m_lst.Add(v);
            }
        }
    }

    m_grid = new VertexBuffer(typeof(CustomVertex.PositionColored),
                  m_lst.Count, device,
                    Usage.Dynamic | Usage.WriteOnly,
                  CustomVertex.PositionColored.Format,
                    Pool.Default);

    m_grid.SetData(m_lst.ToArray(), 0, LockFlags.None);
}


Du kan så kalde denne her metode til at bygge din grid. Den forudsætter du har to member (globale) variable i klassen:


  private VertexBuffer m_grid;
  System.Collections.Generic.List<CustomVertex.PositionColored> m_lst;


Du kan så kalde den med f.eks:


  intializeGrid(device, 10, 2);


Så laver den et vertexBuffer med en grid der går fra -10 til 10 i alle dimensioner (x,y,z) og med celler af størrelse 2 i alle dimensioner.


Du kan typisk kalde genere grid'en i:


  public void OnResetDevice(object sender, EventArgs e)
  {
        intitalizeGrid((Direct3D.Device)sender, 10, 2);
  }



Og tegne den i en render metode:


private void Render()
{
    d3dDevice.Clear( ClearFlags.Target | ClearFlags.ZBuffer,
                      Color.FromArgb(255, 255, 255, 255), 1.0f, 0 );

    d3dDevice.BeginScene();

    d3dDevice.VertexFormat = CustomVertex.PositionColored.Format;
    d3dDevice.SetStreamSource(0, m_grid, 0);
    d3dDevice.DrawPrimitives(PrimitiveType.LineList, 0, m_lst.Count / 2);

   
    d3dDevice.EndScene();
   
    d3dDevice.Present();
}



Håber det var noget lignende det du mente. :)



Mvh.

- Snap
Avatar billede bjering Nybegynder
22. marts 2007 - 16:13 #2
jeg kan ikke se grid, så den med en anden kamera setup, men bruger denne her pt.

      public static int viewWidth = 800;
        public static int viewHeight = 600;
        public static float rotation = 0.0f;
        public static float camx = 0.0f;
        public static float camy = 0.0f;

        public static void CameraPositioning(Device device)
        {
            // get camera vectors
            float width = (float)viewWidth;
            float height = (float)viewHeight;
            float centerX = width / 2.0f;
            float centerY = height / 2.0f;
            Vector3 cameraPosition = new Vector3(camx, camy, -5.0f);
            Vector3 cameraTarget = new Vector3(camx, camy, 0.0f);

            // create our transforms
            device.Transform.World = Matrix.RotationZ(rotation);
            device.Transform.View = Matrix.LookAtLH(cameraPosition, cameraTarget, new Vector3(0.0f, 1.0f, 0.0f));
            device.Transform.Projection = Matrix.OrthoLH(width, height, 0.0f, 10.0f);
        }

og der kan jeg ikke se den..

forresten, så det ud til at være en box af linier, ikke en grid :o ?

ligesom 20x20 firkanter i en kasse
Avatar billede crazysnap Seniormester
22. marts 2007 - 16:34 #3
Hej bjering,


Javel så du skal have lavet en 2D-grid, har ændret metoden så der laves en 2D grid centreret omkring 0 i stedet. Grid'en er placeret i xy-planen (dvs z = 0).  :)


private void intitalizeGrid(Direct3D.Device device, int intGridLength, int intGridSpace)
{
    m_lst = new System.Collections.Generic.List<CustomVertex.PositionColored>();

    CustomVertex.PositionColored v;

    for (int j = 0; j <= intGridLength * 2; j += intGridSpace)
    {
        v = new CustomVertex.PositionColored();
        v.Position = new Vector3(-intGridLength, -intGridLength + j, 0);
        v.Color = Color.Red.ToArgb();
        m_lst.Add(v);
        v = new CustomVertex.PositionColored();
        v.Position = new Vector3(intGridLength, -intGridLength + j, 0);
        v.Color = Color.Red.ToArgb();
        m_lst.Add(v);

        v = new CustomVertex.PositionColored();
        v.Position = new Vector3(-intGridLength + j, -intGridLength, 0);
        v.Color = Color.Red.ToArgb();
        m_lst.Add(v);
        v = new CustomVertex.PositionColored();
        v.Position = new Vector3(-intGridLength + j, intGridLength, 0);
        v.Color = Color.Red.ToArgb();
        m_lst.Add(v);
    }

    m_grid = new VertexBuffer(typeof(CustomVertex.PositionColored),
                                    m_lst.Count, device,
                                    Usage.Dynamic | Usage.WriteOnly,
                                    CustomVertex.PositionColored.Format,
                                    Pool.Default);

    m_grid.SetData(m_lst.ToArray(), 0, LockFlags.None);
}



Og så vidt jeg kan se ud fra dit kode er kameraet placeret i (0, 0, -5) og kigger på (0, 0, 0) med en up-vektor på (0, 1, 0). Med den konfiguration burde du kunne se grid'et, specielt fordi du kigger på (0, 0, 0) og grid'en har center i origo.


Prøv at ændre lidt på indstillingerne for en sikkerhedsskyld. Prøv f.eks. at sætte cameraTarget til:

Vector3 cameraTarget = new Vector3(camx, camy, 1.0f);



Mvh.

- Snap
Avatar billede crazysnap Seniormester
22. marts 2007 - 16:47 #4
Hov desuden kan jeg se du bruger:


device.Transform.Projection = Matrix.OrthoLH(width, height, 0.0f, 10.0f);


Dvs. at du renderer scenen i et ortogonalt view og alt derfor fremkommer som 2D. Hvis du vil have et 3D view skal du rendere scenen i et perspektiverisk view. Dvs. noget i stil med:


device.Transform.Projection = Matrix.PerspectiveFovLH( Geometry.DegreeToRadian( 45.0f ),
                                  (float)width / height,
                                  0.1f, 1000.0f );



Og for at vise at det ikke bare er et 2D view kan du jo prøve at rykke lidt på kameraets øjeposition. Så prøv at bruge denne her metode i stedet og se forskellen:


public static void CameraPositioning(Direct3D.Device device)
{
    camx = 0;
    camy = -5;
    // get camera vectors
    float width = (float)viewWidth;
    float height = (float)viewHeight;
    float centerX = width / 2.0f;
    float centerY = height / 2.0f;
    Vector3 cameraPosition = new Vector3(camx, camy, -5.0f);
    Vector3 cameraTarget = new Vector3(0, 0, 0.0f);

    // create our transforms
    device.Transform.World = Matrix.RotationZ(rotation);
    device.Transform.View = Matrix.LookAtLH(cameraPosition, cameraTarget, new Vector3(0.0f, 1.0f, 0.0f));
    device.Transform.Projection = Matrix.PerspectiveFovLH( Geometry.DegreeToRadian( 45.0f ),
                                  (float)width / height,
                                  0.1f, 1000.0f );
}


og initializeGrid med parametre:


intitalizeGrid(device, 6, 1);


Mvh.

- Snap
Avatar billede bjering Nybegynder
22. marts 2007 - 18:35 #5
jeg kan ikke vise den grid i isometric, har prøvet alt, inc. manuel via mus at rotere rundt om alle axis ect.

er dette ikke bare en 2d grid tegnet på skærmen ? og ikke en "fast" 3d grid som i f.eks 3dsmax som man kan "rotere" kameraet rundt om ?
Avatar billede bjering Nybegynder
22. marts 2007 - 18:43 #6
ohh vent, nu virker det :)

          device.Transform.World = Matrix.RotationYawPitchRoll(0, 0, 0);
            device.Transform.World = Matrix.RotationZ(rotation);
            device.Transform.View = Matrix.LookAtLH(
                new Vector3(0.0f + camx, 3.0f, camz + camy),
                new Vector3(0.0f + camx, 0.0f, 0.0f + camy),
                new Vector3(0.0f, 1.0f, 0.0f));
            device.Transform.Projection = Matrix.OrthoLH(19.0f, 19.0f, 1.0f, 100.0f);

forstår bare ikke hvorfor man skal bruge OrthoLH(19.0f, 19.0f... ikke ikke skærmens størrelse...
Avatar billede bjering Nybegynder
22. marts 2007 - 18:45 #7
der er dog stadig ingen farve på den grid, underligt..
Avatar billede bjering Nybegynder
22. marts 2007 - 18:53 #8
okay, denne virker som smurt, mangler bare farve i den grid..

          device.Transform.World = Matrix.RotationYawPitchRoll(0, 0, 0);
            device.Transform.World = Matrix.RotationZ(rotation);
            device.Transform.View = Matrix.LookAtLH(
                new Vector3(0.0f + camx, -5.0f, camz + camy),
                new Vector3(0.0f + camx, 0.0f, 0.0f + camy),
                new Vector3(0.0f, 1.0f, 0.0f));
            device.Transform.Projection = Matrix.PerspectiveFovLH(Geometry.DegreeToRadian(45.0f),
                                          (float)width / height,
                                          1.1f, 1000.0f);
Avatar billede crazysnap Seniormester
22. marts 2007 - 19:43 #9
Ok, perfekt!

Så smider jeg lige et svar, og prøv at indsæt din renderings metode hvor scenen og grid'en bliver tegnet. Så skal jeg prøve at se om jeg kan gennemskue hvor farven bliver af! :)


Mvh.

- Snap
Avatar billede bjering Nybegynder
22. marts 2007 - 20:37 #10
public void Render()
        {
            if (!devLost)
            {
                device.Clear(ClearFlags.Target | ClearFlags.ZBuffer, Color.AntiqueWhite, 1.0f, 0);
                Camera.FPS();
                Camera.CameraPositioning(device);
                device.BeginScene();               

                // update Lights
                light.UpdateLights(device);               
                // draw grid
                grid.drawGrid(device);               

                device.EndScene();
                device.Present();
            }
        }

renderingen :)
Avatar billede crazysnap Seniormester
22. marts 2007 - 21:53 #11
Hej igen,


Jeg kunne forestille mig du glemte at tilføje denne sætning inden du tegner grid'en:


device.VertexFormat = CustomVertex.PositionColored.Format;


Men det hele kommer lidt an på hvordan du sætter lyset op i 'light.UpdateLights(device);', for det er helt sikkert der du slår noget til som gør at vertex farverne i grid'en ikke har nogen effekt. Det ville meget typisk være en sådan en her sætning der 'ødelagder' grid farven (som jeg satte til rød):


device.VertexFormat = CustomVertex.PositionNormalColored.Format; 


Hvis det ikke virker at ansætte den første sætning inden du tegner grid'en bliver du nok også lige nødt til at indsætte koden for UpdateLights! :)


Mvh.

- Snap
Avatar billede bjering Nybegynder
22. marts 2007 - 22:07 #12
grid
-------------
    public class Grid
    {
        private VertexBuffer m_grid;
        System.Collections.Generic.List<CustomVertex.PositionColored> m_lst;

        public Grid(Device device, int intGridLength, int intGridSpace)
        {
            m_lst = new System.Collections.Generic.List<CustomVertex.PositionColored>();

            CustomVertex.PositionColored v;
            int step = intGridSpace;

            for (int j = 0; j <= intGridLength * 2; j += intGridSpace)
            {
                v = new CustomVertex.PositionColored();
                v.Position = new Vector3(-intGridLength, -intGridLength + j, 0);
                v.Color = Color.WhiteSmoke.ToArgb();
                m_lst.Add(v);
                v = new CustomVertex.PositionColored();
                v.Position = new Vector3(intGridLength, -intGridLength + j, 0);
                v.Color = Color.WhiteSmoke.ToArgb();
                m_lst.Add(v);

                v = new CustomVertex.PositionColored();
                v.Position = new Vector3(-intGridLength + j, -intGridLength, 0);
                v.Color = Color.WhiteSmoke.ToArgb();
                m_lst.Add(v);
                v = new CustomVertex.PositionColored();
                v.Position = new Vector3(-intGridLength + j, intGridLength, 0);
                v.Color = Color.WhiteSmoke.ToArgb();
                m_lst.Add(v);
            }

            m_grid = new VertexBuffer(typeof(CustomVertex.PositionColored),
                                            m_lst.Count, device,
                                            Usage.Dynamic | Usage.WriteOnly,
                                            CustomVertex.PositionColored.Format,
                                            Pool.Default);

            m_grid.SetData(m_lst.ToArray(), 0, LockFlags.None);           
        }

        public void drawGrid(Device dev)
        {
            dev.VertexFormat = CustomVertex.PositionColored.Format;
            dev.SetStreamSource(0, m_grid, 0);
            dev.DrawPrimitives(PrimitiveType.LineList, 0, m_lst.Count / 2);
        }
-----------

Lights :
----------
      public Lights(Device device)       
        {
            // add global light
            device.Lights[0].Type = LightType.Point;
            device.Lights[0].Position = new Vector3();
            device.Lights[0].Diffuse = Color.White;
            device.Lights[0].Attenuation0 = 0.2f;
            device.Lights[0].Range = 10000.0f;
            device.Lights[0].Update();
            device.Lights[0].Enabled = true;
        }

        public void UpdateLights(Device device)
        {
            foreach (Light light in device.Lights)
            {
                light.Update();
            }
        }

---------

men selvom jeg disabler min light hjælper det ikke...

og jeg bruger den kode du gav mig (prøvede dog at ændre det til Color.WhiteSmoke (linierne))
Avatar billede crazysnap Seniormester
22. marts 2007 - 22:24 #13
Hej bjering,

Ahh, det er selvfølgelig fordi du ikke disabler lighting helt (kun ved det enkelte light-source) når du tegner grid'en. Du behøver ikke nogen shading på en grid (idet den er wireframe), så derfor er det fint du tegner grid'en uden lys. Hvis du vil have shading på grid'en kan du bruge 'PositionNormalColored' til at lave linjepunkterne i stedet, det er dog ikke nødvendigt i dette tilfælde da det er sjældent man vil have shading på wireframe modeller.

Så prop du dette ind så skal du se flotte farver på din Grid:


device.RenderState.Lighting = false;
// draw grid
grid.drawGrid(device);
device.RenderState.Lighting = true;


Mvh.

- Snap
Avatar billede bjering Nybegynder
22. marts 2007 - 22:29 #14
Jep, det var det :)

så siger jeg rigtig mange tak :))
Avatar billede crazysnap Seniormester
22. marts 2007 - 22:32 #15
Ok smukt! Og det var så lidt. Skriv endelig hvis der opstår andre problemer, rart at der endelig dukker spørgsmål op indenfor 3D grafik. :)


Tak for pointene... :)


Mvh.

- Snap
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
IT-kurser om Microsoft 365, sikkerhed, personlig vækst, udvikling, digital markedsføring, grafisk design, SAP og forretningsanalyse.

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester