#0 

17-03-2008 20:44:58

wetneb
Membre
Date d'inscription: 15-04-2007
Messages: 29
Site web

Bonsoir,

J'essaye en ce moment d'écrire une scene node de terrain, à partir d'une heightmap évidemment.
Je ne parviens pas à le texturer.
Lors du rendu, j'ai mis une lumière ambiente mais le terrain reste noir.
Les paramètres du Material ne semblent pas être pris en compte par le driver video
lors du rendu (le paramètre Wireframe n'influence pas le rendu, par exemple)

Voici son code source, vraiment basique :

Code:

\*
STerrainMeshSceneNode hérite de ISceneNode
*/

void STerrainMeshSceneNode::loadFromHeightMap(video::ITexture *heightMap)
        {
            if(heightMap != NULL)
            {
                if(heightMap->getSize().Height == heightMap->getSize().Width)
                {
                    mSize = heightMap->getSize().Height;

                    scene::SMeshBufferLightMap *meshBuffer = new scene::SMeshBufferLightMap;
                    meshBuffer->Vertices.set_used(mSize*mSize);
                    meshBuffer->Indices.set_used(6*mSize*mSize);
                    meshBuffer->Indices.clear();

                    setMaterialFlag(video::EMF_WIREFRAME, true);
                    setMaterialFlag(video::EMF_LIGHTING, true);
                    setMaterialTexture(0, heightMap);

                    video::S3DVertex2TCoords vertex;
                    vertex.Normal.set( 0.0f, 1.0f, 0.0f );
                    vertex.Color = video::SColor(255, 127, 127, 127);

                    void* data = heightMap->lock();
                    if(heightMap->getColorFormat() != video::ECF_A8R8G8B8)
                        throw Exception("terrainSceneNode::loadFromTexture", "Impossible de charger la heightmap : format de couleur invalide.\n");

                    int vertexCount = 0;
                    for(int x = 0; x < mSize; x++)
                    {
                        for(int z = 0; z < mSize; z++)
                        {
                            vertex.Pos.X = (f32)x*2;
                            video::SColor pixelColor(video::SColor(((u32*)data)[x*mSize+z]));
                            vertex.Pos.Y = (f32)pixelColor.getRed()*0.25;
                            vertex.Pos.Z = (f32)z*2;

                            vertex.TCoords.X = vertex.TCoords2.X = x;
                            vertex.TCoords.Y = vertex.TCoords2.Y = z;

                            meshBuffer->Vertices[x*mSize+z] = vertex;
                            vertexCount++;

                            if(x < mSize && z < mSize)
                            {
                                meshBuffer->Indices.push_back(x*mSize+z);
                                meshBuffer->Indices.push_back(x*mSize+z+1);
                                meshBuffer->Indices.push_back((x+1)*mSize+z+1);

                                meshBuffer->Indices.push_back((x+1)*mSize+z+1);
                                meshBuffer->Indices.push_back((x+1)*mSize+z);
                                meshBuffer->Indices.push_back(x*mSize+z);
                            }
                        }
                    }
                    mMeshBuffer = meshBuffer;

                    heightMap->unlock();
                    cout << "Loaded "<<mMeshBuffer->getIndexCount()<<" indices ("<<mMeshBuffer->getVertexCount()<<"x6 = "<<mMeshBuffer->getVertexCount()*6<<")\n";
                }
                else throw Exception("STerrainMeshSceneNode::loadFromHeightMap", "La texture n'est pas carrée.");
            }
            else throw Exception("STerrainMeshSceneNode::loadFromHeightMap", "Texture invalide.");
        }

        void STerrainMeshSceneNode::saveToTexture(video::IImage *heightMap)
        {

        }

/**
 * La méthode de rendu...
*/

        void STerrainMeshSceneNode::render()
        {
            if(IsVisible)
               SceneManager->getVideoDriver()->drawMeshBuffer(mMeshBuffer);
        }

Merci !

Dernière modification par wetneb (18-03-2008 17:26:18)

Hors ligne


#1 

21-03-2008 19:05:42

wetneb
Membre
Date d'inscription: 15-04-2007
Messages: 29
Site web

Bon, en lisant un peu le code source du CTerrainSceneNode, j'ai pensé qu'il serait bon de faire hériter ma classe de ImeshSceneNode plutôt que de la scene node basique. Je ne le fais pas hériter de ITerrainSceneNode parce quelques trucs ne me conviennent pas. Mais comme je n'ai pas vraiment envie d'implémenter les méthodes de ImeshSceneNode, j'essaye de le faire hériter de CMeshSceneNode.
Mais malheureusement, il n'y a pas de header dans lequel cette classe est définie (en tout cas il n'est pas installé par défaut, mais il est dans les sources). Est-ce que je copie le header dans mon projet (sachant que l'implémentation doit être dans la lib statique ?) ou il y a une manière plus conventionnelle de régler le problème ?

Hors ligne


#2 

21-03-2008 21:32:07

Aranoth
Abonné
Lieu: Toulouse
Date d'inscription: 25-09-2006
Messages: 242
Site web

Mais malheureusement, il n'y a pas de header dans lequel cette classe est définie (en tout cas il n'est pas installé par défaut, mais il est dans les sources). Est-ce que je copie le header dans mon projet (sachant que l'implémentation doit être dans la lib statique ?) ou il y a une manière plus conventionnelle de régler le problème ?


Il me semble avoir le souvenir que chaque custom scene node était joint avec le header tiré des sources, donc à priori je dirais oui.
Mais comme cela fait longtemps que je n'ai pas touché à Irrlicht (j'ai mon propre moteur 3D maintenant), je ne peux pas être catégorique...



PS: Désolé pour n'avoir pas répondu à ton mail (qui date quand même de janvier), mais je suis sacrément occupé en ce moment, j'espère que tu ne m'en voudras pas (trop) ^^

Hors ligne


#3 

22-03-2008 18:39:12

wetneb
Membre
Date d'inscription: 15-04-2007
Messages: 29
Site web

Merci.

J'ai un nouveau problème lors de la mise en place du mesh (que j'ai isolé cette fois-ci big_smile ) :

Code:

scene::SMesh *testMesh = new scene::SMesh;
            scene::SMeshBufferLightMap *testBuffer = new scene::SMeshBufferLightMap;
            testMesh->addMeshBuffer(testBuffer);

Ce code renvoie l'erreur suivante (à l'exécution) :

Code:

 ../../include/irrArray.h:270: T& irr::core::array<T, TAlloc>::operator[](irr::u32) [with T = irr::video::SMaterial, TAlloc = irr::core::irrAllocator<irr::video::SMaterial>]: Assertion `!(index>=used)' failed.
Abandon (core dumped)

Apparemment, l'array contenant les MeshBuffers n'est pas suffisamment grand pour contenir un buffer supplémentaire... Pourtant, il devrait s'agrandir automatiquement, non ?

(pour le mail, à vrai dire, j'avais un peu oublié depuis ^^)

Hors ligne


Options Liens officiels Caractéristiques Statistiques Communauté
Corrections
irrlicht
irrklang
irredit
irrxml
xhtml 1.0
css 2.1
Propulsé par FluxBB
Traduit par FluxBB.fr
883 membres
1429 sujets
11121 messages
Dernier membre inscrit: Saidov17
78 invités en ligne
Aucun membre connecté
RSS Feed