OpenGL полупрозрачная текстура поверх другой текстуры - PullRequest
7 голосов
/ 02 июля 2010

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

Какие-нибудь советы, как этого добиться?

Следующие 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);

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

Edit:

Дополнительный код:

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 ]

7 голосов
/ 02 июля 2010
glTexImage2D( GL_TEXTURE_2D, 0, 3, t.width(), t.height(), 0, GL_RGBA, GL_UNSIGNED_BYTE, t.bits() );

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

4 голосов
/ 02 июля 2010

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

Как насчет

glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_BLEND)

или

glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE)?

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

3 голосов
/ 02 июля 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).Если вы этого не сделаете, вы получите уродливые артефакты.(как на скриншоте).

...