如何将D3DCOLORVALUE转换为delphi tcolor

时间:2018-06-10 23:37:43

标签: c++ delphi tcolor

我有一个整数列表,通过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中,颜色是黑色或null。有时会得到负数,可以理解,在C ++中,可以用负值表示颜色,但在delphi中不起作用。

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

这些值用于获取对象的颜色 D3DMATERIAL9,D3DCOLORVALUE环境(环境色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解决方案比较颜色:

左:获得的颜色右:所需的颜色

enter image description here enter image description here

enter image description here enter image description here

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

enter image description here

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

1 个答案:

答案 0 :(得分:2)

这看起来像原始的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)来说明反色顺序。