Announcement

Collapse
No announcement yet.

How to do animated graphics (Newbie question)

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

    How to do animated graphics (Newbie question)

    Coming from QB the GRAPHICS function set in PB is a bit overwhelming for me. Could someone point me out some basic principles to do animated graphics.

    What I want to do:
    I have made a graph screen (like a cockpit navigation screen, or a screen in the process industry) in which scale bars (based on X, Y coordinates) are shown.

    In that graph screen I want to project continuously changing "real time" data and pointers (e.g. lines, symbols) to indicate their position on those (fixed) scale bars. But I don't want to rebuild the total graph with every read out of data.

    How do I delete the old data and put new data on the screen without destroying the original graph as the data is projected over the graph?

    Can anyone give me some basic principles how to set up this?

    Kind regards,
    Henk

    #2
    You might be able to save yourself a lot of time and effort by checking out RMChart http://www.rmchart.com/ Maybe it will do what you need without you having to reinvent the wheel.
    Paul Squires
    FireFly Visual Designer (for PowerBASIC Windows 10+)
    Version 3 now available.
    http://www.planetsquires.com

    Comment


      #3
      Henk,
      maybe this example will get you started.

      Paul.
      Code:
      'PBCC5 program
      #COMPILE EXE
      #BREAK ON
      #DIM ALL
      
      FUNCTION PBMAIN() AS LONG
      LOCAL Xsize,Ysize,hGraph,hOverlay,hWindow, Angle, Xpos, Ypos, LastX, LastY, LastTextWidth, LastTextHeight AS LONG
      LOCAL MyText AS STRING
      LOCAL TextWidth,TextHeight  AS SINGLE
      
      Xsize=500
      Ysize=400
      
      GRAPHIC BITMAP NEW Xsize,Ysize TO hGraph
      GRAPHIC BITMAP NEW Xsize,Ysize TO hOverlay
      GRAPHIC WINDOW "test",400,0,Xsize,Ysize TO hWindow
      
      'draw the background graph
      GRAPHIC ATTACH hGraph,0
      
      GRAPHIC CLEAR %WHITE
      GRAPHIC BOX (100,100)-(200,200),0,%RED,-1,0
      GRAPHIC ELLIPSE (300,100)-(400,200),%GREEN,-1,0
      GRAPHIC WIDTH 50
      GRAPHIC LINE (250,200)-(350,300),%BLUE
      
      'copy the graph to the visible window
      GRAPHIC ATTACH hWindow,0
      GRAPHIC COPY hGraph,0
      
      'do some animated text over the graph
      DO
          FOR Angle = 0 TO 359 'step 10
              xpos = 200 + 100 * SIN(Angle/57.29578)
              ypos = 200 + 100 * COS(Angle/57.29578)
              
              MyText$="Angle=" + STR$(Angle)+" degrees"
              
              'print the text on the overlay bitmap
              GRAPHIC ATTACH hOverlay,0
              GRAPHIC SET POS (0,0)
              GRAPHIC COLOR %BLACK, %WHITE
              GRAPHIC PRINT MyText
              GRAPHIC TEXT SIZE MyText TO TextWidth,TextHeight
      
      
              'now update the visible window
              GRAPHIC ATTACH hWindow,0 ,REDRAW
              
              'delete any old text by overwriting with the original graphic
              GRAPHIC COPY hGraph,0,(LastX,LastY) - (LastX + LastTextWidth -1,LastY +LastTextHeight -1) TO (LastX,LastY) ,%MIX_COPYSRC
              
              'copy the new text to the visible window
              GRAPHIC COPY hOverlay,0,(0,0)-(TextWidth -1,TextHeight -1) TO (xpos,ypos) ,%MIX_MASKSRC
              'keep track of where was overwritten so I can copy the graph data back next time around the loop
              LastTextWidth = TextWidth
              LastTextHeight = TextHeight
              LastX = xpos
              LastY = ypos
              
              GRAPHIC REDRAW
              SLEEP 10
          NEXT
          
      LOOP
           
      END FUNCTION

      Comment


        #4
        I might be completey off base here but Chris Boss makes a product that does sprite graphics that might be useful also.

        I don't own the product personally but from comments I have read it's an awesome peice of work.

        <b>George W. Bleck</b>
        <img src='http://www.blecktech.com/myemail.gif'>

        Comment


          #5
          Solved the issue

          Paul (Dixon),

          Thanks for your nice example.

          I just managed to make something similar (see example attached).
          What I did is: First generate a graphic window with items. Then put that window into a graphic bitmap with GRAPHIC GET BITS.

          Then in a loop: put that bitmap on the window and plot the data.

          As simple as that.

          Kind regards,
          Henk
          Attached Files

          Comment


            #6
            " Can anyone give me some basic principles how to set up this?"

            User to user discussions about the PB/Win (formerly PB/DLL) product line. Discussion topics include PowerBASIC Forms, PowerGEN and PowerTree for Windows.


            I posted the above example sometime last year or so. If you have PBWin, or can download the Sample code (See downloads on http://www.powerbasic.com/support/downloads/demos.htm but that has only for 8.01 at present) then look at Sample\DDT\Graphic\Digital and \Graphic Transforms for an idea of various techniques)

            The basic scenario is to make composite (working) bitmap(s) separately in memory, then GRAPHIC COPY into the Graphic Window display. We will want to use the REDRAW option (See GRAPHIC ATTACH, GRAPHIC REDRAW) for this kind of presentation. There are at least two ways to get the job done but for now here a way I've used. Here is a list of what we will need:
            • Persistent background bitmap(s)
            • Working bitmaps for composite assembly
            Let's start with a persistent bitmap or several persistent bitmaps which represent all of the "background" graphic. This can be one bitmap or several, but taken together they represent the display without the items which will change, e.g. bars, needles, numbers etc. In this case we probably will want one for each instrument.

            Then we will need what I've called the "working" bitmaps for the various instruments where we will be showing the changing information. These bitmaps are where we composite the background information, adding to this the current instrument state display (bar, needle,number) .

            In practice this means that we repeatedly do the following:
            • GRAPHIC ATTACH a working bitmap
            • Copy the persistent background area to the working bitmap
            • "Draw" the new bar,needle or other graphic on the working bitmap
            • GRAPHIC REDRAW this working bitmap
            • GRAPHIC ATTACH the GRAPHIC WINDOW
            • GRAPHIC COPY the working bitmap(s) to the GRAPHIC WINDOW
            • GRAPHIC REDRAW
            In the case where you could have stored bitmaps, such as numbers for digital dispays, indicator lights, etc. These could be directly copied to the GRAPHIC WINDOW on demand, since they would be stored as composited graphics in the first place.


            There is one other technique that might not apply for the program you are making, this is where you have an object moving across the whole display. In this case we need more advanced work that preserves the background.
            Then this involves using GRAPHIC GET BITS to establish working arrays and GRAPHIC SET BITS to create the working bitmap image and copy. But we need to maintian the background information so as the object moves across the GRAPHIC WINDOW, we redraw the background area, then draw the object at the new position. In compositing this way it has been usual to use the uper lefthand pixel as a reference pixel for the color not to be copied in compositing. This is illustrated in the first post IIRC, if not I do have other examples. I'd suggest looking Chris Boss's sprites product as well
            Rick Angell

            Comment


              #7
              The problems one may have with animation is the speed.

              If the animation is simple, then speed shouldn't be a problem.
              But if the animation is quite complex and the image area large, then speed becomes a critical matter.

              To increase speed of animation there are a few methods that help.

              (1) Only copy areas of the which are actually changing. If you waste time moving larger areas of the image which haven't changed you decrease animation speed.

              (2) Since windows applications must repaint (WM_PAINT) for you to see what you are animating, then it helps to only invalidate (force to repaint) the areas which have changed. Rather than force the entire window to repaint, you can use the InvalidateRgn API function to force it to only repaint the parts which have changed. This is refered to as "dirty rectangles" for those who do a lot of graphics.


              Now how do you actually animate something ?

              Basically you have a static background image. This image will be in a buffer (or a bitmap).

              The background is copied (bitBlt) to another buffer for creating the current animation frame. Then the "extras" on top of the background are drawn on top of it. This newly created complete image is what is drawn on the screen.

              Since you have to restore the background image every time to change the animation (or at least the parts that will change) there is a lot of work to do. The speed that you do it, will determine how fast the animation runs.

              Much of the high speed animation or video code in Windows (ie. AVI API functions) depended upon a core feature that has been in Windows for a long time and that is:

              DIB Sections

              Now of course things like DirectX, OpenGL, etc. give you access to the video hardware and todays video cards provide amazingly fast rendering functions. Now if you are writing a software based animation (no hardware support), the DIB sections are the fastest means to do this, since you have direct access to the pixel data and you can modify pixels at blazingly fast speed.

              PB provides something akin to working with DIB's (Device Independent Bitmaps) and that is the GRAPHIC SET BITS and GRAPHIC GET BITS.

              It isn't quite as fast as working with DIB's, where you work with the image buffers directly, but it is very good for most animation. These commands allow you to move pixels from the image to a buffer (a string) then you can modify them and then you move the pixel data back again. This moving data twice step, adds some overhead, but on todays computers you can still do a lot.

              Once you have the data into a buffer (GRAPHIC GET BITS) you can now access it in a way similiar to how you would with a DIB. You use pointers directly into the pixel buffer and modify the pixels at high speed.

              One very, very tricky area is Anti-Aliasing.

              When you are drawing lots of curves or lines, the jagginess of the elements you draw onto the background can produce a poorer quality image. The more photo graphic your background image, the worse the non-antialiased elements will look when draw.

              You have to weigh out to what degree you need that quality image. The more cartoon like your image, the less important it is. The more photographic your image, the more important anti-aliasing is.

              Anti-aliasing done high quality graphic editor software (ie. PhotoPaint) is the best it gets, because time is not critical and the software can take its time shading pixels some distance from the edge to produce a perfect appearing edge.

              Animation software must take short cuts and produce a decent result, but a little less time consuning.

              The PB Graphic commands are a great place to start.

              Start by using a Bitmap background image, a working Bitmap buffer for drawing on and then use the draw commands to draw the other elements. Copy the background to the image bitmap buffer. Draw on top of it what you want. Then draw the image buffer bitmap to the PB Graphic control.

              If the speed is acceptable and the quality you are in business, as they say.

              If the speed or the quality is not up to what you require, then consideri experimenting with the GRAPHIC SET BITS and GRAPHIC GET BITS commands. You'll need to learn to work with pointers though, which is not too hard to learn and is quite powerful.
              Last edited by Chris Boss; 6 Mar 2009, 10:40 AM.
              Chris Boss
              Computer Workshop
              Developer of "EZGUI"
              http://cwsof.com
              http://twitter.com/EZGUIProGuy

              Comment


                #8
                Good points Chris!

                There are links I might dredge up where some of this was illustrated as a mix of PB GRAPHIC and GDI API's. Others may have links they can post for forum topics which might not come up in a general search. The main point about speed though is right on! Only copy areas according to need. If speed gets to be a problem, then for sure, using direct API calls should be investigated, e.g. by Chris, InvalidateRgn. Keep in mind too that once you have a graphic area extracted by GRAPHIC GET BITS, as Chis notes too, you can work with the data quite easily and rapidly. Using pointers, PB BASIC or in-line assembler. All depends on how busy your real time display really has to be.

                One thing to keep in mind with regard to GRAPHIC WINDOWs (GW) an using API's yourself is that the Graphic Window is actually a Top Level window, so for sny direct action outside of PB GRAPHICS you may need to get the handle and DC of the actual child graphic control it uses. In those cases you may usually need to sub-class the GW's child. But for now, you probably should learn the PB GRAPHICS and see how it works for your need. Then come back if you have a much more demanding need for speed and step-by-step move into the direct API approach.
                Rick Angell

                Comment


                  #9
                  Probably the most powerful single command in Microsoft DOS graphics is DRAW. It is particularly useful for animations. PBCC does not have a built-in version, but for free amateur source code see, for example:




                  A new version of this program is currently in the works and it enables one to use all of the DRAW commands, as such. It also includes the ability to enter any new command, on the fly, as in interpreted BASICs. E.g., to draw a red square, one could simply type "C4 ULDR" (or paste it in from the clipboard), and press Enter.
                  Last edited by Emil Menzel; 7 Mar 2009, 09:52 AM. Reason: To add the second, more recent & relevant, url

                  Comment


                    #10
                    "PBCC does not have a built-in version"

                    Because PB GRAPHICs wraps a good portion of the GDI which replaces Draw in Windows wirh a great deal of expansion, which in turn in PB handles quite well, wand hich handles many, many different possibilities. before one might need something more sophisticated. But each to their own....
                    Rick Angell

                    Comment


                      #11
                      Actually, I think DRAW is a good option for a very select type of application. It adds no extra graphic primitives, but rather just allows you to access them in a different way. Any graphical item you can create with DRAW can be precisely duplicated without it. DRAW just allows you to create a design dynamically, at run-time, and it interprets the commands which are embedded (somewhat cryptically) in a dynamic string.

                      If you have a need to dynamically create a graphic at run-time, DRAW can be very helpful. However, since it's interpreted, that also adds to the overhead and slows it all down. To each...

                      Best regards,

                      Bob Zale
                      PowerBASIC Inc.

                      Comment


                        #12
                        Thank you, Bob; I certainly could not have said it any more clearly myself, and your comments will hopefully inspire my co-author (Petr Schreiber) and me, to finish up our revised program. I would like to add a few comments, however:

                        (a) One specialized type of application that the PB version of DRAW would be good for is, I believe, the drawing of simple charts, such as Henk wants.

                        (b) My guess is that most non-programmers could learn DRAW syntax in a few afternoons, or a fraction of the time it would take them to learn PBCC. QB graphics programmers should already have a head start.

                        (c) Thanks to PB's MACROs and other capabilities, one does not really have to use DRAW's original cryptic terms unless one really wants to. For that matter, one can not only say UpLeftDownRight or Square instead of ULDR but also concatenate one's strings, as in DRAW A$+B$+C$ in real old-timey BASIC.

                        (d) The hit on speed if one can use MACROs does not strike me as huge. But I am neither an expert on that nor (very often) a speed demon.

                        (e) One does not have to use a runtime interpreter as such. That is an added FUNCTION, for more specialized purposes.

                        Comment

                        Working...
                        X
                        😀
                        🥰
                        🤢
                        😎
                        😡
                        👍
                        👎