AddVertex --> Nur Dreiecke??

Übersicht BlitzBasic Blitz3D

Neue Antwort erstellen

GearTechDE

ehemals 'KillerJo96'

Betreff: AddVertex --> Nur Dreiecke??

BeitragDi, Jan 24, 2012 13:41
Antworten mit Zitat
Benutzer-Profile anzeigen
Hallo, ich verstehe das Prinzip noch nicht so ganz, in der Online Hilfe wird leider nur erklärt wie man ein Dreieck macht aber ich will auch quadrate machen, für so eine kleinen feuer engine zu programmieren. ich weiß überhaupt nicht wie man solche quadrate macht, und ich bin auch nich wirklich gut in mathe deswegen weiß ich jetz schon das ich probleme bekommen werde... aber das will ich alles noch lernen ....

es wäre nett wenn mir jemand helfen kann und mir erklären wie das alles funktioniert.. danke
Mit freundlichen Grüßen: GearTechDE

ozzi789

BeitragDi, Jan 24, 2012 13:56
Antworten mit Zitat
Benutzer-Profile anzeigen
Kleiner Tipp, aus 4 Dreiecken kann man ein Viereck kreiren Wink

edit: So wie Midimaster meinte ich das.. Wink
0x2B || ! 0x2B
C# | C++13 | Java 7 | PHP 5
  • Zuletzt bearbeitet von ozzi789 am Di, Jan 24, 2012 14:38, insgesamt 2-mal bearbeitet

Xeres

Moderator

BeitragDi, Jan 24, 2012 14:01
Antworten mit Zitat
Benutzer-Profile anzeigen
Warum vier wenn zwei Dreiecke auch reichen?
Nicht vergessen, dass man die Vertices in der richtigen Reihenfolge verbinden muss. Stift & Karopapier könnten hier hilfreich sein.
Win10 Prof.(x64)/Ubuntu 16.04|CPU 4x3Ghz (Intel i5-4590S)|RAM 8 GB|GeForce GTX 960
Wie man Fragen richtig stellt || "Es geht nicht" || Video-Tutorial: Sinus & Cosinus
T
HERE IS NO FAIR. THERE IS NO JUSTICE. THERE IS JUST ME. (Death, Discworld)
 

PhillipK

BeitragDi, Jan 24, 2012 14:31
Antworten mit Zitat
Benutzer-Profile anzeigen
Die surfaces unterstützen meines wissens nach nur dreiecke (auch wenn diverse 3d modeller auch vierecke anbieten. Diese werden aber, soweit ich weiß, als dreiecke 'übersetzt')

Um aus 2 dreiecken ein viereck zu machen, musst du lediglich 4 vertices erstellen.

Beispiel:

Code: [AUSKLAPPEN]
x-------x
|  \    |
|    \  |
x-------x


Wenn du die der reihe nach (uhrzeigersinn) erstellst, musst du dir die 'zahlen' merken. AddVertex gibt einen integer zurück, welcher den index wiederspiegelt.

also :


Code: [AUSKLAPPEN]
1-------2
|  \    |
|    \  |
4-------3


1 als erstes adden, 2 danach. usw.

Wenn du nun 2 dreiecke erstellst, achte auf die richtige reihenfolge. Sonst sind deine Triangles (dreiecke) unsichtbar (bzw nur 'von der anderen seite' sichtbar)

Also:
Dreieck 1: Vertex 1, Vertex 2, Vertex 3
Dreieck 2: Vertex 1, Vertex 3, Vertex 4

So hast du deine vier eckpunkte des Quads und kannst sie auch "normal" uv mappen. Die engine und DirectX erledigen den rest.

Midimaster

BeitragDi, Jan 24, 2012 14:37
Antworten mit Zitat
Benutzer-Profile anzeigen
Wenn Du ein Viereck erstellen willst, sagen wir ABCD, dann erstellt Du eine Surface und fügst diese 4 Vertices hinzu.

Als nächstes fügst Du zwei Triangles hinzu, nämlich ABC und ACD. Die Reihenfolge der Punkte ist dabei entscheidend wichtig. Ob es funktioniert hat, testet Du zuerst mit der Option WIREFRAME TRUE, jetzt solltest Du das Drahtgittermodell sehen. Dann der zweite Test mit WIREFRAME FALSE, dann kannst Du erkennen, ob die Reihenfolge der Punkte im Triangle wirklich korrekt war.

Um auch eine Textur aufziehen zu können, achtest Du auf die korrekte Angabe der UV Koordinaten in der Vertices (die letztes beiden Parameter bei AddVertex() ):

A bekommt U=0 V=0
B bekommt U=1 V=0
C bekommt U=1 V=1
D bekommt U=0 V=1
Gewinner des BCC #53 mit "Gitarrist vs Fussballer" http://www.midimaster.de/downl...ssball.exe

darth

BeitragDi, Jan 24, 2012 14:44
Antworten mit Zitat
Benutzer-Profile anzeigen
Hallo,

das tolle an Dreiecken ist, dass man jedes Polygon in Dreiecke unterteilen kann! (Such mal nach Noobodys Subtracting Ear Ding im Codearchiv: (oder hier).

Für Quadrate kannst du dieses Bild hier nehmen:
user posted image

BlitzBasic: [AUSKLAPPEN]
Graphics3D 800, 600, 0, 2
SetBuffer BackBuffer()
Local Timer = CreateTimer(60)

Local cam = CreateCamera()
PositionEntity cam, 0, 0, -10

; <!-- Quadrat
Local quad = CreateMesh()
Local surf = CreateSurface(quad)

Local v[4]
v[0] = AddVertex(surf, -1, 1, 0, 0, 0)
v[1] = AddVertex(surf, 1, 1, 0, 1, 0)
v[2] = AddVertex(surf, 1, -1, 0, 1, 1)
v[3] = AddVertex(surf, -1, -1, 0, 0, 1)

AddTriangle(surf, v[0], v[1], v[2])
AddTriangle(surf, v[2], v[3], v[0])
; Quadrat --!>

While Not KeyHit(1)
RenderWorld

Flip 0
WaitTimer(Timer)
Cls
Wend
End


Für ParticleEngines eignet sich SingleSurface (d.h alle Partikel auf dem gleichen Surface!). Allerdings muss man dann beachten, dass man nicht "direkten Zugriff" auf die Partikel hat. Du kannst also nicht sowas wie
PositionEntity partikel[25], 25, 0, 25
benutzen. Du müsstest dir selber etwas schreiben. Am ehesten würde ich einen Type empfehlen, in dem du dir die 4 Vertices speicherst (so ähnlich wie in meinem Codebeispiel) und dann die neuen Koordinaten mit VertexCoords in jedem Schleifendurchlauf anpasst.
Alternativ könnte man natürlich auch mit ClearSurface das ganze Surface "löschen" und die Partikel neu setzen. Ich vermute allerdings, dass das rechenaufwändiger ist (bin nicht ganz sicher). Deshalb würde ich zur ersten Lösung raten.

MfG,
Darth
Diese Signatur ist leer.

aMul

Sieger des Minimalist Compo 01/13

BeitragMi, Jan 25, 2012 12:53
Antworten mit Zitat
Benutzer-Profile anzeigen
@Darth:
Es spielt von der Performance her keine Rolle, ob du 1000 Vertices pro Frame bewegst oder neu erstellst.
In der Tat kann neu erstellen schneller sein, da man weniger Overhead. Man muss nicht mehr unbedingt eine Liste mit allen Sprites/Objekten haben, etc.

Wenn es sich allerdings um nicht-bewegende Vertices handelt ist es um ein vielfaches schneller, nichts zu tun, als neu zu erstellen. Da dies bei so etwas wie einer Partikel-Engine aber praktisch nie vorkommt, kann man hier getrost jeden Frame neu zeichnen.
Panic Pong - ultimate action mashup of Pong and Breakout <= aktives Spiele-Projekt, Downloads mit vielen bunten Farben!
advASCIIdraw - the advanced ASCII art program <= aktives nicht-Spiele-Projekt, must-have für ASCII/roguelike/dungeon-crawler fans!
Alter BB-Kram: ThroughTheAsteroidBelt - mit Quelltext! | RGB-Palette in 32²-Textur / Farbige Beleuchtung mit Dot3 | Stereoskopie in Blitz3D | Teleport-Animation Screensaver

darth

BeitragMi, Jan 25, 2012 14:37
Antworten mit Zitat
Benutzer-Profile anzeigen
Sup,

Zitat:
In der Tat kann neu erstellen schneller sein, da man weniger Overhead [hat].


Würd ich so nicht unterschreiben. Beim Neuerstellen musst du zuerst das ClearSurface durchführen (je nach Regelung der Entity kann das ein einfaches VertexCount = 0 sein, oder ein wirkliches Löschen sämtlicher Vertices -> was zu tun). Zudem musst du danach sämtliche Triangles neu setzen (2x AddTriangle pro Partikel). Das gibt noch mehr zu tun und zusätzliche Funktionsaufrufe.
Wenn du einfach die Vertices verschiebst, hast du 4x VertexCoords, sonst nix. Ich sehe deinen zusätzlichen Overhead nicht.

Zitat:
Man muss nicht mehr unbedingt eine Liste mit allen Sprites/Objekten haben, etc.


Natürlich musst du sie in einer Liste haben? Wie sonst willst du sie verwalten.. Ob neu machen oder verschieben ändert an der Speicherung der Daten nichts. Es sei denn du willst die Partikel einfach einmal ins Surface eintragen und dann zufällig verschieben oder so, dann könntest du in 4er Paketen (4 Vertices pro Partikel) rumspringen. Aber das würde eher mein Vorschlag des Verschiebens unterstützen.
Ich sehe deinen Punkt nicht, wieso man die Partikel nicht in einer Liste speichern müssen soll.

Zitat:
Da dies bei so etwas wie einer Partikel-Engine aber praktisch nie vorkommt


Je nach Optimierungsstufe. Man kann natürlich verschiedene Partikeltypen einführen (stationäre - bewegliche) und selbst bewegliche können in einen Sleepmodus versetzt werden. Zum Beispiel Blutspritzer oder so, das bewegt sich einmal bis es auf dem Boden liegt, wenn mans nicht sofort killen will, kann mans liegen lassen (-> keine Veränderung mehr).

Zitat:
kann man hier getrost jeden Frame neu zeichnen.


Würd ich immernoch widersprechen. Siehe oben.
Andererseits sind das Haarspaltereien. So viel Speed wird man wahrscheinlich nicht gewinnen (grobe Vermutung, nicht überprüft). Zudem wird die ganze Fachsimpelei wahrscheinlich über den Kopf des Threaderstellers gehn :> Zuerst mal verstehen wie man aus Dreiecken ein Quadrat bastelt, dann eine Partikelengine schreiben die funktioniert und tut was man will, DANN optimieren.

MfG,
Darth
Diese Signatur ist leer.

Noobody

BeitragMi, Jan 25, 2012 16:05
Antworten mit Zitat
Benutzer-Profile anzeigen
aMul hat Folgendes geschrieben:
@Darth:
Es spielt von der Performance her keine Rolle, ob du 1000 Vertices pro Frame bewegst oder neu erstellst.
In der Tat kann neu erstellen schneller sein, da man weniger Overhead.

Das kommt sehr stark drauf an, wie B3D Resourcen intern behandelt. So, wie B3D aber reagiert, kann man davon ausgehen, dass es sowohl einen Vertex- und Indexpuffer anlegt als auch eine Kopie davon im RAM behält. Da man nirgends die Grösse einer Surface festlegen kann, ist davon auszugehen, dass beim Erstellen einer Surface der Puffer im RAM auf eine Mindestgrösse initialisiert wird und jeweils bei AddVertex bzw. AddTriangle der Puffer bei Bedarf vergrössert wird (vermutlich nach Verdoppelungsregel, um asymptotisch lineare Laufzeit zu behalten). Bei Änderungen wird entweder der veränderte Bereich oder der gesamte Inhalt der RAM-Kopie an die Vertex/Indexbuffer auf der Grafikkarte übertragen (sehr wahrscheinlich zum Zeitpunkt des nächsten Aufrufs an RenderWorld).

Sowohl bei ClearSurface und anschliessendem AddVertex als auch direktem Verändern der Vertexkoordinaten muss der ganze Buffer neu an die Grafikkarte übertragen werden. Aber: ClearSurface gibt die Kopie im RAM sehr vermutlich frei, um unbenutzte Resourcen freizugeben - d.h. bei den nächsten Aufrufen an AddVertex/AddTriangle muss tatsächlich der Buffer im RAM die ganze Zeit vergrössert werden, bis er nach etlichen AddVertex wieder die ursprüngliche Grösse erreicht hat (langsam!). Die Lösung mit dem einfachen Modifizieren der Vertexkoordinaten wird daher sehr wahrscheinlich schneller sein.

Das ganze würde sich natürlich ändern, wenn man Kontrolle über das Speichermanagement von Surfaces hätte. Paradoxerweise ist es nämlich auf neueren Treibern schneller, einen Vertex/Indexbuffer komplett freizugeben und nachher neu zu übertragen, als einen bestehenden zu modifizieren. Wenn man also die Kopie im RAM beibehielte und lediglich die Buffer auf der Grafikkarte loswürde, wäre die erste Variante mit dem löschen des Buffers schneller (wobei auch das wohl darauf ankommt, welche Grafikkarte und welche API man benutzt).
Man is the best computer we can put aboard a spacecraft ... and the only one that can be mass produced with unskilled labor. -- Wernher von Braun

aMul

Sieger des Minimalist Compo 01/13

BeitragMi, Jan 25, 2012 18:51
Antworten mit Zitat
Benutzer-Profile anzeigen
Ich möchte anmerken, dass ihr beide da sehr theoretisch herangeht und nur Vermutungen aufstellt. Mein voriger Post war hingegen auf tatsächlichen Beobachtungen und Messungen basiert. Ich benutzte seit Jahren meine eigenen Grafik-Libs in BB, und habe diese schon einige mal neu geschrieben und viel Möglichkeiten ausgetestet.
Mein Post war die Zusammenfassung meiner gewonnenen Erkenntnisse. Ich entschuldige mich, das nicht deutlich gemacht zu haben.

@Noobody:
Ich habe in der Tat keine Ahnung davon wie diese Sachen intern geregelt werden. Allerdings meine ich, irgendwo gelesen zu haben, dass BB so oder so alle Surfaces mit jedem Renderworld erneut an die Grafikkarte schickt.

@darth:
Der Overhead den ich meine entsteht zum Beispiel wenn man seine Grafik-Funktionen für mehr als nur eine Sache benutzte möchte.
Dann braucht man nicht nur die Types für die eigentlichen Spiel-Objekte(TMonster, TCar, etc.) sondern auch noch einen für das eigentliche Bild/Sprite, welches die Vertices speichert. Dieser letzte entfällt wenn du alles jeden Frame neu zeichnest(Man braucht nur noch einen Type pro Textur/Bild, aber das ist in beiden Fällen der Fall).
Weiterhin muss man sich auch um Grafiken kümmern, die nicht mehr gebraucht werden. Hier muss man entweder die Vertices von nicht mehr benutzten Objekten irgendwo hin verschieben wo sie nicht gerendert werden, oder jedes mal wenn etwas gelöscht wird das komplette Surface neu zeichnen.
Wenn nach einiger Zeit zu viele Objekte gelöscht wurden muss man das Surface aber sowieso spätestens neu erstellen, da es sonst zu voll wird und unser Programm sich verabschiedet.
Das kann man natürlich umgehen, indem man nicht benutzte Vertices und Triangles in einer separaten Liste behält und wieder benutzt wenn neue Objekte erstellt werden, was aber wiederum Overhead erzeugt.

Ich habe all diese Möglichkeiten getestet, und auch wenn ich das Ergebnis sehr schade finde, da es mir nicht erlaubt meine dabei entstandenen Algorithmen zu benutzten, war es letzten Endes doch eindeutig:
Die einfachste Lösung, nämlich jeden Frame alles neu zu Zeichnen ist nicht langsamer und teilweise schneller, als die anderen Methoden, solange die Objekte jeden Frame verschoben werden müssen. Woran das genau liegt kann ich euch nicht sagen. Allerdings ist es augenscheinlich schneller, einfach tausende von Vertices neu zu erstellen, als ein paar Types in BB herum zu schieben(leicht dramatisiert).
Neu zeichnen ist selbst dann nicht langsamer, wenn man keine extra Types hat und keine Objekte gelöscht werden. Aber ich würde behaupten, dass das in Projekten bei denen Performance ein Problem werden könnte so oder so nicht vorkommt.

Wenn nun allerdings Objekte still stehen, und nicht bewegt werden müssen sieht die Sache ganz anders aus. Genau aus diesem Grund habe ich vor ungefähr einem Jahr meine aktuelle Grafik-Lib auf beinahe das doppelte(an Code) erweitert, sodass sie nun ein umfangreiches Singlesurface-Entity-System beinhaltet, welches tatsächlich Vertices nur verschiebt, und Surfaces nur dann neu zeichnet, wenn sie zu viele unbenutzte Vertices haben(Vertices neu zu benutzten lohnt sich hier immer noch nicht, gerade wenn man den zusätzlichen Aufwand für den Programmierer betrachtet). Dieses System ist für sich viel bewegendes vollkommen unbrauchbar. Aber für statische Objekte erlaubt sie eine deutliche Performance Steigerung.


So, ich hoffe, dass hat einige Sachen näher erklärt und dass die Basis für meine früheren Behauptungen klarer geworden ist. Aber ihr seit natürlich dazu eingeladen das ganze selbst zu testen.
Panic Pong - ultimate action mashup of Pong and Breakout <= aktives Spiele-Projekt, Downloads mit vielen bunten Farben!
advASCIIdraw - the advanced ASCII art program <= aktives nicht-Spiele-Projekt, must-have für ASCII/roguelike/dungeon-crawler fans!
Alter BB-Kram: ThroughTheAsteroidBelt - mit Quelltext! | RGB-Palette in 32²-Textur / Farbige Beleuchtung mit Dot3 | Stereoskopie in Blitz3D | Teleport-Animation Screensaver

hectic

Sieger des IS Talentwettbewerb 2006

BeitragMi, Jan 25, 2012 19:42
Antworten mit Zitat
Benutzer-Profile anzeigen
Noobody hat Folgendes geschrieben:
...So, wie B3D aber reagiert, kann man davon ausgehen, dass es sowohl einen Vertex- und Indexpuffer anlegt als auch eine Kopie davon im RAM behält. Da man nirgends die Grösse einer Surface festlegen kann, ist davon auszugehen, dass beim Erstellen einer Surface der Puffer im RAM auf eine Mindestgrösse initialisiert wird und jeweils bei AddVertex bzw. AddTriangle der Puffer bei Bedarf vergrössert wird (vermutlich nach Verdoppelungsregel, um asymptotisch lineare Laufzeit zu behalten). Bei Änderungen wird entweder der veränderte Bereich oder der gesamte Inhalt der RAM-Kopie an die Vertex/Indexbuffer auf der Grafikkarte übertragen (sehr wahrscheinlich zum Zeitpunkt des nächsten Aufrufs an RenderWorld)...


Ich hab für meine Draw3D2 einen Befehl erstellt der sich FlushFace3D nennt. Dieser macht nichts anderes, als ein Surface einmal komplett mit Vertices und Triangles auszufüllen, um es anschliessend wieder zu löschen. Wird in der Standardeinstellung automtisch beim laden einer jeden Textur gemacht.

Warum? Weil, wenn man beispielsweise jedes Frame ein Quad mehr erstellt und am Ende des Frames das Face löscht, es irgendwann - auf jeden Fall fürher als maximal von der Grafikkarte Quads angezeigt werden könnten - es zu einem Überlauffehler kommt. Das automatische verdoppeln des Puffern funktioniert also nicht, oder zumindest unzureichend oder zu träge. Erstellt man jedoch einmal ein Riesen Mesh mit maximaler Anzahl Quads, so hat man später keine Probleme mehr mit dieser tubiosen Fehlermeldung.
Download der Draw3D2 V.1.1 für schnelle Echtzeiteffekte über Blitz3D

PSY

BeitragDo, Jan 26, 2012 2:36
Antworten mit Zitat
Benutzer-Profile anzeigen
Hoi,

anhand von Erfahrungswerten kann ich aMul da nur voll zustimmen.

Die Surfaces zu loeschen ist bequemer, einfacher, schneller und uebersichtlicher.
Genauso hab ichs auch bei Particle Labs gemacht.

Allerdings halte ich mich aus der statischen-object-diskussion raus. Bei allen meinen Codes gab es eigentlich immer nur massenweise rumfliegende Partikel Rolling Eyes
Zu statischen Partikelmassen kann ich deshalb keine fundierte Aussage machen Wink

L8er,
PSY
PSY LABS Games
Coders don't die, they just gosub without return

GearTechDE

ehemals 'KillerJo96'

BeitragFr, Jan 27, 2012 1:50
Antworten mit Zitat
Benutzer-Profile anzeigen
wow, danke für die vielen antworten... ich werd mich da mal richtig durchsetzen müssen um das alles so hinzubekommen, danke für euere Hilfe Wink
Mit freundlichen Grüßen: GearTechDE

Noobody

BeitragSa, Jan 28, 2012 15:19
Antworten mit Zitat
Benutzer-Profile anzeigen
Ich habe heute noch kurz getestet, welche der beiden Methoden schneller ist (VertexCoords oder einfach ClearSurface/AddVertex), und tatsächlich ist die erste Methode mit einfachem Abändern der Vertex-Koordinaten in jedem Frame ca. 10%-15% schneller.

Hier mein Testcode BlitzBasic: [AUSKLAPPEN]
Graphics3D 800, 600, 0, 2

Global VertX#, VertY#, VertZ#, VertR, VertG, VertB

Local Camera = CreateCamera()
Local Timer = CreateTimer(60)

Local Mesh = CreateMesh()
EntityFX Mesh, 3

Local Surf = CreateSurface(Mesh)

UpdateVertices2(0, Surf) ; Surface das erste Mal zu befüllen

Local Mode = 1, T# = 0.0
While Not KeyHit(1)
Local Counter = MilliSecs()

If Mode Then
UpdateVertices1(T#, Surf)
Else
UpdateVertices2(T#, Surf)
EndIf

RenderWorld
Counter = MilliSecs() - Counter

Color 0, 0, 0
Rect 0, 0, 800, 20

Color 255, 255, 255
Text 0, 0, "Frametime: " + Counter + "ms"

If Mode Then
Text 200, 0, "Methode: VertexCoords"
Else
Text 200, 0, "Methode: ClearSurface/AddVertex"
EndIf

Text 600, 0, "Leertaste zum Wechseln"

If KeyHit(57) Then Mode = Not Mode

T# = T# + 1.0

Flip 0
WaitTimer Timer
Wend
End

Function UpdateVertices1(T#, Surf)
For I = 0 To 4*10000
CalcVertexCoord(T, I)

VertexCoords(Surf, I, VertX, VertY, VertZ)
Next
End Function

Function UpdateVertices2(T#, Surf)
ClearSurface Surf, True, True

For I = 0 To 4*10000
CalcVertexCoord(T, I)

AddVertex(Surf, VertX, VertY, VertZ)

VertexColor(Surf, I, VertR, VertG, VertB)
Next

For I = 0 To 4*10000 Step 4
AddTriangle(Surf, I, I + 1, I + 2)
AddTriangle(Surf, I, I + 2, I + 3)
Next
End Function

Function CalcVertexCoord(T#, I)
Local Quad = I Shr 2
Local Index = I And 3

Quad = Quad + (Index = 1 Or Index = 2)

Local Angle# = Quad*5.0
Local Radius# = Quad*0.005 + (Index >= 2)*(Quad*0.0002 + 0.005)

VertX = Cos(Angle + T)*Radius
VertY = Sin(Angle + T)*Radius
VertZ = 6.0

PrettyColors(Angle# Mod 240.0, 1.0, 1.0)
End Function

Function PrettyColors(H#, S#, V#)
Local HI = H/60
Local F# = H/60.0 - HI

Local P# = V*(1.0 - S)
Local Q# = V*(1.0 - S*F)
Local T# = V*(1.0 - S*(1.0 - F))

Local Tuple#[3]
Select HI
Case 0
Tuple[0] = V
Tuple[1] = T
Tuple[2] = P
Case 1
Tuple[0] = Q
Tuple[1] = V
Tuple[2] = T
Case 2
Tuple[0] = P
Tuple[1] = Q
Tuple[2] = Q
Case 3
Tuple[0] = T
Tuple[1] = P
Tuple[2] = P
End Select

VertR = Int(Tuple[0]*255.0)
VertG = Int(Tuple[1]*255.0)
VertB = Int(Tuple[2]*255.0)
End Function


Wenn man also nur Vertices bewegen will, ist die erste Methode sicher vorzuziehen. Aber wenn es darum geht, einzelne Quads rauszulöschen und andere einzufügen (und das sehr oft, z.B. in jedem Frame), ist sicher die zweite Variante im Vorteil, da die CPU-Last, um leere Stellen in der Surface zu verwalten, in B3D einfach zu gross ist im Vergleich zum Geschwindigkeitsgewinn.

hectic hat Folgendes geschrieben:
Warum? Weil, wenn man beispielsweise jedes Frame ein Quad mehr erstellt und am Ende des Frames das Face löscht es zu einem Überlauffehler kommt.

Das verstehe ich nicht ganz. Was genau löschst du und was läuft über? Könntest du einen Beispielcode dazu posten?
Man is the best computer we can put aboard a spacecraft ... and the only one that can be mass produced with unskilled labor. -- Wernher von Braun

hectic

Sieger des IS Talentwettbewerb 2006

BeitragSa, Jan 28, 2012 17:34
Antworten mit Zitat
Benutzer-Profile anzeigen
Noobody hat Folgendes geschrieben:
hectic hat Folgendes geschrieben:
Warum? Weil, wenn man beispielsweise jedes Frame ein Quad mehr erstellt und am Ende des Frames das Face löscht es zu einem Überlauffehler kommt.

Das verstehe ich nicht ganz. Was genau löschst du und was läuft über? Könntest du einen Beispielcode dazu posten?

Leider ist mein System zur Zeit zerschossen. Ich kann keine DirectX-Anwendungen starten. Daher kein Beispielcode...

Wenn man ein Mesh nimmt, dann kann dieses ja 16383 Quads anzeigen. Das entspräche etwa 64k Vertices, 32k Triangles.

Lädt man nun eine Textur und zeichnet zum Beispiel jedes Frame immer zehn Quad mehr.

Also:

10 Quads zeichnen -> RenderWorld -> ClearSurface -> Flip
20 Quads zeichnen -> RenderWorld -> ClearSurface -> Flip
30 Quads zeichnen -> RenderWorld -> ClearSurface -> Flip
40 Quads zeichnen -> RenderWorld -> ClearSurface -> Flip
...

Dann erscheint irgendwann eine Fehlermeldung, nachdem man etwa 8k Quads gezeichnet hat.

Zeichnet man jedoch einmal, gleich nach dem laden einer Textur, das ganze Mesh bis an die Obergrenze voll mit Quads, löscht es und arbeitet dann das selbe Programm ab, dass bei 8k abstürzte, läuft es nun bis an die reale Obergrenze von 16k Quads.

Um dieses - für mich merkwürdige - Verhalten zu beheben, habe ich bei der Draw3D2 einen Befehl der sich FlushFace3D nennt geschrieben. Der macht nichts anderes, als gleich nach dem laden einer Textur, dieses einmal komplett voll zu machen, um es gleich wieder zu löschen. Und schon hat man keine Probleme mehr... Dieses Problem lag übrigens nicht nur an meinem System, sondern konnte bei jedem anderen nach rekonstruiert werden. Auch war bei jedem die pseudo Obergrenze absolut identisch.

FlushFace3D Code: [AUSKLAPPEN]
Function FlushFace3D(FDrawHandle%)
   
   
   
   
   ;VARIABLENDEKLARATIONEN
   Local IDrawCount%=0
   Local IDrawV0%=0
   Local IDrawV1%=0
   Local IDrawV2%=0
   Local IDrawV3%=0
   
   ;FACEBANK(AUS)WEISUNGEN
   Local LDrawFace%=PeekInt(GDrawFaceBank,FDrawHandle+DRAWBANKFACE)
   
   ;VORREINIGUNG
   RenderWorld: ClearSurface LDrawFace
   
   ;REINIGUNG/DURCHFÜHREN
   For IDrawCount=1 To 16383
      
      ;VERTEX/POLYGON/ZUWEISUNGEN
      IDrawV0=AddVertex(LDrawFace,-1,+1,100)
      IDrawV1=AddVertex(LDrawFace,+1,+1,100)
      IDrawV2=AddVertex(LDrawFace,+1,-1,100)
      IDrawV3=AddVertex(LDrawFace,-1,-1,100)
      AddTriangle LDrawFace,IDrawV0,IDrawV1,IDrawV2
      AddTriangle LDrawFace,IDrawV2,IDrawV3,IDrawV0
   Next
   
   ;NACHREINIGUNG
   RenderWorld: ClearSurface LDrawFace
   
   
   
   
End Function


Edit1:

Hab den Eintrag von damals gefunden. Bitte sehr...

https://www.blitzforum.de/foru...hp?t=31437

aMul

Sieger des Minimalist Compo 01/13

BeitragSa, Jan 28, 2012 23:01
Antworten mit Zitat
Benutzer-Profile anzeigen
Hab zwar nichts neues beizutragen, wollte aber nur noch anmerken, dass die verschieben Methode in Noobodys Beispiel bei mir ziemlich genau 20% schneller ist.
Ich bin durchaus überrascht.

Ob das an der Grafikkarte liegt(mittlerweile hab ich eine andere als damals), ich mich nur komisch erinnere oder meine Tests damals nicht gut waren, wer weiß.
Auf alle Fälle interessant zu wissen, danke!

Werde zwar deswegen vermutlich nicht umsteigen, dafür ist meine Grafik-Lib zu groß, aber wenn ich mal Langeweile hab, wer weiß. Mr. Green
Panic Pong - ultimate action mashup of Pong and Breakout <= aktives Spiele-Projekt, Downloads mit vielen bunten Farben!
advASCIIdraw - the advanced ASCII art program <= aktives nicht-Spiele-Projekt, must-have für ASCII/roguelike/dungeon-crawler fans!
Alter BB-Kram: ThroughTheAsteroidBelt - mit Quelltext! | RGB-Palette in 32²-Textur / Farbige Beleuchtung mit Dot3 | Stereoskopie in Blitz3D | Teleport-Animation Screensaver

PSY

BeitragSo, Jan 29, 2012 19:15
Antworten mit Zitat
Benutzer-Profile anzeigen
jep, aber wenn er vorhat ne particleengine zu schreiben, sollte er die surfaces loeschen.
gerade da werden permanent quads neu erstellt / geloescht

Zitat:
Wenn man also nur Vertices bewegen will, ist die erste Methode sicher vorzuziehen. Aber wenn es darum geht, einzelne Quads rauszulöschen und andere einzufügen (und das sehr oft, z.B. in jedem Frame), ist sicher die zweite Variante im Vorteil, da die CPU-Last, um leere Stellen in der Surface zu verwalten, in B3D einfach zu gross ist im Vergleich zum Geschwindigkeitsgewinn.


bei meinen tests damals wars so, dass ab einer bestimmten anzahl zu verwaltender particle das eine system gegenueber dem andern ploetzlich dominiert hat.

aber wie gesagt, particleengine ---> surfaces loeschen
viele statische particle ---> particle verwalten


l8er,
PSY
PSY LABS Games
Coders don't die, they just gosub without return

Neue Antwort erstellen


Übersicht BlitzBasic Blitz3D

Gehe zu:

Powered by phpBB © 2001 - 2006, phpBB Group