Problem mit Renderer
-
Hallo alle zusammen,
Ich arbeite zur Zeit an einem Direct3D9 Renderer und implementiere gerade das Ressourcen Management. Dazu habe ich für die aktuell verwendeten VertexBuffer ein std::vector erstellt, welcher die akutell verwendeten VertexBuffer IDs speichert. Nur mein Problem dabei ist, dass das Programm einfach abstürtzt sobald ich eine ID aus dem Vektor mit einer ID als Parameter vergleiche...
Hier stürtzt mein Programm ab:
if(m_vCurrentVertexBuffers[uiStream] == idVertexBuffer) return RESULT_OK;Den Vektor habe ich in der Create-Funktion des Renderers vorbereitet(Speicher allokiert und Standardwerte gesetzt). Ich bin am verzeifeln... Kann mir bitte jemand helfen?
Danke im voraus,
0xDEADBEEF
-
Wie stürzt dein Programm genau ab?
würde mal raten, dass du den Vector "m_vCurrentVertexBuffers" ausserhalb der Grenzen ausliest. Also uiStream > m_vCurrentVertexBuffers.size()...
-
Äh moment, der vector hat doch Zugriffskontrolle, die gerade sowas ausschließt, oder bin ich da auf dem falschen Dampfer?
Aber prüf tatsächlich mal den Index! Vielleicht merkst du dann, was geht!
-
Ich benutze zwar seit Ewigkeiten kein C++ mehr, glaube mich jedoch dunkel erinnern zu können, dass der operator[] NICHT auf Indexgrenzen prüft und At() hingegen schon.
Wie auch immer: Eigentlich kann man solche Art von Bugs recht gut mit dem Debugger finden. Einfach alle Werte unmittelbar vorm Absturz beobachten.
-
Das Programm stürtzt an der oben gennanten Stelle einfach ab... Der Vektor besitzt zur Laufzeit 16 Elemente(die maximale Anzahl an Streams) und es soll eben verglichen werden, ob die spezifizierte VertexBufferID bereits für diesen Stream verwendet wird. Wenn ja wird die Funktion verlassen. Ich zeige einfach mal den kompletten Quelltext der ChangeVertexBuffer Funktion:
EResult CD3D9Renderer::ChangeVertexBuffer(const VertexBufferID idVertexBuffer, const uint32 uiStream, const uint32 uiOffset, const uint32 uiStride) { [cpp] if(uiStream < 0 || uiStream > m_sCaps.MaxStreams) return RESULT_ERROR; // Hier gehts kaputt :) if(m_vCurrentVertexBuffers[uiStream] == idVertexBuffer) return RESULT_OK; if(idVertexBuffer == VB_NONE) { if(FAILED(m_pD3DDevice->SetStreamSource(uiStream, 0, 0, 0))) return RESULT_ERROR; } else { if(FAILED(m_pD3DDevice->SetStreamSource(uiStream, m_vVertexBuffer[idVertexBuffer].pVertexBuffer, uiOffset, uiStride))) return RESULT_ERROR; // und hier m_vCurrentVertexBuffers[uiStream] = idVertexBuffer; } return RESULT_OK; }In der CD3D9Renderer Klassendeklaration ist der Vektor so deklariert:
std::vector<VertexBufferID> m_vCurrentVertexBuffers;Und so bereite ich den Vektor vor:
m_vCurrentVertexBuffers.reserve(m_sCaps.MaxStreams);
for(uint32 i = 0; i < m_vCurrentVertexBuffer.size(); i++) m_vCurrentVertexBuffers[i] = VB_NONE;Der Debugger spuck das hier aus
Unbehandelte Ausnahme bei 0x00405a45 in Speedrun.exe: 0xC0000005: Zugriffsverletzung beim Lesen an Position 0x00000000
-
1. uiStream ist unsigned, daher ist die Prüfung auf < 0 schwachsinnig.
2. Du lässt nach oben hin eins zu viel zu - die Bedingung müsste lauten:
uiStream >= m_sCaps.MaxStreams3. vector::reserve fügt keine Elemente hinzu, sondern reserviert nur schonmal Speicher. Deine unten angegebene for-Schleife ist also falsch. Richtigerweise müsstest du die Elemente dort mit push_back (oder insert) einfügen.
-
Danke schnomal für die zahlreichen Antworten
@ThomasRiker:
zu 1: Hast recht, seh den Wald vor lauter Bäumen einfach nicht mehr...
zu 2: ohne Worte
zu 3: Irgendwann war das auch mal ein push_back
Leider läuft das Programm immer noch nicht. Ich hab schonmal ein bisschen gedebugged und als letzes in der Aufrufliste stehen Funktionen die ich noch nie gesehen hab
_crt_debugger_hook -> kein Plan !!!
_invalid_parameter -> " " "
_invalid_parameter_info -> ???
-
Hab nun herausgefunden wieso das Prog abgestürtzt ist. Die Initialisierung des Vektors war fehlerhaft. Ich zeigs einfach...
vorher:
for(uint32 i = 0; i < m_vCurrentVertexBuffers.size(); i++) m_vCurrentVertexBuffers.push_back(VB_NONE);nachher:
for(uint32 i = 0; i < m_uiMaxStreams; i++) m_vCurrentVertexBuffers.push_back(VB_NONE);Beim Aufrufen der size Funktion ist der Vektor noch leer, und deshalb werden die Anweisungen niemals ausgeführt... Und das ist der Grund weshalb alle späteren abfragen scheitern.
Dennoch funktioniert nichts wie es soll. In meinem Beispielprog wechsele ich mit der ChangeVertexBuffer Funktion meines Renderers den VertexBuffer.
m_pRenderer->ChangeVertexBuffer(idVertexBuffer, 0, // Stream 0, // Offset sizeof(SVertex));Doch jetzt das sehr sehr komische...

Zur Laufzeit haben sich die Werte für Stream, Offset und uiStride(letzter Parameter von ChangeVertexBuffer) von 0 zu 4224537 geänder???

Das sagt mir zumindest mein Debugger wenn ich einen Breakpoint in die ChangeVertexBuffer Funktion setze und mit dem Mauscursor über die Variablen gehe. Ich habe niemals einen solchen Wert gesetzt und deshalb verstehe ich gerade die Welt nicht mehr.