[D3D] Vertex Buffer adressieren
-
Guten Abend.
Ich habe hier eine kleine Verständnisfrage:
Ich verstehe nicht so ganz, wie ich nun den Vertex Buffer richtig adressiere, um die Input Register für den Vertex Shader zu füllen.Wenn die Elemente als Beispiel so aussehen:
D3DVERTEXELEMENT9 declDesc[] = { { 0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0 }, { 0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL, 0 }, { 2, 0, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0 }, { 0xFF, 0, D3DDECLTYPE_UNUSED, 0, 0, 0 } };
Ist es dann richtig, wenn ich so darauf zugreife:
typedef struct { D3DXVECTOR3 v0; D3DXVECTOR2 v1; D3DXVECTOR2 v2; } VERTEXDECLARATION; VERTEXDECLARATION *fStream; StreamData->Lock(BaseVertexIndex + MinIndex, sizeof(declDesc), (void **)&fStream, 0); fStream->v0.x = ...; //v0 == D3DDECLUSAGE_POSITION fStream->v1.x = ...; //v1 == D3DDECLUSAGE_NORMAL fStream->v2.x = ...; //v2 == D3DDECLUSAGE_TEXCOORD StreamData->Unlock();
Also 1. wird das Offset beim Lock-Aufruf richtig berechnet (BaseVertexIndex + MinIndex), 2. ist das so mit v2 richtig, da es ja aus einem anderen Stream kommt und 3. ist das Offset, das man beim D3DVERTEXELEMENT9 angibt, das Offset im Vertex Buffer oder muss man den Index Buffer mit einbeziehen?
Vielen Dank
-
Weiß denn jemand, wie ich die Input Register für Vertex Shader setze?
Nur verstehe ich nicht so richtig, wo ich im Vertex Buffer ansetzen muss und ob ich den Index Buffer auch dazuziehen muss..
-
D3DVERTEXELEMENT9 declDesc[] = { { 0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0 }, { 0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL, 0 }, { 2, 0, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0 }, { 0xFF, 0, D3DDECLTYPE_UNUSED, 0, 0, 0 } };
Der jeweils erste Parameter eines D3DVERTEXELEMENT9 bezeichnet den Stream.
Bist Du sicher dass Deine Texturkoordinaten aus einem anderen Stream kommen sollen?typedef struct { D3DXVECTOR3 v0; D3DXVECTOR2 v1; D3DXVECTOR2 v2; } VERTEXDECLARATION;
"v1" hast Du ja oben als 3 floats deklariert...
Weiß denn jemand, wie ich die Input Register für Vertex Shader setze?
In der Deklaration des Shaders:
Vertex vertexshader(float3 pos: POSITION, float3 normal: NORMAL, float2 uv : TEXCOORD0) { ... }
-
Wie sieht das mit dem Offset der Inputs denn aus?
Also bei
"{ 0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL, 0 },"
wäre es ja sizeof(float) * 3
Ist v1 dann immer an diesem Offset ab dem Anfang des Vertex Shaders oder kommt es darauf an, was man gerade malt, also besitzt jedes Objekt eigene Input-Werte.Was muss man also berücksichtigen, wenn man etwas mit DrawIndexedPrimitive malt?
Ist es ein fixes Offset oder muss man z.B. BaseVertexIndex, MinIndex, NumVertices oder den Index Buffer mit StartIndex o.Ä. mit einbeziehen?
Danke!
-
QuEst! schrieb:
Wie sieht das mit dem Offset der Inputs denn aus?
Den hast Du mit dem jeweils zweiten Parameter angegeben - darum heisst der auch "Offset".
bei "{ 0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL, 0 }," wäre es ja sizeof(float) * 3
Richtig, deswegen steht da ja auch "12".
Ist v1 dann immer an diesem Offset ab dem Anfang des Vertex Shaders oder kommt es darauf an, was man gerade malt, also besitzt jedes Objekt eigene Input-Werte.
Was?
Was muss man also berücksichtigen, wenn man etwas mit DrawIndexedPrimitive malt?
Der Index gibt lediglich an, an welcher Stelle im Vertexbuffer ein Vertex ausgelesen werden soll - davon kriegt der Vertex-Shader nichts mit.
-
Ist v1 dann immer an diesem Offset ab dem Anfang des Vertex Shaders oder kommt es darauf an, was man gerade malt, also besitzt jedes Objekt eigene Input-Werte.
Ups, ich meinte 'ab dem Anfang des Vertex Buffers'
Ich meinte:
Wenn man die Input Werte für den Vertex Shader vorbereitet, wie genau macht man das dann mit dem Vertex Buffer?
Die Vertex Declaration ist ja für den Shader und das bestimmen der Werte übernimmt man ja selber, also das Einsetzen der Werte in den Vertex Buffer,
wo platziert man also die Werte im Buffer für die Input Register?Wenn man in der Declaration Offset = 12 setzt, ist das, damit die Werte aus dem Buffer für den Shader richtig gemappt werden,
aber von wo mappt der die?"Offset ist gleich 12, also gehe ich einfach vom Anfang des Vertex Buffers 12 bytes weiter und da finde ich dann mein v0/v1/etc."
oder wird noch Anderes beim Mappen berücksichtigt, wie z.B.
"Offset ist gleich 12, also addiere ich BaseVertexIndex hinzu und gehe diese Anzahl dann weiter und da finde ich..."
oder wird erst der Index aus'm Index Buffer ab StartIndex + 12 genommen und dann über den neuen Index auf die Werte im Vertex Buffer zugegriffen, um sie in die v-Register zu mappen?
Thx
-
Der Vertexbuffer ist erstmal nur ein Speicherbereich in dem man die einzelnen Vertices hintereinander ablegt.
Jeder Vertex darin ist ebenfalls nur ein Speicherbereich dessen Aufbau der GPU erstmal unbekannt ist.
Die GPU weiss allerdings wie gross ein einzelner Vertex ist (wird bei IDirect3DDevice9::SetStreamSource angegeben) und dadurch wo jeder Vertex im Buffer anfaengt.
Frueher hat man per FVF lediglich spezifiziert, welche Attribute ein Vertex hat und die mussten dann in fester Reihenfolge in der Vertex-Struktur abgelegt werden.
Da zwischenzeitlich diverse Formate angefuehrt wurden in der ein einzelner Vertex-Parameter abgelegt werden kann, benoetigt man die Vertex Declaration um fuer jeden Parameter per D3DVERTEXELEMENT9 anzugeben, wo dieser in der Vertex-Struktur zu finden ist (D3DVERTEXELEMENT9::Offset), in welchem Format dieser vorliegt (D3DVERTEXELEMENT9::Type) und in welches "Input-Register" dieser geladen werden soll (D3DVERTEXELEMENT9::Usage).Beinhaltet Deine Vertex-Declaration also
{ 0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL, 0 }
so weiss die GPU dass der Shader-Parameter "NORMAL" in Form von 3 floats ab Stelle 12 aus dem aktuellen Vertex geladen werden soll.
Deine Vertex-Struktur muss nun dieser Information entsprechen, zb:struct Vertex { /* offset= 0 */ float position[3]; // sizeof(float)*3 = 12 /* offset=12 */ float normal[3]; /* offset=24 */ float texcoord[2]; };
-
"so weiss die GPU dass der Shader-Parameter "NORMAL" in Form von 3 floats ab Stelle 12 aus dem aktuellen Vertex geladen werden soll."
Achso, danke.
Wie genau legt man den aktuellen Vertex denn fest (mit den Variablen von oben?)?
Und wenn man DrawIndexedPrimitive benutzt, wird der aktuelle Vertex mit den Indizen des Index Buffers gebildet, sprich, dieser ist somit auch relevant für die Input Register?
Danke
-
Wie genau legt man den aktuellen Vertex denn fest?
Wozu sollte das gut sein?
Es werden so viele Primitiven verarbeitet wie Du angegeben hast.
In den Vertexshader geht jeweils ein Vertex rein und einer kommt wieder raus.
Im Fall von Triangles muessen dafuer eben jeweils drei verarbeitet werden.
Welcher gerade dran ist ist egal.
Ohne Indexbuffer werden dann immer drei im Vertexbuffer aufeinanderfolgende Vertices abgearbeitet.
Mit Indexbuffer werden diese eben an der entsprechenden Stelle aus dem Vertexbuffer gelesen.
Hier wird auch deutlich dass man die Buffer so anlegen sollte, dass nicht voellig zufaellig im Vertexbuffer herumgesprungen wird.