Параметры 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 все значения совместимы с любым из internalforamtS используется. Таким образом, вы могли бы теоретически сделать это:

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 вы на самом деле используете, вы никогда не столкнетесь с этой ошибкой.

Другие вопросы по тегам