Laden...

Kann ich mit MonoGame ein Objekt definieren, auf dem jeglicher Inhalt am Rand abgeschnitten wird?

Erstellt von stefanpc81 vor 3 Jahren Letzter Beitrag vor 3 Jahren 1.891 Views
S
stefanpc81 Themenstarter:in
24 Beiträge seit 2017
vor 3 Jahren
Kann ich mit MonoGame ein Objekt definieren, auf dem jeglicher Inhalt am Rand abgeschnitten wird?

Hallo,
bevor ich mich noch tiefer mit MonoGame und C# beschäftige, möchte ich wissen, ob folgendes damit möglich ist:

Für einen Flugsimulator möchte ich auf einem rechteckig dargestellten Monitor Linien, geometrische Objekte und Texte abbilden, welcher im Flugverhalten kontinuierlich verändert werden muss. Das Bild im Anhang soll den gesamten Monitor darstellen. Auf dem schwarzen Bereich sollen die o.g. Objekte dargestellt werden und an der Grenze davon abgeschnitten werden. Im roten Bereich soll aber auch anderer Text und o.g. Objekte dargestellt werden können.

Meine Fragen:

  1. Wie man Text und Bilder anzeigen kann, weiß ich im Prinzip. Womit kann ich die Objekte Rechteck, Linie etc. unter MonoGame darstellen?
  2. Die Objekte, die am Rand abgeschnitten werden sollen: wie/womit geht das?

Viele Grüße,
Stefan

5.657 Beiträge seit 2006
vor 3 Jahren

Ich weiß wirklich nicht, wie man deine Fragen beantworten soll. Einerseits willst du dich nicht mit MonoGame beschäftigen, andererseits willst du wissen, wie man Grafiken rendern kann.

Ganz allgemein kann man sagen, daß man mit jeder Game- bzw. Rendering-Engine machen kann, wonach du fragst. Und die Unterschiede sind auch nicht besonders groß. Aber du sagst ja noch nicht einmal, ob es sich dabei um 3D- oder 2D-Grafiken handelt, einerseits schreibst du "Flugsimulator", andererseits Linien und Text...

Siehe dazu auch [FAQ] Wie finde ich den Einstieg in die 3D-Programmierung mit C#?

Weeks of programming can save you hours of planning

S
stefanpc81 Themenstarter:in
24 Beiträge seit 2017
vor 3 Jahren

Hallo,

ich meinte, wenn es nicht möglich wäre, die schwarze Fläche (Rechteck + Teilkreis) und Zeichenobjekte/Texte darauf abgeschnitten darzustellen, würde es für mich persönlich keinen großen Sinn machen, mich tiefer mit MonoGame zu beschäftigen und mich stattdessen lieber einer anderen Programmiersprache zu bedienen mit der eben Genanntes ginge. z.B. kann ich mit C#/WPF dies nicht realisieren, da es die für mich wichtigen Layer (Zeichenobjekte in bestimmter Reichenfolge hintereinander überlappend darstellen) nicht gibt.

Meine gesamte Programmierung ist rein in 2D. 3D-Objekte und 3D-Steuerung brauche ich m.E. hierfür nicht.

Zur 1. Frage (mit MonoGame)
Text kann ich bspw. mit
_spriteBatch.DrawString(font12, "CDU TEXT", new Vector2(500, 150), Color.White, 0, Vector2.Zero, 1.0f, SpriteEffects.None, layerDepth: 0.2f);
realisieren.

Bilddateien (JPG etc.) kann ich bspw. mit
_spriteBatch.Draw(adi_h, destinationRectangle: new Rectangle(100, 100, 200, 200), null, Color.White, 0, Vector2.Zero, SpriteEffects.None, layerDepth: 0.1f);
realisieren.

Wozu ich aber noch gar nichts gefunden habe, wie ich eine Linie von x,y nach x,y oder ein Rechteck etc. zeichen kann ohne eine Bilddatei zu verwenden. Dies ist mir schleierhaft.
Das waren die (Zeichen-)Objekte die ich meinte.

Zur 2. Frage (mit MonoGame)
Wenn ich nun diese in der 1. Frage genannten Zeichenobjekte darstellen könnte, womit (Stichpunkt?) kann ich den Text und die Zeichenobjekte auf dem Bereich der Fläche (Rechteck + Teilkreis) abschneiden?

Im Bildanhang ist ein Bsp. zu sehen, wie der spätere Monitor aussehen sollte. Oberhalb des großen weißen Pfeils (unten) bis unterhalb des weißen Halbkreises sollen die weißen und magenta-farbig dargestellten Texte und Linien angezeigt werden, außerhalb davon abgeschnitten werden (so wie es die obere Linie nach "ESUPI" ist).

Ich hoffe, nun ist klarer geworden, was ich meine.

Viele Grüße,
Stefan

4.931 Beiträge seit 2008
vor 3 Jahren

... z.B. kann ich mit C#/WPF dies nicht realisieren, da es die für mich wichtigen Layer (Zeichenobjekte in bestimmter Reichenfolge hintereinander überlappend darstellen) nicht gibt.

Klar geht das auch mit WPF (Stichwort: Z-Layer). Und Abschneiden geht mittels "Region clipping", s. Clipping or Cropping Images in WPF.

Und zum Zeichnen von Linien (und [gefüllten] Rechtecken etc.) in MonoGame s. Line drawing (z.B. über die Extension MonoGame.Extended).

5.657 Beiträge seit 2006
vor 3 Jahren

Das "Abschneiden" am Rand des Bildschirms bzw. des Viewports bzw. der Grafik nennt sich "Clipping". Das ist aber in jeder Rendering- oder Game-Engine bereits implementiert, und wird automatisch angewendet.

In deinem Fall wäre es wohl am einfachsten, das Ganze direkt in WinForms ([Tutorial] Zeichnen in Windows-Forms-Programmen (Paint/OnPaint, PictureBox)) oder in WPF (mit einer Canvas) zu zeichnen, dann brauchst du keine externen Bibliotheken.

Weeks of programming can save you hours of planning

S
stefanpc81 Themenstarter:in
24 Beiträge seit 2017
vor 3 Jahren

Danke soweit. Ich muss erst mal schauen, mit welcher Umgebung (MonoGame, Windows Forms oder Windows WPF) ich meine Vorstellungen am besten unter einen Hut bekomme. Da vieles während der Laufzeit des "Spiels" Flugsimulator dynamisch sein muss, glaube ich aber eher, dass MonoGame doch besser ist. Vielleicht stelle ich später noch Fragen.

T
2.219 Beiträge seit 2008
vor 3 Jahren

Da MonoGame eine richtige Library für Spieleprogrammierung ist, wirst du damit vermutlich besser fahren als mit Windows Forms und WPF.
Wenn du daraus ein richtige Spiel machen willst, müsstest du dich bei Windows Forms und WPF arg verdrehen, da dies nicht die Anwendungszwecke der beiden Libraries ist.

T-Virus

Developer, Developer, Developer, Developer....

99 little bugs in the code, 99 little bugs. Take one down, patch it around, 117 little bugs in the code.

S
stefanpc81 Themenstarter:in
24 Beiträge seit 2017
vor 3 Jahren

Inzwischen konnte ich immerhin die gewünschten "Objekte" unter Monogame.Extended mit

            _spriteBatch.DrawString(font12, "CDU TEXT", new Vector2(470, 260), Color.Red, 0, Vector2.Zero, 1.0f, SpriteEffects.None, layerDepth: 0.4f);
            _spriteBatch.DrawCircle(new CircleF(new Vector2(390, 550), 310), 310, Color.Gray, thickness: 310, layerDepth: 0.1f);
            _spriteBatch.DrawRectangle(new Rectangle(200, 200, 400, 400), Color.Black, thickness: 200, layerDepth: 0.2f);
            _spriteBatch.DrawCircle(new CircleF(new Vector2(390, 550), 311), 310, Color.White, thickness: 1, layerDepth: 0.3f);
            _spriteBatch.DrawLine(250, 250, 400, 400, Color.Red, layerDepth: 0.4f);

realisieren. Damit könnte ich gut meine "Objekte" dynamisch berechnen und anzeigen. Nach einiger Google-Suche konnte ich folgende Sachverhalte dazu leider nicht herausfinden:

  1. Wie funktioniert das von User MrSparkle erwähnte "Clipping" mit diesen Objekten speziell für DrawCircle() und DrawRectangle()?
    bzw. 2. ist es mein Ziel, auf (also über) die gemeinsame Fläche des schwarzen Rechtecks und des grauen Kreises alles abzuschneiden was hier rot (Text rechts oben und die Linie links oben) dargestellt ist. Die schwarzen und grauen Flächen sollen später nur schwarz sein und der restliche Teil des Kreises sollte dann optimalerweise gar nicht erst angezeigt werden. - Wie schneide ich die roten Elemente also ab?
    PS: Es gibt später noch mehr Monitore etc. im Fenster des Programms (Flugsimulator). Daher brauche ich eine Möglichkeit über einen bestimmten Bereich hinaus die Objekte automatisch abzuschneiden.
5.657 Beiträge seit 2006
vor 3 Jahren

Alles, was außerhalb des Viewports ist, wird sowieso nicht gerendert.

Ansonsten siehe die 4 Möglichkeiten in der Antwort zu How to clip before DrawUserPrimitive?

Weeks of programming can save you hours of planning