OpenGL исчезают проблемы

Это то, что я делаю:

  • Визуализируйте первое изображение, используя цвет: glColor4f(1.0, 1.0, 1.0, 1.0);
  • Визуализируйте второе изображение, используя цвет: glColor4f(1.0, 1.0, 1.0, calc);, calc это число, которое изменяется от 0,0 до 1,0 в течение секунды, и я могу убедиться, что оно действительно делает это.

Я ожидаю, что это будет переходить от одного изображения к другому, и он делает это, но на полпути, он переходит в некоторый оттенок серого (черный цвет фона, кстати). Вы можете увидеть проблему здесь: http://www.youtube.com/watch?v=8dZXiYIM43s&Функция = youtu.be .

Я просто хочу, чтобы основные исчезли, БЕЗ сероватый тон в середине затухания (самый сильный при непрозрачности 0,5). Я пытался сделать это с GIMP, нижний слой непрозрачный, верхний слой с переменной непрозрачностью, и он работает нормально, он делает именно так что я хочу сделать, я просто не знаю, почему мой код (или OpenGL) не будет делать то же самое. Видео, демонстрирующее, что я имею в виду: http://www.youtube.com/watch?v=Ym-VPu9hhjQ&Функция = youtu.be

РЕДАКТИРОВАТЬ: После небольшого количества экспериментов (изменение цвета фона на красный), при 0,5, он становится полупрозрачным, что обычно является желаемым эффектом, за исключением того, что И ТО И ДРУГОЕ текстуры полупрозрачные (не только сверху). Почему это происходит ??

Вот код:

void Sprite::render_single(Image* image, Pos2D pos, Angle angle) {
int cx = image->width / 2;
int cy = image->height / 2;
glPushMatrix();
glTranslatef(pos.x + cx, pos.y + cy, 0);
glRotatef(angle.to_degrees(), 0.0, 0.0, 1.0);
glTranslatef(-cx, -cy, 0);
image->bind();
glBegin(GL_QUADS);
glTexCoord2f(0.0, 0.0);
glVertex2f(0.0, 0.0);
glTexCoord2f(1.0, 0.0);
glVertex2f(image->width, 0.0);
glTexCoord2f(1.0, 1.0);
glVertex2f(image->width, image->height);
glTexCoord2f(0.0, 1.0);
glVertex2f(0.0, image->height);
glEnd();
image->unbind();
glPopMatrix();
}

void Sprite::render(Pos2D pos, Angle angle) {
Image* img = this->get_current_frame();
if (this->images.size() == 1) {
this->render_single(img, pos, angle);
return;
}
double calc = (((double)this->current_frame_overflow) / this->frame_length);
std::cout << calc << std::endl;
glPushMatrix();
glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
this->render_single(img, pos, angle);
img = this->get_next_frame();
glColor4f(1.0f, 1.0f, 1.0f, calc);
this->render_single(img, pos, angle);
glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
glPopMatrix();
}

Используемая функция смешивания: glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

Функция инициализации OpenGL:

/**
* @brief Initializes OpenGL
*/
void Game::init_gl() {
float width = this->display->w;
float height = this->display->h;
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(0.0, width, height, 0.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glDisable(GL_DEPTH_TEST);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
}

Кроме того, вот весь исходный код для основного цикла (который содержит большую часть OpenGL): https://github.com/MiJyn/dbab/blob/master/src/game.cpp . И спрайт https://github.com/MiJyn/dbab/blob/master/src/sprite.cpp .

1

Решение

Когда вы используете glBlendFunc Функция (с включенным смешиванием) те же факторы используются для расчета альфа-значения целевого фрагмента.

Это имеет значение только в том случае, если вы визуализируете текстуру с альфа-каналом и впоследствии используете эту текстуру с включенным смешиванием. В этом случае альфа-канал визуализированной текстуры заканчивается значениями от нуля до единицы. Это заставляет некоторые фоны просачиваться, когда текстура выводится в задний буфер.

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

1

Другие решения

Серая окантовка является побочным эффектом не использования предварительно умноженной альфы.

Попробуйте использовать glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); включить предварительно умноженную альфу. Посмотрите предварительное умножение для получения дополнительной информации, но в основном все ваши текстуры и цвета должны быть предварительно умножены. Короче говоря, вы просматриваете каждый пиксель и цвет и умножаете r, g и b на a. Таким образом, если бы у вас было 50% белого как (1, 1, 1, 0,5), теперь оно становится (0,5, 0,5, 0,5, 0,5). В этом случае ваш целевой цвет также должен быть (calc, calc, calc, calc).

0

По вопросам рекламы [email protected]