## visu_extension visu_extension — All objects drawn by V_Sim are defined in by a VisuExtension object |

## Synopsis

    #define             VISU_EXTENSION_PRIORITY_BACKGROUND
    #define             VISU_EXTENSION_PRIORITY_NODES
    #define             VISU_EXTENSION_PRIORITY_NODE_DECORATIONS
    #define             VISU_EXTENSION_PRIORITY_HIGH
    #define             VISU_EXTENSION_PRIORITY_NORMAL
    #define             VISU_EXTENSION_PRIORITY_LOW
    #define             VISU_EXTENSION_PRIORITY_LAST
                        VisuExtension;
    void                (*VisuExtensionRebuildFunc)         (VisuData *dataObj);
    VisuExtension*      visu_extension_new                  (const gchar *name,
                                                             const gchar *nameI18n,
                                                             const gchar *description,
                                                             int objectListId,
                                                             VisuExtensionRebuildFunc rebuild);
    void                visu_extension_free                 (VisuExtension *extension);
    GList*              visuExtensions_getList              (void);
    void                visu_extension_setPriority          (VisuExtension *extension,
                                                             guint priority);
    void                visu_extension_setSaveOpenGLState   (VisuExtension *extension,
                                                             gboolean saveState);
    void                visu_extension_setSensitiveToRenderingMode
                                                            (VisuExtension *extension,
                                                             gboolean status);
    gboolean            visu_extension_setPreferedRenderingMode
                                                            (VisuExtension *extension,
                                                             VisuRenderingModeId value);
    int                 visu_extension_getActive            (VisuExtension *extension);
    void                visu_extension_setActive            (VisuExtension *extension,
                                                             int value);
    void                visuExtensions_add                  (VisuExtension *extension);
    VisuExtension*      VisuExtensionGet_fromName           (const gchar *name);
    void                visuExtensions_remove               (VisuExtension *extension);
    void                visuExtensions_callAllLists         (void);
    void                visuExtensions_callList             (const char *name,
                                                             gboolean lastOnly);
    void                visuExtensions_callAllLastLists     (void);
    void                visuExtensions_rebuildAllLists      (VisuData *dataObj);
    void                visuExtensions_rebuildList          (VisuData *dataObj,
                                                             const char *name);
    int                 initVisuExtensions                  (void);
    void                loadExtensions                      (void);

## Description

All objects that are drawn by V_Sim are handled by a VisuExtension object. Such an object has an OpenGL list. This list is only COMPILED. When V_Sim receives the 'OpenGLAskForReDraw' or the 'OpenGLForceReDraw' signals, each list of all known VisuExtension are excecuted. This excecution can be canceled if the used flag of the VisuExtension object is set to FALSE. The order in which the lists are called depends on the priority of the VisuExtension object. This priority is set to VISU_EXTENSION_PRIORITY_NORMAL as default value, but it can be tune by a call to `visu_extension_setPriority()`. This priority is an integer, the lower it is, the sooner the list is excecuted.

The method `registerVisuExtension()` is used to declare to V_Sim that there is a new VisuExtension object available. This allows to create extension when V_Sim is already running. Nevertheless, an extension must be initialized in the initialisation process, it is better to add an initVisuExtensionFunc method in the listInitExtensionFunc array declared in extensions/externalVisuExtensions.h.

Once again, the OpenGL list corresponding to an OpenGL extension is COMPILE only. Then, OpenGL methods like `glIsenabled()` are totally unusefull because it is called when the list is compiled not when the list is called. If the extension needs to alter some OpenGL state, such as desable GL_LIGHTING, it needs to set a flag for the extension. With this flag, V_Sim will save the OpenGL states and restore it when the list is called. Use `visu_extension_setSaveOpenGLState()` to set this flag.

## Details

### VISU_EXTENSION_PRIORITY_BACKGROUND

    #define VISU_EXTENSION_PRIORITY_BACKGROUND 0

An extension with this priority is drawn first.

### VISU_EXTENSION_PRIORITY_NODES

    #define VISU_EXTENSION_PRIORITY_NODES 2

An extension with this priority is drawn alsmost first with the nodes.

### VISU_EXTENSION_PRIORITY_NODE_DECORATIONS

    #define VISU_EXTENSION_PRIORITY_NODE_DECORATIONS 5

An extension with this priority is drawn just after the nodes.

### VISU_EXTENSION_PRIORITY_HIGH

    #define VISU_EXTENSION_PRIORITY_HIGH 20

An extension with this priority is drawn after the higher priorities.

### VISU_EXTENSION_PRIORITY_NORMAL

    #define VISU_EXTENSION_PRIORITY_NORMAL 50

An extension with this priority is drawn after the higher priorities.

### VISU_EXTENSION_PRIORITY_LOW

    #define VISU_EXTENSION_PRIORITY_LOW 80

An extension with this priority is drawn among last extensions.

### VISU_EXTENSION_PRIORITY_LAST

    #define VISU_EXTENSION_PRIORITY_LAST 100

An extension with this priority is drawn last.

### VisuExtension

    typedef struct {
      /* Some variable to describe this OpenGL extension.
         The attribute name is mandatory since it is
         used to identify the method. */
      gchar *name, *nameI18n;
      gchar *description;

      /* The id of the possible objects list brings by
         the extension is refered by this int. */
      int objectListId;

      /* Function called to rebuild the object list of the extension. */
      VisuExtensionRebuildFunc rebuild;

      /* A priority for the extension. */
      guint priority;

      /* If set, V_Sim save the OpenGL state before the list
         id is called and restore all states after. */
      gboolean saveState;

      /* Fine tune of rendering mode (Wireframe, smooth...).
         The flag isSensitiveToRenderingMode define is the
         extension cares about rendering mode. This flag is FALSE
         by default. When FALSE, the global value for rendering
         mode is used. Otherwise the value is stored in
         preferedRenderingMode. */
      gboolean isSensitiveToRenderingMode;
      VisuRenderingModeId preferedRenderingMode;

      /* A boolean to know if this extension is actually used
         or not. */
      int used;
    } VisuExtension;

This structure allows the user to store data about an OpenGL extension.

gchar *`name`; | name of the extension, in ASCII, used as id in the config files ;
gchar *`nameI18n`; | name in UTF8 that can be translated and shown to user ;
gchar *`description`; | a short text in UTF-8 ;
int `objectListId`; | the id of the OpenGL list that represent this extension. This id is called whenever the extension need to be drawn ;
VisuExtensionRebuildFunc `rebuild`; | method called when the OpenGL context has changed and the extension need to be recomputed ;
guint `priority`; | control the order of drawing ;
gboolean `saveState`; | if TRUE, all OpenGL parameters are saved and will be restored after the extension has been called ;
gboolean `isSensitiveToRenderingMode`; | if TRUE, the extension can be drawn using a rendering mode different from the other extension (smooth, wireframe...) ;
VisuRenderingModeId `preferedRenderingMode`; | the specific rendering mode ;
int `used`; | if FALSE, the OpenGL id is skipped when redraw is necessary.

### VisuExtensionRebuildFunc ()

    void                (*VisuExtensionRebuildFunc)         (VisuData *dataObj);

Prototypes used to recreate OpenGL list of objects for each extension.

`dataObj` : | the VisuData object to be rebuilt.

### visu_extension_new ()

    VisuExtension*      visu_extension_new                  (const gchar *name,
                                                             const gchar *nameI18n,
                                                             const gchar *description,
                                                             int objectListId,
                                                             VisuExtensionRebuildFunc rebuild);

Create a new VisuExtension with the specified name, description and OpenGL object list. The priority is set by default to VISU_EXTENSION_PRIORITY_NORMAL. The flag used to store the OpenGL state is put to FALSE by default (see `visu_extension_setSaveOpenGLState()` to chance it).

`name` : | name of the extension, in ASCII, used as id in the config files,. type filename
`nameI18n` : | name in UTF8 that can be translated and shown to user,. type utf8
`description` : | a brief description of the extension (can be null),. allow-none.
`objectListId` : | an int to identify an list of OpenGL objects (null if this extension as no OpenGL object,
`rebuild` : | handler to a method that is called every time V_Sim needs to create again the OpenGL object list. If NULL, nothing is called.. scope call
Returns : | the new VisuExtension or null if something wrong happens.. transfer none.

### visu_extension_free ()

    void                visu_extension_free                 (VisuExtension *extension);

Free all the allocated attributes of the specified method.

`extension` : | the extension to delete.

### visuExtensions_getList ()

    GList*              visuExtensions_getList              (void);

This method is used to get the list of all registered VisuExtension. This list is own by V_Sim and should not be freed.

Returns : | the list of all VisuExtension.

### visu_extension_setPriority ()

    void                visu_extension_setPriority          (VisuExtension *extension,
                                                             guint priority);

Extentions are drawn in an order that depends on their priority. The lower is the number, the sooner the extension is drawn. Flags, such as VISU_EXTENSION_PRIORITY_NORMAL or VISU_EXTENSION_PRIORITY_LOW, can be used or user defined values are also possible.

`extension` : | a VisuExtension object ;
`priority` : | an integer value.

### visu_extension_setSaveOpenGLState ()

    void                visu_extension_setSaveOpenGLState   (VisuExtension *extension,
                                                             gboolean saveState);

If the extension needs to change some OpenGL state (to disable the fog for example, or the cullface), a flag should be set to enable V_Sim to restore the right values after the extensio have been called. Because the OpenGL list of an extension is just GL_COMPILE the extension can't just save and restore state itself because when the list is called, the state can have been changed.

`extension` : | a VisuExtension object ;
`saveState` : | an boolean value.

### visu_extension_setSensitiveToRenderingMode ()

    void                visu_extension_setSensitiveToRenderingMode
                                                            (VisuExtension *extension,
                                                             gboolean status);

If `status` is TRUE, when the extension is rendered, OpenGL context is switched to the rendering mode preferd for the extension. Use `visu_extension_setPreferedRenderingMode()` to choose one.

`extension` : | a VisuExtension object ;
`status` : | an boolean value.

### visu_extension_setPreferedRenderingMode ()

    gboolean            visu_extension_setPreferedRenderingMode
                                                            (VisuExtension *extension,
                                                             VisuRenderingModeId value);

This method is used to specify the rendering mode that the extension should use to be drawn (if the sensitive flag has been set, see `visu_extension_setSensitiveToRenderingMode()`). If the `value` is set to followGeneralSetting, the extension follows the global setting for rendering mode.

`extension` : | a VisuExtension object ;
`value` : | see VisuRenderingModeId to choose one.
Returns : | TRUE if the "OpenGLAskForReDraw" should be emitted.

### visu_extension_getActive ()

    int                 visu_extension_getActive            (VisuExtension *extension);

Get if the extension is used or not. If not its ObjectList is not rendered.

`extension` : | the extension.
Returns : | 1 if used, 0 otherwise.

### visu_extension_setActive ()

    void                visu_extension_setActive            (VisuExtension *extension,
                                                             int value);

Set if an extension is actually used or not.

`extension` : | the extension,
`value` : | the new value.

### visuExtensions_add ()

    void                visuExtensions_add                  (VisuExtension *extension);

A method used by user to registered a new extension.

`extension` : | an extension.

### VisuExtensionGet_fromName ()

    VisuExtension*      VisuExtensionGet_fromName           (const gchar *name);

Look for the extension with this name.

`name` : | a string.
Returns : | the extension or NULL if none.

### visuExtensions_remove ()

    void                visuExtensions_remove               (VisuExtension *extension);

This method is used to removed fom the list of registered VisuExtension the given one. Removing `extension` does not free it.

`extension` : | an extension.

### visuExtensions_callAllLists ()

    void                visuExtensions_callAllLists         (void);

For each registered extension that has a valid list (id > 1000), it calls it with glCallList.

### visuExtensions_callList ()

    void                visuExtensions_callList             (const char *name,
                                                             gboolean lastOnly);

Select the VisuExtension matching the given `name` and call it. The call is indeed done only if the extension is used. If `lastOnly` is TRUE, the list is called only if it has a VISU_EXTENSION_PRIORITY_LAST priority. On the contrary the list is called only if its priority is lower than VISU_EXTENSION_PRIORITY_LAST. To draw all of them, use `visuExtensions_callAllLists()` instead.

`name` : | the name of the list to be called.
`lastOnly` : | a boolean.

### visuExtensions_callAllLastLists ()

    void                visuExtensions_callAllLastLists     (void);

Call all lists whose priority is exactly VISU_EXTENSION_PRIORITY_LAST. To draw other priority, see `visuExtensions_callList()`.

Since 3.6

### visuExtensions_rebuildAllLists ()

    void                visuExtensions_rebuildAllLists      (VisuData *dataObj);

For each registered extension that has a valid rebuild method, it calls it.

`dataObj` : | the VisuData object to be rebuilt.

### visuExtensions_rebuildList ()

    void                visuExtensions_rebuildList          (VisuData *dataObj,
                                                             const char *name);

Select the VisuExtension matching the given `name` and rebuild it. This routine does not sort the extension on their priority and should be used only to draw some selected extensions. To draw all of them, use `rebuildAllExtensionsLists()` instead.

`dataObj` : | the VisuData object to be rebuilt ;
`name` : | the name of the list to be rebuilt.

### initVisuExtensions ()

    int                 initVisuExtensions                  (void);

Initialise all the variable of this part. It calls all the elements in listInitExtensionFunc (that stores the init function of the extensions). If these elements return valid VisuExtension, they are registered through a call to `registerVisuExtension()`.

Returns : | 1 if everything goes allright during the initialisation.

### loadExtensions ()

    void                loadExtensions                      (void);

This method is used when V_Sim is initialized and should not be called elsewhere. For each valid init method found in listInitExtensionFunc, it is called.