This is an old revision of the document!
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 astuces, 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.
În cadrul laboratorului vom învăța să folosim VAO, VBO, IBO și astfel să generăm și încărcăm geometrie simplă.
Laboratorul pune la dispoziție structura VertexFormat ce va fi utilizată ca bază pentru a crea geometria.
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; };
Clasa Mesh
pune la dispoziție posibilitatea de a încărca geometrie simplă folosind diverse metode:
// Initializes the mesh object using a VAO GPU buffer that contains the specified number of indices bool InitFromBuffer(unsigned int VAO, unsigned short nrIndices); // Initializes the mesh object and upload data to GPU using the provided data buffers bool InitFromData(std::vector<VertexFormat> vertices, std::vector<unsigned short>& indices); // Initializes the mesh object and upload data to GPU using the provided data buffers bool InitFromData(std::vector<glm::vec3>& positions, std::vector<glm::vec3>& normals, std::vector<unsigned short>& indices);
F3 - afișează/ascunde gridul din scenă
Space - desenează primitivele doar prin puncte sau linii (wireframe) sau geometrie opacă
Laborator2::CreateMesh
dar puteți folosi metodele Mesh::InitFromData()
pentru a verifica validitatea geometriei.
VertexFormat
este o structură pentru vertex cu 2 parametrii (poziție, culoare).Laborator2::CreateMesh
astfel încât să încărcați geometria pe GPUglEnable()
/ glDisable()