Объект буфера вершин ( VBO ) — это функция OpenGL , которая предоставляет методы для загрузки данных вершин ( положение , вектор нормали , цвет и т. д.) на видеоустройство для рендеринга в не-немедленном режиме. VBO предлагают существенный прирост производительности по сравнению с рендерингом в немедленном режиме, в первую очередь потому, что данные находятся в памяти видеоустройства, а не в системной памяти, и поэтому они могут быть отрисованы непосредственно видеоустройством. Они эквивалентны буферам вершин в Direct3D .
Спецификация объекта буфера вершин была стандартизирована Советом по рассмотрению архитектуры OpenGL Архивировано 24.11.2011 на Wayback Machine в версии OpenGL 1.5 (в 2003 году). Подобная функциональность была доступна до стандартизации VBO через созданное Nvidia расширение "vertex array range" [1] или расширение ATI "vertex array object" [2] .
Следующие функции составляют основу доступа и манипулирования VBO:
//Инициализация VBO — выполняется только один раз при запуске программы //Создание переменной для хранения идентификатора VBO GLuint triangleVBO ; //Вершины треугольника (обмотка против часовой стрелки) float data [] = { 1.0 , 0.0 , 1.0 , 0.0 , 0.0 , -1.0 , -1.0 , 0.0 , 1.0 }; //попробуйте float data[] = {0.0, 1.0, 0.0, -1.0, -1.0, 0.0, 1.0, -1.0, 0.0}; если вышеприведенное не работает. //Создаем новый VBO и используем переменную id для хранения идентификатора VBO glGenBuffers ( 1 , & triangleVBO ); //Делаем новый VBO активным glBindBuffer ( GL_ARRAY_BUFFER , triangleVBO ); //Загрузить данные вершин на видеоустройство glBufferData ( GL_ARRAY_BUFFER , sizeof ( data ), data , GL_STATIC_DRAW ); //Сделать новый VBO активным. Повторите здесь, если он изменился с момента инициализации glBindBuffer ( GL_ARRAY_BUFFER , triangleVBO ); // Рисуем треугольник из VBO — делаем это при каждом изменении временного окна, точки обзора или данных // Устанавливаем его 3 координаты на вершину с нулевым шагом в этом массиве; здесь необходимо glVertexPointer ( 3 , GL_FLOAT , 0 , NULL ); //Создать массив, содержащий вершины (не нормали, цвета, текстурные координаты и т. д.) glEnableClientState ( GL_VERTEX_ARRAY );//Фактически рисуем треугольник, задавая указанное количество вершин glDrawArrays ( GL_TRIANGLES , 0 , sizeof ( data ) / sizeof ( float ) / 3 ); //Принудительно отрисовываем дисплей сейчас glFlush ();
Вершинный шейдер:
/*----------------- "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 мы используем.precision highp float ; // Драйверам видеокарты эта строка необходима для правильной работы из vec4 fragColor ; void main () { fragColor = vec4 ( 1.0 , 1.0 , 1.0 , 1.0 ); //Установить цвет каждого фрагмента на БЕЛЫЙ } /*---------------------------------------------------------------*/
Основная программа OpenGL:
/*--------------------- Основная программа OpenGL ---------------------*//* Создаем переменную для хранения идентификатора VBO */ GLuint triangleVBO ; /* Это дескриптор программы шейдера */ 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 и использование переменной "triangleVBO" для хранения идентификатора VBO */ glGenBuffers ( 1 , & triangleVBO ); /* Делаем новый VBO активным */ glBindBuffer ( GL_ARRAY_BUFFER , triangleVBO ); /* Загрузка данных вершин на видеоустройство */ 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 , triangleVBO ); /*-------------------------------------------------------------------------------------------------------*/ /*--------------------- Загружаем вершинные и фрагментные шейдеры из файлов и компилируем их --------------------*/ /* Считываем наши шейдеры в соответствующие буферы */ 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 ); free ( fragmentSource );/* Компилируем наши шейдерные объекты */ glCompileShader ( vertexShader ); glCompileShader ( fragmentShader ) ; /*-------------------------------------------------------------------------------------------------------*//*-------------------- Создаем шейдерную программу, присоединяем к ней шейдеры и затем связываем ее ---------------------*/ /* Назначаем нашему дескриптору программы «имя» */ shaderProgram = glCreateProgram (); /* Присоединяем наши шейдеры к нашей программе */ glAttachShader ( shaderProgram , vertexShader ); glAttachShader ( shaderProgram , fragmentShader ); /* Привязать индекс атрибута 0 (shaderAttribute) к in_Position*/ /* "in_Position" будет представлять содержимое массива "data" в вершинном шейдере */ 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 )); /*--------------------------------------------------------------*/
{{cite web}}
: CS1 maint: бот: исходный статус URL неизвестен ( ссылка )