JLI Spieleprogrammierung Foren-Übersicht JLI Spieleprogrammierung

 
 FAQFAQ   SuchenSuchen   MitgliederlisteMitgliederliste   BenutzergruppenBenutzergruppen 
 medals.php?sid=8cb4c130615e1e33828e549e0dc1f055Medaillen   RegistrierenRegistrieren   ProfilProfil   Einloggen, um private Nachrichten zu lesenEinloggen, um private Nachrichten zu lesen   LoginLogin 

Device Reset schlägt fehl bei Rendertarget
Gehe zu Seite 1, 2  Weiter
 
Neues Thema eröffnen   Neue Antwort erstellen    JLI Spieleprogrammierung Foren-Übersicht -> DirectX, OpenGL
Vorheriges Thema anzeigen :: Nächstes Thema anzeigen  
Autor Nachricht
The Lord of Programming
Living Legend


Alter: 37
Anmeldedatum: 14.03.2003
Beiträge: 3122

Medaillen: Keine

BeitragVerfasst am: 27.02.2008, 16:27    Titel: Device Reset schlägt fehl bei Rendertarget Antworten mit Zitat

Die Überschrift drückts recht gut aus.
Es klappt alles ohne Probleme, aber sobald ich ein Rendertarget erstelle (ich muss das nicht mal per SetRendertarget setzen), bekomme ich von der Reset()-Methode des D3D9-Devices ein unbarmherziges "D3DERR_INVALIDCALL".
Ich gebe alle Texturen (egal ob managed oder nicht) vor dem Reset frei.

So erstelle ich das Target:
CPP:
//*******************************************************************
//[[[ Rendertarget erstellen ]]]
//*******************************************************************
cDevice->CreateTexture(Width,Height,1,D3DUSAGE_RENDERTARGET,
        D3DFMT_A8R8G8B8,D3DPOOL_DEFAULT,&new_sprite.sTexture,NULL);


Größe und Format sind dieselben wie bei den PresentationParameters für den Backbuffer angegeben. Diese übergebe ich natürlich beim Reset()-Aufruf mit.

Irgendwelche Ideen, woran es liegen könnte?
_________________
www.visualgamesentertainment.net
Current projects: RDTDC(1), JLI-Vor-Projekt, Tetris(-Tutorial), JLI-Format
(1) Realtime Developer Testing and Debugging Console


Anschlag, Anleitung zum Atombombenbau, Sprengkörper...
Hilf Schäuble! Damit er auch was findet...
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden Website dieses Benutzers besuchen
Fallen
JLI MVP
JLI MVP


Alter: 40
Anmeldedatum: 08.03.2003
Beiträge: 2860
Wohnort: Münster
Medaillen: 1 (mehr...)

BeitragVerfasst am: 27.02.2008, 17:49    Titel: Antworten mit Zitat

Wenn CreateTexture erfolgreich verläuft aber Reset() fehlschlägt dann musst du noch irgendwo eine Referenz auf deine Textur halten, aktiviere die DX Deebug Runtime und beachte das Outputfenster deiner IDE, dort sollte stehen was genau da Probleme macht.
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden Website dieses Benutzers besuchen
The Lord of Programming
Living Legend


Alter: 37
Anmeldedatum: 14.03.2003
Beiträge: 3122

Medaillen: Keine

BeitragVerfasst am: 28.02.2008, 01:06    Titel: Antworten mit Zitat

Danke, hab die Debug Runtime eigentlich noch nie so wirklich verwendet, aber hab jetzt gleich mal einen Heap-Memoryleak feststellen können.
Dummer Fehler von mir.

Ich hab fürs Erstellen des Indexbuffers einen Zeiger erstellt, der auf NULL zeigt, den für den Buffer angegeben, gesperrt und per Indexoperator hineingeschrieben. Ich weiß auch nicht mehr, wo ich mir das abgeschaut hab und wieso das bisher geklappt hat...
Jedenfalls hab ich das jetzt als Array definiert und nicht als einfachen Zeiger ins Leere laufen lassen.

So, nun aber noch eine Frage: Beim direkten Reinschreiben scheints ja so Probleme zu geben, aber (wieso) gibt es die nicht, wenn man per memcpy in den Buffer kopiert?

Beispiele:

Geht nicht:
CPP:
short* index_data;

//Create Indexbuffer

//Buffer fürs Schreiben locken
sIndexbuffer->Lock(0,0,(void**)&index_data,0);

//Daten(Indizies) schreiben
index_data[0]=0;
index_data[1]=1;
index_data[2]=2;
index_data[3]=3;

//Unlocken


Wieso geht das hier? So wirds nämlich auch im Buch gemacht.
Hier wird auch kein Speicher für den letztendlichen Zielbuffer reserviert.
Seh ich richtig, dass das schlechter Stil ist bzw, auch zu Leaks/Problemen führen kann?
CPP:
short* index_data;
short index_data_array[4];

//Daten(Indizies) schreiben
index_data_array[0]=0;
index_data_array[1]=1;
index_data_array[2]=2;
index_data_array[3]=3;

//Create Indexbuffer

//Buffer fürs Schreiben locken
sIndexbuffer->Lock(0,0,(void**)&index_data,0);

//Daten kopieren
memcpy(index_data,index_data_array,sizeof(index_data_array));

//Unlocken

_________________
www.visualgamesentertainment.net
Current projects: RDTDC(1), JLI-Vor-Projekt, Tetris(-Tutorial), JLI-Format
(1) Realtime Developer Testing and Debugging Console


Anschlag, Anleitung zum Atombombenbau, Sprengkörper...
Hilf Schäuble! Damit er auch was findet...
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden Website dieses Benutzers besuchen
Fallen
JLI MVP
JLI MVP


Alter: 40
Anmeldedatum: 08.03.2003
Beiträge: 2860
Wohnort: Münster
Medaillen: 1 (mehr...)

BeitragVerfasst am: 28.02.2008, 06:42    Titel: Antworten mit Zitat

Sollte der IndexBufferArray nicht vom Typ WORD anstatt vom Typ short sein? Zumidest mache ich es so und es funktioniert.
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden Website dieses Benutzers besuchen
The Lord of Programming
Living Legend


Alter: 37
Anmeldedatum: 14.03.2003
Beiträge: 3122

Medaillen: Keine

BeitragVerfasst am: 28.02.2008, 16:32    Titel: Antworten mit Zitat

Haben doch beide 2 Bytes. KA, ob WORD da richtiger ist. Es funktioniert ja jetzt auch mit short.

Nur meine Frage war, wieso man memcpy einfach auf einen Zeiger anwenden kann, der irgendwo in den Speicher zeigt.
Dass es knallen kann, wenn man per Indexoperator drauf zugreift, ist mir klar. Aber ich verstehe/weiß nicht, was da memcpy anders macht.
_________________
www.visualgamesentertainment.net
Current projects: RDTDC(1), JLI-Vor-Projekt, Tetris(-Tutorial), JLI-Format
(1) Realtime Developer Testing and Debugging Console


Anschlag, Anleitung zum Atombombenbau, Sprengkörper...
Hilf Schäuble! Damit er auch was findet...
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden Website dieses Benutzers besuchen
DirectXer
Dark JLI'ler



Anmeldedatum: 05.02.2005
Beiträge: 1201
Wohnort: Köln
Medaillen: Keine

BeitragVerfasst am: 28.02.2008, 17:45    Titel: Antworten mit Zitat

kann es sein das deine Indexdaten read-only sind? Laut DX-Doc führt sowas zu undefiniertem verhalten, da das ja direkt auf der graka ist und die keine guardians hat...

Gruß DXer
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden
The Lord of Programming
Living Legend


Alter: 37
Anmeldedatum: 14.03.2003
Beiträge: 3122

Medaillen: Keine

BeitragVerfasst am: 28.02.2008, 18:50    Titel: Antworten mit Zitat

DirectXer hat Folgendes geschrieben:
kann es sein das deine Indexdaten read-only sind? Laut DX-Doc führt sowas zu undefiniertem verhalten, da das ja direkt auf der graka ist und die keine guardians hat...

Gruß DXer

Wenn Readonly der Standardwert (0) ist, sind sie das wohl. Spielt aber auch keine Rolle, es gibt ja keine Probleme/Leaks mehr.

Ich finds nur verwirrend - deshalb die Frage - wieso memcpy da so einfach rankommt, ohne Speicher zu reservieren (was ja mit dem Indexoperator anstatt memcpy Probleme bereiten kann).
_________________
www.visualgamesentertainment.net
Current projects: RDTDC(1), JLI-Vor-Projekt, Tetris(-Tutorial), JLI-Format
(1) Realtime Developer Testing and Debugging Console


Anschlag, Anleitung zum Atombombenbau, Sprengkörper...
Hilf Schäuble! Damit er auch was findet...
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden Website dieses Benutzers besuchen
DirectXer
Dark JLI'ler



Anmeldedatum: 05.02.2005
Beiträge: 1201
Wohnort: Köln
Medaillen: Keine

BeitragVerfasst am: 28.02.2008, 20:44    Titel: Antworten mit Zitat

The Lord of Programming hat Folgendes geschrieben:
DirectXer hat Folgendes geschrieben:
kann es sein das deine Indexdaten read-only sind? Laut DX-Doc führt sowas zu undefiniertem verhalten, da das ja direkt auf der graka ist und die keine guardians hat...

Gruß DXer

Wenn Readonly der Standardwert (0) ist, sind sie das wohl. Spielt aber auch keine Rolle, es gibt ja keine Probleme/Leaks mehr.

Ich finds nur verwirrend - deshalb die Frage - wieso memcpy da so einfach rankommt, ohne Speicher zu reservieren (was ja mit dem Indexoperator anstatt memcpy Probleme bereiten kann).

naja memcpy arbeitet mit pointern und unsigned 8-bit, nicht mit arrays und 16-bit, aber eigentlich dürfte das keinen unterschied machen... wo gibts denn genau den fehler? beim ersten [0]? probier vllt auch mal mit 8-bit-pointern zu arbeiten?

Gruß DXer
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden
The Lord of Programming
Living Legend


Alter: 37
Anmeldedatum: 14.03.2003
Beiträge: 3122

Medaillen: Keine

BeitragVerfasst am: 28.02.2008, 21:39    Titel: Antworten mit Zitat

DirectXer hat Folgendes geschrieben:
wo gibts denn genau den fehler? beim ersten [0]?

Es tritt nicht mal immer auf. Ich konnte meistens ein paar Indexbuffer erstellen, bis er irgendwann deswegen gemeckert hat. Ich vermute, der wird einfach meckern, wenn die Stelle im Speicher [arrayanfang+arraygröße] schon von irgendwas anderes allokiert wurde.

Nehm ich nur den Zeiger "short* indices;" her, wer sagt mir, dass 4 Stellen weiter im Speicher immer noch nichts ist? Ich könnt ja theoretisch auch mit dem Index 9999 zuzugreifen versuchen.
Dasselbe wäre per memcpy im Prinzip auch möglich, wenn ich ein 1000-er Array erstelle und das per memcpy an die betreffende Stelle im Speicher kopiere.

Unsigned 8-bit? Aber Vertexbuffer und Indexbuffer haben doch eine feste Größe für die Einzelwerte. Mit 8 Bit könnten Indexbuffer ja maximal 256 verschiedene Indizes enthalten.
_________________
www.visualgamesentertainment.net
Current projects: RDTDC(1), JLI-Vor-Projekt, Tetris(-Tutorial), JLI-Format
(1) Realtime Developer Testing and Debugging Console


Anschlag, Anleitung zum Atombombenbau, Sprengkörper...
Hilf Schäuble! Damit er auch was findet...
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden Website dieses Benutzers besuchen
DirectXer
Dark JLI'ler



Anmeldedatum: 05.02.2005
Beiträge: 1201
Wohnort: Köln
Medaillen: Keine

BeitragVerfasst am: 02.03.2008, 11:52    Titel: Antworten mit Zitat

The Lord of Programming hat Folgendes geschrieben:
Unsigned 8-bit? Aber Vertexbuffer und Indexbuffer haben doch eine feste Größe für die Einzelwerte. Mit 8 Bit könnten Indexbuffer ja maximal 256 verschiedene Indizes enthalten.

Nein ich meine memcpy, dem übergibst du unsigned char* und die Größe in Bytes (kann auch char* sein, ist hier egal). Ist ja dasselbe hier, wird eben nur byte für byte kopiert, nicht 16-bitweise. Im Grunde ist das aber zweirangig....

Aber der Fehler tritt nur auf, wenn du dem Wert etwas versuchst zuzuweisen oder? memcpy greift ja nur lesend darauf zu, das würde das dann erklären. Dann spricht das vielleicht wirklich für read-only.

Gruß DXer
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden
The Lord of Programming
Living Legend


Alter: 37
Anmeldedatum: 14.03.2003
Beiträge: 3122

Medaillen: Keine

BeitragVerfasst am: 02.03.2008, 14:42    Titel: Antworten mit Zitat

Also jetzt bin ich verwirrt...

DirectXer hat Folgendes geschrieben:
Nein ich meine memcpy, dem übergibst du unsigned char* und die Größe in Bytes (kann auch char* sein, ist hier egal). Ist ja dasselbe hier, wird eben nur byte für byte kopiert, nicht 16-bitweise. Im Grunde ist das aber zweirangig....

Ja...ich übergebe memcpy schlichtweg die Form, in der es vorliegt. D.h. für den Vertexbuffer ein Array mit einer Struktur und für den Indexbuffer ein short-Array. Dürfte eigentlich ziemlich egal sein, da memcpy sowieso immer auf die gleiche Weise kopiert.

DirectXer hat Folgendes geschrieben:
Aber der Fehler tritt nur auf, wenn du dem Wert etwas versuchst zuzuweisen oder? memcpy greift ja nur lesend darauf zu, das würde das dann erklären. Dann spricht das vielleicht wirklich für read-only.

Memcpy greift auf den zweiten Parameter lesend zu(const void *src) und auf den ersten schreibend(void *dest). Insofern verstehe ich nicht, was da anders sein soll.

Das Ziel bleibt ja das gleiche, ob ich memcpy nehme oder den Indexoperator.

CPP:
short* index_data;

memcpy(index_data,index_data_array,sizeof(index_data_array));

//oder:
index_data[0]=0;
//[...]


Die Quelle ist halt einmal ein ganzes Array, das byteweise Kopiert wird und das andere Mal ein einzelner Wert. Aber da sehe ich nicht das Problem(die Quelle ist ja im Speicher schon reserviert)...eher am Ziel.
Erstelle ich einen Zeiger, der einfach ins nichts läuft, wie kann das gut gehen, wenn ich da schreibend darauf zugreife?
Ist es nicht auch schlechter Stil, Zeiger uninitialisiert zu lassen?
_________________
www.visualgamesentertainment.net
Current projects: RDTDC(1), JLI-Vor-Projekt, Tetris(-Tutorial), JLI-Format
(1) Realtime Developer Testing and Debugging Console


Anschlag, Anleitung zum Atombombenbau, Sprengkörper...
Hilf Schäuble! Damit er auch was findet...
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden Website dieses Benutzers besuchen
DirectXer
Dark JLI'ler



Anmeldedatum: 05.02.2005
Beiträge: 1201
Wohnort: Köln
Medaillen: Keine

BeitragVerfasst am: 03.03.2008, 19:58    Titel: Antworten mit Zitat

The Lord of Programming hat Folgendes geschrieben:
DirectXer hat Folgendes geschrieben:
Aber der Fehler tritt nur auf, wenn du dem Wert etwas versuchst zuzuweisen oder? memcpy greift ja nur lesend darauf zu, das würde das dann erklären. Dann spricht das vielleicht wirklich für read-only.

Memcpy greift auf den zweiten Parameter lesend zu(const void *src) und auf den ersten schreibend(void *dest). Insofern verstehe ich nicht, was da anders sein soll.

ahja jetzt seh ichs, ich hab das falsch interpretiert mit memcpy. ich dachte du kopierst nur die werte von der stelle in ein array von dir, d.h. du greifst nur lesen auf den buffer zu; war aber nicht so.. Rolling Eyes Smile

The Lord of Programming hat Folgendes geschrieben:
Die Quelle ist halt einmal ein ganzes Array, das byteweise Kopiert wird und das andere Mal ein einzelner Wert. Aber da sehe ich nicht das Problem(die Quelle ist ja im Speicher schon reserviert)...eher am Ziel.

hmm das macht eigentlich keinen unterschied, es sei denn memcpy ist irgendwie anders implementiert(normalerweise wird memcpy mit __asm{movsb} implementiert...), aber du kannst das ganz einfach testen indem du dir mal ein eigenes memcpy schreibst wo du die werte ganz normal zuweist. Dann kannst du testen, was dabei geht und was nicht....

The Lord of Programming hat Folgendes geschrieben:
Erstelle ich einen Zeiger, der einfach ins nichts läuft, wie kann das gut gehen, wenn ich da schreibend darauf zugreife?
Ist es nicht auch schlechter Stil, Zeiger uninitialisiert zu lassen?

Ohja das ist ein seehhr schlechter stil, im buch schreibt christian einen ganzen abstatz voller warnungen um jeden neuen programmierer davon abzuschrecken Razz Also generell solltest du Zeiger _immer_ mit 0 oder einem anderen gültigen wert initialisieren; sonst kannst im allerschlimmsten fall zu hohem datenverlust führen. Am einfachsten ist, wenn du dir eine smart pointer klasse für normale pointer schreibst die im Konstruktor der pointer mit 0 initialisiert, aber das ist schon wieder etwas anderes. Smile

Gruß DXer
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden
The Lord of Programming
Living Legend


Alter: 37
Anmeldedatum: 14.03.2003
Beiträge: 3122

Medaillen: Keine

BeitragVerfasst am: 04.03.2008, 12:20    Titel: Antworten mit Zitat

Gut, jetzt kommen wir der Sache schon näher Smile


Wäre es also das beste und sauberste, wenn ich anstatt einem "Leerzeiger" einfach ein Array mit entsprechender Größe reserviere?

CPP:
short* index_data=new short [sizeof(index_data_array)/sizeof(index_data_array[0])];

memcpy(index_data,index_data_array,sizeof(index_data_array));

//Buffer fürs Schreiben locken
sIndexbuffer->Lock(0,0,(void**)&index_data,0);

//Daten kopieren
memcpy(index_data,index_data_array,sizeof(index_data_array));

//Unlocken

delete[] index_data;


Nun aber noch ne Frage: Muss ich dann den Speicherbereich solange reserviert lassen wie der Indexbuffer nutzbar sein soll oder hat LPDIRECT3DINDEXBUFFER9 nach dem Erstellen per CreateIndexBuffer() schon einen eigenen Speicherbereich? (Nach dem Namen wohl eher nicht...)
_________________
www.visualgamesentertainment.net
Current projects: RDTDC(1), JLI-Vor-Projekt, Tetris(-Tutorial), JLI-Format
(1) Realtime Developer Testing and Debugging Console


Anschlag, Anleitung zum Atombombenbau, Sprengkörper...
Hilf Schäuble! Damit er auch was findet...
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden Website dieses Benutzers besuchen
Jonathan_Klein
Living Legend


Alter: 37
Anmeldedatum: 17.02.2003
Beiträge: 3433
Wohnort: Siegerland
Medaillen: Keine

BeitragVerfasst am: 04.03.2008, 13:26    Titel: Antworten mit Zitat

Der Speicherbereich sollte sich dann ja auf der Grafikkarte befinden. Da du per C++/Windows normalerweise kein Speicher auf der Grafikkarte reservieren kannst, sollte man den Speicher sicher löschen können.
Den Vertex/Index buffer sind ja gerade deshalb so schnell, weil sich alle Daten schon auf der Garfikkarte befinden.
_________________
https://jonathank.de/games/
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden Website dieses Benutzers besuchen
DirectXer
Dark JLI'ler



Anmeldedatum: 05.02.2005
Beiträge: 1201
Wohnort: Köln
Medaillen: Keine

BeitragVerfasst am: 04.03.2008, 14:57    Titel: Antworten mit Zitat

Der code da würde ein größeres mem-leak verursachen, da Lock() eine Pointervariable erwartet und diese auf den index buffer setzt Arrow dein mit new allokiertes Array würde einfach fallen gelassen, und delete unten hat noch andere schlimmere folgen Razz

Also nochmal komplett in Schritten, wie das mit index buffern ist:
  • Du rufst CreateIndexBuffer auf und übergibst unter anderem die Größe der zukünftigen index-daten in byte; diese Funktion reserviert dann den Speicher in deinem indexbuffer-objekt (norm. auf der graka)
  • Du erstellst einen ganz normalen short* pointer (oder long, je nachdem was du bei Create...() übergeben hast; standard ist short) und initialisierst ihn mit null. Von Lock() wird dieser auf den von Create...() reservierten Speicher gesetzt
  • Du rufst Lock() auf und übergibst diesen Pointer, Lock setzt diesen nun wie gesagt auf den Speicher (die index-daten)
  • Du kopierst entweder mit memcpy die Indices über diesen Pointer in den Speicher oder setzt sie selber mit dem array-index-operator. Du musst hier nur darauf achten, dass du nicht höher greifst als du bei Create...() angegeben hast, da dir der Speicher dadrüber nicht mehr gehört
  • Du rufst Unlock() auf und sagst DX somit, dass du mit bearbeiten fertig bist.

Das ganze jetzt mal in Code:
CPP:
// index buffer für 4 short indices reservieren und in <ib> speichern
device->CreateIndexBuffer( 4 * sizeof(short), 0, D3DFMT_INDEX16, D3DPOOL_DEFAULT, &ib, 0 );

// pointer anlegen
short* pInds = 0;

// pointer holen
ib->Lock( 0, 0, reinterpret_cast<void**>(&pInds), 0 );

// daten schreiben (nur von [0] bis [3]!)
pInds[0] = 0;
...
pInds[3] = 2;

// DX sagen, dass wir fertig sind
ib->Unlock();


Hoffe, dass jetzt alles klar iss Very Happy (mal eine ganz vage vermutung weshalb das ganze: kann es sein dass du bei create() einfach das sizeof(short) weggelassen hast? das passiert nämlich öfter mal Razz )


Gruß DXer
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden
Beiträge der letzten Zeit anzeigen:   
Neues Thema eröffnen   Neue Antwort erstellen    JLI Spieleprogrammierung Foren-Übersicht -> DirectX, OpenGL Alle Zeiten sind GMT
Gehe zu Seite 1, 2  Weiter
Seite 1 von 2

 
Gehe zu:  
Du kannst keine Beiträge in dieses Forum schreiben.
Du kannst auf Beiträge in diesem Forum nicht antworten.
Du kannst deine Beiträge in diesem Forum nicht bearbeiten.
Du kannst deine Beiträge in diesem Forum nicht löschen.
Du kannst an Umfragen in diesem Forum nicht mitmachen.


Powered by phpBB © 2001, 2005 phpBB Group
Deutsche Übersetzung von phpBB.de

Impressum