Du bist nicht angemeldet.

Stilllegung des Forums
Das Forum wurde am 05.06.2023 nach über 20 Jahren stillgelegt (weitere Informationen und ein kleiner Rückblick).
Registrierungen, Anmeldungen und Postings sind nicht mehr möglich. Öffentliche Inhalte sind weiterhin zugänglich.
Das Team von spieleprogrammierer.de bedankt sich bei der Community für die vielen schönen Jahre.
Wenn du eine deutschsprachige Spieleentwickler-Community suchst, schau doch mal im Discord und auf ZFX vorbei!

Werbeanzeige

1

02.11.2015, 00:21

C# XNA 4.0 - Linien werden nicht komplett gezeichnet

Hallo !

Ich habe ein kleines Projekt bei dem ein Sonnensystem mit maximal 5 Planeten erstellt wird (Zufallserstellung).
Um für eine spätere Koordination der Raumschiffe diese präzise zu bewegen, wollte ich die Planeten über eine Linie mit dem Raumgitter verbinden.
Dabei treten jedoch zwei Probleme auf, die ich nicht verstehe.

  1. Es wird meistens nur ein Planet bzw. die Sonne korrekt mit dem Raumgitter verbunden und bei den anderen Planeten sind entweder gar keine Linien oder nur Teile davon zu sehen.
  2. Ich habe den Linien die Planetenposition übergeben, jedoch wird die Linie mit den selben Koordinaten ewig weit entfernt vom Planeten gezeichnet.
    Um die Linien ungefähr in die Nähe der Planeten zu bringen, habe ich die übertragene Planetenposition durch 2500 geteilt.
    Ich verstehe hier nicht, warum allein die Angabe der Planetenposition nicht die Linie exakt unter dem Planeten zeichnet.
Hier Bilder, welches die beschriebene Probleme darstellt:

(Link)



Wenn ich die Liste in der die Planetenpositionen gespeichert sind nicht leere, dann werden alle Linien gezeichnet.
Allerdings kommt die Linie dann dem Planeten bei der Drehung um die Sonne nicht hinterher (Planet ist schneller als seine Linie). Was ich auch wieder nicht verstehe warum das so ist.

(Link)



Hier der C# Code von dem Befüllen des vertices Arrays und der Übergabe an den vertexbuffer:
GridObjectConnector.cs

C#-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
public void LoadGraphicsContent(GraphicsDevice graphicsDevice)
        {
            device = graphicsDevice;
            effect = new BasicEffect(device);
            Vector3[] ObjectPositions = getObjectPositionArray;

            Color[] LineColor = getLineColor;
            this.primitiveCount = ObjectPositions.Length;
            this.vertexCount = this.primitiveCount * 6;

            VertexPositionColor[] vertices = new VertexPositionColor[this.vertexCount];

            int index = 0;
            float fXMark = 0.05f;
            float fDivisor = 2500.0f;
            for (int i = 0; i < ObjectPositions.Length; ++i)
            {
                vertices[index++] = new VertexPositionColor(new Vector3((ObjectPositions[i].X / fDivisor) + fXMark, GridWorldZero, (ObjectPositions[i].Z / fDivisor) + fXMark), LineColor[i]);
                vertices[index++] = new VertexPositionColor(new Vector3((ObjectPositions[i].X / fDivisor) - fXMark, GridWorldZero, (ObjectPositions[i].Z / fDivisor) - fXMark), LineColor[i]);
                vertices[index++] = new VertexPositionColor(new Vector3((ObjectPositions[i].X / fDivisor) + fXMark, GridWorldZero, (ObjectPositions[i].Z / fDivisor) - fXMark), LineColor[i]);
                vertices[index++] = new VertexPositionColor(new Vector3((ObjectPositions[i].X / fDivisor) - fXMark, GridWorldZero, (ObjectPositions[i].Z / fDivisor) + fXMark), LineColor[i]);
                vertices[index++] = new VertexPositionColor(new Vector3((ObjectPositions[i].X / fDivisor), GridWorldZero, (ObjectPositions[i].Z / fDivisor)), LineColor[i]);
                vertices[index++] = new VertexPositionColor(new Vector3((ObjectPositions[i].X / fDivisor), ObjectPositions[i].Y, (ObjectPositions[i].Z / fDivisor)), LineColor[i]);
            }

            
            this.vertexBuffer = new VertexBuffer(device, typeof(VertexPositionColor),this.vertexCount,BufferUsage.WriteOnly);
            this.vertexBuffer.SetData<VertexPositionColor>(vertices);
        }


Die Draw Methode dazu:
GridObjectConnector.cs

C#-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
        public void Draw()
        {
            effect.World = world;
            effect.View = view;
            effect.Projection = projection;
            effect.VertexColorEnabled = true;
            effect.LightingEnabled = false;

            device.SetVertexBuffer(this.vertexBuffer);

            for (int i = 0; i < this.effect.CurrentTechnique.Passes.Count; ++i)
            {
                this.effect.CurrentTechnique.Passes[i].Apply();
                device.DrawPrimitives(PrimitiveType.LineList, 0, this.primitiveCount);
            }

            // we clear all planet positions but not the sun position
            this.objectPositions.RemoveRange(1,this.primitiveCount-1);
            this.lineColor.RemoveRange(1,this.primitiveCount-1);
        }


In der Game1.cs:
Game1.cs

C#-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
        protected override void Draw(GameTime gameTime)
        {
            // Set the View and Projection matrix for the effect
            SkySphereEffect.Parameters["ViewMatrix"].SetValue(View);// * Matrix.CreateRotationY(-angle));
            SkySphereEffect.Parameters["ProjectionMatrix"].SetValue(Projection);

            // Draw the sphere model that the effect projects onto
            foreach (ModelMesh mesh in SkySphere.Meshes)
            {
                mesh.Draw();
            }
            GraphicsDevice.Clear(ClearOptions.DepthBuffer, Color.Black, 1000000, 0);
            // draw the reference grid so it's easier to get our bearings
            grid.Draw();

            float aspectRatio = (float)graphics.GraphicsDevice.Viewport.Width / (float)graphics.GraphicsDevice.Viewport.Height;
            float fieldOfView = aspectRatio * MathHelper.PiOver4 * 3f / 4f;
            
            this.gridObjectConnector.ProjectionMatrix = Matrix.CreatePerspectiveFieldOfView(fieldOfView, aspectRatio, .1f, 1000f);
            this.gridObjectConnector.ViewMatrix = camera.ViewMatrix;

            for (int i = 0; i < arrPlanets.Length; i++)
            {
                this.gridObjectConnector.setObjectPosition = arrPlanets[i].PlanetPosition;
                switch (arrPlanets[i].Type)
                {
                    case PlanetType.Ice:
                        this.gridObjectConnector.setLineColor = Color.Aquamarine;
                        break;
                    case PlanetType.Gas:
                        this.gridObjectConnector.setLineColor = Color.Purple;
                        break;
                    case PlanetType.Molten:
                        this.gridObjectConnector.setLineColor = Color.Red;
                        break;
                    case PlanetType.Rock:
                        this.gridObjectConnector.setLineColor = Color.Brown;
                        break;
                    case PlanetType.Water:
                        this.gridObjectConnector.setLineColor = Color.Blue;
                        break;
                }
            }

            GraphicsDevice.RasterizerState = RasterizerState.CullClockwise;
            this.gridObjectConnector.LoadGraphicsContent(GraphicsDevice);
            this.gridObjectConnector.Draw();

            GraphicsDevice.RasterizerState = RasterizerState.CullNone;
            GraphicsDevice.DepthStencilState = DepthStencilState.Default;
            GraphicsDevice.SamplerStates[0] = SamplerState.AnisotropicWrap;

            for (int i = 0; i < arrPlanets.Length;i++ )
            {
                arrPlanets[i].Draw(View, Projection);
            }

            GraphicsDevice.RasterizerState = RasterizerState.CullNone;
            GraphicsDevice.DepthStencilState = DepthStencilState.Default;
            GraphicsDevice.SamplerStates[0] = SamplerState.AnisotropicWrap;  
            star.Draw(View, Projection);
 
            if (arrPlanets[0] != null)
            {
                spriteBatch.Begin();
                spriteBatch.End();
            }
            GraphicsDevice.SetRenderTarget(null); 
            base.Draw(gameTime);
        }


Das Projekt ist etwas umfangreicher um die verschiedenen Planeten darzustellen.
Wenn jemand interesse hat, kann er sich das Projekt hier runterladen und so evtl. das Problem was ich habe besser analysieren.


Sonnensystem Projekt Download

Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von »FallouT« (02.11.2015, 00:27)


Tobiking

1x Rätselkönig

  • Private Nachricht senden

2

02.11.2015, 02:51

Das mit den fehlenden Linien lässt sich einfach erklären. Das device.DrawPrimitives erwartet die Anzahl der Linien. Du übergibst dort die Anzahl der Planeten, hast aber pro Planet 3 Linien.

Wegen der falschen Positionierung würde ich vermuten das du irgendwo noch mit den Planeten hantierst, das sich deren Position ändert. Das könnte z.B. passieren wenn du nach der Verschiebung rotierst/skalierst. Der Code ist mir allerdings viel zu undurchsichtig um da irgendwas nachzuvollziehen.

Besonders ins Auge gestochen ist mir da folgendes:

C#-Quelltext

1
2
3
4
public Vector3 setObjectPosition
{          
    set { objectPositions.Add(value); }
}

Das ist vom Namen her kein Property, sondern eine Funktion, und es ist auch kein set, sondern ein add. Dein gezeigter Code bekommt so eine ganz andere Bedeutung.

3

02.11.2015, 06:54

Hallo Tobiking!

Danke für den Hinweis, dass ich den falschen count übergebe.
Die setObjectPosition ist tatsächlich von mir nicht umbenannt worden.
Anfangs gab es nur einen Planeten ohne Liste, da hat der Name noch gepasst.
Ich werde daraus eine Funktion zum Hinzufügen machen.

Danke

Werbeanzeige

Ähnliche Themen