UnderwareDESIGN

Dedicated Forums => Games And Apps => Topic started by: kevin on March 17, 2012, 08:34:43 PM

Title: AGE Development Blog (Advanced Graphics Engine for AmosPro / Amiga AGA)
Post by: kevin on March 17, 2012, 08:34:43 PM
 
AMOS AGA - AGE Development Blog (Advanced Graphics Engine for AmosPro / Amiga AGA)


 
 
What Is it?


   AGE is a bare bones graphics engine / library for the Amos / AmosPro developers on the Amiga platform.    The library allows the user to perform various graphical effects, but mainly gives the user the ability to the use the Amiga's AGA chipset from AMOS / AMOSPRO.  

   The project was originally active between 1996 -> 1998, with that version of the library being release around 2000.  It hasn't been updated since.  Given the age of library, it'd be easy to say why bother, well, the recent updates just clean up the code and make it more user friendly.   The previous release examples were very complicated to follow and virtually impossible to use without low level knowledge.    Having said, some new features have been added, but those have mostly been cosmetic.  

    The changes to the package are in the examples..  There are now example, where there wasn't previously.


 
Can I use the library under AMIGA emulation ?


     Yes,  that's how recent updates of the package have been developed.   For those without real AMIGA hardware anymore (like myself), there's also package versions of AMOSPRO (WinUAE + AMOS) that be run directly on Windows.     Well worth a bit of nostalgia..  




Can I use the library from other BASIC languages on AMIGA ?


   Yes, you could.  The library is presented as a pre-assembled chunk of machine code with AMOS wrapper.  Therefore you can use AGE from any language that allows you set the registers and call a function by pointer.    




Didn't you write AMOS AGA


      Yes;  decaded ago now I wrote a collection of simple demos that used AGA in AMOS

      https://aminet.net/package/dev/amos/AmosAGA (https://aminet.net/package/dev/amos/AmosAGA)






 
Home Page?


     AGE From Home Page (http://www.underwaredesign.com/?page=programs.A-G-E-)  (NOTE: OLD 2000 Version )



 
Beta Downloads?


     AGE V1.02 BETA #1 (http://www.underwaredesign.com/forums/index.php?topic=3814.msg25349#msg25349)  (21st,Apr,2012)




Videos


   








Work In Progress.


     Given the age of the library, I'm not going to be updating it on a regular basis, the following updates just make the library a lot more user friendly.  Firstly the library now comes as an separate AMOS file.    So the user just includes the file into their project (at the top of the code) and then is ready to use AGE function bellow that.

     Some of functions/procedure names have been changed and well as some helper functions have been added.   As new functionality is added it'll be documented here.




Function List.


    While the library supports PLANAR, INTERLEAVED PLANAR and CHUNKY pixel formats, not ALL drawing functions do.  




  System

     AGE_ALLOC_RESOURCES[SCRNS,COPS,BLOCKS,BANKS,FONTS,FILECACHE,DATACACHE]       ; This function basically opens the library so you can use it.  The library was designed to be fairly flexible in terms of resources, so rather than it allocate memory for the various resource tables.  You'll need to supply this function withe the sizes of various buffers the library will use.  When you call it, this allocates the base the AGE resource structure the entire library then uses.

           SCRNS       = Number of Screens you want
           COPS         =  Number of Coppers you want
           BLOCKS      =  Numbers of Blocks banks you want
           BANKS       = Number of banks
           FONTS       = Number of fonts
           FILECACHE  = Size of temporary file buffer for loading.
           DATACACHE =  Set users required data cache size
 

     AGE_TAKE_SYSTEM[COPADDR]       ; This function takes over system and sets up the low level machine state.  The function expects the address of the COPPER List to install upon execution.

     AGE_RESTORE_SYSTEM       ; Restore system state after it's been taken over.

     AGE_FORBID_TASKING       ; Disable the Amiga OS from multi tasking

     AGE_PERMIT_TASKING       ; Allow the Amiga OS to multi task




  Screen

      AGE_OPEN_SCREEN[SCRN,WIDTH,HEIGHT,DEPTH,TYPE]      ; Creates a screen of width/height/depth, of particular type.  Supports Planar / Interleaved & Chunky screen types.  The screen default to being created in chip memory, but can be forced into Fast.

      AGE_OPEN_CHUNKY_SCREEN[SRCN,WIDTH,HEIGHT]      ; Creates a 8bit chunky screen in fast memory.

      AGE_DELETE_SCREEN[SRCN]      ; Releases a screens memory.  Beware that if this screen is the current copper list screen you'll get undefined results.

      AGE_LOAD_IFF_TO_SCREEN[FILENAME$,SCRN]      ; Loads an IFF file into a previously created screen.   Supports 1 to 8bit IFF images


      AGE_SAVE_IFF[FILENAME$,SCRN]      ; Save screen to disk as IFF file.

      AGE_EXAMINE_IFF[FILENAME$      ; Queries IFF file for it's size information.  The function returns the Width/Height/Depth in the dregs(0),dregs(1),dregs(2)

      AGE_SET_SCREEN[SCRN]      ; Make the library direct rendering to this screen from now on.

      AGE_SCREEN_VIEWPORT[X1,Y1,X2,Y2]      ; Set the viewport (Render area) of the current output screen.  This lets you clip rendering to within a certain care of the screen.

      AGE_RESTORE_SCREEN_VIEWPORT          ; Restore the view port to the screens original size.

      AGE_GET_SCREEN_VIEWPORT          ; The screens current view port size.  Values returns in dreg 0,1,2,3


      AGE_GET_BITPLANE_ADDR[SCRN,BP]          ; Get Address of bit plane within this screen.

      AGE_GET_SCREEN_WIDTH[SCRN]          ; Get width of screen.  Param  or  dreg(0)=result
      AGE_GET_SCREEN_HEIGHT[SCRN]          ; Get height of screen.  Param  or  dreg(0)=result
      AGE_GET_SCREEN_DEPTH[SCRN]          ; Get depth of screen.  Param  or  dreg(0)=result
      AGE_GET_SCREEN_TYPE[SCRN]          ; Get type of screen.  Param  or  dreg(0)=result




    Copper

      AGE_CREATE_COPPER[Index, ScreenIndex, BurstMode, BurstModulo]      ; Creates a standard copper list in chip memory.  The view settings are is based upon a screen you provide
 
      AGE_DELETE_COPPER[Index]      ; Delete a copper list from chip memory.  
 
      AGE_SHOW_COPPER[Index]         ; Set the copper hardware to view your copper list.  Sme as AGE_SET_COPPER, except this version flushs the display hardware.

      AGE_SET_COPPER[Index]         ; Set the copper hardware to view your copper list

      AGE_REFRESH_COPPER_PALETTE[COPPER_INDEX,PAL_POINTER]         ; Update the colour table in the copper with a user defined list of 256  32bit RGB colour values.

      AGE_GET_COPPER_PTR[COPPER_INDEX]         ; This functions returns a pointer to the copper list in chip memory.  You can modify it all you want.  The only limit is that copper lists allocated by the library, must be smaller than 4096 bytes..







   Graphics

      AGE_DOT[x,y]              ; Draw DOT in current ink colour (CLIPPED)  to current surface   (Supports PLANAR / CHUNKY)  
       AGE_DOTC[x,y,colour]    ; Draw DOT in user defined  ink colour (CLIPPED) to current surface  

      AGE_DOT_NC[x,y]      ; Draw DOT in current ink colour (NO CLIPPED)  to current surface   (Supports PLANAR / CHUNKY)  
       AGE_DOTC_NC[x,y,colour]    ; Draw DOT in user defined  ink colour (NO CLIPPED) to current surface  

      AGE_LINE[x1,y1,x2,y2]      ; Draw Lines in current ink colour (CLIPPED)    (Supports PLANAR / CHUNKY  )  
       AGE_LINEC[x1,y1,x2,y2]    ; Draw Lines in user defined  ink colour (CLIPPED)  


      AGE_BOX[X1,Y1,X2,Y2]      ; Draws a filled rectangle in current ink colour.  (Supports PLANAR / INTERLEAVED PLANAR & CHUNKY)  

      AGE_BOXC[X1,Y1,X2,Y2,PCOL]      ; Draws a filled rectangle in user defined colour.  (Supports PLANAR & CHUNKY)  

      AGE_DRAW_FILLED_BOX[X1,Y1,X2,Y2,PLANEMASK]      ; Draws a filled rectangle on the user defined planes.  (Supports PLANAR)  

      AGE_DRAW_CLEAR_BOX[X1,Y1,X2,Y2,PLANEMASK]      ; Clears a filled rectangle on the user defined planes.  (Supports PLANAR)  
   
      AGE_DRAW_SHADE_BOX[X1,Y1,X2,Y2,C1,C2,C3,C4]      ; Grads a gouraud shaded rectangle to the current screen  (Supports Chunky)  


      AGE_CIRCLE[X,Y,RAdius]      ; Draws a filled circle in current ink colour.  (Supports PLANAR & CHUNKY)  

      AGE_CIRCLEC[X,Y,RAdius,PCOL]      ; Draws a filled circle in user defined colour.  (Supports PLANAR & CHUNKY)  


      AGE_COPY_RECT[SrcScreen,X1,Y1,X2,Y2,DestScreen,DestX,DestY]      ; Copy a section from the source image to the destination.     (Supports PLANAR & CHUNKY)  


      AGE_COPY_RECT_QUEUE[QUERE_POINTER, X_OFFSET,Y_OFFSET, NUMB_OF_ITEMS_IN_QUEUE]      ; Render a list of queued copy rect's.  The output location can be displaced  using with X & Y offsets.  The structure is expected to be 16 bytes wide (16 bytes per queue item)   (Supports PLANAR & CHUNKY)


      AGE_SET_RECT_QUEUE[QUERE_POINTER, INDEX,SrcScreen,X1,Y1,X2,Y2,DestScreen,DestX,DestY]      ; This is a wrapper function to set the source rect and destination position of the rect to be copied.  The Function requires a user allocated buffer big enough to fit the queue data.  If you wanted to store 50 items, then you'd need to allocate at least 50*16 (16 bytes per item) for the buffer.   Each item in the queue is accessed via an Index, ranging from 0 to Number_Of_items -1



      AGE_TRI[x1,y1,x2,y2,x3,y3]      ; Draws a triangle in the current INK colour.     (Chunky)

      AGE_TRIC[x1,y1,x2,y2,x3,y3,Colour]      ; Draws a triangle in a user defined colour  (Chunky)

      AGE_QUADC[x1,y1,x2,y2,x3,y3,x4,y4,Colour]      ; Draws a 4 sided polygon in user defined  colour, the vertex given to the function must form a CONVEX polygon     (Chunky)


      AGE_GOURAUDTRI[x1,y1,Colour1,x2,y2,Colour2,x3,y3,Colour3]      ; Draws a gouraud shaded triangle to the current screen.  (Chunky)

      AGE_GOURAUDQUAD[x1,y1,Colour1,x2,y2,Colour2,x3,y3,Colour3,x4,y4,Colour4]      ; Draws a gouraud shaded 4 sided convex polygon to the current screen.  (Chunky)



  Fonts

     AGE_LOAD_FONT[FILENAME$,INDEX]       ; Load a Font into a available font buffer.  

     AGE_DELETE_FONT[Index]                    ; Delete a front from memory

     AGE_FONT_PLANE_MASK[INDEX,MASK]           ; Specify which bitplanes the font should write to when drawn.  Defaults to %11111111 (All Planes)

     AGE_GET_FONT_PLANE_MASK[INDEX[Index]                    ; Get the bitplane mask this font is using.

     AGE_GET_FONT_HEIGHT[INDEX]                    ; Get the fonts overall height.

     AGE_SET_FONT[INDEX]                    ; Set default font for rendering functions like AGE_PRINT

     AGE_GET_FONT                    ; Get the current output font if any.


     AGE_INK[ColourIndex]             ; Set the current INK colour for rendering functions.

     AGE_GET_INK             ; Set the current INK colour for rendering functions.

     AGE_SET_CURSOR             ; Set the current cursor position (X/Y) coordinates.

     AGE_PRINT[t$]             ; Prints the String T$ at current cursor position, in the current colour and font.  NOTE:  Only seem to support rendering to PLANAR formatted screens

     AGE_TEXT[T$,X,Y,C]      ; Render text at any position on the current screen. Using the current font.


     
NOTE:  PRINT & TEXT functions truncate the X coordinate to nearest byte when rendering, and there only seems to be clipping on the vertical axis.




   C2p (Chunky To Planar)

     AGE_C2P[SourceChunkyScreen,TargetPlanarScreen]       ; Convert the chunky formatted source image to an 8bit planat screen.

     AGE_C2P_CLS[SourceChunkyScreen,TargetPlanarScreen]       ; Convert the chunky formatted source image to 8bit planar screen with chunky CLS (colour 0).



   Colours

     RGB[R,G,B]       ; Merges the three 8Bit R,G,B values into packed 32bit colour value.

     RGBR[ThisRGB]       ; Get the 8Bit Red Value from colour , result in Param
     RGBG[ThisRGB]       ; Get the 8Bit Green Value from colour , result in Param
     RGBB[ThisRGB]       ; Get the 8Bit Blue Value from colour , result in Param

     RGB_24TO12[RGB]       ; Convert 24bit RGB value into 12Bit RGB value, result in Param
     RGB_12TO24[RGB]       ; Convert 12bit RGB value into 24Bit RGB value, result in Param

     RGB_ALPHA_BLEND[RGB1,RGB2,SCALE#]       ; Alpha Blend Two RGB colours, scale range 0.0 to 1.0,  result in Param
     RGB_INT_ALPHA_BLEND[RGB1,RGB2,INTSCALE]       ; Alpha Blend Two RGB colours, IntScale Range 0 To 255,  result in Param

     RGB_ALPHA_ADD[RGB1,RGB2]       ; Alpha Add  Two RGB colours,  result in Param
     RGB_ALPHA_SUB[RGB1,RGB2]       ; Alpha Subtract Two RGB colours,  result in Param

     RGB_FADE[THISRGB,SCALE#]       ; Scale the input RGB colour.  (Scale range 0 to 1.0)  result in Param
     RGB_INTFADE[THISRGB,IntSCALE]       ; Scale the input RGB colour.  (IntScale range 0 to 255)  result in Param




  Blitter

     AGE_OWN_BLITTER       ; Take exclusive control over the blitter chip.
     AGE_DISOWN_BLITTER  ; Release control over the blitter
     AGE_WAIT_BLIT           ; Wait for blitter to complete it's current work.




  Banks

     AGE_CREATE_BANK[BANK,SIZE]       ; CReate a bank of SIZE (in bytes)
     AGE_DELETE_BANK[BANK]       ; Deletes a BANK from memory
     AGE_LOAD_BANK[FILENAME$,BANK]       ; Load Data directly to a Bank
     AGE_GET_BANK_PTR[BANK]       ; Returns the address (pointer) of the first byte in a bank
     AGE_GET_BANK_SIZE[BANK]       ; Returns the size in bytes of a bank

     You can use the Amos Peek/Poke commands to modify the banks content at will




  Fixed Point Math / Trig Functions

     AGE_COS[ANGLE]       ; Cosine of angle (in degrees), returns fixed point 16:16 integer
     AGE_SIN[ANGLE]        ; Sine of angle (in degrees), returns fixed point 16:16 integer

     AGE_COSRADIUS[ANGLE]       ; Cosine of angle (degrees) * RADIUS, returns fixed point 16:16 integer
     AGE_SINRADIUS[ANGLE]        ; Sine of angle (degrees) * RADIUS, returns fixed point 16:16 integer

     AGE_POLAR[ANGLE]              ; returns X / Y in dreg(0) and dreg(1) returns fixed point 16:16 integer

     AGE_SINRADIUS[ANGLE]        ; Sine of angle (degrees) * RADIUS, returns fixed point 16:16 integer

      AGE_ROTATE2D[ANGLE,X,Y]   ; Rotate a 2d coordinate by ANGLE degrees. Result returned in D0/D1 registers.

      AGE_ROTATE2D_BATCH[SRCPTR,SRCVERTEXMODULO,DESTPTR,DESTVERTEXMODULO,METHOD,ANGLE,VERTEXCOUNT]
   ; 2D Rotate a set of points.   See Here for More Info (http://www.underwaredesign.com/forums/index.php?topic=3814.msg25346#msg25346)

     ANGLES are wrapped to 360 degrees internally.  To convert from fixed point to Integer  we divide  the value by $10000.   Some functions will do this for you, others won't to keep the precision.  


Title: Re: AGE Development Blog (Advanced Graphics Engine for AmosPro / Amiga)
Post by: kevin on March 17, 2012, 09:34:29 PM
 AGE Example - Loading 256 Colour Picture In AmosPro

 In very short this video we see the AGE library wrapper being used from AmosPRO.  The demo frame work sets up the library,  create a screen, loads the 8bit (256 colour) IFF, creates a copper list and then displays it.  

Developed By:
https://www.underwaredesign.com









Set Buffer 50

' *=-------------------------------------------------------------------=*
'
'                         AGE - Loading 256 Colour IFF's    
'
'                                      By  
'
'                                By Kevin Picone
'
'                         Last Updated - 14th, Mar, 2012                  
'
'                (c) Copyright 1997/98/1999/2000- 2012, Kevin Picone
'
'                             www.UnderwareDesign.com        
'
' *=-------------------------------------------------------------------=*
'

   ' Sorry but AMOSPRO seems to require absolute include paths ??  
   '  SO,  YOU'LL HAVE TO TWEAK THE PATHS IN ORDER TO RUN
   '  THE DEMOS FROM AMOS/AMOSPRO correctly on your machine    


   ' To make the pathing less annoying, here we store the 'root path'  
   '  in a variable APPPATH$ .. Then use this through our program.  


     APPPATH$="Dh0:/AGE_V102/"



    ' Set the location of the AGE lib..  
      AGE_LIBRARY_PATH$=APPPATH$+"Includes/Asm/Age.lib"

    ' Include the AGE wrapper into your AMOS project
      Include "Dh0:/AGE_V102/INCLUDES/AMOS/AGE_V064.AMOS"




'   *=-----------------------------------------------------------------=*    
'
'                        >> ALLOC AGE RESOURCE TABLEs <<
'
'   *=-----------------------------------------------------------------=*    

           SCRNS=15
           COPS=15
           BLKDATAS=10
           BANKS=11

           FONTS=12
           FILECACHESIZE=50000
           DCACHESIZE=10000

           AGE_ALLOC_RESOURCES[SCRNS,COPS,BLKDATAS,BANKS,FONTS,FILECACHESIZE,DCACHESIZE]




        ' -----------------------------------  
        ' Create our LOWRES / INTERLEAVED  AGE screen in Chip Memory
        ' -----------------------------------  

           TYPE=AGE_LOWRES
           TYPE=TYPE+AGE_INTERLEAVED
           AGE_OPEN_SCREEN[0,320,256,8,TYPE]



        ' -----------------------------------  
        '  Load IFF into this screen.  
        ' -----------------------------------  
           FILE$=APPPATH$+"GFXFILES/PICTURES/DRAGONAA.IFF"
           AGE_LOAD_IFF_TO_SCREEN[FILE$,0]


        ' -----------------------------------  
        ' Create a standard/ simple copper list for viewing this screen.  
        ' -----------------------------------  
           AGE_OPEN_STANDARD_COPPER[0,0,3,8]



        ' -----------------------------------  
        '  Create copper to view our AGE screen  
        ' -----------------------------------  
           Doke $DFF096,$180 : Rem Kill Bitplane + copper DMA  

           AGE_WAIT_TOP_OF_FRAME

           AGE_SHOW_COPPER[0]

           Doke $DFF096,$8180 : Rem restore Bitplane + copper DMA  


        ' -----------------------------------  
        ' Direct ALL RENDERING To OUR Screen
        ' -----------------------------------  
           AGE_SET_SCREEN[0]



        ' -----------------------------------  
        '  Wait for a key
        ' -----------------------------------  

           Wait Key



        ' -----------------------------------  
        ' Clean Up/Close Down AGE  
        ' -----------------------------------  

           AGE_CLEAN_UP






Title: Re: AGE Development Blog (Advanced Graphics Engine for AmosPro / Amiga)
Post by: kevin on March 18, 2012, 07:20:03 PM
AGE Clean Up

   The original library was written using AsmOne on the my Amiga 1200,  but sadly this is really unstable under emulation, so in order to update the library i've had to change assemblers.   Which means running the code through a make ship translator written in PlayBASIC (http://www.playbasic.com).  Even so, it still took a few hours to get it assembling under PHXASS.   So the build process now,  is editing code on the PC side, switching to WinUAE and assembly through the command line.  A little messy, but it's fairly comfortable really once you get going.  

   While looking through the command set of the library, there's some obvious pitfalls in the commands, by that i mean, there's some missing functionality to tie some parts together better.   One such issue, was that you couldn't update the display copper colour list once it'd be created from the parent screen.  Might not sound like a big deal, but it meant you couldn't change the palette colours.     So I've added a function to write a custom palette back into the copper list on demand.   

    Here's an example that grabs the palette from the source screen,  then fades it out after hitting a key.



Set Buffer 50

' *=-------------------------------------------------------------------=*
'
'           AGE - Loading 256 Colour IFF's  With Palette fade    
'
'                                      By  
'
'                                By Kevin Picone
'
'                         Last Updated - 16th, Mar, 2012                  
'
'                (c) Copyright 1997/98/1999/2000- 2012, Kevin Picone
'
'                             www.UnderwareDesign.com        
'
' *=-------------------------------------------------------------------=*
'

   ' Sorry but AMOSPRO seems to require absolute include paths ??  
   '  SO,  YOU'LL HAVE TO TWEAK THE PATHS IN ORDER TO RUN
   '  THE DEMOS FROM AMOS/AMOSPRO correctly on your machine    


   ' To make the pathing less annoying, here we store the 'root path'  
   '  in a variable APPPATH$ .. Then use this through our program.  


     APPPATH$="Dh0:/AGE_V102/"



    ' Set the location of the AGE lib..  
      AGE_LIBRARY_PATH$=APPPATH$+"Includes/Asm/Age.lib"

    ' Include the AGE wrapper into your AMOS project
      Include "Dh0:/AGE_V102/INCLUDES/AMOS/AGE_V064.AMOS"



'   *=-----------------------------------------------------------------=*    
'
'                        >> ALLOC AGE RESOURCE TABLEs <<
'
'   *=-----------------------------------------------------------------=*    

           SCRNS=15
           COPS=15
           BLKDATAS=10
           BANKS=11

           FONTS=12
           FILECACHESIZE=50000
           DCACHESIZE=10000

           AGE_ALLOC_RESOURCES[SCRNS,COPS,BLKDATAS,BANKS,FONTS,FILECACHESIZE,DCACHESIZE]




        ' -----------------------------------  
        ' Create our LOWRES / INTERLEAVED  AGE screen in Chip Memory
        ' -----------------------------------  

           TYPE=AGE_LOWRES
           TYPE=TYPE+AGE_INTERLEAVED
           AGE_OPEN_SCREEN[0,320,256,8,TYPE]



        ' -----------------------------------  
        '  Load IFF into this screen.  
        ' -----------------------------------  
           FILE$=APPPATH$+"GFXFILES/PICTURES/DRAGONAA.IFF"
           AGE_LOAD_IFF_TO_SCREEN[FILE$,0]



        ' -----------------------------------  
        '  Read the Colour Palette from the this screen
        ' -----------------------------------  

           Dim CURRENT_PALETTE(256)

           AGE_SCREEN_COPY_PALETTE_TO_ARRAY[0,Varptr(CURRENT_PALETTE(0))]




        ' -----------------------------------  
        ' Create a standard / simple copper list for viewing this screen.    
        ' -----------------------------------  
           AGE_OPEN_STANDARD_COPPER[0,0,3,8]



        ' -----------------------------------  
        '  Create copper to view our AGE screen  
        ' -----------------------------------  
           Doke $DFF096,$180 : Rem Kill Bitplane + copper DMA  

           AGE_WAIT_TOP_OF_FRAME

           AGE_SHOW_COPPER[0]

           Doke $DFF096,$8180 : Rem restore Bitplane + copper DMA  


        ' -----------------------------------  
        ' Direct ALL RENDERING To OUR Screen
        ' -----------------------------------  
           AGE_SET_SCREEN[0]









        ' -----------------------------------  
        '  Wait for a key
        ' -----------------------------------  
           Wait Key



        ' -----------------------------------  
        '  FAde Screen Out
        ' -----------------------------------  


        Dim TEMP_PALETTE(256)


       LEVEL=100

       Repeat


           LEVEL=LEVEL-2
           SCALE#=LEVEL/100.0

          ' --------------------------------------------------------
          ' Fade all the colours in our copy of the screens palette
          ' --------------------------------------------------------

           For LP=0 To 255
              ' grab the screens original palette colour
              C=CURRENT_PALETTE(LP)

              ' fade this colour by the required amount

               RGB_FADE[C,SCALE#]

              ' store the new colour in a second temp array of palette colours
               TEMP_PALETTE(LP)=Param
           Next



           AGE_WAIT_TOP_OF_FRAME


          ' get a pointer to the Faded array of colour values
           PAL_POINTER=Varptr(TEMP_PALETTE(0))

          '  Copy this array of colour values to this copper list
           AGE_REFRESH_COPPER_PALETTE[0,PAL_POINTER]

       Until LEVEL<1

        ' -----------------------------------  
        ' Clean Up/Close Down AGE  
        ' -----------------------------------  
           AGE_CLEAN_UP



      Just picking through the library,  there does seem to be some command sets that require specially formatted external data such as FONTS and MAPS.  I haven't looked at the block map stuff, but fonts seems to have some problems in the updated version of the Library.   Hopefully that's an easy fix, as if it's not,  it may well stay broken.  We'll see.  

Title: Re: AGE Development Blog (Advanced Graphics Engine for AmosPro / Amiga)
Post by: kevin on March 20, 2012, 08:39:11 AM
AGE - Double Buffering / Animation

     Been picking through the library in my spare time, it's a bit hit and miss as to some things.  Took a while to set up a working double buffering example, not because the buffer swapping wasn't working, it turned out that the LINE function has a bug in it, where it will only draw to SCREEN 0.  So you can draw to one frame buffer and not the other. 

     Anyway so here we have simple set up example.  The demo creates two frame buffers and two copper lists, a variable CURRENT_BUFFER is the index of the current SCREEN we're rendering to, so while we're drawing to CURRENT_SCREEN, we show the other screens copper list.    The main loop is of the demo is copying a 256 colour picture to the current screen, then draws some orbiting filled circles over the top. 



Set Buffer 50

' *=-------------------------------------------------------------------=*
'
'                      AGE - DOUBLE BUFFER / ANIMATION     
'
'                                      By 
'
'                                By Kevin Picone
'
'                         Last Updated - 19th, Mar, 2012                   
'
'                (c) Copyright 1997/98/1999/2000- 2012, Kevin Picone
'
'                             www.UnderwareDesign.com       
'
' *=-------------------------------------------------------------------=*


    ' Sorry but AMOSPRO seems to require absolute include paths ??   
    '  SO,  YOU'LL HAVE TO TWEAK THE PATHS IN ORDER TO RUN
    '  THE DEMOS FROM AMOS/AMOSPRO correctly on your machine     


    ' To make the pathing less annoying, here we store the 'root path'   
    '  in a variable APPPATH$ .. Then use this through our program. 


      APPPATH$="Dh0:/AGE_V102/"



     ' Set the location of the AGE lib.. 
       AGE_LIBRARY_PATH$=APPPATH$+"Includes/Asm/Age.lib"

     ' Include the AGE wrapper into your AMOS project
       Include "Dh0:/AGE_V102/INCLUDES/AMOS/AGE_V067.AMOS"



'   *=-----------------------------------------------------------------=*   
'
'                        >> ALLOC AGE RESOURCE TABLEs <<
'
'   *=-----------------------------------------------------------------=*   

            SCRNS=15
            COPS=15
            BLKDATAS=10
            BANKS=11

            FONTS=12
            FILECACHESIZE=50000
            DCACHESIZE=10000

            AGE_ALLOC_RESOURCES[SCRNS,COPS,BLKDATAS,BANKS,FONTS,FILECACHESIZE,DCACHESIZE]


         ' ----------------------------------- 
         ' Create our LOWRES / INTERLEAVED  AGE screen in Chip Memory '
         ' ----------------------------------- 
             TYPE=AGE_LOWRES
'            TYPE=TYPE+AGE_INTERLEAVED
             TYPE=TYPE+AGE_PLANAR

             AGE_OPEN_SCREEN[0,320,256,8,TYPE]
             AGE_OPEN_SCREEN[1,320,256,8,TYPE]

             CURRENT_BUFFER=0


         ' ----------------------------------- 
         '  Load IFF into this a temp screen.   
         ' ----------------------------------- 

              FILE$=APPPATH$+"GFXFILES/PICTURES/DRAGONAA.IFF"
              AGE_OPEN_SCREEN[3,320,256,8,TYPE]
              AGE_LOAD_IFF_TO_SCREEN[FILE$,3]

        ' copy the palette from the backdrop picture in the chip buffers

              AGE_SCREEN_COPY_PALETTE[3,0]
              AGE_SCREEN_COPY_PALETTE[3,1]


         ' ----------------------------------- 
         ' Create two copper lists for viewing our screens.   
         ' ----------------------------------- 
              AGE_CREATE_COPPER[0,0,3,8]
              AGE_CREATE_COPPER[1,1,3,8]


         ' ----------------------------------- 
         '  Set copper to view our AGE screen   
         ' ----------------------------------- 
             Doke $DFF096,$180 : Rem Kill Bitplane + copper DMA   

             AGE_WAIT_TOP_OF_FRAME

             AGE_SHOW_COPPER[1-CURRENT_BUFFER]

             Doke $DFF096,$8180 : Rem restore Bitplane + copper DMA 


        ' ----------------------------------- 
        ' Direct ALL RENDERING To OUR Screen
        ' ----------------------------------- 
             AGE_SET_SCREEN[CURRENT_BUFFER]


       ' ----------------------------------- 
       ' Load a Font
       ' ----------------------------------- 

             FONTS$=APPPATH$+"gfxfiles/fonts/"
             AGE_LOAD_FONT[FONTS$+"Alex8.font",2]
             AGE_SET_FONT[2]


       ' ----------------------------------- 
'
       ' ----------------------------------- 

Degree

        Do




          ' -------------------------------------------------
          ' Swap Buffers
          ' -------------------------------------------------

              CURRENT_BUFFER=1-CURRENT_BUFFER

              AGE_SET_SCREEN[CURRENT_BUFFER]

              AGE_SET_COPPER[(1-CURRENT_BUFFER)]

              AGE_WAIT_TOP_OF_FRAME


          ' -------------------------------------------------
          ' Copy the temp image to the current render buffer
          ' -------------------------------------------------

             AGE_COPY_SCREEN[3,0,0,320,256,CURRENT_BUFFER,0,0]


          ' -------------------------------------------------
          ' Draw spinning circles
          ' -------------------------------------------------

            RENDER_STAR[160,128,BASEANGLE]
            BASEANGLE=(BASEANGLE+1) mod 360


          ' ---------------------------
          ' Render some text on the scene 
          ' ---------------------------

             AGE_TEXT["Double Buffering",10,10,1]


          ' ---------------------------
          ' Check for key press
          ' ---------------------------

             KEYPRESS$=Inkey$()
             If KEYPRESS$=" " Then Exit

        Loop



         ' ----------------------------------- 
         ' Clean Up/Close Down AGE 
         ' ----------------------------------- 
            AGE_CLEAN_UP


           End



Procedure RENDER_STAR[X,Y,BASEANGLE]

       ' -----------------------------------------------------------------
       ' Draw a bunch of rotating circles in orbit around the screen center
       ' -----------------------------------------------------------------

           AGE_OWN_BLITTER

            For ANGLE=0 To 359 Step 30

                ANGLE2=BASEANGLE+ANGLE
              '  ANGLE2=ANGLE mod 360

                X2=X+Cos(ANGLE2)*100
                Y2=Y+Sin(ANGLE2)*100

                Inc INDEX
                AGE_INK[INDEX]

                AGE_CIRCLE[X2,Y2,20]



            Next

            AGE_DISOWN_BLITTER

End Proc











Title: Re: AGE Development Blog (Advanced Graphics Engine for AmosPro / Amiga)
Post by: kevin on March 21, 2012, 11:15:36 AM
AGE - Gouraud Shaded Cube in Amos Pro (AGA)

    Tonights little goal was to get the C2P side of library all tested,  so I can throw together some examples to wrap it all up... But you know as soon as you make plans,  the ground shifts and another adjustment is required.  On this occasion, it turns out the C2p conversion routines in the library weren't working anymore after the port.   Was initially thinking the issue was just me not remembering how to set up the buffers anymore (it's been over 12 years after all all), but after some trail and error it turns out the Chunky to planar conversion routines weren't working.  Which after a bit more detective work, the fault was caused by the new assembler optimizing out what it through was redundant offsets, but that's fixed now.  

     So bellow we have a picture of an AMOS PRO remake of the gouraud shaded cube demo (the demo found in the PLLBC2p library).  Now granted  it's not going to be as fast as the native assembly version,  given that's doing more work than that demo, but it's still fairly quick when running under JIT enabled emulation,  without even compiling the demo.  Moreover, the library doesn't have any built in rotation support, so all the rotation/ projection and back face culling are running in little old AMOS.

     Will post a video later..  



AGE Gouraud Cube  (AmosPro / Amiga AGA)

In this video, I'm using the AGE library from AmosPRO to draw a chunky 8Bit AGA scene with gouraud shaded cube.  The program is drawing the 320*256 backdrop picture, some orbiting circles and the gouraud shaded cube each frame.  All the grunt work is done by the library, expect the 3D stuff (rotation/projection/back face culling) which is done in little old Amos.  

 The clip is recording running from WinUAE with no jit and without compiling the Amos example.  It runs surprisingly quickly with JIT, even the Amos Interpreter, so it should give those Amos fans a bit of fun.  

Developed By:
https://www.underwaredesign.com







Here's the AmosPro source code to this demo.



Set Buffer 50

' *=-------------------------------------------------------------------=*
'
'                              AGE - GOURAUD CUBE      
'
'                                      By  
'
'                                By Kevin Picone
'
'                         Last Updated - 21st, Mar, 2012                  
'
'                (c) Copyright 1997/98/1999/2000- 2012, Kevin Picone
'
'                             www.UnderwareDesign.com        
'
' *=-------------------------------------------------------------------=*
'

   ' Sorry but AMOSPRO seems to require absolute include paths ??  
   '  SO,  YOU'LL HAVE TO TWEAK THE PATHS IN ORDER TO RUN
   '  THE DEMOS FROM AMOS/AMOSPRO correctly on your machine    


   ' To make the pathing less annoying, here we store the 'root path'  
   '  in a variable APPPATH$ .. Then use this through our program.  


     APPPATH$="Dh0:/AGE_V102/"



    ' Set the location of the AGE lib..  
      AGE_LIBRARY_PATH$=APPPATH$+"Includes/Asm/Age.lib"

    ' Include the AGE wrapper into your AMOS project
      Include "Dh0:/AGE_V102/INCLUDES/AMOS/AGE_V069.AMOS"



'   *=-----------------------------------------------------------------=*    
'
'                        >> ALLOC AGE RESOURCE TABLEs <<
'
'   *=-----------------------------------------------------------------=*    

           SCRNS=15
           COPS=15
           BLKDATAS=10
           BANKS=11

           FONTS=12
           FILECACHESIZE=50000
           DCACHESIZE=10000

           AGE_ALLOC_RESOURCES[SCRNS,COPS,BLKDATAS,BANKS,FONTS,FILECACHESIZE,DCACHESIZE]


        ' -----------------------------------  
        ' Create our LOWRES / PLANAR  AGE screens in Chip Memory  
        ' -----------------------------------  
            TYPE=AGE_LOWRES+AGE_PLANAR

            AGE_OPEN_SCREEN[0,320,256,8,TYPE]
            AGE_OPEN_SCREEN[1,320,256,8,TYPE]



            CURRENT_BUFFER=0


        ' -----------------------------------  
        ' CReate CHUNKY temp screen.    
        ' -----------------------------------  

            CHUNKY_BUFFER=3

            AGE_OPEN_CHUNKY_SCREEN[CHUNKY_BUFFER,320,256]



        ' -----------------------------------  
        '  Load IFF into another chunky screen.  
        ' -----------------------------------  

             CHUNKY_PICTURE=4

              FILE$=APPPATH$+"GFXFILES/PICTURES/DRAGONAA_156.IFF"

            AGE_OPEN_CHUNKY_SCREEN[CHUNKY_PICTURE,320,256]
            AGE_LOAD_IFF_TO_SCREEN[FILE$,CHUNKY_PICTURE]

       ' Fill the palette with a gradient from colours 256 to 255
            MAKE_PALETTE[CHUNKY_PICTURE,$443355,$FFBB88,156,255]

' Copy the pictures palette to the chunk buffers
             AGE_SCREEN_COPY_PALETTE[CHUNKY_PICTURE,0]
             AGE_SCREEN_COPY_PALETTE[CHUNKY_PICTURE,1]





        ' -----------------------------------  
        ' Create standard / simple copper list for viewing our screens.    
        ' -----------------------------------  
             AGE_CREATE_COPPER[0,0,3,8]
             AGE_CREATE_COPPER[1,1,3,8]


        ' -----------------------------------  
        '  Set copper to view our AGE screen  
        ' -----------------------------------  
            Doke $DFF096,$180 : Rem Kill Bitplane + copper DMA  

            AGE_WAIT_TOP_OF_FRAME

            AGE_SHOW_COPPER[1-CURRENT_BUFFER]

            Doke $DFF096,$8180 : Rem restore Bitplane + copper DMA  



       Degree


Gosub _INIT_3D



       Do


         ' -------------------------------------------------
         ' Swap Buffers
         ' -------------------------------------------------


             AGE_C2P_SCRN_CLS[CHUNKY_BUFFER,CURRENT_BUFFER]


             CURRENT_BUFFER=1-CURRENT_BUFFER

             AGE_SET_COPPER[(1-CURRENT_BUFFER)]

             AGE_WAIT_TOP_OF_FRAME

             AGE_SET_SCREEN[CHUNKY_BUFFER]



             AGE_COPY_SCREEN[CHUNKY_PICTURE,0,0,320,256,CHUNKY_BUFFER,0,0]





         ' -------------------------------------------------
         ' Copy the temp image to the current render buffer
         ' -------------------------------------------------

             RENDER_STAR[160,128,BASEANGLE]

             BASEANGLE=(BASEANGLE+1) mod 360



         ' -------------------------------------------------
         ' Render 3D Scene
         ' -------------------------------------------------

   Gosub _UPDATE_3D



            KEYPRESS$=Inkey$()
            If KEYPRESS$=" " Then Exit

       Loop


        ' -----------------------------------  
        ' Clean Up/Close Down AGE  
        ' -----------------------------------  
           AGE_CLEAN_UP


          End




'  ---------------------------------------------------------------
'    -----------------------------------------------------------  
'     -------------->> SUB ROUTINES & FUNCTIONS <<-------------
'    -----------------------------------------------------------  
'  ---------------------------------------------------------------  

_INIT_3D:


   'Define our number system.  In this demo i'm using 24:8
   ' (24 bit whole part, 8 bit fractional) fixed point  

     Global ACC
     ACC=256



   ' Vertex Buffer for the object, XYZ order groups of 3
    Dim VERTEX_BUFFER(2000)

   ' Rotated vertex buffer
    Dim ROTATED_VERTEX_BUFFER(2000)

   ' Face list for Object
     Dim FACE_LIST(1000)

   '  CReate SIN/COS Tables
     Dim CS(720)
     Dim SN(720)
     Shared CS()
     Shared SN()

     INIT_MATH_TABLES[720]


    ' CReate a Cube mesh in the vertex buffer array

      PTR=Varptr(VERTEX_BUFFER(0))

      INIT_CUBE_VERTEX_BUFFER[PTR,BX_WIDTH,BX_HEIGHT,BX_DEPTH]

      PTR=Varptr(FACE_LIST(0))

      INIT_CUBE_FACE_LIST[PTR]

      FACECOUNT=Param


    Return



'  ---------------------------------------------------------------
'    -----------------------------------------------------------  
'          -------------->> UPDATE 3D SCENE <<-------------
'    -----------------------------------------------------------  
'  ---------------------------------------------------------------  

_UPDATE_3D:


     SRCPTR=Varptr(VERTEX_BUFFER(0))
     DESTPTR=Varptr(ROTATED_VERTEX_BUFFER(0))


      VERTS=8

      ROTATE_POINTS[SRCPTR,DESTPTR,8,160,128,300,ALPHA,BETA,GAMMA]

      ALPHA=(ALPHA+1) mod 360
      BETA=(BETA+2) mod 360
       GAMMA=(GAMMA+3) mod 360

      VERTCOUNT=(VERTS-1)*3
       For LP=0 To VERTCOUNT Step 3

           X=ROTATED_VERTEX_BUFFER(LP)
           Y=ROTATED_VERTEX_BUFFER(LP+1)

           AGE_CIRCLEC[X,Y,5,100]


       Next


      COUNT=(FACECOUNT-1)*3
       For LP=0 To COUNT Step 3

           V1=FACE_LIST(LP)*3
           V2=FACE_LIST(LP+1)*3
           V3=FACE_LIST(LP+2)*3

           X1=ROTATED_VERTEX_BUFFER(V1)
           Y1=ROTATED_VERTEX_BUFFER(V1+1)

           X2=ROTATED_VERTEX_BUFFER(V2)
           Y2=ROTATED_VERTEX_BUFFER(V2+1)

           X3=ROTATED_VERTEX_BUFFER(V3)
           Y3=ROTATED_VERTEX_BUFFER(V3+1)

           AX=X2-X1
           AY=Y2-Y1
 
           BX=X3-X1
           BY=Y3-Y1

           If((AX*BY)-(BX*AY))<0

            Z1=ROTATED_VERTEX_BUFFER(V1+2)
            Z2=ROTATED_VERTEX_BUFFER(V2+2)
            Z3=ROTATED_VERTEX_BUFFER(V3+2)

            C1=(Z1/500.0)*100
            C2=(Z2/500.0)*100
            C3=(Z3/500.0)*100
Add C1,156
Add C2,156
Add C3,156

                AGE_GOURAUDTRI[X1,Y1,C1,X2,Y2,C2,X3,Y3,C3]

           End If

       Next

     Return




'  ---------------------------------------------------------------
'    -----------------------------------------------------------  
'          -------->> INIT MATH (COS/SIN) Tables <<----------
'    -----------------------------------------------------------  
'  ---------------------------------------------------------------  


Procedure INIT_MATH_TABLES[SIZE]
  For LP=0 To SIZE
      CS(LP)=Cos(LP)*ACC
      SN(LP)=Sin(LP)*ACC
  Next
End Proc


' --------------------------------------------------------------------
'    ROTATE POINTS
' --------------------------------------------------------------------

Procedure ROTATE_POINTS[SRCPTR,DESTPTR,VERTS,XPOS,YPOS,ZPOS,ALPHA,BETA,GAMMA]

  AX=ALPHA
  AY=BETA
  AZ=GAMMA

' cos&sin alpha pre calcs
  CA=CS(AX)
  SA=SN(AX)

' Cos & Sin Beta pre calc
  CB=CS(AY)
  SB=SN(AY)


' Cos & Sin Gamma pre calcs
  CG=CS(AZ)
  SG=SN(AZ)

  XPOS2=XPOS*ACC
  YPOS2=YPOS*ACC


     For I=0 To VERTS
 
        X=Leek(SRCPTR)
        Y=Leek(SRCPTR+4)
        Z=Leek(SRCPTR+8)

        SRCPTR=SRCPTR+12

        Y2=((Y*CA)+(Z*SA))/ACC
        Z=((Z*CA)-(Y*SA))/ACC
     '   Y=Y2
        X2=((X*CB)+(Z*SB))/ACC
        Z=((Z*CB)-(X*SB))/ACC
        '   X=X2
        Y=(Y2*CG)+(X2*SG)
        X=(X2*CG)-(Y2*SG)
 
        Add Z,ZPOS


        Loke DESTPTR,(X/Z)+XPOS
        Loke DESTPTR+4,(Y/Z)+YPOS
        Loke DESTPTR+8,Z

        DESTPTR=DESTPTR+12


  Next I


End Proc



Procedure INIT_CUBE_VERTEX_BUFFER[VERTBUFFERPTR,BX_WIDTH,BX_HEIGHT,BX_DEPTH]

  BX_WIDTH=120
  BX_HEIGHT=120
  BX_DEPTH=120

  DESTPTR=VERTBUFFERPTR

  For Z=1 To -1 Step -2

     ZPOS=(BX_DEPTH/2)*(Z)

     For Y=-1 To 1 Step 2

        YPOS=(BX_HEIGHT/2)*(Y)
        For X=-1 To 1 Step 2
       
           XPOS=(BX_WIDTH/2)*(X)

           Loke DESTPTR,XPOS
           Loke DESTPTR+4,YPOS
           Loke DESTPTR+8,ZPOS

           DESTPTR=DESTPTR+12

        Next X
     Next Y
  Next Z


End Proc



Procedure INIT_CUBE_FACE_LIST[FACEBUFFERPTR]

  PTR=FACEBUFFERPTR

 ' front  
  SET_FACE[PTR,0,1,3] : Add PTR,12
  SET_FACE[PTR,0,3,2] : Add PTR,12

 ' Back  
  SET_FACE[PTR,5,4,6] : Add PTR,12
  SET_FACE[PTR,5,6,7] : Add PTR,12


 ' top      
  SET_FACE[PTR,4,5,1] : Add PTR,12
  SET_FACE[PTR,4,1,0] : Add PTR,12

 ' bottom      
  SET_FACE[PTR,2,3,7] : Add PTR,12
  SET_FACE[PTR,2,7,6] : Add PTR,12


 ' left      
  SET_FACE[PTR,0,2,6] : Add PTR,12
  SET_FACE[PTR,0,6,4] : Add PTR,12

 ' right        
  SET_FACE[PTR,1,5,7] : Add PTR,12
  SET_FACE[PTR,1,7,3] : Add PTR,12



 FACECOUNT=12

End Proc[FACECOUNT]



Procedure SET_FACE[PTR,V1,V2,V3]
  Loke PTR,V1
  Loke PTR+4,V2
  Loke PTR+8,V3
End Proc








Procedure RENDER_STAR[X,Y,BASEANGLE]

        AGE_INK[1]

      ' -----------------------------------------------------------------
      ' Draw a bunch of rotating circles in orbit around the screen center
      ' -----------------------------------------------------------------

           For ANGLE=0 To 359 Step 20

               ANGLE2=BASEANGLE+ANGLE
             '  ANGLE2=ANGLE mod 360

               X2=X+Cos(ANGLE2)*100
               Y2=Y+Sin(ANGLE2)*100


               AGE_CIRCLE[X2,Y2,20]

               Inc INDEX
                AGE_INK[INDEX]


           Next


End Proc



Procedure MAKE_PALETTE[THISSCREEN,RGB1,RGB2,INDEX_START,INDEX_END]

   RANGE#=INDEX_END-INDEX_START

   For LP=0 To RANGE#

      SCALER#=LP/RANGE#

      RGB_ALPHA_BLEND[RGB1,RGB2,SCALER#]
      AGE_SCREEN_SET_PALETTE_COLOUR[THISSCREEN,INDEX_START+LP,Param]
    Next

End Proc




Title: Re: AGE Development Blog (Advanced Graphics Engine for AmosPro / Amiga)
Post by: ATLUS on March 21, 2012, 11:31:52 AM
hmm nice pictures =)
Title: Re: AGE Development Blog (Advanced Graphics Engine for AmosPro / Amiga)
Post by: kevin on March 23, 2012, 01:08:01 AM
AGE - 300 triangle Gouraud Donut (Torus) in Amos Pro ( AGA)

     This is only a small step from the previous demo, here we're just upping the vertex and polygon counts dramatically,  from the humble cube of 6 verts and 12 polygons (triangles), to a 300 triangle torus..  While the scene  / polygon count are old hat for assembly programmers on the AMIGA,  I don't recall ever seeing anything in AMOS do this,  so it's likely to be world first in AMOS anyway. 

     The demo is doing all the 3D worlk in interpreted AMOS, so it's rotating / projecting and rotating the 150 vertexes, back facing and rendering the 300 faces (approximate 150 odd visible faces),  the drawing all AGE obviously..  But it shows that you can certainly have a bit of fun with the library if you put your mind to it.   

Title: Re: AGE Development Blog (Advanced Graphics Engine for AmosPro / Amiga)
Post by: kevin on March 28, 2012, 10:16:14 AM
   AGE-  Copy Rect / Copy Rect Queue

     Still making my way through the commands when free time appears, fixed a number of little issues here and there.  Most of the changes have been to function names or adding the odd little helper function.   In the older version of the library, there's a copy image / rect function, with a long but complete name, while descriptive, it wasn't practical.  So that's been renamed to AGE_COPY_RECT.  This function copies 'blocks' of graphics from one screen surface to another.   Now since we're running the library from interpreted AMOS,  you'll notice there's some QUEUED versions of functions also. Basically, these allows us to set to list of things to draw as batch.  


     In the example bellow we're using the Copy Rect Queue function to create a randomized scrolling block map.  To build the queue, we need to allocate some memory of suitable size, here i'm using an array but you can use a bank or whatever.    Each item in the queue is 16 bytes,  so to store a 100 items in the queue you'd allocate 100*16 bytes.    To write to the queue there's a helper function called AGE_SET_RECT_QUEUE  which requires the pointer to the first item in the queue, the Offset this item should be stored at, then Screen Index, source rect and destination and location.  For this example it's just randomly picking 16*16 blocks from the dragon picture.  

     Now to help avoid some Amos overhead, we can draw the queue with an X and Y offset.  So to make the scene scroll, we're just drawing the queue items offset from their output location.  




  Set Buffer 100

' *=-------------------------------------------------------------------=*
'
'                AGE - Copy Rect Queues (Block Map Example)
'
'                                      By  
'
'                                By Kevin Picone
'
'                         Last Updated - 28th, Mar, 2012                  
'
'                (c) Copyright 1997/98/1999/2000- 2012, Kevin Picone
'
'                             www.UnderwareDesign.com        
'
' *=-------------------------------------------------------------------=*
'

   ' Sorry but AMOSPRO seems to require absolute include paths ??  
   '  SO,  YOU'LL HAVE TO TWEAK THE PATHS IN ORDER TO RUN
   '  THE DEMOS FROM AMOS/AMOSPRO correctly on your machine    


   ' To make the pathing less annoying, here we store the 'root path'  
   '  in a variable APPPATH$ .. Then use this through our program.  


     APPPATH$="Dh0:/AGE_V102/"



    ' Set the location of the AGE lib..  
      AGE_LIBRARY_PATH$=APPPATH$+"Includes/Asm/Age.lib"

    ' Include the AGE wrapper into your AMOS project
      Include "Dh0:/AGE_V102/INCLUDES/AMOS/AGE_V071.AMOS"



'   *=-----------------------------------------------------------------=*    
'
'                        >> ALLOC AGE RESOURCE TABLEs <<
'
'   *=-----------------------------------------------------------------=*    

           SCRNS=15
           COPS=15
           BLKDATAS=10
           BANKS=11

           FONTS=12
           FILECACHESIZE=50000
           DCACHESIZE=10000

           AGE_ALLOC_RESOURCES[SCRNS,COPS,BLKDATAS,BANKS,FONTS,FILECACHESIZE,DCACHESIZE]


        ' -----------------------------------  
        ' Create our LOWRES / PLANAR  AGE screens in Chip Memory  
        ' -----------------------------------  
            TYPE=AGE_LOWRES+AGE_PLANAR

            AGE_OPEN_SCREEN[0,320,256,8,TYPE]
            AGE_OPEN_SCREEN[1,320,256,8,TYPE]


            CURRENT_BUFFER=0


        ' -----------------------------------  
        ' CReate  Load IFF into this a temp screen.    
        ' -----------------------------------  

            CHUNKY_BUFFER=3

            AGE_OPEN_CHUNKY_SCREEN[CHUNKY_BUFFER,320,256]



        ' -----------------------------------  
        '  Load IFF into this a temp screen.  
        ' -----------------------------------  

             CHUNKY_PICTURE=4

            FILE$=APPPATH$+"GFXFILES/PICTURES/DRAGONAA_156.IFF"

            AGE_OPEN_CHUNKY_SCREEN[CHUNKY_PICTURE,320,256]
            AGE_LOAD_IFF_TO_SCREEN[FILE$,CHUNKY_PICTURE]


       ' copy the palette from the backdrop picture in the chip buffers


             AGE_SCREEN_COPY_PALETTE[CHUNKY_PICTURE,0]
             AGE_SCREEN_COPY_PALETTE[CHUNKY_PICTURE,1]





        ' -----------------------------------  
        ' Create standard / simple copper list for viewing our screens.    
        ' -----------------------------------  
             AGE_CREATE_COPPER[0,0,3,8]
             AGE_CREATE_COPPER[1,1,3,8]


        ' -----------------------------------  
        '  Set copper to view our AGE screen  
        ' -----------------------------------  
            Doke $DFF096,$180 : Rem Kill Bitplane + copper DMA  

            AGE_WAIT_TOP_OF_FRAME

            AGE_SHOW_COPPER[1-CURRENT_BUFFER]

            Doke $DFF096,$8180 : Rem restore Bitplane + copper DMA  



       Degree





        ' -------------------------------------------------
        ' Init the scene
        ' -------------------------------------------------


           Gosub _CREATE_RECT_QUEUE



           AGE_SET_SCREEN[CHUNKY_BUFFER]


       Do


         ' -------------------------------------------------
         ' Swap Buffers
         ' -------------------------------------------------


             AGE_C2P[CHUNKY_BUFFER,CURRENT_BUFFER]

             CURRENT_BUFFER=1-CURRENT_BUFFER

             AGE_SET_COPPER[(1-CURRENT_BUFFER)]

             AGE_WAIT_TOP_OF_FRAME


         ' -------------------------------------------------
         ' Copy the Backdrop picture to the main chunky buffer screen
         ' -------------------------------------------------

         '    AGE_COPY_RECT[CHUNKY_PICTURE,0,0,319,256,CHUNKY_BUFFER,-SCRLLX,0]
         '    AGE_COPY_RECT[CHUNKY_PICTURE,0,0,319,256,CHUNKY_BUFFER,-SCRLLX+320,0]

              AGE_COPY_RECT_QUEUE[QUEUE_POINTER,-SCRLLX,-SCRLLY,BLOCK_COUNT]
              AGE_COPY_RECT_QUEUE[QUEUE_POINTER,-SCRLLX+320,-SCRLLY,BLOCK_COUNT]


              AGE_COPY_RECT_QUEUE[QUEUE_POINTER,-SCRLLX,-SCRLLY+256,BLOCK_COUNT]
              AGE_COPY_RECT_QUEUE[QUEUE_POINTER,-SCRLLX+320,-SCRLLY+256,BLOCK_COUNT]


              SCRLLX=(SCRLLX+1) mod 320
              SCRLLY=(SCRLLY+1) mod 256



         ' -------------------------------------------------
         ' Check for any key presses
         ' -------------------------------------------------

            KEYPRESS$=Inkey$()
            If KEYPRESS$=" " Then Exit

       Loop


        ' -----------------------------------  
        ' Clean Up/Close Down AGE  
        ' -----------------------------------  
           AGE_CLEAN_UP


   End





'  ---------------------------------------------------------------
'    -----------------------------------------------------------  
'     -------------->> SUB ROUTINES & FUNCTIONS <<-------------
'    -----------------------------------------------------------  
'  ---------------------------------------------------------------  

_CREATE_RECT_QUEUE:


        ' -------------------------------------------------
        ' Fill the Copy Rect Queue
        ' -------------------------------------------------

           ' This routine makes a queue of 100,  16*16 block
           ' to be drawn at a target.  The target can be offset
           ' at run time. So you cna make block map.

            BLOCKS_WIDE=(320/16)
            BLOCKS_HIGH=(256/16)


            BLOCK_COUNT=BLOCKS_WIDE*BLOCKS_HIGH


          ' DIm an array to hold all the queue data in.
          ' each queue item takes 16 bytes

            Dim BLOCKQUEUE((BLOCK_COUNT+1)*16)


            QUEUE_POINTER=Varptr(BLOCKQUEUE(0))

         ' Fill in the queue wwith the copy rects

          For LP=0 To BLOCK_COUNT-1

              THISBLOCK=Rnd(BLOCK_COUNT-1)

              SRCY1=THISBLOCK/BLOCKS_WIDE
              SRCX1=THISBLOCK mod BLOCKS_WIDE

              SRCX1=SRCX1*16
              SRCY1=SRCY1*16

              SRCX2=SRCX1+16
              SRCY2=SRCY1+16

              AGE_SET_RECT_QUEUE[QUEUE_POINTER,LP,CHUNKY_PICTURE,SRCX1,SRCY1,SRCX2,SRCY2,CHUNKY_BUFFER,DEST_XPOS,DEST_YPOS]

              DEST_XPOS=DEST_XPOS+16
              If DEST_XPOS=>320

                    DEST_XPOS=0
                    DEST_YPOS=DEST_YPOS+16

              End If

          Next

    Return






Title: Re: AGE Development Blog (Advanced Graphics Engine for AmosPro / Amiga AGA)
Post by: kevin on March 30, 2012, 01:17:51 PM

   AGE-  Star Field / Dot Queue

       In keeping with the previous demo,  here we're another golden oldie, the star field.   The demo is drawing 5 layers of 500 pixels (in chunky) over the top of the scrolling picture and the orbiting circles.  Yep, it's cut 'n;paste from the same template as most of the other demos are.    Each layer of dots is scrolling faster than the previous layer. 

       To make the star field,  we're creating a dot queue for each layer in the scene.  This time rather than use Amos arrays for our queue data, were allocated AGE Bank's for each queue.   Then storing random dot positions in the queue's via the helper function AGE_SET_DOT_QUEUE.  This function write the coordinate and colour into our allocated buffer.    Each dot in the queue costs us  6 bytes, (16bit X, 16bit Y, 16bit Colour).  So the size of the dot queue of 50 points is going to use up (50*6)=300 bytes. 

       Just like the copy rect demo, we're able to render a queue offset from a user defined position. So to make the fields move, we're just bumping a scroll speed variable  each layer. Then using that to offset the batch.
 


   Set Buffer 100

' *=-------------------------------------------------------------------=*
'
'                  AGE - Star Field (DOT QUEUE Example)
'
'                                      By 
'
'                                By Kevin Picone
'
'                         Last Updated - 31st, Mar, 2012                   
'
'                (c) Copyright 1997/98/1999/2000- 2012, Kevin Picone
'
'                             www.UnderwareDesign.com       
'
' *=-------------------------------------------------------------------=*
'

    ' Sorry but AMOSPRO seems to require absolute include paths ??   
    '  SO,  YOU'LL HAVE TO TWEAK THE PATHS IN ORDER TO RUN
    '  THE DEMOS FROM AMOS/AMOSPRO correctly on your machine     


    ' To make the pathing less annoying, here we store the 'root path'   
    '  in a variable APPPATH$ .. Then use this through our program. 


      APPPATH$="Dh0:/AGE_V102/"



     ' Set the location of the AGE lib.. 
       AGE_LIBRARY_PATH$=APPPATH$+"Includes/Asm/Age.lib"

     ' Include the AGE wrapper into your AMOS project
       Include "Dh0:/AGE_V102/INCLUDES/AMOS/AGE_V072.AMOS"



'   *=-----------------------------------------------------------------=*   
'
'                        >> ALLOC AGE RESOURCE TABLEs <<
'
'   *=-----------------------------------------------------------------=*   

            SCRNS=15
            COPS=15
            BLKDATAS=10
            BANKS=11

            FONTS=12
            FILECACHESIZE=50000
            DCACHESIZE=10000

            AGE_ALLOC_RESOURCES[SCRNS,COPS,BLKDATAS,BANKS,FONTS,FILECACHESIZE,DCACHESIZE]


         ' ----------------------------------- 
         ' Create our LOWRES / PLANAR  AGE screens in Chip Memory   
         ' ----------------------------------- 
             TYPE=AGE_LOWRES+AGE_PLANAR

             AGE_OPEN_SCREEN[0,320,256,8,TYPE]
             AGE_OPEN_SCREEN[1,320,256,8,TYPE]


             CURRENT_BUFFER=0


         ' ----------------------------------- 
         ' CReate  Load IFF into this a temp screen.   
         ' ----------------------------------- 

             CHUNKY_BUFFER=3

             AGE_OPEN_CHUNKY_SCREEN[CHUNKY_BUFFER,320,256]



         ' ----------------------------------- 
         '  Load IFF into this a temp screen.   
         ' ----------------------------------- 

              CHUNKY_PICTURE=4

             FILE$=APPPATH$+"GFXFILES/PICTURES/DRAGONAA_156.IFF"

             AGE_OPEN_CHUNKY_SCREEN[CHUNKY_PICTURE,320,256]
             AGE_LOAD_IFF_TO_SCREEN[FILE$,CHUNKY_PICTURE]


        ' copy the palette from the backdrop picture in the chip buffers


              AGE_SCREEN_COPY_PALETTE[CHUNKY_PICTURE,0]
              AGE_SCREEN_COPY_PALETTE[CHUNKY_PICTURE,1]





         ' ----------------------------------- 
         ' Create standard / simple copper list for viewing our screens.   
         ' ----------------------------------- 
              AGE_CREATE_COPPER[0,0,3,8]
              AGE_CREATE_COPPER[1,1,3,8]


         ' ----------------------------------- 
         '  Set copper to view our AGE screen   
         ' ----------------------------------- 
             Doke $DFF096,$180 : Rem Kill Bitplane + copper DMA   

             AGE_WAIT_TOP_OF_FRAME

             AGE_SHOW_COPPER[1-CURRENT_BUFFER]

             Doke $DFF096,$8180 : Rem restore Bitplane + copper DMA 



        Degree





         ' -------------------------------------------------
         ' Init the scene
         ' -------------------------------------------------


            Gosub _CREATE_STAR_FIELDS


            AGE_SET_SCREEN[CHUNKY_BUFFER]


        Do


          ' -------------------------------------------------
          ' Swap Buffers
          ' -------------------------------------------------


              AGE_C2P[CHUNKY_BUFFER,CURRENT_BUFFER]

              CURRENT_BUFFER=1-CURRENT_BUFFER

              AGE_SET_COPPER[(1-CURRENT_BUFFER)]

              AGE_WAIT_TOP_OF_FRAME


          ' -------------------------------------------------
          ' Copy the Backdrop picture to the main chunky buffer screen
          ' -------------------------------------------------

               AGE_COPY_RECT[CHUNKY_PICTURE,0,0,319,256,CHUNKY_BUFFER,-SCRLLX,0]
               AGE_COPY_RECT[CHUNKY_PICTURE,0,0,319,256,CHUNKY_BUFFER,-SCRLLX+320,0]


               SCRLLX=(SCRLLX+1) mod 320
               SCRLLY=(SCRLLY+1) mod 256






          ' -------------------------------------------------
          ' Render a bunch of orbiting circles
          ' -------------------------------------------------

                 RENDER_CIRCLES[160,128,BASEANGLE]

                 BASEANGLE=(BASEANGLE+1) mod 360



          ' -------------------------------------------------
          ' Render Star field 
          ' -------------------------------------------------

               Gosub _RENDER_STAR_FIELD



          ' -------------------------------------------------
          ' Check for any key presses
          ' -------------------------------------------------

             KEYPRESS$=Inkey$()
             If KEYPRESS$=" " Then Exit

        Loop


         ' ----------------------------------- 
         ' Clean Up/Close Down AGE 
         ' ----------------------------------- 
            AGE_CLEAN_UP


    End





'  ---------------------------------------------------------------
'    -----------------------------------------------------------   
'     -------------->> SUB ROUTINES & FUNCTIONS <<-------------
'    -----------------------------------------------------------   
'  ---------------------------------------------------------------   

_CREATE_STAR_FIELDS:

     Global ACC
      ACC=256


     Dim CS(720)
     Dim SN(720)
     Shared CS()
     Shared SN()
     INIT_MATH_TABLES[720]


         ' -------------------------------------------------
         ' Each Star Field Is a  DOT Queue 
         ' -------------------------------------------------

            ' Number of dots in each layer

             STAR_COUNT=500


            ' Number of star Layers
             STAR_LAYERS=5


            ' Dim array to store the layers SCroll offsets

             Dim STAR_SCROLLX(STAR_LAYERS)



           ' Calc the size of the Star layer in bytes
             LAYER_SIZE_IN_BYTES=(STAR_COUNT+1)*6


           ' Init the star queue (buffers)
             For LP=0 To STAR_LAYERS-1
                 AGE_CREATE_BANK[LP,LAYER_SIZE_IN_BYTES]

                 AGE_GET_BANK_PTR[LP]

                 _FILL_QUEUE[Param,STAR_COUNT]

            Next

     Return




_RENDER_STAR_FIELD:


             For LP=0 To STAR_LAYERS-1


               AGE_GET_BANK_PTR[LP]
               QUEUE_POINTER=Param

               If QUEUE_POINTER

                  X=STAR_SCROLLX(LP)
                   X=X+(LP+1)
                   STAR_SCROLLX(LP)=X mod 320

                   AGE_DOT_QUEUE[QUEUE_POINTER,-X,0,STAR_COUNT]
                   AGE_DOT_QUEUE[QUEUE_POINTER,-X+320,0,STAR_COUNT]

               End If

            Next


   Return





'  ---------------------------------------------------------------
'  -----------------------------------------------------------   
'    >> FILL DOT QUEUE with random dots <<----------
'  -----------------------------------------------------------   
'  ---------------------------------------------------------------   


Procedure _FILL_QUEUE[PTR,STARS]

          ' Fill in the queue with some random pixels

           For STARLP=0 To STARS-1

               X=Rnd(319)
               Y=Rnd(255)
               C=Rnd(255)

               AGE_SET_DOT_QUEUE[PTR,STARLP,X,Y,C]

           Next
End Proc









'  ---------------------------------------------------------------
'  -----------------------------------------------------------   
'    >> INIT MATH (COS/SIN) Tables <<----------
'  -----------------------------------------------------------   
'  ---------------------------------------------------------------   


Procedure INIT_MATH_TABLES[SIZE]
   For LP=0 To SIZE
       CS(LP)=Cos(LP)*ACC
       SN(LP)=Sin(LP)*ACC
   Next
End Proc






' -----------------------------------------------------------------
' -----------------------------------------------------------------
'   >> Render Circles <<
' -----------------------------------------------------------------
' -----------------------------------------------------------------


Procedure RENDER_CIRCLES[X,Y,BASEANGLE]

         AGE_INK[1]


       ' -----------------------------------------------------------------
       ' Draw a bunch of rotating circles in orbit around the screen center
       ' -----------------------------------------------------------------

            For ANGLE=0 To 359 Step 10

                ANGLE2=BASEANGLE+ANGLE

                X2=CS(ANGLE2)*100
                Y2=SN(ANGLE2)*100

                X2=X+(X2/ACC)
                Y2=Y+(Y2/ACC)

                Inc INDEX

                AGE_CIRCLEC[X2,Y2,20,INDEX]

            Next


End Proc


Title: Re: AGE Development Blog (Advanced Graphics Engine for AmosPro / Amiga AGA)
Post by: kevin on April 01, 2012, 05:33:32 PM
   AGE - Texture Mapped Dragon

     AGE supports texture mapped triangles, the lib is a lot like PlayBASIC (http://www.playbasic.com) really, just not as complete.    The texture mapping works in AGE, but i'm not 100% happy with the rendering code,  mainly the edges conversion is a bit dodgy, so the left and right fill convention doesn't seem all that accurate.  I'd like to re-write it, and probably will, but better not just now.  

      Anyway, in this picture you can see the Dragon model (converted from quake MD2 format, into vertex and face lists)  spinning in the middle of the screen.  It's here we find a few omissions in the scene buffer implementation in AGE.   AGE uses a capturing interface where we create a Z buffer cache, then call special functions to buffer our items up in the cache.    When we're done, we call the Render scene function, which sorts and renders the scene. This eliminates the need to sort the triangles in AMOS.  The issue with the buffer is that it's missing support for texture mapped triangles.  So the scene bellow is not actually z buffered..  Will have to fix that in order to make the library more useful.  

      If you're wondering how fast this stuff is, well it's not express, but of you're only interested in AMOS programming under emulation, then with WinUAE's  JIT enabled it's quite fast considering.  It'll be interesting seeing what people can knock up with it.  
Title: Re: AGE Development Blog (Advanced Graphics Engine for AmosPro / Amiga AGA)
Post by: kevin on April 05, 2012, 05:16:56 PM
  AGE - Line Clipping

       As mentioned previously, the library has a lot of meat on the bones in some areas and then in others there's glaring omissions.    The line support was another part of the library that I'm not comfortable re-releasing as is.   There's a few reasons for this,  primarily the existing version of the LINE function only supports rendering to chip memory via Blitter and the clipping isn't stellar.   While it works, it's a bit of bottleneck.   But there's a problem looming for me, which is time and a complete lack of it for such side projects.

       To speed up development of the library and to make extending it more viable in the future, i'm now using a mixture of C and Assembly via VBCC / Phxass.  Which just means that in In terms of convenience, I can leverage the code base that PlayBASIC is based upon.   So far, i've just been tinkering with it tonight, but i'm already satisfied it's a workable solution.  Although was having a few dramas initially.. But the VBCC compiler seems more than  happy to produce some decent inner loops,  can always inline them if they're not.     

       One difference to the PB libraries is that AGE is all fixed point integer operations, where PB's is generally floating point with integer inner loops.   So rather than drag and drop the line clipper across, found myself having to write an integer version instead... yes... typical.. :) .  Anyway, whats interesting is that while I've looked at the older clipper a million times,  tonight it dawned on me there's another (pretty obvious) simplification just waiting to be implemented.   So with a little messing around, the pure integer version seems to work rather well in the test.  Will have to add that in not only to AGE, but PB also...

Title: Re: AGE Development Blog (Advanced Graphics Engine for AmosPro / Amiga AGA)
Post by: kevin on April 07, 2012, 08:41:30 AM

  AGE - Line Render (With Brute Force Clipping)

     Ok, so last nights little chore (see understatement..), was to drag some of the PB render functions over and make AGE friendly versions.   The PB backend is generally C++ (but with C styled render functions) and we're moving to VBCC which is a C compiler,  which creates a few syntax issues here and there.  But ya get that. 
 
     Figured I'd just use VBCC to process the C code to asm,  add some macros for our functions and bobs your uncle.     But soon run into some problems with compile speed and ultimately collision issues on the assembler side.   Had assumed the  C compiler would use local labels in the output, but it doesn't seem to, there may well be a switch to turn such a  feature on, I dunno.   

     How i imagined this working,  was that I'd  just compiling all the C stuff into one blob of assembly, renaming some labels and include.  But when compiling the code on the Amiga side,  through winUae with -O4 enabled, the process turned out to be  pretty time consuming, given it's length.  So figured a better (easier/quicker) solution would be to split the C side up into seperate stand alone files.   Then compile the parts are needed.  This works pretty well speed wise, but we get collisions in the output code from the labels. 

     To counter the collision hurdle, ended up writing a little app in PlayBASIC to run through and clean up the fragments.  So the work flow is drop the function into C,  convert that to 68K, clean the output code and include the resulting assembly output into AGE.   A bit of messing around, but not too bad, had worse.. :)  -   Could probably have written the line draw stuff in assembly is less time, but this is just easier all around.  Yeah, i'm getting lazy in my old age..

     Ok after all that messing around we're now got a Draw Line function that draw to chunky screens.   The version of the function you're looking at is brute force clipped (every dot is clipped to the viewport),  since i'm yet to drag the clipper across.  Had figured all that'd all be done yesterday, but then all the above happened.   None the less the routine works pretty well in AGE, when with brute force clipping.   This version only draws to chunky screens though, the old blitter based solution is used on planar screens.   The trouble with blitter version is there's all this latency between each planar pass.   Haven't tested it, but I've sneaking suspicion a cpu filler would be better.

     Anyway, here's a bit of scene made from the star field demo with some clipped lines on top of that.. 

   
Title: Re: AGE Development Blog (Advanced Graphics Engine for AmosPro / Amiga AGA)
Post by: kevin on April 08, 2012, 05:46:32 PM
  AGE - 8bit Planar Dot Render (Brute Force)

        After adding the chunky line function, i've been having somewhat of an adventure with dot rendering on planar surfaces.  Those who are familiar with planar know the pain for dot rendering to such surfaces.   While i've trimmed some fat from the PLANAR DOT rendering routines in AGE, it's certainly not going to be express.     But it's supported just in case you absolute have to have it.

       The dot plot routine basically is a loop of Bit Sets / Clears across the planes.  Rendering to an 8Bit surface, means there's 8 iterations per dot to set the correct colour.   Had a play with unrolling the bitsets, which seemed a little quicker, but couldn't justify the bulk of unrolling every colour combination would create.   Those you know some AMOS and a little 680x0 assembly knowledge,  you could probably allocate a bank and unroll the code into memory yourself then just call it.   This approach is commonly found in many old school Amiga demos..    

        Personally, I'd recommend you avoid Planar screen types altogether and just use CHUNKY screens and C2P the result to the planar display.   The performance of this approach  under emulation is pretty good with JIT enabled in WinUAE.. I'm guessing those more familiar with AMOS, will be able to squeeze out more performance than me also.    None of the examples are compiled in BTW,  I'm just running them through the AMOS interpreter, so there's certainly some meat on the bones performance wise.

       
       Anyway, here's the code for the demo.   Finally changed backdrop pictures.. :)  

   


Set Buffer 50

' *=-------------------------------------------------------------------=*
'
'             AGE - ANIMATION  - PLANAR DOT RENDERING (Brute Force)  
'
'                                      By  
'
'                                By Kevin Picone
'
'                         Last Updated - 9th, Apr, 2012                  
'
'                (c) Copyright 1997/98/1999/2000- 2012, Kevin Picone
'
'                             www.UnderwareDesign.com        
'
' *=-------------------------------------------------------------------=*
'

   ' Sorry but AMOSPRO seems to require absolute include paths ??  
   '  SO,  YOU'LL HAVE TO TWEAK THE PATHS IN ORDER TO RUN
   '  THE DEMOS FROM AMOS/AMOSPRO correctly on your machine    


   ' To make the pathing less annoying, here we store the 'root path'  
   '  in a variable APPPATH$ .. Then use this through our program.  


     APPPATH$="Dh0:/AGE_V102/"


    ' Set the location of the AGE lib..  
      AGE_LIBRARY_PATH$=APPPATH$+"Includes/Asm/Age.lib"

    ' Include the AGE wrapper into your AMOS project
      Include "Dh0:/AGE_V102/INCLUDES/AMOS/AGE_V074.AMOS"



'   *=-----------------------------------------------------------------=*    
'
'                        >> ALLOC AGE RESOURCE TABLEs <<
'
'   *=-----------------------------------------------------------------=*    

           SCRNS=15
           COPS=15
           BLKDATAS=10
           BANKS=11

           FONTS=12
           FILECACHESIZE=50000
           DCACHESIZE=10000

           AGE_ALLOC_RESOURCES[SCRNS,COPS,BLKDATAS,BANKS,FONTS,FILECACHESIZE,DCACHESIZE]


        ' -----------------------------------  
        ' Create our LOWRES / INTERLEAVED  AGE screen in Chip Memory '
        ' -----------------------------------  
            TYPE=AGE_LOWRES
'            TYPE=TYPE+AGE_INTERLEAVED
            TYPE=TYPE+AGE_PLANAR

            AGE_OPEN_SCREEN[0,320,256,8,TYPE]
            AGE_OPEN_SCREEN[1,320,256,8,TYPE]

            CURRENT_BUFFER=0



        ' -----------------------------------  
        '  Load IFF into this a temp screen.  
        ' -----------------------------------  

              FILE$=APPPATH$+"GFXFILES/PICTURES/TREE.IFF"

             AGE_OPEN_SCREEN[3,320,256,8,TYPE]
             AGE_LOAD_IFF_TO_SCREEN[FILE$,3]

       ' copy the palette from the backdrop picture in the chip buffers

             AGE_SCREEN_COPY_PALETTE[3,0]
             AGE_SCREEN_COPY_PALETTE[3,1]


        ' -----------------------------------  
        ' Create standard / simple copper list for viewing our screens.    
        ' -----------------------------------  
             AGE_CREATE_COPPER[0,0,3,8]
             AGE_CREATE_COPPER[1,1,3,8]


        ' -----------------------------------  
        '  Set copper to view our AGE screen  
        ' -----------------------------------  
            Doke $DFF096,$180 : Rem Kill Bitplane + copper DMA  

            AGE_WAIT_TOP_OF_FRAME

            AGE_SHOW_COPPER[1-CURRENT_BUFFER]

            Doke $DFF096,$8180 : Rem restore Bitplane + copper DMA  


       ' -----------------------------------  
       ' Direct ALL RENDERING To OUR Screen
       ' -----------------------------------  
            AGE_SET_SCREEN[CURRENT_BUFFER]


      ' -----------------------------------  
      ' Load a Font
      ' -----------------------------------  


            FONTS$=APPPATH$+"gfxfiles/fonts/"

            AGE_LOAD_FONT[FONTS$+"Alex8.font",2]

            AGE_SET_FONT[2]



Degree


            TIME=Timer
            REDRAWS=0
            FPS=0


       Do

         ' -------------------------------------------------
         ' Swap Buffers
         ' -------------------------------------------------

             CURRENT_BUFFER=1-CURRENT_BUFFER

             AGE_SET_SCREEN[CURRENT_BUFFER]

             AGE_SET_COPPER[(1-CURRENT_BUFFER)]

             AGE_WAIT_TOP_OF_FRAME


         ' -------------------------------------------------
         ' Copy the temp image to the current render buffer
         ' -------------------------------------------------

            AGE_COPY_RECT[3,0,0,320,256,CURRENT_BUFFER,0,0]


         ' -------------------------------------------------
         ' Draw Layer Of Colour Dots to the 8bit planar screen  
         ' -------------------------------------------------

            PAD=8

            XPOS=(XPOS+1) mod PAD

            RENDER_DOT_LAYER[-XPOS,PAD]

            COUNT=Param


         ' ---------------------------
         ' Render some text on the scene  
         ' ---------------------------

            AGE_TEXT["Brute Force PLANAR Dot Rendering",10,10,50]
            AGE_TEXT["Dot Count:"+Str$(COUNT),10,20,50]
            AGE_TEXT["Fps::"+Str$(FPS),10,30,50]


          ' calc the fps of this demo

            FRAMESPAST=Timer-SECOND_START

            RENDER=RENDER+1
            If FRAMESPAST=>50
                   FPS=RENDER
                   RENDER=0
                   SECOND_START=Timer
            End If



            KEYPRESS$=Inkey$()


             If KEYPRESS$=" " Then Exit
       Loop




        ' -----------------------------------  
        ' Clean Up/Close Down AGE  
        ' -----------------------------------  
           AGE_CLEAN_UP


          End







Procedure RENDER_DOT_LAYER[XPOS,PAD]

  For YLP=0 To 256 Step PAD

     XS=0+XPOS
     XE=320+XPOS

     For XLP=XS To XE Step PAD
          AGE_DOTC[XLP,YLP,XLP]
     Next

     COUNT=COUNT+(XLP/PAD)

  Next

End Proc[COUNT]




       NOTE: Not using a a DOT QUEUE in this example



 AGE - 8bit Planar Dot Render (QUEUE VERSION)

        This is basically the same demo, but this one has brute and queued (batching) in it.  In queued mode it'll draw about 5000 (8bit) planar points.  Building the queue is a little more hasle, but we get rid of lots of Amos function calling overhead by going the extra mile.  Even on planar screen, the speed is pretty good running under jitted emulation .




Set Buffer 50

' *=-------------------------------------------------------------------=*
'
'             AGE - ANIMATION  - PLANAR DOT RENDERING (Brute Force)  
'
'                                      By  
'
'                                By Kevin Picone
'
'                         Last Updated - 10th, Apr, 2012                  
'
'                (c) Copyright 1997/98/1999/2000- 2012, Kevin Picone
'
'                             www.UnderwareDesign.com        
'
' *=-------------------------------------------------------------------=*
'

   ' Sorry but AMOSPRO seems to require absolute include paths ??  
   '  SO,  YOU'LL HAVE TO TWEAK THE PATHS IN ORDER TO RUN
   '  THE DEMOS FROM AMOS/AMOSPRO correctly on your machine    


   ' To make the pathing less annoying, here we store the 'root path'  
   '  in a variable APPPATH$ .. Then use this through our program.  


     APPPATH$="Dh0:/AGE_V102/"


    ' Set the location of the AGE lib..  
      AGE_LIBRARY_PATH$=APPPATH$+"Includes/Asm/Age.lib"

    ' Include the AGE wrapper into your AMOS project
      Include "Dh0:/AGE_V102/INCLUDES/AMOS/AGE_V074.AMOS"



'   *=-----------------------------------------------------------------=*    
'
'                        >> ALLOC AGE RESOURCE TABLEs <<
'
'   *=-----------------------------------------------------------------=*    

           SCRNS=15
           COPS=15
           BLKDATAS=10
           BANKS=11



           FONTS=12
           FILECACHESIZE=50000
           DCACHESIZE=10000

           AGE_ALLOC_RESOURCES[SCRNS,COPS,BLKDATAS,BANKS,FONTS,FILECACHESIZE,DCACHESIZE]


        ' -----------------------------------  
        ' Create our LOWRES / INTERLEAVED  AGE screen in Chip Memory '
        ' -----------------------------------  
            TYPE=AGE_LOWRES
'            TYPE=TYPE+AGE_INTERLEAVED
            TYPE=TYPE+AGE_PLANAR

            AGE_OPEN_SCREEN[0,320,256,8,TYPE]
            AGE_OPEN_SCREEN[1,320,256,8,TYPE]

            CURRENT_BUFFER=0



        ' -----------------------------------  
        '  Load IFF into this a temp screen.  
        ' -----------------------------------  

              FILE$=APPPATH$+"GFXFILES/PICTURES/TREE.IFF"

             AGE_OPEN_SCREEN[3,320,256,8,TYPE]
             AGE_LOAD_IFF_TO_SCREEN[FILE$,3]

       ' copy the palette from the backdrop picture in the chip buffers

             AGE_SCREEN_COPY_PALETTE[3,0]
             AGE_SCREEN_COPY_PALETTE[3,1]


        ' -----------------------------------  
        ' Create standard / simple copper list for viewing our screens.    
        ' -----------------------------------  
             AGE_CREATE_COPPER[0,0,3,8]
             AGE_CREATE_COPPER[1,1,3,8]


        ' -----------------------------------  
        '  Set copper to view our AGE screen  
        ' -----------------------------------  
            Doke $DFF096,$180 : Rem Kill Bitplane + copper DMA  

            AGE_WAIT_TOP_OF_FRAME

            AGE_SHOW_COPPER[1-CURRENT_BUFFER]

            Doke $DFF096,$8180 : Rem restore Bitplane + copper DMA  


       ' -----------------------------------  
       ' Direct ALL RENDERING To OUR Screen
       ' -----------------------------------  
            AGE_SET_SCREEN[CURRENT_BUFFER]


      ' -----------------------------------  
      ' Load a Font
      ' -----------------------------------  


            FONTS$=APPPATH$+"gfxfiles/fonts/"

            AGE_LOAD_FONT[FONTS$+"Alex8.font",2]

            AGE_SET_FONT[2]



             Degree


            '  CReate a bank to store our queue version


          ' Init the star queue (buffers)

             WIDTH=320
             HEIGHT=256
             PIXEL_SPACING=4

             SIZE=WIDTH*HEIGHT

             AGE_CREATE_BANK[1,(SIZE+2)*6]


             AGE_GET_BANK_PTR[1]
             QUEUE_POINTER=Param


             QUEUE_DOT_LAYER[WIDTH,HEIGHT,PIXEL_SPACING,QUEUE_POINTER]


            REDRAWS=0
            FPS=0


       Do

         ' -------------------------------------------------
         ' Swap Buffers
         ' -------------------------------------------------

             CURRENT_BUFFER=1-CURRENT_BUFFER

             AGE_SET_SCREEN[CURRENT_BUFFER]

             AGE_SET_COPPER[(1-CURRENT_BUFFER)]

             AGE_WAIT_TOP_OF_FRAME


         ' -------------------------------------------------
         ' Copy the temp image to the current render buffer
         ' -------------------------------------------------

            AGE_COPY_RECT[3,0,0,320,256,CURRENT_BUFFER,0,0]


         ' -------------------------------------------------
         ' Draw Layer Of Colour Dots to the 8bit planar screen  
         ' -------------------------------------------------


            XPOS=(XPOS+1) mod PIXEL_SPACING

             If DEMO_MODE=0
                  RENDER_DOT_LAYER[-XPOS,WIDTH,HEIGHT,PIXEL_SPACING]
                  COUNT=Param



            Else

                   AGE_DOT_QUEUE[QUEUE_POINTER,-XPOS,0,COUNT]

             End If


         ' ---------------------------
         ' Render some text on the scene  
         ' ---------------------------

          If DEMO_MODE=0

              AGE_TEXT["8Bit Planar Dot Rendering (Brute Force)",10,10,50]

          End If

          If DEMO_MODE=1
            AGE_TEXT["8Bit Planar Dot Rendering (Queue)",10,10,50]

          End If


            AGE_TEXT["Dot Count:"+Str$(COUNT),10,20,50]
            AGE_TEXT["Fps::"+Str$(FPS),10,30,50]





          ' calc the fps of this demo

            FRAMESPAST=Timer-SECOND_START

            RENDER=RENDER+1
            If FRAMESPAST=>50
                   FPS=RENDER
                   RENDER=0
                   SECOND_START=Timer
            End If



            KEYPRESS$=Inkey$()

            If KEYPRESS$="m"

               DEMO_MODE=1-DEMO_MODE

            End If


             If KEYPRESS$=" " Then Exit
       Loop




        ' -----------------------------------  
        ' Clean Up/Close Down AGE  
        ' -----------------------------------  
           AGE_CLEAN_UP


          End







Procedure RENDER_DOT_LAYER[XPOS,WIDTH,HEIGHT,PAD]

  For YLP=0 To HEIGHT Step PAD

     XS=0+XPOS
     XE=WIDTH+XPOS

     For XLP=XS To XE Step PAD
          AGE_DOTC[XLP,YLP,INDEX]
          Inc INDEX

    Next

     COUNT=COUNT+(XLP/PAD)

  Next

End Proc[COUNT]




Procedure QUEUE_DOT_LAYER[WIDTH,HEIGHT,PAD,PTR]

  For YLP=0 To HEIGHT Step PAD


     For XLP=0 To WIDTH Step PAD
           C=XLP
           AGE_SET_DOT_QUEUE[PTR,STARLP,XLP,YLP,INDEX]
           STARLP=STARLP+1
           Inc INDEX

     Next

     COUNT=COUNT+(XLP/PAD)

  Next

End Proc[COUNT]





 AGE - Remap BOX (Colour Remapping)

    The AGE_REMAP_BOX function allows us to remap a rectangle of chunky pixels against a remap table of our choice.   To make the picture bellow, i'm drawing a bunch of 16 * 16 rects onto the chunky buffer at random positions.   Each rect is using a table that adds 2 to each colour index, where the colours are clamped at 255.    At the end of the frame, i'm subtracting one from every index.    

    So if a pixel is drawn say 5 times, then after this it's value will be 10.   The palette is set up so that colour index 0 is the backdrop coluor, where the entire 256 colour palette fades towards the brighter colour.    Since we're only subtracting one from each pixel each frame, the pixels appear to linger and then slowly fade out or cool down.  


Title: Re: AGE Development Blog (Advanced Graphics Engine for AmosPro / Amiga AGA)
Post by: monkeybot on April 09, 2012, 03:13:50 PM
i must ask,why are you doing this age project?

I loved the Amiga but why?...
Title: Re: AGE Development Blog (Advanced Graphics Engine for AmosPro / Amiga AGA)
Post by: kevin on April 09, 2012, 06:06:52 PM

   There's  plenty of reasons, but the one's that sparked my interest the most would be the release of Windows packaged version of AMOS.   This installer allows basic programmers run AMOS on Windows PC (via emulation of course) legally.    AGE isn't new,  it's much older than PlayBASIC (http://www.playbasic.com).   All i'm doing here, is cleaning up the library (to a degree)  in order make it more useful for those intersted in AGA programming under AMOS emulation.     

 
 



   The rather interesting by product of using emulation like this, is that programmers could knock up little games/demos in AMOS then distribute them across various platforms, the same way AMOS is being distributed above..  Which is rather bizarre, but perfectly viable.   
Title: Re: AGE Development Blog (Advanced Graphics Engine for AmosPro / Amiga AGA)
Post by: Kev G on April 09, 2012, 07:11:35 PM
Hello Kevin.

Just registered to say that I (and many other amos users) have been following your progress on this for a couple of weeks now.
I must say that it is looking promising. I use a real Amiga for AMOS programming and there are many others like me who still
design programs for the Amiga.

I really hope that you can knock up an AGA Dual Playfield mode at some point. I've tried it myself
using a modified copper list but its not a workable solution. I have however, managed to get a 'Sliced-HAM' screen working
using the copper list from a 4 bit display. It displays 16 unique colours on each scan line so on a PAL display you have 4096 colours
without the dithering that you get on a standard HAM display. If you want the code for AGE then I would be more than happy
to give you it so that you can include it in AGE.

Keep up the good work.

Kev G.
Title: Re: AGE Development Blog (Advanced Graphics Engine for AmosPro / Amiga AGA)
Post by: kevin on April 09, 2012, 11:32:57 PM
 Hi Kev,

Quote
Just registered to say that I (and many other amos users) have been following your progress on this for a couple of weeks now.
I must say that it is looking promising. I use a real Amiga for AMOS programming and there are many others like me who still
design programs for the Amiga.

    Well,  it's nice to know that somebody noticed, had assumed so from the view count.   I really can't stress enough that while AGE works, its far from a tried and true polished solution,  so people should keep their expectations well and truly in check.   I hope it works OK on real hardware, but it might not also !

    The clean up has taken a bit longer than expected, but will not doubt reuse bits of the lib in other projects.. so all is not lost.

Quote
I really hope that you can knock up an AGA Dual Playfield mode at some point. I've tried it myself
using a modified copper list but its not a workable solution. I have however, managed to get a 'Sliced-HAM' screen working
using the copper list from a 4 bit display. It displays 16 unique colours on each scan line so on a PAL display you have 4096 colours
without the dithering that you get on a standard HAM display. If you want the code for AGE then I would be more than happy
to give you it so that you can include it in AGE.

   yeah..   Dual playfield & dyanmic had crossed my mind, the copper support in the library isn't like AMOS's native management, in fact there's barely any copper related functions at all.  The standard view, just sets the display mode, bitplane pointers, 24bit palette  and that's about it.  You can roll your own copper list,  which is not unlike how the original AmosAGA hack works. 
     
   Setting a dual playfield screen, will mean creating two 4bit AGE screens, then building a copper view with dual mode enabled.   One of the issues with the AGA chipset,  is that running all 8 bitplanes chews up a loads of DMA during our video refresh. Much, like turning hires modes on.   We can reduce this some what, by enabling 32bit or 64bit fetch modes for the video hardware, but this some negative side affects, in that it means everything must be alligned to either 32 or 64 bits.   This is not really issue if you want to scroll the screen vertically, but horizontally it can be rather painful, since we have to over side the buffers to accommodate hardware scrolling, which kills most of the hardware sprites.   

   Anyway, we'll see how we go.


Title: Re: AGE Development Blog (Advanced Graphics Engine for AmosPro / Amiga AGA)
Post by: kevin on April 10, 2012, 12:43:16 AM

  AGE - 8Bit Planar Line Rendering / Line Queues

      There's still a few odds and ends that i'm cleaning up.  The replacement line clipper and chunky line render are in and work pretty well. But the older line render was blitter based and choked badly, very badly.   It didn't really fit with design of library, which was originally written to favor CPU rendering over blitter, as mid range systems 020/030 with fast memory can easy beat it.       
     
      Anyway, so now the line function can draw to chunky or planar surfaces, if your going to be drawing to planar, then I'd really recommend going easy on it, in particular when rendering directly to chip/video memory.    Speed wise, it's ok given its a generic routine after all.   Moreover, while looking through the functions there was line queue stub, but no actual routine.   I dunno if that was in the older release version  or not, I think this based on the final source(s), but ya never know..   But it's added now. 

      The Line queue has two functions the render function AGE_LINE_QUEUE[Ptr,Xoffset,YOffset,FLAGS,ITEMCOUNT]  and the queue builder function.  AGE_SET_LINE_QUEUE[Ptr,QueueIndex,X1,Y1,X2,y2,ColorINdex] ,  each queye item is 10 bytes  in memory (X1.w,Y1.w,X2.w,y2.w,Colour.w) .  When you render, you can uses the flags parameter to select if you want the output to be clipped or not.  Warning,  if you turn clipping off and render outside the viewport, it will crash !

Title: Re: AGE Development Blog (Advanced Graphics Engine for AmosPro / Amiga AGA)
Post by: kevin on April 12, 2012, 09:05:04 PM
  AGE - Interleaved Planar + Porting Colour Functions

    The original AGE lib had provision for both standard PLANAR and INTERLEAVED planar, but the interleaved mode didn't seem to work in the latest versions.   Turned out to be just the pre mult table wasn't being set up correctly in that mode.  The premult's is a look up table of Y values, that library routines use when working out the address of particular scan line when reading or writing a screen buffer,  it's just quicker fetching pre-computed values than multing the Y coordinate by the surface pitch every time.    

     In early versions of the update the Colour functions were written in AMOS, but unfortunately doing things like blending RGB values is a lot of work for AMOS to actually do.  Wasn't going to bother, but if you try and fade the palette IN/OUT then just calling the blend function 256 times can eat most of a complete frame on it's own.  Which is a bit scary really,  so those functions have been ported to assembly and dropped into the library.

     For the sake of a comparison,   the native version the RGB_ALPHA_BLEND function is about 25 FRAMES (that's about 25*20 milliseconds) faster than interpreted AMOS implementation when blending 2000 colours.   While not exactly a fair comparison, it does demostrate just how important data management seems to be in AMOS.  

     Another subtle change has been to the initialize function for AGE, it appears that I can use variable pointers to help with the function pointer initializations.   While I haven't rolled this completely out, it'd not doubt save some code bloat in the library, with minimal fuss.  The down side of such a change is the having to be a bit more careful with the order of declaration in the start up.    
   

     Sample Colour Functions Test Code (Requires Dev Version Of AGE).



Set Buffer 50

' *=-------------------------------------------------------------------=*
'  
'                            AGE - Colour Functions  
'
'                                      By  
'
'                                By Kevin Picone
'
'                         Last Updated - 13th, Apr, 2012                  
'
'                (c) Copyright 1997/98/1999/2000- 2012, Kevin Picone
'
'                             www.UnderwareDesign.com        
'
' *=-------------------------------------------------------------------=*
'

   ' Sorry but AMOSPRO seems to require absolute include paths ??  
   '  SO,  YOU'LL HAVE TO TWEAK THE PATHS IN ORDER TO RUN
   '  THE DEMOS FROM AMOS/AMOSPRO correctly on your machine    


   ' To make the pathing less annoying, here we store the 'root path'  
   '  in a variable APPPATH$ .. Then use this through our program.  


     APPPATH$="Dh0:/AGE_V102/"



    ' Set the location of the AGE lib..  
      AGE_LIBRARY_PATH$=APPPATH$+"Includes/Asm/Age.lib"

    ' Include the AGE wrapper into your AMOS project
      Include "Dh0:/AGE_V102/INCLUDES/AMOS/AGE_V076.AMOS"


'   *=-----------------------------------------------------------------=*    '
'
'                        >> TEST COLOUR FUNCTIONS <<
'
'   *=-----------------------------------------------------------------=*    


 RGB[255,16,$A0]

 C=Param
 Print Hex$(C)

 RGBR[C]
 Print "R:"+Hex$(Param)

 RGBG[C]
 Print "G:"+Hex$(Param)

 RGBB[C]
 Print "B:"+Hex$(Param)


'-----------------------------------------------

Print ""



 RGB_24TO12[C]
 C12=Param
 Print "RGB12to12:"+Hex$(C12)



 RGB_12TO24[C12]
 C24=Param

 Print "RGB12to24:"+Hex$(C24)




'-----------------------------------------------


 RGB1=$8090A0
 RGB2=$10203

 RGB_ADD[RGB1,RGB2]

 C=Param
Print ""
 Print "RGB  Alpha Add"
 Print Hex$(RGB1)
 Print Hex$(RGB2)
 Print Hex$(C)


 RGB_SUB[RGB1,RGB2]

 C=Param
 Print "RGB  Alpha Add"
 Print Hex$(RGB1)
 Print Hex$(RGB2)
 Print Hex$(C)



'-----------------------------------------------


Print ""

Print "FADE RGB"

 RGB_FADE[RGB1,0.5]

 C=Param
 Print Hex$(RGB1)

 Print Hex$(C)





'-----------------------------------------------
Print "Press Space"
Wait Key

Cls


  Print ""

  Print "FADE ALPHA BLEND"

  RGB1=$AABBCC
  RGB2=$334455


  RGB_ALPHA_BLEND[RGB1,RGB2,0]
  Print Hex$(Param)



  RGB_ALPHA_BLEND[RGB1,RGB2,1]
  Print Hex$(Param)

  RGB_ALPHA_BLEND2[RGB1,RGB2,1]
  Print Hex$(Param)



  RGB_ALPHA_BLEND[RGB1,RGB2,0.5]
  Print Hex$(Param)

  RGB_ALPHA_BLEND2[RGB1,RGB2,0.5]
  Print Hex$(Param)



  Print "Speed Test Start"

   M=10000

  ST=Timer()

   For LP=0 To M
      RGB_ALPHA_BLEND[RGB1,RGB2,0.5]
   Next

   T=Timer()

      Print(T-ST)



  ST=Timer()

    For LP=0 To M
       RGB_INT_ALPHA_BLEND[RGB1,RGB2,128]
    Next

   T=Timer()

      Print(T-ST)



  ST=Timer()

     For LP=0 To M
        RGB_ALPHA_BLEND2[RGB1,RGB2,0.5]
     Next

   T=Timer()

   Print(T-ST)

  Wait Key


        ' -----------------------------------  
        ' Clean Up/Close Down AGE  
        ' -----------------------------------  
           AGE_CLEAN_UP






 
Title: Re: AGE Development Blog (Advanced Graphics Engine for AmosPro / Amiga AGA)
Post by: kevin on April 14, 2012, 07:28:52 PM
  AGE - Convex Polygon Rendering (Flat / Gouraud / Texture Mapped)

   Dropped a bit more time into this update yesterday afternoon,  the new code is a replacement of poylgon edge conversion routines.   The code was basically drag and dropped in from PlayBASIC (http://www.playbasic.com),  while the library already contained triangle based rendering routines, which apart from being a big mess, they're limited to only triangles.    So of you want to render a textured quad, you had to draw it in at least two halves.  When you do this, we're doubling a number operations not to mention that one edge is converted twice.

   So a better solution is to use a polygon filler than can render sets of 3 or more vertex, which is how the replacement  routine works.  It's limited to the 32 vertex,  but can potentially draw any set as long as the vertex form a convex polygon shape.  It'll fail on the concave or complex polygons.

   In the picture bellow we're looking at a flat filled quad drawn over the star field example, the colours per scan line is just random junk in this example.  Porting the code was pretty painless,  a few syntax issues with comments in VBCC, but you get that.   Typically when things are moving quickly something pops up to hinder that progress and this time was no exception.   So the routine was ported, but of course when I called it from the library, nothing happened..

   Long story short,  the ported code isn't identical to the version in PB, this version is styled to use the AGE screen structure.  In AGE the viewport structure is 16bit, it's 32bit in PB.  Which turned out to the problem.  The caller was passing a 32bit structure in where it expected a 16 bit.  Making it reject virtually anything.  Pretty novel issue, but annoying none the less.  
   
   The polygon fillers, don't actually draw pixels.  It just calcs the visible spans.  In the example bellow, i'm just running through the resulting span buffer can drawing LINES between them for test purposes.    What i plan to do in this session,  is set up the filler to use the built in SPAN routines (which are used in Circles/Boxes) to render the strips out.   At least then the flat shaded filler work on chunky or planar/interleaved screens.   Texture Mapping and Gouraud will be CHUNKY only i'm afraid.

   

AGE - Filled TRI + QUADS

     Dropped in the some commands into the Amos wrapper (Second picture), they're basically the same as the PB commands, so we've AGE_TRI[x1,y1,x2,y2,x3,y3] and it's sister function AGE_TRIC[x1,y1,x2,y2,x3,y3,Colour] as well as AGE_QUADC[x1,y1,x2,y2,x3,y3],x4,y4,Colour.  It's nice being able to project some points and and just draw quad out of the edge verts.

     The Texture mapped and gouraud version of the span buffering as in, but there's no AMOS wrapping code at the moment.  There's a lot of Amos function overhead passing all the required fields into the function.  Might end up having  Textured TRI + Textured Quad functions, with some type of user generated vertex buffer.   A vert buffer would prolly be best.   

   
Title: Re: AGE Development Blog (Advanced Graphics Engine for AmosPro / Amiga AGA)
Post by: kevin on April 18, 2012, 12:37:26 AM
  AGE - FIXED POINT MATH / TRIG FUNCTIONS

    From messing with AMOS, you can't help but notice floating point performance isn't pretty.  It's not really AMOS's fault, given it's just using the Amiga floating point math libraries underneath, which need to emulate FPU when one's not present.   You can improve the performance on real hardware, if you have FPU in your system, by replacing the math lib with an FPU optimized version (Check Aminet there some on there).     Even so, Fixed Point should still be better. 
   
     While most of the examples shown here are using fixed point, there is some floating poijnt usage still in them, namely COS/SIN functions.  So i've knocked up a couple of Fixed point replacement functions for the native routines.   The routines use a 16:16 formatted fixed point values, so there's 16 bits one whole part and 16 bit fractional part.    This limits the numeric range, but we can perform floating point styled using Integer operations without same the Floating Point overhead.  

     The functions i've included focus around cos/sine,  where functions like AGE_COS[ANGLE]  / AGE_SIN[ANGLE]   are the COS/SIN equivalents.  Internally the lib uses a sinus TABLE, so it should be pretty efficient.  I often use polar coordinates when mapping character paths in games (Angle and Speed), so i've added a couple of functions that bundle up some processing into a single function.   While i suspect this will be slower from the AMOS interpreter,  compiled it should work really well, if not... You could actually inline some of those function if push came to shove.  

     Anyway,  in the example we're plotting some circles using the functions.  



Set Buffer 50

' *=-------------------------------------------------------------------=*
'  
'                   AGE - FIXED POINT MATH/ TRIG FUNCTIONS  
'
'                                      By  
'
'                                By Kevin Picone
'
'                         Last Updated - 18th, Apr, 2012                  
'
'                (c) Copyright 1997/98/1999/2000- 2012, Kevin Picone
'
'                             www.UnderwareDesign.com        
'
' *=-------------------------------------------------------------------=*
'

   ' Sorry but AMOSPRO seems to require absolute include paths ??  
   '  SO,  YOU'LL HAVE TO TWEAK THE PATHS IN ORDER TO RUN
   '  THE DEMOS FROM AMOS/AMOSPRO correctly on your machine    


   ' To make the pathing less annoying, here we store the 'root path'  
   '  in a variable APPPATH$ .. Then use this through our program.  


     APPPATH$="Dh0:/AGE_V102/"



    ' Set the location of the AGE lib..  
      AGE_LIBRARY_PATH$=APPPATH$+"Includes/Asm/Age.lib"

    ' Include the AGE wrapper into your AMOS project
      Include "Dh0:/AGE_V102/INCLUDES/AMOS/AGE_V081.AMOS"


'   *=-----------------------------------------------------------------=*    '
'
'                        >> TEST FIXED POINT MATH FUNCTIONS <<
'
'   *=-----------------------------------------------------------------=*    

'    


' Step Fixde point accuracy (16 bits if fraction part)
ACC=$10000

' Size of the circles we'll be drawing

RADIUS=100



' Testing the FIXED POINT COS + SIN  
'  These function return a cos/sin value in fixed point 16:16 format
' the function returns results in fixed point 16:16 format


For LP=-360 To 720 Step 2

  AGE_COS[LP]
  X=Param*RADIUS

  AGE_SIN[LP]
  Y=Param*RADIUS

 Plot 160+X/ACC,100+Y/ACC

Next


Print "AGE FIXED POINT COS & SIN"
Print "Ppess Space"
Wait Key

Cls

' ------------------------------------------------------
' ------------------------------------------------------
' ------------------------------------------------------




' Testing the FIXED POINT COSRADIUS + SINRADIUS  
'  This function Mults the Cos/Sin value by radius as part of it
' the function returns results in fixed point 16:16 format


For LP=-360 To 720 Step 2

  AGE_COSRADIUS[LP,RADIUS]
  X=Param

  AGE_SINRADIUS[LP,RADIUS]
  Y=Param

 Plot 160+X/ACC,100+Y/ACC

Next

Print "AGE FIXED POINT COSRADIUS & SINRADIUS"
Print "Press Space"
Wait Key

Cls



' ------------------------------------------------------
' ------------------------------------------------------
' ------------------------------------------------------

' Testing the FIXED POINT POLAR
'  This function returns movement along X / Y cord
' from an angle and Radius/speed
' the results are in fixed point 16:16 format  


For LP=-360 To 720 Step 2

  AGE_POLAR[LP,RADIUS]
  X=Dreg(0)
  Y=Dreg(1)

  Plot 160+X/ACC,100+Y/ACC

Next

Print "AGE POLAR"
Print "Press Space"
Wait Key

Cls



' ------------------------------------------------------
' ------------------------------------------------------
' ------------------------------------------------------

' Testing the FIXED POINT POLAR STEP
'  This function returns movement along X / Y cord
' from an angle and Radius/speed
' the results are in fixed point 16:16 format  


' calc the screen center in Fixed point  
 CX=160*ACC
 CY=100*ACC


For LP=-360 To 720 Step 2

  AGE_POLARSTEP[LP,RADIUS,CX,CY]
  X=Dreg(0)
  Y=Dreg(1)

  Plot X/ACC,Y/ACC

Next

Print "AGE POLAR STEP (FIXED POINT)"
Print "Press Space"
Wait Key

Cls




' ------------------------------------------------------
' ------------------------------------------------------
' ------------------------------------------------------

' Testing the FIXED POINT POLAR STEP (INTEGER)
'  This function returns movement along X / Y cord
' from an angle and Radius/speed
' the results are as signed integers



' calc the screen center in Fixed point  
 CX=160*ACC
 CY=100*ACC


For LP=-360 To 720 Step 2

  AGE_INTPOLARSTEP[LP,RADIUS,CX,CY]
  X=Dreg(0)
  Y=Dreg(1)

  Plot X,Y

Next

Print "AGE POLAR STEP (INTEGER)"
Print "Press Space"
Wait Key

Cls

        ' -----------------------------------  
        ' Clean Up/Close Down AGE  
        ' -----------------------------------  
           AGE_CLEAN_UP






Title: Re: AGE Development Blog (Advanced Graphics Engine for AmosPro / Amiga AGA)
Post by: kevin on April 18, 2012, 10:18:51 PM
  AGE - FIXED POINT MATH / ROTATE2D and ROTATE2D BATCH

     Did a little more tinkering with the math functions last night, adding a 2D ROTATE vertex function, along with a Batch version of the function.    The rotated 2d function, takes an individual 2D vector and rotates this by the required number of degrees   AGE_ROTATE2D[ANGLE,X,Y], the function returns the rotated vector in registers D0 and D1.

    So to rotate the point at 100x,200y by 50 degrees  we'd go



    AGE_ROTATE2D[50,100,200]

    NewX = Dreg(0)
    NewY = Dreg(1)



    Input and returns coordinates are in 32bit Integers.  Internally the rotation is all fixed point though and is faster than manually rotating the point in pure AMOS code.     The trouble is with calling AMOS functions heavily in our programs,  is that it add overhead to the procedure.   So a faster method, is to rotate a BATCH of vertex in one hit.  So the function call has very little (none really) impact upon performance.  To do this, we've added the AGE_ROTATE2D_BATCH function.    

   AGE_ROTATE2D_BATCH is a little more complex to set up, but will give us much better through put for the more verts you want to rotate.   The function expects the user  to set up two buffers of suitable size. (  if they're not it'll die !).    These are the SOURCE and DESTINATION vertex buffers.    It's not recommended to use the same buffer for both source and destination, since this will only give you compounded precision errors, over successive rotations.      

   AGE_ROTATE2D_BATCH[SRCPTR,SRCVERTEXMODULO,DESTPTR,DESTVERTEXMODULO,METHOD,ANGLE,VERTEXCOUNT]

   SrcPTR  = The address of the original (none rotated) vertex

   SrcVertexModulo  = The distance (in bytes) between each vertex

   DESTPTR  = The address where the rotated vertex will be stored.  

   DestVertexModulo  = The distance (in bytes) between each vertex

   METHOD =  1= 32bit Vertex ,  - = 16bit vertex

   ANGLE = To rotate this set i degrees

   VERTEXCOUNT = Number of verts in this batch


  When calling the function, we can choose the size of the vertex data using the METHOD field.  There's only 2 options, 16bit or 32bit.   In 16bit mode, the routine expects the X data to be located at SRCPTR, and Y data to be located at SRCPTR+2, same for Destination data.   In 32bit mode, they're 4 bytes apart in source and destination.    The modulo allows you to access structures of different width.    

  Ideally what this allows us to do, is create queues of dots / lines then batch rotate the ordinates prior to rendering the queue.  This bypasses a huge amount of AMOS overhead and will give us near assembly results.    


  Math Test Example



' *=-------------------------------------------------------------------=*
'  
'                   AGE - FIXED POINT MATH/ TRIG FUNCTIONS  
'
'                                      By  
'
'                                By Kevin Picone
'
'                         Last Updated - 19th, Apr, 2012                  
'
'                (c) Copyright 1997/98/1999/2000- 2012, Kevin Picone
'
'                             www.UnderwareDesign.com        
'
' *=-------------------------------------------------------------------=*
'

   ' Sorry but AMOSPRO seems to require absolute include paths ??  
   '  SO,  YOU'LL HAVE TO TWEAK THE PATHS IN ORDER TO RUN
   '  THE DEMOS FROM AMOS/AMOSPRO correctly on your machine    


   ' To make the pathing less annoying, here we store the 'root path'  
   '  in a variable APPPATH$ .. Then use this through our program.  


     APPPATH$="Dh0:/AGE_V102/"



    ' Set the location of the AGE lib..  
      AGE_LIBRARY_PATH$=APPPATH$+"Includes/Asm/Age.lib"

    ' Include the AGE wrapper into your AMOS project
      Include "Dh0:/AGE_V102/INCLUDES/AMOS/AGE_V082.AMOS"


'   *=-----------------------------------------------------------------=*  
'
'                        >> TEST FIXED POINT MATH FUNCTIONS <<
'
'   *=-----------------------------------------------------------------=*    
'    
 Curs Off


' Step Fixed point accuracy (16 bits if fraction part)
  ACC=$10000


' Size of the circles we'll be drawing
  RADIUS=100

'  Testing the FIXED POINT COS + SIN  
' These function return a cos/sin value in fixed point 16:16 format  
' the function returns results in fixed point 16:16 format


For LP=-360 To 720 Step 2

  AGE_COS[LP]
  X=Param*RADIUS

  AGE_SIN[LP]
  Y=Param*RADIUS

  Plot 160+X/ACC,100+Y/ACC

Next


  Print "AGE FIXED POINT COS & SIN"
  Print "Ppess Space"
  Wait Key

  Cls

' ------------------------------------------------------
' ------------------------------------------------------
' ------------------------------------------------------




' Testing the FIXED POINT COSRADIUS + SINRADIUS  
'  This function Mults the Cos/Sin value by radius as part of it
' the function returns results in fixed point 16:16 format


For LP=-360 To 720 Step 2

  AGE_COSRADIUS[LP,RADIUS]
  X=Param

  AGE_SINRADIUS[LP,RADIUS]
  Y=Param

 Plot 160+X/ACC,100+Y/ACC

Next

Print "AGE FIXED POINT COSRADIUS & SINRADIUS"
Print "Press Space"
Wait Key

Cls



' ------------------------------------------------------
' ------------------------------------------------------
' ------------------------------------------------------

' Testing the FIXED POINT POLAR
'  This function returns movement along X / Y cord
' from an angle and Radius/speed
' the results are in fixed point 16:16 format  


For LP=-360 To 720 Step 2

  AGE_POLAR[LP,RADIUS]
  X=Dreg(0)
  Y=Dreg(1)

  Plot 160+X/ACC,100+Y/ACC

Next

Print "AGE POLAR"
Print "Press Space"
Wait Key

Cls



' ------------------------------------------------------
' ------------------------------------------------------
' ------------------------------------------------------

' Testing the FIXED POINT POLAR STEP
'  This function returns movement along X / Y cord
' from an angle and Radius/speed
' the results are in fixed point 16:16 format  


' calc the screen center in Fixed point  
 CX=160*ACC
 CY=100*ACC


For LP=-360 To 720 Step 2

  AGE_POLARSTEP[LP,RADIUS,CX,CY]
  X=Dreg(0)
  Y=Dreg(1)

  Plot X/ACC,Y/ACC

Next

Print "AGE POLAR STEP (FIXED POINT)"
Print "Press Space"
Wait Key

Cls




' ------------------------------------------------------
' ------------------------------------------------------
' ------------------------------------------------------

' Testing the FIXED POINT POLAR STEP (INTEGER)
'  This function returns movement along X / Y cord
' from an angle and Radius/speed
' the results are as signed integers



' calc the screen center in Fixed point  
 CX=160*ACC
 CY=100*ACC


For LP=-360 To 720 Step 2

  AGE_INTPOLARSTEP[LP,RADIUS,CX,CY]
  X=Dreg(0)
  Y=Dreg(1)

  Plot X,Y

Next

Print "AGE POLAR STEP (INTEGER)"
Print "Press Space"
Wait Key

Cls



  Screen Open 0,320,200,16,Lowres
  Screen Open 1,320,200,16,Lowres




' ------------------------------------------------------
' ------------------------------------------------------
' ------------------------------------------------------

' Testing the FIXED POINT POLAR STEP (INTEGER)
'  This function returns movement along X / Y cord
' from an angle and Radius/speed
' the results are as signed integers



' calc the screen center

 CX=160
 CY=100


NUMBEROFLOOPS=50
For LP=0 To NUMBEROFLOOPS

   CURRENTBUFFER=1-CURRENTBUFFER
   Screen 1-CURRENTBUFFER
   Screen Show CURRENTBUFFER


   If LP+1=NUMBEROFLOOPS
     Print "Press Space"
    End If



  Cls
   Print "AGE ROTATE 2D"

   ANGLE=ANGLE+5 mod 360

   AGE_ROTATE2D[ANGLE,0,0]
   X1=CX+Dreg(0)
   Y1=CY+Dreg(1)

   AGE_ROTATE2D[ANGLE,100,0]
   X2=CX+Dreg(0)
   Y2=CY+Dreg(1)

   AGE_ROTATE2D[ANGLE,100,100]
   X3=CX+Dreg(0)
   Y3=CY+Dreg(1)

   AGE_ROTATE2D[ANGLE,0,100]
   X4=CX+Dreg(0)
   Y4=CY+Dreg(1)


   Polyline X1,Y1 To X2,Y2 To X2,Y2 To X3,Y3
   Polyline X3,Y3 To X4,Y4 To X4,Y4 To X1,Y1

Next

Print "Press Space"
Wait Key






' ------------------------------------------------------
' ------------------------------------------------------
' ------------------------------------------------------

'  Testing BATCH ROTATE Function on  array of 32bit integers
' the function has two data type methods built in.  It can
' rotate batches of 16bit vertexs or 32bit..  First we'll test
' 32bits

'  I'm using two arrays here. One as the source Vertex buffer
' and the other is the ROTATED vertex buffer. SO we create our
'  vertex set.   Then we just rotate them during the game, thus
' avoiding the need to recreate the source vertex each time.
'      
'  You should be able to use this function with the various queue
' functions in the library.  

  VERTEXCOUNT=100


' The number of bytes between each vertex in the source structure  
  SRCVERTEXMODULO=8

' The number of bytes between each vertex in the source structure  
  DESTVERTEXMODULO=8


  Dim VERTBUFFER(VERTEXCOUNT*(SRCVERTEXMODULO/4))
  Dim ROTATED_VERTBUFFER(VERTEXCOUNT*(DESTVERTEXMODULO/4))

 INDEX=0


 For LP=0 To(VERTEXCOUNT-1)
     X1=Rnd(320)-160
     Y1=Rnd(200)-100
     VERTBUFFER(INDEX)=X1
     VERTBUFFER(INDEX+1)=Y1
     Add INDEX,2
 Next




' calc the screen center

 CX=160
 CY=100


SRCPTR=Varptr(VERTBUFFER(0))
DESTPTR=Varptr(ROTATED_VERTBUFFER(0))


NUMBEROFLOOPS=25




For LP=0 To NUMBEROFLOOPS

   Screen Show CURRENTBUFFER
   CURRENTBUFFER=1-CURRENTBUFFER
   Screen CURRENTBUFFER


  Cls
   Print "AGE ROTATE 2D BATCHES"
   If LP+1=NUMBEROFLOOPS
     Print "Press Space"
    End If

   ANGLE=ANGLE+1 mod 360

   AGE_ROTATE2D_BATCH[SRCPTR,SRCVERTEXMODULO,DESTPTR,DESTVERTEXMODULO,1,ANGLE,VERTEXCOUNT]

   INDEX=0

   X1=CX+ROTATED_VERTBUFFER(INDEX)
   Y1=CY+ROTATED_VERTBUFFER(INDEX+1)


  For EDGELP=1 To VERTEXCOUNT-1

       X2=CX+ROTATED_VERTBUFFER(INDEX)
       Y2=CY+ROTATED_VERTBUFFER(INDEX+1)
       Add INDEX,2

       Polyline X1,Y1 To X2,Y2

       X1=X2
       Y1=Y2

  Next




Next

Print "Press Space"
Wait Key






' -------------------------------------------------------------
' -------------------------------------------------------------
' ------------------>> BRUTE FORCE TEST <<---------------------
' -------------------------------------------------------------
' -------------------------------------------------------------

 Screen CURRENTBUFFER
 Screen To Front CURRENTBUFFER


Cls

Print "Brute Force Math Test"


COUNT=10000



_STARTTIME=Timer

 For LP=0 To COUNT
     X=Cos(ANGLE)
 Next

 Print "Floating Point COS:"+Str$(Timer-_STARTTIME)




_STARTTIME=Timer

 For LP=0 To COUNT
     AGE_COS[ANGLE]
     X=Param
 Next

 Print "Fixed Point COS:"+Str$(Timer-_STARTTIME)




_STARTTIME=Timer

 For LP=0 To COUNT
     X=Cos(ANGLE)*RADIUS
 Next

 Print "Floating Point COS* RADIUS:"+Str$(Timer-_STARTTIME)


_STARTTIME=Timer

 For LP=0 To COUNT
     AGE_COSRADIUS[ANGLE,RADIUS]
     X=Param
 Next

 Print "Fixed Point COSRADIUS:"+Str$(Timer-_STARTTIME)



_STARTTIME=Timer

 For LP=0 To COUNT
     Dreg(0)=ANGLE
     Dreg(1)=RADIUS
     Call LIBAGE_COSRADIUS
     X=Dreg(0)
 Next

 Print "Unrolled Fixed Point COSRADIUS:"+Str$(Timer-_STARTTIME)


Wait Key



        ' -----------------------------------  
        ' Clean Up/Close Down AGE  
        ' -----------------------------------  
           AGE_CLEAN_UP




  At the bottom of the test is a loop that runs some brute force performance comparisons on the AGE_COS/SIN functions compared to the native floating point functions.    From the emulator I get some interesting, but not that unexpected results.   If we compare COS() with AGE_COS[], over 10,000 calls, the AGE function is quicker, but not dramatically so.  A lot benefit is lost wrapping the function as a Procedure.    Which is demonstrated nicely when comparing the Cos(Angle)*Radius  equivalents, in that they're about the same speed here.  That is, until you get rid of the procedure, then it's twice as fast.  


Compiling Amos Issues

   So far i'm just running the demos from the AmosPRO IDE / runtime interpreter, so we should be able to strip out a lot of runtime overhead when compiled to EXE, but the compiler doesn't want to play nice.   Not too sure what it's problem is, but it appears that the AGE Wrapper might need to be modded in order to be able to compile the final game/demos to EXE's.   Which is really NOT what i was hoping.    The library does actually run really well from the WinAUE 2.3.3 / with JIT enabled.  In fact we're seeing demo's approach 50fps under emulation,  chunky or planar doesn't seem to matter.    Which is neat for those running under emulation, but compiling to exe would be a huge benefit on real hardware.



Title: Re: AGE Development Blog (Advanced Graphics Engine for AmosPro / Amiga AGA)
Post by: kevin on April 19, 2012, 08:45:47 AM
  AGE - DRAW POLY  / DRAW TEXTURED POLY

        These touch back to triangle / quad routines mentioned previously.   In the original library, it seems that AMOS would spit out an integer overflow if it felt the result exceeds the range of 32bit value in some operations, which i'd never noticed before.   Anyway this would cause issues if which the polygon routines try and bundles up the coordinates into packed registers.  

        For example, the in triangle function there's enough registers to happily just send them as is,  but if you want gouraud or texture mapping you need to send more information than just the vertexs.  So the function would pack pairs  X1,Y1 / X2,Y2 / X3,Y3 into three 32bit registers.

        A bit like this.

        PackedX1Y1 = (X1 * $10000) + Y1

        But there's a few obvious problems with this, but mainly since the X1/Y1 are 32 bit integers,  what happens if X1 or Y1's negative ? .. Yeah it overflows...    To Get around this we need to mask the fields before ,merging the bits.    

        Something like this,

        PackedX1Y1 = ((X1 and $ffff) * $10000) + (Y1 and $ffff)

        But you'll still get overflows in AMOS, not too sure how MULT is implemented in AMOS actually, since the 68000 cpu doesn't have a native 32bit integer multiply, which makes you wonder ? hmmm.   Of course shifting is a much better option, but it seems the shifters are a type of custom operator in Amos.

        So to pack a pair of fields, we've effectively forced to do this.
 
        X1 = X1 and $ffff
        Rol.l 16,X1
        PackedX1Y1 = X1  or  (Y1 and $ffff)
           
        Now i only bring it up, as that's a lot of overhead on the AMOS side of the library to batch up the data every time to send it.   Obviously, it'd be a much better idea to stream line the data setup into a more Amos friendly format like an array or memory bank.  

        So the DRAWPOLY functions come at the same problem from that perspective, basically we fill in a list of Vertex data, pass this list to the polygon rendering function and it draws it for us (if possible).   There's a few limitations,  such as the shape must be convex and less than 32 vertex in the list, but that's about it.    You can draw filled shapes and texture mapped shapes also.  

        The DrawPoly functions expect user to lay the vertex data out in the following 20 byte structure,  X,Y, U,V, Col.  So each field is a 32bit integer



  0   X
  4   Y
  8   U
 12  V
 16  Col
 Size = 20 bytes


             

        So if you wanted to create a vertex buffer in an array,  what you'd is dimension the array so there's 5 times the number vertex you need.    Why 5 times ?, well each cell in the array is 4 bytes (one 32bit integer) so each cell is a field in our vertex structure above,  since the structure is 20 bytes, we'll need 5 slots per vertex in our array .  

       Ie.

       VertexCount = 10

       Dim Vertex_Buffer(VertexCount * 5)
       

    Then to render a textured 10 sided poylgon disc thing..  We can do that like this.


      ' Array index into Vertex_Buffer()
      INDEX=0

      ' Step in degrees for this number of vertex
       ANGLESTEP=360/VERTEXCOUNT

      ' Bump rotation angle each refresh
       SPIN=SPIN+2 mod 360

      ' Set starting angle to the current rotation angle
      ANGLE=SPIN

      ' Angle Texture coordinates.  These aren't rotating
        ANGLE2=0

           For LP=0 To VERTEXCOUNT-1
                ' bump the current angle
                ANGLE=ANGLE+ANGLESTEP mod 360

               '  project a polar cord at 150 units same as X=Cos(Angle)*Radius   / Y=Sin(angle)*RAdius
                 AGE_POLAR[ANGLE,150]

               ' set the X + Y cords of the Vertex
                VERTEX_BUFFER(INDEX)=160+Dreg(0)/$10000
                VERTEX_BUFFER(INDEX+1)=128+Dreg(1)/$10000

                ' set the U/V cord
                ANGLE2=ANGLE2+ANGLESTEP
                AGE_POLAR[ANGLE2,124]

                VERTEX_BUFFER(INDEX+2)=128+Dreg(0)/$10000
                VERTEX_BUFFER(INDEX+3)=128+Dreg(1)/$10000

                ' bump the array index to the next vertex in buffer
                Add INDEX,5

           Next

           ' Get the address of the first byte in this array
           PTR=Varptr(VERTEX_BUFFER(0))

          ' draw this shape as textured polygon using the dragon texture  
           AGE_DRAWTEXTUREDPOLY[PTR,VERTEXCOUNT,DRAGON_TEXTURE]



        Bellow you can see the result of the code, which is it's drawing a spining textured circle shape thing using the dragons texture map for something to look at.    You can draw the same thing as triangles, which is not a lot of extra programming, but it's lot of extra work on the AMOS and ultimately AGE.  




 AGE - GOURAUD TORUS (AGAIN)

        Hadn't updated all the polygon filler routines to the N-sided versions,  so bellow (Second shot) we see the gouraud torus demo, using the new filler with a object pushed right up in the viewers face.   It's running in the low 30fps mark under emulation (with jit).    To be honest, the fill quality isn't great, but it works.    

 

  AGE - GOURAUD QUAD

         Dropped a AGE_GouraudQUAD[x1,y1,c1,x2,y2,c2,x3,y3,c3,x4,y4,c4]  function into the wrapper.   Pictured bellow drawing a quad between some random palette data. 



 
Title: Re: AGE Development Blog (Advanced Graphics Engine for AmosPro / Amiga AGA)
Post by: kevin on April 21, 2012, 02:20:48 AM



A.G.E  V1.02 BETA #1  is Now Available (21st, Apr, 2012)



  This release contains an 'as is' snap shot of the AGE package at this time. Those familiar with the original package will notice a lot has changed since the previous release some 12 years ago, way too much to paraphrase now.  So to get up to speed please make sure you read this thread and the examples carefully.
   
   The package includes revision 85 of AGE AMOS wrapper and binary library, as well as various examples.

   What's AGE ?  it's a replacement / plug in graphics engine for AMOSPRO that enables AMOS programmers to use the AGA chipset.

   You can find out more information about AGE at AGE HOME PAGE (http://www.underwaredesign.com/?page=programs.A-G-E-)



Download

   Download AGE V1.02 BETA #1 (http://www.underwaredesign.com/getfile.php?file=Get-AGE-Beta/AGE-V102-Beta-01.zip)  



Installation

  Download the package to your computer and unzip the folder.    The examples are hard coded to expect a path of DH0:AGE-V102-Beta-01,  so you'll need to mod the paths if you place it anywhere else.    You don't need to the copy the AGE.LIB file into your libraries folder, it's not a general purpose library.




History

   Changes since last release



---------------------------------------------------------------------------------------------------------------
         ------------------------------------>> Release V1.02 - BETA #1 << -------------------------------------------------
---------------------------------------------------------------------------------------------------------------

      Too many to mention




Title: Re: AGE Development Blog (Advanced Graphics Engine for AmosPro / Amiga AGA)
Post by: Amiten on August 20, 2012, 10:07:30 AM
Hi all,

First to all I want to say CONGRATULATIONS!! Kevin Picone for make this AGE extension Amazing Work!

I Coding in Amos/Amos pro from early 90 until 2003 and now in 2012 I working again with Amos in some own projects   an example :  http://youtu.be/qv8IK6aXV8k  or http://youtu.be/v-0_gJQAHDM this only some examples about ideas I want to do in future visit my web site in www.amiten.webatu.com for more info.

The thing is I would like to use your Extension to Have AGA support in AMOS ( just a Dream if I can Do it)

At the moment I only play i little bit with your extension AGE , but cant do work.

Y download the last Beta calls Download AGE V1.02 BETA #1  I extract on Dh0:  go in Amos pro and allways in winuae and in A1200 REAL say me the same this Screen:

(https://lh6.googleusercontent.com/-HnwlIrqxI9g/UDFXF-9p9iI/AAAAAAAABSQ/aYAVb-KvqoY/s640/FalloFAGA.png)

So Really I dont know now What I Can Do with This...  hope some body can help me to start use AGE.

Thanks for all in advance,

Keep with the good Work!
And Amiga 4Ever!
Amiten.
Title: Re: AGE Development Blog (Advanced Graphics Engine for AmosPro / Amiga AGA)
Post by: kevin on August 20, 2012, 01:21:06 PM

Quote
At the moment I only play i little bit with your extension AGE , but cant do work.
I extract on Dh0:  go in Amos pro and allways in winuae and in A1200 REAL say me the same this Screen:

  It's not actually an extension, it's more a generic library.   The library comes with an AMOS wrapper and the raw machine code bundled up with it.     The wrapper is just a chunk of Amos code laid out as a set of procedures  that call the machine code library functions. 

  Setting it like this was meant to make it easier, but unfortunately AmosPro only seems to be support absolute include paths.  Meaning that if folder structure is extracted differently/moved etc,  than the code examples are setup to expect, Amos won't be able to locate the wrapper and you'll get that error from Amos. 

  So the package should be extracted to Dh0:AGE-V102-Beta-01/  inside this folder, there should  be the example files and the folders "includes", "Manual", GFxFiles and Tools. 


  ie. so  directory of the folder structure would look a bit like this. 



  Dh0:AGE-V102-Beta-01/includes
  Dh0:AGE-V102-Beta-01/includes/Amos
  Dh0:AGE-V102-Beta-01/includes/Amos/AGE_V085.AMOS
  Dh0:AGE-V102-Beta-01/includes/Asm/Age.lib
  Dh0:AGE-V102-Beta-01/includes/Manual
  Dh0:AGE-V102-Beta-01/includes/Tools
 
  Dh0:AGE-V102-Beta-01/Example_V001_Show_Picture.AMOS
  Dh0:AGE-V102-Beta-01/Example_V002_Palette.AMOS

  etc
  etc
  etc
  etc
  etc

  Dh0:AGE-V102-Beta-01/Example_V120_Dragon3.AMOS





Title: Re: AGE Development Blog (Advanced Graphics Engine for AmosPro / Amiga AGA)
Post by: Amiten on August 20, 2012, 02:15:10 PM

Hi Kevin  , Thanks for your quick Response ;)

Quote
  It's not actually an extension, it's more a generic library.   The library comes with an AMOS wrapper and the raw machine code bundled up with it.     The wrapper is just a chunk of Amos code laid out as a set of procedures  that call the machine code library functions. 

May be I´m a little crap jejeje, sorry   but Amos Wrapper?? dont know what is this, is a Extension for Amos??

Now I try again  download the AGE again in original Zip File. put in Winuae  extract with MirawizARC 1.1b  in DH0:   Rigth!   and  now I get diferent error:

   Variable´s Name buffer to small ???

I think now the Path is recognised rigth  but something  remain.

So if you know why I will very grateful .

Regards
Amiten
 
 
Title: Re: AGE Development Blog (Advanced Graphics Engine for AmosPro / Amiga AGA)
Post by: baggey on November 25, 2012, 08:30:12 AM
Hi, Just come across this thread  ;D

Ive browsed through and think.

I need Amos pro "Download" and the "Beta". Will google "AMOS PRO"

I never owned An amiga! But remember seeing a demo of "Walker" i think it was called. Which looked like cool game  :)

Baggey


Title: Re: AGE Development Blog (Advanced Graphics Engine for AmosPro / Amiga AGA)
Post by: colinmiland on January 01, 2017, 02:51:47 AM
There are a lot of engines and they do different things. Some are better in a smaller environment, some in a huge world. Some enable really complex water and visual effects, while others do great things with skelatal animation.
Title: Re: AGE Development Blog (Advanced Graphics Engine for AmosPro / Amiga AGA)
Post by: Epo on March 11, 2019, 03:36:50 PM
Hello Kevin,

Your AGE looks fantastic. I tried it couple of times in those past years. Also, did it today. However, I never succeeded in compiling any of your examples. Is it even possible? I'm experienced with Amos and I'd like to make use of your "extension" but if it can not be compiled then it misses the point. Can you help?
Title: Re: AGE Development Blog (Advanced Graphics Engine for AmosPro / Amiga AGA)
Post by: kevin on March 11, 2019, 09:38:49 PM
Quote from: Epo on March 11, 2019, 03:36:50 PM
Hello Kevin,

Your AGE looks fantastic. I tried it couple of times in those past years. Also, did it today. However, I never succeeded in compiling any of your examples. Is it even possible? I'm experienced with Amos and I'd like to make use of your "extension" but if it can not be compiled then it misses the point. Can you help?

   If AmosPro can't locate the include and or it can't load the binary part of library then it wont compile or run.  The paths in the examples are absolute, making the extraction path critically important to success.   If you change the extraction path, you'd have to mod the paths in the examples manually. 

   


  

Title: Re: AGE Development Blog (Advanced Graphics Engine for AmosPro / Amiga AGA)
Post by: Epo on March 15, 2019, 03:53:16 AM
QuoteIf AmosPro can't locate the include and or it can't load the binary part of library then it wont compile or run.  The paths in the examples are absolute, making the extraction path critically important to success.   If you change the extraction path, you'd have to mod the paths in the examples manually.

Thank you Kevin for quick response and sorry for delay from my part (something unexpected came up). To the point. I do understand absolute path issue. However, it does not work. I mean it works in editor but I can't make it compile without getting an error (most examples report it in line 67 but I don't think it's the line we see in editor, most probably it's internal numbering that the compiler sees only). Anyway, I've seen your video and saw you're using version 1.02 but it's not available to download (only 1.01 and 1.02-Beta-01; I'm using the latter). If you still have access to your configuration, could you please check if you're able to compile any of your examples? I'd be grateful. And thanks a lot for keeping interest in people who are interested in you old project.

(https://i.imgur.com/2Oiz1Yal.png)
Title: Re: AGE Development Blog (Advanced Graphics Engine for AmosPro / Amiga AGA)
Post by: kevin on March 22, 2019, 10:53:53 PM

  Had a quick look and if you cut'n'paste the include into one of the examples,  the AmosPRO compiler complains about the variable buffer overflowing.    I do remember something about being able to change the heap size in Amos, but not off the top of my head..
Title: Re: AGE Development Blog (Advanced Graphics Engine for AmosPro / Amiga AGA)
Post by: Epo on March 23, 2019, 12:23:42 PM
Quote from: kevin on March 22, 2019, 10:53:53 PM
  Had a quick look and if you cut'n'paste the include into one of the examples,  the AmosPRO compiler complains about the variable buffer overflowing.    I do remember something about being able to change the heap size in Amos, but not off the top of my head..

Kevin, your tip worked! But only with two examples: Show picture and v020_Graphic. But that's something. With others I get errors like above on the screenshot but with much further line (after 3000.)
However, after quitting from the program I must reset the Amiga because it causes some system stability problems (and does not recover all the Chip memory back.)
Title: Re: AGE Development Blog (Advanced Graphics Engine for AmosPro / Amiga AGA)
Post by: kevin on March 31, 2019, 05:03:25 AM

Quote
  However, after quitting from the program I must reset the Amiga because it causes some system stability problems (and does not recover all the Chip memory back.)


  On close the dellocation functions need to be called to release the buffers..   So any possible app close would have to be trapped so it calls the delloc or it'll leak.   
Title: Re: AGE Development Blog (Advanced Graphics Engine for AmosPro / Amiga AGA)
Post by: Epo on April 04, 2019, 02:28:24 AM
Thank you again Kevin for taking time to respond. I'll see if I'm successful with the other examples, because those two are simply not sufficient to make a satisfactory project.
Title: Re: AGE Development Blog (Advanced Graphics Engine for AmosPro / Amiga AGA)
Post by: nonarkitten on May 30, 2019, 02:59:45 PM
Any chance of open sourcing this? I'd love to get into the weeds and rewrite some of the inner code for the Vampire AMMX.