BASIC

Author Topic: Ray of lights  (Read 6632 times)

Offline Albert

  • Dr. Type
  • ****
  • Posts: 257
    • View Profile
    • Blog
Ray of lights
« on: 2011-Sep-21 »
Hi!

I'm experimenting with ray of lights. You can download the fully commented project from here or you can found in the attachment.
http://dl.dropbox.com/u/292449/lightrays.zip




[attachment deleted by admin]
« Last Edit: 2011-Sep-21 by Albert »

Offline Albert

  • Dr. Type
  • ****
  • Posts: 257
    • View Profile
    • Blog
Re: Ray of lights
« Reply #1 on: 2011-Sep-21 »
Here is the code:

Code: GLBasic [Select]
// --------------------------------- //
// Project: Shadow
// Start: September 21, 2011
// IDE Version: 9.006

//written by Bence Dobos, 2011

SETCURRENTDIR("Media") // seperate media and binaries?
SYSTEMPOINTER TRUE

LOADFONT "smalfont2.png",1
SETFONT 1

//card
GLOBAL maxcard = 4
GLOBAL spr_card = 0
GLOBAL card_w, card_h
GLOBAL map[]

//player
GLOBAL spr_player = 10
GLOBAL plr_x=1000, plr_y=1050

//blob
GLOBAL spr_blob = 20 //first blob

//screen
GLOBAL scr_w, scr_h
GLOBAL scr_wf, scr_hf //half

//gui object
GLOBAL gui AS UIState

//all the variables you can change using the GUI
GLOBAL r=255,g=255,b=255
GLOBAL alpha=150
GLOBAL alpha2=20
GLOBAL LightSource=TRUE
GLOBAL iter=2   //keep it low for slower machines
GLOBAL raystep=1
GLOBAL scale=10
GLOBAL nblob=0
GLOBAL showGUI=FALSE
GLOBAL lightrays=TRUE
GLOBAL controlsheme=0 //0 keyboard, 1 mouse
//init
GETSCREENSIZE scr_w, scr_h
scr_wf=scr_w/2
scr_hf=scr_h/2

//creating random map, for a nice background
DIM map[10][10]
FOR x=0 TO 9
        FOR y=0 TO 9
                map[x][y]=RND(maxcard-1)
        NEXT
NEXT

//loadind cards
//NOTE: all the graphics from Draco by Puli Games (c)
FOR i=0 TO maxcard-1
        LOADSPRITE "card"+i+".png", spr_card+i
NEXT
GETSPRITESIZE spr_card, card_w, card_h
DEBUG card_w+"\n"
DEBUG card_h+"\n"
IF card_w=0 OR card_h=0
        DEBUG "card not loaded!\n"
        END
ENDIF


//loading player
//NOTE: all the graphics from Draco by Puli Games (c)
LOADSPRITE "player0.png", spr_player

//loading blobs
LOADSPRITE "blob.png", spr_blob
LOADSPRITE "blobinv.png", spr_blob+1
LOADSPRITE "blobtrans.png", spr_blob+2

//creating screens
CREATESCREEN 5, 250, scr_w, scr_h
CREATESCREEN 6, 251, scr_w, scr_h

//gameloop
WHILE KEY(1)=0
        //prepare the gui, and catch all the interesting keyboard and mouse events
        gui.prepare()
       
        //render the background
        ALPHAMODE 0
        rendermap()
       
        IF lightrays
                //render ray of lights
                USESCREEN 5
                CLEARSCREEN
               
                //initial light source
                ALPHAMODE (alpha-100)/100.0
                PolySprite( spr_blob+nblob, scr_wf-plr_x+1000, scr_hf-plr_y+1050, scale/10.0, scale/10.0, RGB(r,g,b),0.5,0.5,0.0)
               
                //overlapping player sprite rendered in black
                ALPHAMODE 0
                PolySprite( spr_player, scr_wf+plr_x-1000, scr_hf+plr_y-1050, 0.5, 0.5, RGB(0,0,0),0.5,0.5,0.0)
               
                //now we have the light source with some covering black image in it (the player)
               
                //this is the trick
                //copying the same image to itself, but zooming it bigger every time
                //we have to use two screens, and wsitching them.
                //IF you using only one AND copying it on itself, you get unexpected result
                LOCAL m
                LOCAL n
                FOR i=1 TO (iter)*2 //start from odd (1), end to even (3,5,7,etc.)!
                        m=MOD(i,2)      //this is the destination screen
                        n=1-m           //this is the source screen
                        USESCREEN 5+m   //we want draw into the destination screen
                        m=250+m
                        n=250+n
                        //copy the whole source screen                 
                        DRAWSPRITE n, 0, 0
                        //then draw again the source screen but zoom it and blend                      
                        ALPHAMODE (alpha-100)/100.0
                        PolySprite( n, scr_wf, scr_hf, 1+(i)/(raystep+1), 1+(i)/(raystep+1), RGB(r,g,b),0.5,0.5,0.0)
                NEXT
               
                //back to normal screen
                USESCREEN -1
               
                IF LightSource
                        //a strong additional light to the background, only for fun
                        ALPHAMODE (190-100)/100.0
                        PolySprite( spr_blob, scr_wf-plr_x+1000, scr_hf-plr_y+1050, scale/10.0, scale/10.0, RGB(r,g,b),0.5,0.5,0.0)            
                ENDIF

                //blend the raylight screen
                ALPHAMODE (alpha2-100)/100.0
                PolySprite( 250, scr_wf, scr_hf, 1, 1, RGB(r,g,b),0.5,0.5,0.0)
               
                //player
                ALPHAMODE 0
                PolySprite( spr_player, scr_wf+plr_x-1000, scr_hf+plr_y-1050, 0.5, 0.5, RGB(255,255,255),0.5,0.5,0.0)
               
        ELSE
                //player       
                PolySprite( spr_player, scr_wf, scr_hf, 0.5, 0.5, RGB(255,255,255),0.5,0.5,0.0)
                //blend
                ALPHAMODE (alpha-100)/100.0
                PolySprite( spr_blob+nblob, scr_wf, scr_hf, scale/10.0, scale/10.0, RGB(r,g,b),0.5,0.5,0.0)
        ENDIF
       
        //draw GUI
        ALPHAMODE 0
        LOCAL color
        IF showGUI
                IF nblob=0
                        color=RGB(128,255,128)
                ELSE
                        color=RGB(64,64,64)
                ENDIF
                IF button(1, 5, 5, 110, 20, color, "blob.png")
                        nblob=0
                ENDIF
                IF nblob=1
                        color=RGB(128,255,128)
                ELSE
                        color=RGB(64,64,64)
                ENDIF
                IF button(2, 115, 5, 110, 20, color, "blobinv.png")
                        nblob=1
                ENDIF
                IF nblob=2
                        color=RGB(128,255,128)
                ELSE
                        color=RGB(64,64,64)
                ENDIF
                IF button(3, 225, 5, 110, 20, color, "blobtrans.png")
                        nblob=2
                ENDIF
                sliderH(5, 5, 30, 400, 200, alpha)
                PRINT FORMAT$(2,1,alpha-100)+"% alpha", 450,30, TRUE
                IF button(9, 420, 30, 20, 20, RGB(255,255,0), "0") THEN alpha=100
                sliderH(6, 5, 50, 400, 400, scale)
                PRINT FORMAT$(2,1,scale/10.0)+"% scale", 420,50, TRUE
                sliderH(10, 5, 70, 255, 255, r)
                PRINT "R "+r, 270,70, TRUE
                sliderH(11, 5, 90, 255, 255, g)
                PRINT "G "+g, 270,90, TRUE
                sliderH(12, 5, 110, 255, 255, b)
                PRINT "B "+b, 270,110, TRUE
                IF lightrays
                        color=RGB(128,255,128)
                ELSE
                        color=RGB(64,64,64)
                ENDIF
                IF button(13, 5, 130, 110, 18, color, "Light Rays")
                        lightrays = 1-lightrays
                ENDIF
                IF LightSource
                        color=RGB(128,255,128)
                ELSE
                        color=RGB(64,64,64)
                ENDIF
                IF button(14, 150, 130, 110, 18, color, "Light Source")
                        LightSource = 1-LightSource
                ENDIF          
                sliderH(15, 5, 150, 200, 20, iter)
                iter = INTEGER(iter)
                PRINT (iter)*2+" iterations", 215,150, TRUE
                sliderH(16, 5, 170, 200, 20, raystep)
                raystep = INTEGER(raystep)
                PRINT (raystep+1)+" ray step", 215,170, TRUE                                   
                sliderH(17, 5, 190, 400, 200, alpha2)
                PRINT FORMAT$(2,1,alpha2-100)+"% alpha2", 450,190, TRUE
                IF button(18, 420, 190, 20, 20, RGB(255,255,0), "0") THEN alpha2=100
                IF controlsheme=0
                        IF button(20, 5, 220, 120, 20, RGB(255,100,100), "Keyboard") THEN controlsheme=1
                ELSE
                        IF button(20, 5, 220, 120, 20, RGB(255,100,100), "Mouse") THEN controlsheme=0
                ENDIF                          
        ENDIF
        //draw buttons to bottom. Presets
        IF button(50, 5, scr_h-30, 50, 20, RGB(0,255,0), "GUI") THEN showGUI=NOT showGUI
        IF button(51, 105, scr_h-30, 90, 20, RGB(255,255,0), "Light")
                nblob=0
                alpha=145
                r=255
                g=255
                b=255
                scale=20
                alpha2=200
        ENDIF
        IF button(52, 205, scr_h-30, 90, 20, RGB(255,255,0), "Sun")
                nblob=1
                alpha=145
                r=255
                g=240
                b=180
                scale=20
                alpha2=200
        ENDIF
        IF button(53, 305, scr_h-30, 90, 20, RGB(255,255,0), "Light+dark")
                nblob=1
                alpha=5
                r=255
                g=255
                b=255
                iter=5
                scale=40
                alpha2=200
        ENDIF
        IF button(54, 405, scr_h-30, 90, 20, RGB(255,255,0), "Laser1")
                nblob=2
                alpha=200
                r=255
                g=255
                b=255
                iter=5
                scale=70
                alpha2=0
        ENDIF
        IF button(55, 505, scr_h-30, 90, 20, RGB(255,255,0), "Laser2")
                nblob=2
                alpha=200
                r=255
                g=255
                b=255
                iter=5
                scale=70
                alpha2=200
        ENDIF

        //move player
        IF controlsheme=0
                IF gui.up THEN DEC plr_y
                IF gui.down THEN INC plr_y
                IF gui.left THEN DEC plr_x
                IF gui.right THEN INC plr_x
        ELSE
                plr_x = gui.mousex + 1000 - scr_wf
                plr_y = gui.mousey + 1050 - scr_hf
        ENDIF  
        SHOWSCREEN
       
        gui.finish()
WEND

//simplified render function from Draco
FUNCTION rendermap:
        LOCAL x=plr_x-scr_wf, y=plr_y-scr_hf
        LOCAL mx%=x/card_w, my%=y/card_h
        LOCAL cx, cy
        cx=mx*card_w-x
        cy=my*card_h-y
        WHILE my<10 AND cy<scr_h
                IF (mx>=0 AND my>=0 AND mx<10 AND my<10)
                        DRAWSPRITE map[mx][my], cx, cy
                ENDIF
                INC mx, 1
                INC cx, card_w
                IF mx>scr_w
                        mx=x/card_w
                        cx=mx*card_w-x
                        INC my, 1
                        INC cy, card_h
                ENDIF
        WEND
ENDFUNCTION

//made for blobmondter by Bence Dobos

//Draw and colorize a sprite. You can set the handle point, rotation, scale and color of the sprite
//Written by Bence Dobos
//spr - the ID of the sprite
//scalex, scaley - the ratio of the sprite scale [0.0-inf]
//color - 0xffffff is the normal color
//xc,yc - the ratio of the handle point of the sprite [0.0-1.0], this point is used to draw the sprite, rotate and scale. 0,0 is the top-left point, 0.5,0.5 is the center point
//rot - rotation of the sprite [0-360]
//w,h - width, height of the sprite in pixel, if not specified it's determined automatically
FUNCTION PolySprite: spr, x, y, scalex, scaley, color=0xffffff, xc=0.0, yc=0.0, rot=0, w=-1, h=-1
        IF w=-1
                GETSPRITESIZE spr, w, h
        ENDIF
        LOCAL w2=w*scalex
        LOCAL h2=h*scaley
        LOCAL xcenter=x+xc*w2
        LOCAL ycenter=y+yc*h2
        LOCAL xr1=-xc*w2
        LOCAL yr1=-yc*h2
        LOCAL xr2=(1.0-xc)*w2
        LOCAL yr2=-yc*h2
        LOCAL xr3=(1.0-xc)*w2
        LOCAL yr3=(1.0-yc)*h2
        LOCAL xr4=-xc*w2
        LOCAL yr4=(1.0-yc)*h2

        LOCAL x1, y1, x2, y2
        LOCAL x3, y3, x4, y4
        IF rot<>0
                LOCAL sp = SIN(rot)
                LOCAL cp = COS(rot)
                x1 = xr1*cp-yr1*sp+x
                y1 = xr1*sp+yr1*cp+y
                x2 = xr2*cp-yr2*sp+x
                y2 = xr2*sp+yr2*cp+y
                x3 = xr3*cp-yr3*sp+x
                y3 = xr3*sp+yr3*cp+y
                x4 = xr4*cp-yr4*sp+x
                y4 = xr4*sp+yr4*cp+y
        ELSE
                x1=xr1+x
                y1=yr1+y
                x2=xr2+x
                y2=yr2+y
                x3=xr3+x
                y3=yr3+y
                x4=xr4+x
                y4=yr4+y
        ENDIF

         STARTPOLY spr
          POLYVECTOR   x1, y1,  0,  0, color
          POLYVECTOR   x2, y2,  w,  0, color
          POLYVECTOR   x3, y3,  w,  h, color
          POLYVECTOR   x4, y4,  0,  h, color
         ENDPOLY
ENDFUNCTION
 

About IMGUI: http://www.glbasic.com/forum/index.php?topic=5431.0
« Last Edit: 2011-Sep-21 by Albert »

Offline Ian Price

  • Administrator
  • Prof. Inline
  • *******
  • Posts: 4144
  • On the shoulders of giants.
    • View Profile
    • My Apps
Re: Ray of lights
« Reply #2 on: 2011-Sep-21 »
That's really cool. Nice one =D
I came. I saw. I played.

Offline Albert

  • Dr. Type
  • ****
  • Posts: 257
    • View Profile
    • Blog
Re: Ray of lights
« Reply #3 on: 2011-Sep-21 »
Changed the program a bit to adapt to the Galaxy S 800x480 resolution. Running fast on android.
However IMGUI not so good with touchscreen.

Offline bigsofty

  • Community Developer
  • Prof. Inline
  • ******
  • Posts: 2605
    • View Profile
Re: Ray of lights
« Reply #4 on: 2011-Sep-21 »
It's lovely affect, had fun just messing around with the params! ;)
Cheers,

Ian.

“It is practically impossible to teach good programming style to students that have had prior exposure to BASIC.  As potential programmers, they are mentally mutilated beyond hope of regeneration.”
(E. W. Dijkstra)

Offline Nathan

  • Mr. Polyvector
  • ***
  • Posts: 116
    • View Profile
Re: Ray of lights
« Reply #5 on: 2011-Sep-21 »
I agree with the above, superb work!

Offline Marmor

  • Community Developer
  • Prof. Inline
  • ******
  • Posts: 908
  • 96A285CC
    • View Profile
    • my youtube channel
Re: Ray of lights
« Reply #6 on: 2011-Sep-21 »
thx a lot ! great work

Offline Wampus

  • Prof. Inline
  • *****
  • Posts: 1004
    • View Profile
Re: Ray of lights
« Reply #7 on: 2011-Sep-21 »
Very cool

Offline Albert

  • Dr. Type
  • ****
  • Posts: 257
    • View Profile
    • Blog
Re: Ray of lights
« Reply #8 on: 2011-Sep-22 »
You can create a whole bunch of light sources if you want, this not affect the speed, only the number of iteration and the screen's resolution.

So change the rows after the comment //initial light source

Code: GLBasic [Select]
                //initial light source
                ALPHAMODE (alpha-100)/100.0
                //PolySprite( spr_blob+nblob, scr_wf-plr_x+1000, scr_hf-plr_y+1050, scale/10.0, scale/10.0, RGB(r,g,b),0.5,0.5,0.0)
                DRAWRECT scr_wf-plr_x+1000 - 100, scr_hf-plr_y+1050 - 150, 50,50, RGB(255, 255, 255)
                DRAWRECT scr_wf-plr_x+1000 - 50, scr_hf-plr_y+1050 + 100, 200,20, RGB(255, 255, 255)
                DRAWRECT scr_wf-plr_x+1000 - 10, scr_hf-plr_y+1050 - 100, 30, 30, RGB(100, 100, 255)
                DRAWRECT scr_wf-plr_x+1000 + 100, scr_hf-plr_y+1050 + 50, 50,50, RGB(255, 0, 255)
                DRAWRECT scr_wf-plr_x+1000 + 10, scr_hf-plr_y+1050 + 100, 200,50, RGB(255, 255, 255)
                DRAWRECT scr_wf-plr_x+1000 + 0, scr_hf-plr_y+1050 - 50, 20, 20, RGB(100, 100, 255)
 

This code draw some rectangles:


And with the ray light effect:


Oh this is very rough, even if you push up the iterations and the ray step parameters. It's cool if you use soft shapes, but very jaggy with theese rectangles.
Would be nice some sort of blur. It's easy to implement, just draw the screen to a temporary buffer, but scale it down (lower the resolution) then scale it back and draw.
To achieve this we need a new screen:
//creating screens
CREATESCREEN 5, 250, scr_w, scr_h
CREATESCREEN 6, 251, scr_w, scr_h
CREATESCREEN 7, 252, scr_wf, scr_hf

and change the iteration:
      //this is the trick
      //copying the same image to itself, but zooming it bigger every time
      //we have to use two screens, and wsitching them.
      //IF you using only one AND copying it on itself, you get unexpected result

      LOCAL o
      LOCAL m
      LOCAL n
      FOR i=1 TO (iter)*2 //start from odd (1), end to even (3,5,7,etc.)!
         o=MOD(i,2)   //this is the destination screen
         n=1-o      //this is the source screen
         USESCREEN 5+o   //we want draw into the destination screen
         m=250+o
         n=250+n
         //copy the whole source screen
         DRAWSPRITE n, 0, 0
         //blur
         USESCREEN 7
         STRETCHSPRITE n, 0, 0, scr_wf/i, scr_hf/i      

         //then draw again the source screen but zoom it and blend
         USESCREEN 5+o         
         ALPHAMODE (alpha-100)/100.0
         //PolySprite( n, scr_wf, scr_hf, 1+(i)/(raystep+1), 1+(i)/(raystep+1), RGB(r,g,b),0.5,0.5,0.0)
         PolySprite( 252, scr_wf, scr_hf, (1+(i)/(raystep+1))*i*2, (1+(i)/(raystep+1))*i*2, RGB(r,g,b),0.5,0.5,0.0, scr_wf/i, scr_hf/i)
      NEXT

Also change the draw order, draw the player before the completed ray light sprite.


« Last Edit: 2011-Sep-22 by Albert »

Offline Schranz0r

  • Premium User :)
  • Administrator
  • Prof. Inline
  • *******
  • Posts: 5013
  • O Rly?
    • View Profile
Re: Ray of lights
« Reply #9 on: 2011-Sep-23 »
WOW... nothing more to say!
I <3 DGArray's :D

PC:
AMD RYzen 7 1700 @3.9Ghz, 16GB HyperX Fury 2666Mhz Ram, ASUS ROG GTX 1060 STRIX 6GB, Windows 10 Pro 64Bit, MSi Tomahawk B350 Mainboard

Offline mentalthink

  • Prof. Inline
  • *****
  • Posts: 3363
  • Integrated Brain
    • View Profile
Re: Ray of lights
« Reply #10 on: 2011-Sep-27 »
Awesome!!!, only a question, I can implement part of your code in my developement, I think this effect, can be abosulty brutal in my game.

Kinds Regards,
Iván J.

PS: I test whit animates Sprite and it´s abosulutely a beatifull for look.
« Last Edit: 2011-Sep-27 by mentalthink »

Offline Albert

  • Dr. Type
  • ****
  • Posts: 257
    • View Profile
    • Blog
Re: Ray of lights
« Reply #11 on: 2011-Sep-28 »
Iván of yourse you can! I would love to see what you guys can do with this effect.
I experimented with bloom effect, and I tried to add some very simple shader, but it's really buggy. Are you interested? It would be nice if somebody could fix my shader...

Offline mentalthink

  • Prof. Inline
  • *****
  • Posts: 3363
  • Integrated Brain
    • View Profile
Re: Ray of lights
« Reply #12 on: 2011-Sep-28 »
Quote
I experimented with bloom effect, and I tried to add some very simple shader, but it's really buggy. Are you interested? It would be nice if somebody could fix my shader...

 :nw: :nw: :nw: , We are speaking in 3D?¿, Sure my friend, I goes crazy for have a 3d Bloom effect, this can be absolutelly brutal.

If you can do, and not it´s too much disturb, for me will be great have a set of shaders.... or only the bloom FX

Thanks again, for your code, and  for permet the use in my game....

Kinds Regards,
Iván J.
« Last Edit: 2011-Sep-28 by mentalthink »

Offline Albert

  • Dr. Type
  • ****
  • Posts: 257
    • View Profile
    • Blog
Re: Ray of lights
« Reply #13 on: 2011-Sep-28 »
2D

Offline mentalthink

  • Prof. Inline
  • *****
  • Posts: 3363
  • Integrated Brain
    • View Profile
Re: Ray of lights
« Reply #14 on: 2011-Sep-28 »
Ok, it´s perfect too!!!, thanks again.