Mask for background animations and transparencies

Previous topic - Next topic

fuzzy70

Quote from: Kitty Hello on 2013-Feb-09
Can you tell me how to do alpha drawing in other languages? The mem2sprite thing should work. Also, drawrect can draw alpha on an offscreen.

In BlitzBasic/3D by default RGB(0,0,0) is transparent & thus anything you draw (sprites or rects etc) in black is automatically seethru.
here is the code in Blitz3d
Code (glbasic) Select

Graphics 800,600,32,2

hole = LoadImage("hole.bmp")


mask = CreateImage(800,600)
MaskImage mask,255,0,128    ;by default Blitz3D treats black as transparent


SetBuffer ImageBuffer(mask) ;draw directly onto the newly created image to be used as the mask

Color 0,0,0
Rect 0,0,800,600,1 ;fill the image with black
DrawImage hole,100,100 ;draw our hole sprite

SetBuffer BackBuffer() ;go back to our double buffering

While Not KeyHit(1)

Cls

For loop = 0 To 100 ;draw some random background
Color Rand(255),Rnd(255),Rnd(255)
Rect Rand(1,700),Rand(1,500),Rand(1,200),Rand(1,100),1
Next

DrawImage mask,0,0 ;draw our created mask

Flip

Wend


also attached the code & exe.

Lee


[attachment deleted by admin]
"Why don't you just make ten louder and make ten be the top number and make that a little louder?"
- "These go to eleven."

This Is Spinal Tap (1984)

fuzzy70

OK I have sussed it, lots of experiments & head scratching I came to the following conclusion.

As we know DRAWRECT works with no problems drawing alpha so here is my solution


  • Create a screen to be used for the hole cutting overlay (full screen)
  • Draw a full screen black rectangle
  • Draw a rectangle where we want to place the the spotlight in the transparency colour
  • Draw our 'hole' sprite

BTW the 'hole' sprite has to be transparent in the area you want to see through, could not get it to work using RGB(255,0,128), see the attached  :D

Also if you want to cut more than one item out it has to be done inside the cutshape function for obvious reasons due to it drawing a full size black rect  :D

the code

Code (glbasic) Select

SETCURRENTDIR("Media") // go to media files
LOADFONT "smalfont.bmp",1


GLOBAL sw%,sh%,loop%,starttime,totaltime

LOCAL cx%=10

SETSCREEN 240,320,0

GETSCREENSIZE sw%,sh%

LOADSPRITE "round.png",10

CREATESCREEN 2,1,240,320
CREATESCREEN 3,2,240,320

USESCREEN 2
SEEDRND 10

FOR loop%=0 TO 100
DRAWRECT RND(200),RND(300),RND(70),RND(70),RGB(RND(255),RND(255),RND(255))
NEXT

USESCREEN -1

WHILE TRUE

starttime=GETTIMERALL()

DRAWSPRITE 1,0,0

cutshape(cx,0,64,64)

DRAWSPRITE 2,0,0

INC cx,1
IF cx>sw-64 THEN cx=10

totaltime=1000/(GETTIMERALL()-starttime)
PRINT "FPS="+INTEGER(totaltime),0,300,1
SHOWSCREEN

WEND

FUNCTION cutshape: x%,y%,sprw%,sprh%

USESCREEN 3
SETTRANSPARENCY RGB(255,0,128)
DRAWRECT 0,0,sw,sh,RGB(0,0,0)
DRAWRECT x,y,sprw,sprh,RGB(255,0,128)
DRAWSPRITE 10,x,y
USESCREEN -1

ENDFUNCTION


Lee

edit: using a black sprite the size of the screen maybe quicker than drawing the full screen rect on some devices

edit2: The above works perfectly except if you have more than one sprite that overlaps with another sprite as you then see the corners of it that are not transparent. ARRGGGHHHHH back to the drawingboard  :rant:

[attachment deleted by admin]
"Why don't you just make ten louder and make ten be the top number and make that a little louder?"
- "These go to eleven."

This Is Spinal Tap (1984)

fuzzy70

Sorry for the triple post, my bad

I have got round the problem by not using sprites at ALL. Seeing as DRAWRECT works no problem I changed the cutter function to draw circles using a modifying a Midpoint circle algorithm using rects. Its a hell of a lot quicker then the MEM2SPRITE version, has none of the problems associated with the sprite version if things overlap & uses pure integers so no sin/cos performance loss on lower end machines  =D.

I tested it on my pocket pc (xscale 400mhz cpu & no graphics chip that I'm aware of) & got an average of 160fps, compared to 95fps on the sprite version (with it's overlap issues) & 20fps on the MEM2SPRITE version. That was with 2 circles with a 32px radius, hopefully the caanoo etc should have no problems as am pretty sure it is specced better than my ancient pocket pc  :D.

Lee

Code (glbasic) Select
SETCURRENTDIR("Media") // go to media files

GLOBAL sw%,sh%,loop%,starttime,totaltime

LOCAL cx%=10

SETSCREEN 240,320,0

GETSCREENSIZE sw%,sh%


CREATESCREEN 2,1,240,320
CREATESCREEN 3,2,240,320

USESCREEN 2
SEEDRND 10

FOR loop%=0 TO 100
DRAWRECT RND(200),RND(300),RND(70),RND(70),RGB(RND(255),RND(255),RND(255))
NEXT

USESCREEN -1

WHILE TRUE

starttime=GETTIMERALL()

DRAWSPRITE 1,0,0

cutshape(cx,100,64)

DRAWSPRITE 2,0,0

INC cx,1
IF cx>sw-64 THEN cx=10

totaltime=1000/(GETTIMERALL()-starttime)
PRINT "FPS="+INTEGER(totaltime),0,300,1
SHOWSCREEN

WEND

FUNCTION cutshape: cx%,cy%,r%

LOCAL f%, x%, y%, ddx%, ddy%

USESCREEN 3

SETTRANSPARENCY RGB(255,0,128)

DRAWRECT 0,0,sw,sh,RGB(0,0,0)

f% = 1 - r% ; y% = r% ; ddy% = - 2*r%

DRAWRECT cx%-r%,cy%,r%*2,1,RGB(255,0,128)

WHILE x% < y%

IF f% >= 0
          DEC y%,1
          INC ddy%,2
          INC f%,ddy%
        ENDIF

        INC x%,1
        INC ddx%,2
        INC f%,ddx% + 1

        DRAWRECT cx%-x%,cy%+y%,x%*2,1,RGB(255,0,128)
        DRAWRECT cx%-x%,cy%-y%,x%*2,1,RGB(255,0,128)
        DRAWRECT cx%-y%,cy%+x%,y%*2,1,RGB(255,0,128)
        DRAWRECT cx%-y%,cy%-x%,y%*2,1,RGB(255,0,128)

WEND

USESCREEN -1

ENDFUNCTION
"Why don't you just make ten louder and make ten be the top number and make that a little louder?"
- "These go to eleven."

This Is Spinal Tap (1984)

erico

I get some error (global definition) on the r%.
Is that normal? I´m using v11.

fuzzy70

Quote from: erico on 2013-Feb-09
I get some error (global definition) on the r%.
Is that normal? I´m using v11.

Just to check I started another project & pasted the code from here & it ran fine  :S

The r% is used only in the cutshape function as a parameter & inside the function so shouldn't get an error (i'm still using 10.283). try replacing all occurrences of r% with something else like cr% for example. Perhaps r% is reserved in v11 beta otherwise no idea  :O

Lee
"Why don't you just make ten louder and make ten be the top number and make that a little louder?"
- "These go to eleven."

This Is Spinal Tap (1984)

erico

Ok,

I got both installed, will try v10

fuzzy70

Quote from: erico on 2013-Feb-09
Ok,

I got both installed, will try v10

Changed the code so that no variables that are used in the function are used outside just in case & attached the project

Lee

Code (glbasic) Select

// --------------------------------- //
// Project: cutter2
// Start: Saturday, February 09, 2013
// IDE Version: 10.283


// FREE-VERSION:
// Need Premium for Features:
// 3D Graphics
// Network Commands
// INLINE C/C+++ code

// SETCURRENTDIR("Media") // go to media files
SETCURRENTDIR("Media") // go to media files

GLOBAL sw%,sh%,loop%,starttime,totaltime

LOCAL plotx%=10

SETSCREEN 240,320,0

GETSCREENSIZE sw%,sh%


CREATESCREEN 2,1,240,320
CREATESCREEN 3,2,240,320

USESCREEN 2
SEEDRND 10

FOR loop%=0 TO 100
DRAWRECT RND(200),RND(300),RND(70),RND(70),RGB(RND(255),RND(255),RND(255))
NEXT

USESCREEN -1

WHILE TRUE

starttime=GETTIMERALL()

DRAWSPRITE 1,0,0

cutshape(plotx,100,64)

DRAWSPRITE 2,0,0

INC plotx,1
IF plotx>sw-64 THEN plotx=10

totaltime=1000/(GETTIMERALL()-starttime)
PRINT "FPS="+INTEGER(totaltime),0,300,1
SHOWSCREEN

WEND

FUNCTION cutshape: cx%,cy%,r%

LOCAL f%, x%, y%, ddx%, ddy%

USESCREEN 3

SETTRANSPARENCY RGB(255,0,128)

DRAWRECT 0,0,sw,sh,RGB(0,0,0)

f% = 1 - r% ; y% = r% ; ddy% = - 2*r%

DRAWRECT cx%-r%,cy%,r%*2,1,RGB(255,0,128)

WHILE x% < y%

IF f% >= 0
          DEC y%,1
          INC ddy%,2
          INC f%,ddy%
        ENDIF

        INC x%,1
        INC ddx%,2
        INC f%,ddx% + 1

        DRAWRECT cx%-x%,cy%+y%,x%*2,1,RGB(255,0,128)
        DRAWRECT cx%-x%,cy%-y%,x%*2,1,RGB(255,0,128)
        DRAWRECT cx%-y%,cy%+x%,y%*2,1,RGB(255,0,128)
        DRAWRECT cx%-y%,cy%-x%,y%*2,1,RGB(255,0,128)

WEND

USESCREEN -1

ENDFUNCTION


[attachment deleted by admin]
"Why don't you just make ten louder and make ten be the top number and make that a little louder?"
- "These go to eleven."

This Is Spinal Tap (1984)

erico

Worked with V10 of GLB.
Tried on Caanoo, works like a charm, can this be used, let´s say to have multiple balls?

I first thought of drawing a black virtual screen (sprite or rec) and then draw the multiple balls on a very low res, like those uploaded some pages ago. Balls made of a set of rectangles, considering the speed of drawrect, it could be even a set of horizontal blocks, or a combination of bigger and smaller ones to reduce drawrec calls. I would not be a pixel perfect circle, more a blown up pixelated one. ;)

You function is really cool, very little amount of code going there.
I have to study it a bit. Fear for functions creeps in :-[

Thanks a lot for a solution fuzzy70!

I hope this all can help Ian too.

EDIT: ps. those marks on the right of my screen protection is all your fault Ian! (Drench!)

EDIT2: sorry to ask, how can I change the diameter of the ball?

[attachment deleted by admin]

kanonet

Interestingly this does not work for me, I only see a black screen (with fps counter). Looks like i can not set the transparency colour with DRAWRECT.
Using V11 on an integrated intel graphic card.
Lenovo Thinkpad T430u: Intel i5-3317U, 8GB DDR3, NVidia GeForce 620M, Micron RealSSD C400 @Win7 x64

erico

I will try the last version on v11  to check...
On version 11 of GLB I get the black screen too. GTX460.

...works fine on v10 O_O

fuzzy70

here's a hack that draws 5 circles

to change the size of the ball erico just call the cutshape from the 1st example with the radius you want, the last parameter is the one.

Code (glbasic) Select
cutshape(x position,y position ,radius)

better still play with the one below  :D

Lee

Code (glbasic) Select
// --------------------------------- //
// Project: cutter2
// Start: Saturday, February 09, 2013
// IDE Version: 10.283


// FREE-VERSION:
// Need Premium for Features:
// 3D Graphics
// Network Commands
// INLINE C/C+++ code

// SETCURRENTDIR("Media") // go to media files

TYPE Tcircles
x%
y%
radius%
ENDTYPE

SETCURRENTDIR("Media") // go to media files

GLOBAL sw%,sh%,loop%,starttime,totaltime
GLOBAL circles[] AS Tcircles

LOCAL plotx%=10

SETSCREEN 240,320,0

GETSCREENSIZE sw%,sh%


CREATESCREEN 2,1,240,320
CREATESCREEN 3,2,240,320

DIM circles[5]

FOR loop=0 TO 4
circles[loop].x=RND(sw)
circles[loop].y=RND(sh)
circles[loop].radius=RND(32)+16
NEXT



WHILE TRUE

starttime=GETTIMERALL()

FOR loop%=0 TO 100
DRAWRECT RND(200),RND(300),RND(70),RND(70),RGB(RND(255),RND(255),RND(255))
NEXT


DRAWSPRITE 1,0,0

FOR loop%=0 TO 1
INC circles[loop%].x,RND(2)-1
INC circles[loop%].y,RND(2)-1

IF circles[loop].x=sw OR circles[loop].x=0 THEN circles[loop].x=RND(sw)
IF circles[loop].y=sh OR circles[loop].y=0 THEN circles[loop].y=RND(sh)
NEXT
cutshape()

DRAWSPRITE 2,0,0

INC plotx,1
IF plotx>sw-64 THEN plotx=10

totaltime=1000/(GETTIMERALL()-starttime)
PRINT "FPS="+INTEGER(totaltime),0,300,1
SHOWSCREEN

WEND

FUNCTION cutshape:

LOCAL lo%

USESCREEN 3

SETTRANSPARENCY RGB(255,0,128)

DRAWRECT 0,0,sw,sh,RGB(0,0,0)

FOR lo%=0 TO 4

drawcircle(circles[lo%].x,circles[lo%].y,circles[lo%].radius)

NEXT

USESCREEN -1

ENDFUNCTION

FUNCTION drawcircle: cx%,cy%,r%

LOCAL f%, x%, y%, ddx%, ddy%

f% = 1 - r% ; y% = r% ; ddy% = - 2*r%

DRAWRECT cx%-r%,cy%,r%*2,1,RGB(255,0,128)

WHILE x% < y%

IF f% >= 0
          DEC y%,1
          INC ddy%,2
          INC f%,ddy%
        ENDIF

        INC x%,1
        INC ddx%,2
        INC f%,ddx% + 1

        DRAWRECT cx%-x%,cy%+y%,x%*2,1,RGB(255,0,128)
        DRAWRECT cx%-x%,cy%-y%,x%*2,1,RGB(255,0,128)
        DRAWRECT cx%-y%,cy%+x%,y%*2,1,RGB(255,0,128)
        DRAWRECT cx%-y%,cy%-x%,y%*2,1,RGB(255,0,128)

WEND
ENDFUNCTION


There does seem to be an issue with V11 by the look of things  :O

Looking forward to Ians response to see if he gets any improvement out of this :)

Lee
"Why don't you just make ten louder and make ten be the top number and make that a little louder?"
- "These go to eleven."

This Is Spinal Tap (1984)

Ian Price

Cheers Lee. :)

I haven't tested any of these yet as I've not long got home form work. It looks as though you've finally put this to bed though. I'll have a play tomorrow now. I'm using V10, so whatever the problem may be with v11 it shouldn't affect me :)
I came. I saw. I played.

fuzzy70

Quote from: Ian Price on 2013-Feb-10
Cheers Lee. :)

I haven't tested any of these yet as I've not long got home form work. It looks as though you've finally put this to bed though. I'll have a play tomorrow now. I'm using V10, so whatever the problem may be with v11 it shouldn't affect me :)

No problems Ian, just feel sorry for Gernot as not only is he looking for how to draw other items with transparency it appears I have uncovered something thats changed in V11  :'(

Btw just done the above test on my pocket pc & got 70fps with the 5 random balls & drawing the 100 coloured rects in the background randomly each frame. Hardly game logic I know but pushes my little pocket pc harder than my previous example  =D

Lee
"Why don't you just make ten louder and make ten be the top number and make that a little louder?"
- "These go to eleven."

This Is Spinal Tap (1984)

erico

Tried the latest on GLB V10:

works fine on PC.
works fine on caanoo.

With GLB V11:

black on PC.
black with pink balls on caanoo. :O

Strange, I hope it helps Gernot on the reason for this.

EDIT: This might be the reason I could not make it work back again on my sprite attempts beguinning of this thread after I changed to V11. I´m sure I did something cool but was not able to come back to it. At that point though, I was using a worse self method, with alphamode 1, which is killer on caanoo and while it worked on PC, none worked on caanoo. I hope, for Gernot´s sake, that I was allucinating...but I´m pretty sure of it. Now I wish I had saved versions, specially those that worked on PC on V10 :(
Have to learn to save versions the hard way.

fuzzy70

Quote from: erico on 2013-Feb-10
Tried the latest on GLB V10:

works fine on PC.
works fine on caanoo.

With GLB V11:

black on PC.
black with pink balls on caanoo. :O

Strange, I hope it helps Gernot on the reason for this.

Hmmm, either something has changed in V11 in the way DRAWRECT works or SETTRANSPARENCY is broken.

I cannot think of another way to do the routine, my circle routine is about as optimised as it can be I think(no trig & pure integer math) & so far it seems DRAWRECT is the only command currently that works with SETTRANSPARENCY. I have not tried SETPIXEL as I know that is slow & I would not gain any speed boost at all using it.

Lee
"Why don't you just make ten louder and make ten be the top number and make that a little louder?"
- "These go to eleven."

This Is Spinal Tap (1984)