Это то, что я делаю:
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 .
Когда вы используете glBlendFunc
Функция (с включенным смешиванием) те же факторы используются для расчета альфа-значения целевого фрагмента.
Это имеет значение только в том случае, если вы визуализируете текстуру с альфа-каналом и впоследствии используете эту текстуру с включенным смешиванием. В этом случае альфа-канал визуализированной текстуры заканчивается значениями от нуля до единицы. Это заставляет некоторые фоны просачиваться, когда текстура выводится в задний буфер.
Решение состоит в том, чтобы просто отключить смешивание при рисовании полноэкранного четырехугольника. Также вы можете удалить канал из текстуры, если вы его не используете (используйте GL_RGB
вместо GL_RGBA
для внутреннего формата текстур).
Серая окантовка является побочным эффектом не использования предварительно умноженной альфы.
Попробуйте использовать 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).