Anfänger: Pointer auf SDL_Surface-Pointer,funktioniert nicht. Warum?



  • Macht leider keinen unterschied. Trotzdem danke für die Hilfe.



  • Storm.Xapek.de schrieb:

    Macht leider keinen unterschied. Trotzdem danke für die Hilfe.

    Hmm. Wie BigBoomer bereits sagte: Überprüfe mal den Rückgabewert der Funktion SDL_SetVideoMode() (falls du es noch nicht gemachtr hast)

    (sicher, dass du das Problem rivchtig eingegrenzt hast udn dass das problem nicht irgendwo anders liegt?)

    EDIT:

    surface = SDL_SetVideoMode( 800, 600, 16, SDL_SWSURFACE );
      if ( surface == NULL )
      {
        fprintf(stderr, "error: SDL_SetVideoMode()\n %s",
          SDL_GetError());
        exit(1);
      }
    


  • Direkt nach dem aufruf hatte cih es schon überprüft gibt keinen fehler.
    Nachdem man aber aus der funktion draußen ist und dann nochmal surface auf NULL überprüft wirft er die Warnung aus!

    Das heißt das surface wird irgendwie wieder gelöscht.
    Ich probier mal den Zeiger auf das Surface wieder zurückzugeben und neu zu specihern.

    Aber genau das sollen doch zeiger eigentlich verhindern!

    //EDIT:
    So gehts!
    surface = init(surface,800,600);

    Das ist aber eigentlich genau das was ich nciht wollte, warum verwende ich den pointer wenn der garnichts bringt. Ich glaub ich bin zu dumm um das richtig zu machen!



  • Storm.Xapek.de schrieb:

    Direkt nach dem aufruf hatte cih es schon überprüft gibt keinen fehler.
    Nachdem man aber aus der funktion draußen ist und dann nochmal surface auf NULL überprüft wirft er die Warnung aus!

    Das heißt das surface wird irgendwie wieder gelöscht.
    Ich probier mal den Zeiger auf das Surface wieder zurückzugeben und neu zu specihern.

    Aber genau das sollen doch zeiger eigentlich verhindern!

    //EDIT:
    So gehts!
    surface = init(surface,800,600);

    Das ist aber eigentlich genau das was ich nciht wollte, warum verwende ich den pointer wenn der garnichts bringt. Ich glaub ich bin zu dumm um das richtig zu machen!

    Irgendwie sehe ich den fehler auch nicht.
    (Muss jetzt wohl raten 😃 )

    Vieleicht stört ja das "static" vor "SDL_Surface* surface". (Was ich nciht glaube..aber versuchs mal OHNE static)



  • Jetzt funktioniert der Pointer, allerdings bleib das Programm jetzt wieder hier hängen;

    SDL_FreeSurface(surface);

    Ich hab das gefühl wir drehn uns im Kreis.



  • Storm.Xapek.de schrieb:

    Jetzt funktioniert der Pointer, allerdings bleib das Programm jetzt wieder hier hängen;

    SDL_FreeSurface(surface);

    Ich hab das gefühl wir drehn uns im Kreis.

    Jetzt mal langsam!
    Hab deinen code (etwas abgeändert) bei mir (hab grad rebootet und bin endlich in linux :D) getestet. bei mir funktioniert es wunderbar.

    #include <SDL/SDL.h>
    #include <stdlib.h>
    
    int init (SDL_Surface* surface , int width , int height)
    {
            if (SDL_Init(SDL_INIT_VIDEO) < 0)
            {
                    fprintf(stderr , "error: SDL_Init()\n%s" , SDL_GetError());
                    exit(-1);
            }
    
            surface = SDL_SetVideoMode(width , height , 16 , SDL_DOUBLEBUF | SDL_HWSURFACE);
            if (surface == 0)
            {
                    fprintf(stderr , "error: SDL_VideoMode()\n%s" , SDL_GetError());
                    exit(-1);
            }
    
            atexit(SDL_Quit);
    
            return 0;
    }
    
    int main ()
    {
            static SDL_Surface* surface;
            init(surface , 800 , 600);
    
            for (int frames = 0; frames < 20; ++frames)
            {
                    SDL_Delay(20);
                    printf("%d\n" , frames);
            }
    
            SDL_FreeSurface(surface);
            return 0;
    }
    

    Kopiere mal DIESEN code (kopieren, nicht abtippen ➡ copy&paste), kompilier des und teste es mal. Das geht bei mir zumindest.

    Was "SDL_FreeSurface(surface);" angeht:
    Teste mal vor dem Aufruf von SDL_FreeSurface() ob surface NULL ist.
    So:

    if (surface)
    {
        SDL_FreeSurface(surface);
    }
    

    (Ich shcätze mal, du hast nicht den gesamten code gepostet...dein code hat bestimmt den pointer surface auf NULL gesetzt (wenn SDL_SetVideoMode() davor erfolgreichwahr, versteht sich))

    EDIT: Hast du vllt irgendwo "surface = NULL" statt "surface == NULL" geschrieben?



  • So funktioniert mein ursprünglicher code auch, aber sobald etwas mit dem surface passiert geht er nciht emhr.
    Mach bei dir mal SDL_Flip(surface); in die Schleife.
    Bekommst du dann auch einen Error?

    EDIT: Hast du vllt irgendwo "surface = NULL" statt "surface == NULL" geschrieben?

    Nein, mein code ist so wie ich ihn gepostet hab, den ganzen rest hab ich erstmal rauskommentiert.



  • Storm.Xapek.de schrieb:

    So funktioniert mein ursprünglicher code auch, aber sobald etwas mit dem surface passiert geht er nciht emhr.
    Mach bei dir mal SDL_Flip(surface); in die Schleife.
    Bekommst du dann auch einen Error?

    EDIT: Hast du vllt irgendwo "surface = NULL" statt "surface == NULL" geschrieben?

    Nein, mein code ist so wie ich ihn gepostet hab, den ganzen rest hab ich erstmal rauskommentiert.

    Erstmal sag ich: roooofl 😃 😃 😃

    Ich stand selber derb auf dem Schlauch 🙂

    Also. Bei mir kam auch der Fehler. Dann ist mir aber aufgefallen, dass man das displaysurface (das surface, dass von SDL_SetVideoMode() zurückgegeben wird)
    NICHT freigeben soll/darf.

    also: KEIN SDL_FreeSurface() aufrufen beim deinem Displaysurface.

    #include <SDL/SDL.h>
    #include <stdlib.h>
    
    int init (SDL_Surface* surface , int width , int height)
    {
            if (SDL_Init(SDL_INIT_VIDEO) < 0)
            {
                    fprintf(stderr , "error: SDL_Init()\n%s" , SDL_GetError());
                    exit(-1);
            }
    
            surface = SDL_SetVideoMode(width , height , 16 , SDL_DOUBLEBUF | SDL_HWSURFACE);
            if (surface == 0)
            {
                    fprintf(stderr , "error: SDL_VideoMode()\n%s" , SDL_GetError());
                    exit(-1);
            }
    
            atexit(SDL_Quit);
    
            return 0;
    }
    
    int main ()
    {
            SDL_Surface* surface;
            init(surface , 800 , 600);
    
            if (surface == 0)
            {
                    printf("surface == 0\n");
                    exit(-1);
            }
    
            for (int frames = 0; frames < 20; frames++)
            {
                    SDL_Flip(surface);
                    SDL_Delay(20);
                    printf("%d\n" , frames);
            }
    
            return 0;
    }
    

    Dieser code funzt jetzt!



  • Ohh,
    naja das ist der Grund warum ich ein Buch brauch das mir sowas beibringt,
    denn code hab ich nämlich einfach nur so zusammengebastelt.

    Jetzt bleibt noch das Problem das auf dem surface nichts ausgegeben wird, wenn ich die methode
    test.draw();
    aufrufe.

    Die mehtde hab ich vorher mal gepostet, sie arbeitet mit einem zweiten pointer der ebenfalls auf dasselbe surface zeigt
    user_info.surface = surface;
    so wirds übergeben.

    Hier muss also auch noch ein Fehler liegen.

    Ich danke dir jedenfalls mal für deine bisherige Hilfe, ohne dich hät ich das bestimmt nie rausgefunden. 🙂



  • Storm.Xapek.de schrieb:

    Hallo,
    ich bin noch ziemelich neu in SDL und habe nun folgendes Problem:

    Ich ahbe einen Pointer auf einen Pointer auf ein SDL_Surface

    SDL_Surface *surface;
    ...
       user_info.surface = &surface;
    ...
       class figure back(user_info);
    

    Ich habe also ein surface das ich in der struktur user_info an den konstruktor meiner klasse gebe. user_info.surface ist folgendermassen in der struktur definiert: SDL_Surface **surface;
    Wenn nun aber meine Klasse auf dieses Surface zeichnet:

    int figure::draw() {
    
       //Show image on surface
       if(SDL_BlitSurface(image,&info.current,*info.surface,&info.next) != 0)
          error = true;
       return 0;
    
    }
    

    Gibt es zwar nirgendwo einen Fehler, aber der Bildschrim bleibt schwarz. Und das bild erscheint nciht.

    Frage:
    Funktioniert eine solche Technik mit einem Pointer auf Des SDL_Surface Pointer überhaupt? (Der Compiler macht keien Probleme,aber vielleicht schreib ich auf ein falsches Surface)

    Hier noch meine main-schleife:

    for(int frames = 0; frames < 20; ++frames) {
    
          back.draw();
          SDL_Flip(surface);
          SDL_Delay(20);
    
       }
    

    Ich hoffe ich ahb mich einigermassen Verständlich ausgedrückt, wenn nciht fragt bitte nach.

    1 : Übergibst du immernoch Zeiger auf Zeiger? Wenn ja, dan übergeb es lieber nur als Zeiger. (Ich meine: Wenn dir das dereferenzieren Spaß macht, kannst du es auch als Zeiger auf Zeiger auf Zeiger speichern, was aber eher sinnlos ist)

    2 : Warum dein Bildschirm schwarz bleibt, kann ich dir jetzt nicht sagen.
    Poste mal etwas mehr code.

    3 : Wie sind denn die Rests info.current und info.next belegt? Teste mal wie die werte belegt sind. Und Teste noch ob Quell- und Zielsurface ungleich null sind. Mehr kann ich dir grad auch net sagen. Sonst müsste ich mir deinen code aus den Fingern ziehen.

    4 : SDL Buch? Ich glaube nicht, dass man für SDL ein Buch braucht.(Gibts ja auch net so viel...google reicht denke ich mal)



  • Nach der überprüfung weis ich nun das es an folgender zeile liegt
    SDL_BlitSurface(image,&info.current,info.surface,&info.next);
    Die funktion schlägt fehl. Ich weis aber nicht warum.
    Beide surfaces scheinen gültig zu sein, und die SDL_Rect's sind auch ok.
    Ich versuch mal noch genauer zu überprüfen ob auch wirklich beide surfaceses gültig sind gibts da ne funktion?

    //EDIT:
    Surfaces must not be locked during blit
    gibt SDL_Error aus. ich glaub ich weis wie das geht.
    Wusste aber nciht das das hier nötig ist!
    Warum ist es überhaupt gelockt? (ich mach das nicht!)



  • Storm.Xapek.de schrieb:

    Nach der überprüfung weis ich nun das es an folgender zeile liegt
    SDL_BlitSurface(image,&info.current,info.surface,&info.next);
    Die funktion schlägt fehl. Ich weis aber nicht warum.
    Beide surfaces scheinen gültig zu sein, und die SDL_Rect's sind auch ok.
    Ich versuch mal noch genauer zu überprüfen ob auch wirklich beide surfaceses gültig sind gibts da ne funktion?

    //EDIT:
    Surfaces must not be locked during blit
    gibt SDL_Error aus. ich glaub ich weis wie das geht.
    Wusste aber nciht das das hier nötig ist!
    Warum ist es überhaupt gelockt? (ich mach das nicht!)

    Also funktioniert es jetzt? JA/NEIN?

    Wenn nein:
    Gib mal Werte der Quell- und Zielrects.
    (info.current und info.next)



  • Nein ich bekomms nicht hin
    die WErte sind bei beiden gleich! info.current.x = 0 info.current.y = 0
    info.current.w = image->w info.current.h = image->h
    so hab ich das definiert.
    Aber so wie ich das jetzt sehe liegts am surface (dem Hauptfenster also auf das ich zeichnen will) das ist irgendwie gesperrt:
    Surfaces must not be locked during blit

    Aber warum? Die Variable surface ist in der main definiert, vielleicht wird sie irgendwie automatisch gesperrt wenn ich die main verlasse.
    Also ich kapiers garnicht.

    Vielelicht ist das auch ein folgefehler aus einem anderen fehler 😕

    Hast du ne ahnung von was sowas kommen kann?



  • Storm.Xapek.de schrieb:

    Nein ich bekomms nicht hin
    die WErte sind bei beiden gleich! info.current.x = 0 info.current.y = 0
    info.current.w = image->w info.current.h = image->h
    so hab ich das definiert.
    Aber so wie ich das jetzt sehe liegts am surface (dem Hauptfenster also auf das ich zeichnen will) das ist irgendwie gesperrt:
    Surfaces must not be locked during blit

    Aber warum? Die Variable surface ist in der main definiert, vielleicht wird sie irgendwie automatisch gesperrt wenn ich die main verlasse.
    Also ich kapiers garnicht.

    Vielelicht ist das auch ein folgefehler aus einem anderen fehler 😕

    Hast du ne ahnung von was sowas kommen kann?

    Du hattest anfangs recht. Es liegt am übergeben per Zeiger (Warum weiß ich grad auch nicht...bin auch recht verwundert.Vllt beim poppen vom Stack 😕 . bei mir kam der gleiche Fehler).

    Wie du bereits gesagt hast, funktioniert es, wenn man den Zeiger zurückgibt.
    Dann gib halt einfach den Zeiger auf dein Bildschirmsurface zurück.

    #include <SDL/SDL.h>
    #include <SDL/SDL_image.h>
    #include <stdlib.h>
    
    SDL_Surface* init (int width , int height)
    {
    	if (SDL_Init(SDL_INIT_VIDEO) < 0)
    	{
    		fprintf(stderr , "error: SDL_Init()\n%s" , SDL_GetError());
    		exit(-1);
    	}
    
    	SDL_Surface* surface = SDL_SetVideoMode(width , height , 16 , SDL_DOUBLEBUF | SDL_HWSURFACE);
    	if (surface == 0)
    	{
    		fprintf(stderr , "error: SDL_VideoMode()\n%s" , SDL_GetError());
    		exit(-1);
    	}
    
    	atexit(SDL_Quit);
    
    	return surface;
    }
    
    int main (void)
    {
    	SDL_Surface* surface;
    	surface = init(800 , 600);
    
    	if (surface == 0)
    	{
    		printf("surface == 0\n");
    		exit(-1);
    	}
    
    	SDL_Surface*	img	= IMG_Load("aaa.png");
    	if (img == 0)
    	{
    		fprintf(stderr , "IMG_Load\n");
    		exit(-1);
    	}
    
    	SDL_Rect	srect , drect; /* srect == Quelle (sourcerect) , drect == Ziel (destination rect)*/
    
    	srect.x		= 0;
    	srect.y		= 0;
    	srect.w		= img->w;
    	srect.h		= img->h;
    
    	drect.x		= 20;
    	drect.y		= 20;
    	drect.w		= img->w;
    	drect.h		= img->h;
    
    	for (int frames = 0; frames < 20; ++frames)
    	{
    		SDL_BlitSurface(img , &srect , surface , &drect);
    		SDL_Flip(surface);
    		SDL_Delay(20);
    		printf("%d \n" , frames);
    	}
    
    	SDL_Delay(3000);
    	SDL_FreeSurface(img);
    	exit(0);
    	return 0;
    }
    

    Dann brauchst du aber den Zeiger auf das surface nicht der init() funktion zu übergeben.

    also:

    SDL_Surface* init (int width , int height);
    

    Was besseres fällt mir im Moment auch nicht ein.

    EDIT:
    Der code funkt jetzt wenigstens. ALso das Bild wird gezeichnet.



  • Das heißt aber acuh das ich das so wie ich es jetzt habe nicht machen kann,
    also das mit der methode draw(). Das finde ich allerdings am einfachsten.
    Ich hab leider heut kaum noch zeit, aber sobald ich kann versuche ich
    es mal mit ner referenz. Vielleicht klappts ja so.

    ansonsten muss ich mein klassendesign nochmal neu überdenken



  • Storm.Xapek.de schrieb:

    Das heißt aber acuh das ich das so wie ich es jetzt habe nicht machen kann,
    also das mit der methode draw().
    Das finde ich allerdings am einfachsten.
    Ich hab leider heut kaum noch zeit, aber sobald ich kann versuche ich
    es mal mit ner referenz. Vielleicht klappts ja so.

    ansonsten muss ich mein klassendesign nochmal neu überdenken

    Ähm was? 😕 Warum soll was nicht mit deiner draw funktion funktionieren?
    Änder einfach mal die int funktion ab. (zB wie in dem code, den ich gepostet hab)
    Probiers dann mal aus. Vllt gehts. Ich kann dir nix genaueres sagen, da ich dein code net kenne.



  • Ok,
    hast recht es läuft jetzt halbwegs, ich denke mit dem rest werd ich alleine fertig.
    Sonst post ich wieder.

    Danke für deine hilfe



  • int init (SDL_Surface* surface , int width , int height)
    {
            if (SDL_Init(SDL_INIT_VIDEO) < 0)
            {
                    fprintf(stderr , "error: SDL_Init()\n%s" , SDL_GetError());
                    exit(-1);
            }
    
            surface = SDL_SetVideoMode(width , height , 16 , SDL_DOUBLEBUF | SDL_HWSURFACE);
            if (surface == 0)
            {
                    fprintf(stderr , "error: SDL_VideoMode()\n%s" , SDL_GetError());
                    exit(-1);
            }
    
            atexit(SDL_Quit);
    
            return 0;
    }
    

    falsch richtig währe

    int init (SDL_Surface** surface , int width , int height)
    {
            if (SDL_Init(SDL_INIT_VIDEO) < 0)
            {
                    fprintf(stderr , "error: SDL_Init()\n%s" , SDL_GetError());
                    exit(-1); // oder return false;
            }
    
            *surface = SDL_SetVideoMode(width , height , 16 , SDL_DOUBLEBUF | SDL_HWSURFACE);
            if (*surface == 0)
            {
                    fprintf(stderr , "error: SDL_VideoMode()\n%s" , SDL_GetError());
                    exit(-1); // oder return false;
            }
    
            atexit(SDL_Quit);
    
            return true;
    }
    

    aber wie du es jetzt hast ist es besser


Anmelden zum Antworten