Author Topic: Mandelbrot viewer with colour cycling  (Read 2468 times)

Offline fuzzy70

  • Community Developer
  • Prof. Inline
  • ******
  • Posts: 828
  • Look left, Look right, LOOK OUT!!
    • View Profile
Done more as a exercise than anything else  :D

I get 29fps @ 640x480 which is higher than I expected on my core 2 duo 2.13ghz & crappy gfx card, considering the amount of array modifying & MEM2SPRITE calls. There is probably a far better way of doing it but this is the only way that has popped into my head at the moment.

Do not change the MAX_ITERATION% variable as I have not got round to scaling the fractal data to a 0-255 colour range as yet. Also the MinY & MaxY coords are reversed when they are read into the type due to the image was flipped compared to winfracts output, so I assume winfract treats Y=0 as the bottom of the window & not top.

keys are as follows (although are commented in the code)

F1 = Start colour cycling
F2 = Stop colour cycling
F3 = Previous Fractal point (4 available)
F4 = Next Fractal point (4 available)
Cursor Up = cycle colours up
Cursor Down = cycle colours down
Cursor Left = previous palette
Cursor Right = next palette
Spacebar = Reload the pallette back to defaults (after cycling)

Have fun

Lee

Code: GLBasic [Select]
TYPE Tpalette
        red%[256]
        green%[256]
        blue%[256]
        memcolour[256]                  // MEM2SPRITE friendly values :)
        total%
        name$

        FUNCTION cycle_memcolours: dir

                LOCAL loop%,temp%

                SELECT dir

                CASE 1

                        temp%=self.memcolour%[0]
                        FOR loop = 1 TO 255
                                self.memcolour%[loop%-1]=self.memcolour%[loop%]
                        NEXT
                        self.memcolour%[255]=temp

                CASE 0

                        temp%=self.memcolour%[255]
                        FOR loop = 255 TO 1 STEP -1
                                self.memcolour%[loop%]=self.memcolour%[loop%-1]
                        NEXT
                        self.memcolour%[0]=temp
                ENDSELECT

        ENDFUNCTION

ENDTYPE

TYPE Tfrac_coords
        MinX#
        MaxX#
        MinY#
        MaxY#
ENDTYPE

CONSTANT up_cursor%=200
CONSTANT down_cursor%=208
CONSTANT left_cursor%=203
CONSTANT right_cursor%=205
CONSTANT F1%=59
CONSTANT F2%=60
CONSTANT F3%=61
CONSTANT F4%=62
CONSTANT SPC%=57

GLOBAL palette[] AS Tpalette
GLOBAL frac_coords[] AS Tfrac_coords
GLOBAL Width%=640,Height%=480
GLOBAL screencolours%[]
GLOBAL screen%[]
GLOBAL currpal%=0
GLOBAL fracount%

LOCAL starttime,endtime,totaltime,fx%,fy%
LOCAL cyclestate%=0,cycledir%=0,curfract%=0

DIM screencolours%[Width%*Height%]
DIM screen%[Width%*Height%]

SETSCREEN Width%,Height%,0
SETCURRENTDIR("Media") // go to media files
LOADFONT "font.png",0
GETFONTSIZE fx%,fy%

loadpalette("palettedata.dat")
readfractcoords()
//draw initial set

calc_mandel(frac_coords[curfract%].MinX#,frac_coords[curfract%].MaxX#,frac_coords[curfract%].MinY#,frac_coords[curfract%].MaxY#)


WHILE NOT KEY(1)

        starttime=GETTIMERALL()

        IF KEY(up_cursor) THEN cycledir%=1                                              // UP cursor = cycle colours up
        IF KEY(down_cursor) THEN cycledir%=0                                    // Down cursor = cycle colours down

        IF KEY(right_cursor) AND currpal%<palette[0].total%-1   // Right cursor = next palette
                INC currpal%,1
                refresh_sprite()
                SLEEP 200
        ENDIF

        IF KEY(left_cursor) AND currpal%>0                                              // Left cursor = previous palette
                DEC currpal%,1
                refresh_sprite()
                SLEEP 200
        ENDIF

        IF KEY(F1) THEN cyclestate%=1                                                   // F1 = Start Cycle colours
        IF KEY(F2) THEN cyclestate%=0                                                   // F2 = Stop Cycle colours

        IF KEY(F3) AND curfract%>0                                                              // F3 = Previous fractal
                DEC curfract%,1
                calc_mandel(frac_coords[curfract%].MinX#,frac_coords[curfract%].MaxX#,frac_coords[curfract%].MinY#,frac_coords[curfract%].MaxY#)
        ENDIF

        IF KEY(F4) AND curfract%<fracount%-1                                    // F4 = Next fractal
                INC curfract%,1
                calc_mandel(frac_coords[curfract%].MinX#,frac_coords[curfract%].MaxX#,frac_coords[curfract%].MinY#,frac_coords[curfract%].MaxY#)
        ENDIF

        IF KEY(SPC)                                                                                     // Press space to reload default palette
                loadpalette("palettedata.dat")
                refresh_sprite()
        ENDIF

        IF cyclestate%=1
                palette[currpal%].cycle_memcolours(cycledir%)
                refresh_sprite()
        ENDIF

        DRAWSPRITE 10,0,0
        totaltime=1000/(GETTIMERALL()-starttime)
        PRINT "FPS="+INTEGER(totaltime),0,0,1
        PRINT "Current palette="+currpal%,0,fx%,1
        PRINT "Palette Name="+palette[currpal%].name$,0,fx%*2,1

        SHOWSCREEN

WEND

KEYWAIT

FUNCTION calc_mandel: MinX#,MaxX#,MinY#,MaxY#

        LOCAL dx#,dy#,x%,y%

        dx=(MaxX-MinX)/Width%
        dy=(MaxY-MinY)/Height%

        FOR y=0 TO Height%-1

                FOR x=0 TO Width%-1
                        screencolours%[x+(y*Width%)]=calc_pixel(MinX+x*dx,MinY+y*dy)
                        screen%[x+(y*Width%)]=palette%[currpal%].memcolour[screencolours%[x+(y*Width%)]]
                NEXT

        NEXT

        MEM2SPRITE(screen%[],10,Width%,Height%)

ENDFUNCTION

FUNCTION calc_pixel: CA#,CBi#

        LOCAL MAX_ITERATION%=255
        LOCAL OLD_A#
        LOCAL ITERATION%
        LOCAL A#,Bi#
        LOCAL LENGTH_Z#

        A=0
        Bi=0

        ITERATION=0

        REPEAT

                OLD_A=A

                A=A*A-Bi*Bi+CA
                Bi=2*OLD_A*Bi+CBi

                LENGTH_Z=A*A+Bi*Bi

                IF ITERATION > MAX_ITERATION THEN RETURN MAX_ITERATION
                INC ITERATION
        UNTIL LENGTH_Z > 4

        RETURN ITERATION-1

ENDFUNCTION

FUNCTION refresh_sprite:

        LOCAL x%,y%

        FOR y=0 TO Height%-1
                FOR x=0 TO Width%-1
                        screen%[x+(y*Width%)]=palette%[currpal%].memcolour[screencolours%[x+(y*Width%)]]
                NEXT
        NEXT
        MEM2SPRITE(screen%[],10,Width%,Height%)
ENDFUNCTION

FUNCTION loadpalette: filename$

        LOCAL palcount%,namesize%,palname$,r%,g%,b%,pal_loop%,col_loop%

        OPENFILE (1,filename$,TRUE)
        READUBYTE 1,palcount
        DIM palette[palcount]

        palette[0].total%=palcount

        FOR pal_loop=0 TO palcount-1

                READUBYTE 1,namesize
                READSTR 1,palname$,namesize
                palette[pal_loop].name$=palname$

                FOR col_loop=0 TO 255
                        READUBYTE 1,r%
                        palette[pal_loop].red%[col_loop]=r
                        READUBYTE 1,g%
                        palette[pal_loop].green%[col_loop]=g
                        READUBYTE 1,b%
                        palette[pal_loop].blue%[col_loop]=b
                        palette[pal_loop].memcolour[col_loop]=RGB(r,g,b)+INTEGER(0xff000000)
                NEXT

        NEXT

        CLOSEFILE 1

ENDFUNCTION

FUNCTION drawpalette: id%

        LOCAL x%,y%,r%,g%,b%,cur_colour%

        PRINT palette[id].name$,0,10

        FOR y=0 TO 15
                FOR x=0 TO 15
                        r=palette[id].red%[cur_colour%]
                        g=palette[id].green%[cur_colour%]
                        b=palette[id].blue%[cur_colour%]

                        DRAWRECT x*16,(y*16)+20,15,15,RGB(r,g,b)

                        INC cur_colour%,1
                NEXT
        NEXT

ENDFUNCTION

FUNCTION readfractcoords:

        LOCAL amount%,loop%,value#

        RESTORE fracdata
        READ amount%
        fracount%=amount%
        DIM frac_coords[amount%]

        FOR loop%=0 TO amount%-1
                READ value#
                frac_coords[loop%].MinX#=value#
                READ value#
                frac_coords[loop%].MaxX#=value#
                READ value#
                frac_coords[loop%].MaxY#=value#
                READ value#
                frac_coords[loop%].MinY#=value#
                DEBUG frac_coords[loop%].MinX#+"\n"
                DEBUG frac_coords[loop%].MaxX#+"\n"
                DEBUG frac_coords[loop%].MinY#+"\n"
                DEBUG frac_coords[loop%].MaxY#+"\n"
        NEXT
ENDFUNCTION


STARTDATA fracdata:
DATA 4
DATA -2.500000000000,1.499999660000,-1.499999730000,1.500000000000
DATA -1.611111110000,-0.985133316000,0.194154827000,0.663883090000
DATA -1.204480370000,-1.190686790000,0.309634963000,0.319990810000
DATA -0.655607441000,-0.649605315000,0.492290244000,0.496800002000
ENDDATA

 

[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)

Offline Hemlos

  • To boldy go where no pixel has gone before!
  • Global Moderator
  • Prof. Inline
  • *******
  • Posts: 1634
  • Particle Hawk
    • View Profile
Re: Mandelbrot viewer with colour cycling
« Reply #1 on: 2012-Nov-03 »
Volume_of_Earth(km^3) = 4/3*3.14*POW(6371.392896,3)

Offline Ian Price

  • Administrator
  • Prof. Inline
  • *******
  • Posts: 4147
  • On the shoulders of giants.
    • View Profile
    • My Apps
Re: Mandelbrot viewer with colour cycling
« Reply #2 on: 2012-Nov-03 »
That is incredibly neat - I love the "firestorm" palette and the "blues" on the zoomed in "tentacles" - the blues makes it look like ice/frost is forming.

Nice one :)
I came. I saw. I played.

Offline fuzzy70

  • Community Developer
  • Prof. Inline
  • ******
  • Posts: 828
  • Look left, Look right, LOOK OUT!!
    • View Profile
Re: Re: Mandelbrot viewer with colour cycling
« Reply #3 on: 2012-Nov-03 »
That is incredibly neat - I love the "firestorm" palette and the "blues" on the zoomed in "tentacles" - the blues makes it look like ice/frost is forming.

Nice one :)

Thanks Ian, I done it more as a test for playing around with. The FPS was a lot higher than expected which means colour cycled sprites like small logos or highscore tables etc should be possible without a big performance hit.

Lee

Sent from my GT-I5700 using Tapatalk 2

"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)