home *** CD-ROM | disk | FTP | other *** search
- Gemini
- ======
- version : 1.05
- questions to: Giancarlo Castagno (s64922@galileo.polito.it)
- disabled : some lens-flares effects and some camera parameters.
-
- © 1996 Sincronia Soluzioni Multimediali, Italy
- It cannot be used without the written permission of Sincronia
-
- Here follows a description of Gemini, the new TopModel's graphic engine.
- It is a relocatable module available also to third parties, as it can be shared
- across all the applications that need 3D visualisation. It lets users to
- display a 3D scene and navigate into it.
- Gemini can be run also on older machines (pre RiscPC, without dynamic areas).
- Applications that use it will work happily with all its the future versions as well.
- Module upgrades will offer automatic file loading and a common wimp
- interface (like the Acorn !ColourPicker one).
-
- Gemini main features:
- =====================
- - Works on any Acorn processor, from ARM2 to StrongArm.
- - Phong illumination model and support for Cook&Torrance's one.
- - Wireframe, flat shading, gouraud shading and phong shading view modes.
- - Up to 1024 light sources per scene, of any type (sun, point, spot) and colour, all recalculated real-time.
- - Shaded wireframe, for high-speed illuminated rendering; this display style was originally
- created by Sincronia and introduced in TopModel from its very first versions.
- - Phisical-based material models (ambient, diffusion, reflection RGB, transparency RGB
- and refractive index).
- - Full Z-buffer (in any view mode), with a T-Buffer for a correct rendering of transparencies.
- - Real-time parametrized fog and haze.
- - Texture, chrome and bump mapping. Gemini supports also several techniques superposed.
- - Lens-flares effects.
- - Several camera models.
- - Normal and VR navigation modes.
- - Scene is always calculated at 96bits per pixel and then reduced using a real-time Floyd/Steinberg
- error diffusion algorithm.
- - New enhanced radiosity view mode that deals with real-time soft shadows and light diffusion.
- - Possibility to place an image (in any format) in the background; it can follow the rotation
- of the view (like a VRQuickTime).
- - Direct import of VRML files (up to 40 nested Separator nodes, support for recursive nested
- DEF-USE nodes, gestion of lights and navigation nodes).
- - Support for animation: hierarchic objects management and a "Gemini_Transform" call to
- move/scale/rotate them.
-
- Gemini environment:
- ===================
-
- Gemini is basically a collection of routines to manage a 3D database and render
- it both on the screen or to a memory area (to create a sprite); the code contains
- tables of precalculated datas (1/x, sin(x), 1/SQR(x) and so on). If you need to
- know how to use them not to duplicate informations (i.e. if you need to use
- them too), ask us for the full specs...
- All the relevant informations on how to render the files are stored within the
- application using it. That's why it can be shared istantly beetween applications.
- Gemini is simple to use, as it only has three main calls: one for initialise itself,
- one to set the workarea and one to draw the whole scene. The tricky part of the
- system are the memory areas used to make it work. You can simply set them big enough
- (go on reading this file), without bother why they are needed. Anyway better if you
- understand fully how the whole system works and what are the main memory areas used...
-
- A 3D scene is made of 2 separated database, for speed & memory needs: a points
- database, which contains all the points used by the model (X,Y,Z of the point
- plus some infos) and a primitives database, that contains the description of
- each primitive (polygon, sphere or Bezier line/surface) used. For example, this
- is a reduced GEO file which describes a cube that can be used to provide a good
- example of how the data bases work:
-
- 8 | total number of points
- 0 0 0 | points 0: X Y Z
- 1 0 0 | points 1: X Y Z
- 1 1 0 | ...
- 0 1 0 | ...
- 0 0 1 |
- 1 0 1 |
- 1 1 1 |
- 0 1 1 |
- |
- 4 0 1 2 3 | polygon of 4 sides, connecting points 0,1,2,3
- 4 7 6 5 4 | polygon of 4 sides, connecting points 7,6,5,4
- 4 0 4 5 1 | ...
- ... | ...
-
- Obviousely TopModel files use the memory location of a point (from now on LDM)
- instead of its number for speed needs, but basically this is the structure.
- It allows to share points between polygons (a cube uses 8 points and 6 polygons,
- instead of 24 points (4 for each poly) and 6 polygons).
- A TopModel file is basically a memory dump of these two TopModel work areas,
- plus some other informations (for example the minimum size of each area).
- So, before loading a file you have to reserve enough workspace for it. If you
- want to speed up things, you can simply reserve a memory area as big as the 3Dfile
- size, (plus 2/3 Kbytes for security... ;-). The areas can be stored within your
- application workspace or in a dynamic area, and can be two different areas or
- just one splitted. Gemini needs only to know where Points and Primitives areas
- start in memory.
-
- Please note: Gemini (and TopModel) uses the first 58 points for internal use (axis
- and so on); thus you must reserve them (32 bytes each, so 58*32 bytes) at the
- start of the Points area. So, once you have dimensioned enough workspace for points,
- starting from an ldm stored in the variable PointsLDM, you should load the Points
- informations of the file at PointsLDM+58*32.
-
- There is another memory area to store the main resources: a table of presetted
- (plus user defined) colours and materials definition plus a table for textures
- and groups setup.
-
- TopModel (and Gemini) manages 512 colours, (up to 200 presetted and up to 311
- user defined). Each colour uses 16 bytes (0-11 for the name and 12-15 for the
- &BBGGRR00 of the colour palette). So you have to reserve a 512*16 bytes for
- the colour table. In the same way TopModel stores also the 256 materials
- (up to 100 predefined and up to 155 user defined). Each material uses 32 bytes
- (0-11 for the name 12-31 for material definition). Thus you have to reserve
- 256*32 bytes for the material table. In this area you should also store the
- texture information table. Gemini manages up to 512 textures and each entry in
- table is 16 bytes long, so you have to reserve another 512*16 bytes.
- Texture 0 is reserved to say "No texture", so its values in the table should
- always remains 0; the first valid texture entry is n^1 (at the offset +16). The
- entry for each texture are:
- +0 =ldm of the sprite;
- +4 =X dimension of the sprite (pixel);
- +8 =Y dimension of the sprite (pixel);
- +12=2^29 (or colour (at 16bpp) to be made transparent).
- Finally this buffer holds also group datas. Gemini allows up to 2048 groups to
- be defined, and each of them uses 8 bytes. Thus this area needs 2048*8 bytes.
- When you call "Gemini_Initialise" for the first time, it fills this buffer
- with the predefined materials and colours and zeroes the textures and groups tables.
- To do this, set the bit 1 int the flag word (R4).
- Every TopModel file (&B5C) may contain some colours or materials created by user.
- These should be loaded from the 200th colour (offset +200*16) and from the 100th
- material (offset +100*32). Look at the loading procedure (see later) to see how
- they are loaded. The total size of the area is 40960 bytes (512*16+256*32+512*16+2048*8).
-
- After that you should create a normal sprite area defined in RiscOS, in which
- you have to load the textures used, taking them from inside the Resources
- folder. In the file you find the path of each texture used inside the
- "!TopRes.texture" directory (the system variable <TopModel$Textures> holds the full path.
- You may need to use !ChangeFSI if the textures aren't 16bpp RiscOS Sprites, as Gemini
- can manage only them; once loaded you should set the corrispondent table entry
- with the texture ldm and dimensions. If you want to discard textures, simply don't
- load them, leaving the texture table filled with 0s.
-
- Then you have to reserve some memory for the Z buffer. The exact amount
- depends upon the size of the image to be created. Gemini uses 4 bytes for each pixel
- of the image. Last but not least there is the image buffer. You can plot directly
- on the screen, and in this case you don't have to dimension nothing, or you may
- want to plot to sprite. In this case you need as much memory as the one required
- to store a normal RiscOS sprite in the resolution and number of colours you need.
-
- To sum up: you have to set 5or6 work areas:
- 1) Points workarea (the file contains the minimum size)
- 2) Primitives workarea (the file contains the minimum size)
- 3) Colours+Material+Textures+Groups table (40960 bytes (512*16+256*32+512*16+16384))
- 4) Texture sprite area (big enough to load all the 16bpp sprites)
- 5) Z buffer (4 bytes for each pixel of the image to be created)
- 6) image buffer (if you aren't plotting to the screen): the same size of a RiscOS sprite.
-
- Obviously you can store all of them in a single area or split them on several
- segments. Note: ALL THEM MUST BE WORD ALIGNED!
-
- Now Gemini is ready to work happily within your application.
- There are three main blocks of informations to drive Gemini engine.
- I call them TMmemoryblock, TMviewblock, TMcolourblock.
-
- TMmemoryblock (256 bytes)
- -------------------------
- it contains the relevant memory information for Gemini. Some of the
- locations are updated, some other are filled with ldm of tables of
- precalculated datas. These must be filled:
-
- +0 ldm start of Points workspace
- +8 dimension of Points workarea in bytes
- +12 ldm start of Primitives workspace
- +20 dimension of Primitives workarea in bytes
- +40 ldm start of Z buffer
- +44 ldm colours+materials+textures+groups table
-
-
- Other relevan values, set by "Gemini_Initialise", when you call it with
- bit 0 (in the flag word) set, are:
-
- +4 first free location in Points workspace (where to load Points from
- file). Updated when loading the file (or editing it).
- +16 first free location in Primitives workspace (where to load Points
- from file). Updated when loading the file (or editing it).
- When no object is loaded, the default values are:
- TMmemoryblock!4 =TMmemoryblock!0 +58*32
- TMmemoryblock!16=TMmemoryblock!12
- +52 ldm of texture table
- +64 ldm of materials table
- +68 ldm of groups table
- These three are used by Gemini to speed up things. Instead of recalculating each time
- the ldm of the start of each area, Gemini simply calculates them once when a
- "Gemini_Initialise" is called, storing the start ldm of textures, materials and groups
- tables out of the address you pass in TMMemoryblock!44.
- Simply: +44 colours+materials+textures+groups table; this is also the ldm of
- the start of colour area: 512*16 bytes
- +52 texture table: (previous ldm + 512*16); it uses 256*32 bytes
- +64 materials table: (previous ldm + 256*32); it uses 512*16 bytes
- +68 groups table: (previous ldm + 512*16); it uses 2048*8 bytes
-
- TMviewblock (256 bytes)
- -----------------------
- it contains all the relevant parameters to drive the shading process. Some
- locations are updated and some others are filled with some infos about the
- current screen modes and so on. For a full list, ask me. The values
- inside [] are the default values set when you call "Gemini_Initialise". All
- the values must be integers, so to keep some precision, your numbers are
- multiplied by some factor. To obtain their original value, just take the value
- stored inside the corresponding location and divide it by the multiplier
- factor (eg. if you have 0.5 and a multiplier factor of 2^16, you should
- store the number 2^16*0.5=2^15=32768. When you need to know its value,
- read it and divide it by 2^16, so 2^15/2^16=0.5). You have to alter only the
- values you are interested in.
-
- +0 Z angle of view *16 (so 0 <= Zangle <= 360*16).To rotate around Z [ 0*16]
- +4 Y angle of view *16 (so 0 <= Yangle <= 360*16).To rotate around Y [90*16]
- +8 0 (for the X angle, but currently unused) [ 0*16]
- +12 X position of the observer (*2^17) To pan around [ 0*2^17]
- +16 Y position of the observer (*2^17) [ 0*2^17]
- +20 Z position of the observer (*2^17) [ 0*2^17]
- +24 current OS version (currently unused)
- +28 zoom factor *2^10 ( 1*2^10 =100%) Note: (0 <= zoom <= 64*2^10) [ 5*2^10]
- +44 distance observer-plane of projection (*2^17). Used to alter the
- perspective deformation (works just in perspective...) [10*2^17]
- +100 Linear FOG intensity *2^14 (0 <= intensity <= 4*2^14) [ 1*2^14]
- +104 Z coordinates at which the fog starts (*2^17). [ 0*2^17]
- +108 Z intensity of the fog *2^14 (0 <= height <= 4*2^14) [ 1*2^14]
- +112 Sun light X direction (the X component of the normal) [ 0*2^15]
- +116 Sun light Y direction [ 0*2^15]
- +120 Sun light Z direction [ 1*2^15]
- +124 Sun light intensity (0..1 *2^16) [ 1*2^16]
- +128 Sun light colour (&BBGGRR00) [&FFFFFF00]
- +132 Ambiental light intensity (0..1 *2^16) [ 0*2^16]
- +136 Ambiental light colour (&BBGGRR00) [&FFFFFF00]
- +140 "Illumination has changed" flag [255 ]
- +144 Gemini_version set in Gemini_Initialise [104 ]
- +156 "Colours have changed" flag [255 ]
- +172 precision in drawing a bezier curve (1=high...6=low) [3 ]
- +176 precision in drawing a bezier surface (1=high...6=low) [5 ]
- +192 "Geometry has changed" flag [0 ]
- +200 bits 0 -8 : texture used for picture in background (0=none) [0 ]
- bit 9 : set to 1 if texture must rotate with the view [0 ]
- bits 10-20: X offset on screen [0 ]
- bits 21-31: Y offset on screen [0 ]
- +204 Parametric grid: step X (*2^17) [ 4*2^17]
- +208 Parametric grid: step Y (*2^17) [ 4*2^17]
- +212 Parametric grid: step Z (*2^17) [ 4*2^17]
- +216 Parametric grid: number of points for each side [50 ]
- +220 Parametric grid: centre X (*2^17) [ 0*2^17]
- +224 Parametric grid: centre Y (*2^17) [ 0*2^17]
- +228 Parametric grid: centre Z (*2^17) [ 0*2^17]
-
- Note: set the three flags (+140,+156,+192) to tell Gemini to recalculate the
- correspondent value: +140 (illumination) if you have changed front light
- or you have moved the lights in the scene; +156 (colours) if you have
- changed some values in TMcolour block; +192 (geometry) if you want to
- recalculate all the normals of points and primitives in the scene
- (for example if you have deformed some objects or you simply want to
- calculate normals of objects you have created yourself). Gemini will
- recalculate the correspondent values next time you issue a "Gemini_Render"
- call, then it will reset them to 0 (you need to calculate those things
- just once).
-
- TMcolourblock (256+1024*4 bytes)
- it contains all the colours used in the Gemini environment. They are stored
- separately, because Gemini recalculates them each time a user change
- graphic mode. The 1024*4 additional bytes are used to store a table of user
- defined lights. See later. Each colour entry uses 8 bytes; 4 for &BBGGRR00
- of the colour and the second 4bytes to store the translated colour for the
- current graphic mode. The values inside [] are the default values set when
- you call "Gemini_Initialise".
- Once Gemini is running, if you want to change a colour (say the fog colour)
- just alter the corrispondent location with the new palette entry and then
- inform Gemini that you have changed colour setting TMviewblock!156 to a
- value different from 0. Gemini will recalculate the new colour table next
- time a "Gemini_Render" call is issued and zeroes this location (+156) on exit.
-
- +0 Background colour (or sky start,for shaded background) [&AA999900]
- +8 Active plane colour [&00FFFF00]
- +16 Active axis colour [&0000FF00]
- +24 Fog colour [&AA999900]
- +32 Sky end colour (shaded background - disabled) [&FF000000]
- +40 Ground start colour (shaded background - disabled) [&BF444400]
- +48 Ground end colour (shaded background - disabled) [&00FF2200]
- +56 Bezier visual-hull lines colour [&FFD53B00]
- +64 Polygons' vertices colour [&00FFA000]
- +72 Bezier control-points colour [&FF000000]
- +80 Selected points colour [&0000FF00]
- +88 Lattice deformation (used in TopModel editor) [&00FFFF00]
- +96 Colour of active path (used in TopModel editor) [&00FFA000]
- +104 Colour of grid (mainly used in TopModel editor) [&FFFFFF00]
-
-
- Please note: Gemini, apart from the lights stored within a TopModel file, works
- with two ever present lights: a general sun light and an ambiental one (as you
- see from the structure of TMviewblock). To disable them just set their
- intensity to 0. If you want to light the scene frontally, you should set the
- sun beam direction (TMviewblock!112,116,120) to the values contained in
- TMviewblock!48,52,56 respectively, which hold the current view vector. After
- this you should inform Gemini that illumination has changed, setting
- TMviewblock!140 to a value different from 0. In this way, next time you issue
- a Gemini_Render call, Gemini will recalculate illumination before drawing the
- scene. Gemini will automatically reset this location to 0 on exit.
-
-
- Now let's come to the Gemini calls.
- First of all you must initialise your workareas (TMmemory and view blocks):
-
- SYS"Gemini_Initialise"
- ----------------------
- R0 = TMmemoryblock
- R1 = TMviewblock
- R2 = TMcolourblock
- R4 = flags: Bit Meaning if set
- ---------------------------------------------------------------------------
- 0 | Initialise Points&Primitives workarea and zeroes textures and groups
- 1 | Reset colour&material table loading the default colours and materials
- 2 | Reset TMviewblock & TMcolourblock entries to their defaul values
- 3-31 | reserved - must be 0
-
- On exit, this call also returns the Gemini version number*100, in TMviewblock!144
-
- The first time you call "Gemini_Initialise" you should set R4 to 7 (set bits 0-2)
- This loads the colour and material default definitions and clear the scene, filling
- with 0s the texture table and setting the right values in the first 58 points.
- It also updates the Point's and Primitive's first free ldm (TMmemory+4 and +16).
- In this way, when you issue a Gemini_Render call, after this, Gemini will display
- just the axis in the centre of the workarea.
- Then you can call "Gemini_Initialise" each time you need to reset your scene (delete
- the objects inside) setting R4 to 1.
-
-
-
-
- SYS"Gemini_InitScene"
- ---------------------
- When you have loaded a file you have to adjust all its internal links (i.e. the
- ldm of the points used by the polygons); you should call this from inside the loader
- code (see later).
-
- R1 = offset to add to the points
- [(current location at which points are loaded in memory)-(the old location
- from where they were saved, stored in the file)]
- R2 = offset to add to the primitives
- [idem]
- R3 = location at which points are loaded (TMmemoryblock!4 , mostly)
- R4 = location at which primitives are loaded (TMmemoryblock!16, mostly)
-
-
-
-
- SYS"Gemini_SetUpLights"
- -----------------------
- After loading a file, you should compile a light table, to access quickly to
- the light informations. The lights (up to 1024 per scene) are memorized in a
- table (of 1024*4 bytes) within the TMcolour block. You only have to dimension
- correctly the TMcolourblock and call this routine, which scans the Point database
- (in which lights are stored) and compile a table of ldm of the lights in memory.
- Then recalculates also the illumination of Points and primitives...
-
- entry:
- R0 = TMmemoryblock
- R1 = TMviewblock
- R2 = TMcolourblock
- exit:
- R4 = n^ of lights found
-
- ||| If you want to move your scene in memory, once you have loaded and used it,
- ||| just move phisically the memory, update the links within TMmemoryblock
- ||| (+0 to +20), call "Gemini_InitScene" with the new parameters; then
- ||| call "Gemini_SetUpLights".
-
-
-
-
- Then you must specify the dimension of the work area. You must call these
- routine every time (1) you want to change the image size or
- (2) a change of the desktop palette or of the graphic mode
- has occurred.
- There are two routines, which let you specify if you want to work on the screen
- or in a memory buffer (you have to call only one of these):
-
- (a) SYS"Gemini_SetUpScreen"
- -----------------------
- This allows you to output the scene on the screen. You have to set:
- R0 = TMmemoryblock
- R1 = TMviewblock
- R2 = TMcolourblock
- R3 = X min workarea (OS units, inclusive)
- R4 = Y min workarea (OS units, inclusive)
- R5 = X max workarea (OS units, inclusive)
- R6 = Y max workarea (OS units, inclusive)
- R7 = 0 (for a complete setup, which recalculates also the colour tables for the current palette)
- <>0 (window/workarea resize only, much faster)
-
- (b) SYS"Gemini_SetUpSprite"
- -----------------------
- This allows you to output the scene on a sprite. You must set:
- R0 = TMmemoryblock
- R1 = TMviewblock
- R2 = TMcolourblock
- R3 = sprite width (in pixels) Please note that the sprite width will be "corrected":
- 16 colours mode: rounded to a multiple of 8 pixels
- 256 colours mode: rounded to a multiple of 4 pixels
- 32K colours mode: rounded to a multiple of 2 pixels
- 16M colours mode: all values are accepted
- R4 = sprite height (in pixels)
- R5 = log2 bit/pixel (2=16colours 3=256colours 4=32Kcolours 5=16Mcolours)
- R6 = pointer to control block of sprite area (it is reinitialized and must contain
- (R3 * R4 * 2^R5 / 8 + 128) bytes at least)
-
-
- On exit, both these calls fill in the TMviewblock with some informations. In
- particular (in TMviewblock):
- +72 X min workarea (OS units)
- +76 Y min workarea (OS units)
- +80 X max workarea (OS units)
- +84 Y max workarea (OS units)
- these may or may not be equal to those you pass as input. Coordinates are
- translated into memory addresses for plotting purposes, which MUST be byte
- aligned. In practice, only the X coordinates may be affected from this
- readjustament phase. In particular, when in a 4bpp mode, X workarea coordinates
- must be multiple of 2 pixels. From 8bpp modes upwards (and so also 16bpp and 32bpp)
- there aren't restrictions.
-
- So: call Gemini_SetUpScreen (or _SetUpSprite) specifing your workarea, then
- check which are the settings Gemini assumes to be right and use them
- instead. Please NOTE: Gemini DOESN'T WORK in any 2 or 4 colours mode. If a
- user enters these graphic modes, Gemini fill these addresses (+72 to +84)
- with a particular value: -1. You don't have to check the graphic mode specs
- on a mode change. Just call Gemini_SetUpScreen (or _SetUpSprite) as usual.
- If you get, on exit, the -1 value in the previous locations, then warn the
- user that Gemini doesn't work in this mode and close all the windows you
- need (or fill them with a dummy background or use ChangeFSI to convert the
- last image Gemini produces in one suitable for that graphic mode).
- In anycase don't call Gemini_Render while in a "wrong" graphic mode, as the
- result will be unpredictable.
-
-
-
-
- And, (at last!), the call to render all the scene on the specify output stream
- (video or memory) in the specified size...
-
- SYS"Gemini_Render"
- ------------------
- R0 = TMmemoryblock
- R1 = TMviewblock
- R2 = TMcolourblock
- R3 = screen bank to use (1 or 2; 1 for default)
- R4 = mode
-
- Gemini enables you to have a full double buffering for smooth animation. Just
- redraw the screen with R3 set to 1 or 2 alternatively. (see later)
- The R4 register contains the mode word. These are the actual defined bits:
-
- Bit Meaning if set [meaning if not set]
- --------------------------------------------------------------------------
- 0 | Colour [grey-shade]
- 1 | Wireframe
- 2 | Flat shading
- 3 | Gouraud shading
- 4 | Phong shading
- 5 | Transparency enabled [always opaque]
- 6 | Texture mapping enabled
- 7 | Chrome mapping enabled
- 8 | Bump mapping enabled
- 9-11 | reserved - set to 0
- 12 | draw primitives [don't draw them]
- 13 | reserved - set to 0
- 14 | perspective view [axonometric view]
- 15 | normal navigation mode [VR mode: objects behind observer aren't drawn]
- 16 | visualize axes [don't]
- 17 | recalculate active plane while rotating [don't]
- 18 | remove objects with normals against the current view vector [draw all]
- 19 | test ESC key to stop redraw [don't]
- 20 | fog activated [fog disabled]
- 21 | reserved - set to 0
- 22 | recalculate light reflections if you aren't in Phong mode [don't]
- 23 | clear the workarea with the current background colour [draw just objects]
- 24 | draw bezier-curves/surfaces' visual-hull lines [don't]
- 25 | draw polygons' vertices [don't]
- 26 | draw control points [don't]
- 27 | enable lens-flares [don't]
- 28 | show grid points [don't] ---> not activated yet
- 29 | visualise lights position [don't]
- 30-31 | reserved - set to 0
-
- Please note: bits 1-4 are mutually exclusive; you should set just one of these.
- Nevertheless you can set Flat+Gouraud+Phong shading (so bits 2-4=%111)
- to obtain the radiosity view-mode. But at the moment it is for internal
- use only.
-
-
-
-
- Then there are another two calls, to enable screen buffering
-
- SYS"Gemini_StartBuffering"
- --------------------------
- R1 = TMviewblock
-
- This tries to reserve enough video memory to obtain a second bank to enable
- screen banking for smooth animations. If it hits the goal, then it copies the
- first page into the second, to enable a bank switching also from desktop (the
- second page isn't filled with strange colours this way...). Otherwise nothing
- happens and Gemini will use the current video memory.
-
- SYS"Gemini_EndBuffering"
- ------------------------
- R1 = TMviewblock
-
- This ends the bank switching, releasing (if any) the reserved memory and
- copying the contents of the second page (if the current page is the second)
- into the first.
-
- So, to have a working engine with bank switching do this:
- "Gemini_StartBuffering":bank%=1
- REPEAT
- bank%=bank%EOR3:"Gemini_Render",... ,... ,... ,bank% ,...
- UNTIL end
- "Gemini_EndBuffering"
-
- this work also if there isn't enough memory for bank switching.
-
-
-
-
- Operations over loaded objects
- ==============================
- SYS"Gemini_Transform"
- ---------------------
- This call allows you to move/rotate/scale objects. It works over selected objects (so
- you first have to select something) but it can affect numbered groups only (both
- selected or unselected).
- R0 = TMmemoryblock
- R2 = objects to alter:
- 0 --> modify selected objects (you have to select something first)
- n --> logical number of the group to be modified (no need to select it)
- R4 = reason code:
- 0 --> translate objects/group
- 1 --> scale objects/group
- 2 --> transform objects/group using a general transformation matrix
- R5 = memory block filled with geometric datas for the operation (all the values are
- multiplied by 2^17, i.e.: original value=0.5, value to store=0.5*2^17):
-
- offset | translate | scale | general transform
- -------|---------------------------|------------------|-------------------------------------------
- +0 | amount to add to X coord. | X coord. of the point around which the operation takes place
- +4 | amount to add to Y coord. | Y coord. of the point around which the operation takes place
- +8 | amount to add to Z coord. | Z coord. of the point around which the operation takes place
- +12 | - | X scale factor | A11 component of the transformation matrix
- +16 | - | Y scale factor | A21
- +20 | - | Z scale factor | A31
- +24 | - | - | A12
- +28 | - | - | A22
- +32 | - | - | A32
- +36 | - | - | A13
- +40 | - | - | A23
- +44 | - | - | A33
- +48 | - | - | amount to add to X coord.
- +52 | - | - | amount to add to Y coord.
- +56 | - | - | amount to add to Z coord.
-
- The general transformation acts as follows: first of all the object is modified accordingly to
- the 3x3 matrix (around the specified point), then it is translated by the amount specified in
- (+48,+52,+56)
-
-
-
-
- SYS"Gemini_Select"
- ------------------
- This is a multi-purpose selection command.
- Its behaviour depends upon the reason code passed in R4, as follow:
-
- R4 values | action taken
- -----------|-------------------------------------------------------------------
- 1 | Select all/only visible objects (the ones inside working area)
- 2 | Select the specified group of objects
- 3 | Select all the points inside the specified rectangle
- 4 | Find the point closest to the passed (X,Y) screen coordinates
- 6 | Find the primitive closest to the passed (X,Y) screen coordinates
- 16 | Deselect all/only visible objects
- 17 | Deselect the specified group of objects
- 18 | Deselect all the points inside the specified rectangle
-
-
- SYS"Gemini_Select" R4=6
- -----------------------
- R0 = TMmemoryblock
- R1 = X (OS-Units relative to the whole screen, eg.: X mouse coordinate)
- R2 = Y (as above)
- R3 = flag: if bit0 is set, then Gemini will check only visible primitives
- R4 = 6
-
- The other calls aren't implemented yet
-
-
-
-
- MISC
- ====
- SYS"Gemini_readVRML"
- --------------------
- This call loads a VRML 1.1 file whose name (completed with its path,
- otherwise in the current directory) is given in R6.
-
- entry:
- R0 = TMmemoryblock
- R1 = TMviewblock
- R2 = TMcolourblock
- R3 = U number of polygons for the sphere
- R4 = V number of polygons for the sphere
- R5 = Number of sides for cone/cylinder's base
- R6 = bits 0-15: number of user-defined materials
- 16 : set to resize the scene to a default dimension
- 17 : set to triangularize all the polygons (if the scene contains convex polygons)
- R7 = pointer to NULL terminated filename of VRML file (with full path)
- exit:
- R3 = number of created points
- R4 = number of created polygons
- R5 = number of created user-defined materials
-
-
- How to draw the scene in several passes
- =======================================
- You may need to produce a picture in more than one go, expecially if you want
- big resolutions (a 2048*2048 32bpp image, with Zbuffer requires 32Mb free!).
- You also may want to draw only a portion of the scene required for example by
- a Wimp Redraw Request. I recommend you to use this tecnique only for file or
- sprite output, as it slows down the rendering time; anyway it works also
- if you specify the workarea using "Gemini_SetUpScreen". The basic idea is quite
- similar to the one used by the wimp scrollbars. When you specify the workarea,
- Gemini assumes that the origin is placed in the top left corner, and the Y
- coordinate is positive downwards. To place the origin at the centre of the work-
- area, Gemini simply adds a fixed amount to each coordinate. These amounts are
- the centre of the scene (in pixel); let's call them (fx,fy). They are stored
- in TMviewblock+32 and +36, respectively. These locations are filled each time
- you issue a "Gemini_SetUpScreen" or "Gemini_SetUpSprite" call. (fx,fy) are set
- to the centre of the currently specified workarea on exit (i.e. if you specify
- a workarea of (20,20,120,120) OS-Units (with a X and Y scale factor of 2), on
- exit from Gemini_SetUpS... you get (fx,fy)=(25,25), as the workarea is 50x50).
- Let's create a 600x384 pixels image, using 3 strips of 600x128 pixels each.
- Let's take a scale factor of 2 on both X and Y (eg. MODE28).
- Please note: produce strips starting from the top left one to the bottom
- righ. In the following example I consider only 3 horizontal strips, but
- once you have understood how it works, you can redraw any portion inside the
- "main" (logical) workarea.
-
- In OS-Units, here are the 3 workareas to specify:
-
- ________________________________________________________768
- | |
- | |
- | |
- | Strip #1 |
- | |
- | |
- | |
- |______________________________________________________|512
- | |
- | |
- | |
- | Strip #2 |
- | |
- | |
- | |
- |______________________________________________________|256
- | |
- | |
- | |
- | Strip #3 |
- | |
- | |
- |______________________________________________________|0
- 0 1200
-
- So, we have to:
- 1) "Gemini_SetUpS..." specifying strip#1
- 2) alter the (fx,fy) settings like using scroll bars (see later)
- 3) "Gemini_Render" to draw this strip
- 4) "Gemini_SetUpS..." specifying strip#2
- 5) alter the (fx,fy) settings
- 6) "Gemini_Render" to draw this strip
- 7) "Gemini_SetUpS..." specifying strip#3
- 8) alter the (fx,fy) settings
- 9) "Gemini_Render" to draw this strip
- Each strip, once defined, will have its local coordinate system, starting
- from its top-left corner. So, in pixel:
- ________________________________________________________
- |(0,0) |
- | |
- | |
- | Strip #1 |
- | |
- | |
- | (599,127) |
- |______________________________________________________|
- |(0,0) |
- | |
- | |
- | Strip #2 |
- | |
- | |
- | (599,127) |
- |______________________________________________________|
- |(0,0) |
- | |
- | |
- | Strip #3 |
- | |
- | (599,127) |
- |______________________________________________________|
-
- the centre of the whole scene MUST BE THE SAME for all the strips, considering
- their relative positions. In OS-Units, considering the global image, (fx,fy)
- IS POSITIONED to the middle of the second strip (600,384), but when you specify
- and work inside a strip, you have to translate the global position of the
- logical centre (OS-Unit) in the current local coordinate system of the strip
- (pixel).
- So, the strip#1 MUST have (fx,fy) set manually to (300,192)
- the strip#2 MUST have (fx,fy) set manually to (300, 64)
- the strip#3 MUST have (fx,fy) set manually to (300,-64)
-
- ______________________________________________________
- |(0,0) | |
- | Strip#1 | |
- | | |
- | |128+64 |
- | | |
- | | |
- | | (599,127) |
- |_____________________|________________________________|
- |(0,0) | | |
- | Strip#2 |64 | |
- | | | |
- | 300 | | |
- |<---------------------->. (fx,fy) |
- | | |
- | | (599,127) |
- |___________________|__________________________________|
- |(0,0) |-64 |
- | Strip#3 |
- | |
- | |
- | |
- | (599,127) |
- |______________________________________________________|
-
- We are altering only Y position of each strips, so the fx coordinate is
- unchanged, equal to half the Xsize of the total image in pixel (i.e. 300).
- In general, to generate a portion of the main image, you have to work out
- both the coordinates (fx,fy).
-
-
-
-
- Restrictions
- ============
- 1) Gemini DOESN'T WORK in any 2 or 4 colours mode.
- 2) Workarea coordinates are translated into memory addresses for plotting purposes, which
- MUST BE BYTE aligned. This involves just the routine that clears the background, not the
- render routine used for objects. Anyway, even if you don't want to redraw background (bit
- 23 of R4 in "Gemini_Render" clear), workarea position is moved, so all the objects inside
- are moved accordingly. In practice, only the X coordinates may be affected from this
- readjustament. In particular, when in a 4bpp mode, X workarea coordinates must be multiple
- of 2 pixels. From 8bpp modes on (and so also 16bpp and 32bpp) there aren't restrictions.
- 3) ALL MEMORY LOCATIONS (Points&Primitives workarea, Zbuffer, TMmemoryblock, .... etc.)
- MUST BE WORD ALIGNED!
- 4) When drawing to screen, the workarea you specify is always clipped to fit into it:
- ________________ ________________
- | screen | | screen |
- ___|__________ | |__________ |
- | | | | | | |
- | | | | ====>>> | workarea | |
- | | | | | | |
- | |__________|_____| |__________|_____|
- | workarea |
- |______________|
-
-
-
-
- TopModel 3D scene
- =================
- In a TopModel 3Dscene (&139) basically you can find (raw by raw)
-
- 3DScene | Header
- 2.00 | file version number
- 27185169 | mode as described in "Gemini_Render" (in R4)
- 48896 | min size of points workarea needed (+58*32 bytes always)
- 85056 | min size of primitives workarea needed
- 0 | min size of group data needed
- 24576 | min size of mats+cols+textures
- 122000 | min size of a standard RiscOS sprite-area to load the textures used
- 256 | size of the portion of TMviewblock saved
- 0 | reserved, must be 0
- 0 | reserved, must be 0
- 0 | reserved, must be 0
- 55232 | ldm of points workarea when it was saved
- 333376 | ldm of primit.workarea when it was saved
- 1680832 | ldm of texture sprite-area when it was saved
-
- Then you find a memory dump of points, primitives and groups workareas,
- colours+materials+textures table, spritefile containing the texture and TMviewblock area.
-
-
-
-
- TopModel 3D file
- ================
- In a TopModel 3DFile (&B5C) basically you can find (raw by raw)
-
- 3DModel | Header
- 2.00 | file version number
- View1 0,403520,-63204,[...] | view infos (optional, may be present or not)
- Ambiental 255,255,255, 0 | ambiental light infos (optional)
- Solar 255,255,255, [...] | standard sun light infos (optional)
- Grid 50,4.0000,4.0000 [...] | grid infos (optional)
- 127392 | min size of points workarea needed (+58*32 bytes always)
- 284992 | min size of primitives workarea needed
- 0 | min size of group data needed
- 3980 | total number of points and lights
- 7124 | total number pf primitives in the file
- 3980 | number of selected points when saved
- 7124 | number of selected primitives when saved
- 0 | number of selected groups when saved
- 0 | number of selected lights when saved
- 981456 | ldm of points workarea when it was saved
- 1113392 | ldm of primit.workarea when it was saved
- 1 | n^ of textures used
- 1 -536870912 ,Materials.ceramic.2 | (text.number) (transparent colour), path
- 1 , 1 | n^ of user defined colours, materials
- Colour1,15658507 | (colour name),(&BBGGRR00)
- Material1, 194841272,0,0,0,0 | (material name),mat!12,mat!16,mat!20,mat!24,mat!28 (the latter is currently unused)
-
- Then the file goes on with a memory dump of the points workarea followed
- immediately by a memory dump of the primitives and of the groups workareas.
-
-
-
-
- Disclaimer
- ==========
- The module and this documentation are supplied "as is"; neither Sicronia nor
- the author of Gemini make any warranty, whether express or implied, as to the
- merchantability of the software or its fitness for any purpose.
- In no circumstances will Sincronia or the author of Gemini be liable for
- any damage, loss of profits, goodwill or for any indirect or inconsequential
- loss arising from the use of this software or of this documentation.
- Using Gemini is deemed acceptance of these terms.
-