stringtranslate.com

Объект буфера вершин

Объект буфера вершин ( 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:

В OpenGL 1.4 :
glGenBuffersARB (размер_n, uint *buffers)
Генерирует новый VBO и возвращает его идентификационный номер как целое число без знака. Идентификатор 0 зарезервирован.
glBindBufferARB (целевой элемент enum, буфер uint)
Использовать ранее созданный буфер в качестве активного VBO.
glBufferDataARB (целевой элемент перечисления, размер sizeiptrARB, const void *data, использование перечисления)
Загрузите данные в активный VBO.
glDeleteBuffersARB (sizei n, const uint *buffers)
Удаляет указанное количество VBO из предоставленного массива или идентификатора VBO.
В OpenGL 2.1 , [3] OpenGL 3.x [4] и OpenGL 4.x : [5]
glGenBuffers (sizei n, uint *buffers)
Генерирует новый VBO и возвращает его идентификационный номер как целое число без знака. Идентификатор 0 зарезервирован.
glBindBuffer (целевой элемент enum, буфер uint)
Использовать ранее созданный буфер в качестве активного VBO.
glBufferData (целевой элемент перечисления, размер sizeiptrARB, const void *data, использование перечисления)
Загрузите данные в активный VBO.
glDeleteBuffers (sizei n, const uint *buffers)
Удаляет указанное количество VBO из предоставленного массива или идентификатора VBO.

Пример использования

На языке C, с использованием OpenGL 2.1

//Инициализация 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 ();

На языке 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 мы используем.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 )); /*--------------------------------------------------------------*/      

Ссылки

  1. ^ "GL_NV_vertex_array_range Whitepaper". Архивировано из оригинала 2004-08-17 . Получено 2024-06-24 .{{cite web}}: CS1 maint: бот: исходный статус URL неизвестен ( ссылка )
  2. ^ "ATI_vertex_array_object". Архивировано из оригинала 2012-07-04 . Получено 2011-08-12 .
  3. ^ «Справочник функций OpenGL 2.1».
  4. ^ «Справочник функций OpenGL 3.3».
  5. ^ «Справочник функций OpenGL 4.2».

Внешние ссылки