OpenGL SuperBible (6th Edition) / OpenGL Супер Книга (6-ое издание): Data

← →
Английский оригинал Перевод на русский

Сожалеем, но текст оригинала доступен только зарегистрированным пользователям.

Глава 5. Данные.
Что вы изучите в этой главе
Как создавать буферы и текстуры которые вы можете использоваться для хранения данных к которым получает доступ ваша программа
Как научить OpenGL передавать значение вершинных атрибутов автоматически
Как получить доступ к текстуре из шейдера для чтения и записи

alexm_notabenoid 18.08.14 в 18:35

0

В примерах, которые мы видели до сих пор, мы либо жёстко программировали данные в шейдерах либо мы передавали все значения за раз. Хотя этого достаточно для демонстрации работы конвейера OpenGL, вряд ли это показывает современное программирование графики. Современные графические процессоры спроектированы как потоковые процессоры которые принимают и вычисляют огромные массивы данных. Передача нескольких значений в OpenGL за один раз крайне неэффективно. Чтобы хранить данные и предоставить к ним доступ OpenGL мы вводим две основные формы хранения данных -- буферы и текстуры. В этой главе мы сначала введём буферы которые являются линейными блоками не типизированных данных которые можно считать generic memory allocations. Затем, мы введём текстуры которые обычно используются для хранения многомерных данных, таких как изображение или другие типы данных.

alexm_notabenoid 18.08.14 в 19:31

0

Буферы
В OpenGL буферы являются линейными данными ( linear allocations of memory ) которые можно использовать для различных целей. Они представлены именами которые являются непрозрачными ссылками ( opaque handles прим. пер. ) которые OpenGL использует для их идентификации. Прежде чем начать использовать буфер, вы должны попросить OpenGL зарезервировать имя для вас, затем использовать его для выделения памяти и для заполнения данными. Память выделяемая для буфера называется хранилищем данных.

alexm_notabenoid 18.08.14 в 19:58

0

Выделение памяти используя буферы
Функция которая используется для выделения памяти под буфер это glBufferData() прототип поторой

alexm_notabenoid 18.08.14 в 19:59

0

void glBufferData(GLenum target, GLsizeiptr size, const GLvoid * data, GLenum usage);

alexm_notabenoid 18.08.14 в 19:59

0

Параметр target говорит OpenGL под какой буфер вы хотите выделить память. Например, буфер который будет использоваться для хранения вершинных атрибутов называется GL_ARRAY_BUFFER. Возможно вы слышали термин вершинный буфер или юниформ буфер OpenGL, в отличии некоторых графических библиотек, на самом деле не назначает типы буферам -- буфер просто буфер и его можно использовать когда угодно и в любых целя ( и даже для нескольких задач если хотите ). Параметр size указывает OpenGL какого размера должен быть буфер и data является указателем на данные для буфера ( он может быть NULL если вы не хотите заполнять буфер сразу ). Наконец, usage говорит OpenGL как вы хотите использовать буфер. В Таблице 5.1 перечисленные возможные значения использования.

alexm_notabenoid 18.08.14 в 20:01

0

Таблица 5.1 Использование буфера
Листинг 5.1 показывает как резервировать имя с помощью glGenBuffers(), как присоединять к контексту используя glBingBuffer() и как выделяется под него вызовом glBufferData().

alexm_notabenoid 29.08.14 в 01:04

0

GLuint buffer;
//Создаём имя для буфера
glGenBuffers( 1, &buffer );
//Теперь присоединяем к контексту используя GL_ARRAY_BUFFER
glBingBuffer( GL_ARRAY_BUFFER, buffer );
//Укажем объём памяти который мы хотим использовать для буфера
glBufferData(GL_ARRAY_BUFFER, 1024 * 1024, NULL, GL_STATIC_DRAW);

alexm_notabenoid 29.08.14 в 01:07

0

После исполнения кода в Листинге 5.1, буфер содержит имя объекта буфера который был инициализирован для хранения 1 Мб данных для данных которые мы выберем. Использование GL_ARRAY_BUFFER подсказывает OpenGL что мы собираем использовать этот буфер для хранения вершинных данных, но мы сможем взять этот буфер и использовать для других целей. Есть несколько способов передачи данных в буфер. Вы возможно заметили что мы передали в качестве указателя NULL третьим аргументом функции glBufferData() в Листинге 5.1. Если бы мы передали данные в качестве указателя, то они бы использовались для инициализации буфера. Другой путь передачи данных в буфер это дать их OpenGL и сказать чтобы он их скопировал их в буфер. Чтобы сделать это мы вызываем glBufferSubData(), передавая size данных мы хотим их переместить в буфер, offset это смещение в буфере куда мы хотим их переместить и указатель на данные в памяти которые переместятся в буфер.

alexm_notabenoid 29.08.14 в 01:24

0

void glBufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid * data);

alexm_notabenoid 29.08.14 в 01:24

0

Листинг 5.2 показывает как мы можем поместить данные первоначально использовавшиеся в Листинге 3.1 в объект буфера, который является 1 шагом в автоматической подачи вершины шейдера в данных.

Lebedev_Ivan 26.09.14 в 17:20

0

Щелкните здесь для просмотра кода
// Данные, которые мы поместим в объект буфер
static const float data[] =
{
0.25, -0.25, 0.5, 1.0,
-0.25, -0.25, 0.5, 1.0,
0.25, 0.25, 0.5, 1.0
};
// Помещаем данные в буфер с нулевым смещением
glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(data), data);
Листинг 5.2: Обновление содержимого буфера с помощью glBufferSubData()

tnike 21.10.14 в 18:57

0

Другим методом получения данных в буфер может быть запрос у OpenGL указателя на область памяти, содержащую буфер и копирование туда данных.
Листинг 5.3 показывает, как это сделать с помощью функции glMapBuffer ().

tnike 21.10.14 в 19:03

0

Нажмите здесь, чтобы посмотреть код
// Данные, которые мы поместим в буфер
static const float data[] =
{
0.25, -0.25, 0.5, 1.0,
-0.25, -0.25, 0.5, 1.0,
0.25, 0.25, 0.5, 1.0
};
// Получаем указатель на место хранения буфера
void * ptr = glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY);
// Копируем туда наши данные
memcpy(ptr, data, sizeof(data));
// Сообщаем OpenGL, что мы закончили работу с указателем
glUnmapBuffer(GL_ARRAY_BUFFER);
Листинг 5.3: Маппинг хранилища буфера с помощью glMapBuffer ()

tnike 21.10.14 в 19:12

0

Заполнение и копирование данных в буферы.
После выделения места для хранения буфера с использованием glBufferData(), одним из возможных следующих шагов может быть заполнение буфера известными данными. Используете ли вы начальный параметр данных glBufferData(), glBufferSubData () для того чтобы поместить исходные данные в буфер, или glMapBuffer(), чтобы получить указатель на место хранения данных буфера и заполнения его с помощью вашего приложения, вам нужно переписать весь буфер целиком. Если данные, которые нужно поместить в буфер является постоянной величиной, гораздо более эффективным вероятно будет вызвать glClearBufferSubData(), прототипом которой является

tnike 26.10.14 в 13:35

0

void glClearBufferSubData(GLenum target,
GLenum internalformat,
GLintptr offset,
GLsizeiptr size,
GLenum format,
GLenum type,
const void * data);

tnike 26.10.14 в 13:35

0

Функция glClearBufferSubData () принимает указатель на переменную, содержащую значения, которыми вы хотите заполнить буфер и, после преобразования его в формат, указанный в internalformat, повторяет его по всей области, отведенной для буфера, определенной с помощью указанных размера и смещения, измеряемых в байтах. Формат и тип говорят OpenGL о данных, на которые указывают данные. Формат может быть одним из GL_RED, GL_RG, GL_RGB или GL_RGBA, определяя, к примеру, 1-, 2-, 3- или 4-канальные данные. Между тем, тип должен представлять тип данных компонентов. Например, это может быть GL_UNSIGNED_BYTE или GL_FLOAT для определения беззнаковых байт или данных с плавающей точкой. Наиболее распространенные типы, поддерживаемые OpenGL и соответствующие им типы данных в С приведены в таблице 5.2.

tnike 26.10.14 в 13:46

0

После того, как ваши данные были отправлены в GPU, вполне возможно, вы можете захотите распределить данные между буферами или скопировать результаты из одного буфера в другой. OpenGL предоставляет простой в использовании способ сделать это. glCopyBufferSubData () позволяет вам указать, какие буферы задействованы, а также размер и смещение.

tnike 26.10.14 в 13:51

0

void glCopyBufferSubData(GLenum readtarget,
GLenum writetarget,
GLintptr readoffset,
GLintptr writeoffset,
GLsizeiptr size);

tnike 26.10.14 в 13:51

0
Минутку...

Следующая страница →