Kirjautuminen

Haku

Tehtävät

Keskustelu: Ohjelmointikysymykset: C: SDL, pikselin osittainen läpinäkyvyys

Sivun loppuun

Andu [19.02.2008 00:12:49]

#

Mitenköhän saisi piirrettyä osittain läpinkyvän pikselin SDL_Surfaceen? Ilman läpinäkyvyyttä koodi kyllä toimii, mutta näin se ei ota ollenkaan huomioon läpinäkyvyyttä.

void drawPixel(SDL_Surface *surface, int x, int y, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
{
    Uint32 color = SDL_MapRGBA(surface->format, r, g, b, a);

    Uint32 *bufp;
    bufp = (Uint32*)surface->pixels + y*surface->pitch/4 + x;
    *bufp = color;
}

tgunner [19.02.2008 00:41:34]

#

Häh, "osittain" läpinäkyvä pikseli? Tai ylipäätänsä läpinäkyvä pikseli?

User137 [19.02.2008 05:06:22]

#

Läpinäkyvä pikseli tarkoittaa tätä:
http://nicolaescher.com/images/tut_alpha_images/alpha_rebus_t.jpg

tgunner [19.02.2008 11:40:16]

#

Tjaa, hassu nimi silläkin, olettaen, että pikseli on vain yhtä väriä.

Baglair [19.02.2008 11:49:37]

#

Lataat ensin pikselin x, y *SDL_Surface:sta ja katot sen värit. Sitten piirrät sen haluamas pikselin kohtaan x, y, mutta lasketkin sille pikselille sen alkuperäsen pikselin värin ja sun haluaman värin keskiarvon.

Andu [19.02.2008 13:08:51]

#

Tarkoitus olisi siis saada "osittain läpinäkyvä" (ei kokonaan näkymätön, eikä kokonaan näkyvä) pikseli juuri SDL_Surfaceen, eikä vasta piirtovaiheessa. SDL_imagellakin saa ladattua surfaceen läpinäkyviä kuvia, joten luulisi sen olevan mahdollista.
Tässä vielä esimerkki "osittain läpinäkyvästä" pikselistä.

Legu [19.02.2008 16:31:18]

#

SDL_SetAlpha on se mitä haet.

if (SDL_SetAlpha(kuvapinta, SDL_SRCALPHA, läpinäkyvyyden_aste_väliltä_0_255) < 0) {
    // Virhe
}

SDL_image osaa muistaakseni säätää tuon, eli jos käytät jotain kuvaformaattia mihin saa määriteltyä läpinäkyvyyden, niin se onnistuu "automaattisesti".

Andu [19.02.2008 22:37:26]

#

Legu kirjoitti:

SDL_SetAlpha on se mitä haet.

Ei ole. Tuo kuva saattoi kyllä johtaa vähän harhaan, mutta se oli minun vikani.
Kyse oli siis yhden pikselin piirtämisestä (kuten tuo funktioni tekee. Se ei tosin ota alphaa huomioon), eli ei siis koko kuvan alphan muuttamisesta.

Edit: Mikäs tuo sivupalkkiin ilmestyvä välilyönti on?

sivupalkki kirjoitti:

SDL_SetAlp ha on se mitä haet.

Gaxx [20.02.2008 08:36:17]

#

No mikäs vika tuossa Baglairin menetelmässä sitten on?

Baglair kirjoitti:

Lataat ensin pikselin x, y *SDL_Surface:sta ja katot sen värit. Sitten piirrät sen haluamas pikselin kohtaan x, y, mutta lasketkin sille pikselille sen alkuperäsen pikselin värin ja sun haluaman värin keskiarvon.

Tässä vielä koodivinkki, josta on apua laskemiseen.

Eli

SDL_GetRGB(...);

hajottaa värikoodin punaiseksi, vihreäksi ja siniseksi. Ja

SDL_MapRGB(...);

kokoaa värit yhdeksi koodiksi.

Andu [20.02.2008 13:50:24]

#

Gaxx kirjoitti:

Pakko kai sitten on tehdä noin. Mutta luulisi kyllä, että tuon voisi tehdä esimerkiksi tuolla aloitusviestissä olevalla funktiolla.

Edit: Luulisi tuon olevan kuitenkin melko hidasta varsinkin suurilla kuvilla, kun tuo pitäisi tehdä aina, eikä vain ohjelman alussa, kuten esimerkissä.

User137 [21.02.2008 02:18:35]

#

En ainakaan äkkiseltään löytänyt tapaa piirtää alphakanavoitua kuvaa kuten PNG SDL avulla. OpenGL ja DirectX ainakin suoriutuu hommasta 3D kortin avulla yhtä vaivattomasti ja nopeasti kuin minkä tahansa muun kuvan kanssa.

Metabolix [21.02.2008 10:50:51]

#

Kyllä SDL tukee pikselikohtaista alfakanavaa. Lähdepinnalle tarvitaan SDL_SRCALPHA-lippu. Piirtäminen toimii tämän jälkeen aivan normaaliin tapaan SDL_BlitSurface-funktiolla. Pinnan formaatin täytyy tietenkin olla alfakanavallinen. Myös läpinäkyvän PNG:n lataaminen SDL_image-kirjastolla toimii aivan hyvin.

Andu [21.02.2008 16:15:00]

#

Pitäisikö siis tämän toimia?

SDL_Surface* img;
img = SDL_CreateRGBSurface(SDL_SWSURFACE|SDL_SRCALPHA, 64, 64, 32, 0, 0, 0, 0);
...
drawPixel(img, x, y, r, g, b, alpha);
...
drawImage(img, x, y);


void drawPixel(SDL_Surface *screen, int x, int y, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
{
    Uint32 color = SDL_MapRGBA(screen->format, r, g, b, a);

    Uint32 *bufp;
    bufp = (Uint32*)screen.pixels + y*screen.pitch/4 + x;
    *bufp = color;
}

void drawImage(SDL_Surface *image, int x, int y)
{
    SDL_Rect rect;
    rect->x = x;
    rect->y = y;
    SDL_BlitSurface(image, null, screen, &rect);
}

Ymmrärsinkö jotakin väärin, vai miksi tuo ei toimi?

zacura [21.02.2008 18:19:19]

#

Andu kirjoitti:

img = SDL_CreateRGBSurface(SDL_SWSURFACE|SDL_SRCALPHA, 64, 64, 32, 0, 0, 0, 0);

Alfa-kanavaa varten pitää asetta Amask muuksi kuin nolla. Katso tuolta lisää asiasta: http://www.libsdl.org/cgi/docwiki.cgi/SDL_5fCreateRGBSurface

Andu [21.02.2008 18:37:55]

#

No nyt toimii! FPS:kin nousi mukavasti. Kiitoksia. Tosin pelkän alfa-kanavan muuttaminen ei toiminut. Tämmönen rivi on nyt:

img = SDL_CreateRGBSurface(SDL_SWSURFACE, 64, 64, 32, 0xff000000, 0x00ff0000, 0x0000ff00, 0x000000ff);

Metabolix [21.02.2008 20:34:48]

#

Kannattaa myös panostaa hieman siihen, että saa piirrettävän pinnan samaan formaattiin kuin näyttöpinnan, jos vain näyttöpinnan formaatti on lainkaan tarkoitukseen sopiva.


Sivun alkuun

Vastaus

Aihe on jo aika vanha, joten et voi enää vastata siihen.

Tietoa sivustosta