Tutoriel OpenSceneGraph 2: Ajouter une texture à une forme géométrique
Par
Thomas Baquet (Cheveche4) (cheveche4.developpez.com)
Ce tutoriel est la traduction du tutoriel de Joseph Sullivan disponible à l'adresse suivante: http://www.openscenegraph.org/projects/osg/wiki/Support/Tutorials/.
Il est possible qu'il y ait encore des erreurs de traduction, si c'est le cas, prévenez-moi. Aucune responsabilité ne peut cependant être engagée contre le traducteur
ou l'auteur suite à ces erreurs, ou à quelconque erreur à la lecture de la traduction.
Il y a eu également eu des mots impossibles à retraduire en les mettant en contexte dans la traduction (je pense à des mots comme « geometry » par exemple qui est employé comme nom simple). Dans ces cas, j'ai soit employé le mot en anglais, soit tourné la
phrase de façon à garder le même sens. En lisant ce document, le lecteur prend pleinement conscience de ce qui vient d'être écrit.
1. But du tutoriel
2. Avant de commencer
3. Charger une texture, créer un état, et assignation à un noeud
1. But du tutoriel
Ajouter une texture à la forme géométrique dessinée par les primitives d'OpenGl que nous avons vu dans le tutoriel précédent.
2. Avant de commencer
Le tutoriel précédent nous a appris à créer des scènes incluant des formes de base créées à partir de primitives d'OpenGl. Cette section va expliquer comment leur ajouter des textures. Pour rendre le code plus facile à utiliser, nous allons mettre le code de la pyramide dans une fonction qui crée une nouvelle instance de Geode et retourne un pointeur dessus. Le code suivant vient donc du tutoriel précédent.
osg::Geode* createPyramid()
{
osg::Geode* pyramidGeode = new osg::Geode();
osg::Geometry* pyramidGeometry = new osg::Geometry();
pyramidGeode->addDrawable(pyramidGeometry);
osg::Vec3Array* pyramidVertices = new osg::Vec3Array;
pyramidVertices->push_back( osg::Vec3(0, 0, 0) );
pyramidVertices->push_back( osg::Vec3(2, 0, 0) );
pyramidVertices->push_back( osg::Vec3(2, 2, 0) );
pyramidVertices->push_back( osg::Vec3( 0,2, 0) );
pyramidVertices->push_back( osg::Vec3( 1, 1,2) );
pyramidGeometry->setVertexArray( pyramidVertices );
osg::DrawElementsUInt* pyramidBase =
new osg::DrawElementsUInt(osg::PrimitiveSet::QUADS, 0);
pyramidBase->push_back(3);
pyramidBase->push_back(2);
pyramidBase->push_back(1);
pyramidBase->push_back(0);
osg::Vec4Array* colors = new osg::Vec4Array;
colors->push_back(osg::Vec4(1.0f, 0.0f, 0.0f, 1.0f) );
colors->push_back(osg::Vec4(0.0f, 1.0f, 0.0f, 1.0f) );
colors->push_back(osg::Vec4(0.0f, 0.0f, 1.0f, 1.0f) );
colors->push_back(osg::Vec4(1.0f, 1.0f, 1.0f, 1.0f) );
osg::TemplateIndexArray
<unsigned int, osg::Array::UIntArrayType,4,4> *colorIndexArray;
colorIndexArray =
new osg::TemplateIndexArray<unsigned int, osg::Array::UIntArrayType,4,4>;
colorIndexArray->push_back(0);
colorIndexArray->push_back(1);
colorIndexArray->push_back(2);
colorIndexArray->push_back(3);
colorIndexArray->push_back(0);
pyramidGeometry->setColorArray(colors);
pyramidGeometry->setColorIndices(colorIndexArray);
pyramidGeometry->setColorBinding(osg::Geometry::BIND_PER_VERTEX);
osg::Vec2Array* texcoords = new osg::Vec2Array(5);
(*texcoords)[0].set(0.00f,0.0f);
(*texcoords)[1].set(0.25f,0.0f);
(*texcoords)[2].set(0.50f,0.0f);
(*texcoords)[3].set(0.75f,0.0f);
(*texcoords)[4].set(0.50f,1.0f);
pyramidGeometry->setTexCoordArray(0,texcoords);
return pyramidGeode;
}
|
3. Charger une texture, créer un état, et assignation à un noeud
La méthode pour rendre des primitives est contrôlée par StateSets. Cette section de code montre comment charger une texture d'un fichier, créer un état StateSet dans lequel cette texture sera activée, et assigner cet état à un noeud de la scène. La première section commence comme dans le tutoriel précédent. On initialise une vue et construit une scène avec une simple pyramide.
int main()
{
osgProducer::Viewer viewer;
osg::Group* root = new osg::Group();
osg::Geode* pyramidGeode = createPyramid();
root->addChild(pyramidGeode);
|
Maintenant, il faut ajouter une texture. Ici nous allons déclarer une instance de texture et lui mettre ses données comme « DYNAMIC ». (Si nous ne le faisons pas, certaines routines d'optimisation d'Osg pourraient les retirer). La classe de texture encapsule les modes de texture d'OpenGl (wrap, filter, etc) comme beaucoup d'autre, comme osg::Image. Le code suivant montre comment lire une instance osg::Image depuis un fichier et l'associer à une texture.
osg::Texture2D* KLN89FaceTexture = new osg::Texture2D;
KLN89FaceTexture->setDataVariance(osg::Object::DYNAMIC);
osg::Image* klnFace = osgDB::readImageFile("KLN89FaceB.tga");
if (!klnFace)
{
std::cout << " couldn't find texture, quiting." << std::endl;
return -1;
}
KLN89FaceTexture->setImage(klnFace);
|
Les textures peuvent être associées avec un renderer StateSets. La prochaine étape est de créer un StateSet, associer et activer notre texture à cet état, assigner et mettre notre StateSet à pyramidGeode.
osg::StateSet* stateOne = new osg::StateSet();
stateOne->setTextureAttributeAndModes
(0,KLN89FaceTexture,osg::StateAttribute::ON);
pyramidGeode->setStateSet(stateOne);
|
La dernière étape est la boucle de simulation:
viewer.setUpViewer(osgProducer::Viewer::STANDARD_SETTINGS);
viewer.setSceneData( root );
viewer.realize();
while( !viewer.done() )
{
viewer.sync();
viewer.update();
viewer.frame();
}
return 0;
}
|
Joyeux Coding!

Le résultat final, compilé avec Code::Block


Ce document est issu de http://www.developpez.com et reste la propriété exclusive de son auteur.
La copie, modification et/ou distribution par quelque moyen que ce soit est soumise à l'obtention préalable de l'authorisation de l'auteur.