Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Multimedia (https://www.delphipraxis.net/16-multimedia/)
-   -   Delphi Texturbearbeitung (https://www.delphipraxis.net/173580-texturbearbeitung.html)

VkPenguin 5. Mär 2013 16:58

Texturbearbeitung
 
Hallo zusammen,
ich habe ein Programm geschrieben, welches eine 2D "Karte", z.B. eines Labyrinths, in eine (Pseudo-)3D-Umgebung umwandelt, in der man sich frei bewegen kann. Ich verwende dabei keine Zusätze wie Genesis3D oder ähnliches. Nachdem ich noch einige Soundeffekte eingefügt habe funktioniert das ganze auch schon recht gut und man fühlt sich wie in einem (zugegebenermaßen schlechten) Computerspiel. Um die Wirkung zu steigern habe ich statt einfacher Farben (z.B. Grau für Wand) einen Algorithmus eingefügt, der die Farben für eine bessere Tiefenwirkung manipuliert. Viel besser ist der Effekt natürlich noch, wenn man statt einfacher Farben Texturen verwendet.

Das ganze funktioniert bei mir im Moment so:

Delphi-Quellcode:
...Canvas.Brush.Bitmap:=[TEXTUR-BITMAP]
...Canvas.FloodFill(...); oder Canvas.FillRect(...);
Dabei ergeben sich aber zwei Probleme. Zum einen verändert sich die Position der Pattern-Textur auf dem Gegenstand beim Bewegen mit (Wenn man z.B. an einer Wand mit einem Symbol darauf vorbeigeht würde immer nur den Teil des Symbols sehen, der noch vor einem liegt, bei meiner Methode zu zeichnen fängt die Textur von Anfang neu an, man würde also den Beginn des Symbols sehen, aber nicht das Ende). Dieses Problem möchte ich aber erst einmal zurückstellen, ich erwähne es nur, weil es eventuell mit dem anderen Problem zusammenhängt.

Zweitens müssten die Texturen ja eigentlich in der Tiefe "kleiner" werden (Seht euch mal dieses und dieses Bild an, dann versteht ihr denke ich, was ich meine) Ich suche also einen Weg, wie ich eine Wandtextur so bearbeiten kann, dass ich sie auf meine vorberechneten Formen auftragen kann und dabei eine solche Tiefenwirkung haben.

Beim Suchen bin ich auf das Stichwort "inverses Mapping" im Zusammenhang mit folgender Formel gestossen:

u = (u/z)/(1/z)
v = (v/z)/(1/z)

Ich verstehe allerdings nicht so ganz, was mir das sagen soll. Hat jemand vielleicht einen Tipp für mich?

Vielen Dank für die Hilfe!

Aphton 5. Mär 2013 17:13

AW: Texturbearbeitung
 
Ich weiß nicht genau, wie du vorgehst, aber im Grunde müsste man eine Projektions Matrix und ne View Matrix erstellen/managen.. Diese multiplizieren und mit der dabei entstehenden Matrix kannst du einzelne Vektoren transformieren.
Kannst du Codeteile zeigen?

VkPenguin 5. Mär 2013 19:58

AW: Texturbearbeitung
 
Hey, Danke erstmal für Deine Antwort. :-)

"Matrix" ist mir in diesem Zusammenhang noch gar nicht begegnet, werd' ich mir gleich mal anschaun.

Klar zeig ich Dir gern Ausschnitte aus dem Code, ich weiß nur nicht, was genau im speziellen wichtig ist. Man sollte nur erstmal wissen, dass meine "3D-Engine" natürlich sehr rudimentär ist, da ich immer noch Anfänger in Delphi bin und auch nur in meiner Freizeit programmiere (Auch wenn ich finde, dass das Ergebnis bisher schon ganz gut aussieht).

Mal ganz grob erklärt, damit Du erstmal eine Vorstellung meines Ansatzes hast: Ich habe ein Array mit den Positionen und Daten der Wände etc. und einen festen Fluchtpunkt. Mit Sinussatz und ähnlichem rechne ich die Verhältnisse im Raum aus (also das eine Mauer weiter hinten "kürzer" ist zum Beispiel) und verbinde die so berechneten Eckpunkte dann mit
Delphi-Quellcode:
Canvas.LineTo(...);
. Dann Fülle ich die dadurch entstandenen Flächen einfach mit den Oben genannten befehlen aus. Das ist natürlich keine perfekte Lösung, aber ich bin wie gesagt eben Anfänger und eigentlich so schon stolz, das überhaupt hinbekommen zu haben. :)

In einer neuen Version habe ich nun die
Delphi-Quellcode:
Canvas.Brush.Color:=$...
-Befehle einfach durch
Delphi-Quellcode:
Canvas.Brush.Bitmap:=[Bitmap]
ersetzt, um mein kleines Spiel ein wenig plastischer wirken zu lassen. Es sieht auch eigentlich nicht so schlecht aus (abgesehen davon, dass ich noch keine wirklich guten Texturen gefunden habe), aber sobald man sich bewegt merkt man schnell, dass das ganze ziemlich unrealistisch ist. Wenn die Texturen ebenso "kleiner" würden wie die Wände wäre das schon deutlich besser, ich finde aber keinen Ansatz, wie ich das umsetzten soll.

Aphton 5. Mär 2013 20:50

AW: Texturbearbeitung
 
Oh, ok.. Also du machst es dir zu umständlich.. als Anfänger würde ich mich zuerst mal den existierenden Tools bedienen.
Für computer graphische Sachen verwendet man entweder DirectX oder OpenGL.
OpenGL ist imho viel anfängerfreundlicher und du darfst sehr bald schon Ergebnisse sehen.
Weiters gibts ne tolle Delphi Community drumherum.
Nimm dir die Zeit und arbeite diese Tutorials durch!
Da werden im späteren Verlauf auch näher auf rendertechnische Sachen eingegangen.
Matrizen werden auch erklärt!

VkPenguin 5. Mär 2013 21:25

AW: Texturbearbeitung
 
Ja, das kenne ich schon, der Spass liegt für mich aber darin es selbst zu programmieren.. Bisher bin ich damit ja auch ganz gut zurecht gekommen, aber hier weiß ich echt nicht weiter. Werde mir die Tutorials aber trotzdem mal ansehen, vielleicht erfahre ich da ja was. Hast du sonst vielleicht noch einen Tipp ? Oder sonst jemand?

Jens01 5. Mär 2013 23:11

AW: Texturbearbeitung
 
Zitat:

Bisher bin ich damit ja auch ganz gut zurecht gekommen, aber hier weiß ich echt nicht weiter.
Die Angelegenheit legt exponential an Schwierigkeit zu.
Eine Alternative ist noch GLScene, das baut auf OpenGL auf.

Medium 6. Mär 2013 09:09

AW: Texturbearbeitung
 
Zitat:

Zitat von VkPenguin (Beitrag 1206025)
der Spass liegt für mich aber darin es selbst zu programmieren..

OpenGL und DX machen jetzt auch nicht so wahnsinnig viel automatisch - da kommst du sicherlich noch genug zum Selbermachen. Allerdings sind die 3D APIs gerade was das Handhaben von Texturen angeht doch eine große Hilfe (in Sachen Komfort aber auch Geschwindigkeit).

Dein Problem, dass der von der Windows GDI bereit gestellte Bitmap-Filler keine perspektivische Verzerrungen kennt ist unumgänglich. Du müsstest auf diese einfach Art des Flächen füllens gänzlich verzichten, und im Grunde deine Bitmaps Pixel für Pixel selbst sowohl mappen als auch zeichnen. Ohne eine vernünftige Matrixdarstellung der Welt ist das schon fast ein Ding der Unmöglichkeit (zumindest wird man oft mit Singularitäten und horrend unübersichtlichen und daher fehlerträchtigen Termen konfrontiert).
Beim Textur-Mapping scheint mir eine Grenze deines prinzipiellen Ansatzes einfach erreicht zu sein. Bzw. wäre der Aufwand und die Problemchen die man sich damit mittelfristig einhandeln würden das Ergebnis wohl nicht wert.

VkPenguin 6. Mär 2013 12:21

AW: Texturbearbeitung
 
Auch wenn ich nun natürlich immer noch nicht weiter bin weiß ich immerhin, dass es so, wie ich es mir erst dachte wohl nicht geht. Ich würde aber trotzdem gern auf Erweiterungen verzichten, zur Not lasse ich Texturen eben ganz weg. Einen (natürlich keineswegs optimalen) Weg gibt es aber glaube ich doch (und das würde mir schon reichen, es ist ja nur ein kleines Projekt zum Spaß und zum Üben der Syntax): wenn ich im Code

Delphi-Quellcode:
Canvas.StretchDraw(rect(...)),[TEXTUR]);
schreibe, kommt im Prinzip das richtige raus. Nun ist Stretchdraw natürlich weder sonderlich effizient noch geschickt, aber immerhin funktionierts so. Allerdings funktioniert das ja nur mit Wänden, die exakt Rechteckig erscheinen. Seitenwände, also quasi Parallelogramme, kann ich damit nicht füllen. Hat jemand eine Idee, wie das geht? Ich könnte die Bitmap zwar passend zuschneiden/skalieren, aber wie kann ich die Bitmap zur Laufzeit skalieren ?

Medium 6. Mär 2013 13:02

AW: Texturbearbeitung
 
Das ist eben genau der Knackpunkt, auf den ich quasi hinaus wollte ;) Ohne Matrizen wird diese Transformation zum einen kostspieliger (Trigonometrie ist einfach lahm), und ziemlich hässlich. Du musst deine Bilder Pixel für Pixel anfassen, und jeden quasi wie einen Eckpunkt deiner Geometrie auch durch die Projektionsmethode schubsen. Jetzt ganz kurz und vereinfacht gesagt.

mkinzler 6. Mär 2013 13:04

AW: Texturbearbeitung
 
P.S. ohne mathematische Kenntnisse tutst du dich auch bei Verwendung von OpenGL oder DX schwer.

VkPenguin 6. Mär 2013 13:10

AW: Texturbearbeitung
 
Hm. Du scheinst dich da ja gut auszukennen; weißt du denn, wie ich genug über Matrizen lernen kann, um das umzusetzen? Ich kenne Matrizen nur aus dem Matheunterricht und wüsste so jetzt nicht, was das mit Projektionsberechnungen zu tun haben soll ;-)

Aber um nochmal kurz auf meinen ursprünglichen Ansatz zurückzukommen: Es gibt wirklich keine Methode wie Stretchdraw(Obenrechts,Obenlinks,Untenrechts,Unten links,Bild)? Also genau dasselbe nur allgemein für Vierecke?

*Edit*: @Mkinzler: Mit Matrizenrechnung bin ich durchaus vertraut, ich hab nur keine Ahnung, wie ich die auf mein Problem anwenden soll..

mkinzler 6. Mär 2013 13:26

AW: Texturbearbeitung
 
Stichwort homogenisierte Koordinaten/Normalvektor. In einer Matrizenoperation kann ein Vektor auf einmal skaliert, rotiert und transponiert werden. Intern arbeiten die Grafikkarten auch mit diesen 4D-Tupeln.

http://iasp2.informatik.htw-dresden....Dgrafik_vp.pdf
http://www.hki.uni-koeln.de/sites/al...e_3dgrafik.pdf
http://www2.informatik.hu-berlin.de/.../3D-basics.pdf

Aphton 6. Mär 2013 13:27

AW: Texturbearbeitung
 
Lies den ganzen Thread nochmal durch... Links sind bereits gegeben!

VkPenguin 6. Mär 2013 14:03

AW: Texturbearbeitung
 
Damit werde ich wahrscheinlich erstmal eine Weile zu tun haben, vielen Dank an Euch. :-) Hab es zusätzlich eben mal mit einfachem Skalieren des Patterns probiert, wenn man genug Zwischenschritte einbaut sieht das für den Anfang auch schon gar nicht so schlecht aus, auch wenn es eigentlich natürlich quatsch ist ;-)

*Edit* Eine (hoffentlich) ganz kurze Nachfrage noch: Wie kann ich Floodfill so verwenden, dass der Rand ebenfalls gefüllt wird? Also Floodfill+1Pixel in etwa.. Oder muss ich tatsächlich die ganze Fläche erst mit der Farbe des Rands füllen und dann nochmal mit FSSurface die andere Farbe/Textur drüber?

VkPenguin 10. Mär 2013 09:47

AW: Texturbearbeitung
 
Hallo noch einmal,

habe eure Tipps so gut ich konnte umgesetzt (also neu angefangen ;-) ). Das neue Programm auf Vektorbasis funktioniert auch schon ganz gut, es sieht zumindest nicht schlecht aus. Ich habe allerdings eine Frage zur Transformationsmatrix (Wie hier erklärt).

Wenn ich das so umsetze, passiert rein garnichts, ich wüsste aber auch nicht, wie es nach dem Modell anders sein sollte.

Laut der Internetseite soll die Transformationsmatrix so aussehen (zum verschieben)

Code:
(X+a)  (1 0 0 0) (X)
(Y+B)  (0 1 0 0) (Y)
(Z+C) = (0 0 1 0)*(Z)
(W)    (a b c 1) (W)
Also zum Beispiel:

Code:
(5+3)  (1 0 0 0) (5)
(6+2)  (0 1 0 0) (6)
(7+1) = (0 0 1 0)*(7)
(1)    (3 2 1 1) (1)
Aber man sieht doch sofort, dass am Ende immer nur ein größerer W-Wert rauskommt und alle anderen gleich bleiben.... wie soll das denn funktionieren? :?:

terence14 10. Mär 2013 12:48

AW: Texturbearbeitung
 
Ich habe auch eine zeitlang mit solchen Problemen
with TextureMapping zu tun und mir half der Quellcode
von Ken Silverman weiter, der diesen auch veröffentlicht
hat.

Es handelt sich um die DukeNukem Build Engine und seinem
Level Editor, mit dem man zwischen 2D (einer Karte) und
einem 3D (Texture Setzer) umschalten konnte.

Alles in C geschrieben, was für mich aber kein Problem
darstellte.

Suche mal nach Ken Silverman.

MfG,
terence

VkPenguin 10. Mär 2013 13:09

AW: Texturbearbeitung
 
Hi, vielen Dank für den Tipp, das werd ich mal machen :) Trotzdem würde mich aber der Sinn dieser Matrizenrechnung interessieren - ich komme einfach nicht darauf, was ich falsch verstanden habe. Hat das vielleicht etwas mit der Homogenisierung der Koordinatenpunkte zu tun ?

Aphton 10. Mär 2013 18:36

AW: Texturbearbeitung
 
Jo, dividiere den Vektor, der dabei rauskommt durch die w Komponente durch!
Ich weiß ned, ob das auch auf die Matrix zutrifft. Aber mit Vektoren sollte das so klappen!

VkPenguin 10. Mär 2013 20:27

AW: Texturbearbeitung
 
Wie meinst Du das ? Dann würden sich doch alle Koordinaten verändern...?

VkPenguin 10. Mär 2013 20:48

AW: Texturbearbeitung
 
Ich hab mal überlegt, eigentlich müsste die Transformationsmatrix

Code:
(1 0 0 A)
(0 1 0 B)
(0 0 1 C)
(0 0 0 1)
lauten. Getestet und siehe da - es funktioniert.. Bin mir daher ziemlich sicher, dass die Darstellung des Links einfach falsch ist - oder irre ich mich?

Jens01 10. Mär 2013 22:09

AW: Texturbearbeitung
 
http://wiki.delphigl.com/index.php/Tutorial_Nachsitzen

Medium 11. Mär 2013 08:49

AW: Texturbearbeitung
 
Es kommt darauf an, ob man mit sog. Zeilen- oder Spaltenvektoren arbeitet. Beide Varianten sind letztlich gleichwertig, nur muss man sich für eines entscheiden und durchgängig benutzen. Ich vermute mal (habs nicht angeschaut), dass deine Quelle für die Transformationsmatrix mit Zeilenvektoren arbeitet - imho die exotischere Form, und auch weniger intuitiv. (Zumindest für mich :))

VkPenguin 12. Mär 2013 00:18

AW: Texturbearbeitung
 
Das wird's sein - da hätte man eigentlich auch so drauf kommen müssen ;-) Dann ist zumindest dieses Problem schon mal gelöst, danke an alle :-)


Alle Zeitangaben in WEZ +1. Es ist jetzt 05:33 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