Параметры glTexImage2D () и создание кадровых буферов - PullRequest
0 голосов
/ 09 сентября 2018

Согласно справочной странице opengl, структура glTexImage2D выглядит следующим образом:

void glTexImage2D(  GLenum target,
    GLint level,
    GLint internalformat,
    GLsizei width,
    GLsizei height,
    GLint border,
    GLenum format,
    GLenum type,
    const GLvoid * data);

Насколько я знаю, последние 3 параметра - это то, как функция должна интерпретировать данные изображения, заданные как const GLvoid * data

Тем временем я изучал тему кадровых буферов. А в разделе «Кадровые буферы с плавающей точкой» этой ссылки https://learnopengl.com/Advanced-Lighting/HDR, автор создает цветовое вложение кадрового буфера, как это

glBindTexture(GL_TEXTURE_2D, colorBuffer);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16F, SCR_WIDTH, SCR_HEIGHT, 0, GL_RGBA, GL_FLOAT, NULL);

У меня вопрос: почему он дал GL_FLOAT в качестве параметра для GLenum type? Если const GLvoid * data равно NULL, нужно ли использовать GL_FLOAT? Сначала я подумал, что это что-то, связанное с GL_RGBA16F, но 16 бит - это 2 байта, а число с плавающей запятой - 4 байта, поэтому я думаю, что это вообще не связано.

Кроме того, до этого урока писатель делал цветовые вложения вроде этого:

glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, SCR_WIDTH, SCR_HEIGHT, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);

В этом случае, почему он использовал GL_UNSIGNED_BYTE для параметра GLenum type?

1 Ответ

0 голосов
/ 09 сентября 2018

Независимо от того, является ли последний параметр NULL или нет (при условии, что PBO не используются), параметры format и type всегда должны быть допустимыми значениями относительно параметра internalformat.

При этом не обязательно, чтобы параметры передачи пикселей format и type точно соответствовали internalformat. Но они должны быть совместимыми с ним, в соответствии с правилами совместимости передачи пикселей . В конкретных случаях, которые вы цитируете, все значения format и type совместимы с любым из используемых internalforamt. Таким образом, вы могли бы теоретически сделать это:

glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16F, SCR_WIDTH, SCR_HEIGHT, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);

Как говорится, вы не должны по двум причинам:

  1. Вы не должны писать код, который вы не хотите, чтобы он выполнялся по-настоящему. Реализация вручную преобразованного из беззнаковых нормализованных байтов в 16-разрядные числа с плавающей запятой снижает производительность. Даже если он на самом деле не будет выполнять это преобразование, потому что указатель равен NULL, вы все равно никогда не захотите, чтобы это произошло на самом деле. Поэтому напишите код, который имеет смысл.

  2. Вы должны помнить все правила совместимости передачи пикселей. Потому что если вы получите их неправильно , если вы запросите нелегальное преобразование, вы получите ошибку OpenGL и, следовательно, испорченный код. Если вы не привыкли всегда думать о параметрах format и type, то действительно легко переключиться на целочисленные текстуры и получить немедленную ошибку, потому что вы не использовали один из форматов _INTEGER. Принимая во внимание, что если вы всегда думаете о параметрах передачи пикселей, которые представляют internalformat, которые вы фактически используете, вы никогда не столкнетесь с этой ошибкой.

...