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

Anonymous

unregistriert

1

18.09.2003, 16:00

Lohnen sich VertexBuffer?

Hallo,

ich habe eine Anwendung, die mehrere Objekte zeichnet. Bis jetzt kam ich ganz gut damit hin, bei jedem Rendern die Vertices zu generieren und mit DrawUserPrimitive zu zeichnen.

Je mehr Objekte, desto langsamer wirds. Kann ich durch eine Umstellung auf VertexBuffer die Geschwindigkeit erhöhen oder bremst häufiges Ändern des VB die Anwendung sogar noch mal zusätzlich aus?

Otto

Tobiking

1x Rätselkönig

  • Private Nachricht senden

2

18.09.2003, 16:59

Wenn du einen dynamischen VB benutzt sollte es schneller sein. Der ist extra dafür optimiert jedes Bild geändert zu werden. Steht zumindest so ähnluch im buch wenn ich es recht verstanden habe. Und es gibt wohl nichts langsameres als DrawPrimitiveUP.

AXA

Frischling

  • Private Nachricht senden

3

18.09.2003, 17:03

Natürlich ist das Mit den Vertex Buffer besser wenn du viele
Prmitivien Zeichnen möchtest.

Bei einen Dreieck lohnt sich das noch nicht!
Aktuelles Projekt: Geheim

wird diese Projekt ein erfolg gründe ich
ein Team !!!

Anonymous

unregistriert

4

18.09.2003, 19:12

Hallo,

ich habe jetzt mal damit angefangen, einen großen VertexBuffer zu erstellen (dynamisch). Wenn sich ein Objekt verändert, soll es den Bereich, in dem es steht, sperren und überschreiben.

In C# gibt die Lock-Methode, bei der man den Offset und die Länge angeben kann, einen GraphicStream zurück. Wie kann ich daraus wieder die Vertices bekommen? Im Buffer stehen PositionNormalColored-Vertices ?

Bzw. es gibt noch eine Signatur der Lock-Methode, die ein Array zurückgibt, aber einen Parameter params int[] ranks haben will, mit dem ich gar nichts anfangen kann. Kann man damit auch einen bestimmten Bereich sperren?

Otto

Tobiking

1x Rätselkönig

  • Private Nachricht senden

5

18.09.2003, 20:13

Dafür weiß ich so genau keine Lösung kenne mich net mit C# aus aber es ist schneller sich immer eine kopie von den Vertizes zu machen, da es sehr sehr langsam ist Daten aus der Grafikkarte zu lesen. Also wenn du die Vertizes in den VB schreibst einfach noch eine kopie davon behalten und damit arbeiten.

NoName

Treue Seele

Beiträge: 118

Beruf: Student

  • Private Nachricht senden

6

18.09.2003, 20:24

Genau! Während der Vertexbuffer gesperrt ist, kann der gesperrte Teil nicht beim Rendern verwendet werden. Man sollte die Sperrzeit möglichst gering halten um einen Performanceverlust zu vermeiden.

In C++ wandelst du einfach die Adresse, die die Lock-Funktion die gibt, per static_casr in dein Vertexformat um. Mit C# kenne ich mich aber nicht aus.

Anonymous

unregistriert

7

19.09.2003, 14:58

Hallo,

erstmal vielen Dank für die Hilfe.

Nun bin ich schon einen großen Schritt weiter: Ich habe einen großen VertexBuffer. Jedes Objekt kennt seinen Platz in demselbenund aktualisiert seinen Bereich bei Bedarf. Das ganze funktioniert auch ganz gut.

Nur ein Problem gibt es: Vor jedem Rendern muss ich den Buffer komplett neu füllen. Wenn ich es nicht meche, wird der Inhalt nicht angezeigt. Hier mal ein Ausschnitt aus der Render-Methode:

if (_vertexBuffer == null || _model.vertexNumberChanged())
_vertexBuffer = _model.refillVertexBuffer (_device, true);

_device.SetStreamSource (0, _vertexBuffer, 0);
_device.VertexFormat = CustomVertex.PositionNormalColored.Format;

_device.Clear(ClearFlags.Target | ClearFlags.ZBuffer | ClearFlags.Stencil, _backGroundColor, 1.0f, 0);
_device.BeginScene();
_model.renderModel (_device, _vertexBuffer, _camera, _drawShadows);
_device.EndScene();
_device.Present();

Am Anfang die if-Abfrage prüft, ob der VertexBuffer komplett neu gezeichnet werden muss. Wenn ja, wird das gemacht. Ansonsten bleibt der VB unverändert.

Leider läufts so nicht. Nur wenn ich das if rauswerfe und den VB immer neu fülle, dann gehts. Aber das würde ja unnötig verlangsamen...

Hat jemand einen Verdacht?

Otto

NoName

Treue Seele

Beiträge: 118

Beruf: Student

  • Private Nachricht senden

8

19.09.2003, 15:02

Wieso musst du vor jedem Rendern, wenn sich etwas ändert, den VB komplett neu füllen? Reicht es nicht aus, nur den betreffenden Teil zu sperren?

Poste doch mal die refillVertexBuffer - Funktion.

Anonymous

unregistriert

9

19.09.2003, 15:40

Hallo,

warum ich den jedesmal neu füllen muss, wüsste ich auch gerne ;) Fakt ist aber, dass wenn ich es nicht mache, nichts gezeichnet wird.

Die refillVertexBuffer Methode ist eigentlich auch ziemlich unspektakulär:

public VertexBuffer refillVertexBuffer (Device device, bool markAsUpdated)
{
int vertexCount = countNeededVertices();

if (vertexCount == 0)
return null;

VertexBuffer vertexBuffer = new VertexBuffer (typeof CustomVertex.PositionNormalColored), vertexCount, device, Usage.Dynamic, CustomVertex.PositionNormalColored.Format, Pool.Default);

int vbCount = 0;
foreach (ObjectModel m in _objectList)
{
m.ObjectStyle.toVertexBuffer (vbCount, vertexBuffer, markAsUpdated);
vbCount += m.ObjectStyle.VertexCount;
}

return vertexBuffer;
}


Die Klasse m.ObjectStyle trägt die Vertices für ein spezielles Objekt ein.

Otto

Anonymous

unregistriert

10

19.09.2003, 15:43

Sorry, habe grade erst deine Frage verstanden ;)

Jedes Objekt kennt die Position im VB, wo es steht. Wenn ein Objekt auf einmal mehr Vertices benötigt, würde sich ja alles verschieben. Daher lasse ich einfach den kompletten Buffer neu zeichnen. Wenn die Zahl der Vertices gleich bleibt und sich nur z.B. die Farbe ändert, soll das Objekt nur den von ihm besetzten Bereich ändern.

Könnte das Problem sein, dass ich einen dynamischen VB habe? Muss man den öfters initialisieren?

Otto

Werbeanzeige