OpenGL полупрозрачная текстура поверх другой текстуры

Я получил 2 PNG изображения, которые используются в качестве текстур в приложении OpenGL Qt/C++ 2D. Первый используется как своего рода "среднее" основание, а второй используется как "объект", визуализируемый "поверх" (Примечание: все они имеют одно и то же значение z-значения atm, я получаю желаемое поведение, отображая его в определенный порядок). Текстура "объект" частично полупрозрачна. Текстура "middleground" в основном цельная. Проблема в том, что полупрозрачная часть моей "объектной" текстуры делает сплошной цвет фона, а не текстуру "средней части".

Любые советы, как этого добиться?

Следующие OpenGL Falgs используются для рендеринга моих текстур

glEnable (GL_TEXTURE_2D);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
glEnable (GL_BLEND);
glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

Спасибо за любую помощь.

Редактировать:

Больше код:

glColor4f(1.0f, 1.0f, 1.0f, 1.0f);

glEnable(GL_DEPTH_TEST);
glDepthMask(GL_TRUE);

glEnable(GL_ALPHA_TEST);
glAlphaFunc(GL_GREATER, 0.1f);

glEnable(GL_TEXTURE_2D);
glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
glBindTexture(GL_TEXTURE_2D, c->_texture);

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

glBegin(GL_QUADS);
{
    glTexCoord2i(0,0);
    glVertex2i(-128,-128);

    glTexCoord2i(0,1);
    glVertex2i(-128,128);

    glTexCoord2i(1,1);
    glVertex2i(128,128);

    glTexCoord2i(1,0);
    glVertex2i(128,-128);

}
glEnd();

glDisable(GL_TEXTURE_2D);

glDisable(GL_ALPHA_TEST);
glDisable(GL_DEPTH_TEST);

Редактировать: Как я загружаю свою текстуру и насколько я могу сказать, она загружается с альфа-каналом

QImage img("./images/dummycar.png","PNG");
QImage t(QGLWidget::convertToGLFormat(img));
glGenTextures(1, &_texture);
glBindTexture(GL_TEXTURE_2D, _texture);
glTexImage2D( GL_TEXTURE_2D, 0, 3, t.width(), t.height(), 0, GL_RGBA, GL_UNSIGNED_BYTE, t.bits() );
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);

Снимок экрана: http://img824.imageshack.us/img824/1912/blackbox.png

Skyimage - это "середина", фон - сплошной черный.

3 ответа

Решение
glTexImage2D( GL_TEXTURE_2D, 0, 3, t.width(), t.height(), 0, GL_RGBA, GL_UNSIGNED_BYTE, t.bits() );

Вы указываете 3 каналы для internalFormatтак что это RGB, а не RGBA. Попробуйте использовать GL_RGBA в этом положении вместо

Вы пробовали возиться с glAlphaFunc? Вы можете использовать его, чтобы отказаться от рисования полупрозрачных частей текстуры вашего объекта на основе альфа-значения.

Как насчет либо

glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_BLEND)

или же

glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE)?

Надеюсь, это поможет.

Если вы визуализируете одну текстуру на объект, вам нужно использовать glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE).

Если текстура все еще имеет "коробку" вокруг нее даже после этого, то она была загружена без альфа-канала.

Это прекрасно работает для меня:

    glEnable(GL_BLEND);
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
    glBindTexture(GL_TEXTURE_2D, texture2->tex);
    glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
    glColor4f(0.5f, 1.0f, 0.5f, 0.5f);
    glBegin(GL_TRIANGLE_FAN);
    glTexCoord2f(0, 0);
    glVertex2f(x, y);
    glTexCoord2f(1, 0);
    glVertex2f(x + texture2->width, y);
    glTexCoord2f(1, 1);
    glVertex2f(x + texture2->width, y+ texture2->height);
    glTexCoord2f(0, 1);
    glVertex2f(x, y + texture2->height);
    glEnd();
    glDisable(GL_BLEND);

Полупрозрачная текстура, тонированная по последнему цвету.

Если "наличие рамки вокруг текстуры" не описывает вашу проблему, то вам нужно опубликовать скриншоты.

--РЕДАКТИРОВАТЬ--

Обновлены данные на основе вашего скриншота.

Вам нужно ПЕРВЫЙ отрендерить фон, а затем отрендерить автомобиль. Вы видите цвет фона, потому что даже если поверхность прозрачна, она заполняет z-буфер значениями, а поскольку фон находится ниже автомобиля, он становится невидимым.

Когда вы визуализируете полупрозрачные объекты, вы должны следовать этим правилам.

  1. Все непрозрачные объекты должны быть визуализированы перед полупрозрачными объектами. Всегда.

  2. Все прозрачные объекты должны быть визуализированы обратно переднему объекту. Самые дальние объекты должны отображаться первыми, ближайшие объекты - вторыми.

  3. Если рендеринг в обратном порядке не возможен (несортированные частицы со смесью GL_ADD), запись в буфер глубины должна быть отключена с помощью glDepthMask(GL_FALSE). Если вы этого не сделаете, вы получите уродливые артефакты. (как тот, что на скриншоте).

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