[erledigt] Texturieren DX9



  • Hi leutz,
    hab ma ne Frage zum Textutrieren.
    Wie man es mit nem Dreieck anstellt ist mir ja klar. Nun hab ich aber nen Würfel, der oben und unten offen ist (soll ne Mauer darstellen). Nun möchte ich ne schöne Textur drauflegen. Wie mache ich das jetzt?
    Bei meinem Versuch, der Vorderseite zu texturieren, sieht man nichts. Ich habs genauso wie beim Dreieck gemacht. Also die Texturkoordinaten, die Koordinaten der Vertices zugeordnet.
    Muss ich was beachten, wenns was anderes wie ein Dreick ist?



  • Lass mal deine Vertexdaten sehen (x,y,z,tu,tv)



  • Meine Vertexstruktur sieht so aus

    struct Vertex
    {
         D3DXVECTOR3 vPos;
         D3DCOLOR color;
         D3DXVECTOR2 vTex;
    }
    

    Hab als Texturkoordinaten halt einen 2D-Vektor genommen. Wie gesagt, bei Dreiecken gabs keine Probleme.



  • Und jetzt die Vertexdaten ...



  • Also, jetzt ne andere Frage:
    Was muss ich beim Texturieren beachten, wenn ich nen Indexbuffer benutze?



  • Crossposting
    Ich mache den Thread zu.



  • 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 😉


Anmelden zum Antworten