Nach mehrmaligem durcharbeiten des Buches und die ersten kleineren Programmierversuche mit der Engine (die mir im übrigen persönlich recht gut gefällt :biggrinlove: ) bin ich auf ein kleines Problem im Texturmanager gestoßen:
Wenn man den Texturmanager startet, wieder herunterfährt und dann ein weiteres mal startet bricht das Programm mit einem kritischen Fehler ab.
Ja, wer startet schon den Texturmanager ein weiteres mal? :huhu:
Das Problem liegt daran, dass tbMemFree() den void-Pointer nach Freigabe des Speichers nicht selbst auf NULL setzt. Von größeren Änderungen der Engine möchte ich lieber absehen, denn wer weiß (außer David vielleicht), was das für Folgebrobleme mit sich bringen könnte.
Als Ansatz könnte man aus dem Parameter einen Referenzpointer à la tbResult tbMemFree(void*& pMemory); machen und dann auf NULL setzen, allerdings gabs dann Probleme in der tbGUI mit dem Makro TB_SAFE_MEMFREE und ganz ansi-mäßig ist das sicher auch nicht.
Ok, also zur Ersatz-Lösung:
Das eigentliche Problem über das ich gestolpert bin, ist dass in der Exit()-Funktion der Pointer m_pTexturList immernoch in den Speicher zeigt, obwohl er nach dem freigeben aller Texturen auf NULL zeigen sollte. Also gehen wir in der tbTextureManager.cpp in die DeleteAllTextures() und vervollständigen am Ende:
// Die ganze Liste löschen
tbMemFree(m_pTextureList);
m_pTextureList = NULL;
m_iListSize = 0;
m_iNumTextures = 0;
Das sollte dieses kleine Problem beheben, über das sowieso niemand weiteres stolpern wird
Aber wenn wir schon mal dabei sind in der tbTextureManager.cpp rumzupfuschen...
Mir ist aufgefallen, dass beim laden einer Textur in der Struktur tbTextureListEntry die Werte für die Höhe, Breite und Tiefe der Textur nicht gespeichert werden, wenn wir als Parameter D3DX_DEFAULT verwenden. Ob das so sein soll && / || einen tieferen Sinn hat, weiss ich nicht, allerdings benötigte ich diese Informationen und ich bin mir relativ sicher, dass ich in diesem Fall nicht alleine dastehen sollte. Also hier die Änderungen:
In der Funktion LoadTexture(tbVFile* pVFile,...) folgende Zeilen vor dem Label TryAgain einfügen:
D3DXIMAGE_INFO imageInfo;
ZeroMemory(&imageInfo, sizeof(imageInfo));
Und folgende nach dem if(D3DXCreateTextureFromFileInMemoryEx)-Block, also vor AddTextureToList():
// tatsächliche Bilddimensionen ermitteln
iHeight = imageInfo.Height;
iWidth = imageInfo.Width;
Damit die imageInfo-Daten auch gefüllt werden muss er natürlich auch als vor-vor-letzter Parameter in D3DXCreateTextureFromFileInMemoryEx() eingefügt werden, also so:
D3DXCreateTextureFromFileInMemoryEx(tbDirect3D::GetDevice(), &(((BYTE*)(pVFile->GetBuffer()))[pVFile->GetCursor()]), pVFile->GetSize() - pVFile->GetCursor(), iWidth, iHeight, iNumMIPLevels, dwUsage, Format, Pool, dwFilter, dwMIPFilter, ColorKey, &imageInfo, NULL, &pTexture)
Diese Änderungen sollte man jetzt auch noch in LoadCubeTexture() und LoadVolumeTexture() vornehmen.
Bei der kubischen Textur reicht die Info einer Seite:
// tatsächliche Bilddimensionen ermitteln
iSize = imageInfo.Height;
Und bei der volumiösen ist die Tiefe auch recht interessant:
// tatsächliche Bilddimensionen ermitteln
iHeight = imageInfo.Height;
iWidth = imageInfo.Width;
iDepth = imageInfo.Depth;
Soviel dazu, ich hoffe das hilft weiter.