2010-10-25 10 views
7

Je suis un peu confus à ce sujet. Tout ce que j'ai trouvé dans les livres, les blogs, les forums et même dans les spécifications OpenGl ne parle que de techniques très abstraites. Rien sur les exemples du monde réel.OpenGL ES 2.0 plusieurs maillages? (Juste exemples du monde réel)

Et je deviens fou avec ceci: Comment mettre et gérer plusieurs objets (mailles) avec OpenGL ES 2.x?

En théorie semble simple. Vous avez un Vertex Shader (vsh) et un Shader de fragments (fsh), puis vous liez les deux à un programme (glGenProgram, glUseProgram, ...). Dans chaque cycle de rendu, ce programme exécutera son VSH par chaque sommet et après cela exécutera FSH sur chaque "pixel" de cet objet 3d et enverra finalement le résultat final au buffer (évidemment sans parler du per-vertex, rastérisation et autres étapes dans le pipeline).

OK, semble simple ...

Tout cela est tiré par un appel à la fonction de tirage (ou de glDrawArrays glDrawElements).

OK à nouveau.

Maintenant, les choses me sont confuses. Et si vous avez plusieurs objets à rendre?

Parlons d'un exemple concret. Imaginez que vous avez un paysage avec des arbres et un personnage. L'herbe du paysage a une texture, les arbres ont une texture pour le tronc et les feuilles (Texture Atlas) et enfin le personnage a une autre texture (Texture Atlas) et est animé aussi. Après avoir imaginé cette scène, ma question est simple: Comment cela s'organise-t-il?

Vous créez un programme séparé (avec un VSH et un FSH) pour chaque élément de la scène? Comme un programme au soulagement d'herbe et de sol, un programme aux arbres et un programme au caractère?

Je l'ai essayé, mais ... lorsque je crée plusieurs programmes et que j'essaie d'utiliser glVertexAttribPointer(), les textures et les couleurs des objets entrent en conflit les uns avec les autres. Parce que l'emplacement des attributs, les index, du premier programme répètent dans le deuxième programme. Permettez-moi d'expliquer, j'ai utilisé glGetAttribLocation() dans une classe qui contrôle le sol de la scène, de sorte que le noyau OpenGL m'a renvoyé l'indice de 0,1 et 2 pour les vertexes attributs. Après, dans la classe des arbres, j'ai créé un autre programme, d'autres shaders, et après avoir utilisé à nouveau le glGetAttribLocation() à ce moment le retour du noyau OpenGL avec les index 0, 1, 2 et 3.

Après dans le rendu cycle, j'ai commencé à définir le premier programme avec glUseProgram() et j'ai modifié ses attributs de vertex avec glVertexAttribPointer() et enfin un appel à glDrawElements(). Après cela, appelez à nouveau glUseProgram() au second programme et utilisez à nouveau glVertexAttribPointer() et finalement glDrawElements(). Mais à ce stade, les choses entrent dans les conflits, car les index des vertexes attributs du deuxième programme affecte aussi les vertex du premier programme.

J'ai essayé beaucoup de choses, j'ai beaucoup cherché, j'ai beaucoup demandé ... Je suis épuisé. Je ne peux pas trouver ce qui ne va pas.

Alors j'ai commencé à penser que je faisais tout faux!

Maintenant, je répète ma question: Comment travailler avec plusieurs maillages (avec des textures et un comportement différents) dans OpenGL ES 2.x? Utiliser plusieurs programmes? Comment?

Répondre

0

Merci pour la réponse,

Mais je pense que vous répéter mes propres mots ... sur les méthodes de dessin, environ un programme actif, de tout.

Peu importe.

Le fait est que vos mots me donnent un aperçu! Vous avez dit: "vous devez réinitialiser tous les attributs de vertex et les pointeurs".

Eh bien ... pas exactement réinitialisé, mais ce que je ne mettais pas à jour tous les attributs de vertex sur le cycle de rendu, comme les coordonnées de texture. Je mettais à jour seulement les attributs qui changent. Et quand j'ai effacé les tampons, j'ai perdu les anciennes valeurs.

Maintenant, je commence à mettre à jour tous les attributs, indépendamment du changement ou pas leurs valeurs, tout fonctionne!

Voir, ce que j'avais avant est:

glCreateProgram(); 
... 
glAttachShader(); 
glAttachShader(); 
... 
glLinkProgram(); 
glUseProgram(); 
... 
glGetAttribLocation(); 
glVertexAttribPointer(); 
glEnableVertexAttribArray(); 
... 
glDrawElements(); 

Je répète le processus du deuxième programme, mais juste appeler glVertexAttribPointer() à quelques reprises. Maintenant, ce que j'ai un appel à glVertexAttribPointer() pour TOUS les attributs. Ce qui m'a rendu fou est le fait que si j'ai enlevé le premier bloc de code au premier programme, tout le deuxième programme a bien fonctionné. Si j'ai supprimé le deuxième bloc de code au deuxième programme, le premier a bien fonctionné.

Maintenant semble tellement évident. Bien sûr, si le VSH est une opération par vertex, il fonctionnera avec une valeur nulle si je ne mets pas à jour TOUS les attributs et uniformes. Je pense à propos d'OpenGL plus comme un moteur 3D, qui fonctionne avec des objets 3D, a une scène où vous placez vos objets, mettre des lumières. Mais pas ... OpenGL ne connaît que les triangles, les lignes et les points, rien de plus. Je pense différemment maintenant.

De toute façon, le point est que maintenant je peux aller de l'avant!

Merci

+0

Pourriez-vous améliorer votre réponse? Je suis vraiment content que tu aies compris: D – MatterGoal

2

Pour dessiner plusieurs maillages, appelez glDrawElements/glDrawArrays plusieurs fois. Si ces maillages nécessitent des shaders différents, il suffit de les définir. ONE, et un seul programme de shader est actif.

Ainsi, chaque fois que vous changez votre programme de shader (plus précisément le VS), vous devez réinitialiser tous les attributs de vertex et les pointeurs.

Juste simple comme ça.