Vertexbuffer und Memory Leak
-
Ich verzweifel mal wieder. Nachdem ich erfolgreich mein Dreieck in einem Fenster gerendert habe, jetzt das naechste fette Problem, fuer das ich absolut keinen Fehlergrund finde.
Es geht anscheinend um meinen Vertexbuffer - wenn ich den anzeigen will, gibt es einen BlueScreen bei Systemen ohne Debug-DLL's. Da das Programm aber ueberall laufen muss, sollte das Problem doch irgendwie geloest werden
Es geht um eine Darstellung von Daten in einem Diagramm. Dazu habe ich eine Funktion, die mir die reellen Daten in 3D-Daten umrechnet (also ungefaehr alles zwischen -2.0f und 2.0f).
Zur Darstellung benutze ich einen Linestrip (es hat lange gedauert, bis ich herausgefunden habe, dass man sich dabei nicht ausziehen muss). Dieser verbindet alle Punkte des Diagramms.
Zuerst reserviere ich Speicher, je nach Anzahl der gegebenen Daten:
m_screen_data = new CUSTOMVERTEX[m_array_size];
CUSTOMVERTEX besteht aus x, y, z und Farbe (definiert als D3DFVF_CUSTOMVERTEX). Nach Befuellen des Feldes lege ich einen Vertexbuffer an:
if( FAILED( m_pD3DDevice->CreateVertexBuffer( m_array_size*sizeof(CUSTOMVERTEX), 0, D3DFVF_CUSTOMVERTEX, D3DPOOL_DEFAULT, &m_pVB, NULL ) ) ) { return E_FAIL; } VOID* pVertices; if( FAILED( m_pVB->Lock( 0, m_array_size*sizeof(CUSTOMVERTEX), (void**)&pVertices, 0 ) ) ) return E_FAIL; memcpy( pVertices, m_screen_data, m_array_size*sizeof(CUSTOMVERTEX) ); m_pVB->Unlock();
Da ich schon bei meiner umfangreichen Recherche herausgefunden habe, dass ich (natuerlich) irgendwo auf Speicher zugreife, auf den ich nicht zugreifen darf, hab ich (natuerlich) mir die Parameter genau angeguckt. Obwohl nach MSDN der Aufruf von CreateVertexBuffer nicht die Groesse des gesamten Feldes (hier m_array_size*sizeof(CUSTOMVERTEX)) angegeben werden muss, sondern nur die eines Vertex, klappt es leider nicht anders. Nach der Erstellung des Buffers locke ich diesen (wieder mit der Groesse des Arrays), kopiere die Daten rein und gebe den Buffer anschliessend wieder frei.
Das Rendern geht folgendermassen vonstatten:
m_pD3DDevice->SetStreamSource( 0, m_pVB, 0, sizeof(CUSTOMVERTEX) ); m_pD3DDevice->SetFVF( D3DFVF_CUSTOMVERTEX ); m_pD3DDevice->DrawPrimitive( D3DPT_LINESTRIP, 0, m_array_size-1 );
Hier setze ich den Stream und zeichne genau Feldgroesse-1 Linien.
Wie gesagt, das klappt auch alles (wunderbar), allerdings fuehrt das Prog bei anderen Systemen zum Bluescreen (genau an der Stelle DrawPrimitive).
Also, was verdammt mache ich falsch? Wo gebe ich zuviel Speicher frei oder zu wenig und was ist der richtige Wert?
Meine Grafikkarte am Entwicklungsrechner (wo's laeuft) ist "Intel(r) 82815 Graphics Controller", der Rechner an dem es nicht laeuft hat eine ATI Radeon 7500. Es gibt einen Thread im Internet, wo jemand vor einem Jahr geschrieben hat, dass die NVIDIA Treiber nicht pruefen, ob der Vertexbuffer richtig geschrieben wird. Ich hoffe, es liegt daran, aber wie gesagt, ich kann keinen Fehler finden!
viel gruesse aus dem warmen Australien,
bjoern
-
Kann m_array_size 0 werden?
-
Nein, wird es nicht. Wie gesagt, der Code funktioniert auf meinem Arbeitsrechner wunderbar!
Allerdings habe ich das Prog auf der Arbeitg jetzt weiterentwickelt und wenn ich es jetzt zuhause starte, habe ich schon einen Bluescreen bei
m_pHelplineFont->Begin();
zuvor initialsiert mit
LPD3DXFONT m_pHelplineFont;
Vielleicht liegts auch an meinem Grafiktreiber. Den kann ich aber nicht gefahrlose updaten, denn ich habe eine Mobility Radeon 7500. Dennoch - wie kann ich einen Fehler finden, wenn Windows mich immer mit einem Bluescreen verabschiedet? Und warum läuft das Prog auf der Arbeit, wo ich exakt dieselben Versionen von VS und DX verwende?
-
Dann würde ich einfach mal auf Treiberprobleme tippen. Aus deinem Code lassen sich jedenfalls zu wenig Infos rausholen. Wieso kannst du deine Treiber nicht gefahrlos updaten?
-
Das Problem war, dass ich einen Sony Laptop hab und deshalb ATI keine Treiber dafür herstellt. Aber durch Zufall hab ich dann doch den Vaio Link gefunden (man sollte denken, den zu finden, sollte schneller gehen!) und geupdatet.
Jetzt gehts!!
Allerdings wieder ein Fehler: Mit DrawText und LPD3DXFONT lasse ich einen Text updaten. Der wird am Anfang auch angezeigt, sobald ich aber mit der neuen Routine render, gibts nur noch ein rechteck in der Schriftgröße. Auch hier ist der Code nicht schuld, der geht, vermutlich liegts immer noch am Treiber...
Schon komisch, dass solche rudimentären Dinge nicht funktionieren...