AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Multimedia Delphi DirectX Vertex Darstellung
Thema durchsuchen
Ansicht
Themen-Optionen

DirectX Vertex Darstellung

Ein Thema von neolithos · begonnen am 1. Sep 2003 · letzter Beitrag vom 15. Sep 2003
Antwort Antwort
Seite 1 von 3  1 23      
neolithos

Registriert seit: 31. Jul 2003
Ort: Dresden
1.386 Beiträge
 
Delphi 7 Architect
 
#1

DirectX Vertex Darstellung

  Alt 1. Sep 2003, 09:31
In vielen Tut's und Bsp's wird IDirect3DVertex8, direct nach dem das Direct3D Interface erstellt wurde, erstellt.
Die Daten werden immer in einem extra Speicher gehalten und in der Render fkt in den Vertex-Buffer hineinkopiert.

Da bei diesem vorgehen Speicher verschwendet wird, folgende Fragen:

Ich verwendet derzeit den Vertex-Buffer als speicher, daher nur werden die Daten nur einmal gehalten, es gibt also keine Kopie davon, da ich die Daten direkt manipulire.

Kann das Probleme geben bzw. Wie muss der Vertex erstellt sein? Was bedeutet der Usage-Parameter (D3DUSAGE_WRITEONLY) genau?

Wann und wo werden die Vertexe benötigt, nur für DrawPrimitive oder auch für Present?

---------------------------------------------------------------------

Kennt jemand ne seite wo, etwas genaueres steht zu der ganzen geschichte!
- ciao neo -
Es gibt niemals dumme Fragen, sondern nur dumme Antworten!
  Mit Zitat antworten Zitat
neolithos

Registriert seit: 31. Jul 2003
Ort: Dresden
1.386 Beiträge
 
Delphi 7 Architect
 
#2

Re: DirectX Vertex Darstellung

  Alt 1. Sep 2003, 14:52
Wollte es nur nochmal in Erinnerung rufen.
- ciao neo -
Es gibt niemals dumme Fragen, sondern nur dumme Antworten!
  Mit Zitat antworten Zitat
OregonGhost

Registriert seit: 8. Jun 2002
Ort: Lübeck
1.216 Beiträge
 
Delphi 3 Professional
 
#3

Re: DirectX Vertex Darstellung

  Alt 2. Sep 2003, 10:20
Du musst den IDirect3DVertexBuffer8 als Managed Resource erstellen, heißt bei der Erstellung gibst du als Pool D3DPOOL_MANAGED an. Dann übernimmt Direct3D die komplette Verwaltung, aber dafür ist er nicht so gut geeignet für dynamische Daten. Dafür müsstest du einen anderen Pool nehmen, und in dem Fall müsstest du immer, wenn ein Device Lost ist, die Daten neu reinkopieren. Genau das macht Direct3D aber auch im Managed Pool, nur halt automatisch. Das hängt damit zusammen, dass bei einem Device Lost das Gerät (heißt die Grafikkarte) ihren Speicher "verliert", in dem der Vertexbuffer seine Daten hält.

In jedem Fall ist es FALSCH, d.h. nicht gerade performanceträchtig, diese Kopieraktion in der Render-Funktion (oder in einer beliebigen anderen Funktion, die pro Frame aufgerufen wird) durchzuführen. Wenn du WRITE_ONLY nimmst, heißt das, du kannst die Vertices NICHT auslesen, musst sie also alle selbst erzeugen und kannst sie nicht verändern (sondern nur neu schreiben). Die Vertices werden bei DrawPrimitive benötigt. Dir muss im übrigen klar sein, dass es relativ ineffizient ist, ständig den Buffer zu locken etc. Beschreibe am besten nochmal genauer, was du mit den Vertices machen willst und wie und wann.
Oregon Ghost
---
Wenn NULL besonders groß ist, ist es fast schon wie ein bisschen eins.
  Mit Zitat antworten Zitat
neolithos

Registriert seit: 31. Jul 2003
Ort: Dresden
1.386 Beiträge
 
Delphi 7 Architect
 
#4

Re: DirectX Vertex Darstellung

  Alt 2. Sep 2003, 10:36
Erst mal Danke für die ausführliche Antwort...

Da ich noch blutiger Änfänger bin hab ich mir einen kleinen Sternen-Himmel gebastelt (es sieht so aus als würde man aus dem Seitenfenster eines Raumschiffes schauen).

Es gibt n Ebenen mit m Sternen. Die Sterne auf einer Ebene bewegen sich unterschiedlich schnell.

Anz. Sterne = n + mn + m(n - 1) + ... + m1
Speicher = Anz. Sterne * 16 (x, y, z, color)

[n steht für frei wählbar]
[mn ist m indiziert durch n]

Die Menge an Daten immer kopieren war mir relativ lästig, vorallem gerinde Fps (wert's mal durchtesten).

Der Fehler Lost-Devices ist mir gestern auch untergekommen, doch weiß ich noch nicht genau wie ich damit umgehen soll, habe bis jetzt noch kein Tut. gefunden der diesen Fehler auswertet.

Weiterhin ist mir aufgefallen das meine Fps-raten viel zu gering sind. Bei wesentlich komplexeren Grafiken in Spielen, ist jene wesentlich geringer. Auch aus diesem Grund habe ich auch die Frage gestellt.

Meine Fps-Berechnung:
Init: Zähler nullsetzen, StartTime auf GetTickCount

iFrame-Zähler in Render-Funktion eröhen

Berechnung:
fps = 1000 * iFrame / (GetTickCount - StartTime)

sollte funktionieren oder?
- ciao neo -
Es gibt niemals dumme Fragen, sondern nur dumme Antworten!
  Mit Zitat antworten Zitat
OregonGhost

Registriert seit: 8. Jun 2002
Ort: Lübeck
1.216 Beiträge
 
Delphi 3 Professional
 
#5

Re: DirectX Vertex Darstellung

  Alt 2. Sep 2003, 16:51
Dass du mit Lost Devices nicht umgehen kannst, ist natürlich ungünstig - ist aber ganz einfach, einfach mal im DX SDK unter Lost Devices nachgucken. Ist ein klein wenig Routine und gehört zu jedem Programm. Es ist auch kein richtiger Fehler, sondern deine Anwendung gibt halt ihren exklusiven Modus auf und verliert daher den Grafikkartenspeicher. Mit IDirect3DDevice8::Reset() musst du darauf reagieren.

Dein FPS-Zähler wird prinzipiell funktionieren. Alternativ kannst du auch die Zeit mit QueryPerformanceCounter in jedem Frame messen (das ist innerhalb des Frames eine praktische Sache). Der Kehrwert sind die aktuellen ("instant") FPS, wenn du es über längere Zeit mittelst, schwankt das auch nicht so stark.

Wie zeichnest du die Sterne? Als Textur? Oder einfach so als 3D-Objekt?

Du musst nicht unbedingt die Vertices bearbeiten, laut SDK sollte man wenn möglich immer Matrixtransformationen verwenden.
Oregon Ghost
---
Wenn NULL besonders groß ist, ist es fast schon wie ein bisschen eins.
  Mit Zitat antworten Zitat
neolithos

Registriert seit: 31. Jul 2003
Ort: Dresden
1.386 Beiträge
 
Delphi 7 Architect
 
#6

Re: DirectX Vertex Darstellung

  Alt 2. Sep 2003, 17:34
Erstmal habe ich ein Orthogonales (2D) Koordinatensystem eingestellt.

Die Sterne werden in einem großen Vertex-Buffer gehalten.
Ein Stern stellt einfach nur ein Punkt dar.

Wie gesagt klein und einfach, dachte ich (jedenfalls in DOS war das so).
-> Info: ich überarbeite gerade alte DOS-Spielereien um ein wenig DX zu lernen.

Aber es gibt wie gesagt dieses kleinen Detail's.

---------

Ist überhaupt direktes kopieren in den BackBuffer bei großen Objekten sinnvoll/schnell oder lieber an der stelle ein Viereck erstellen mit Texture?

---------

Wie geh ich zur Zeit mit den Lost Devices um:
1. Ich zerstöre alle D3D-Objecte (Surface, Texturen, Vertexes, Texte außer Device)
2. Rufe Reset
3. Baue alles wieder auf

Ist das zuviel des guten?

---------

Langsam mach die ganze sache Spaß (lob @OregonGhost)!!!
- ciao neo -
Es gibt niemals dumme Fragen, sondern nur dumme Antworten!
  Mit Zitat antworten Zitat
OregonGhost

Registriert seit: 8. Jun 2002
Ort: Lübeck
1.216 Beiträge
 
Delphi 3 Professional
 
#7

Re: DirectX Vertex Darstellung

  Alt 2. Sep 2003, 18:35
Ein Stern stellt einen Punkt dar?
Nimmst du Point Sprites, oder arbeitest du direkt auf dem Backbuffer?

Ich glaube in DOS war eine Menge anders als unter Windows und mit Direct3D ;c)

---

IMMER (egal wie groß) ein Viereck mit Textur erstellen. In einem anderen Thread (der war auch von dir, glaube ich (c; ) habe ich auf Tutorials auf gamedev.net hingewiesen, diese passen hier auch. Genau das empfehle ich auch: Nimm eine Textur, die einen oder mehrere Sterne enthält und rendere ein Viereck für jeden Stern.

Du brauchst dann nur vier Vertices im Vertexbuffer.
Diese bekommen Standardkoordinaten (z.B. (-1,-1;1,-1;-1,1;1,1)), die du mit Transformationsmatrizen auf das entsprechende Format bringst und auch an die richtige Stelle. Du nimmst auch Standardtexturkoordinaten (von 0,0 bis 1,1) und transformierst diese per Texturtransformationsmatrix so hin, dass der richtige Ausschnitt aus der Textur genommen wird.

Das hat nämlich einen Vorteil: Die Grafikkarte übernimmt den Löwenanteil der Arbeit. Zum Beispiel muss die CPU pro Stern jeweils zwei Matrizen berechnen, während die Grafikkarte dies pro Vertex machen muss (also acht). Mit Mipmapping wird auch der Rasterizer nicht mehr ganz so stark gefordert (stell's z.B. auf bilineare Filterung).

In Direct3D ist seit Version 8 eigentlich eine direkte Manipulation des Backbuffers nicht mehr vorgesehen.

---

Du musst bei einem Device Lost nur Objekte zerstören, die sich nicht im Managed Pool befinden. Wenn du so vorgehst, wie ich oben beschrieben habe, können sowohl der Vertexbuffer als auch die Textur im Managed Pool liegen. Wenn du weiterhin den Vertexbuffer ständig verändern willst, musst du ihn in den Default Pool schieben und ihm Dynamic Usage zuweisen. In dem Fall musst du ihn tatsächlich zerstören, dann das Device resetten und den Buffer neu erzeugen und füllen. Die Textur kann trotzdem im Managed Pool liegen, wenn du sie nicht bearbeiten willst.

Du brauchst eigentlich keinen Zugriff auf Surfaces. Folglich brauchst du eigentlich auch keine Surfaces zu zerstören. Ansonsten gilt dasselbe wie oben.

---

Wenn du noch Fragen hast (und ich bin sicher, du hast jetzt einige neue, auch wenn die alten beantwortet sind (c; ), dann frag' nur. Wenn du C++ lesen kannst, kann ich dir auch den Code von meinem Spriterenderer schicken, der macht genau das, was ich da oben beschrieben habe.

Die meisten Fragen beantwortet aber das DirectX SDK, insbesondere alles, was im DirectX Graphics -> Programming Guide steht...

--- und noch ein Addendum:

Wenn ich richtig verstehe, nutzt du den Vertexbuffer nur als Speicher für deine eigenen Routinen. Dafür ist er nicht gedacht. Er ist dafür gedacht, Vertices (d.h. die 3D-Punkte, die die Grafikkarte direkt rendern soll) darin zu speichern. Wenn eh' nur die CPU damit arbeitet, ist es effizienter, ein pimpfiges Array zu verwenden. Das gilt auch, wenn du meine oben beschriebene Methode verwenden willst - in den Vertexbuffer gehören dann die vier Eckvertices des Vierecks, die Koordinaten der Sterne (die ja nur punktförmig sind), hältst du besser in einem Array, denn aus ihnen musst du (sprich die CPU) ja die Matrizen errechnen. Die Farbe (die du auch in deinem Array speicherst) gibst du den Sternen übrigens, indem du den Texture Factor festlegst, und als Farboperation die Multiplikation der Texturfarbe mit dem Texture Factor angibst.
Oregon Ghost
---
Wenn NULL besonders groß ist, ist es fast schon wie ein bisschen eins.
  Mit Zitat antworten Zitat
neolithos

Registriert seit: 31. Jul 2003
Ort: Dresden
1.386 Beiträge
 
Delphi 7 Architect
 
#8

Re: DirectX Vertex Darstellung

  Alt 4. Sep 2003, 08:47
Jeder Stern ist ein Vertex-Punkt.
In den Backbuffer kopier ich bei einen anderen Programm! Ich werde es aber jetzt anders machen.

------

Ich werde mich mal mit den X-Funtionen von D3D beschäftigen, denn das klingt ja nach dem Verfahren die ich zum Abitur gebraucht habe (Verschiebe zum Koordinatenursprung, rechne, Schiebe zurück).

------

Wenn die Teile im Manage Pool sind kann man sie anscheinend nicht mehr so richtig bearbeiten. Das ist mir bei einem Surface aufgefallen, von welchem ich einen DC geholt habe, das ging nur mit D3DPOOL_DEFAULT, jeder andere Wert führte zu einen Fehler. (DX9)

------

Die DirectX SDK hab ich schon zu genüge strabaziert, doch fällt mir immer wieder auf, das sie manchmal nicht Tief genug geht.

------

Ob C++, VO, Basic oder Pascal mir ist das Egal, denn wenn man eine Sprache kann, kann man die anderen wenigstens Lesen.
1. Übrigens es wäre nicht schlecht wenn ich mal ein etwas realitätsnahe Bsp hätte, denn der Programm aufbau macht mir noch Probleme.
2. Zweites wollte ich über DX auch mal wieder C++ Programmieren. Leider hab ich noch etwas scheu davor, da C++ leicht genau mit Datentypen und Interfaces ist (zum Freigeben muss man ja noch Release rufen).

------

Wöllte ich die Sterne als kleine Bildschchen auf den Schirm bringen müsste ich nach deiner Beschreibung einen Vertext-Buffer für 4 Vertex's haben, den ich sagen wir mal 350 mal befülle und mit DrawPrimitiv zeichne.

Code:
for(int iStern = 0; iStern < 350; iStern)
{
  xBuffer->Lock(  );
  befülle Vertexe
  Transformiere zur Position
  xBuffer->UnLock();
  xDevice->DrawPrimitive(D3DPT_TRIANGLESTRIP, 0, 4);
}
So ungefähr würde ich denken.

<- ich kann auch C++ (e bissle)

Weitere Fragen kommen bestimmt, aber erst nächste Woche!
- ciao neo -
Es gibt niemals dumme Fragen, sondern nur dumme Antworten!
  Mit Zitat antworten Zitat
OregonGhost

Registriert seit: 8. Jun 2002
Ort: Lübeck
1.216 Beiträge
 
Delphi 3 Professional
 
#9

Re: DirectX Vertex Darstellung

  Alt 4. Sep 2003, 10:04
Zitat:
Ich werde mich mal mit den X-Funtionen von D3D beschäftigen, denn das klingt ja nach dem Verfahren die ich zum Abitur gebraucht habe (Verschiebe zum Koordinatenursprung, rechne, Schiebe zurück).
Im Prinzip ja ;c)
D3DX enthält lediglich Hilfsfunktionen, du kannst es natürlich auch ohne machen ;c)

---

Wozu brauchst du in einer Direct3D-Anwendung einen DC?

---

Das mit dem Vertexbuffer stimmt nicht. Du befüllst ihn EINMAL. Wenn du jetzt dein Sprite rendern willst, verschiebst du den Ursprung z.B. mit einer D3XMatrixTranslation an die jeweilige Stelle, rotierst und skalierst gegebenenfalls mit D3XMatrixScaling und D3DXMatrixRotation* und dann musst du noch eine Matrix erstellen, die auf der Textur den richtigen Bereich auswählt (also Translation + Skalierung), die du als Texturtransformationsmatrix Direct3D übergibst. Der Witz ist, der Vertexbuffer braucht von dir nie wieder angetastet zu werden (außer du willst ihn freigeben). Die Parameter für die Matrix-Funktionen sind also lediglich Größe und Position der Sterne, die du in einem Array hältst. Auf dieses Array kann die CPU wesentlich schneller zugreifen als auf einen Vertexbuffer.
Oregon Ghost
---
Wenn NULL besonders groß ist, ist es fast schon wie ein bisschen eins.
  Mit Zitat antworten Zitat
neolithos

Registriert seit: 31. Jul 2003
Ort: Dresden
1.386 Beiträge
 
Delphi 7 Architect
 
#10

Re: DirectX Vertex Darstellung

  Alt 4. Sep 2003, 10:23
Ganz so versteh ich das nicht, denn ich habe ja 350 Sterne und nicht einen. Und ich wollte auch nich 350 VertextBuffer anlegen. Denn jeder Stern besitz nur die Eigenschaften X, Y und Helligkeit (12 Byte pro Stern). Genauso will ich nicht 350 mal das selbe Bild geladen haben, denn dann werden aus den 12*350 schnell mehr. Bei diesen Beispiel mag das nicht stören, aber ....

-----

Den DC-Hab ich für eine kleinen Info-Bereich benötigt.

mit CreateOffScreenSurface (D3DPOOL_DEFAULT) angelegt.

GetDC
Etwas reingemalt [Linen (DrawEdge) und Text (DrawText)]
ReleaseDC
<- was ich nur einmal mache

und dann immer wieder auf den Bildschirm gerendert.

-----

> Nenn mich verrückt ...

Kennst du noch das alte Train aus den 286-Zeiten von dem Russen.
Ich will es mal aus den gedächtnis neu entwerfen. Mal sehen!

Aber erst wenn ich jedes detail bei den Sternen begriffen habe. [Punkt]
- ciao neo -
Es gibt niemals dumme Fragen, sondern nur dumme Antworten!
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 3  1 23      


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 05:24 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