Альфа-значение OpenGL делает текстуру белее? - PullRequest
4 голосов
/ 17 апреля 2009

Я пытаюсь загрузить текстуру со значениями RGBA, но альфа-значения просто делают текстуру более белой, а не регулируют прозрачность. Я слышал об этой проблеме с 3D-сценами, но я просто использую OpenGL для 2D. Можно ли как-нибудь это исправить?

Я инициализирую OpenGL с

glViewport(0, 0, winWidth, winHeight);
glDisable(GL_TEXTURE_2D);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glDisable(GL_DEPTH_TEST);
glClearColor(0, 0, 0, 0);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(0, winWidth, 0, winHeight); // set origin to bottom left corner
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glColor3f(1, 1, 1);

Скриншот: image Это размытое пятнистое изображение должно быть полупрозрачным. Черные биты должны быть полностью прозрачными. Как видите, позади него изображение, которое не просвечивает.

Код для генерации этой текстуры довольно длинный, поэтому я опишу, что я сделал. Это массив 40 * 30 * 4 типа unsigned char. Каждому 4-му символу присвоено значение 128 (должно быть прозрачным на 50%, верно?).

Затем я передаю его в эту функцию, загружаю данные в текстуру:

void Texture::Load(unsigned char* data, GLenum format) {
    glEnable(GL_TEXTURE_2D);
        glBindTexture(GL_TEXTURE_2D, _texID);
        glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, _w, _h, format, GL_UNSIGNED_BYTE, data);
    glDisable(GL_TEXTURE_2D);
}

И ... я думаю, что только что нашел проблему. Инициализировал полноразмерную текстуру с этим кодом:

glEnable(GL_TEXTURE_2D);
    glBindTexture(GL_TEXTURE_2D, _texID);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, tw, th, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, NULL);
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
glDisable(GL_TEXTURE_2D);

Но я думаю, что glTexImage2D тоже должен быть GL_RGBA? Я не могу использовать два разных внутренних формата? Или, по крайней мере, не разных размеров (3 байта против 4 байтов)? GL_BGR отлично работает, даже если его инициализировать так ...

Ответы [ 3 ]

4 голосов
/ 18 апреля 2009

В интересах других, я публикую свое решение здесь.

Проблема была в том, что хотя моя функция загрузки была правильной,

glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, _w, _h, GL_RGBA, GL_UNSIGNED_BYTE, data);

Я передавал GL_RGB этой функции

glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, tw, th, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, NULL);

Какой также должен указать правильное количество байтов (четыре). Насколько я понимаю, вы не можете использовать другое количество байтов для SubImage, хотя я думаю, что вы можете использовать другой формат, если он имеет одинаковое количество байтов (т.е. смешивает GL_RGB и GL_BGA все в порядке, но не GL_RGB и GL_RGBA).

1 голос
/ 17 апреля 2009

Есть ли в вашей сцене перекрывающиеся примитивы?

Вы знаете, что вы вызываете трехпараметрическую версию glColor, которая устанавливает альфа в 1.0, верно?

Было бы полезно, если бы вы могли опубликовать скриншот или иным образом описать, что происходит, например, когда вы рисуете два примитива с одинаковыми цветами и разными альфа-символами. Фактически, любой код, устраняющий проблему, может помочь.

Edit:

Я полагаю, что использование TexImage с GL_RGB (для internalformat , 3-й параметр) создает 3-компонентную текстуру без альфа или альфа-значений, неявно инициализированных в 1, независимо от того, какой тип предоставленные вами данные пикселей.

GL_BGR не является допустимым значением для этого параметра, возможно, оно обманывает вашу реализацию в использовании полного 4-байтового внутреннего формата? (Или 2-байтовый, согласно GL_LUMINANCE_ALPHA) Или вы имеете в виду передачу GL_BGR в функцию Texture :: Load (), которая на самом деле не должна отличаться от передачи GL_RGB?

0 голосов
/ 17 апреля 2009

Я думаю, что это должно работать, но предполагается, что изображение имеет альфа-канал. Если вы попытаетесь загрузить изображение без альфа-канала, вы получите исключение, иначе ваше приложение может аварийно завершить работу. Для изображений не альфа-канала используйте GL_RGB вместо GL_RGBA во втором параметре, непосредственно перед настройкой GL_UNSIGNED_BYTE.

void Texture::Load(unsigned char* data) {
  glEnable(GL_TEXTURE_2D);
    glBindTexture(GL_TEXTURE_2D, _texID);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tw, th, 0, GL_RGBA, GL_UNSIGNED_BYTE, data);
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
  glDisable(GL_TEXTURE_2D);
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...