Plusieurs Caméras

Par défaut vous avez un seul objet camera dans votre jeu. Mais il y a des situations particulières dans lesquels plus d'objets de caméra sont requis. Par exemple vous pouvez vouloir faire un jeu multijoueur avec écran splitté. Ou vous voulez peut être ajouter des caméra de surveillance à votre jeu, qui prenne des photos qui peuvent être affichées sur des moniteurs. Aussi, vous voulez peut être ajouter une reflexion réelle du monde à vos plans d'eau ou autres objets. Pour toutes ces choses vous avez besoin de caméras supplémentaires.

Dans Ultimate 3D vous pouvez utiliser jusqu'à 32 objets caméras simultanément. Les utiliser est très simple. En principe, tout les objets caméras fonctionne de la même manière que la première. La seule différence est qu'il vous faut définir la destination du rendu des autres objets de caméras. Il y a deux type de destinations. Vous pouvez afficher le rendu, soit sur une partie de l'écran de l'utilisateur, soit sur une texture spéciale. Ces textures spéciales peuvent être appliquées aux objets, de la même façon que les textures standards. Elles peuvent aussi être affichées à l'écran à l'aide de DrawTex(...) ou DrawTexEx(...).

Ajouter une nouvelle caméra à la scène

Chaque objet de caméra a les mêmes variables que le premier objet caméra, qui sont les suivantes: x, y, z, height, rotx, roty, rotz, view, min_range, max_range, falling, falling_speed, follow, perspective, et distance. Pour obtenir plus d'informations sur ces variables, jetez un oeil au tutorial Commençons par le début. Il y a aussi un ensemble de nouvelles variables que vous devez connaîtres. Le premier objet caméra les possède également, mais si vous ne le définissez pas manuellement elles sont définies avec des valeurs par défaut. Donc voici les nouvelles variables:

number
L'indice de cet objet caméra. La première caméra a 0 pour indice (il doit toujours y avoir une caméra avec number=0). La valeur valide la plus haute est 31. Vous ne devez jamais avoir deux objets caméra avec le même indice, au même moment.

v_left, v_top, v_width, v_height
La position et les dimensions de la vue que vous voulez utiliser pour la caméra. Ce sera la zone où le rendu de la caméra sera affiché. Remarquez que ces valeurs doivent être relatives à la coin haut gauche de la première view Game Maker (NdT: view[0]).

actual_aspect
Si vous n'avez pas besoin de cette variable, vous pouvez simplement l'ignorer. Par défaut, Ultimate 3D calculera l'aspect de la vue en divisant v_width/v_height. Mais étant donné que les textures de destination doivent avoir des dimensions faites de puissances de deux, il apparaîtra que ce quotient n'est pas l'aspect que vous souhaitez réellement.  Dans ce cas vous pouvez utiliser cette variable pour en définir un autre.

render_target
Si vous ne voulez pas afficher le rendu dans une texture, vous pouvez simplement ignorer cette variable. Sinon, vous devrez la définir à l'indice de la texture cible de rendu (render target texture) que vous voulez. Les textures cible de rendu peuvent être créées à l'aide de la fonction CreateTextureRenderTarget(...) (voir plus bas).

Chaque objet caméra doit appeler MoveCamera() dans son évènement step et Destroy() dans son évènement destroy. MoveCamera() transmettra n'importe quel changement des variables à Ultimate 3D. Si la caméra a une texture cible de rendu de définie, vous devrez appeller RenderToTexture() pour lui faire calculer son rendu. Bien entendu, vous n'êtes pas contraint de faire cet appel à chaque step. Si les objets utilisants la textures ne sont pas visible, ce serait un gigantesque gaspillage de temps de calcul d'appeler cette fonction. Aussi, les caméras de sécurités, n'ont pas besoin de mettre à jour leur image à chaque step. Dix fois par seconde devrait suffire. De cette façon vous pouvez rendre votre programme beaucoup plus rapide.


Plans de détourage et vues orthogonales

Parfois, certaines caméras n'ont pas besoin de rendre tout. Il y a deux possibilité de programmer cela. La plus facile est l'utilisation des fonctions de culling avancées. Avec ces fonctions vous pouvez définir quelles caméras rendront quels objets. Mais quelque fois il arrive que ce ne soit pas suffisamment précis. Par exemple, lors de la programmation d'effets pour le reflechissement de l'eau, vous avez besoin d'une caméra qui ne rend que le monde au dessus de la surface de l'eau. Pour ce faire, vous pouvez utiliser les plans de détourage. Vous définissez simplement un plan arbitraire. Tout ce qui est au dessus du plan sera calculé et rendu, et le reste sera invisible. Voici la fonction, vous permettant de définir un plan de détourage pour la caméra qui l'appelle.

SetClippingPlane(
ClippingPlaneIndex,
PlaneOriginX, PlaneOriginY, PlaneOriginZ,
PlaneOrientationLongitude, PlaneOrientationLatitude
)

ClippingPlaneIndex
Il peut y avoir jusqu'à six plans de détourage par caméra, selon la carte graphique. GetClippingPlaneSupport() retourne le nombre de plans de détourage supportés. Au travers de ce paramètre vous définissez quel plan de détourage vous souhaitez. Cela peut être une valeur entre 0 et 5.

PlaneOriginX/Y/Z
C'est un point arbitraire du plan que vous souhaitez définir comme plan de détourage.

PlaneOrientationLongitude, PlaneOrientationLatitude
Ces deux variablesn définissent l'orientation du plan (la direction vers laquelle le plan se dresse).


Une autre fonctionnalité petite mais utile d'Ultimate 3D est que le moteur permet l'utilisation de caméras avec une projection orthogonale. Cette dernière est principalement utilisée pour les utilitaires tels que les éditeurs de niveaux ou les programmes de modélisation. Dans une vue orthogonale, les objets qui sont loin derrière n'ont pas l'air d'être plus petits (ni plus grands). Il n'y a pas de ligne d'horizon. Vous n'avez pas d'angle donnant le champ de vision, parce que les limites de la zone visible sont toujours parallèles. À la place vous donnez une zone rectangulaire qui devra être visible en donnant une hauteur et une largeur.  Les caméras orthogonales ne peuvent exister dans la réalité, mais pour différents types d'éditeurs elles sont vraiment utiles, parce qu'elles réduisent l'image vue à deux axes. 

Cette fonction active la projection orthogonale pour la caméra qui l'appelle.

SetOrtho(
UseOrthogonalProjection,
SeenAreaWidth, SeenAreaHeight
)

UseOrthogonalProjection
Si vous passez true pour ce paramètre, Ultimate 3D activera la projection orthogonale pour cette caméra, si vous passez autre chose elle sera désactivée.

SeenAreaWidth, SeenAreaHeight
La largeur et la hauteur de la zone qui devra être visible. Ces valeurs sont utilisées au lieu de la valeur de la variable view.


Remarquez que les caméras orthogonales seront incapables de voir quelque chose se trouvant derrière elles, tout comme les caméras habituelle. Pour cette raison il vous faut l'éloigner suffisamment de la scène.


Création de textures (cible) de rendu et calculer des rendus pour les cube maps

Calculer des rendus vers une texture est une technique s'appliquant à un grand éventail de situation. Vous pouvez calculer le rendu d'une image vers une texture et l'utiliser comme n'importe quelle autre texture. Aussi, les fonctions de calcul du rendu vers les textures sont nécessaires pour faire des post screen shaders, qui peuvent être utilisées pour des effets tels que le HDR, motion blur ou les effets qui donnent l'aspect d'un très vieux film à votre jeu. Utiliser un post screen shader signifie que vous calculez le rendu de la scène vers une texture, au lieu d'afficher le rendu directement à l'écran. Ensuite vous calculez le rendu de la texture qui contient une image de la scène à l'écran, en y appliquant quelques effets de shaders.  Une prochaine version d'Ultimate 3D rendra l'utilisation des post screen shaders un peu plus simple.

Etant donné que vous savez déjà comment définir une texture comme une texture cible de rendu pour une caméra, la seule chose que vous devez apprendre maintenant est comment créer une texture cible de rendu. Pour ce faire vous n'aurez besoin que d'une simple fonction:

Cette fonction crée une texture (cible) de rendu avec les dimensions données et l'associe avec l'indice donné.

CreateTextureRenderTarget(
TextureIndex,
RequestedWidth, RequestedHeight
)

TextureIndex
L'indice qui sera associé à la texture. Cela peut être une valeur entière tout à fait arbitraire dans la plage allant de 0 à 998.

RequestedWidth, RequestedHeight
Les dimensions souhaitées pour la texture de rendu. Comme beaucoup d'autre type de texture, la plupart des periphériques graphiques ne supportent pas les textures de rendu qui ne sont pas faites de puissances de deux. Certains périphériques graphiques très anciens ne supportent que les textures carrées!


Il est aussi possible de calculer le rendu ver les textures cubiques.  De cette façon vous pouvez créer des effets de reflets extrêmement réalistes. Vous calculez le rendu d'une image de l'environnement vers une texture cubique et vous utilisez ensuite l'environment mapping cubique pour appliquer cette image de l'environnement sur un objet. C'est la technique parfaite pour faire des réflections, et ce n'est pas difficile à utiliser. La première étape est la création d'une texture cubique qui peut être utilisée comme cible de rendu. Pour ce faire il vous suffit d'appeler une fonction: 

Cette fonction crée une texture cubique avec les dimensions données qui peut être utilisée comme cible de rendu et l'associe avec l'indice donné.

CreateCubeTextureRenderTarget(
TextureIndex,
RequestedEdgeLength
)

TextureIndex
L'indice qui sera associé à la texture. Cela peut être une valeur entière, arbitraire, entre 0 et 998.

RequestedEdgeLength
La longueur des côtés de la texture cubique que vous souhaitez créer. La texture cubique sera faite de six textures 2D avec une taille de RequestedEdgeLengthRequestedEdgeLength. Vous devriez entrer une puissance de deux pour ce paramètre étant donné que la plupart des périphériques graphiques ne supportent pas d'autres tailles de texture.


Calculer le rendu vers des textures cubiques n'est pas fait au moyen d'un objet caméra. C'est bien plus facile. Etant donné que toutes les directions sont représentées par une texture cubique, il n'est pas nécessaire de donner une direction à la vue ou encore un angle. La seule information qui joue est la position, et éventuellement une couleur avec une valeur alpha. Une fois que le rendu de la scène toute entière a été calculé vers une texture cubique, des carrés de vertex avec cette couleur et cette transparence seront affiché sur la texture finie. Vous devriez toujours entrer une valeur alpha plus petite que 255, sinon le processus de calcul du rendu n'aura aucun sens étant donné que les résultats ne seront pas visibles. Vous devriez d'usage mettre quelque chose comme r=g=b=0 et a=128. Voici la fonction:

Cette fonction calcule le rendu de la scène telle qu'elle est vue depuis la position donnée vers la texture cubique cible de rendu.

RenderToCubeTexture(
CubeTextureIndex,
PositionX, PositionY, PositionZ,
ColorR, ColorG, ColorB, ColorA
RoomIndex1, RoomIndex2, ..., RoomIndex8
)

CubeTextureIndex
L'indice de la texture cubique cible de rendu vers laquelle vous voulez calculer le rendu. Cela doit être l'indice d'une texture cubique de rendu qui a été créée à l'aide de CreateCubeTextureRenderTarget(...), autrement cette fonction échouera.

PositionX, PositionY, PositionZ
La position depuis laquelle la scène doit être rendue. 

ColorR, ColorG, ColorB, ColorA
La couleur des carrés de vertex qui devront être rendu sur la texture cubique après avoir calculé le rendu de la scène. Les valeurs pour ces paramètres doivent être entre 0 et 255. Si vous ne souhaitez pas que ces carrés de vertex soient affichés, définissez seulement 0 pour ColorA. Passer 255 pour ColorA n'a aucun sens, parce que vous ne verriez pas la scène.

RoomIndex1, RoomIndex2, ..., RoomIndex8
Les indices des pièces qui devront être rendues. Pour plus d'informatiions sur les indices des pièces, jetez un oeil aux fonctions de culling avancées. Room 0 sera toujours rendue, quelque soit les valeurs que vous passez pour ce paramètre.


Dessiner des graphiques 2D en textures

J'aurai appeller ce sous-chapitre "Dessiner des textures et des textures sur les textures" si cela n'avait pas été aussi lourd. Mais c'est seulement ce que vous pourrez faire une fois que vous l'aurez lu et compris. Imaginez que vous ayez un panneau de contrôle dans votre jeu sur lequel différents réglages sont affichés. Il vous faut donc afficher des graphismes 2D sur une texture pouvant être utilisée comme texture pour le moniteur. C'est tout juste l'usage auquel est destiné cette fonctionnalité. Vous connaissez déjà les fonctions qui peuvent être utilisées pour dessinner des textures et du texte sur les  textures: DrawTexEx(...) et DrawText(...). Il n'y a qu'un seul paramètre additionnel dont je ne vous ai pas parlé dans la section débutant pour éviter de vous troubler. Voici donc la syntaxe complète de ces deux fonctions.

DrawTexEx(
TextureIndex, Left,Top, Width,Height, X,Y, ScalingX,ScalingY, Rotation, R,G,B,A,
CameraIndex
)

CameraIndex
L'indice de la caméra de la cible de rendu sur laquelle vou souhaitez dessiner la texture.

DrawText(
FontIndex, X, Y, Text,
CameraIndex
)

CameraIndex
Voir ci-dessus.

Notez que la texture ne sera pas affichée sur la texture cible de rendu avant que l'objet de caméra correspondant n'appelle RenderToTexture().



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

Creative Commons License XHTML 1.0 Transitional