Obligement - L'Amiga au maximum

Dimanche 16 décembre 2018 - 12:02  

Translate

En De Nl Nl
Es Pt It Nl


Rubriques

 · Accueil
 · A Propos
 · Articles
 · Galeries
 · Glossaire
 · Liens
 · Liste jeux Amiga
 · Quizz
 · Téléchargements
 · Trucs et astuces


Articles

 · Actualité (récente)
 · Actualité (archive)
 · Comparatifs
 · Dossiers
 · Entrevues
 · Matériel (tests)
 · Matériel (bidouilles)
 · Points de vue
 · En pratique
 · Programmation
 · Reportages
 · Tests de jeux
 · Tests de logiciels
 · Tests de compilations
 · Articles divers

 · Articles in english
 · Articles en d'autres langues


Twitter

Suivez-nous sur Twitter




Liens

 · Sites de téléchargements
 · Associations
 · Pages Personnelles
 · Matériel
 · Réparateurs
 · Revendeurs
 · Presse et médias
 · Programmation
 · Logiciels
 · Jeux
 · Scène démo
 · Divers


Jeux Amiga

0, A, B, C, D, E, F,
G, H, I, J, K, L, M,
N, O, P, Q, R, S, T,
U, V, W, X, Y, Z


Trucs et astuces

0, A, B, C, D, E, F,
G, H, I, J, K, L, M,
N, O, P, Q, R, S, T,
U, V, W, X, Y, Z


Glossaire

0, A, B, C, D, E, F,
G, H, I, J, K, L, M,
N, O, P, Q, R, S, T,
U, V, W, X, Y, Z


Partenaires

Annuaire Amiga

Amedia Computer

Relec

Hit Parade


Contact

David Brunet

Courriel

 


Programmation : C - Graphismes 3D en C (les projections perspectives)
(Article écrit par Pascal Amiable et extrait d'Amiga News Tech - juillet 1990)


Bonjour à toutes et à tous ! Ce mois-ci, nous allons terminer l'étude des différentes projections planes par les projections perspectives. Et puis, comme il me restait un peu de temps, j'ai modifié le petit programme d'affichage d'objet 3D du numéro 23 pour permettre le calcul de la perspective et l'animation temps réel de cet objet (vous verrez cela se réalise très simplement).

Projections perspectives

Alors que les projections parallèles suivent les règles de la géométrie affine classique, les projections perspectives suivent leur propre géométrie. Dans une perspective, deux lignes parallèles quelconques ne sont plus parallèles. La longueur d'un segment est réduite par un facteur proportionnel à sa distance par rapport à l'observateur. Ceci implique deux choses :
  • Aucune information dimensionnelle ne peut être extraite d'une projection perspective.
  • Cette compression des distances produit un excellent effet de profondeur, très utile pour le rendu réaliste de scènes, car elle correspond à notre vision naturelle de l'espace.
En utilisant les coordonnées homogènes, la perspective peut être assimilée à une transformation classique de l'espace 3D vers l'espace 3D. Dès lors, il ne reste plus qu'à réaliser une projection orthographique et la projection perspective est réalisée (simple, non ?).

Lorsque la direction de vision est confondue avec un des axes principaux du repère objet, cette projection perspective est des plus simple. La figure 1 vous montre, de manière intuitive, le principe de modélisation de la perspective.

C

On peut s'imaginer que le plan de projection, c'est-à-dire l'écran de votre Amiga, est une vitre placée entre l'observateur et les objets. La projection perspective est alors simplement l'image des objets perçus par l'observateur à travers la vitre.

Comme on désire toujours obtenir les coordonnées de projections dans le plan de projection (écran), il est nécessaire de décrire l'ensemble des données utiles à une perspective, par rapport au plan de projection. Une perspective simple est définie par trois éléments :
  • Un centre de projection [0, 0, L, 1].
  • Une direction de vision [0, 0, -1, 0].
  • Un plan de projection Z=0.
Un point P [x y z w] se transforme en perspective en P' [x' y' z'w'] à l'aide de la matrice suivante :

C

A partir de cette matrice de transformation perspective, on obtient la matrice de projection perspective en multipliant cette matrice par une matrice de projection orthographique suivant z :

C

A partir de cette matrice de projection perspective, on peut calculer les coordonnées du point projeté :

C

Soit :
  • x'=x
  • y'=y
  • z'=0
  • w'=-a*z+w avec toujours a=-1/L.
On revient en coordonnées unitaires non homogène 2D pour affichage à l'écran. C'est-à-dire :
  • x"=x'/w'
  • y"=y'/w'
  • Soit : x"=x*(1/(-z/L+1))
  • y"=y"(1/(-z/L+1))
Ces équations correspondent à une perspective avec seul point de fuite.

Pour une direction de vision quelconque, c'est-à-dire d'une perspective générale on passe simplement le cas général au cas particulier ci-dessus en utilisant un changement de repère.

La matrice de transformation M Persp (phi,teta) est égale à la multiplication de la matrice M Persp(z) ci-dessus par une matrice de changement de repère M-1.

M-1 est composée de quatre matrices :
  • T-1 : translation à l'observateur.
  • R-1(z) : rotation d'axe z.
  • R-1(y) : rotation d'axe y.
  • E-1 : échange de coordonnées.
M-1 se calcule de la manière suivante :

M-1=E-1,R-1(y),R-1(z),T-1

C

La matrice de transformation générale se calcule donc assez simplement.

Mtranspersp(phi,teta)=Mtranspersp.M-1

On peut alors déterminer la matrice de projection perspective de la même manière en remplaçant Mtranspersp par la matrice Mprojpersp.

Mprojpersp(phi,teta)=Mprojpersp.M-1

C

Ce qui donne en calculant P'=P.Mprojpersp(phi,teta) :
  • x'=-x.sin(phi)+y.cos(phi)-Tx.w
  • y=-x.sin(teta).cos(phi)-y.sin(teta).cos(phi)
  • z'=0
  • w'=-(x.cos(teta).cos(phi))/L-(y.cos(teta).sin(phi))/L-(z.sin(teta))/L+((Tz+L).w)/L
On ramène l'ensemble en coordonnées unitaires 2D non homogènes à l'aide des formules x"=x'/w' et y"=y'/w' avec pour hypothèse w=1.

A partir des données de base :

Centre de projection `obsv' et Point vise 'vise' nous avons la direction de vision :

Direction=[xobsv-xvise,yobsv-yvise,zobsv-zvise,1]

...et sa norme vaut :

|Direction|=sqrt((xobsv-xvise)^2+(yobsv-yvise)^2+(zobsv-zvise)^2)

La projection sur le plan z=0 donne :

Dirproj=[xobsv-xvise,yobsv-yvise,0,1]

Ce vecteur peut être normalisé :

|Dirproj|=sqrt((xobsv-xvise)^2+(yobsv-yvise)^2)

Dès lors, nous avons directement les deux cosinus et sinus de la projection :

cos(phi)=(xobsv-xvise)/|Dirproj| sin(phi)=(yobsv-yvise)/|Dirproj| cos(teta)=|Dirproj|/|Direction| sin(teta)=(zobsv-zvise)/|Direction|

Cette astuce évite le calcul des cosinus et sinus très gourmands en temps de calcul.

Affichage objet 3D

Bien, sur ces fortes paroles je vais arrêter la théorie et passer à la pratique en vous proposant une version remaniée du petit programme d'affichage d'objet en 3D du numéro 23. En prime et sans supplément, j'ai modifié le programme pour qu'il y est une petite animation de l'objet. Bien sûr, cette animation n'est pas parfaite mais ne désespérez pas, nous étudierons l'animation un peu plus tard.

C
C
C
C

Annexe : bibliothèque de fonction

En examinant l'important courrier suscité par les articles sur le 3D en C et d'autres publications de mes confrères, les questions qui reviennent le plus souvent concernent l'utilité de passer par les bibliothèques de fonctions (library) disponibles dans l'environnement Amiga pour accéder aux routines systèmes. Je vais donc faire le point sur ce sujet.

Une bibliothèque de fonction est un ensemble de routines, que votre application peut utiliser et qui vous déchargent d'un certain travail, en général la programmation de fonctions de bas niveau (par exemple la gestion des ressources). Ces bibliothèques résident soit en ROM (exemple : graphics.library, intuition.library), soit sur disque (mathtrans.library, iconlibrary). A ce sujet, rien ne vous empêche de créer les vôtres.

Étudions maintenant l'accès à ces routines et plus particulièrement, celles intégrées en ROM. Les différentes routines système sont positionnées de manière séquentielle dans la ROM. On peut donc accéder directement à une fonction, quelle qu'elle soit, pour peu que l'on connaisse l'adresse de début de la routine (instruction "JSR" en assembleur ou par un pointeur de fonction en C). Mais cette méthode, utilisée (malheureusement) par certains programmeurs peu scrupuleux, est très dangereuse. En effet, l'adresse physique de cette routine peut évoluer d'une révision de système à l'autre (même si les concepteurs de l'Amiga font tout pour éviter cela, c'est parfois obligatoire) et votre programme qui fonctionnait très bien va aller rendre visite au Guru parce qu'il pointe désormais n'importe où dans la ROM et non plus sur la routine prévue.

Pour éviter cela, on va utiliser un adressage indirect et c'est là que la notion de bibliothèque va servir. Chaque série de routines est organisée en bibliothèque suivant un thème précis (exemple : graphics.library contient les routines graphiques). La bibliothèque principale est l'exec.library. En tête de cette bibliothèque, positionnée à une adresse absolue immuable, on trouve une table de pointeur. Il s'agit de pointeurs sur les fonctions d'Exec et sur les autres bibliothèques de la ROM. L'accès aux fonctions d'Exec se fait via cette table.

Par contre, l'accès aux fonctions des autres bibliothèques nécessite une étape supplémentaire, le chargement de la table de pointeurs lié à cette bibliothèque. Pour ce faire on utilise la fonction OpenLibrary() en lui passant comme paramètres le nom de la bibliothèque et son numéro de version. Une fois cette table chargée on accède aux fonctions, comme pour Exec. Dès lors, il n'y a plus de problème de compatibilité car à chaque révision de système la table des pointeurs est aussi remise à jour.

Une fois votre application terminée, il ne faut pas oublier de refermer les bibliothèques ouvertes à l'aide de CloseLibrary() avec comme paramètre l'adresse de la table des pointeurs de la bibliothèque.

Dans les différents programmes de la série le "3D C facile" des exemples d'ouverture et de fermeture des bibliothèques sont fournis. J'espère que cela répond à vos questions.


[Retour en haut] / [Retour aux articles] [Article précédent] / [Article suivant]