【问题标题】:OpenGL fade issueOpenGL淡入淡出问题
【发布时间】:2013-05-15 03:28:21
【问题描述】:

这就是我正在做的:

  • 使用以下颜色渲染第一张图像: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&feature=youtu.be

我只想要基本的褪色,没有在褪色过程中的灰色调(不透明度为 0.5 时最强)。我试过用 GIMP 做这个,底层是不透明的,顶层是可变不透明度的,它工作正常,它正是我想要它做的,我只是不知道为什么我的代码(或OpenGL)不会做同样的事情。演示我的意思的视频:http://www.youtube.com/watch?v=Ym-VPu9hhjQ&feature=youtu.be

编辑:经过一些实验(将背景颜色更改为红色),在 0.5 时,它变为半透明,这通常是想要的效果,除了 BOTH 纹理是半透明的(不仅仅是顶部的那个)。为什么会这样??

代码如下:

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

【问题讨论】:

  • 他们的视频有帮助,但我们不知道您实际上想做什么。它应该是什么样子?
  • @Trax,谢谢,我知道有些东西我忘记了...我在帖子中添加了它:)
  • 你试过混合(ONE,ONE_MINUS_SRC_ALPHA)吗?这是图像编辑器默认执行的操作,即“总和”两个图层(背景为不透明 + 顶部半透明)。
  • @Trax,是的,但是它开始看起来真的奇怪(整个游戏都这样,虽然我没有问题,但它似乎分层或什么的。 .. 这很奇怪)... 使用 GL_SRC_ALPHA 而不是 GL_ONE 可以正常工作,但我的问题仍然存在
  • 我的错,我刚醒来,它是 (GL_SRC_ALPHA, GL_ONE),但是使用后你应该回到之前的设置,否则这个混合功能会在你所有的对象中使用。跨度>

标签: c++ opengl fade


【解决方案1】:

当您使用glBlendFunc 函数(启用混合)时,使用相同的因子来计算目标片段的 alpha 值。

这仅在您渲染到具有 Alpha 通道的纹理并随后使用启用了混合的纹理时才有意义。在这种情况下,渲染纹理的 Alpha 通道最终值介于 0 和 1 之间。当纹理被绘制到后台缓冲区时,这会导致一些背景渗出。

解决方案只是在绘制全屏四边形时禁用混合。此外,如果您不使用通道,不妨从纹理中移除通道(使用GL_RGB 而不是GL_RGBA 用于内部纹理格式)。

【讨论】:

    【解决方案2】:

    灰边是不使用预乘 alpha 的副作用。

    尝试使用 glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); 启用预乘 alpha。查看预乘以获取更多信息,但基本上所有纹理和颜色都需要预乘。简而言之,您遍历每个像素和颜色,然后将 r、g 和 b 乘以 a。因此,当您将 50% 的白色设为 (1, 1, 1, 0.5) 时,它现在变为 (0.5, 0.5, 0.5, 0.5)。在这种情况下,您的目标颜色也需要是 (calc, calc, calc, calc)。

    【讨论】:

    • 我试过这个,但随后出现了不同的效果。起初,纹理变得异常明亮,最后,它终于恢复到正常亮度。我尝试在函数之前和中间使用调用(在渲染第一个之后)
    • 另外,还有一个问题: (0.5, 0.5, 0.5, 0.5) 不会比 (1.0, 1.0, 1.0, 0.5) 更透明吗?还是我没有正确理解你?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-04-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多