1

A partir d'un tableau[640X480] contenant la profondeur d'un pixel, comment remplir un buffer dans l'ordre avec des triangles en OpenGl?
Quel est le bon sens, horaire ou anti-horaire?
Je connais plus ou moins le principe (ça se résume à ça) mais je peine sur les bordures, et sur les inversions à chaques lignes.
Sur le papier c'est simple, mais dès qu'on quitte le papier on se rend compte des problèmes de triangles non-bouclés en début et fin de ligne.
Et que faire des points non-affichables car trop près ou trop loin : que deviennent les triangle qui utisaient ce point? Un point en moins et deux triangles (au moins) disparaissent?

Auriez vous un algo tout fait, même en pseudo code? Depuis le temps que les triangles_strip existent, c'est incroyable qu'il faille encore se coltiner ça à la main...

2

tout d'abord tu n'as pas à t'occuper des points trop près ou trop loin. les triangles utilisant ces points seront tronqués au rendu et uniquement les partie entre les plans near et far seront affichés.

bon, je n'ai jamais utilisé de triangle srtips, je ne comprends pas trop les boucles sur les points 7 et 8. si je comprends le schéma, tu utilises deux fois de suite ces triangles, et tu te retrouves avec 2 triangles plats 3-7-7 et 7-7-11 alors que si tu n'avais pas fait de répétition tu aurais juste un seul triangle plat 3-7-11 confus

sinon le problème que tu as, c'est trouver un algo pour générer la suite de numéros de points servant à créer le triangle strip ?
je pense que tu devrais plutôt essayer d'utiliser la suite décrite dans le post de paic dans ce thread : http://www.gamedev.net/community/forums/topic.asp?topic_id=393248
le principe est ressemblant et surtout tu vas toujours de gauche à droite
avatar

3

Oui, c'est ça mon problème :
J'ai les points, en mode GL_points je dirais que le rendu est "parfait", donc la géométrie est OK.
Mon problème c'est de passer en rendu par triangles. C'est plus un problème d'indices de vertex je pense.
La question subsidiaire étant : comment gérer les bordures?

4

avec la méthode dans le lien, pour une grille comme ça
0  1  2  3
4  5  6  7
8  9  10 11
12 13 14 15
ça donne
0, 4, 1, 5, 2, 6, 3, 7, 7, 4, 4, 8, 5, 9, 6, 10, 11, 11, 8, 8, 12, 9, 13, 10, 14, 11, 15

donc pour une grille n*m, avec des points identifiés par x,y (pour simplifier) le code doit ressembler à ça :
for(int y = 0; y < m-1; y++) // m lignes de points mais m-1 lignes de triangles
{
	for(int x = 0; x < n; x++) // cette fois il faut parcourir n colonnes, et non n-1 colonnes
	{
		utiliser_point(x, y); // point sur la ligne du dessus
		utiliser_point(x, y+1); // point sur la ligne du dessous
	}
	if(y != 0 && y != m-1)
	{
		// génère les deux triangles dégénérés de retour à la ligne
		utiliser_point(n-1, y+1); // point dupliqué de fin de ligne
		utiliser_point(0, y+1); // point dupliqué du début de la ligne du dessous
	}
}

(code non testé grin)
avatar

5

./3 > Comment ça les bordures ?
Et je vois pas ton problème, si tu suis rigoureusement le schéma que tu as montré (même sans le comprendre) ça fonctionnera. (Chaque flèche rouge représente un point à balancer)
Le principe énoncé dans le topic pointé par aze est exactement le même, les explications en plus.
Par contre je crois que ton schéma dessine les triangles dans le sens anti-horaire…
Et on doit se « coltiner ça à la main » parce que c'est trivial. De plus le matériel moderne te permet également de déformer une surface avec une texture si ça t'amuse. (Mais pour le coup à moins de modifier la texture en temps réel, je ne suis pas sûr que ce soit forcément la meilleure option… Et tu devra malgré tout créer cette surface à déformer cheeky )
Tu sais quand même calculer les coordonnées et/ou l'adresse d'un pixel dans une texture hein ? tongue
(Car le problème se résume à ça)

./2 > On est en 3D, 3-7-11 n'est pas forcément un triangle plat wink
Les autre sont des triangles nuls car utilisant toujours deux fois le même point.
avatar
Le scénario de notre univers a été rédigée par un bataillon de singes savants. Tout s'explique enfin.
T'as un problème ? Tu veux un bonbon ?
[CrystalMPQ] C# MPQ Library/Tools - [CrystalBoy] C# GB Emulator - [Monoxide] C# OSX library - M68k Opcodes

6

oui, exact grin
et puis si on était resté en 2D, ça n'aurait pas forcément valu la peine de faire uns grille plutôt qu'un gros quad cheeky

pour le coup, je pense aussi que le dessin en mode immédiat est plus adapté qu'un vertex buffer + vertex shader qui lit la texture
avatar

7

Merci de vos réponses. Je n'étais pas loin de l'algo de aze, je crois même l'avoir tester dans la centaine de combinaisons que j'ai essayé.
GoldenCrystal (./5) :
./2 > On est en 3D, 3-7-11 n'est pas forcément un triangle plat wink
Les autres sont des triangles nuls car utilisant toujours deux fois le même point.
Je vois pourquoi c'est un triangle, mais je ne vois pas quand l'algo de aze pourrait le sortir?

Et comment gérez vous les demi-triangles non traités en première et dernière ligne?

8

il n'y a rien a faire, tous les triangles seront bien générés. de quels demi triangles tu parles ? ( sur ton image d'exemple )

le problème avec le triangle 3-7-11, c'est que dans le cas où le point 7 est à une profondeur différente des points 3 et 11, tu auras un triangle qui ne sera perpendiculaire à la grille
avatar

9

A moins que l'algo de aze et le mien soient différents, je parle de la moitié de tous les triangles du bas de la première ligne et de la moitié de tous ceux du haut de la dernière.

Par exemple, si l'algo de aze commence par (8,12,9), et s'il "monte en X", il n'ira pas par (9,12,13).

10

avec mon algo, je vais ajouter les points 8, 12, 9 et ça va créer le triangle 8-12-9, puis je vais ajouter le point 13 et ça va créer le triangle 12-9-13. j'ajoute 10 ça crée 9-13-10, etc.
c'est le principe du triangle strip : quand tu ajoutes un point, tu crées toujours un triangle avec les deux points précédents.
avatar

11

OK, laisses moi vérifier ça demain. Là je code dans ma tête, et c'est pire que le papier et le crayon.
Merci beaucoup à vous deux. Je suis juste un peu surpris qu'il n'y ai pas plus d’exception dans ton code. Si ça déconne, tu vas m'entendre, rassure toi. wink
A + (demain) et encore merci.

12

Bon ça ne marche toujours pas.
Avec un code similaire à celui de Aze, j'ai 2 fois plus de points que la résolution de l'image. Donc ce n'est pas du triangle_strip.

Pour revenir à ma première question, comment gère t'on lorsque il y a des points aberrant au milieu de la map? Car j'en ai, et si j’enlève sur ces points, je casse plusieurs triangle, et le triangle_strip fait des triangles aberrant car il continu son chemin.

13

Tu pourrais poster ton code ? Ça irait probablement plus vite pour comprendre ce que tu veux faire, et identifier les éventuels problèmes.
avatar
All right. Keep doing whatever it is you think you're doing.
------------------------------------------
Besoin d'aide sur le site ? Essayez par ici :)

14

Je ne peux poster que le bout de code dont nous parlons, car il faut un kinect pour obtenir la depth-map. Ça explique pourquoi il y a des points aberrants. Le hardware

marche bien mais il n'est pas parfait.
int n = 640;
int m = 480;
int id = 0;
int indice=0;

for(int y = 0; y <= m-1; y++) // m lignes de points mais m-1 lignes de triangles 
{ 
        if(y != 0 || y != m-1) 
        {
                for(int x = 0; x <= n; x++) // cette fois il faut parcourir n colonnes, et non n-1 colonnes 
                {
                        id += utiliser_point(x, y, mDepthBuffer[y*640+x], id); // point sur la ligne du dessus 
                        id++;   
                        utiliser_point(x, y+1, mDepthBuffer[(y+1)*640+x], id); // point sur la ligne du dessous
                        id++;
                } 	
        }
       else
        { 
                // génère les deux triangles dégénérés de retour à la ligne 
                utiliser_point(n-1, y+1, mDepthBuffer[(y+1)*640+n-1], id); // point dupliqué de fin de ligne 
	        id ++;
                utiliser_point(0, y+1, mDepthBuffer[(y+1)*640], id); // point dupliqué du début de la ligne du dessous 
                id++;
        }

}
mActualVertexCount = id;
mVBOGrid->Upload(mVertices, mActualVertexCount);


Et la fonction utiliser_point qui élimine les points aberrant de la depthmap. Si je les affiche quand même le résultat n'est pas meilleur.
void utiliser_point(int x, int y, float z, int id)
{
       mVertices[id].x = x;
       mVertices[id].y = y;
       mVertices[id].z = z;
}

Je précise qu'en mode GL_POINTS le résultat est excellent.

15

C'est quoi que tu appelles un point aberrant ? J'arrive pas à comprendre avec ta fonction zarb tongue (Si c'est ce à quoi je pense, tu as envisagé de filtrer la texture avant de l'utiliser ? Par exemple avec un filtre moyenneur ou un filtre gaussien)
Et pour le coup si ta texture évolue en temps réel, tu aurais sans doute meilleur temps à utiliser un shader (v3) pour faire du vertex texturing.
(Rebalancer un vertex buffer entier à la carte graphique à chaque image y'a difficilement plus couteux en perfs…)
avatar
Le scénario de notre univers a été rédigée par un bataillon de singes savants. Tout s'explique enfin.
T'as un problème ? Tu veux un bonbon ?
[CrystalMPQ] C# MPQ Library/Tools - [CrystalBoy] C# GB Emulator - [Monoxide] C# OSX library - M68k Opcodes

16

Ce n'est pas vraiment une texture, c'est un tableau de profondeur, mis c'est vrai que je pourrais le filtrer.
J'utilise déjà les shaders, même plusieurs pour visualiser la profondeur ou appliquer diverse texture. Ca marche bien en mode point.

Elle est pas zarb ma fonction, elle enlève les points dont la profondeur z>-90000 car ce sont des aberration, et aussi ceux > max, car ça me permet d'enlever le fond si je veux. (d'ou le booleen mKeyBackground )

Le problème que j'ai actuellement c'est de remplir un vertex buffer comme il faut pour utiliser triangle_strip.
On voit bien dans la fonction de aze que le buffer contiendra 2 fois trop de points.

17

Tu ne peux pas simplement omettre un point. Si tu veux avoir une grille correcte avec des trous à la place des points aberrent, ça va énormément compliquer ton code et je ne pense pas que ça soit faisable simplement avec un triangle strip. par contre tu peux toujours limiter le z de ces points comme tu le fait et les afficher en transparent. comme ça ils ne seront pas visibles.

pour le reste, je ne sais pas trop. je vais tester le code de ./4 chez moi et voir ce que ça donne
mais sinon, l'idée de la fonction utiliser_point, c'était un peu de cacher tout le code que tu fais avant et de ne pas avoir à la dupliquer à chaque fois tongue

edit : attention, en mode triangle strip, tu auras bien plus de points que que dans la texture, car tous les points ne sont pas partagés. il faut utiliser le mode triangle list pour ça.
en triangle strip les points seront dupliqués pour la ligne de triangle au dessus et pour la ligne de triangle du dessous

sinon, oublie le triangle strip et passe au triangle list, ça sera surement plus simple
avatar

18

La fonction de aze donnera exactement le bon nombre de points.
avatar
Le scénario de notre univers a été rédigée par un bataillon de singes savants. Tout s'explique enfin.
T'as un problème ? Tu veux un bonbon ?
[CrystalMPQ] C# MPQ Library/Tools - [CrystalBoy] C# GB Emulator - [Monoxide] C# OSX library - M68k Opcodes

19

GUNNM (./14) :
if(y != 0 || y != m-1) {
...
}
if(y == 0 || y == m-1) {
...
}
Ça ne me parait pas très sain tout ça (et le premier test me semble suspect)
Dans tous les cas, un
if ( y == 0 || y == m-1 ) {
...
}
else {
...
}
me semble préférable.

20

aze > Le principe des triangles strip c'est d'utiliser 2 points de moins à chaque triangle (sauf le premier). Et tu as toujours 2 * (x - 1) triangles par ligne. Donc je ne vois pas comment des triangle list utiliseraient moins de points cheeky
Ce qu'il peut être intéressant d'utiliser c'est un index buffer (c'est ce que j'aurai fait en tout cas…) mais sinon…
avatar
Le scénario de notre univers a été rédigée par un bataillon de singes savants. Tout s'explique enfin.
T'as un problème ? Tu veux un bonbon ?
[CrystalMPQ] C# MPQ Library/Tools - [CrystalBoy] C# GB Emulator - [Monoxide] C# OSX library - M68k Opcodes

21

Bon elle m'en donne environ 2 * largeur * hauteur
Ce qui est normal puisqu'il a une boucle en largeur, une boucle en hauteur et que dans ces deux boucle on ajoute 2 vertex.
Il me semble pourtant que chaque vertex ajouter utilise les points précédents pour faire un triangle. Donc on devrait avoir grosso-modo autand de triangle que largeur * hauteur.

Je ne connais pas triangle list. C'est le mode GL_TRIANGLES ?

22

Tu ne connais pas non plus OpenGL, pas vrai ? tongue
avatar
Le scénario de notre univers a été rédigée par un bataillon de singes savants. Tout s'explique enfin.
T'as un problème ? Tu veux un bonbon ?
[CrystalMPQ] C# MPQ Library/Tools - [CrystalBoy] C# GB Emulator - [Monoxide] C# OSX library - M68k Opcodes

23

./19 > oui c'est vrai, mais je venais de tester ça, je n'ai pas nettoyé.

24

./22 > non, c'est la première fois que je tente un truc avec open_gl. Je l'avoue humblement.

25

GC> en fait je pensais aux index buffer, désolé grin
j'ai jamais fait d'openGL donc je me mélange un peu les termes (j'ai quasiment utilisé que OGRE)
avatar

26

C'est la doc de MSDN mais bon, ça a le mérite d'illustrer clairement les principes avec leur nom standard associé: (au cas où)
http://msdn.microsoft.com/en-us/library/bb206273(v=VS.85).aspx
http://msdn.microsoft.com/en-us/library/bb206274(v=VS.85).aspx
aze > Et t'en as pas trop chié avec Ogre ? Perso je me suis arraché des cheveux avec ce truc grin
avatar
Le scénario de notre univers a été rédigée par un bataillon de singes savants. Tout s'explique enfin.
T'as un problème ? Tu veux un bonbon ?
[CrystalMPQ] C# MPQ Library/Tools - [CrystalBoy] C# GB Emulator - [Monoxide] C# OSX library - M68k Opcodes

27

J'ai corrigé mon code en ./14
Comme ça c'est plus clair, je ne parle plus des vertex aberrants, je les affiche tous. (je ferais un filtre, ou les afficherais en transparent comme vous me l'avez conseillé)
Si vous voyez pourquoi ça ne marche pas, dites le moi.

GC > Merci pour la doc, je suis en train de lire ça.

Pour te citer, car je ne comprend pas :
Le principe des triangles strip c'est d'utiliser 2 points de moins à chaque triangle (sauf le premier). Et tu as toujours 2 * (x - 1) triangles par ligne
Comment en utilisant un points par triangle sauf pour le premier, tu obtiens 2 *x triangle par ligne? Tu dois faire erreur. J'en compte x-1 par ligne. C'est pour ça que je ne comprend pas pourquoi la fonction de aze me donne autand de points... je devrais en avoir +/- 480*640 ? Non?

Edit : ben non, je viens de voir sur le schema qu'on passe bien 2 fois par chaque points. Mea-culpa.

28

GC> Non, j'aime vraiment Ogre, je trouve ça très bien fait. Après j'ai commencé avec ça en stage, je n'avais jamais fait d'openGL ou directx avant, j'avais juste des notions de 3d générales
GUNNM> non, ce n'est pas comme ça que fonctionne le triangle strip
si on reprend l'exemple l'image de ./1, tu vas créer tes points dans l'ordre suivant : 0,4,1,5,2,6,3,7,7,11,6,10,5,9,4,8
Dans cette liste tu as des points qui sont dupliqués. Pour opengl, ce sont des points complètement distincts. Tu vas simplement ajouter deux fois ces points et ils auront exactement les mêmes caractéristiques (position, uv, ect)
dans cet exemple, tu te retrouves avec 16 points et dans ces 16 points tu en as deux qui ont les même caractéristiques que 4 mais un seul qui a les même caractéristiques que 0
avatar

29

./27 > Pose toi ces questions:
1. Combien y a-t-il de lignes de triangles pour N lignes de pixels.
2. Combien y a-t-il de colonnes de triangles pour N colonnes de pixels.
3. Combien de triangles au minimum y a-t-il dans un carré ?
avatar
Le scénario de notre univers a été rédigée par un bataillon de singes savants. Tout s'explique enfin.
T'as un problème ? Tu veux un bonbon ?
[CrystalMPQ] C# MPQ Library/Tools - [CrystalBoy] C# GB Emulator - [Monoxide] C# OSX library - M68k Opcodes

30

GUNNM (./27) :
Comment en utilisant un points par triangle sauf pour le premier, tu obtiens 2 *x triangle par ligne? Tu dois faire erreur. J'en compte x-1 par ligne. C'est pour ça que je ne comprend pas pourquoi la fonction de aze me donne autand de points... je devrais en avoir +/- 480*640 ? Non?
C'est bien environ un point par triangle dont tu as besoin. Tu te trompes juste sur le nombre de triangles smile

En fait, avec 640 * 480 points, tu formes une grille de 639 * 479 cases et chaque case est découpée en deux triangles (regarde le schéma que tu montres en ./1). Il te faut donc 2 * 639 * 479 + 2 (deux premiers points) + 478 (doubles points de changement de ligne) = 2 * 640 * 479 + 1 points pour former tes triangles.

Cross...
avatar