OpenGL: отключить цвета текстуры? - PullRequest
4 голосов
/ 22 марта 2010

Можно ли отключить цвета текстуры и использовать только белый в качестве цвета? Он по-прежнему будет читать текстуру, поэтому я не могу использовать glDisable (GL_TEXTURE_2D), потому что я тоже хочу рендерить альфа-каналы.

Все, что я могу думать сейчас, - это создать новую текстуру, в которой все данные о цвете будут белыми, а альфа останется такой, как есть.

Мне нужно сделать это без шейдеров , так это вообще возможно?

Редактировать: , чтобы уточнить: я хочу использовать обе текстуры: белые и нормальные цвета.

Редактировать: ВНЕ ЭТО НЕВОЗМОЖНО

Ответы [ 2 ]

5 голосов
/ 24 марта 2010

Я все еще не полностью уверен, что правильно понимаю, что вы хотите, но я сделаю попытку. Я имел в виду, что когда вы вызываете glTexImage2D, вы указываете формат загружаемых текселей и , вы указываете "внутренний формат" текстуры, которую вы создаете из этих текселей. В типичном случае вы указываете (примерно) один и тот же формат для обоих - например, вы обычно будете использовать GL_RGBA для обоих.

Существует причина для указания обоих: хотя format (параметр, близкий к концу списка) определяет формат загружаемых текселей из , но internal format (тот, что ближе к началу списка параметров) указывает формат для фактической текстуры, которую вы создаете из этих текселей.

Если вы хотите загрузить некоторые тексели, но только на самом деле использовать альфа-канал из них, вы можете указать GL_ALPHA для internal format, и это все, что вы получите - когда вы сопоставьте эту текстуру с поверхностью, это повлияет только на альфа, а не на цвет. Это не только позволяет избежать создания дополнительной копии ваших текселей, но (по крайней мере обычно) уменьшает объем памяти, потребляемой самой текстурой, поскольку она включает только альфа-канал, а не три цветовых канала.

Редактировать: Хорошо, подумав немного, есть способ сделать то, что (я думаю) вы хотите, используя только одну текстуру. Сначала вы устанавливаете функцию смешивания на использование только альфа-канала, затем, когда вы хотите скопировать цвет текстуры, вы вызываете glTextureEnvf с помощью GL_REPLACE, но когда вы хотите использовать только альфа-канал, вы вызываете его с GL_BLEND. Например, давайте создадим зеленую текстуру и нарисуем ее (дважды) поверх синего квадрата, один раз с GL_REPLACE и один с GL_BLEND. Для простоты мы будем использовать сплошную текстуру gree с альфа-увеличением линейно от вершины (0) до низа (1):

static GLubyte Image[128][128][4];

for (int i=0; i<128; i++)
    for (int j=0; j<128; j++) {
        Image[i][j][0] = 0;
        Image[i][j][1] = 255;
        Image[i][j][2] = 0;
        Image[i][j][3] = i;
    }

Я пропущу большую часть создания и связывания текстуры, установки параметров и т. Д., И сразу перейду к рисованию пары квадов с текстурой:

glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);

glBegin(GL_QUADS);
    glColor4f(0.0f, 0.0f, 1.0f, 1.0f);
    glTexCoord2f(0.0, 0.0); glVertex3f(-1.0f, 1.0f, 0.0f);
    glColor4f(0.0f, 0.0f, 1.0f, 1.0f);
    glTexCoord2f(1.0, 0.0); glVertex3f(0.0f, 1.0f, 0.0f);
    glColor4f(0.0f, 0.0f, 1.0f, 1.0f);
    glTexCoord2f(1.0, 1.0); glVertex3f(0.0f, -1.0f, 0.0f);
    glColor4f(0.0, 0.0f, 1.0f, 1.0f);
    glTexCoord2f(0.0, 1.0); glVertex3f(-1.0f, -1.0f, 0.0f);
glEnd();

glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_BLEND);

glBegin(GL_QUADS);
    glColor4f(0.0f, 0.0f, 1.0f, 1.0f);
    glTexCoord2f(0.0, 0.0); glVertex3f(0.0f, 1.0f, 0.0f);
    glColor4f(0.0f, 0.0f, 1.0f, 1.0f);
    glTexCoord2f(1.0, 0.0); glVertex3f(1.0f, 1.0f, 0.0f);
    glColor4f(0.0f, 0.0f, 1.0f, 1.0f);
    glTexCoord2f(1.0, 1.0); glVertex3f(1.0f, -1.0f, 0.0f);
    glColor4f(0.0, 0.0f, 1.0f, 1.0f);
    glTexCoord2f(0.0, 1.0); glVertex3f(0.0f, -1.0f, 0.0f);
glEnd();

Это производит:

Blended Textures

Итак, слева, где он рисуется с помощью GL_REPLACE, мы получаем зеленый цвет текстуры, но справа, где он рисуется с помощью GL_BLEND (а glBlendFunc был настроен на использование только альфа-канала), мы получаем синий квад, но с альфа-каналом, взятым из текстуры, - но мы используем одинаковую текстуру для обоих.

Редактировать 2: Если вы решите, что вам действительно нужна текстура белого цвета, я бы просто создал 1-пиксельную текстуру и установил GL_TEXTURE_WRAP_S и GL_TEXTURE_WRAP_T в GL_REPEAT. Даже при том, что для этого все еще используется дополнительная текстура, эта дополнительная текстура будет действительно крошечной, так как это всего один пиксель. И время его загрузки, и потребляемая память будут по-настоящему крошечными - данные для пикселя в основном "шумовые". Я не пробовал тестировать, но вам лучше использовать блок пикселей размером 8x8 или 16x16. Это все еще настолько мало, что вряд ли имеет значение, но это размеры, используемые в JPEG и MPEG соответственно, и я вижу, где карта и (особенно) драйвер могут быть оптимизированы для них. Это может помочь, и не повредит (достаточно, чтобы заботиться о любом случае).

1 голос
/ 22 марта 2010

Как насчет изменения всех цветов текстуры (кроме альфа) на белый после их загрузки и до их использования в OpenGL? Если в какой-то момент они хранятся в виде растровых изображений, это должно быть легко, и вам не понадобятся отдельные файлы текстур.

...