Si nous essayions de réduire l’ensemble de l’API OpenGL à de grands concepts, ils seraient:
Shaders shader sera présenté pendant le cours.
Les états représentent un concept plus large, OpenGL étant en fait un grand automate fini avec beaucoup d'états et de possibilités de passer d'un état à un autre. Dans tous les laboratoires, certains de ces états seront utilisés pour obtenir les effets souhaités.
Les données contiennent les informations qui définissent la scène, ainsi que:
La primitive de base dans OpenGL est le triangle. Ainsi, comme on peut le voir dans l'image ci-dessus, dessiner un objet doit être spécifié par des triangles.
Le cube décrit ci-dessus est spécifié par la liste des 8 coordonnées de sommets et une liste de 12 triangles décrivant la manière dont les sommets spécifiés dans la liste précédente doivent être joints pour former les faces du cube. En utilisant des sommets et des index, nous pouvons décrire discrètement tout objet en trois dimensions.
Vous trouverez ci-dessous les principales primitives supportées par le standard OpenGL 3.3+.
Comme on peut le constater, il existe plusieurs méthodes permettant de spécifier la géométrie:
primitive
peut être n'importe lequel des primitifs mentionnés dans l'image ci-dessus.
Une observation importante liée à la topologie est l’ordre des sommets dans une primitive solide (pas une ligne, pas un point) avec plus de 2 sommets. Cet ordre peut être horaire ou antihoraire.
L'API OpenGL offre la possibilité de tester l'orientation apparente de chaque triangle à l'écran avant sa lecture et de l'ignorer en fonction du statut de suppression défini.: GL_FRONT oú GL_BACK. Cette fonctionnalité s'appelle Face Culling et est très important car cela réduit le coût total de traitement.
Normalement, la sélection du visage est désactivée. Il peut être activé en utilisant la commande glEnable:
glEnable(GL_CULL_FACE);
Pour désactiver la sélection face-à-face, utilisez la commande glDisable:
glDisable(GL_CULL_FACE);
Pour spécifier l'orientation des faces à ignorer, utilisez la commande glCullFace
// GL_FRONT, GL_BACK, and GL_FRONT_AND_BACK are accepted. // The initial value is GL_BACK. glCullFace(GL_BACK);
Un „maillage” est un objet en trois dimensions défini par des points et des indices. Au laboratoire, vous pouvez télécharger des maillages dans presque tous les formats possibles en classe. Mesh.
Un vertex buffer object (objet tampon de sommet) représente un conteneur dans lequel nous stockons des données liées au contenu des sommets, telles que:
Un vertex buffer object peut être créé à l'aide de la commande OpenGL glGenBuffers:
GLuint VBO_ID; // L'ID (nom ou référence) du tampon qui sera requis du GPU glGenBuffers(1, &VBO_ID); // l'identifiant de tampon (nom) est généré
VBO_ID
.
Pour détruire un VBO et libérer ainsi la mémoire du GPU utiliser la commande glDeleteBuffers:
glDeleteBuffers(1, &VBO_ID);
Pour pouvoir mettre les données dans un tampon, nous devons d’abord lier ce tampon à un „target”. Pour un vertex buffer this „binding point” ça s'appelle GL_ARRAY_BUFFER et peut être spécifié par la commande glBindBuffer:
glBindBuffer(GL_ARRAY_BUFFER, VBO_ID);
À ce stade, nous pouvons télécharger des données de la mémoire du CPU au GPU à travers la commande glBufferData:
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices[0]) * vertices.size(), &vertices[0], GL_STATIC_DRAW);
&vertices[0]
, et copier dans la mémoire vidéo la taille spécifiée par le paramètre 2.
Un index buffer object (objet tampon d’index) est un conteneur dans lequel nous stockons des sommets. Comme VBO si IBO sont des tampons, ils sont extrêmement similaires dans leur construction, leur chargement et leur suppression.
glGenBuffers(1, &IBO_ID); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, IBO_ID); glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices[0]) * indices.size(), &indices[0], GL_STATIC_DRAW);
Comme avec VBO, nous créons un IBO et le lions ensuite à un point de connexion, mais cette fois, le point de connexion est GL_ELEMENT_ARRAY_BUFFER. Les données sont envoyées au tampon mappé à ce point de liaison. Dans le cas des index, tous auront la taille d'un seul entier.
Dans un vertex array object (objet tableau de sommets) nous pouvons stocker toutes les informations relatives à l'état de la géométrie dessinée. Nous pouvons utiliser un grand nombre de tampons pour stocker chacun des différents attributs („separate buffers”). Nous pouvons stocker plusieurs attributs (ou tous) dans un seul tampon („interleaved” buffers). Normalement, avant chaque commande de dessin, toutes les commandes “de liaison” pour les tampons ou les attributs décrivant les données à restituer doivent être spécifiées. Pour simplifier cette opération, on utilise un objet tableau de sommets prenant en compte tous ces liens.
Un objet tableau de sommets est créé à l'aide de la commande glGenVertexArrays:
unsigned int VAO; glGenVertexArrays(1, &VAO);
Il est lié à glBindVertexArray:
glBindVertexArray(VAO);
Une fois tous les liens spécifiés, il est recommandé de commander glBindVertexArray(0)
désactiver le lien avec le VAO actuel, car sinon, nous risquons que d'autres commandes OpenGL ultérieures soient liées au même VAO, ce qui facilitera grandement les erreurs dans le programme.
Avant la commande de dessin, il suffit de lier uniquement le VAO pour qu'OpenGL connaisse toutes les liaisons créées lors de la construction de l'objet.
En laboratoire, nous allons apprendre à utiliser VAO, VBO, IBO et ainsi nous générons et chargeons une géométrie simple.
Le laboratoire fournit la structure VertexFormat qui servira de base à la création de la géométrie.
struct VertexFormat { // position of the vertex glm::vec3 position; // vertex normal glm::vec3 normal; // vertex texture coordinate glm::uvec2 text_coord; // vertex color glm::vec3 color; };
La classe Mesh
offre la possibilité de télécharger une géométrie simple en utilisant diverses méthodes:
// Initialise l'objet maillé à l'aide d'un tampon VAO GPU contenant le nombre spécifié d'index. bool InitFromBuffer(unsigned int VAO, unsigned short nrIndices); // Initialise l'objet maillé et télécharge les données sur les GPU à l'aide des tampons de données fournis. bool InitFromData(std::vector<VertexFormat> vertices, std::vector<unsigned short>& indices); // Initialise l'objet maillé et télécharge les données sur les GPU à l'aide des tampons de données fournis. bool InitFromData(std::vector<glm::vec3>& positions, std::vector<glm::vec3>& normals, std::vector<unsigned short>& indices);
F3 - affiche / masque la grille dans la scène
Space - dessiner des primitives uniquement par points ou lignes (wireframe) ou géométrie opaque
Laborator2::CreateMesh
mais vous pouvez utiliser les méthodes Mesh::InitFromData()
pour vérifier la validité de la géométrie.
VertexFormat
est une structure de sommet avec 2 paramètres (position, couleur).Laborator2::CreateMesh
afin que vous puissiez charger la géométrie sur le GPUglEnable()
/ glDisable()