VBO
Сначала нужно создать имена буферным объектам:
VBOid = new int[2]; GL.GenBuffers(2, VBOid);
Существует два буферных объекта: для хранения массива вершин (ArrayBuffer) и для хранения массива индексов (ElementArrayBuffer).
Для этих буферов мы создали два имени.
Теперь связываем имена с буферными объектами:
GL.BindBuffer(BufferTarget.ArrayBuffer, VBOid[0]); //связываем VBO GL.BindBuffer(BufferTarget.ElementArrayBuffer, VBOid[1]); //связываем IBO
Нам необходимо создать в нужном формате два массива для хранения информации о вершинах и индексах, которые мы передадим в только что созданные буферные объекты. Какой именно будет формат, решать Вам. Возможно, для быстрой загрузки Вы захотите хранить объекты в файлах в этом формате.
В массиве для вершин минимально требуется только координаты вершин (x, y, z). Но, если требуются нормали и текстурные координаты, то обычно можно увидеть данные в таком виде:

sizeof(float) * 3 для указания позиции вершины, sizeof(float) * 3 на вектор нормали и sizeof(float) * 2 на текстурные координаты. Если на машине размер типа float равен 4 байтам, то на описание точки требуется 4*3 + 4*3 + 4*2 = 4*8 =32 байта. Всего размер массива будет (sizeof(float) * 8) * vertex_count.
Массив индексов состоит из целочисленных данных типа int. Каждый элемент индекса указывает на блок данных из массива вершин. Т.к. массив вершин одномерный, то позиция блока с нужными данными находится по адресу index * sizeof(float) * 8.
Передаём буферу вершин указатель на массив вершин, в котором находятся данные в нашем формате (массив с именем, например, "vertexes"):
GL.BufferData(BufferTarget.ArrayBuffer, (IntPtr)(vertexes.Length * sizeof(float)), vertexes, BufferUsageHint.StaticDraw); //записываем в память VBO
Данные из массива вершин перемещаются в т.н. "хранилище данных". Параметр-подсказка BufferUsageHint со значением StaticDraw "подсказывает" машине, что данные будут меняться редко.
Точно также передаём буферу индексов указатель на массив индексов (с именем, например, "indexes"):
GL.BufferData(BufferTarget.ElementArrayBuffer, (IntPtr)(indexes.Length * sizeof(int)), indexes, BufferUsageHint.StaticDraw); //записываем в память IBO
Данные переданы в буфер. Обходя буфер индексов, OpenGL будет искать данные в буфере вершин, и теперь нужно указать, по какому адресу искать данные о позициях точек, нормалей и текстурных координат:
GL.VertexPointer(3, VertexPointerType.Float, sizeof(float) * 8, 0); //координаты точек идут первыми, смещение 0 GL.NormalPointer(NormalPointerType.Float, sizeof(float) * 8, sizeof(float) * 3); //вектор нормали идет после данных о позиции GL.TexCoordPointer(2, TexCoordPointerType.Float, sizeof(float) * 8, sizeof(float) * 6); //текстурные координаты после вектора нормали
Эти функции указывают расстояние между данными и начальную позицию данных в буфере вершин. Расстояние одинаковое sizeof(float) * 8 (длина блока данных о вершине), а начальная позиция зависит от положения внутри блока.
Осталось указать OpenGL, что мы в данный момент хотим вывести на экран всю информацию о точках:
GL.EnableClientState(ArrayCap.VertexArray); GL.EnableClientState(ArrayCap.NormalArray); GL.EnableClientState(ArrayCap.TextureCoordArray);
Эти команды можно давать в каждом кадре.
И в каждом кадре даем команду рисования:
GL.DrawElements(BeginMode.Triangles, indexes.Length, DrawElementsType.UnsignedInt, IntPtr.Zero);
Эта функция находит буфер индексов, берет каждые 3 индекса для рисования треугольников (т.к. мы указали BeginMode.Triangles), находит по ним 3 блока данных из буфера вершин, по данным о позициях (из функций VertexPointer, NormalPointer и TexCoordPointer) берет нужные данные из буфера вершин, рисует.
- Printer-friendly version
- Login or register to post comments


Comments
Re: Vertex Buffer Objects
Этот перевод ещё более непонятный, чем источник. Цель какая преследовалась, запутать ещё больше?
Re: Vertex Buffer Objects
/