10.03.2019 - Round 1 results of our "A Love Letter For FreeBASIC" game dev competition have been published. Please be sure to check the results thread: http://games.freebasic.net/forum/index.php?topic=629.0. Don't forget that the competition is continuing with a round 2, lasting till 29th of April, 300 USD first prize. Stay tuned!

Author Topic: Rotate images?  (Read 9396 times)

N3trunn3r

  • Novice
  • ***
  • Posts: 73
    • View Profile
Rotate images?
« on: January 21, 2012, 02:19:50 PM »
I wanted to work now with "rotate image". What is there out on the flee-market that is valuable? ;)
Would like to rotate the images in real time(fast), I need the code to accept alpha channel(yea that would be awesome) and rotation filter. So the rotated images won't look clumsy.

That are a lot of demands for one day, I know! But what should I say...
Can anyone help? Has anyone experience with this? 8)
In return I will post later on an alpha of the game I'm making from it ;D

N3trunn3r

  • Novice
  • ***
  • Posts: 73
    • View Profile
Re: Rotate images?
« Reply #1 on: January 22, 2012, 04:23:08 AM »
I tried multiput but is has no rotation smooth filter...

Lachie Dazdarian

  • Double dipper
  • Administrator
  • Forum Sage
  • *****
  • Posts: 1308
    • Yahoo Instant Messenger - lachie13
    • View Profile
    • The Maker Of Stuff
    • Email
Re: Rotate images?
« Reply #2 on: January 22, 2012, 10:32:33 AM »
I guess converting your project to OpenGL wouldn't be of interest to you? Try relsoft's GL2D wrapper perhaps.
"Things like Basic and Free Basic provide much-needed therapy and a return to sanity and a correct appreciation of people. The arrogant folk really hate a word like 'Basic' - fine, and good riddance." ~ pragmatist

N3trunn3r

  • Novice
  • ***
  • Posts: 73
    • View Profile
Re: Rotate images?
« Reply #3 on: January 22, 2012, 03:17:30 PM »
I think I have no choice for now. Lets check out the Tutorial in BG#3 :D - I have all night baby... ;D

By the way, the reason I didn't want GL was I wanted to compile to DOS too, so that I could use DosBox on it so you would be able to play on a Mac...
« Last Edit: January 22, 2012, 03:20:10 PM by N3trunn3r »

Lachie Dazdarian

  • Double dipper
  • Administrator
  • Forum Sage
  • *****
  • Posts: 1308
    • Yahoo Instant Messenger - lachie13
    • View Profile
    • The Maker Of Stuff
    • Email
"Things like Basic and Free Basic provide much-needed therapy and a return to sanity and a correct appreciation of people. The arrogant folk really hate a word like 'Basic' - fine, and good riddance." ~ pragmatist

N3trunn3r

  • Novice
  • ***
  • Posts: 73
    • View Profile
Re: Rotate images?
« Reply #5 on: January 24, 2012, 02:45:32 PM »
Jay found that too, I'm already making progress :D

Dr_D

  • Forum Sage
  • *****
  • Posts: 257
    • Yahoo Instant Messenger - dr_davenstein
    • View Profile
    • Dr_D's apps
    • Email
Re: Rotate images?
« Reply #6 on: May 13, 2012, 08:17:01 PM »
Looks like I was late! :p

This one is in an archive and comes with all kinds of tests and an image & stuff...
http://jafile.com/uploads/dr_d/rotozoom.zip



This "wankerput" one works more like multiput, but it has better quality, since it uses some sub-pixel stuff... I prefer it, but it also requires the image dimensions be a power of two. It doesn't have to be square, per se... but each dimension does need to be a power of two.
Code: [Select]
   #include "fbgfx.bi"

    declare sub wankerput(byval dst as fb.image ptr = 0, byval src as fb.image ptr, byval posx as integer, byval posy as integer, byval angle as single, byval scalex as single, byval scaley as single, byval transcol as uinteger = 0 )

    dim as integer scr_w = 640
    dim as integer scr_h = 480
    dim as integer scr_w2 = scr_w\2
    dim as integer scr_h2 = scr_h\2

    screenres scr_w, scr_h, 32,,FB.GFX_HIGH_PRIORITY

    dim shared as integer fnum
    fnum = freefile
    dim as integer iw, ih

    dim as string filename = "texture7.bmp"

    open filename for binary as #fnum
       get #fnum,19,iw
       get #fnum,23,ih
    close #fnum

    if iw = 0 or ih = 0 then
       iw = 256
       ih = 128
    end if

    dim as FB.IMAGE ptr image = imagecreate( iw, ih )


    if bload( filename, image) <> 0 then

       for y as integer = 0 to ih - 1
          for x as integer = 0 to iw - 1
             pset image,(x,y),x xor y
          next
       next  
      
       filename = "^^^I'M WITH STUPID^^^"
       draw string image, ((iw\2) - len(filename)*4, ih\2), filename, &hffffff00
      
    end if

    dim as double otime = timer

    dim as double ttime, ftime
    dim as integer fps
    dim as string fps_string
    dim as single scalarx = 2, scalary = 2, ang


    do

       ttime = timer - otime
       otime = timer
       ang += ttime
      
       scalarx = 5+10*sin(ang*1.3)
       scalary = 5+10*sin(ang/2.1)

       screenlock
       cls
      
       wankerput( , image, scr_w2, scr_h2, ang, scalarx, scalary, rgba(255,0,255,255) )

       locate 1,1
       print fps_string

       screenunlock

       fps+=1

       if otime>ftime then
          ftime = timer+1
          fps_string = "FPS " & fps
          fps = 0
       end if

       sleep 3,1

    loop until multikey(FB.SC_ESCAPE)


    sub wankerput( byval dst as fb.image ptr = 0, byval src as fb.image ptr, byval posx as integer, byval posy as integer, byval angle as single, byval scalex as single, byval scaley as single, byval transcol as uinteger = 0 )

       'wankerput by Dr_D
       'yet another sprite rotation algo
       'this one actually renders 2 triangles with subpixel/texel accuracy
       'it works like gl_quad, you can stretch on either axis and it will hold it's integrity
       'it wont skew like a rotozoomer
       'credit's to yetifoot for help with the asm optimization and bug hunting :)

       if src = 0 then exit sub

       dim as single dy = any, dxdy1 = any, dxdy2 = any, dxdy3 = any
       dim as single xa = any, xb = any, uiza = any, viza = any
       dim as single dxdya = any, dxdyb = any, dizdya = any, duizdya = any, dvizdya = any
       dim as single u = any, v = any, uiz = any, viz = any, dn = any
       dim as single x1 = any, y1 = any, x2 = any, y2 = any, x3= any, y3= any
       dim as single uiz1 = any, viz1 = any
       dim as single uiz2 = any, viz2 = any
       dim as single uiz3 = any, viz3 = any
       dim as single dizdx = any, dizdy = any
       dim as single duizdx = any, dvizdx = any
       dim as single duizdy = any, dvizdy = any
       dim as single y2my1 = any, y3my1 = any, y3my2 = any, x2mx1 = any, x3mx1 = any, x3mx2 = any
       dim as integer y1i = any, y2i = any, y3i = any
       dim as integer sx = any, ex = any, order = any, jumpvar = any, shlonger = any
       dim as integer sy = any, ey = any, scr_h = any, scr_w = any

       dim as uinteger ptr srcptr = cast( uinteger ptr, src + 1 )
       dim as uinteger ptr dstptr

       if dst = 0 then
          dstptr = screenptr
          screeninfo scr_w, scr_h
       else
          dstptr = cast( uinteger ptr, dst+1)
          scr_w = dst->width
          scr_h = dst->height
       end if

       dim as integer spitch = src->pitch
       dim as integer sbpp = src->bpp
       dim as integer sw = src->width-1
       dim as integer sh = src->height-1
       dim as uinteger shifter = log(spitch) / log(2)
      
       dim as integer scalarx = (src->width\2)*scalex
       dim as integer scalary = (src->height\2)*scaley

       dim as single tc = cos(angle)
       dim as single ts = sin(angle)

       dim as single otx1 = -scalarx
       dim as single oty1 = -scalary
       dim as single otx2 = -scalarx
       dim as single oty2 = scalary
       dim as single otx3 = scalarx
       dim as single oty3 = -scalary
       dim as single otx4 = scalarx
       dim as single oty4 = scalary

       dim as single tx1 = (otx1 * tc - oty1 * ts) + posx
       dim as single ty1 = (oty1 * tc + otx1 * ts) + posy
       dim as single tx2 = (otx2 * tc - oty2 * ts) + posx
       dim as single ty2 = (oty2 * tc + otx2 * ts) + posy
       dim as single tx3 = (otx3 * tc - oty3 * ts) + posx
       dim as single ty3 = (oty3 * tc + otx3 * ts) + posy
       dim as single tx4 = (otx4 * tc - oty4 * ts) + posx
       dim as single ty4 = (oty4 * tc + otx4 * ts) + posy

       for order = 0 to 1

          select case order

             case 0
                x1 = tx1+.5f
                y1 = ty1+.5f
                x2 = tx2+.5f
                y2 = ty2+.5f
                x3 = tx3+.5f
                y3 = ty3+.5f

                uiz1 = 0
                viz1 = 0
                uiz2 = 0
                viz2 = sh
                uiz3 = sw
                viz3 = 0

             case 1
                x1 = tx3+.5f
                y1 = ty3+.5f
                x2 = tx4+.5f
                y2 = ty4+.5f
                x3 = tx2+.5f
                y3 = ty2+.5f

                uiz1 = sw
                viz1 = 0
                uiz2 = sw
                viz2 = sh
                uiz3 = 0
                viz3 = sh

          end select

          if (y1 > y2) then
             swap x1, x2
             swap y1, y2
             swap uiz1, uiz2
             swap viz1, viz2
          end if

          if (y1 > y3) then
             swap x1, x3
             swap y1, y3
             swap uiz1, uiz3
             swap viz1, viz3
          end if

          if (y2 > y3) then
             swap x2, x3
             swap y2, y3
             swap uiz2, uiz3
             swap viz2, viz3
          end if

          y1i = int(y1)
          y2i = int(y2)
          y3i = int(y3)

          if (y1i = y2i) andalso (y1i = y3i) then
             exit sub
          end if

          if (int(x1) = int(x2)) andalso (int(x1) = int(x3)) then
             exit sub
          end if

          dn = ((x3 - x1) * (y2 - y1) - (x2 - x1) * (y3 - y1))

          if dn = 0 then
             exit sub
          end if

          y2my1 = y2-y1
          y3my1 = y3-y1
          y3my2 = y3-y2
          x2mx1 = x2-x1
          x3mx1 = x3-x1
          x3mx2 = x3-x2

          dn = 1f / dn
          dizdx  = (y2my1 * y3my1) * dn
          duizdx = ((uiz3 - uiz1) * y2my1 - (uiz2 - uiz1) * y3my1) * dn
          dvizdx = ((viz3 - viz1) * y2my1 - (viz2 - viz1) * y3my1) * dn
          dizdy  = (x3mx1* x2mx1) * dn
          duizdy = ((uiz2 - uiz1) * x3mx1 - (uiz3 - uiz1) * x2mx1) * dn
          dvizdy = ((viz2 - viz1) * x3mx1 - (viz3 - viz1) * x2mx1) * dn

          if (y2 > y1) then
             dxdy1 = x2mx1 / y2my1
          end if

          if (y3 > y1) then
             dxdy2 = x3mx1 / y3my1
          end if

          if (y3 > y2) then
             dxdy3 = x3mx2 / y3my2
          end if

          shlonger = dxdy2 > dxdy1

          if (y1 = y2) then
             shlonger = x1 > x2
          end if

          if (y2 = y3) then
             shlonger = x3 > x2
          end if

          if shlonger = 0 then

             dxdya = dxdy2
             dizdya = dxdy2 * dizdx + dizdy
             duizdya = dxdy2 * duizdx + duizdy
             dvizdya = dxdy2 * dvizdx + dvizdy
             dy = 1f - (y1 - y1i)
             xa = x1 + dy * dxdya
             uiza = uiz1 + dy * duizdya
             viza = viz1 + dy * dvizdya

             if (y1i < y2i) then

                xb = x1 + dy * dxdy1
                dxdyb = dxdy1
                sy = y1i
                ey = y2i

                jumpvar = 1
                goto render_loop

             end if
             jump1:

             if (y2i < y3i) then

                xb = x2 + (1f - (y2 - y2i)) * dxdy3
                dxdyb = dxdy3
                sy = y2i
                ey = y3i

                jumpvar = 2
                goto render_loop

             end if
             jump2:

          else

             dxdyb = dxdy2
             dy = 1f - (y1 - y1i)
             xb = x1 + dy * dxdyb

             if (y1i < y2i) then

                dxdya = dxdy1
                dizdya = dxdy1 * dizdx + dizdy
                duizdya = dxdy1 * duizdx + duizdy
                dvizdya = dxdy1 * dvizdx + dvizdy
                xa = x1 + dy * dxdya
                uiza = uiz1 + dy * duizdya
                viza = viz1 + dy * dvizdya
                sy = y1i
                ey = y2i

                jumpvar = 3
                goto render_loop

             end if
             jump3:

             if (y2i < y3i) then

                dxdya = dxdy3
                dizdya = dxdy3 * dizdx + dizdy
                duizdya = dxdy3 * duizdx + duizdy
                dvizdya = dxdy3 * dvizdx + dvizdy
                dy = 1f - (y2 - y2i)
                xa = x2 + dy * dxdya
                uiza = uiz2 + dy * duizdya
                viza = viz2 + dy * dvizdya
                sy = y2i
                ey = y3i

                jumpvar = 4
                goto render_loop

             end if
             jump4:

          end if
       next

       exit sub

       render_loop:

       if -sy > 0 then
          dim as integer cnt = -sy
          if (ey - sy) < cnt then cnt = ey - sy
          xa += dxdya * cnt
          xb += dxdyb * cnt
          uiza += duizdya * cnt
          viza += dvizdya * cnt
          sy += cnt
       end if

       dim as uinteger ptr p = @dstptr[sy*scr_w]

       if ey>scr_h-1 then
          ey = scr_h-1
       end if
      
       do while (sy < ey)

          sx = xa
          ex = xb

          uiz = uiza
          viz = viza

          if ex>=scr_w-1 then
             ex = scr_w-1
          end if

          if sx<0 then
             dim as integer absx = -sx
             uiz+=(duizdx*absx)
             viz+=(dvizdx*absx)
             sx = 0
          end if

          dim as uinteger ptr dptr1 = @p[sx]
          dim as integer tv = any
          dim as integer tu = any

          if ex > sx then

             asm

                mov eax, [ex]
                sub eax, [sx] ' eax = cnt(ex - sx)
                
                fld dword ptr[dvizdx] ' st(0) = dvizdx
                fld dword ptr[duizdx] ' st(0) = duizdx : st(1) = dvizdx
                fld dword ptr [viz] ' st(0) = viz : st(1) = duizdx : st(2) = dvizdx
                fld dword ptr [uiz] ' st(0) = uiz : st(1) = viz : st(2) = duizdx : st(3) = dvizdx
                
                mov edi, [dptr1]
                mov ecx, [shifter]
                mov esi, [srcptr]
                
                wanker_inc_x:
                mov edx, esi
                
                fld st(1) ' st(0) = viz : st(1) = uiz : st(2) = viz : st(3) = duizdx : st(3) = dvizdx
                fistp dword ptr[tv] ' tv = viz : st(0) = uiz : st(1) = viz : st(2) = duizdx : st(3) = dvizdx
                mov ebx, [tv]
                and ebx, [sh]
                shl ebx, cl
                
                add edx, ebx
                
                fist dword ptr[tu] 'tu = uiz
                mov ebx, [tu]
                and ebx, [sw]
                
                mov edx, [edx+ebx*4] 'source pixel color
                
                
                cmp edx, [transcol]
                je wanker_no_draw
                mov [edi], edx
                wanker_no_draw:
                
                fadd st(2) ' uiz += duidzx
                
                fld st(3) ' st(0) = dvidzx : st(1) = uiz : st(2) = viz : st(3) = duizdx : st(4) = dvizdx
                faddp st(2) ' viz += dvidzx : st(0) = viz : st(1) = uiz : st(2) = viz : st(3) = duizdx : st(3) = dvizdx
                
                add edi, 4 'sptr1+=1
                sub eax, 1 'cnt -= 1
                jnz wanker_inc_x 'if cnt > 0 then goto poly_inc_x
                
                emms ' clear off duizdx, dvizdx
                
                wanker_exit:

             end asm

          end if

          xa += dxdya
          xb += dxdyb
          uiza += duizdya
          viza += dvizdya
          sy+=1
          p += scr_w

       loop

       select case as const jumpvar

          case 1
             jumpvar = 0
             goto jump1
          case 2
             jumpvar = 0
             goto jump2
          case 3
             jumpvar = 0
             goto jump3
          case 4
             jumpvar = 0
             goto jump4

       end select

    end sub
« Last Edit: May 13, 2012, 08:19:41 PM by Dr_D »