Optimisation des performances

Si vous travaillez sur un grand projet, il est extrêmement important que vous vous préoccupiez des bonnes performances. C'est une croyance répandue que les graphismes qui peuvent êtres faits, dépendent seulement du moteur 3D qui est utilisé. Bien entendu un meilleur moteur peut conduire à de meilleur résultats. Mais plus un moteur a de potentiel, plus il est difficile d'utiliser toutes les fonctionnalités qui sont requises pour faire tourner le jeu de manière fluide. La complexité d'un jeu qui peut être fait avec un moteur dépend seulement de combien de possibilités sont offertes pour optimiser les performances du jeu. Généralement la façon la plus facile de réaliser quelque chose n'est pas la plus efficace, ni la plus rapide. Il faut de l'expérience et des connaissances pour trouver la solution optimale. Vous aurez aussi besoin de comprendre comment Ultimate 3D fonctionne de façon interne. Ce tutorial vous aidera à apprendre ces choses.

Conseils généraux

Pour les programmeurs avancés, les conseils généraux suivants devraient être tout à fait évidents. Mais étant donné qu'il est extrêmement important de les connaître ils seront listés ici à nouveau. Une des choses les plus importantes qu'il vous faut savoir est que le nombre de vertex et de triangles sont des facteurs extrêmement importants pour les performance de votre jeu. Calculer toutes les données qui sont requises pour un vertex prend un certain temps de calcul, vous devriez donc utiliser le moins de vertices possibles lors de la création d'un nouveau modèle pour votre jeu. Si vous travaillez dans un programme de modélisation professionnel tel que Blender ou 3D Studio Max vous pouvez utiliser des plugins pour optimiser vos meshs (Dans Blender c'est le Decimate Modifier). Les programmes de modélisation moins complexes auront au moins une fonctionnalité qui vous permet de voir de combien de vertices le modèles est fait actuellement. C'est utile pour réduire le nombre de vertex manuellement. Bien entendu, la façon la plus facile pour obtenir des modèles avec peu de vertex est de ne pas gaspiller de vertices dès le début de la modélisation. Soyez extrêmement prudents avec les fonctionnalités qui subdivisent les faces des modèles pour les rendre plus agréables. Aussi, n'utilisez pas un nombre élevé de subdivision lors de la création d'objets primitifs (les variables partsx, partsy et partsz).

Le prochain conseil est moins évident. Les performances de votre jeu dépendent aussi de combien de pièces de géométrie doivent être rendues séparement. Si vous avez deux pièces de géométrie dans votre modèle, Ultimate 3D les rendra seulement ensemble si elles utilisent le même matériau et si elles font parties du même mesh. Le pire des cas sera un modèle dans lequel vous avez une quarantaine de meshs différents, fait chacun de 20 triangles tout au plus mais utilisant encore trois matériau différents. Dans ce cas Ultimate 3D ne serait pas capable d'afficher plus de 10 triangles simultanément. Donc soyez parcimonieux avec le nombre de matériaux différents et utilisez des meshs qui sont faits de beaucoup de géométries lorsque vous modelez. Souvent l'utilisation d'un matériau texturé est plus efficace et rapide que l'utilisation de trois ou quatres matériaux différents et généralement c'est même plus beau de cette façon.

Vous ne devriez pas utiliser des textures trop grosses étant données qu'elles prennent beaucoup de mémoire. Plus vos textures prennent de mémoire, plus tôt la mémoire vidéo du périphérique graphique sera pleine. Ensuite la mémoire système devra être utilisée et dans ce cas la texture devra être passée de la mémoire système à la mémoire vidéo à chaque step, ce qui est très intensif et trop long. Donc si vous avez beaucoup de textures chargées simultanément, vous devriez libérer autant de mémoire que possible en appellant ReleaseTexture(...). En dehors de cela, vous devriez vraiment utiliser des dimensions qui sont faites de puissances de deux pour toutes vos textures. Si vous chargez une texture de la taille de 512*512 elle sera chargée exactement avec cette taille, mais si vous chargez une texture avec une taille de 513*513 elle sera mise à l'échelle de la puissance de deux supérieure, qui est 1024*1024. Il est très clair que c'est un gaspillage énorme de mémoire et de temps de calcul.

Soyez économe avec le nombre de sources de lumières dans votre scène. Si vous avez un nombre extrêment haut de sources de lumières, cela prendra beaucoup de temps de calcul pour chacun des vertex. Dans ce cas il peut être plus rapide d'apprendre à utiliser Deled ou d'autre logiciels de modélisation pour réaliser le light mapping. Pour obtenir un jeu efficace et rapide vous devrez souvent trouver un compromis entre les solutions flexibles et statiques. La flexibilité requière toujours beaucoup de temps de calcul, mais fait généralement moins de travail et rend le jeu plus vivant. Les solutions statiques prennent plus de mémoire étant donné que vous avez quelques données précalculées, mais elles prendront beaucoup moins de temps de calcul et pourront paraîtres plus belles, puisque le temps de précalcul des données statiques n'aura aucune influence. La comparaison entre l'éclaire par pixel ou l'éclairage par vertex et le light mapping est un très bon exemple, dans ce cas. Une répetition du coût élevé en terme de temps de calcul de la projection d'ombres n'est, je l'espère, pas requise ici. 

Trouver le moyen le plus efficace de dessiner une pièce de géométrie

Ultimate 3D offre un ensemble de possibilités différentes pour manipuler une pièce de géométrie chargée depuis un fichier de modèle. Vous pouvez créer les LoD (Niveaux de Détail) pour ce dernier ou vous pouvez le manipuler comme un objet primitif. L'une ou l'autre de ces possibilités peuvent être la meilleure selon la situation. Quelque fois ce sera peut être plus efficace d'afficher un modèle avec des LoDs; quelque fois l'opposé pourrait être la solution. Il existe aussi des cas où il est beaucoup plus efficace et rapide de manipuler la pièce de géométrie comme un objet primitif; dans d'autres cas cela ne ferait aucun sens. Ce sous-chapitre contient quelques informations à propos de l'utilisation correcte des différentes façons de manipuler les modèles et donne des indications sur les solutions les meilleures dans différents scénarios.

Commençons avec l'utilisation correcte et propre des différents niveaux de détail. C'est une fonctionnalité très pratique qu'Ultimate 3D peut faire automatiquement et souvent cela peut augmenter considérablement les performances de votre jeu. En général, cela devrait être utilisé pour n'importe quel modèle qui doit paraître très détaillé lorsqu'il est proche de la caméra. Mais comme je l'ai déjà dit, vous ne devriez jamais l'utiliser pour les modèles utilisant les frames d'animation (que ce soit les modèles chargé depuis des fichiers *.md2 ou des animations créées à l'aide de AddFrame(...)). Il ne fait non plus aucun sens d'utiliser des LoDs si vous ne pouvez aller suffisamment loin du modèle. Par exemple, si vous avez un jeu quelconque de tir à la première personne dans lequel vous êtes toujours et seulement dans de petites pièces, l'utilisation de LoDs sera inefficace. Dans un tel cas il y a une façon bien meilleure d'optimiser le jeu. Cela sera introduit plus bas.

Il y a certains cas où l'utiilisation de la fonction CreatePrimitiveFromModel() pourra conduire à une nette amélioration de la performance, et d'autres cas où cela se révèlera tout à fait inefficace. En général les primitifs sont parfait pour tout les types d'objets simples ou statiques qui constituent le niveau. Par exemple, si vous avez de simples modèles de murs qui ne requièrent aucun effet pour donner une bonne apparence et qui sont faits de moins de 100 vertices, l'utilisation de primitifs serait parfaite dans un tel scénario. Les primitifs sont aussi parfaits pour calculer le rendu de la végétation. Vous devriez donc vraiment l'utiliser si c'est possible. Bien entendu il est un peu plus difficile de faire un modèle complexe avec seulement une texture mais le jeu en vaut la chandèle. Je vous conseille vivement d'utiliser des fichiers *.an8 pour les modèles que vous voulez utiliser avec cette fonction, parce que pour ces derniers Ultimate 3D les mettra,  automatiquement, tous ensembles dans un même mesh.    

Désactiver l'alpha blending

Contrairement aux versions antérieures d'Ultimate 3D, Ultimate 3D 2.0 beta 3 et les nouvelles versions n'ont aucun problème avec les textures partiellements transparentes. Dans les versions antérieures, ces dernières conduisaient très souvent à des problèmes d'affichage. Malheureusement le prix pour cela est plutôt élevé. L'objet tout entier doit être rendu deux fois dans le cas où il utilise une texture partiellement transparente. Au premier passage, on ne rend que les parties totalement opaques, au second passage on rend seulement les parties complètement transparentes. Etant donné que cela peut réduire considérablement les performances, Ultimate 3D vous permet de désactiver ces méthodes pour les objets particuliers. Les choses partiellements transparentes vont devenir complètement transparentes, mais cela accelèrera beaucoup les choses.

Cette fonction active ou non l'alpha blending pour l'objet de modèle ou le primitif donné. Par défaut l'alpha blending est activé.

SwitchAlphaBlending(
EnableDisable
)

EnableDisable
Si vous passez true pour ce paramètres, les parties partiellements transparentes seront rendues durant un second calcul de rendu (coûteux en performances), autrement les parties partiellements transparentes seront complètement invisible (rapide et efficace).


Mesurer les facteurs de performance importants

Pour être à même de dire, si vous avez bien optimisé votre projet, vous devez être capable de mesurer les facteurs, qui influent sur la performance. Il existe essentiellement deux facteurs. Le premier est le bien connu nombre de triangles. Le second est le nombre d'appel de traçage, qui était nécessaire pour calculer le rendu de la scène. À chaque fois qu'Ultimate 3D passe une pièce de géométrie au périphérique graphique, pour en calculer le rendu, c'est qu'un appel de traçage a été fait. Par exemple chaque groupe d'objets primitifs avec des propriétés identiques, requièrent un appel de traçage par step et par caméra, et chaque objet de modèle requière un appel de traçage par step par matériau et par caméra. C'est tailles indicatrices de la performance, peuvent être récupérées très facilement dans Ultimate 3D. 

Cette fonction retourne le nombre de triangles qui ont été tracés au step précédent. Cela inclus également les triangles, dont le rendu n'a pas été calculé du fait du backface culling.

GetDrawnTriangleCount()

Cette fonction retourne le nombre d'appel de traçage qui ont été nécessaires au step précédent pour dessiner la scène.

GetDrawCallCount()

Les valeurs de retour de ces fonctions peuvent être très intéressantes. Vous pouvez voir combien les techniques de culling utilisées (voir plus bas) fonctionnent et quels objets ont un fort impact sur le nombre de triangles tracés. Vous pouvez voir combien l'utilisation de LoDs réduit le nombre de triangles et comment l'utilisation d'objets primitifs réduits le nombre d'appel de traçage.  Tandis que vous modifiez les performances de votre application vous devriez ajouter un peu de code, qui affiche ces valeurs à l'écran, de sorte que vous puissiez toujours avoir un oeil sur elles.

Les fonctions avancées de culling

Le concept qui se cache derrière le culling est plutôt simple. Il consiste à éviter de calculer le rendu de ce qui n'est pas actuellement visible. Par défaut Ultimate 3D utilise deux techniques de culling; le back face culling et le frustum culling. Le Back face culling signifie que seul le rendu du côté face à nous de chaque triangle est calculé. De cette façon pas plus de la moitié du rendu de la géométrie doit être calculé. Le Frustum culling est la technique par laquelle on va éliminer du rendu les polygones ou objets se trouvant en dehors du champ de vision, on appelle cela une view frustum. L'image suivante explique ce qu'est une view frustum:

PerformanceFrustumCulling.pngIllustration not available

Vous pouvez aussi directement accéder au frustum culling d'Ultimate 3D. C'est très utile si du code doit être éxécuté seulement si un objet particulier est visible. Par exemple si vous avez un moniteur de sécurité, qui utilise une caméra avec une texture cible de rendu, cette caméra ne doit calculer le rendu de la scène qu'elle voit, seulement si le moniteur de sécurité peut être vu. Pour déterminer si un objet est dans le view frustum ou pas, vous pouvez utiliser la fonction suivante.

Cette fonction retourne "true" si la bounding box donnée est dans le view frustum de la caméra, ou "false" si elle ne l'est pas.

CheckBoundingBoxVisibility(
BoundingBoxMinimumVectorID, BoundingBoxMaximumVectorID,
BoundingBoxTransformationID,
CameraIndex
)

BoundingBoxMinimumVectorID, BoundingBoxMaximumVectorID
L'ID de deux vecteurs définissant la bounding box. La bounding box sera cubique, où le coin inférieur arrière gauche aura la coordonnée BoundingBoxMinimumVectorID et le coin droit supérieur avant aura la coordonnée BoundingBoxMaximumVectorID. Si BoundingBoxMinimumVectorID est négatif, le vecteur (-1, -1, -1) sera utilisé, si BoundingBoxMaximumVectorID est négatif, le vecteur (1, 1, 1) sera utilisé.  

BoundingBoxTransformationID
L'ID de la matrice de transformation, qui sera utilisée pour transformer la bounding box spécifiée par les deux paramètre précedents. Si ce paramètre est négatif, aucune transformation ne sera utilisée.

CameraIndex
L'indice de la caméra, qui a le view frustum qui doit être utilisé. C'est la valeur de la variable number, et non pas l'ID de l'objet caméra.

Quoi qu'il en soit, il est temps de revenir aux fonctions de culling avancées. Si certaines géométries qui sont rendues ne sont pas visibles, cela signifie qu'elles ont été couvertes par d'autres objets. Pour éviter que les géométries soient couvertes dans ce cas, une trois technique de culling est nécessaire. Et c'est exactement à quoi sont destinées les fonctions de culling avancées. Elles fonctionnent de la façon suivante. Tout d'abord, vous assignez chaque objet de la scène - que ce soit un primitif, un modèle, un terrain, un système de particule ou une source de lumière - à une room. Une room n'est rien qu'un indice et la somme d'objet qui y est associée. Par défaut chaque objet est assigné à la room avec l'indice 0. Ensuite vous devrez définir quelle room peut être vue par quelle caméra. Par défaut seule la room avec l'indice 0 est définie comme visible pour chaque caméra. Cela peut être fait soit manuellement, ou Ultimate 3D peut le faire automatiquement. 

Dans les niveaux d'intérieur cela peut être particulièrement utile. Lorsque le joueur ouvre une porte, une nouvelle room est définie comme visible. Si le joueur passe à travers la porte et la ferme, l'ancienne room est définie comme invisible. De cette façon vous pouvez réduire le nombre de rooms qui doivent être rendues, par un ou deux. Toutes les autres rooms n'ont pas d'intérêt. La source de lumière éclairera seulement les objets qui sont associés à la même room, ce qui conduit bien sûr à une augmentation des performances. La seule exception à cette règle sont les sources de lumières qui sont associées avec la room 0. Celles-ci éclaireront absolument tous les objets.

Les fonctions qui sont nécessaires pour cette fonctionnalité sont vraiment simples. Il n'y a que deux fonctions, une pour assigner les objets aux rooms, et une pour définir une room à l'état visible ou invisible pour une caméra particulière.

Cette fonction assigne l'objet qui l'appelle à une room.

SetObjectRoom(
RoomIndex
)

RoomIndex
L'indice de la room à laquelle vous souhaitez assigner l'objet. Cela peut être une valeur entière arbitraire allant de 0 à 1999.

Cette fonction définit la room donnée à l'état visible ou invisible pour l'objet de caméra qui l'appelle, ou pour la première caméra si ce n'est pas appellé par un objet de caméra. Remarquez que cette fonction doit être appellée après MoveCamera().

SetRoomVisibility(
RoomIndex,
NewVisibilityState
)

RoomIndex
L'indice de la room que vous voulez définir à l'état visible. Cela peut être un entier arbitraire entre 0 et 1999.

NewVisibilityState
L'état de visibilité que vous voulez définir pour la room donnée. Cela peut être soit "true" pour définir la room comme visible ou "false" pour définir la room comme invisible.

Plus haut, j'ai dit que le changement d'état visible/invisible des rooms pouvait être fait manuellement ou automatique. Comme vous pouvez le voir, la manière manuelle est vraiment simple, mais cela vous fera beaucoup de travail. Et vous avez déjà suffisamment de travail, à assigner les objets aux différentes rooms. La façon automatique devrait donc être préférée en général. Elle est basée sur ce qu'on appelle les portails.

Un portail peut être une porte, une fenêtre, un portail, une rue, un canyon ou toute autre chose au travers de laquelle on peut passer ou regarder. C'est quelque chose qui peut conduire l'objet de caméra ou un autre objet, d'une room A vers une room B. Les portails sont représentés par la plus simple des formes, un cercle. Si une caméra passe au travers d'un portail, elle ira dans une nouvelle room, ce qui signifie que cette room sera visible. Et toutes les rooms qui se cachent derrière les portails qui sont visibles, seront bien entendu visibles. Etant donné que cette définition est plutôt abstraite, cela va se clarifier à l'aide d'un ensemble d'illustrations montrant différentes situations.

PerformancePortalNewRoom.png

Il s'agit d'un cas très simple. Il ya quatre rooms différentes, avec quatres portes entre elles. Chaque porte a un portail (bleu) défini pour elle. Initialement la caméra est dans la room 1, mais ensuite elle se déplace au travers du portail de room 1 vers room 2, donc après elle est dans room 2 et Ultimate 3D est à même de le détecter, puisqu'il a les données du portail. À peu près la même chose arrive pour l'objet de modèle. Au début il est dans room 1, donc il ne sera visible que si la room 1 est visible. Ensuite il se déplace vers la room 4 et Ultimate 3D le détecte, grâce au portail. Donc après ça il ne sera visible que si room 4 est visible. Pour les objets de modèle et les autres objets de géométrie c'est tout ce qui est nécessaire, mais pour la caméra c'est un peu différent, tout en restant aussi simple, parce que la caméra peut voir plus de room que celle dans laquelle elle est. Lorsque la caméra est dans room 1 elle peut aussi voir la room 2 au travers de la porte. Pour être plus précis, elle peut voir room 2 lorsqu'elle peut voir le portail allant de room 1 à room 2. Donc room 2 sera visible lorsque la porte vers room 2 est visible. Le schéma suivant illustre ce concept.  

PerformancePortalVisibleRoom.png

Sur la gauche, la caméra ne regarde aucun portail, donc aucune room, mis à part celle où est la caméra est actuellement visible. Sur la droite, la caméra regarde vers le portail allant de room 1 à room 2, donc room 2 est aussi visible. Suit un dernier cas spécifique. La caméra ne peut pas uniquement voir les rooms qui sont derrière les portails visibles, qui conduit de la room actuelle à une autre room, mais aussi les rooms qui sont derrière un portail visible qui conduit de n'importe quelle room visible à une autre room. À nouveau un graphique explique cela.

PerformancePortalVisibleRoom2.png

Comme vous pouvez le constater room 1, room 2 et room 3 sont visibles. Room 1 est visible, parce que la caméra est dans cette room, room 2 est visible parce que le portail allant de room 1 à room 2 est dans l'angle de vision de la caméra et room 3 est visible, parce qu'un portail présent dans une room visible et conduisant à la room 3 est dans l'angle de vision de la caméra. Quelque chose ne va pas ici cependant, parce qu'il est très facile de voir que la room 3 n'est en réalité pas visible. C'est une petite erreur qui peut qui peut facilement arriver avec le moteur de portails d'Ultimate 3D. Mais il existe un moyen d'éviter ce problème dans de nombreux cas. D'usage les portes se ferme derrière le personnage une fois qu'il les a passé. Si elle est fermée, vous ne pouvez plus voir ce qui est derrière elle et cet effet est utilisé par Ultimate 3D. Dans la mesure où un portail est défini comme fermé, les rooms qui sont derrière ce portail ne seront plus visibles, même si le portail lui même est dans la zone de vision de la caméra. 

À l'aide de tous ces exemples, vous pouvez très bien comprendre l'utilité du moteur de portail. Dans un niveau habituel dans un plus gros jeu, il peut aisément y avoir une vingtaine de room dans un niveau. Calculer le rendu pour chacune d'elle à chaque frame serait un suicide total pour le CPU et le périphérique graphique. En utilisant le moteur de portails vous pouvez réduire le nombre de rooms dont le rendu doit être calculé simultanément à une simple room, qui est tout de même un gain de performances énorme. Cela va même mieux, parce que l'utilisation du moteur de portail ne prend pas de temps de calcul, ou presque pas. Le seul désavantage, réside dans le fait que cela fait énormément de travail pour définir tous les portails, et d'assigner tous les objets (ou du moins le plus grand nombre) aux différentes rooms. Différents méchanismes, qui aurait pu assigner les objets aux différentes rooms automatiquement, furent considérés durant le développement d'Ultimate 3D 2.0, mais la plupart d'entre eux se révélèrent trop compliqués, ou pas suffisamment fiables. Et sérieusement, combien de travail passez-vous sur votre jeu? Et comparé au gain de performance gigantesque, le peu de travail supplémentaire est insignifiant. Aussi, un éditeur de niveau qui est pensé pour être utilisé avec Ultimate 3D est prévu, et il rendra l'utilisation du moteur de portail bien plus facile. Quoiqu'il en soit ce projet n'est rien d'autre qu'une idée pour le moment, ne l'attendez donc pas pour tout de suite. (NdT: Rien ne vous empêche de créer le votre! ^^)

Eh bien, cela faisait à nouveau beaucoup de théorie, mais si l'avez entièrement comprise, les fonctions seront presque évidentes pour vous. La première fonction que vous devez connaître, active le moteur de portail pour un objet de caméra particulier.

Cette fonction active le moteur de portail pour l'objet de caméra qui l'appelle.

SwitchPortalEngine(
EnableDisable
)

EnableDisable
Si le moteur de portail doit être activé (true) ou désactivé (false).

Une fois que le moteur de portail est activé n'importe quel appel à SetRoomVisibility(...) sera ignoré. Peu importe il existe une bonne remplaçante pour cela. Cette fonction peut être utilisée pour forcer la visibilité d'une room pour la caméra qui l'appelle, même si le moteur de portail est activé.

SetRoomVisibilityEnforcement(
RoomIndex,
NewVisibilityEnforcementState
)

RoomIndex
L'indice de la room pour laquelle vous souhaitez forcer l'état de visibilité. Cela peut être un nombre arbitraire allant de 0 à 1999.

NewVisibilityEnforcementState
L'état de visibilité forcé, que vous voulez définir pour la room donnée. Si ce paramètre est "true" la room sera visible en toutes circonstances, autrement la visibilité dépendra des portails (ou de SetRoomVisibility(...) si le moteur de portail est désactivé). Pour la room 0 l'état de visibilité est forcé sur visible par défaut, pour toutes les autres c'est désactivé par défaut.

Les quatres prochaines fonctions peuvent être utilisées pour créer, modifier, fermer ou détruire des portails. Comme je l'ai dit plus haut, les portails sont représentés par des cercles. Un cercle est défini par une orientation (la direction vers laquelle il fait face), un centre et un rayon. De plus les portails contiennent deux indices de room.

Cette fonction crée un portail en utilisant les données fournies et retourne son identifiant.

CreatePortal(
CenterX, CenterY, CenterZ,
FacingDirectionLongitude, FacingDirectionLatitude,
Radius,
RoomIndex1, RoomIndex2
)

CenterX/Y/Z
Le centre du cercle qui définit le portail.

FacingDirectionLongitude, FacingDirectionLatitude
La direction vers laquelle le cercle fait face, qui définit le portail. Si vous créez un rayon à partir de ces deux angles, le cercle sera perpendiculaire à ce rayon.

Radius
Le rayon du cercle définissant le portail.

RoomIndex1, RoomIndex2
Les indices des rooms qui sont des différents côtés du cercle. Ces paramètres ne doivent jamais être égal à 0, parce que la room avec l'indice 0 est toujours visible lorsque le moteur de portail est activé et ne devrait pas être considéré comme une véritable room. L'ordre de ces paramètres n'a aucune influence. Si une caméra est dans une room avec RoomIndex1 et se déplace au travers du portail il sera dans la room avec RoomIndex2, et vice versa.

Cette fonction peut être utilisée pour modifier un portail après sa création.

SetPortal(
PortalID,
FacingDirectionLongitude, FacingDirectionLatitude, Radius, RoomIndex1, RoomIndex2
)

PortalID
L'identifiant du portail que vous souhaitez modifier. C'est la valeur de retour de l'appel à CreatePortal(...) qui a créé le portail.  

FacingDirectionLongitude, FacingDirectionLatitude, Radius, RoomIndex1, RoomIndex2
Voir ci-dessus.


Cette fonction peut être utilisée pour ouvrir un portail (il est ouvert par défaut) ou pour en fermer un.

OpenPortal(
PortalID,
OpenClose
)

PortalID
L'identifiant du portail que vous souhaitez modifier. C'est la valeur de retour de l'appel à CreatePortal(...) qui a créé le portail.

OpenClose
Passez "true" pour ouvrir ce portail ou "false" pour le fermer. Si un portail est fermé la caméra sera toujours capable de passer à travers pour aller dans une autre pièce, parce que les portails ne font pas de détection de collision, mais les rooms qui auraient pu être visibles à travers le portail ne le seront plus.

Cette fonction détruit le portail avec l'identifiant spécifié.

DestroyPortal(
PortalID
)

PortalID
L'identifiant du portail que vous voulez détruire. C'est la valeur de retour de l'appel à CreatePortal(...) qui a créé le portail.

Une donnée qui ne peut être trouvée au travers de l'utilisation des portails est, dans quelle room est la caméra initialement. Pour cette raison vous devez être à même de le définir manuellement. Cela peut être fait à l'aide de la fonction SetObjectRoom(...) juste comme n'importe quels autres objets.

Le moteur de portails ne vous apporte pas seulement un gain de performance, il peut aussi être très utiles pour programmer les choses liées au gameplay. Par exemple vous pouvez démarrer une cinématique particulière si une caméra passe pour la première fois à travers un portail particulier. Cela peut aussi être utile pour la programmation des IA. Si la caméra est dans la même room que l'ennemi, l'ennemi doit être actif. Pour réaliser des choses comme celles-ci, vous devez être à même de trouver dans quelle room se trouve actuellement un objet. Cette information peut être retrouvée à l'aide de la fonction suivante.

Cette fonction récupère l'indice de la room dans laquelle est l'objet qui l'appelle.

GetObjectRoom()

Une autre chose à ce propos, vous pouvez éviter beaucoup de calculs inutiles en les réalisant uniquement pour les objets qui sont dans une room visible. Par exemple les systèmes de particules n'ont pas besoin d'être mis à jour sans qu'ils ne soient visibles par la caméra, et les les objets n'ont pas besoin de chercher les collisions avec les autres objets dans les autres rooms. Pour déterminer si une room peut être vue par une caméra particulière vous pouvez utiliser la fonction suivante.

Cette fonction retourne si la room avec l'indice donné peut être vue par la caméra qui l'appelle.

GetRoomVisibility(
RoomIndex
)

RoomIndex
L'indice de la room dont vous souhaitez récupérer l'état de visibilité.

Beaucoup d'avantages sur l'utilisation des fonctions avancées de culling ont déjà été mentionnées. Elles augmentent fortement la performance, et peuvent être utilisées pour éviter l'exécution de code inutile, elles rendent le système de détection des collisions plus rapide, peuvent être utiles pour l'IA et elles vous donnent la possibilité de contrôler quelle source de lumière affecte quels objets. Voici maintenant, un autre avantage. L'utilisation des fonctions de culling avancées vous donne également la possibilité d'avoir différents éclairages ambiants pour différents objets. SetAmbient(...) spécifie une couleur d'éclaire ambiant particulière pour toutes les rooms. Vous pouvez changer cette couleur pour chaque room en usant de la fonction suivante.

Cette fonction change la couleur de l'éclairage ambiant pour une room donnée.

SetRoomAmbient(
RoomIndex,
AmbientColorR, AmbientColorG, AmbientColorB
)

RoomIndex
L'indice de la room pour laquelle vous voulez spécifier une nouvelle couleur d'éclairage.

AmbientColorR, AmbientColorG, AmbientColorB
La couleur de l'éclairage ambiant, qui doit être définie pour cette room. Pour plus d'informations sur l'éclairage ambiant, référez vous à la description de SetAmbient(...).

Remarquez que tout appel à SetAmbient(...) écrasera les changement fait avec cette fonction.


© Christoph Peters. Certains droits réservés. (Traduction FR 04/2008, Franck Vernel / Damien Buhl).

Creative Commons License XHTML 1.0 Transitional