AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Multimedia Delphi Mit DirectX->DrawPrimitive umrandete Flächen zeichnen
Thema durchsuchen
Ansicht
Themen-Optionen

Mit DirectX->DrawPrimitive umrandete Flächen zeichnen

Ein Thema von TOC · begonnen am 14. Nov 2009 · letzter Beitrag vom 15. Nov 2009
Antwort Antwort
Benutzerbild von TOC
TOC

Registriert seit: 5. Jan 2005
Ort: Trier
248 Beiträge
 
Delphi 7 Personal
 
#1

Mit DirectX->DrawPrimitive umrandete Flächen zeichnen

  Alt 14. Nov 2009, 06:37
Hi!

Also, vorab: Ich Verwende immer noch Delphi 3.0 Pro , mangels eine besseren Version, zusammen mit DelphiX von Hiroyuki Hori .
Ich habe zwar auch ein Delphi7 Pe, auch mit DelphiX, aber ich verwende es nur sehr ungern zum programmieren. Aber dass nur zur Info, meine Frage bezieht sich mehr auf Microsoft DirectX.

Ich habe folgendes Problem: Ich möchte mit der Function "DrawPrimitive" eine Fläche (bestehend aus mehreren Dreiecken) rendern und mit einer Farbe ausfüllen (also OHNE Texture). Ok, das klappt. Aber ich möchte dass das Dreieck sagen wir mal Innen mit Rot ausgefüllt und außen herum ein blauer Rand gezeichnet wird. Und das ist das Problem, ich weiß echt nit wie. Ich habe schon die halbe MSN-Bib nach einer Lösung abgesucht. Es gibt nämlich ein Problem mit dem Z-Puffer bei dieser Sache. Also, im Moment zeichne ich das Dreieck (bzw. eine komplexere Form aus Dreiecken) mit DrawPrimitive->TriangleList oder ->TriangleStrip, und anschließend zeichne nochmal den Rahmen herum mit DrawPrimitive->LineList oder ->LineStrip. Das ist erstens nicht sehr Effektiv und zweitens führt dies dazu das der Rand um das Objekt herum optisch zerrissen wird, also keine durchgezogene Linie. Und das liegt daran das der (blaue) Pixel vom Rand in Z-Richtung mal vor, mal hinter dem (roten) Pixel der Dreieck-Fläche berechnet wird . Je nachdem wie ich die Form sich dann im 3D-Raum bewegen und rotieren lasse ist der Rahmen mal durchgezogen, mal gestrichelt und mal leider völlig unsichtbar.

Meine Frage: Kennt einer von Euch eine Lösung für diese Problem? Vielleicht einen RenderState denn man setzen kann? Oder irgendeinen FillMode, oder was auch immer.

Ich bin für jeden Hinweis zur Lösung dieses Problems echt dankbar.

MfG, TOC!
Lars Uwe Hohmann
"Wäre die Erde eine Bank, ihr hättet sie längst gerettet!"
(Zitat GreenPeace)
  Mit Zitat antworten Zitat
Medium

Registriert seit: 23. Jan 2008
3.686 Beiträge
 
Delphi 2007 Enterprise
 
#2

Re: Mit DirectX->DrawPrimitive umrandete Flächen zeichnen

  Alt 14. Nov 2009, 16:12
Zwei Dinge fallen mir ein:

1) Über eine Textur, die eben einen blauen Rand und rotes Inneres hat. Nachteile: Die Texcoords könnten evtl. gräßlich werden, und der Rand wächst mit der Fläche eines Dreiecks - ist also u.U. verschieden Dick in ein und dem selben Patch.
2) Mache den Wireframe-Pass mit einem gaaanz leicht "gewachsenem" Patch. Die Normalenvektoren für jeden Vertex hast du ja wahrscheinlich schon, also dann einfach die Vertices um einen Bruchteil ihres Norm. verrücken. Da es ja wirklich nur um ein "Titsch" geht und es ein Wireframe wird ist, ist das sonst dabei teilweise auftretende Problem der Selbstschneidung kaum vorhanden bzw. von Bedeutung. (Nämlich hochstens dort, wo sich das Objekt selbst berührt.)
"When one person suffers from a delusion, it is called insanity. When a million people suffer from a delusion, it is called religion." (Richard Dawkins)
  Mit Zitat antworten Zitat
Benutzerbild von TOC
TOC

Registriert seit: 5. Jan 2005
Ort: Trier
248 Beiträge
 
Delphi 7 Personal
 
#3

Re: Mit DirectX->DrawPrimitive umrandete Flächen zeichnen

  Alt 14. Nov 2009, 17:46
Hi!

Vielen Dank für Deine Antwort und Deine Vorschläge.

Zitat von Medium:
Zwei Dinge fallen mir ein:
1) Über eine Textur, die eben einen blauen Rand und rotes Inneres hat. Nachteile: Die Texcoords könnten evtl. gräßlich werden, und der Rand wächst mit der Fläche eines Dreiecks - ist also u.U. verschieden Dick in ein und dem selben Patch.
Also, die Idee hatte ich im Prinzip auch schon. Aber, mit ner Texture geht es leider nicht. Die Texture-Koords zu berechnen ist nicht das große Problem. Ich habe eine Funktion die ein Rechteck zeichnet, und in dem Rechteck ist ein kleineres Rechteck mit drehbarem Winkel ausgespart, also durchsichtig. Dazu setze ich das große Rechteck aus 4 Rechtecken und, wennn der innere Drehwinkel ungleich 0 ist, zusätzlich 4 Dreiecken zusammen.In dem aktuellen Programm verwende ich diese Funktion und zeichne 6 Quadrate so räumlich versetzt dass ein Würfel entsteht, ja, und die kleineren durchsichtigen Quadrate drehen sich um ihre Mittelachse, und der ganze Würfel dreht sich noch dazu im Raum. Also ich könnte ja eine Texture erzeugen mit einem beispielsweise blauem Rand und einer roten Füllung, nur, ich muss ja auch das kleine ausgesparte Quadrat im inneren Umranden, und das dreht sich um sich selbt- also geht es nicht mit einer Texture...

Zitat von Medium:
2) Mache den Wireframe-Pass mit einem gaaanz leicht "gewachsenem" Patch. Die Normalenvektoren für jeden Vertex hast du ja wahrscheinlich schon, also dann einfach die Vertices um einen Bruchteil ihres Norm. verrücken. Da es ja wirklich nur um ein "Titsch" geht und es ein Wireframe wird ist, ist das sonst dabei teilweise auftretende Problem der Selbstschneidung kaum vorhanden bzw. von Bedeutung. (Nämlich hochstens dort, wo sich das Objekt selbst berührt.)
Ja, habe ich auch schon versucht. Klappt leider ebenfalls nit. Ich habe alle Z-Koordinaten von der Umrandung einfach mal eiskalt um einen Betrag nach vorne geschoben, weil ich hoffte dass sie dann in Z-Richtung über der Grafik zu liegen kommen. Klappt aber nicht, weil: Wenn ich den Z-Unterschied so groß mache, dass die Linien nicht mehr unterbrochen werden, dann sind die Linien dafür aber in der X- und Y-Position versetzt und auch in der Länge vergrößert und decken sich nicht mehr mit der darunterliegenden Grafik...

Echt blöd. Fällt Dir, oder sonst irgend jemandem da draußen, vielleicht noch etwas anderes zur Lösung dieses Problems ein?
Ich freue mich über jeden weiteren Vorschlag und jede weitere Idee!

Grüße von TOC!
Lars Uwe Hohmann
"Wäre die Erde eine Bank, ihr hättet sie längst gerettet!"
(Zitat GreenPeace)
  Mit Zitat antworten Zitat
Medium

Registriert seit: 23. Jan 2008
3.686 Beiträge
 
Delphi 2007 Enterprise
 
#4

Re: Mit DirectX->DrawPrimitive umrandete Flächen zeichnen

  Alt 14. Nov 2009, 18:46
Versetzen auf der Z-Achse ist nicht was ich vorgeschlagen hab Dass das oft nicht ganz zum Ziel führt ist klar. Deswegen ja um die Normalenvektoren verschieben!

Edit: Noch was. Viele machen auch den Fehler, das Near- und Far-Clipping vieeel zu nah bzw. weit zu setzen, wodurch sich der Z-Buffer arg auseinanderzieht. Vor allem ist da wohl das Near-Clipping kritisch, da sich der Z-Buffer logarithmisch von vorn nach hinten verteilt, so dass du je näher ein Objekt ist eine größere Auflösung in Z hast. Das hilft zwar auch nichts wenn du garnicht oder nur um Z verschiebst, aber damit kann man sich mit meiner Methode mit recht kleinem Wachstum begnügen ohne dass einem der Z-Buffer zu schnell einen Strich durch die Rechnung macht.
Im Zweifel kannst du auch einfach mal den Z-Buffer in 32Bit versuchen (können nur nicht alle GraKas, und der Stencil-Buffer ist flöten - wenn du den brauchst).
"When one person suffers from a delusion, it is called insanity. When a million people suffer from a delusion, it is called religion." (Richard Dawkins)
  Mit Zitat antworten Zitat
Benutzerbild von TOC
TOC

Registriert seit: 5. Jan 2005
Ort: Trier
248 Beiträge
 
Delphi 7 Personal
 
#5

Re: Mit DirectX->DrawPrimitive umrandete Flächen zeichnen

  Alt 14. Nov 2009, 19:08
Hi!

Zitat von Medium:
Versetzen auf der Z-Achse ist nicht was ich vorgeschlagen hab Dass das oft nicht ganz zum Ziel führt ist klar. Deswegen ja um die Normalenvektoren verschieben!
Sorry, ich habe Deine Idee wohl noch nicht verstanden. Was meinst Du denn mit "um die Normalenvektoren verschieben". Klar, ok, ich habe in den Vertices den Vector selbst als XYZ und ein dazugehöriges Normal, dass vom Mittelpunkt aus weg in die Richtung der Gesamtfläche zeigt, so dass DX Lichteffekte berechnen kann etc. . Aber wie soll ich den Vector um das Normal verschieben? Irgendwie raffe ich das nicht. Könntest Du es mir vielleicht bitte genauer erklären wie Du das meinst? Vielleicht den Vector aus dem Vertice einfach skalieren, mit einer Scale-Matrix also multiplizieren, also etwas vergrößern, und im inneren Rechteck für die ausgesparrte Umrandung skalieren und etwas verkleinern?

Auf jeden Fall Danke für Deine Antwort, ich raufe mir hier schon die Haare aus Wenn ich keine Lösung finde hab ich bald ne Glatze , und das obwohl ich Glatzen hasse !

Grüße von TOC.
Lars Uwe Hohmann
"Wäre die Erde eine Bank, ihr hättet sie längst gerettet!"
(Zitat GreenPeace)
  Mit Zitat antworten Zitat
Benutzerbild von TOC
TOC

Registriert seit: 5. Jan 2005
Ort: Trier
248 Beiträge
 
Delphi 7 Personal
 
#6

Re: Mit DirectX->DrawPrimitive umrandete Flächen zeichnen

  Alt 14. Nov 2009, 19:26
Zitat von Medium:

Edit: Noch was. Viele machen auch den Fehler, das Near- und Far-Clipping vieeel zu nah bzw. weit zu setzen, wodurch sich der Z-Buffer arg auseinanderzieht.
Also, ich nehme :

Delphi-Quellcode:
...
  D3DUtil_SetProjectionMatrix(Matrix, Pi/4, Aspect, 50, 20000000);
...
Also NearClipping 50 und FarClipping 20000000. Meinst Du das es daran liegen könnte?

Ich könnte das Programm auch Posten dann könntest Du es Dir genauer ansehen was mein Problem ist- obwohl ich dies nit gerade so gerne tun würde, weil es ist nur ein DxTest-Programm und auch noch nit fertig...
Aber wenn es helfen würde dann würde ich es Posten (die .exe).

Grüße von TOC!
Lars Uwe Hohmann
"Wäre die Erde eine Bank, ihr hättet sie längst gerettet!"
(Zitat GreenPeace)
  Mit Zitat antworten Zitat
Benutzerbild von TOC
TOC

Registriert seit: 5. Jan 2005
Ort: Trier
248 Beiträge
 
Delphi 7 Personal
 
#7

Re: Mit DirectX->DrawPrimitive umrandete Flächen zeichnen

  Alt 15. Nov 2009, 09:53
Hi Medium!

Vielen Dank für Deine Vorschläge und Hilfe, es hat mich auf einige neue Ideen gebracht.

Zitat von Medium:
Edit: Noch was. Viele machen auch den Fehler, das Near- und Far-Clipping vieeel zu nah bzw. weit zu setzen, wodurch sich der Z-Buffer arg auseinanderzieht.
Ok, das wusste ich auch noch nicht. Ich habe in meinem Programm das FarClipping jetzt mal runter gesetzt auf 2000. Irgendwie sieht die Grafik dadurch wesentlich kristalliner aus, irgendwie einfach besser, vielleicht weil es jetzt weniger Z-Rundungsfehler gibt. Super Tip !

Wie Du das mit dem verschieben um die Normalen meinst habe ich immer noch nit kapiert, aber, egal, mir ist ein neuer Trick eingefallen. Also, ich berechne mir zuerst die 4 Vektoren von dem Rechteck, dann ziehe ich davon zweidimensional gesehen einen einstellbaren kleinen Betrag ab und berechne nochmal 4 Vektoren für ein etwas kleineres Rechteck bzw. Quadrat. Zum Zeichnen der ausgefüllten Fläche nehme ich dann das kleinere Quadrat, und zeichne nun ZWEI mal den WireFrame herum, einmal mit dem etwas verkleinerten Vektoren und einmal mit den Vektoren in Normalgröße- funzt super! Mit dem ausgesparten Rechteck/Quadrat im Inneren Umrande ich das ganze ebenso. Ok, es ist etwas mehr Rechen- und Zeichenaufwand, weil ich ja den inneren und äußeren Rand nun 2 mal Zeichne, also 4 Ränder, und das pro Quadrat, also mal 6 für meinen Würfel. Trotzdem: Der Aufwand lohnt sich, da die Umrandungen jetzt nahezu aus durchgezogenen Linien bestehen und die Optik 10 mal besser ist.
Und als Nebeneffekt sehen die Umrandungen jetzt auch noch etwas dicker aus als vorher, das erleichtert das erkennen der Grafik enorm!

Grüße von TOC!
Lars Uwe Hohmann
"Wäre die Erde eine Bank, ihr hättet sie längst gerettet!"
(Zitat GreenPeace)
  Mit Zitat antworten Zitat
Medium

Registriert seit: 23. Jan 2008
3.686 Beiträge
 
Delphi 2007 Enterprise
 
#8

Re: Mit DirectX->DrawPrimitive umrandete Flächen zeichnen

  Alt 15. Nov 2009, 17:55
Mit um die Normalenvektoren verschieben meine ich quasi einfach "V+k*N", V ist ein Vertex, N sein Normalenvektor, und k ein kleiner konstanter Wert um den das Mesh wachsen soll. Da die Normalen ja immer "von der Oberfläche weg" zeigen, bewirkt ein Verschieben um diese eben ein Wachstum des Volumens. Im Fall eines zentrierten Würfels ist das gleich einer Skalierungsmartix, bei komplexeren Objekten ist das Ergebnis allerdings unterschiedlich, und eine reine Skalierung ist dann nicht mehr wirklich zielführend (da man sich dann auch Teile "in" das vorige Objekt hinein schiebt).
Ein weiterer Vorteil dessen ist, dass die Normalenvektoren nachher auch noch stimmen ohne sie neu zu berechnen. Auch das ist bei einer einfachen Skalierung nicht unbedingt mehr gegeben.
"When one person suffers from a delusion, it is called insanity. When a million people suffer from a delusion, it is called religion." (Richard Dawkins)
  Mit Zitat antworten Zitat
Benutzerbild von TOC
TOC

Registriert seit: 5. Jan 2005
Ort: Trier
248 Beiträge
 
Delphi 7 Personal
 
#9

Re: Mit DirectX->DrawPrimitive umrandete Flächen zeichnen

  Alt 15. Nov 2009, 18:47
Hi Medium!

Zitat von Medium:
Mit um die Normalenvektoren verschieben meine ich quasi einfach "V+k*N", V ist ein Vertex, N sein Normalenvektor, und k ein kleiner konstanter Wert um den das Mesh wachsen soll. Da die Normalen ja immer "von der Oberfläche weg" zeigen, bewirkt ein Verschieben um diese eben ein Wachstum des Volumens.
Oh, super, diesmal habe ich Dich verstanden, vielen Dank !

Zitat von Medium:
Ein weiterer Vorteil dessen ist, dass die Normalenvektoren nachher auch noch stimmen ohne sie neu zu berechnen. Auch das ist bei einer einfachen Skalierung nicht unbedingt mehr gegeben.
Den Trick werde ich mir auf jeden Fall merken. In meinem konkreten Testprogramm hier wäre dies aber etwas Problematisch- weil bei mir die Normals nicht normalisiert sind. Ich habe kurzerhand DirectX per Renderstate-->NormalizeNormals dazu überedet sie automatisch zu normalisieren... Nicht aus Faulheit, sondern das hat einen praktischen Grund: die Normals haben bei mir, je nach Grafik, unterschiedliche Längen und Farben. Und ich kann in meinem Programm einen Debug-Modus einschalten, der die Normals dann von dem Vector aus wegzeigend einzeichnet. So kann ich also optisch kontrollieren ob ich diese Normals richtig berechnet habe.

Gerade schreibe ich meine Rechteck-Funktion, aus der ich ja meinen Würfel zusammen setzte, nochmal um. Dank Dir bin ich auf diesen Gedanken gekommen: Ich zeichne jetzt nicht mehr einen einfachen WireFrame 2 mal, sondern ziehe einen einstellbaren Betrag von der Länge und Höhe ab, und diese dadurch außen neu entstehenden Rechtecke fülle ich dann wieder mit DrawPrimitive->TriangleList in einer anderen Farbe aus. Mit anderen Worten: Ich mache die Rahmenbreite nun mit einstellbarer Breite. Vielen Dank das Du mich auf diesen Idee gebracht hast !

Grüße von TOC!
Lars Uwe Hohmann
"Wäre die Erde eine Bank, ihr hättet sie längst gerettet!"
(Zitat GreenPeace)
  Mit Zitat antworten Zitat
Medium

Registriert seit: 23. Jan 2008
3.686 Beiträge
 
Delphi 2007 Enterprise
 
#10

Re: Mit DirectX->DrawPrimitive umrandete Flächen zeichnen

  Alt 15. Nov 2009, 19:37
Immer gern. 3D Gefummel macht halt auch immer wieder Spaß
"When one person suffers from a delusion, it is called insanity. When a million people suffer from a delusion, it is called religion." (Richard Dawkins)
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 18:45 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz