【问题标题】:How to Convert D3DCOLORVALUE to delphi tcolor如何将 D3DCOLORVALUE 转换为 delphi tcolor
【发布时间】:2018-06-10 23:37:43
【问题描述】:

我有一个整数列表,通过 C++ 代码获得,代表不同的 D3DCOLORVALUE 环境等...

在 Delphi 中,从这个数字获得相同颜色的正确方法是什么?

例如,使用 C++ (Visual Studio 2012) 中的程序,通过调用 C++ 中的库例程(单独的 dll 文件),我可以获得以下值:

-1.44852785e-016 = 2770796799 (represent the color)
 1.57844226e+11  = 1376977151 (represent the color)
-1.98938735e+034 = 4168431103 (represent the color)
 3.39617733e+038 = 4294967295 (represent the color)

@Rudy Velthuis,原代码为:(数组中包含的一些值如上所示)

int32_t index = ifcObject->indicesForFaces[0];

uint32_t    ambient  = ((int32_t*) vertices)[index * (vertexElementSize / sizeof(float)) + 6],
            diffuse  = ((int32_t*) vertices)[index * (vertexElementSize / sizeof(float)) + 7],
            emissive = ((int32_t*) vertices)[index * (vertexElementSize / sizeof(float)) + 8],
            specular = ((int32_t*) vertices)[index * (vertexElementSize / sizeof(float)) + 9];

然后在Delphi XE6中使用

PInteger (@ColorsArray [index * sizeOfVertices + 6])^

我得到相同的值,但在 delphi 中,颜色是黑色或空值。有时会得到负数,理解为在C++中可以用负值表示颜色,但在delphi中不行。

如何将以 D3DCOLORVALUE 格式获得的颜色值转换为 Delphi 的 TColor?

这些值用于获取对象的颜色 D3DMATERIAL9, D3DCOLORVALUE Ambient(环境色 RGB)

FLOAT r;
FLOAT g;
FLOAT b;
FLOAT a;

这个函数使颜色:

void    SetColor(
                D3DCOLORVALUE   * iColor,
                uint32_t        color
            )
{
    iColor->r = (float) (color & ((unsigned int) 255 * 256 * 256 * 256)) / (256 * 256 * 256);
    iColor->r /= 255.f;

    iColor->g = (float) (color & (255 * 256 * 256)) / (256 * 256);
    iColor->g /= 255.f;

    iColor->b = (float) (color & (255 * 256)) / 256;
    iColor->b /= 255.f;

    iColor->a = (float) (color & (255));
    iColor->a /= 255.f;
}

但是在Delphi中不行,得到的颜色是错误的。

颜色与@Dsm 解决方案的比较:

左:得到的颜色右:想要的颜色

我做了一个简单的例子来说明差异:

第一种颜色对应于柱脚,第二种颜色对应于柱子。带有平台的图是带有库查看器的示例,该版本具有正确的颜色,右图是 Visual Studio 2012 中手表的图像,以显示数组的内容和值相同使用 cast 获得的结果也是相同的,但是当将这些数字转换为颜色时,它们不会给出相同的结果。

【问题讨论】:

  • C++ 标准库不包含任何与图形相关的东西,因此它没有颜色的概念。您使用什么库来获取值?
  • 将浮点值转换为int32_t *(IOW,转换为指针!)非常可疑。到底是谁写了这段代码?
  • 来自Lights and Materials (Direct3D 9)Ambient light color takes the form of an RGBA value, where each component is an integer value from 0 to 255. This is unlike most color values in Direct3D.
  • 如果那是你的原始代码,你为什么不把它发布到 int32* 上,而不是奇怪的、可能是错误的转换?原始代码将指针转换为指针,假设 vertices 是一个数组,而不是指向指针的浮点数。
  • @LURD:这些是命名的颜色。但是 R、G 和 B 的任意组合都是可能的。

标签: c++ delphi tcolor


【解决方案1】:

这看起来就像原始 C++ 提取颜色时非常了解记录数组的内部结构。在您的代码中,您不应该使用 (int32_t*),因为这会创建一个指向常量的指针,而您只想将浮点数转换为 uint_32_t,所以我认为您想要满足测试代码的只是

ambient := uint32_t(-1.44852785e-016);
diffuse := uint32_t(1.57844226e+11);
etc;

这在 Delphi 中无法编译(无效类型转换),因此您需要执行类似的操作

var
  p : pointer;
  iFloat : single;
  iColour : TColor;
begin
  iFloat := 1.57844226e+11;
  p := @(iFloat);
  iColour := TColor(p^);
  diffuse := iColour;

end;

呈现红色。

请注意,您的所有颜色看起来都相似,因为您使用了几个相似地址的开头。

表示为一个可能变成的函数

function FloatToColor( const pVal : single ) : TColor;
var
  p : pointer;
  iFloat : single;
begin
  iFloat := 1.57844226e+11;
  p := @(iFloat);
  Result := TColor(p^);
end;

编辑

基于 $FF 出现在错误位置的事实,我想到这些值可能是 CMYK 格式。在测试中,我发现它是一种修改过的 CMYK 格式——如果你愿意的话,它更像是一种 YMCK 格式,所以为了获得正确的颜色,我必须颠倒红色和蓝色的角色。

没有真正的从 CMYK 到 RGB 的转换,但以下是近似值。

function CMYKtoRGB( const pValue : TColor) : TColor;
var
  c,m,y,k,r,g,b : byte;
begin
  c := GetCValue( pValue );
  m := GetMValue( pValue );
  y := GetYValue( pValue );
  k := GetKValue( pValue );

  //r := $FF xor c;
  r := $FF - c;
  b := $FF - y;
  g := $FF - m;
  if k <> $FF then
  begin
    k := $FF - k;
    r := r * k;
    g := g * k;
    b := b * k;
  end;
  Result := RGB( b, g, r );
end;

function FloatToColor( const pVal : single ) : TColor;
var
  p : pointer;
  iFloat : single;
begin
  iFloat := pVal;
  p := @(iFloat);
  Result := CMYKtoRGB(TColor(p^));
end;

请注意,我使用 RGB(b,g,r) 而不是预期的 RGB(r,g,b) 来解释反转的颜色顺序。

【讨论】:

  • 关闭,但我不断收到 10 位整数值,颜色错误,还有负值。
  • 您期望每个值的颜色是什么? Rudy 建议将十六进制反转,但我不认为它那么简单..
  • 上述左边的值是数组中包含的一些值,右边的值是在 C++ 中强制转换的值。当颜色应该是橙色时使用你的技术,你会得到粉红色到紫红色。右边的每个值都通过 SetColor 函数传递一些引用来获取颜色(uint32_t color)
  • 不同深浅的橙色,是吗?
  • 有可能。作为附加信息,浮点值属于 IFC 格式文件(构造元素)的配置,用于 BIM 分析。问题是我每次分析文件时都必须分析数百个值,这些值不是静态的,它们是动态的.据我了解,这些值包括透明度的 alpha 值
猜你喜欢
  • 2012-01-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-01-01
  • 2016-05-17
相关资源
最近更新 更多