Объект буфера вершин ( VBO ) - это функция OpenGL, которая предоставляет методы для загрузки данных вершин ( положение , вектор нормали , цвет и т. Д.) На видеоустройство для рендеринга не в немедленном режиме. VBO предлагают существенный прирост производительности по сравнению с рендерингом в немедленном режиме, прежде всего потому, что данные находятся в памяти видеоустройства, а не в системной памяти, и поэтому они могут быть визуализированы непосредственно видеоустройством. Они эквивалентны буферам вершин в Direct3D .
Спецификация объекта буфера вершины стандартизирована Советом по обзору архитектуры OpenGL начиная с OpenGL версии 1.5 (в 2003 г.). Аналогичная функциональность была доступна до стандартизации VBO через созданное Nvidia расширение «диапазон массива вершин» [1] или расширение « объект массива вершин» [2] от ATI .
Основные функции VBO
Следующие функции составляют основу доступа и управления VBO:
- В OpenGL 1.4 :
- glGenBuffersARB (размер буферов, uint *)
- Создает новый VBO и возвращает его идентификационный номер в виде целого числа без знака. Id 0 зарезервирован.
- glBindBufferARB (цель перечисления, буфер uint)
- Используйте ранее созданный буфер в качестве активного VBO.
- glBufferDataARB (цель перечисления, размер iptrARB, const void * данные, использование перечисления)
- Загрузите данные в активный VBO.
- glDeleteBuffersARB (размер, константа uint * буферы)
- Удаляет указанное количество VBO из предоставленного массива или идентификатора VBO.
- В OpenGL 2.1 , [3] OpenGL 3.x [4] и OpenGL 4.x : [5]
- glGenBuffers (размер буферов, uint *)
- Создает новый VBO и возвращает его идентификационный номер в виде целого числа без знака. Id 0 зарезервирован.
- glBindBuffer (цель перечисления, буфер uint)
- Используйте ранее созданный буфер в качестве активного VBO.
- glBufferData (цель перечисления, размер iptrARB, данные const void *, использование перечисления)
- Загрузите данные в активный VBO.
- glDeleteBuffers (размер буферов, const uint *)
- Удаляет указанное количество VBO из предоставленного массива или идентификатора VBO.
Пример использования
В C с использованием OpenGL 2.1
// Инициализировать VBO - выполнить только один раз, при запуске программы // Создать переменную для хранения идентификатора VBO GLuint треугольникVBO ;// Вершины треугольника (вращение против часовой стрелки) float data [] = { 1.0 , 0.0 , 1.0 , 0.0 , 0.0 , -1.0 , -1.0 , 0.0 , 1.0 }; // пробуем данные с плавающей запятой [] = {0.0, 1.0, 0.0, -1.0, -1.0, 0.0, 1.0, -1.0, 0.0}; если вышеуказанное не работает.// Создаем новый VBO и используем идентификатор переменной для хранения идентификатора VBO glGenBuffers ( 1 , & треугольникVBO );// Делаем новый VBO активным glBindBuffer ( GL_ARRAY_BUFFER , треугольникVBO );// Загрузить данные вершин в видеоустройство glBufferData ( GL_ARRAY_BUFFER , sizeof ( data ), data , GL_STATIC_DRAW );// Делаем новый VBO активным. Повторите здесь, если после инициализации изменилось glBindBuffer ( GL_ARRAY_BUFFER , треугольникVBO );// Рисуем треугольник из VBO - делаем каждый раз, когда окно, точка обзора или данные меняются // Устанавливаем его 3 координаты на вершину с нулевым шагом в этом массиве; здесь необходимо glVertexPointer ( 3 , GL_FLOAT , 0 , NULL );// Создать массив содержит вершины (не нормали, цвет, текстуру и т.д. Coords) glEnableClientState ( GL_VERTEX_ARRAY );// Фактически рисуем треугольник с указанием количества предоставленных вершин glDrawArrays ( GL_TRIANGLES , 0 , sizeof ( data ) / sizeof ( float ) / 3 );// Принудительно отрисовывать отображение glFlush ();
В C с использованием OpenGL 3.x и OpenGL 4.x
Вершинный шейдер:
/ * ----------------- "exampleVertexShader.vert" ----------------- * /#version 150 // Укажите, какую версию GLSL мы используем.// in_Position был привязан к индексу атрибута 0 ("shaderAttribute") в vec3 in_Position ;void main () { gl_Position = vec4 ( in_Position . x , in_Position . y , in_Position . z , 1.0 ); } / * ----------------------------------------------- --------------- * /
Фрагментный шейдер:
/ * ---------------- "exampleFragmentShader.frag" ---------------- * /#version 150 // Укажите, какую версию GLSL мы используем.высокоточный поплавок высокого давления ; // Драйверы видеокарты требуют, чтобы эта строка работала правильно out vec4 fragColor ;void main () { fragColor = vec4 ( 1,0 , 1,0 , 1,0 , 1,0 ); // Устанавливаем БЕЛЫЙ цвет каждого фрагмента } / * -------------------------------------- ------------------------ * /
Основная программа OpenGL:
/ * --------------------- Основная программа OpenGL --------------------- * // * Создаем переменную для хранения идентификатора VBO * / GLuint треугольникVBO ; / * Это дескриптор программы шейдера * / GLuint shaderProgram ;/ * Эти указатели получат содержимое наших файлов исходного кода шейдера * / GLchar * vertexSource , * fragmentSource ;/ * Это дескрипторы, используемые для ссылки на шейдеры * / GLuint vertexShader , fragmentShader ;const unsigned int shaderAttribute = 0 ;/ * Вершины треугольника (вращение против часовой стрелки) * / float data [ 3 ] [ 3 ] = { { 0.0 , 1.0 , 0.0 }, { -1.0 , -1.0 , 0.0 }, { 1.0 , -1.0 , 0.0 } };/ * ---------------------- Инициализировать VBO - (Примечание: выполнить только один раз при запуске программы) ----------- ---------- * / / * Создайте новый VBO и используйте переменную "треугольникVBO" для хранения идентификатора VBO * / glGenBuffers ( 1 , & треугольникVBO );/ * Делаем новый VBO активным * / glBindBuffer ( GL_ARRAY_BUFFER , треугольникVBO );/ * Загрузить данные вершин в видеоустройство * / glBufferData ( GL_ARRAY_BUFFER , sizeof ( data ), data , GL_STATIC_DRAW );/ * Указываем, что наши данные координат входят в индекс атрибута 0 (shaderAttribute) и содержат три числа с плавающей запятой на вершину * / glVertexAttribPointer ( shaderAttribute , 3 , GL_FLOAT , GL_FALSE , 0 , 0 );/ * Включить индекс атрибута 0 (shaderAttribute) как используемый * / glEnableVertexAttribArray ( shaderAttribute );/ * Делаем новый VBO активным. * / glBindBuffer ( GL_ARRAY_BUFFER , треугольникVBO ); / * ------------------------------------------------ -------------------------------------------------- ----- * // * --------------------- Загрузка вершинных и фрагментных шейдеров из файлов и их компиляция ----------------- --- * / / * Считываем наши шейдеры в соответствующие буферы * / vertexSource = filetobuf ( "exampleVertexShader.vert" ); fragmentSource = filetobuf ( "exampleFragmentShader.frag" );/ * Присваиваем нашим дескрипторам «имя» новым шейдерным объектам * / vertexShader = glCreateShader ( GL_VERTEX_SHADER ); fragmentShader = glCreateShader ( GL_FRAGMENT_SHADER );/ * Свяжите буферы исходного кода с каждым дескриптором * / glShaderSource ( vertexShader , 1 , ( const GLchar ** ) & vertexSource , 0 ); glShaderSource ( fragmentShader , 1 , ( const GLchar ** ) & fragmentSource , 0 );/ * Освобождаем временно выделенную память * / free ( vertexSource ); бесплатно ( fragmentSource );/ * Скомпилируем наши шейдерные объекты * / glCompileShader ( vertexShader ); glCompileShader ( fragmentShader ); / * ------------------------------------------------ -------------------------------------------------- ----- * // * -------------------- Создать программу шейдера, прикрепить к ней шейдеры и затем связать ее ---------------- ----- * / / * Присвойте нашему программному дескриптору «имя» * / shaderProgram = glCreateProgram ();/ * Присоединяем наши шейдеры к нашей программе * / glAttachShader ( shaderProgram , vertexShader ); glAttachShader ( shaderProgram , fragmentShader );/ * Привязать индекс атрибута 0 (shaderAttribute) к in_Position * / / * «in_Position» будет представлять содержимое массива «данных» в вершинном шейдере * / glBindAttribLocation ( shaderProgram , shaderAttribute , «in_Position» );/ * Ссылка на программу шейдера * / glLinkProgram ( shaderProgram ); / * ------------------------------------------------ -------------------------------------------------- ----- * // * Установить программу шейдера как активно используемую * / glUseProgram ( shaderProgram );/ * Установить ЧЕРНЫЙ цвет фона * / glClearColor ( 0.0 , 0.0 , 0.0 , 1.0 );/ * Очистить фон ЧЕРНЫМ цветом * / glClear ( GL_COLOR_BUFFER_BIT );/ * Фактически нарисуйте треугольник, указав количество вершин, предоставленных вызовом glDrawArrays , сообщая, что наши данные являются треугольником, и мы хотим нарисовать 0–3 вершины * / glDrawArrays ( GL_TRIANGLES , 0 , ( sizeof ( data ) / 3 ) / sizeof ( GLfloat )); / * ------------------------------------------------ --------------- * /
Рекомендации
- ^ "GL_NV_vertex_array_range Технический документ" .
- ^ "ATI_vertex_array_object" .
- ^ «Справочник по функциям OpenGL 2.1» .
- ^ «Справочник по функциям OpenGL 3.3» .
- ^ «Справочник по функциям OpenGL 4.2» .