Announcement

Collapse
No announcement yet.

Rotating Bitmaps - some fun

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • #21
    Kevin,

    I meant no offense.

    I was just refering to the original code being in C and yours was a translation of it to BCX.
    Chris Boss
    Computer Workshop
    Developer of "EZGUI"
    http://cwsof.com
    http://twitter.com/EZGUIProGuy

    Comment


    • #22
      Paul,

      Very interesting code.

      Not quite as fast a world transformation, but not bad.
      Chris Boss
      Computer Workshop
      Developer of "EZGUI"
      http://cwsof.com
      http://twitter.com/EZGUIProGuy

      Comment


      • #23
        Paul,

        Thank you to remind me the old method i was using in my PDS 7.1 applications, still very accurate with modern processors!

        By the way i found amazing to compare the size of the resulting EXE solutions that have been posted there:
        - DDT.exe = 58880 bytes (Chris, rotate.exe)
        - Console.exe = 36864 bytes (Paul, PBCC GRAPHIC example)
        - SDK.exe = 12288 bytes (Patrice, PlgBlt.exe)

        ...
        Patrice Terrier
        www.zapsolution.com
        www.objreader.com
        Addons: GDImage.DLL 32/64-bit (Graphic library), WinLIFT.DLL 32/64-bit (Skin Engine).

        Comment


        • #24
          Chris: "Not quite as fast a world transformation,"
          Patrice: "i found amazing to compare the size of the resulting EXE solutions "

          There's just no pleasing some people!
          The code was just straight forward BASIC, it was not intended to be extra small or extra fast but, just to keep you happy, here's a slightly modified version of the same code which appears to be faster.

          As for smaller, the RTL included with the compiler is 23k so I'd have to avoid the GRAPHIC commands but they make life easier. The rotation code itself is already quite small but I'm sure I could shrink it further and speed it up if I use a bit of ASM.

          Paul.

          Code:
          'PBCC5.01 program
          #COMPILE EXE
          #BREAK ON
          #DIM ALL
          
          %xWindowSize = 280
          %yWindowSize = 280
          
          %xRotateOffset=140
          %yRotateOffset=140
          
          FUNCTION PBMAIN () AS LONG
          LOCAL hInitialBMP,hWindow, hThread AS DWORD
          LOCAL InitialBMPstring, RotatedBMPstring AS STRING
          LOCAL x,y,a,xSize,ySize,t1,t2, Oldx,Oldy, QuitAll, lResult AS LONG
          LOCAL Angle,sina, cosa AS EXT
          LOCAL file AS STRING
          LOCAL initial(), rotated() AS LONG
          
          
          file$="logo1.bmp"
          x = FREEFILE
          OPEN file$ FOR BINARY AS x
          GET #x, 19, xSize
          GET #x, 23, ySize
          CLOSE x
          
                           
          GRAPHIC WINDOW "Rotation test",200,200, %xWindowSize,%yWindowSize TO hWindow
          GRAPHIC ATTACH hWindow,0
          GRAPHIC GET BITS TO RotatedBMPstring
          GRAPHIC DETACH
          
          GRAPHIC BITMAP LOAD file$, xSize&, ySize&  TO hInitialBMP
          GRAPHIC ATTACH hInitialBMP,0
          GRAPHIC GET BITS TO InitialBMPstring
          GRAPHIC DETACH
          
          THREAD CREATE RedrawGraphics (hWindow) TO hThread
          
          DIM initial&(1 TO xSize&,1 TO ySize&) AT STRPTR(InitialBMPstring)+8
          DIM rotated&(1 TO %xWindowSize,1 TO %yWindowSize) AT STRPTR(RotatedBMPstring)+8
          
          
          
          LOCAL tc, ts AS EXT
          
          t1&=TIMER*100
          
          FOR a& = 0 TO 360    'degrees
              
          angle##=a&/(180/3.141592653589)
          cosa=COS(angle##)
          sina=SIN(angle##)
          
          
          FOR x&=1 TO %xWindowSize
              tc = (x& - %xRotateOffset) *cosa  + %xRotateOffset  -40
              ts = -(x& - %xRotateOffset)*sina + %yRotateOffset  -70
              FOR y& = 1 TO %yWindowSize
          
                 oldx& =tc + (y& - %yRotateOffset)*sina
                 oldy& =(y& - %yRotateOffset) *cosa + ts
                  
                                
                 IF oldx&>0 AND oldx& < xSize&  AND oldy&>0 AND oldy&< ySize& THEN
                      Rotated&(x&,y&)   =  Initial&(oldx& ,oldy&)
                 ELSE
                      Rotated&(x&,y&)   =  %WHITE
                      
                 END IF
             
          
              NEXT
          NEXT
          
          
          GRAPHIC ATTACH hWindow,0 ,REDRAW
          GRAPHIC SET BITS RotatedBMPstring
          GRAPHIC DETACH
          
          SLEEP 0
          NEXT
          
          t2&=TIMER*100
          PRINT "Time Taken = "(t2&-t1&)/100
          PRINT "Frames per second ="; 360/((t2&-t1&)/100 )
          
          QuitAll& =1
          
          THREAD CLOSE hThread TO lResult
          WAITKEY$
          
          END FUNCTION
          
          
          
          'This is a flag intended to cause all otherwise non-terminating threads to quit
          GLOBAL QuitAll&
          
          'This routine and the main program must use GRAPHIC ATTACH WindowID,0,REDRAW but the main program shouldn't
          'issue a GRAPHIC REDRAW command in normal use. Leave that up to this thread.
          FUNCTION RedrawGraphics(BYVAL WinID AS DWORD) AS DWORD
          
          GRAPHIC ATTACH WinID,0,REDRAW
          
          DO
          
              GRAPHIC REDRAW
              SLEEP 1
          LOOP UNTIL QuitAll&
          
          END FUNCTION

          Comment


          • #25
            Paul,

            I was not trying to imply anything negative by my comment about speed.

            I am just curious about what is the fastest way to accomplish image rotation. PlgBlt appears to be quite fast. Both PlgBlt and SetWorldTransform (and BltBlt) are quite fast.

            What I am wondering is whether it would be better to just use this feature in Windows (limited to NT systems, XP, Vista) or to write my own routine ?

            Your code (and some others) shows it can be done other ways and that would make the code usable on Windows 95/98/ME as well.


            Patrice, the EXE I posted has a lot of library code generated by my DDT designer and I didn't remove the extra library code, so it would be much larger. I rewrote the code using a simple DDT dialog and no library code by hand and the EXE comes out to be 27 KB in size.
            Chris Boss
            Computer Workshop
            Developer of "EZGUI"
            http://cwsof.com
            http://twitter.com/EZGUIProGuy

            Comment


            • #26
              Chris,
              so far, at least on my computer, the version written entirely in BASIC in post #24 is by far the fastest.

              Rotating your logo1.bmp image in all cases, your code is doing 112 frames per second and the BASIC code in post #24 is running at 500fps.
              Patrice's appears to do 257 fps but doesn't clear the background. If the background doesn't need to be cleared then the code in post #24 runs at 560fps, over twice as fast as the next nearest and there are plenty of ways to speed it up further.

              Paul.

              Comment


              • #27
                and the EXE comes out to be 27 KB in size
                Yes, twice bigger than pure SDK

                SDK source code is larger, but we both know that it produces smaller and faster EXE...
                Patrice Terrier
                www.zapsolution.com
                www.objreader.com
                Addons: GDImage.DLL 32/64-bit (Graphic library), WinLIFT.DLL 32/64-bit (Skin Engine).

                Comment


                • #28
                  Paul,

                  FPS is very subjective, and whatever you are doing you must always avoid to hog the whole CPU, thus in real application you should used something that is close to movie animation (24 FPS) this is quite enough because you won't see any difference due to the human eyes conformation.

                  I usualy use 30 FPS (see my BassBox project for an example of real time application)


                  Added:
                  Paul, the bitmap being used in PglBlt is larger, and to produce faster code the solution is to use a permanent memory DC instead of re-creating it for each iteration.


                  ...
                  Last edited by Patrice Terrier; 29 May 2009, 12:26 PM.
                  Patrice Terrier
                  www.zapsolution.com
                  www.objreader.com
                  Addons: GDImage.DLL 32/64-bit (Graphic library), WinLIFT.DLL 32/64-bit (Skin Engine).

                  Comment


                  • #29
                    Patrice,
                    FPS gives an indication of the speed of the code.

                    500fps means the one frame is being drawn in 2ms or less.
                    127fps means the one frame takes 7.8ms or less.


                    I only used fps as a measure because Chris uses it in his example so I was keeping to the same units in order to make an easy comparison.
                    Perhaps timing a single pass of the rotation code would be better.

                    Paul.

                    Comment


                    • #30
                      Patrice,

                      I wouldn't start touting SDK code as half the size of DDT quite yet.

                      First, your code doesn't use the API includes, but simply has the declares for what is used.

                      When compiled using the PB 9.0 compiler, your plgblt.bas app compiles to:

                      18 KB (no includes)
                      25 KB (when using win32api.inc and deleting references to commtrl.inc)
                      61 KB (when using win32api.inc and commctrl.inc)

                      The API include files add some fat to an application, albeit not an awful lot.

                      Also your app isn't cleaning up the background of each blit (which requires extra memory buffers and redrawing them each time), so it has a little less code.

                      Also DDT apps when using DDT commands add a bit more runtime library time code when compiled. This adds a little more fat when the program is small, but balances out when the app gets bigger (runtime code is efficient and modular so size savings are not found until the app gets some size).

                      For those browsing the forums and new to PB it is only fair to get the real facts on DDT. DDT is quite efficient and lean, IMO. One does not gain significant advantages by using SDK style code over DDT for most applications.
                      Chris Boss
                      Computer Workshop
                      Developer of "EZGUI"
                      http://cwsof.com
                      http://twitter.com/EZGUIProGuy

                      Comment


                      • #31
                        I agree with Paul.

                        Frame speed is important because it shows how fast the code itself is being executed. One actually wants to use the CPU 100% during testing of code speed. This is why I don't use things like timers with test code, since one does not get a real picture of the actual code speed.

                        While the bitmap rotation using world transforms and PlgBlt are quite reasonable for one single image of medium or small size, I am not sure it would be so fast when dealing with dozens of images at one time.

                        Another consideration is the effects of running an app when other apps are running and there is less CPU time per app. A frame rate at 100% CPU time and one app running does not mean the frame rate will be that good when multiple apps are running at the same time.

                        Personally I like to squeeze out every bit of speed I possibly can, so when the code is run in the real world it will run at a decent speed.

                        I am also interested in the avoidance of later API's if possible so I can run the code on Windows 95/98/ME (I know, everybody says they are obsolete). I try to design software which can take advantage of legacy systems.
                        Chris Boss
                        Computer Workshop
                        Developer of "EZGUI"
                        http://cwsof.com
                        http://twitter.com/EZGUIProGuy

                        Comment


                        • #32
                          Chris,

                          Granulaity has always been one of my major concern.

                          While we are unable to use static linking doesn't mean that we can't clean up our code. Fortunatly a tool like Borje's inclean utility does a very nice job.

                          I was just amazed by the difference in size.

                          Removing the background in PlgBlt would not make the code twice large.

                          I wrote it to show the use of an API that was almost unknown by most of us.

                          In case of image rotation FPS is absolutly not meaningful, what is meaningful is are you using linear interploation, bicubic, Nearestneighbor, etc.

                          If we do not use the same algorithm then we can't do any fair comparison.

                          ...
                          Patrice Terrier
                          www.zapsolution.com
                          www.objreader.com
                          Addons: GDImage.DLL 32/64-bit (Graphic library), WinLIFT.DLL 32/64-bit (Skin Engine).

                          Comment

                          Working...
                          X