[erledigt] Texturieren DX9
-
Ok, nachdem die Sache mit dem Crossposting nun aus der Welt ist, starte ich einen neuen Versuch.
Was muss ich denn machen, damit das Texturieren auch mit IndexBuffer klappt?
-
TomasRiker schrieb:
Und jetzt die Vertexdaten ...
-
Was muss ich denn machen, damit das Texturieren auch mit IndexBuffer klappt?
eigentlich waere es doch hinreichend, einfach mal nachzulesen, was index-buffer sind.
-
Ich weis das man mit dem indexbuffer, die Vertices aus dem Vertexbuffer auf den Bildschirm bringen kann. Wie hilft mir das nun beim Texturieren? Ich möchte jetzt nicht ungeduldig wirken, aber ich denke mal, dass es klar ist, dass ich moment nicht weiter komme. Ausserdem bekomme ich nie konkrete Antworten. Es ist nicht so dass ich nicht versucht habe es selbst zu lösen, ich kriegs einfach nicht hin. Also würde ich gerne wissen, was ich beachten muss, wenn ich einen Indexbuffer zum zeichnen benutze.
Muss man da was überhaupt was beachten? Ich hab ma gelesen, dass man um z.B. einen Würfel zu texturieren, die 8 Vertices aus dem VBuffer, welche ich dann mit 36 indices anspreche, nicht ausreichen, und man deswegen noch mehr Vertices un den VBuffer packen muss. Bin aber daraus nicht sonderlch schlau geworden, deswegen suche ich hier jemanden der mir das genau erklären kann.
-
mit einem indexbuffer gibst du nichtmehr direkt dreiecke als abfolge von vertices an, sondern hast einen haufen vertices und gibst an wie die verbunden werden um die entsprechenden dreiecke zu bilden. (hoffe ich hab das einigermaßen verständlich ausgedrückt)
wo du aufpassen musst, sind dinge wie z.b. normalvektoren und texturkoordinaten (generell also vertexattribute).
du kannst nun z.b. einen würfel aus 8 vertices machen und die dann über indices zu den dreiecken verbinden. das problem was sich hier stellen wird ist, dass sich zwar mehrere dreiecke einen gemeinsamen eckpunkt teilen, aber an dieser ecke verschiedene texturkoordinaten und normalvektoren benötigen (das berühmte würfel problem mit den scharfen kanten...).
nun musst du z.b. entweder den gleichen vertex mehrmals mit verschiedenen normalvektoren erzeugen und die indices anpassen, oder du nimmst einen gemittelten wert (was im würfelfall dumm aussieht, andererseits aber auch brauchbar sein kann -> stichwort smoothing groups).
das bsp mit den normalvektoren gilt prinzipiell für jedes beliebige vertexattribut, sobald mehrere dreiecke die auf das gleiche vertex verweisen verschiedene attribute erfordern, gibts entweder duplizieren und indices anpassen oder die einzelwerte mitteln...mehr kann ich zu deinem problem nicht sagen, weil dus ein bisschen informationsarm beschrieben hast
-
Hey super, danke fr die schnelle Antwort.
Nun mein Problem ist eigentlich viel einfacher. Ich hab zur Übung ein ganz normales Viereck mit nem IndexBuffer gezeichnet. Das Texturieren funktioniert aber nicht. Wenn ich das 4Eck mit DrawPrimitiveUP() zeichne, und die Texturkoordinaten angebe, dann klappts.int InitQuad() { quad.vertices[0].vPos = D3DXVECTOR3(-1, 1, 0); quad.vertices[1].vPos = D3DXVECTOR3(1, 1, 0); quad.vertices[2].vPos = D3DXVECTOR3(1, -1, 0); quad.vertices[3].vPos = D3DXVECTOR3(-1, -1, 0); //Texturkoordinaten quad.vertices[0].vTex = D3DXVECTOR2(0.0f, 0.0f); quad.vertices[1].vTex = D3DXVECTOR2(1.0f, 0.0f); quad.vertices[2].vTex = D3DXVECTOR2(1.0f, 1.0f); quad.vertices[3].vTex = D3DXVECTOR2(0.0f, 1.0f); for(int i = 0; i < 4; i++) { quad.vertices[i].color = D3DCOLOR_ARGB(255, 255, 255, 255); } CreateIndexBuffer(); LoadTexture(); ... }
Warum klappt das nicht so. Ich hab ja 4Vertices, und gebe jedem eine Textukoordinate mit. Das 4Eck erscheint aber nur einfarbig in der Farbe der Textur, ohne Muster oder so.
Wenn noch mehr Infos benötigt werden einfach bescheid sagen.
-
zeig mal bitte den code der das ganze rendert (und dein verwendetes FVF bzw. deinen shader).
außerdem wäre noch der inhalt des indexbuffers und des vertexbuffers interessant
-
das bloede ist halt, dass der indexbuffer gerade beim wuerfel fast ueberfluessig ist. lediglich die zwei dreiecke die jeweils eine seite bilden, haben an einer kante gemeinsame vertexattribute - dh du haettest fuer jede der 6 seiten jeweils 4 vertices in deinem vertexbuffer plus 6 indices im index-buffer die daraus 2 dreiecke bilden:
a1-----a4 | | | | a2-----a3
vertexbuffer= {a1,a2,a3,a4, // [0-3] vertices des ersten quads (gegen uhrzeigersinn) b1,b2,b3,b4, // [4-7] zweites quad //... e1,e2,e3,e4, // [16-19] fuenftes quad f1,f2,f3,f4};// [20-23] letztes quad
indexbuffer= {0,1,2, // erstes dreieck des ersten quads (a1,a2,a3,a4) 0,2,3, // zweites dreieck des quads 4,5,6, // zweites quad 4,6,7, // ... };
der clou ist jetzt - an diesem beispiel aber schlecht einzusehen - dass die grafikkarte einen begrenzten vertex-cache hat, in dem jeder vertex erstmal abgelegt wird, der durch die transformations-einheit gelaufen ist.
ein folgender vertex mit einem im cache noch vorhanden index ist also umsonst.
ziel des ganzen waere also, die eintraege des indexbuffers so zu sortieren, dass ein maximum von vertices wiederverwendet werden kann.
fuer das letzte stueckchen performance sollte man den vertexbuffer dann noch so sortieren, dass trotz indexings immer sequentiell ausgelesen wird.
-
@ dot:
hier mal meine Draw3D Funktion.
int Draw3D() { pD3DDevice->SetFVF(D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_TEX1); //Projektionsmatrix D3DXMATRIX mxProjection; D3DXMatrixPerspectiveFovLH(&mxProjection, D3DX_PI/4, iWindowWidth/iWindowHeight, 0.1f, 200.0f); pD3DDevice->SetTransform(D3DTS_PROJECTION, &mxProjection); //Vereinende Weltmatrix D3DXMATRIX mxWorld; D3DXMatrixTranslation(&mxWorld, fWorldX, fWorldY, fWorldZ); pD3DDevice->SetTransform(D3DTS_WORLD, &mxWorld); //Weltmatrix directX Mitteilen pD3DDevice->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 0, 0, 6, 0, 2); //pD3DDevice->DrawPrimitiveUP(D3DPT_TRIANGLELIST, 1, static_cast<void*>(&tri2.vertices[0]), sizeof(Vertex)); //pD3DDevice->DrawPrimitiveUP(D3DPT_TRIANGLELIST, 2, static_cast<void*>(&tou.vertices[0]), sizeof(Vertex)); return 0; }
Und mein IndexBuffer
int CreateIndexBuffer() { pD3DDevice->CreateVertexBuffer(4 * sizeof(Vertex), 0, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_TEX1, D3DPOOL_MANAGED, &pD3DIndexedVertexBuffer, NULL); pD3DDevice->CreateIndexBuffer(6 * sizeof(USHORT), 0, D3DFMT_INDEX16, D3DPOOL_MANAGED, &pD3DIndexBuffer, NULL); Vertex *pVBuffer = NULL; USHORT *pIBuffer = NULL; //VertexBuffer sperren pD3DIndexedVertexBuffer->Lock(0, 0, reinterpret_cast<void**>(&pVBuffer), D3DLOCK_NOSYSLOCK); //Sperren des IndexBuffers pD3DIndexBuffer->Lock(0, 0, reinterpret_cast<void**>(&pIBuffer), D3DLOCK_NOSYSLOCK); D3DXVECTOR3 vWallPos; //V-Buffer füllen for(int i = 0; i < 4; i++) { pVBuffer[i].vPos = quad.vertices[i].vPos; pVBuffer[i].color = quad.vertices[i].color; } //IndexBuffer füllen USHORT indices[6] = {0,1,2, 0,2,3}; for(int i = 0; i < 6; i++) { pIBuffer[i] = indices[i]; } //Alle Puffer entsperren pD3DIndexedVertexBuffer->Unlock(); pD3DIndexBuffer->Unlock(); //Vertex- und IndexBuffer als Quelle angeben pD3DDevice->SetStreamSource(0, pD3DIndexedVertexBuffer, 0, sizeof(Vertex)); pD3DDevice->SetIndices(pD3DIndexBuffer); return 0; }
@hellihjb:
Warum 4 Vertices pro Seite. Wenn man nen Indexbuffer hat reichen doch 8 aus. Hat das dann was mit dem Texturieren zu tun?
Und was hat es eigentlich für auswirkungen, wenn sich mehrere Dreiecke ein Vertex teilen?
Sorry bin echt noch ein Anfänger und hab noch nicht viel Ahnung
-
Ok, hat sich erledigt. Ich habs geschafft, Danke an dott, der mir bei spieleprogrammirer.de den entscheidenden Tipp gegeben hat.
-
immer wieder gerne