Tutorial 1
Comme la plupart des codeurs, j'aime bien entré dans le tas et voir dessuite ce qu'on peut obtenir d'une nouvelle API. C'est ce que nous allons voir avec ces tutoriaux basés (copiés???) sur les tutoriaux vendus dans le package RenderWare Graphics®.
Nous allons donc voir dans ce premier tutorial comment charger un cube et comment tourner autour.
Compilation du projet tutorial 1
Lecture d'un objet
Affichage du cube
Destruction du cube
La première chose à faire est de compiler le projet tutorial 1. Ici 9 configurations s'offrent à nous : 3 pour directX 8, 3 pour DirectX 9 et 3 pour OpenGL. Les 3 configurations sont Debug, Metric et Release. Nous allons compiler en OpenGL Debug.
![]() |
![]() |
Une fenêtre RenderWare est créée. De plus il est possible d'afficher le nombre d'image par seconde avec une pression sur 'F'. Nous allons voir comment tout cela marche au fur et à mesure de ces tutoriaux.
En fait c'est dans main.c que sont gérés les événements et ce n'est pas RenderWare Graphics qui les gère. Dnas main.c se trouvent aussi les fonctions de création du monde, de la caméra, d'initialisation mais aussi de terminaison. Mais on verra cela plus tard.
Nous allons voir comment lire un objet dff (un cube en l'occurence)(dff= RenderWare Dive File Format) et comment l'afficher. Pour cela, on va créer 2 nouveaux fichiers et on va modifier le contrôleur d'événement du clavier.
#include
<rwcore.h> #include
"skeleton.h" RpClump
* /*
Open stream */ /*
close the stream */ return
(clump); |
Voici le code d'utils.c. Et maintenant le code d'utils.h :
|
#ifndef
UTILS /*
Function prototypes */ extern RpClump *DffLoad(RwChar *filename); #ifdef
__cplusplus #endif /* UTILS */ |
En ajoutant, les fichiers au projet et en compilant, il ne devrait pas y avoir d'erreur.
Maintenant, regardons la fonction AttachInputDevices(void) qui se trouve dans events.c.
| /*
AttachInputDevices function */ RwBool AttachInputDevices(void) { RsInputDeviceAttach(rsKEYBOARD, KeyboardHandler); RsInputDeviceAttach(rsMOUSE, MouseHandler); return TRUE; |
On remarque pour chaque device que sont le clavier et le souris, il y a un gestionnaire d'événements. Nous allons regarder le gestionnaire du clavier car c'est lui qui va nous permettre de lire le cube.
| static
RsEventStatus KeyboardHandler(RsEvent event, void *param) { /* Let the menu system have a look-in first... */ if( MenuKeyboardHandler(event, param) == rsEVENTPROCESSED ) { return rsEVENTPROCESSED; } /* ...then the application events, if necessary... */ switch( event ) { case rsKEYDOWN: { return HandleKeyDown((RsKeyStatus *)param); } case rsKEYUP: { return HandleKeyUp((RsKeyStatus *)param); } default: { return rsEVENTNOTPROCESSED; } } } /* End of KeyboardHandler function */ |
2 nouveaux gestionnaires sont apparus : un s'occupe de l'appui des touches, l'autre du relachement. Celui qui nous intéresse, c'est le gestionnaire de l'appui.
| static RsEventStatus HandleKeyDown(RsKeyStatus *keyStatus) { switch( keyStatus->keyCharCode ) { case rsUP: { /* CURSOR-UP... */ return rsEVENTPROCESSED; } case rsDOWN: |
Ce n'est que le début de la fonction. Mais ici, on peut voir que rien n'est fait. Nous allons donc ajouter une action lors de l'ppui sur la touche F1.
| //ajout
pour l'appui sur F1 case rsF1: { RpClump * clump= DffLoad("models/cube.dff"); if(clump) { RpWorldAddClump(World,clump); } return rsEVENTPROCESSED; } |
Lors de l'appui sur F1, on crée un clump en lisant le fichier cube.dff. Si le clump est créé alors on l'ajoute au monde. Pour que le monde soit accessible, il faut l'ajouter dans utils.h.
| //pour qu'on puisse
avoir connaissance du monde extern RpWorld *World; |
Compilation, exécution, appui sur F1:

Super!!! Le même écran que tout à l'heure. En fait, l'objet et la caméra sont placés à l'origine tout les deux. De plus, on ne rend pas l'objet... Ca marche beaucoup moins bien du coup!!
Pour afficher le cube, il va falloir le mettre devant la caméra. On faire ça dans le gestionnaire du clavier:
| case rsF1: { RpClump * clump= DffLoad("models/cube.dff"); if(clump) { //vecteur 3D RwV3d v = {0.0f, 0.0f, 5.0f}; // on se déplace de 5 selon Z RwFrameTranslate(RpClumpGetFrame(clump), &v, rwCOMBINEREPLACE); //translation effective RpWorldAddClump(World,clump); } return rsEVENTPROCESSED; } |
Voici donc comment éloigné notre cube de 5 unités sur l'axe des Z de la caméra. Le flag rwCOMBINEREPLACE permet d'écraser la matrice de transformation courante du cube. Nous allons maintenant rendre le cube. Pour cela, il faut se rendre (...) dans la fonction Render() de main.c. Une fois ceci fait, voici la nouvelle fonction Render():
| static
void Render(void) { RwCameraClear(Camera, &BackgroundColor, rwCAMERACLEARZ|rwCAMERACLEARIMAGE); if( RwCameraBeginUpdate(Camera)
) //rendu
effective de la scène DisplayOnScreenInfo(Camera); |
On recompile, on exécute, on appui sur F1:

Victoire notre premier objet est affiché dans un fenêtre RenderWare!!
On a lu un objet on l'a affiché. Mais maintenant il faut le détuire!!
Comme indiqué plus haut, la fonction d'initialisation et de destruction se trouvent dans main.c.
| /** Destruction d'un clump */ static RpClump * _destroyClumpCB(RpClump *c, void *d) { RpWorldRemoveClump(World, c); RpClumpDestroy(c); return c; } |
Voici la fonction qui détruit 1 clump. Il faut rajouter ceci dans Terminate3D:
| static void Terminate3D(void) { //Destruction de tous les clump du World #ifdef RWMETRICS |
Dans cette première partie du premier tutorial, nous avons vu comment lire un objet .dff et comment l'afficher à l'écran. Nous allons voir comment ajouter de la lumière