J
Mein Quellcode ist leider ganz schön verwinkelt, aber ich geb hier einfach mal paar Fetzen Code an:
Hier das Erzeugen, Updaten (Kopieren der Systemkopie in den Buffer) und Größe setzen für die Indexbuffer:
// :::::::::::::::::......... Erzeugungsfunktion
// ....::: Erzeugt das Vertex-Buffer Objekt mit den übergebenen Parametern fürs Device pcDevice.
// ....::: Dabei wird immer D3DUSAGE_WRITEONLY mit übergeben.
bool CVertexBuffer::Create(DWORD dwVertCount, DWORD dwVertSize, DWORD dwFVF,
LPDIRECT3DDEVICE8 pcDevice, DWORD dwUsage, D3DPOOL enPool)
{
if (dwVertCount == 0 || dwVertSize == 0 || pcDevice == NULL)
return false;
dwUsage |= D3DUSAGE_WRITEONLY;
if (FAILED(pcDevice->CreateVertexBuffer(dwVertCount * dwVertSize, dwUsage, dwFVF, enPool,
&this->m_pcVB)))
if (dwUsage & D3DUSAGE_DYNAMIC)
return this->Create(dwVertCount * dwVertSize, dwVertSize, dwFVF, pcDevice,
dwUsage ^ D3DUSAGE_DYNAMIC, enPool);
else
return false;
this->m_dwSize = dwVertCount * dwVertSize;
this->m_dwItemSize = dwVertSize;
this->m_dwFVF = dwFVF;
this->m_dwUsage = dwUsage;
this->m_dwItemCount = dwVertCount;
this->m_enPool = enPool;
this->m_pbData = new BYTE[this->m_dwSize];
return true;
}
// :::::::::::::::::......... Aktualisieren
// ....:::
bool CVertexBuffer::Update(void)
{
if (this->m_pcVB == NULL || this->m_pbData == NULL)
return false;
if (this->m_dwFirstItemIndex > m_dwLastItemIndex)
return true;
if (this->m_dwFirstItemIndex >= this->m_dwItemCount || m_dwLastItemIndex >= this->m_dwItemCount)
return false;
BYTE *pbVertices; // Hier werden die gesperrten VB-Daten zur Verfügung gestellt
DWORD dwCopyCount = (m_dwLastItemIndex - this->m_dwFirstItemIndex + 1) * this->m_dwItemSize;
// Vertex-Buffer sperren: Sperrflag 0 bei statischem Vertex-Buffer und Sperrflag
// D3DLOCK_DISCARD bei dynamischen.
if (FAILED(this->m_pcVB->Lock(this->m_dwFirstItemIndex * this->m_dwItemSize, dwCopyCount,
(BYTE**) &pbVertices, (m_dwUsage & D3DUSAGE_DYNAMIC) ? D3DLOCK_DISCARD : 0)))
return false;
// Vertexbuffer aktualisieren
memcpy(pbVertices, &this->m_pbData[this->m_dwFirstItemIndex], dwCopyCount);
this->m_pcVB->Unlock();
this->m_dwFirstItemIndex = this->m_dwItemCount - 1;
m_dwLastItemIndex = 0;
return true;
}
// :::::::::::::::::......... Größe verändern
// ....::: Setzt eine neue Größe für den Vertex-Buffer, indem zuerst lokal ein neuer mit der
// ....::: neuen Größer und den alten Eigenschaften erzeugt wird, danach der alte Inhalt in
// ....::: den neuen reinkopiert und der alte freigegeben wird.
bool CVertexBuffer::SetSize(const DWORD dwNewVertCount, LPDIRECT3DDEVICE8 pcDevice)
{
DWORD dwOldLast, dwOldFirst;
LPDIRECT3DVERTEXBUFFER8 pcNewVB;
if (dwNewVertCount == this->m_dwItemCount)
return true;
if (dwNewVertCount == 0 || pcDevice == NULL)
return false;
this->m_dwItemCount = dwNewVertCount;
if (FAILED(pcDevice->CreateVertexBuffer(dwNewVertCount * this->m_dwItemSize, this->m_dwUsage,
this->m_dwFVF, this->m_enPool, &pcNewVB)))
return false;
this->m_pcVB->Release();
this->m_pcVB = pcNewVB;
BYTE *pbData;
if (this->m_dwSize != 0)
{
pbData = new BYTE[this->m_dwSize];
memcpy(pbData, this->m_pbData, this->m_dwSize);
delete[] this->m_pbData;
}
this->m_pbData = new BYTE[dwNewVertCount * this->m_dwItemSize];
if (this->m_dwSize != 0)
{
memcpy(this->m_pbData, pbData, this->m_dwSize);
delete[] pbData;
}
dwOldFirst = this->m_dwFirstItemIndex;
dwOldLast = m_dwLastItemIndex;
this->m_dwFirstItemIndex = 0;
m_dwLastItemIndex = this->m_dwItemCount - 1;
if (!this->Update())
return false;
this->m_dwFirstItemIndex = dwOldFirst;
m_dwLastItemIndex = dwOldLast;
if (this->m_dwFirstItemIndex >= this->m_dwItemCount)
this->m_dwFirstItemIndex = this->m_dwItemCount - 1;
if (m_dwLastItemIndex >= this->m_dwItemCount)
m_dwLastItemIndex = this->m_dwItemCount - 1;
this->m_dwSize = dwNewVertCount * this->m_dwItemSize;
return true;
}
Ganz analog sehen die entsprechenden Funktionen für den IB aus, so dass ich die hier nich mehr angebe.
In einer Ladefunktion rufe ich diese Methoden auf, und zwar so:
// Wenn noch keine Vertizes drin, VB erzeugen
if (this->m_dwVertCount == 0)
this->m_pcVB->Create(dwVertCount, sizeof(VERTEX), D3DFVF_VERTEX, pcDevice);
// ansonsten erweitern
else
this->m_pcVB->SetSize(this->m_dwVertCount + dwVertCount, pcDevice);
....
// Vertex-Koos holen
D3DVECTOR *pstVertPointer = (D3DVECTOR*) lDataPointer;
for (DWORD h = 0; h < dwVertCount; h++)
{
pstVertices[h].fx = pstVertPointer[h].x;
pstVertices[h].fy = pstVertPointer[h].y;
pstVertices[h].fz = pstVertPointer[h].z;
}
....
// Textur-Koos holen
for (DWORD j = 0; j < dwCoords; j++)
{
pstVertices[j].ftu = pfCoords[2 * j];
pstVertices[j].ftv = pfCoords[2 * j + 1];
}
....
this->m_pcVB->SetItems(this->m_dwVertCount, dwVertCount, (BYTE*) pstVertices);
this->m_pcVB->Update();
delete[] pstVertices;
this->m_dwVertCount += dwVertCount;
...
Wenn ihr unbedingt noch sehen wollt, wie die IBs gefüllt werden, kann ich das ja noch posten.
Aber wie gesagt, die Daten müssen 100% OK sein, ich hab sie wieder aus den Buffern gelesen und
mit den Meshdaten verglichen, außerdem wird er ja mit DrawIndexedPrimitiveUP() korrekt gerendert.
Das Problem ist: Mit DrawIndexedPrimitive() geht es nicht, es wird nichts gerendert/angezeigt/ist nichts sichtbar, und nochmal: Keine der DX-Funktionen schlägt fehl.
Hier der relevante Code der Render-Funktion:
if (FAILED(pcDevice->SetStreamSource(0, this->m_pcVB->GetVB(), sizeof(VERTEX))))
fout << "FAILED VB" << endl;
if (FAILED(pcDevice->SetVertexShader(D3DFVF_VERTEX)))
fout << "FAILED VS" << endl;
for (DWORD i = 0; i < this->m_pcMaterialRef->GetMaterialCount(); i++)
{
pcDevice->SetMaterial(this->m_pcMaterialRef->GetMatDesc(i));
pcDevice->SetTexture(0, this->m_pcMaterialRef->GetTexture(i));
pcDevice->SetIndices(this->m_pcMaterialRef->GetIB(i), 0);
pcDevice->BeginScene();
if (FAILED(pcDevice->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 0, this->m_pcVB->GetItemCount(), 0,
this->m_pcMaterialRef->GetTriCount(i))))
fout << "FAILED Draw" << endl;
pcDevice->EndScene();
}
Hoffe das reicht !