Конечно, на самом деле это довольно просто, у вашего атрибута есть местоположение, а данные о вершинах снабжаются glVertexAttribPointer для простых массивов вершин, например:
float *vertices = ...;
int loc = glGetAttribLocation(program, "position");
glVertexAttribPointer(loc, 3, GL_FLOAT, GL_FALSE, 0, vertices);
Для VBO это то же самое, но вы должны привязать буфер к цели GL_ARRAY_BUFFER, и последний параметр glVertexAttribPointer теперь является смещением в памяти буферной памяти. Само значение указателя интерпретируется как смещение:
glBindBuffer(GL_ARRAY_BUFFER, buffer);
int loc = glGetAttribLocation(program, "position");
glVertexAttribPointer(loc, 3, GL_FLOAT, GL_FALSE, 0, 0);
В этом случае смещение равно 0, при условии, что данные вершины загружены в начале буфера. Смещение измеряется в байтах.
Затем рисование выполняется с помощью glDrawArrays / glDrawElements. Надеюсь, это поможет!