RaptorGL est un moteur 3D spécialement mis au point pour la section tutoriaux du site
oZone3D.Net (et oui on ne
se refuse rien!). Le but de ce moteur est de donner une idée de comment les choses fonctionnent
sous le capot d'Hyperion. Ce
moteur est en quelque sorte une réponse aux feedbacks des tutoriaux reçus de la communauté et demandant
comment les choses sont implémentées dans les coulisses
d'Hyperion.
RaptorGL est un moteur 3D expérimental dans le sens ou il fournit une plateforme de test
facile d'accès pour mettre au point et tester les nouveaux algorithmes de la 3D temps réel. La
mise à jour de RaptorGL se fera en fonction des besoins des nouveaux tutoriaux. Pour le moment
peu de fonctionnalités sont disponibles mais il offre malgrès tout une interface relativement
complète pour attaquer les shaders GLSL (deux codepaths sont disponibles pour le GLSL: le codepath ARB et le codepath GL2).
Le grand intérêt de RaptorGL réside en la totale disponibilité des codes sources. Rien ne vaut une
bonne immersion dans le code pour comprendre le fonctionnement d'un moteur.
RaptorGL peut être aussi le point de départ pour mettre au point votre propre moteur 3D.
En effet, les briques fondamentales sont fonctionnelles et l'adaptation à vos besoins spécifiques
peut se faire facilement.
Actuellement les fonctionnalités principales de RaptorGL sont les suivantes:
- Renderer polymorphique - Implementation OpenGL 2.0 en cours - Shaders GLSL - VBO
- Memory Manager - allocation et tracking des fuites memoires
- Log Manager - écriture des log et autre infos de debug
- Object Factory - création centralisée de toutes les entités des scènes 3D
- Lumières dynamiques
- Matériaux (mais pas encore de texture - mais ça arrivera très vite!)
- Mesh - (formes integrées: torus, box et plan) - Pas encore de chargement de modèles extérieurs.
L'objectif n'est absolument pas d'en faire un moteur 3D complet car une telle tâche demanderait
plusieurs mois voire années. Les fonctionnalités manquantes seront rajoutées au fur et à mesure
des nouveaux tutoriaux. Les fonctionnalités actuelles sont suffisantes pour les premiers tutoriaux
dont fait parti celui-ci: Mesh Deformer.
RaptorGL est livré sous la forme d'un librairie statique à linker avec votre projet.
Je ne vais pas entrer dans le détail de la configuration du compilateur, les forums sont là pour ça.
Les projets d'exemples sont prévus pour Visual C++ 6.0. La conversion vers VC2005 ne devrait pas poser de
problème (si ce n'est les milliard de warnings générés par les nouveaux standards de sécurité sauce
Microsoft...).
L'utilisation du moteur est relativement simple et logique. Une démo 3D peut être décomposée
de la manière suivante:
- 1 - initialisation
- 2 - boucle de rendu (endless loop tant que pas fin)
- 2.1 - update de la scène
- 2.2 - rendu de la scène
- 3 - liberation des ressources et fin
La première étape de l'initialisation de la scène est l'init du moteur lui-même. C'est fait par
le code suivant:
RaptorGL::getInstance()->initialize();
L'étape suivante consiste à créer un renderWindow. Le renderWindow permet de donner un
accès au framebuffer de la fenêtre 3D. Cette opération n'est pas nécessaire si vous disposez déja
de votre propre renderWindow, ce qui est le cas avec certaines librairies comme la GLUT. Le code
suivante montre la création d'un renderWindow:
pRw = RaptorGL::getInstance()->createRenderWindow( RGL_RENDERER_OPENGL );
memset( &RWCtx, 0, sizeof(RglRenderWindowContext) );
RWCtx.m_width = w;
RWCtx.m_height = h;
RWCtx.m_wndHwnd = hWnd;
pRw->create( &RWCtx );
RaptorGL::getInstance()->setCurrentRenderWindow( pRw );
L'étape suivante est la création du renderer OpenGL. RaptorGL étant un core de
rendu polymorphe, plusieurs types de renderer peuvent être disponibles (OpenGL, Direct3D, software).
Actuellement, seul un renderer de type OpenGL est disponible. Mais j'espère attaquer très bientôt le
renderer Direct3D (dx9 pour commencer!). Le code suivant montre la création du renderer:
RaptorGL::getInstance()->createRenderer( RGL_RENDERER_OPENGL );
Maintenant que les fonctions principales sont initialisées, on peut attaquer la création de
la scène et de sa population. Une scène se crée de la manière suivante:
scene = RglSceneMgr::getInstance()->createScene( "Main_Scene" );
Après avoir créer la scène, la première chose à faire est d'y placer une caméra. Le code
suivant montre la création d'une caméra perspective avec un FOV de 60.0 degrés:
cam = (RglCamera *)RglSceneNodeMgr::getInstance()->createNode(RGL_SCENE_NODE_CAMERA,
"Main_Camera"));
scene->insertNode( cam );
cam->setProjPerspParams( 60.0, aspect, 1.0, 1000.0 );
cam->setViewParams( &RglVec4(0.0, 30.0, 50.0),
&RglVec4(0.0, 0.0, 0.0),
&RglVec4(0.0, 1.0, 0.0) );
Ajoutons maintenant un peite lumière afin d'éclairer les objets de la scène et réglons ses paramètres
de position et de couleur:
light = (RglLight *)RglSceneNodeMgr::getInstance()->createNode(RGL_SCENE_NODE_LIGHT,
"Light01"));
scene->insertNode( light );
light->setAmbient( &RglVec4(0.0, 0.0, 0.0) );
light->setDiffuse( &RglVec4(1.0, 1.0, 1.0) );
light->setSpecular( &RglVec4(0.0, 0.0, 0.0) );
light->setPosition( &RglVec4(0.0, 50.0, 100.0) );
La dernière étape de l'initialisation consiste à ajouter un "vrai" objet, c'est un dire un mesh.
Nous allons ajouter, histoire d'être originaux, un tore:
torus = (RglMesh *)(RglSceneNodeMgr::getInstance()->createNode(RGL_SCENE_NODE_MESH,
"MeshTorus"));
scene->insertNode( torus );
torus->buildTorus( 20.0, 5.0, 100 );
torus->getShader()->clearMaterialList();
u32 nfaces = torus->getMeshData()->m_numFaces;
torus->assignMaterialToFaces( "torus_mat_yellow", 0, nfaces-1 );
Tous les objets visibles de la scène possèdent le même matériau par défaut. Il faut
donc le supprimer et attacher au torus un nouveau matériau (torus_mat_yellow).
Le réglage des paramètres d'un matériau se fait comme suit:
mat = RglMaterialMgr::getInstance()->getMaterial( "torus_mat_yellow" );
if(mat)
{
mat->setAmbient( &RglVec4(0.4f, 0.4f, 0.4f) );
mat->setDiffuse( &RglVec4(0.9f, 0.9f, 0.2f) );
mat->setSpecular( &RglVec4(0.0f, 0.0f, 0.0f) );
}
Tous les matériaux sont centralisés dans un gestionnaire de matériaux ce qui en simplifie la gestion.
Maintenant que l'initialisation de la scène est faite, passons à la boucle sans fin. Son implémentation
peut être la suivante:
while( !done )
{
processWindowMessages();
scene->update( dt );
scene->renderBegin();
scene->render( dt );
scene->renderEnd();
RaptorGL::getInstance()->displayCurrentRenderWindow();
}
Le resultat final doit ressembler à: