Прозрачные текстуры в OpenGL не заменяют четырехъядерный альфа - PullRequest
0 голосов
/ 05 января 2011

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

// Setup
glEnable(GL_DEPTH_TEST);
glEnable(GL_TEXTURE_2D);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);

// (...)
// Get image bits in object 't'
glBindTexture(GL_TEXTURE_2D, textureIDs[idx]); 
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
glTexImage2D(GL_TEXTURE_2D, 0, 3, t.width(), t.height(), 0, GL_RGBA, GL_UNSIGNED_BYTE, t.bits());
// (...)

glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);

// Underlying coloured quad
glColor4d(0.0, 1.0, 0.0, 1.0);    
glBindTexture(GL_TEXTURE_2D, 0); 
glBegin(GL_QUADS);
  glVertex3d(coords11.first, coords11.second, -0.001);
  glVertex3d(coords12.first, coords12.second, -0.001);
  glVertex3d(coords21.first, coords21.second, -0.001);
  glVertex3d(coords22.first, coords22.second, -0.001);
glEnd();

// Textured quad    
glColor4d(1.0, 1.0, 1.0, 0.5);
glBindTexture(GL_TEXTURE_2D, textureIDs[castleTextureIndices[0]]); 
glBegin(GL_QUADS);
  glTexCoord2d(0.0, 0.0); glVertex3d(coords11.first, coords11.second, 0);
  glTexCoord2d(1.0, 0.0); glVertex3d(coords12.first, coords12.second, 0);
  glTexCoord2d(1.0, 1.0); glVertex3d(coords21.first, coords21.second, 0);
  glTexCoord2d(0.0, 1.0); glVertex3d(coords22.first, coords22.second, 0);
glEnd();

Текстура черного цвета, кроме тех, где она имеет контур замка; эта часть прозрачна (и белая). Следовательно, ожидаемое поведение - это черный прямоугольник с зеленым контуром. Вместо этого я получаю зеленоватый прямоугольник с белым контуром:

Скриншот

Это с альфа на текстурированном квадре, установленном на 0,5. Если вместо этого я установлю его на 1,0, я вернусь к текстуре без прозрачности, как в (да ладно, я не могу опубликовать второй скриншот как ссылку; = вид и ток = replace10.png). С альфа 0 я получаю зеленый прямоугольник. Поэтому мне кажется, что текстурированный квадрат смешивается с использованием альфа-значения, установленного glColor4d, вместо значения из текстуры, чего я и ожидал от GL_REPLACE. (Я также экспериментировал с GL_DECAL и GL_MODULATE, но я не смог получить желаемое поведение.) Может кто-нибудь сказать мне, как заставить OpenGL использовать текстуру, а не квад, альфа для смешивания?

1 Ответ

9 голосов
/ 05 января 2011

Приготовьтесь к поездке по переулку памяти.

glTexImage2D(GL_TEXTURE_2D, 0, 3, ..., ..., 0, GL_RGBA, GL_UNSIGNED_BYTE, ...);

Это 3 в вашей проблеме. В правой части аргументов (RGBA + UNSIGNED_BYTE) указывается тип данных источника. тип данных destination является третьим аргументом (т.е. как GL будет хранить вашу текстуру как).

Как это случилось, когда GL 1.0 был создан, текстурирование было несколько проще. Таким образом, параметр требовался только для указания количества каналов, которые вы хотели получить для вашей окончательной текстуры, с отображением

1=GL_LUMINANCE
2=GL_LUMINANCE_ALPHA
3=GL_RGB
4=GL_RGBA

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

Итак ... Ваша текстура хранится как GL_RGB, без альфа.

Остальное - простое применение спецификации. Замена текстуры с внутренним форматом RGB делает final_color=texture_color и final_alpha=fragment_alpha (он же источник от glColor в вашем случае). См. эту справочную страницу с полными таблицами текстурного окружения на основе внутренних форматов.

...