简体   繁体   English

ALLEGRO5 根据背景更改文本的像素颜色

[英]ALLEGRO5 change pixel color of text based on background

First attempt:第一次尝试:

void Tower::_DrawHealthBarText(std::string text, int x, int y, ALLEGRO_FONT* font)
{
    al_set_new_bitmap_flags(ALLEGRO_MEMORY_BITMAP);
    ALLEGRO_BITMAP* bmp = al_create_bitmap(196, 17);
    int bmpIndex[196][17] = { };

    al_set_target_bitmap(bmp);
    al_draw_rectangle(5, 20, 200, 20 + 15, al_map_rgb(255, 255, 255), 1.0f);
    al_draw_filled_rectangle(5, 20, 5 - 195.0f + ((195.0f / _player->playerMaxHealth) * _player->playerHealth) + 195.0f, 20 + 15, al_map_rgb(255, 255, 255));
    al_draw_filled_rectangle(4, 19, 201, 20 + 15 + 1, al_map_rgb(0, 0, 0));

    for (int x = 0; x < 196; x++)
    {
        for (int y = 0; y < 17; y++)
        {
            unsigned char r, g, b;
            al_unmap_rgb(al_get_pixel(bmp, x, y), &r, &g, &b);
            if ((r + g + b) / 3 == 255)
            {
                bmpIndex[x][y] = 0;
            }
            else if ((r + g + b) / 3 == 0)
            {
                bmpIndex[x][y] = 1;
            }
        }
    }
    // Clear to transparent background
    al_clear_to_color(rgba(0, 0, 0, 0));

    al_draw_text(getFont(12), al_map_rgb(255, 255, 255), 0, 0, 0, text.c_str());

    al_set_new_bitmap_flags(ALLEGRO_VIDEO_BITMAP);
    al_set_target_backbuffer(g_Window);
    al_draw_bitmap(bmp, x, y, 0);

    al_destroy_bitmap(bmp);
}

Second attempt:第二次尝试:

int bmpIndex[196][17] = { };
void Tower::_DrawHealthBarText(std::string text, int _x, int _y, ALLEGRO_FONT* font)
{
    al_set_new_bitmap_flags(ALLEGRO_MEMORY_BITMAP);
    al_hold_bitmap_drawing(true);
    for (int x = 0; x < 196; x++)
    {
        for (int y = 0; y < 17; y++)
        {
            unsigned char r, g, b;
            al_unmap_rgb(al_get_pixel(al_get_backbuffer(g_Window), _x + x, _y + y), &r, &g, &b);
            if ((r + g + b) / 3 == 255)
            {
                bmpIndex[x][y] = 0;
            }
            else if ((r + g + b) / 3 == 0)
            {
                bmpIndex[x][y] = 1;
            }
        }
    }
    al_hold_bitmap_drawing(false);
    al_set_new_bitmap_flags(ALLEGRO_VIDEO_BITMAP);
}

I've googled and tried my own code as you can see above... However using this multi-leveled loop is very slow.正如您在上面看到的,我已经用谷歌搜索并尝试了我自己的代码......但是使用这个多级循环非常慢。 My thought was to use a shader but I haven't the slightest clue how to use them yet.我的想法是使用着色器,但我一点也不知道如何使用它们。

I want the text to change color based off the background of where the text is located...我希望文本根据文本所在位置的背景更改颜色...

Basically it's a health bar and I want to show the text ontop of the health bar and change colors based on the background... If the background is black, the corresponding pixels are changed to white.基本上它是一个健康栏,我想在健康栏上显示文本并根据背景更改 colors ... 如果背景为黑色,则相应的像素将更改为白色。 Subsequently if the background pixels are white, the pixels of the text change to black.随后,如果背景像素为白色,则文本的像素变为黑色。

like this: photoshop render concept像这样: photoshop 渲染概念

The simplest way is to use the clipping rectangle , a common feature of most graphics APIs.最简单的方法是使用剪切矩形,这是大多数图形 API 的共同特性。 When you set the clipping rectangle, nothing can be drawn outside of it.设置剪切矩形时,不能在其之外绘制任何内容。

  • First, set the clipping rectangle to cover the white part of the progress bar.首先,将剪切矩形设置为覆盖进度条的白色部分。 Draw your text in black.用黑色画出你的文字。
  • Then, set the clipping rectangle to cover the black part of the progress bar.然后,设置剪切矩形以覆盖进度条的黑色部分。 Draw your text in white, in the same position as it was drawn in black.用白色绘制你的文本,在相同的 position 中绘制为黑色。
int x = 0, y = 0;
int bar_width = 196, bar_height = 17;
int bar_position = static_cast<int>(
    bar_width * _player->playerHealth / _player->playerMaxHealth);

// Set the clipping rectangle so text only appears on the left
// side of the bar (which is white),
al_set_clipping_rectangle(x, y, bar_position, bar_height);

// Draw black text.
al_draw_text(getFont(12), al_map_rgb(0, 0, 0), x, y, 0, text.c_str());

// Set the clipping rectangle so text only appears on the right
// side of the bar (which is black).
al_set_clipping_rectangle(x + bar_position, y, bar_width - bar_position, bar_height);

// Draw white text in the same position as the black text.
al_draw_text(getFont(12), al_map_rgb(255, 255, 255), x, y, 0, text.c_str());

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM