【问题标题】:Creating a UINT32 from 4 floats从 4 个浮点数创建一个 UINT32
【发布时间】:2019-03-22 14:43:44
【问题描述】:

好的。

我正在使用用于 DirectX 的 FW1FontWrapper 代码

https://archive.codeplex.com/?p=fw1

这让我不再需要使用由纹理驱动的过时且无用的字体引擎。

但是,此 Wrapper 中的 DrawString 函数对颜色表示有特殊要求。

UINT32 Color : In the format 0xAaBbGgRr

我为此任务提供的数据是一个恒定的 Alpha 值:1.0f。

R、G 和 B 的 3 个可变浮点值,范围从 0.0f 到 1.0f。

鉴于 UNIT32 中颜色的特殊排列,我正在尝试编写一个函数,该函数将使用给定的 3 个浮点值创建这个 UNIT32。

我的尝试

UINT32 TextClassA::getColour(SentenceType* sentence)
{
    //Convert each float value to its percentage of 255
    int colorb = 255 * sentence->blue;
    int colorg = 255 * sentence->green;
    int colorr = 255 * sentence->red;

    //convert each int to 8 bit Hex
    UINT8 ucolorb = colorb;
    UINT8 ucolorg = colorg;
    UINT8 ucolorr = colorr;

    //Push each hex back onto a UNIT32
    UINT32 color = 0xFF + (ucolorb << 6) + (ucolorg << 4) + (ucolorr << 2);

    return color;
}

句子类型

对于 0.0-1.0f 的每个 RGB 值,红色、绿色和蓝色只是浮点数

我的想法。

我大概可以:

  1. 将每个浮点值转换为其 255 的百分比(不要太担心完美的准确性。

  2. 将这些整数值转换为 UINT8s

  3. 然后将它们推回 UINT32

【问题讨论】:

  • 这个问题似乎错过了一个实际问题。为什么它不起作用:&lt;&lt;6 是 6 位移位,当您需要 16 位移位时; &lt;&lt;4 应该是 &lt;&lt;8&lt;&lt;2 根本不应该移动。如果您仍在为十六进制数字 (4) 中的位数或从哪里开始计数 (0) 苦苦挣扎,您似乎有点过头了。
  • 啊,是的!当我让它工作但颜色值关闭时,我也在我的解决方案中意识到了这一点!这是我第一次真正搞砸位移,所以我的逻辑基于我的逻辑

标签: c++ text directx


【解决方案1】:

通过避免所有临时变量并使用类似下面的代码,可以使实现更清晰。也就是说,任何合理的优化编译器都应该在这两种情况下生成相同的代码。

UINT32 TextClassA::getColour(SentenceType* sentence)
{
    //Convert color components to value between 0 and 255.
    UINT32 r = 255 * sentence->red;
    UINT32 b = 255 * sentence->blue;
    UINT32 g = 255 * sentence->green;

    //Combine the color components in a single value of the form 0xAaBbGgRr
    return 0xFF000000 | r | (b << 16) | (g << 8);
}

【讨论】:

  • 错字:return color 应该被删除。
  • @MichaelSurette 谢谢。
  • 更干净!感谢您的评论!
【解决方案2】:

我想通了!!!

UINT32 TextClassA::getColour(SentenceType* sentence)
{
    //Convert each float value to its percentage of 255
    int colorb = 255 * sentence->blue;
    int colorg = 255 * sentence->green;
    int colorr = 255 * sentence->red;

    //convert each int to 8 bit Hex
    UINT8 ucolorb = 0x00 + colorb;
    UINT8 ucolorg = 0x00 + colorg;
    UINT8 ucolorr = 0x00 + colorr;

    //Convert each UINT8 to a UINT32
    UINT32 u32colorb = ucolorb;
    UINT32 u32colorg = ucolorg;
    UINT32 u32colorr = ucolorr;

    //Create final UINT32s and push the converted UINT8s back onto each.
    UINT32 u32finalcolorb = 0x00000000 | (u32colorb << 16);
    UINT32 u32finalcolorg = 0x00000000 | (u32colorg << 8);
    UINT32 u32finalcolorr = 0x00000000 | (u32colorr);

    //0xAaBbGgRr
    //Push each hex back onto a UNIT32
    UINT32 color = 0xFF000000 | u32finalcolorb | u32finalcolorg | 
        u32finalcolorr;

    return color;
}

我的错误

...我相信,是试图将 UINT8 向后推,导致溢出,所以我需要先转换为 UINT32。

【讨论】:

  • 请仅使用发布答案按钮获取实际答案。您应该修改原始问题以添加更多信息。
  • 我将您的解决方案从问题移至您的答案。请发布它作为下次开始的答案。此外,如果您有一个新问题(在您询问此代码是否可以针对速度进行优化的问题的解决方案下),请将其作为一个单独的问题提出。 (这个未来的问题更适合codereview.stackexchange.com
  • @Johan 我试图这样做,但是我必须等待两天才能将我的答案设置为解决方案。
  • @HolyBlackCat 感谢您的管理工作。关于你的不同点,有时我认为代码过于分散,对于这样一个小问题,寻找答案的人会发现在与问题相同的地方看到解决方案更方便。不过感谢您建议 CodeReview,我以后会记住这一点
猜你喜欢
  • 2020-06-23
  • 2011-03-23
  • 2011-04-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-02-10
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多