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

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

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

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

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 — это «средний план», фон сплошной черный.


person drahnr    schedule 02.07.2010    source источник
comment
Хорошо бы скриншоты с пояснениями.   -  person SigTerm    schedule 02.07.2010


Ответы (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 в этой позиции.

person Thomas    schedule 02.07.2010
comment
Я знал, что это какая-то глупость. Большое спасибо, это спасло мой день :) - person drahnr; 02.07.2010

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

Как насчет

glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_BLEND)

or

glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE)?

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

person Greg S    schedule 02.07.2010
comment
Это не сработало. Я попробовал glEnable(GL_ALPHA_TEST); glAlphaFunc(GL_GREATER, 0.1f); но без изменений. GL_MODULATE ничего не изменил, GL_BLEND изменил цвет, но рамка вокруг моего объекта осталась. - person drahnr; 02.07.2010
comment
Это было очень полезно для меня. Используя BB, когда я включил альфа-тест и использовал GL_GREATER, это сработало как шарм. - person bobobobo; 16.11.2010

Если вы визуализируете одну текстуру для каждого объекта, вам нужно использовать 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). Если вы этого не сделаете, то получите уродливые артефакты. (как на вашем скриншоте).

person SigTerm    schedule 02.07.2010
comment
Это показывает основные текстуры? Пока это работает и для меня, но моя проблема в том, что я хочу видеть другой объект текстуры помимо того, который я рисую. Но вместо этого я получаю цвет фона (черный). Скриншот: img824.imageshack.us/img824/1912/blackbox.png - person drahnr; 02.07.2010
comment
@ soxs060389: я обновил свой ответ. Вы должны СНАЧАЛА рендерить землю, а ПОСЛЕ ЭТОГО рендерить машину. Это не сработает, если вы сделаете это в обратном порядке. - person SigTerm; 02.07.2010
comment
Я делал это с часа zer0. Автомобиль есть и всегда был последним элементом, который нужно было отрендерить. - person drahnr; 02.07.2010
comment
@ soxs060389: тогда он был загружен без альфа-канала. Когда я ответил, кода загрузки текстур здесь не было. - person SigTerm; 02.07.2010
comment
Я знаю, тем не менее я ценю вашу помощь. Я совершенно новичок в OpenGL Blending/Textures и т.п. - person drahnr; 03.07.2010