пятница, 16 апреля 2010 г.

Вывод статических моделей с использованием VBO

О том что такое VBO можно почитать тут: http://steps3d.narod.ru/tutorials/tutorial-VBO.html, выдержка: "Использование данного расширения позволяет кэшировать (хранить) различные типы данных (как информацию о вершинах, так и индексы в массив вершин) в быстрой памяти графического ускорителя".

Т.е. используя данное расширение можно ускорить вывод геометрии, особенно статической (не изменяющейся), передав одинажды данные граф. ускорителю можно сократить много ФПС-ов! :)

Я не буду рассказывать, теории и так полно, я примерик покажу (который бы мне так помог!). Инициализация:

type
PVec2 = ^TVec2;
TVec2 = record
x, y: Single;
end;

PVec3 = ^TVec3;
TVec3 = record
x, y, z: Single;
end;

//это наш формат хранения вершин (положение, нормаль, текст. коорд.)
TVert = record
vert, norm: TVec3;
coord: TVec2;
end;

var
vbo: TGLint;
//numVerts - кол-во вершин, verts - массив вершин (в примере не заполняется)
numVerts: Integer;
verts: array of TVert;

//итак создаем буфер, GL_STATIC_DRAW_ARB указывает на то что мы не собираемся изменять данные после их передачи граф. ускорителю
glGenBuffersARB(1, @vbo);
glBindBufferARB(GL_ARRAY_BUFFER_ARB, vbo);
glBufferDataARB(GL_ARRAY_BUFFER_ARB, numVerts * SizeOf(TVert), @verts[0], GL_STATIC_DRAW_ARB);
glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0);

И отрисовка:

glPushClientAttrib(GL_CLIENT_VERTEX_ARRAY_BIT);

//включаем массивы положений, нормалей и текстурных координат
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_NORMAL_ARRAY);
//координаты будем задавать для текстуры на "0" слое
glClientActiveTextureARB(GL_TEXTURE0_ARB);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);

glBindBufferARB(GL_ARRAY_BUFFER_ARB, vbo);

//указываем смещения к положению, нормали и текс. коорд. внутри нашей вершины TVert
//положение как и нормаль у нас представлено 3 целыми
glVertexPointer(3, GL_FLOAT, SizeOf(TVert), Pointer(0));
glNormalPointer(GL_FLOAT, SizeOf(TVert), Pointer(3 * SizeOf(Single)));
//текс. коорд. у нас представлена 2 целыми
glTexCoordPointer(2, GL_FLOAT, SizeOf(TVert), Pointer(6 * SizeOf(Single)));

//и собственно выводим, start - номер вершины с которой начинать вывод, count - кол-во вершин (не примитивов а вершин)
glDrawArrays(GL_TRIANGLES, start{0}, count{numVerts});

glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0);
glPopClientAttrib;

0 коммент.:

Отправить комментарий