Параметры glTexImage2D() и создание кадровых буферов
Согласно справочной странице 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 ответ
Независимо от того, является ли последний параметр NULL или нет (при условии, что PBO не используются), format
и type
параметры всегда должны быть допустимыми значениями относительно internalformat
параметр.
При этом не обязательно, чтобы передача пикселей format
а также type
параметры точно соответствуют internalformat
, Но они должны быть совместимы с ним в соответствии с правилами совместимости передачи пикселей. В конкретных случаях, которые вы цитируете, format
а также type
все значения совместимы с любым из internalforamt
S используется. Таким образом, вы могли бы теоретически сделать это:
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16F, SCR_WIDTH, SCR_HEIGHT, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);
При этом, вы не должны, по двум причинам:
Вы не должны писать код, который вы не хотите, чтобы он выполнялся по-настоящему. Наличие реализации ручного преобразования из беззнаковых нормализованных байтов в 16-разрядные числа с плавающей запятой снижает производительность. Даже если он на самом деле не будет выполнять это преобразование, потому что указатель равен NULL, вы все равно никогда не захотите, чтобы это произошло на самом деле. Так что напишите код, который имеет смысл.
Вы должны помнить все правила совместимости передачи пикселей. Потому что, если вы ошибаетесь, если вы запрашиваете нелегальное преобразование, вы получаете ошибку OpenGL и, следовательно, испорченный код. Если вы не привыкли всегда думать о том, что ваш
format
а такжеtype
параметры, это действительно легко переключиться на целочисленные текстуры и получить немедленную ошибку, потому что вы не использовали один из_INTEGER
форматы. Принимая во внимание, что если вы всегда думаете о параметрах передачи пикселей, которые представляютinternalformat
вы на самом деле используете, вы никогда не столкнетесь с этой ошибкой.