Du bist nicht angemeldet.

Stilllegung des Forums
Das Forum wurde am 05.06.2023 nach über 20 Jahren stillgelegt (weitere Informationen und ein kleiner Rückblick).
Registrierungen, Anmeldungen und Postings sind nicht mehr möglich. Öffentliche Inhalte sind weiterhin zugänglich.
Das Team von spieleprogrammierer.de bedankt sich bei der Community für die vielen schönen Jahre.
Wenn du eine deutschsprachige Spieleentwickler-Community suchst, schau doch mal im Discord und auf ZFX vorbei!

Werbeanzeige

11

09.12.2010, 15:05

Hallo Chaia*,

wie dir die Fehlermeldung des Compilers schon versucht hat zu verraten: In der SFML gibt es Klassen die von einer Klasse Namens sf::NonCopyable abgeleitet sind und wie dieser Name vermuten lässt kannst du Objekte einer solchen Klasse nicht kopieren. Wenn du jetzt allerdings das RenderWindow von einer Funktion zurückgeben lassen möchtest, dann wird intern nämlich genau das versucht: eine Kopie des Objekts anzulegen.

Du könntest entweder eine Referenz auf das Objekt zurückgeben und damit arbeiten oder alternativ das Objekt auf dem Heap (statt wie bei dir auf dem Stack) anlegen.


Gruß
SaRu_

12

09.12.2010, 15:41

Gut, danke lässt sich jetzt kompilieren. Das mit dem noncopyable hatte ich mir schon gedacht, aber ich bin nicht drauf gekommen es als Referenz zu übergeben :pinch:

Allerdings habe ich das nächste Problem^^

Und zwar:
Unbehandelte Ausnahme bei 0x5e3b65af in SFML App.exe: 0xC0000005: Zugriffsverletzung beim Lesen an Position 0x622e6574.
Das "in SFML App.exe", bedeutet das, dass ich in meiner eigenen App lesen will?

Es passiert, wenn ich versuche ein Image zu laden.
Das mache ich wie folgt:

Game.cpp

C-/C++-Quelltext

1
2
m_BlackCube = new Image;
m_BlackCube->Load ("Data/Sprites/BlackCube.bmp"); 


und hier die Klasse, die dann letztendlich das Bild lädt:

Image.hpp

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
class Image
{
public: 
    Image () {m_Image = new sf::Image;}
    void Load (std::string FileName); // Lädt ein Image
    sf::Image GetImage () {return *m_Image;} // Zum zurückgeben eines Images, damit es für ein Sprite verwendet werden kann
    void SetColorKey (sf::Color Color, int Strength = 0); // Zum setzen der Transparenten Farbe


private: 

    sf::Image *m_Image; // das Image 

}; 


Und Image.cpp

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
void Image::Load (std::string FileName)
{
    if (!m_Image->LoadFromFile(FileName))  //<<<<- Hier tritt der Fehler auf 
    {
        std::cout << "Fail beim Laden des Bildes: " << FileName << std::endl; 
        std::cin.get (); 
    }

} 



Zuerst hatte ich das Image ganz normal angelegt, also nicht auf dem Heap und ohne den Konstruktor. Das funktioniert aber genauso wenig.
Kann jemand erkennen, was ich falsch mache?

lg chaia

EDIT:

Irgendwie scheint das ganze bei mir überhaupt nicht zu funktionieren.
Ich habe einfach mal folgendes direkt an den Anfang der main() gesetzt, um zu testen, ob das überhaupt geht.

C-/C++-Quelltext

1
2
sf::Image Image;
    Image.LoadFromFile("sprite.tga");


Es erscheint folgende Meldung:

Durch einen Pufferüberlauf in SFML App.exe wurde der interne Programmzustand beschädigt. Klicken Sie auf "Unterbrechen", um das Programm zu debuggen, oder auf "Weiter", um es zu beenden.
Weitere Informationen finden Sie im Hilfethema "Gewusst wie: Debugging von Pufferüberlaufproblemen".

Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von »Chaia*« (09.12.2010, 17:23)


13

09.12.2010, 17:21

Hey,

also vielleicht setzt du einfach mal Haltepunkte und wenn das Programm an den entsprechenden Stellen angehalten wird, dann kannst du mit der Maus im Quellcode über die Variablen fahren und dir deren Inhalt anschauen. Prüf mal ob bzw. ab wann der Zeiger ungültig ist. Das wäre eine mögliche Fehlerquelle. Aber in diesem Fall sollte es auch ausreichen das Image auf dem Stack anzulegen (ohne new) das sollte man auch immer machen wenn es sich anbietet. Beschreib doch mal genauer was dabei nicht funktioniert?!

Ach ja und deine Funktion GetImage() gibt wieder eine Kopie zurück und keine Referenz. ;)

Gruß
SaRu_

14

09.12.2010, 17:48

Also wenn ich m_Image auf dem Stack anlege, passiert genau das selbe.
Ehrlich gesagt, habe ich keine Ahnung, wie es jetzt zu diesem Fehler kommt, es ist doch beinahe exakt der selbe Code wie im Tutorial!
Siehe hier:
http://sfml-dev.org/tutorials/1.6/graphics-sprite.php

Nur dass es bei mir in einer Funktion verpackt ist.
Wenn ich den Code aus dem Tutorial einfach ausführe (in der main ()) gibt es den selben Fehler. (Siehe EDIT im letzten Post).

Wenn ich das Image als Referenz (also return &m_Image) zurückgebe, wie muss dann das hier aussehen?:

C-/C++-Quelltext

1
m_pBlackCubeSprite->SetImage (m_BlackCube->GetImage ())


Wenn ich es so wie hier verwende kann es nicht von "'sf::Image *' in 'const sf::Image &'" konvertiert werden.

lg chaia

15

09.12.2010, 19:26

"Referenz (also return &m_Image)" auf die Art und weise gibst du einen Zeiger zurück, keine Referenz.
Entsprechender Funktionsaufruf müsste wie folgt abgewandelt werden:
"m_pBlackCubeSprite->SetImage (*m_BlackCube->GetImage ())"

16

09.12.2010, 20:55

Ups, und wie gebe ich dann eine Referenz zurück?
Wenn ich eine Referenz so wie hier erzeuge und dann zurückgebe, habe ich wieder den Fehler mit dem "noncopyable":

C-/C++-Quelltext

1
2
sf::RenderWindow &App2 = App; 
return App2;



Ich habe jetzt übrigens die SFML einfach nochmal neu kompiliert und der Fehler mit dem Lesezugriff tritt nun nicht mehr auf.
Allerdings habe ich (schon wieder^^) ein Problem:

Es hängt damit zusammen, dass ich nicht weiß, wie ich das mit der Referenzübergabe machen soll.
Denn das was ich vorhin hatte (also return &app) lässt sich zwar kompilieren, aber nicht richtig anwenden. (weil es ein zeiger ist, wie du sagst)
Wenn es aufgerufen wird, erscheint die Meldung: "Failed to get device context of window -- cannot create OpenGL context"
Was ja wohl damit zu tun hat, dass nicht das richtige Fenster zum rendern etc. da ist.

Also, wie habt ihr das Window zurückgegeben?
Wenn möglich bitte mit kleinem Codebeispiel (tue mich noch etwas schwer im reindenken mit zeigern, referenzen, adressen etc.)

lg chaia

Stazer

Alter Hase

Beiträge: 468

Wohnort: Berlin

Beruf: Student

  • Private Nachricht senden

17

09.12.2010, 21:02

Referenzen gibst du zurück in dem du den Rückgabewert der Funktion veränderst.

C-/C++-Quelltext

1
2
3
4
sf::RenderWindow & GetWindow ( ) const
{
    return this->Window ;
}


MfG Stazer

18

09.12.2010, 21:54

Alles klar, danke an alle die mir geholfen haben :)
Es funktioniert jetzt alles soweit.
Die Performance ist um welten besser als die der SDL. (ca. 700 FPS)
Wenn wieder was ist melde ich mich.

lg chaia*

NachoMan

Community-Fossil

Beiträge: 3 885

Wohnort: Berlin

Beruf: (Nachhilfe)Lehrer (Mathematik, C++, Java, C#)

  • Private Nachricht senden

19

10.12.2010, 10:12

in deiner imageklasse vergisst du den speicher fürs image wieder frei zu geben.
ich versteh allerdings nicht wofür du die brauchst. willst du dein spiel später eventuell mit anderen APIs oder Libs nutzen? wenn nicht ist die imageklasse in meinen augen überflüssig. als anfänger kannst oder solltest du direkt sf::Image benutzen.
"Der erste Trunk aus dem Becher der Erkenntnis macht einem zum Atheist, doch auf dem Grund des Bechers wartet Gott." - Werner Heisenberg
Biete Privatunterricht in Berlin und Online.
Kommt jemand mit Nach oMan?

20

10.12.2010, 11:32

ja, habe eben die Imageklasse entfernt und direkt mit in die Sprite Klasse gepackt.
Dort kann man jetzt einmal in ein Image laden und es wird für die SpriteInstanz verwendet.
Hatte gestern übrigens nur im Debug-Modus getestet. Im Release habe ich 2000FPS bzw. Frametimes von 0,00045 - 0,0005 ms

Werbeanzeige