gKit2 light
interface C openGL

une api3d est...

un ensemble de fonctions. openGL est utilisable à travers un ensemble de fonctions C, ce qui signifie, pas de surchage, mais une famille de fonctions, des types opaques, pas d'objet, mais des identifiants.

une interface C++ pourrait ressembler à ça :

Context *context= new Context();
Point positions[]= { ... };
Buffer *buffer= context->createBuffer();
buffer->data(sizeof(positions), positions);

tout est explicite, on connait le contexte, le buffer, etc.

la version C pur pourrait ressembler à ça :

struct Context *context= context_create();
Point positions[]= { ... };
struct Buffer *buffer= context_createBuffer(context);
buffer_data(buffer, sizeof(positions), positions);

tout est explicite, mais un peu plus long à écrire.

l'interface d'openGL utilise une convention différente : au lieu de rendre explicite l'objet / la structure manipulée, elle est d'abord "sélectionnée" pour une opération particulière, puis manipulée implicitement :

createContext(); // crée un contexte, et le sélectionne,
uint buffer= createBuffer(); // crée un buffer, représenté par un identifiant numérique
bindBuffer(0, buffer); // sélectionne le buffer, pour une utilisation particulière
Point positions[]= { ... };
bufferData(0, sizeof(positions), positions); // alloue le buffer et l'initialise avec le contenu de positions.
// le buffer manipulé est celui sélectionné sur l'attribut 0...

ce qui permet d'obtenir une syntaxe compacte, mais peut être source de nombreuses erreurs, si l'on n'y prête pas attention.

pas de surcharge

autre détail important, il n'y a pas de surchage en C, on ne peut écrire ça pour modifier la valeur d'un paramètre de shader :

Program *program= context->createProgram( ... );
program->uniform("color", Color(1, 1, 0)); // affecter une couleur
program->uniform("time", 12); // affecter un float

ni ça :

struct Program *program= context_createProgram( context, ... );
program_uniform(program, "color", make_color(1, 1, 0));
program_uniform(program, "time", 12);

mais plutot ça :

uint program= createProgram( ... );
program_uniform3f(program, "color", 1.0f, 1.0f, 0.0f);
program_uniform1f(program, "time", 12.0f);

chaque surcharge est nommée explicitement, puisque seul le nom de la fonction est utilisé. selon le type de valeur à manipuler, les noms de fonctions sont décorés par un suffixe indiquant le nombre de paramètres (1, 2, 3, ou 4) et leur type (f pour float, i pour int, u pour unsigned int, v pour vector, un pointeur sur une ou plusieurs valeurs, etc.)

création des objets openGL

pour dessiner, il faut en général créer plusieurs types d'objets openGL, la démarche est toujours la même :

exemple, pour créer plusieurs buffers openGL, cf glGenBuffers( ) :

GLuint buffers[4];
glGenBuffers(4, buffers);

créer un buffer

pour créer un seul buffer, il suffit de passer le pointeur sur l'identifiant :

GLuint buffer;
glGenBuffers(1, &buffer);

le buffer sera ensuite sélectionné avec glBindBuffer( ). cf configurer un format de sommet, vertex array object pour plus de détails sur l'utilisation des buffers.

créer un vertex array object

GLuint vao;
glGenVertexArrays(1, &vao);

le vao sera ensuite sélectionné avec glBindVertexArray( ). cf configurer un format de sommet, vertex array object pour plus de détails.

créer une texture

GLuint texture;
glGenTextures(1, &texture);

la texture sera ensuite sélectionnée avec glBindTexture( ), cf textures, samplers et pipeline.

créer un shader, un shader program

les shaders et les programs sont un peu à part, leur fonction de création ne crée qu'un seul objet à la fois :

GLuint vertex_shader= glCreateShader(GL_VERTEX_SHADER);
GLuint shader_program= glCreateProgram();

le program sera sélectionné avec glUseProgram( ). cf compiler et linker un shader program pour les détails.

documentation complète

l'api complète et sa documentation est consultable sur opengl.org