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

1

14.05.2009, 00:40

Design Frage (Buffer)

Hi Spielerogrammierer! Ich würde euch gerne um eure Meinung zu einer kleinen Klasse in meinem Framework fragen. In meinem Framework habe ich Direct3D und einen kleinen Teil von OpenGL gewrappt. Momentanig macht mir das Resetten des Direct3D Devices sorgen, wenn es verloren geht, beispielsweise wenn das Programm minimiert wird (Vollbild).

Sobald der Device verloren geht, gehen ja auch alle Vertex, Index Buffer und Texturen verloren, halt alle Grafikressourcen. Wenn die den Device nun resetten will, muss ich auch alle Grafikressourcen neu erstellen und mit den alten Daten füllen. Nun habe ich mir gedacht das ganze in der Wurzel an zu packen. Jede Klasse die eine Direct3D Grafikressource als Member haben, haben auch eine Reset Methode, welche beispielsweise den Vertex Buffer neu erstellt und mit den alten Daten füllt. Ich habe mir gedacht die Daten direkt in der Vertex Buffer Klasse zu speichern. Nun sieht das ganze so aus:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
template <class T>
class VertexBuffer
{
public:
    VertexBuffer(GraphicsDevice* graphicsDevice, unsigned int length);
    ~VertexBuffer();
    void Update(unsigned int offset, unsigned int length);

    T* Data;

private:
    GraphicsDevice* mGraphicsDevice;
    IDirect3DVertexBuffer9* mDirect3DVertexBuffer;
};


(Die Klasse habe ich ein wenig gekürzt, damit ich euch nicht mit einem riesen haufen Methoden zu mülle!)

Wenn man den Vertex Buffer nun erstellt, ruft man den Konstruktor auf:

C-/C++-Quelltext

1
VertexBuffer<Vertex>* vertexBuffer = new VertexBuffer<Vertex>(graphicsDevice, 6);


Die Klasse ist Template basierend, und der Konstruktor erstellt ein Array des Typen T, also des Templates. Der zeiger auf diesen Array ist die Member Variable Data.

Wenn man nun den Buffer füllen will, schreibt man einfach direkt in diesen Array:

C-/C++-Quelltext

1
2
3
4
5
6
vertexBuffer->Data[0].Position = Vector3(0,0,0);
vertexBuffer->Data[1].Position = Vector3(0,1,0);
vertexBuffer->Data[2].Position = Vector3(1,0,0);
vertexBuffer->Data[3].Position = Vector3(0,1,0);
vertexBuffer->Data[4].Position = Vector3(1,0,0);
vertexBuffer->Data[5].Position = Vector3(1,1,0);


Und wenn man das Gnaze dann Updaten will, benutzt man die Update Methode:

C-/C++-Quelltext

1
vertexBuffer->Update(0, 6);


der erste Parameter ist der Offset und der zweite wie viele Vertices man ab dem Offset updaten will.

Wenn nun der device neu erstellt wird, wird die Methode Reset() von allen Vertex Buffern aufgerufen, welche den Direct3DVertexBuffer neu erstellt und diesen mit den Daten füllt, welche in Data gespeichert sind.

Nun Frage ich mich ob diese Lösung denn auch ratsam ist? Habt ihr vieleicht verbesserungsvorschläge?

2

14.05.2009, 15:23

wenn VertexBuffer::Data soweiso die gesamten daten des VB enthält, wofür gibts dann bei Update Offset und Länge?
und wenns das nciht tut, hast du in deienr erklärung was vergessen, oder es funzt so nciht ;)

3

14.05.2009, 20:37

In der Update Methode wird der Direct3D Vertex Buffer gelockt und Unlockt, und wenn ich nur 3 Vertices verändert habe wäre es nicht sehr sinnvoll alle Daten neu zu uppen, deswegen offset und Length.

4

15.05.2009, 14:54

achso, ok.
ja, dann entspricht deine lösung so ziemlich dem, was ich mir bisher zu dem thema überlegt hab ;)

5

15.05.2009, 21:43

Nunja, bin mir aber garnicht merh so sicher. Wenn man den Buffern den Pool Managed zuweißt, dann soll Direct3D die Buffer ja automatisch wieder herstellen, bei einem Reset.

6

15.05.2009, 22:11

Eben... ;)
fka tm

7

16.05.2009, 00:18

Also ist meine Variante so ziemlich nutzlos und hat nur den Vorteil das man auf die Backupdaten zugreifen kann?

8

16.05.2009, 11:48

nunja, will man sich auf Managed als speicherklasse festlegen?
denn D3DPOOL_MANAGED kann ja ncith für Rendertargets, Depthstencil-Puffer, dynamische resourcen und texturen mit automipmapping verwendet werden. sprich, für diese fälle bräuchte man dann schon backup-code.
Und bei managed greifst du btw. ausschließlich auf die Backupdaten zu, die daten auf der device werden nur geändert, wenn directX die backupdaten überspielt, sobalds nötig wird.

Werbeanzeige