如何将 D3DCOLORVALUE 转换为 delphi tcolor
How to Convert D3DCOLORVALUE to delphi tcolor
我有一个整数列表,通过 C++ 代码获得,代表不同的 D3DCOLORVALUE 环境等...
从这个数字中获得相同颜色的正确方法是 Delphi?
例如,使用C++程序(Visual Studio2012),通过调用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 年手表的图像,表明数组的内容是相同的并且通过转换获得的值也是相同的,但是,当将这些数字转换为颜色时,它们不会给出相同的结果。
这看起来像原始的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) 来解释颠倒的颜色顺序。
我有一个整数列表,通过 C++ 代码获得,代表不同的 D3DCOLORVALUE 环境等...
从这个数字中获得相同颜色的正确方法是 Delphi?
例如,使用C++程序(Visual Studio2012),通过调用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 年手表的图像,表明数组的内容是相同的并且通过转换获得的值也是相同的,但是,当将这些数字转换为颜色时,它们不会给出相同的结果。
这看起来像原始的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) 来解释颠倒的颜色顺序。