#0 

27-06-2012 14:04:47

3wic
Membre
Date d'inscription: 27-06-2012
Messages: 10
Corrections: 1

Bonjour a tous.


Je vien vers vous apres un bon paquet de recherche sur le net je me tourne vers vous.

Je suis entrain de develloper un client graphique pour un projet de fin d'annee. Je dois generer un terrain (jusqu'ici aucun probleme), y appliquer une texure qui inclus des cases (et c'est ici que ca se complique).

En effet le soucis et que quel que soit le scale que j'applique a ma texture (500x500), j'aurais toujours la texture coupe sur l'extremite Sud et Est du terrain (voir ci-dessous) :



Voici le code generant la map :

void            Map::constructMap(float lenght, float width, irr::video::IVideoDriver *driver, irr::scene::ISceneManager *sceneManager)
{

  Terrain_ = sceneManager->addTerrainSceneNode("./ressources/HeightMap.bmp", 0, -1, irr::core::vector3df(0.f, 0.f, 0.f), irr::core::vector3df(0.f, 0.f, 0.f), irr::core::vector3df(lenght, 4.4f, width), irr::video::SColor ( 255, 255, 255, 255 ), 5, irr::scene::ETPS_17, 3);
  Terrain_->setMaterialFlag(irr::video::EMF_LIGHTING, true);
  Terrain_->setMaterialFlag(irr::video::EMF_ANISOTROPIC_FILTER , true);
  Terrain_->setMaterialTexture(0, driver->getTexture("./ressources/terrdirtgrass.jpg"));
  if (lenght >= 500)
    Terrain_->scaleTexture(500, 500);
  else
    Terrain_->scaleTexture(lenght, lenght);
  mapSizeX_ = lenght;
  mapSizeZ_ = width;
}


Si quelqu'un aurait une piste ca serait d'une grande aide !

merci

Hors ligne


#1 

27-06-2012 16:53:26

Akabane87
Membre
Date d'inscription: 28-05-2012
Messages: 24

Mmmh je sais pas trop comment irrlicht gère en interne ses textures mais en principe une texture doit avoir une largeur et une hauteur en puissance de 2. En général quand ce n'est pas le cas, une texture plus grande au multiple de 2 près le plus proche est créée avec des data bidon sur les partie manquantes. Je comprend pas trop pourquoi ou comment irrlicht se démerde avec ta texture de 500 mais il me semble qu'elle a été stretchée sur 512 avant d'être clampée à 500 sur ton skinning...

Essaie de recommencer la même chose avec une texture de 512 par 512 pour être sûr de ce que j'avance ou sinon attend que quelqu'un qui connait bien le moteur réponde.

Dernière modification par Akabane87 (28-06-2012 19:03:38)

Hors ligne


#2 

27-06-2012 17:40:12

3wic
Membre
Date d'inscription: 27-06-2012
Messages: 10
Corrections: 1

En cherchant un peu apres mon poste je me rend compte que le probleme ne vien pas de mes textures mais du ITerrainSceneNode que je cree.

En effet lorsque je demande a mon programme de generer une map de 50x50 et que je deplace mon personnage en coordonnee 50,50 je me rend compte que le personnage est en dehors de la map.

J'en deduis donc que quelque chose cloche avec cette ligne lorsque je cree mon terrain :

Terrain_ = sceneManager->addTerrainSceneNode("./ressources/HeightMap.bmp", 0, -1, irr::core::vector3df(0.f, 0.f, 0.f), irr::core::vector3df(0.f, 0.f, 0.f), irr::core::vector3df(lenght, lenght, width), irr::video::SColor ( 255, 255, 255, 255 ), 5, irr::scene::ETPS_17, 3);


edit : J'ai deja tester avec different format de texture (512x512, 256x256, etc..) mais merci wink

Dernière modification par 3wic (27-06-2012 17:41:08)

Hors ligne


#3 

27-06-2012 17:42:23

johnplayer
Habitué
Date d'inscription: 30-09-2007
Messages: 431

Tu fais de la répétition de texture avec makePlanarTextureMapping (IMesh *mesh, f32 resolution=0.001f) et en jouant avec la résolution.

Code:

void            Map::constructMap(float lenght, float width, irr::video::IVideoDriver *driver, irr::scene::ISceneManager *sceneManager)
{

  Terrain_ = sceneManager->addTerrainSceneNode("./ressources/HeightMap.bmp", 0, -1, irr::core::vector3df(0.f, 0.f, 0.f), irr::core::vector3df(0.f, 0.f, 0.f), irr::core::vector3df(lenght, 4.4f, width), irr::video::SColor ( 255, 255, 255, 255 ), 5, irr::scene::ETPS_17, 3);
  Terrain_->setMaterialFlag(irr::video::EMF_LIGHTING, true);
  Terrain_->setMaterialFlag(irr::video::EMF_ANISOTROPIC_FILTER , true);
  Terrain_->setMaterialTexture(0, driver->getTexture("./ressources/terrdirtgrass.jpg"));

  /// créé un mapping plat, il faut jouer avec "résolution_à_réglée" pour donner le nombre de répétition voulue
  sceneManager->getMeshManipulator()->makePlanarTextureMapping(Terrain_->getMesh(), résolution_à_réglée);

  if (lenght >= 500)
    Terrain_->scaleTexture(500, 500);
  else
    Terrain_->scaleTexture(lenght, lenght);
  mapSizeX_ = lenght;
  mapSizeZ_ = width;
}

core i7 4970K @ 4GHz - 32GB ddr3 19200(2400MHz) - ssd samsung 840 evo 250GB - GTX1080Ti (4K) - Cooler master storm stryker blanc.
"L'alcool, c'est comme Activia, c'est actif à l'intérieur et ça se voit à l'extérieur."

Hors ligne


#4 

27-06-2012 18:35:31

3wic
Membre
Date d'inscription: 27-06-2012
Messages: 10
Corrections: 1

Ca n'a pas l'air de fonctionner =/ ... Comme dit je pense que le probleme ne vien pas des textures mais de la generation du ITerrain ...

Hors ligne


#5 

27-06-2012 19:40:18

johnplayer
Habitué
Date d'inscription: 30-09-2007
Messages: 431

Quelles valeurs as-tu utilisé pour makeplanar? Peux-tu montrer ta texture?

Edit : J'avais pas vu mais tu utilises scale texture! Utilise-la avec scale = 1.0f puis scale = 2.0f et compare le nombre de fois que ta texture est répétée. Et scale2 mets-la à 0.

virtual void scaleTexture (f32 scale=1.0f, f32 scale2=0.0f)=0
Scales the base texture, similar to makePlanarTextureMapping.
scale   : The scaling amount. Values above 1.0 increase the number of time the texture is drawn on the terrain. Values below 0 will decrease the number of times the texture is drawn on the terrain. Using negative values will flip
             the texture, as well as still scaling it.
scale2 : If set to 0 (default value), this will set the second texture coordinate set to the same values as in the first set. If this is another value than zero, it will scale the second texture coordinate set by this value.

Dernière modification par johnplayer (27-06-2012 19:54:04)


core i7 4970K @ 4GHz - 32GB ddr3 19200(2400MHz) - ssd samsung 840 evo 250GB - GTX1080Ti (4K) - Cooler master storm stryker blanc.
"L'alcool, c'est comme Activia, c'est actif à l'intérieur et ça se voit à l'extérieur."

Hors ligne


#6 

27-06-2012 21:30:29

3wic
Membre
Date d'inscription: 27-06-2012
Messages: 10
Corrections: 1

Ok voici les resultats suivant les valeurs passe en scale :

1.0f :



2.0f :



Formule trouve se rapprochant le plus du resultat voulu (on veut une map de 10x10 on a du 9.5x9.5) avec le code en dessous :\



void            Map::constructMap(float lenght, float width, irr::video::IVideoDriver *driver, irr::scene::ISceneManager *sceneManager)
{
  Terrain_ = sceneManager->addTerrainSceneNode("./ressources/HeightMap.bmp", 0, -1, irr::core::vector3df(0.f, 0.f, 0.f), irr::core::vector3df(0.f, 0.f, 0.f), irr::core::vector3df(lenght / 64 * 50, 0.0f, width / 64 * 50), irr::video::SColor ( 255, 255, 255, 255 ), 5, irr::scene::ETPS_17, 3);
  Terrain_->setMaterialFlag(irr::video::EMF_LIGHTING, true);
  Terrain_->setMaterialFlag(irr::video::EMF_ANISOTROPIC_FILTER , true);
  Terrain_->setMaterialTexture(0, driver->getTexture("./ressources/terrdirtgrass.jpg"));

  Terrain_->setPosition(irr::core::vector3df((lenght / 2) * 32 , 0, (width / 2) * 32));
  Terrain_->scaleTexture((lenght * 64) / 50, (width * 64) / 50);

  mapSizeX_ = lenght;
  mapSizeZ_ = width;
}


On remarque que avec un scale de 1.0f la texture ne s'affiche pas au complet ... Donc ca engendre des soucis quelque soit le scale choisis ...

Voici la texture au complet :




Merci du temps que vous consacrez a mon probleme smile

Hors ligne


#7 

28-06-2012 10:27:38

johnplayer
Habitué
Date d'inscription: 30-09-2007
Messages: 431

Premièrement une texture doit TOUJOURS avoir une dimension en puissance de 2. Donc dans ton cas, 512x512, En tatonnant j'ai trouvé un coef qui palie au problème :

Code:

ITerrainSceneNode *Terrain_ = smgr->addTerrainSceneNode("../MEDIAS/terrain-heightmap.bmp", 0, -1, vector3df(0.f, 0.f, 0.f), vector3df(0.f, 0.f, 0.f), vector3df(10.f, 0.0f, 10.f), SColor ( 255, 255, 255, 255 ), 5, ETPS_17, 3);
Terrain_->setMaterialFlag(EMF_LIGHTING, false);
//Terrain_->setMaterialFlag(EMF_ANISOTROPIC_FILTER , true);
Terrain_->setMaterialTexture(0, driver->getTexture("../MEDIAS/herbe.jpg"));

Terrain_->setPosition(vector3df(0 , 0, 0));
Terrain_->scaleTexture(1.063f*5, 0.0f);

1.063f est le coef que multiplie par le nombre de fois que tu veux répéter la texture.


core i7 4970K @ 4GHz - 32GB ddr3 19200(2400MHz) - ssd samsung 840 evo 250GB - GTX1080Ti (4K) - Cooler master storm stryker blanc.
"L'alcool, c'est comme Activia, c'est actif à l'intérieur et ça se voit à l'extérieur."

Hors ligne


#8 

28-06-2012 19:14:25

Akabane87
Membre
Date d'inscription: 28-05-2012
Messages: 24

C'est quand même étrange la manière dont irrlicht gère les textures de taille non puissance de 2... A mon avis c'est un bug parce que au pire ça aurait du donner une texture fucked si c'était pas du tout pris en charge, ou alors ça aurait du scaler automatiquement la texture de manière à "cacher" les données manquantes de la texture. Là ce qu'il fait avec un scale de 1 m'échappe totalement vu que la puissance de 2 inférieure pour 500 est 256 et la supérieure est 512 ; ce qui ne correspond à aucun de ces 2 cas sur le screenshot de scale 1.

Donc pour moi il y a un bug à ce niveau dans irrlicht (scale inversé ?).

Hors ligne


#9 

28-06-2012 20:16:29

johnplayer
Habitué
Date d'inscription: 30-09-2007
Messages: 431

Non le problème ne vient pas de la texture, j'ai essayé avec une texture en 512x512 mais ça fait pareil. Le problème réside certainement dans une approximation des coordonnées de texture données aux vertices du Terrain. Mais bon avec le coef ça devrait être résolu, il n'y a plus qu'à attendre les retours.

Dernière modification par johnplayer (28-06-2012 20:16:54)


core i7 4970K @ 4GHz - 32GB ddr3 19200(2400MHz) - ssd samsung 840 evo 250GB - GTX1080Ti (4K) - Cooler master storm stryker blanc.
"L'alcool, c'est comme Activia, c'est actif à l'intérieur et ça se voit à l'extérieur."

Hors ligne


#10 

29-06-2012 11:38:10

3wic
Membre
Date d'inscription: 27-06-2012
Messages: 10
Corrections: 1

J'ai donc test avec ton coef et une repetition de 10 (voir code ci dessous) :

void            Map::constructMap(float lenght, float width, irr::video::IVideoDriver *driver, irr::scene::ISceneManager *sceneManager)
{
  Terrain_ = sceneManager->addTerrainSceneNode("./ressources/HeightMap.bmp", 0, -1, irr::core::vector3df(0.f, 0.f, 0.f), irr::core::vector3df(0.f, 0.f, 0.f), irr::core::vector3df(lenght / 64 * 50, 0.0f, width / 64 * 50), irr::video::SColor ( 255, 255, 255, 255 ), 5, irr::scene::ETPS_17, 3);
  Terrain_->setMaterialFlag(irr::video::EMF_LIGHTING, true);
  Terrain_->setMaterialFlag(irr::video::EMF_ANISOTROPIC_FILTER , true);
  Terrain_->setMaterialTexture(0, driver->getTexture("./ressources/terrdirtgrass.jpg"));
  sceneManager->getMeshManipulator()->makePlanarTextureMapping(Terrain_->getMesh(), 500.0f);
  Terrain_->setPosition(irr::core::vector3df((lenght / 2) * 32 , 0, (width / 2) * 32));
  Terrain_->scaleTexture( 1.064f * lenght, 0.0f);
  mapSizeX_ = lenght;
  mapSizeZ_ = width;
}


et le resultat est le meme qu'en temps normal ... =/



je continue a chercher de mon cote, si quelqu'un a une illumination entre temps je suis preneur, merci en tous cas

Hors ligne


#11 

29-06-2012 13:16:08

johnplayer
Habitué
Date d'inscription: 30-09-2007
Messages: 431

C'est 1.063f, pas 1.064f mais faut peut-être l'ajuster. Sinon pourquoi tu mets "vector3df(lenght / 64 * 50, 0.0f, width / 64 * 50)", je vois pas trop l'intérêt d'une telle formule. Mets "vector3df(lenght, high, width)" et utilise des valeurs multiple de 10 voir de 100, dans un float tu as de la marge ( ±1.5 × 10^(−45) à ±3.4 × 10^(38) ) alors ne reste pas autour de zéro. De plus ton terrain est tout petit d'où une erreur d'arrondi peut-être (si lenght = 10, le terrain fait 10/64*50 = 7.8125 unitéIrrlicht), ce qui veut dire que ta texture doit être dessinée dans même pas 1 unitéIrrlicht². Moi je prends 100 unitésIrrlicht pour 1 mètre, comme ça ça concorde aussi avec 3DSMax. Et rajoutes high dans tes paramètres pour avoir une hauteur réglable.

Pour le code que je t'ai donné j'obtiens ça :
terrain texturé correctement

Autrement, je ne vois pas d'autres moyens que de faire ton propre terrainscenenode à moins que tu modifies celui d'Irrlicht afin qu'il convienne à tes attentes. Mais bon, c'est lourd comme travail donc si un coef peut résoudre l'affaire...

Au fait, tu utilises quelle version d'Irrlicht parce que moi, j'utilise la 1.8?


core i7 4970K @ 4GHz - 32GB ddr3 19200(2400MHz) - ssd samsung 840 evo 250GB - GTX1080Ti (4K) - Cooler master storm stryker blanc.
"L'alcool, c'est comme Activia, c'est actif à l'intérieur et ça se voit à l'extérieur."

Hors ligne


#12 

29-06-2012 14:04:56

3wic
Membre
Date d'inscription: 27-06-2012
Messages: 10
Corrections: 1

En gros tu veux que j'arrive a un truc comme ca ? smile

void            Map::constructMap(float lenght, float width, irr::video::IVideoDriver *driver, irr::scene::ISceneManager *sceneManager)
{
  Terrain_ = sceneManager->addTerrainSceneNode("./ressources/HeightMap.bmp", 0, -1, irr::core::vector3df(0.f, 0.f, 0.f), irr::core::vector3df(0.f, 0.f, 0.f), irr::core::vector3df(lenght, 0.0f, width), irr::video::SColor ( 255, 255, 255, 255 ), 5, irr::scene::ETPS_17, 3);

  Terrain_->setMaterialFlag(irr::video::EMF_LIGHTING, true);
  Terrain_->setMaterialFlag(irr::video::EMF_ANISOTROPIC_FILTER , true);
  Terrain_->setMaterialTexture(0, driver->getTexture("./ressources/terrdirtgrass.jpg"));

  Terrain_->setPosition(irr::core::vector3df(0, 0 , 0));
  Terrain_->scaleTexture( 1.063f * lenght, 0.0f);
  mapSizeX_ = lenght;
  mapSizeZ_ = width;
}




Edit : Je suis en version 1.7.2

Hors ligne


#13 

29-06-2012 14:47:23

johnplayer
Habitué
Date d'inscription: 30-09-2007
Messages: 431

Voilà. Ca t'évite de faire des calculs inutiles est répétitifs. Par contre, il y a un truc qui m'étonne, tu n'utilises pas pas la hauteur dans vector3df(lenght, 0.0f, width), le scale Y est à zéro. Parce que si tu veux que ça reste plat, j'ai la solution à ton problème.


core i7 4970K @ 4GHz - 32GB ddr3 19200(2400MHz) - ssd samsung 840 evo 250GB - GTX1080Ti (4K) - Cooler master storm stryker blanc.
"L'alcool, c'est comme Activia, c'est actif à l'intérieur et ça se voit à l'extérieur."

Hors ligne


#14 

01-07-2012 12:02:58

3wic
Membre
Date d'inscription: 27-06-2012
Messages: 10
Corrections: 1

Et bien j'arrive au meme resultat que mon premier post avec le code ci-dessus...

Je devrais essayer avec la version 1.8 peut etre ... Sinon j'y comprend plus rien ><

Hors ligne


#15 

01-07-2012 12:36:49

Taz6700
Petit nouveau
Date d'inscription: 01-07-2012
Messages: 1

J'ai le même problème que 3wic, la version 1.8 du svn ne donne pas plus de résultat hmm

Je suis aussi preneur si quelqu'un a une solution ;-)

Hors ligne


#16 

01-07-2012 13:24:43

johnplayer
Habitué
Date d'inscription: 30-09-2007
Messages: 431

Je ne comprends pas, je code sous la version 1.8 et j'ai le même problème que toi mais le coef résoud le problème. Tu as essayé de changer le coef (genre 1.7f, 1.8f...) pour voir si ça améliore le rendu? Et tu n'as pas répondu à ma question, tu n'utilises pas pas la hauteur dans vector3df(lenght, 0.0f, width), le scale Y est à zéro. Donc tu veux faire un plan texturé ou un terrain avec du relief?


core i7 4970K @ 4GHz - 32GB ddr3 19200(2400MHz) - ssd samsung 840 evo 250GB - GTX1080Ti (4K) - Cooler master storm stryker blanc.
"L'alcool, c'est comme Activia, c'est actif à l'intérieur et ça se voit à l'extérieur."

Hors ligne


#17 

01-07-2012 13:28:40

3wic
Membre
Date d'inscription: 27-06-2012
Messages: 10
Corrections: 1

J'essayerais des que je  booterais ma fedora smile

Non je n'utilise pas le coef Y car je veux un simple plan texturé wink

Hors ligne


#18 

01-07-2012 15:08:55

johnplayer
Habitué
Date d'inscription: 30-09-2007
Messages: 431

Dans ce cas, il y a bien plus simple! Tu t'es vraiment compliqué la vie pour rien.
Pour créer un plan :
ImeshSceneNode *node_plan = scenemanager->addHillPlaneMesh(...);
addHillPlaneMesh

Pour le texturing et la répétition de texture :
sceneManager->getMeshManipulator()->makePlanarTextureMapping(node_plan->getMesh(), répétition);
makePlanarTextureMapping

Avec ça tu peux faire un plan avec le nombre de quads que tu veux, régler la taiile des quads et donc de ta map et bien sûr le texturé facilement. Bien sûr, pour la répétition, faut tester des valeurs en partant de celle par défaut. Il faut aussi appliquer le material sur le node_plan comme tu l'as fait pour le terrain avant.


core i7 4970K @ 4GHz - 32GB ddr3 19200(2400MHz) - ssd samsung 840 evo 250GB - GTX1080Ti (4K) - Cooler master storm stryker blanc.
"L'alcool, c'est comme Activia, c'est actif à l'intérieur et ça se voit à l'extérieur."

Hors ligne


#19 

02-07-2012 01:18:45

3wic
Membre
Date d'inscription: 27-06-2012
Messages: 10
Corrections: 1

Je teste ca demain matin à la première heure wink thx pour le tuyaux

Hors ligne


#20 

02-07-2012 16:22:28

3wic
Membre
Date d'inscription: 27-06-2012
Messages: 10
Corrections: 1

Ca fonctionne niquel maintenant ! Merci beaucoup encore ! A tres bientot !

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
882 membres
1429 sujets
11119 messages
Dernier membre inscrit: LiseBuisson96
63 invités en ligne
Aucun membre connecté
RSS Feed