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

Incrementis

Frischling

  • »Incrementis« ist der Autor dieses Themas

Beiträge: 4

Beruf: Student

  • Private Nachricht senden

1

14.03.2014, 17:12

SDL_SetAlpha Transparenz-Code bitte anschauen! Benötige hilfe dabei...

Hallo liebe Comunity,
ich bin neu hier, aber kenne das Forum schon länger. Aufmerksam auf diese Seite bin ich durch das Buch von Herrn Kalista geworden. Das ist schon mitlerweile fast drei Jahre her. Bis jetzt habe ich es geschafft alle Probleme die SDL betreffen alleine zu lösen, aber nun bleibt mir nichts anderes übrig als mich doch dieser Community zu wenden.Ich hoffe Ihr könnt mir bei dieser Sache helfen.

Die Aufgabe des Programms:

Das Programm soll mithilfe von SDL_SetAlpha in einer Schleife zwei Bilder Transparent machen und ihre Transparenzstärke soll sich während der Laufzeit ständig ändern.

Der Sinn:
Das Programm soll in der Lage sein die Buttons (Speichern,Laden, usw.) langsam Transparent zu machen, wenn die Mausbewegung nicht mehr aktiv ist. Da jedes einzelne Button in meinem Menü ein eigenes Bild ist, hab ich einen abgespeckten Testcode geschrieben, der aber nicht wünschenswert arbeitet.

Für eine ernstgemeinte Hilfe sage ich schon mal vielen Dank!


C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
//Es soll davon ausgegangen werden das die Includedateien korrekt sind, da das Programm sonst überhaupt nicht funktionieren würde

SDL_Surface *screen         = NULL; //Für das Fenster
    SDL_Surface *imageMenu      = NULL; //Für das Hintergrundbild
    SDL_Surface *imageButton    = NULL; //für das Buttonbild

    SDL_Event event;//Für das rechts-oben X-Button zum Schliessen
    Uint8 alpha     = 128;  //Für die Transparenzstärke vom Hintergrundbild
    Uint8 beta      = 128;  //Für die Transparenzstärke vom Buttonbild
    bool run        = true; //Laufzeitvariable
    
    SDL_Init(SDL_INIT_EVERYTHING);//Gesamte SDL initialisieren
    screen = SDL_SetVideoMode(1000,800,32,SDL_SWSURFACE);//Die Fenstereigenschaften festlegen
    
    //Die Bilder Laden
    imageMenu   = IMG_Load("Grafik\\MENU.png");
    imageButton = IMG_Load("Grafik\\RESUME-BUTTON.png");

    //position der Bilder bestimmen
    SDL_Rect ImagePosition;
    ImagePosition.x = 0;
    ImagePosition.y = 0;

    //die Bilder Transparent machen
    SDL_SetAlpha(imageMenu,SDL_SRCALPHA,alpha);
    SDL_SetAlpha(imageButton,SDL_SRCALPHA,beta);

    //Die Bilder auf das Fenster übertragen
    SDL_BlitSurface(imageMenu,NULL,screen,&ImagePosition);
    SDL_BlitSurface(imageButton,NULL,screen,&ImagePosition);
    
    while (run)
    {
        //Falls  button X rechts oben am Fenster gedrückt, dann schliesse das gesamte Programm
        while (SDL_PollEvent(&event))
        {
            switch(event.type)
            {
                case SDL_QUIT:
                    run = false;
                    break;
            }
            
        }
        
        /*Wenn ich diesen komplett auskommentierten Teil aktiviere, dann sind beide bilder so als wären die
        Transparenz auf dem Wert 255. Wenn ich es so auskommentiert lasse dann is komischerweise nur das
        Hintergrundbild auf den von alpha gesetzten Wert transparent.....
        //die Bilder Transparent machen
        SDL_SetAlpha(imageMenu,SDL_SRCALPHA,alpha);
        SDL_SetAlpha(imageButton,SDL_SRCALPHA,beta);

        //Die Bilder auf das Fenster übertragen
        SDL_BlitSurface(imageMenu,NULL,screen,&ImagePosition);
        SDL_BlitSurface(imageButton,NULL,screen,&ImagePosition);

        //Der Overflow ist zu Testzecken beabsichtigt!
        beta++;
        alpah+=50;
        */

        //ohne das sieht man nichts auf dem Bildschirm  
        SDL_Flip(screen);
        

    }

    //Alle surfaces freigeben und SDL beenden, umm Memoryleak zu vermeiden
    SDL_FreeSurface(screen);
    SDL_FreeSurface(imageMenu);
    SDL_FreeSurface(imageButton);
    SDL_Quit();[cpp]
[/cpp]



EDIT: Sorry! Vergaß zu erwähnen das, dass SDL version 1.2 ist...

Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von »Incrementis« (15.03.2014, 19:48)


Incrementis

Frischling

  • »Incrementis« ist der Autor dieses Themas

Beiträge: 4

Beruf: Student

  • Private Nachricht senden

2

15.03.2014, 17:23

kleiner Fortschritt

Wenn in dem code die Zeilen

C-/C++-Quelltext

1
2
3
//Die Bilder auf das Fenster übertragen
SDL_BlitSurface(imageMenu,NULL,screen,&ImagePosition);
SDL_BlitSurface(imageButton,NULL,screen,&ImagePosition);


vertauscht werden und in der Schleife der auskommentierte Teil auskommentiert gelassen wird, dann nehmen beide Bilder die Transparenzstärke abhängig von den Variablen alpha und beta an.

Incrementis

Frischling

  • »Incrementis« ist der Autor dieses Themas

Beiträge: 4

Beruf: Student

  • Private Nachricht senden

3

15.03.2014, 17:55

Nicht ganz...

Nun wurden auskommentierte Teil in der Schleife wieder aktiviert und die Zeilen

C-/C++-Quelltext

1
2
3
//Die Bilder auf das Fenster übertragen
SDL_BlitSurface(imageMenu,NULL,screen,&ImagePosition);
SDL_BlitSurface(imageButton,NULL,screen,&ImagePosition);


in der Schleife ebenfalls vertauscht. Folgendes ist passiert:
Der Button fängt wie gewünscht an zu blinken (und jedes zusätzlich eingefügte Bild kann ebenfalls zum Blinken gebracht werden), jedoch hat das Hintergrundbild seine volle Transparenzstärke, obwohl diese um +50 pro Durchgang verändert werden soll. Theoretisch könnte ich jetzt aufhören und sagen ich habe erreicht was ich wollte, aber es wurmt mich schon warum das Hintergrundbild nicht auch blinkt! Falls einer eine Antwort weis wäre ich froh darum!

Lares

1x Contest-Sieger

  • Private Nachricht senden

4

15.03.2014, 20:06

Ich nehme mal an, dass du das Folgende in deinem eigentlichen Projekt beachtet hast, auch wenn der gepostete Code dies nicht zeigt. Allerdings habe ich sonst keine wirkliche Idee woran Problem liegen könnte:
In deinem SDL-Projekt sollte die Inkrementierung der Variablen abhängig von der Zeit gemacht werden. Wenn du nämlich jeden Frame alpha um 50 erhöhst, hast du innerhalb einer Sekunde volle Opazität. Das kann die Zeit sein, die es braucht um das Fenster überhaupt auf dem Bildschirm anzuzeigen, wesewegen du den Übergang nicht siehst.
Selbst wenn du Zeitfaktoren verwendest, würde ich mal schauen, wie die jeweiligen Werte beim Applikationsstart aussehen. Vllt ist dein Zeitfaktor im ersten Frame aus irgendeinen Grund viel zu hoch, weswegen Alpha direkt den Maximalwert erhält.

Incrementis

Frischling

  • »Incrementis« ist der Autor dieses Themas

Beiträge: 4

Beruf: Student

  • Private Nachricht senden

5

16.03.2014, 13:04

Ein Versuch wars Wert :)

Vielen Dank erstmal für den Vorschlag! Ich hab die Geschwindikeit mit SDL_GetTicks() reduziert und das Endergebnis bleibt leider gleich.
Ich hab das Ganze gedebugged und das SDL-Fenster in seinem Verhalten in Form von Screenshots hier hochgeladen. Auf den Bildern ist die Problematik genauer beschrieben.
Theoretisch kann ich damit arbeiten, aber das ist auch nicht das gelbe vom Ei.


Zusätzlich ein etwas sauberer Code:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
#include <SDL.h>
#include <SDL_image.h>


int main(int argc, char* args[])
{
    
    SDL_Surface *screen = NULL; //Für das Fenster
    SDL_Surface *imageMenu  = NULL; //Für das Hintergrundbild
    SDL_Surface *imageButton    = NULL; //Für das Load-Buttonbild
    SDL_Surface *imageButton2   = NULL; //Für das Save-Buttonbild

    SDL_Event event;//Für das rechts-oben X-Button zum Schliessen
    Uint8 alpha     = 255;  //Für die Transparenzstärke vom Hintergrundbild
    Uint8 beta      = 10;   //Für die Transparenzstärke vom Buttonbild
    Uint32 start    = 0;    //Für die frames per second
    bool run        = true; //Laufzeitvariable
    
    SDL_Init(SDL_INIT_EVERYTHING);//Gesamte SDL initialisieren
    screen = SDL_SetVideoMode(1000,800,32,SDL_SWSURFACE);//Die Fenstereigenschaften festlegen
    
    //Die Bilder Laden
    imageMenu   = IMG_Load("Grafik\\true detective.jpg");
    imageButton = IMG_Load("Grafik\\RESUME-BUTTON.png");
    imageButton2 = IMG_Load("Grafik\\LOAD-BUTTON.png");

    //position der Bilder bestimmen
    SDL_Rect ImagePosition;
    ImagePosition.x = 0;
    ImagePosition.y = 0;

    SDL_Rect ImagePosition2;
    ImagePosition2.x = 0;
    ImagePosition2.y = 100;
    
    
        while (run)
        {
            //Startzeit in Millisekunden
            start = SDL_GetTicks();

            //Falls  button X rechts oben am Fenster gedrückt, dann schliesse das gesamte Programm
            while (SDL_PollEvent(&event))
            {
                switch(event.type)
                {
                    case SDL_QUIT:
                        run = false;
                        break;
                }
                
            }
            
            //die Bilder Transparent machen
            SDL_SetAlpha(imageButton2,SDL_SRCALPHA,beta);
            SDL_SetAlpha(imageMenu,SDL_SRCALPHA,alpha);
            SDL_SetAlpha(imageButton,SDL_SRCALPHA,beta);
            
            
            //Die Bilder auf das Fenster übertragen
            SDL_BlitSurface(imageButton2,NULL,screen,&ImagePosition2);
            SDL_BlitSurface(imageButton,NULL,screen,&ImagePosition);
            SDL_BlitSurface(imageMenu,NULL,screen,&ImagePosition);
            
            //Der Overflow ist zu Testzecken beabsichtigt!
            beta++;
            alpha+=10;
            

            //ohne das sieht man nichts auf dem Bildschirm  
            SDL_Flip(screen);
            
            //Verzögerung der Zeit um 33,333 msec
            if (1000/30 > SDL_GetTicks() - start)
            {
                SDL_Delay((1000/10) - (SDL_GetTicks() - start));
            }

        }

    //Alle surfaces freigeben und SDL beenden, umm Memoryleak zu vermeiden
    SDL_FreeSurface(screen);
    SDL_FreeSurface(imageMenu);
    SDL_FreeSurface(imageButton);
    SDL_Quit();

return 0;
}


Merkwürdigerweise macht es keine Unterschied ob man diese

C-/C++-Quelltext

1
2
 //die Bilder Transparent machen
 SDL_SetAlpha(imageButton2,SDL_SRCALPHA,beta);


C-/C++-Quelltext

1
SDL_SetAlpha(imageButton,SDL_SRCALPHA,beta);


Zeilen auskommentier oder nicht!(komisch)


[/cpp]
»Incrementis« hat folgende Bilder angehängt:
  • Anfangszustand.JPG
  • Zwischenzustand.JPG

Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von »Incrementis« (16.03.2014, 13:11)


Lares

1x Contest-Sieger

  • Private Nachricht senden

6

16.03.2014, 15:07

Wie gesagt ich kann keine Lösung für das Problem geben, da ich mich auch zu wenig mit SDL auskenne. Ich habe aber auf folgender Seite was gefunden, das evt. helfen könnte:
http://www.libsdl.org/release/SDL-1.2.15…dlsetalpha.html

Zitat


RGBA->RGB with SDL_SRCALPHA The source is alpha-blended with the destination, using the alpha channel. SDL_SRCCOLORKEY and the per-surface alpha are ignored.

Kann es sein, dass dein screen Surface vom Typ RGB statt RGBA ist? Würde für mich zumindest den Fehler erklären: Auf Bild 1 renderst du die Buttons auf RBG-> sie werden opak.
Auf Bild zwei wird das Surface mit den Buttons teilweise auf ein anderes RGBA surface gerendert, weswegen sei an der Stelle transparent sind.

Edit: Wobei ich grad sehe, dass du explizit alles auf screen renderst. Vllt hilft dir der Hinweis trotzdem iwie weiter.

Werbeanzeige