cb-hackers / cbEnchanted

A new runtime for CoolBasic
13 stars 3 forks source link

Läpinäkyvällä värillä piirtäminen vaikuttaa kuvan alpha-kanavaan #83

Closed aXu-AP closed 12 years ago

aXu-AP commented 12 years ago

Läpinäkyvällä värillä piirtäminen muuttaa kuvan väriarvojen lisäksi sen läpinäkyvyyttä. Käytännössä siis jos kuultavalla maalaa peittävän päälle, tulos on kuultava. En nyt tiedä onko tämä bugi vai ominaisuus, kyseessähän on ymmärtääkseni allegron oletusblendaus. Koen sen kuitenkin epäintuitiiviseksi (enkä keksi nyt käytännön hyötyjäkään tästä ominaisuudesta/omituisuudesta). Ongelma ei tietenkään toistu suoraan ruudulle piirtäessä, koska sillä ei ole läpinäkyvyyttä.

Seuraava koodi selventää ongelmaa:

Stamp = LoadImage("media/cow.bmp")
Canvas = MakeImage(400, 300)
DrawToImage Canvas
    //Maalataan puolet valkoisella ongelman havainnollistamiseksi (tämän päälle piirtäminen tekee "reikiä")
    Color 255, 255, 255
    Box 0, 0, 200, 300
DrawToScreen

Repeat
    DrawImage Canvas, 0, 0
    DrawImage Stamp, MouseX() - 15, MouseY() - 12
    If MouseHit(1) Then
        DrawToImage Canvas
            cbeColor(255, 255, 255, 128)
            cbeDrawTintedScaledRotatedImage(Stamp, MouseX(), MouseY())
        DrawToScreen
    EndIf
    ClsColor 100 + Sin(Timer() / 13) * 100, 100 + Sin(Timer() / 12) * 100, 100 + Sin(Timer() / 11) * 100
    DrawScreen
Forever

Function cbeColor(r, g, b, a)
    group = 1
    funcId = 2
EndFunction

Function cbeDrawTintedScaledRotatedImage(img, toX#, toY#, scaleX# = 1, scaleY# = 0, angle# = 0)
    If scaleY = 0 Then scaleY = scaleX
    cbeDrawTintedScaledRotatedImageBox(img, 0, 0, ImageWidth(img), ImageHeight(img), toX, toY, scaleX, scaleY, angle)
EndFunction

Function cbeDrawTintedScaledRotatedImageBox(img, startX As Float, startY As Float, width As Float, height As Float, toX As Float, toY As Float, scaleX As Float, scaleY As Float, angle As Float)
    group = 1
    funcId = 6
End Function

Korjaukseksi ehdotan, että oletusblendausmoodi olisi (olettaen, että olen ymmärtänyt tuon oikein): al_set_separate_blender(ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA, ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_INVERSE_ALPHA). Tällöin alphakanavien arvot summataan (jolloin peittävä+kuultava=peittävä).

EDIT: Testikoodi muutettu käyttämään kuvia. EDIT2: Muutin ehdotustani defaultblendaukseksi... edellinen oli pielessä, nyt pitäisi tulla intuitiivinen tulos (eli värit blendautuu alphan mukaan, alphat summataan) EDIT3: Siirsin tuon al_set_separate_blender-ehdotuksen tuonne.

valscion commented 12 years ago

Primitiivien piirtoon ei blendausmoodit vaikuta. Jos haluat tuon toimivan haluamallasi tavalla, joudut aina luomaan uuden väliaikaisen kuvan jonka piirrät blendattuna toiseen kuvaan.

aXu-AP commented 12 years ago

Enpä tuota tiennytkään (en ole blendausmoodeilla kerennyt leikkimään). Miksi blendausmoodit eivät vaikuta primitiiveihin? Onko taustalla allegron rajoitus vai jokin järkevä selitys?

Ei tätä silti tarvitse sulkea, sillä tämä pätee myös kuviin.

EDIT: Hmh, jotenkin en saa kuvien piirtoa kuviin onnistumaan mitenkään järkevästi? Seuraava pätkä piirtää jostakin syystä additiivisesti:

Stamp = LoadImage("media/cow.bmp")
Canvas = MakeImage(400, 300)

Repeat
    DrawImage Canvas, 0, 0
    DrawImage Stamp, MouseX(), MouseY()
    If MouseHit(1) Then
        DrawToImage Canvas
            DrawImage Stamp, MouseX(), MouseY()
        DrawToScreen
    EndIf

    DrawScreen
Forever

EDIT2: cbeDrawTintedScaledRotatedImageBoxilla näyttäisi onnistuvan niin kuin odottaisi. Muutin aloitusviestin esimerkkikoodin.

valscion commented 12 years ago

Avataanpa tämä sitten ja jätetään mietinnän alle. En ihan tiedä että olisiko tämä bugi vaiko erikoisfunktio.

EDIT: Niin joo, on Allegron rajoitus se ettei blendausmoodi vaikuta primitiiveihin.

aXu-AP commented 12 years ago

"En ihan tiedä että olisiko tämä bugi vaiko erikoisfunktio" Laitoit sitten kysymykseksi :D Mielestäni tämä on ehkä "enhancement" sekä "custom-function" (ehdotan oletusblendauksen muutosta ja al_set_separate_blender:n lisäämistä, jos sen tuosta sotkuisasta ekasta viestistä ei saa selville ;)). Päivitin muuten sitä ehdotusta oletusmoodista (siellä oli ALLEGRO_ONE missä oli tarkoitus olla ALLEGRO_ALPHA). EDIT: Muutin vielä sitä alphakanavan laskemista luettuani aiheesta lisää - eli ilmeisesti alphakanavien arvoja ei yleensä summata, vaan pohjalla olevan kuvan alpha kerrotaan piirtovärin alphan komplementilla (en kyllä tuota käytännössä pysty nyt kokeilemaan, mutta teoriassa kuulostaa järkevältä) tai toisinpäin - ei nyt aivot tahdo enää toimia :D

Teen uuden issuen tuolle DrawImage -bugille, kun se ei liity tähän aiheeseen.

valscion commented 12 years ago

Hyvä että selvensit issueta, sitä minä vähän hainkin takaa tuolla question-tägin laittamisella.

aXu-AP commented 12 years ago

Tein uuden issuen tuolle al_set_separate_blender:lle. Parempi yksi ongelma/ehdotus per issue. (eli tuon custom-function -labelin voi ottaa tästä pois).

valscion commented 12 years ago

Tämä on muutettu nyt intuitiivisemmaksi. Esimerkkiäsi täytyi tosin muuttaa hieman, sillä normaalisti tuohon "Canvas" kuvaan piirretään taustalle se läpinäkymätön musta tausta. Kun kuvaan piirrellään, niin blendaukset tapahtuvat sen mustan kanssa, vaikka se maskataankin pois sitten kun kuvaan piirto loppuu.

Voit seuraavassa julkaisussa testailla alla olevalla esimerkkikoodilla tämän toimintaa:

Stamp = LoadImage("media/cow.bmp")
Canvas = MakeImage(400, 300)
DrawToImage Canvas
    // Tyhjennetään kuva ensin täysin läpinäkyväksi
    cbeClsColor(0, 0, 0, 0)
    Cls
    //Maalataan puolet valkoisella ongelman havainnollistamiseksi (tämän päälle piirtäminen tekee "reikiä")
    Color 255, 255, 255
    Box 0, 0, 200, 300
DrawToScreen

cbeClsColor(0, 0, 0, 255)
Repeat
    DrawImage Canvas, 0, 0
    DrawImage Stamp, MouseX() - 15, MouseY() - 12
    If MouseHit(1) Then
        DrawToImage Canvas
            cbeColor(255, 255, 255, 128)
            cbeDrawTintedScaledRotatedImage(Stamp, MouseX(), MouseY())
        DrawToScreen
    EndIf
    ClsColor 100 + Sin(Timer() / 13) * 100, 100 + Sin(Timer() / 12) * 100, 100 + Sin(Timer() / 11) * 100
    DrawScreen
Forever

Function cbeColor(r, g, b, a)
    group = 1
    funcId = 2
EndFunction

Function cbeDrawTintedScaledRotatedImage(img, toX#, toY#, scaleX# = 1, scaleY# = 0, angle# = 0)
    If scaleY = 0 Then scaleY = scaleX
    cbeDrawTintedScaledRotatedImageBox(img, 0, 0, ImageWidth(img), ImageHeight(img), toX, toY, scaleX, scaleY, angle)
EndFunction

Function cbeDrawTintedScaledRotatedImageBox(img, startX As Float, startY As Float, width As Float, height As Float, toX As Float, toY As Float, scaleX As Float, scaleY As Float, angle As Float)
    group = 1
    funcId = 6
EndFunction

Function cbeClsColor(r, g, b, a)
    group = 1
    funcId = 3
EndFunction