Как конвертировать D3DCOLORVALUE в 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 цвета черный или ноль. Иногда получаются отрицательные числа, понятно, что в C ++ можно представить цвет с отрицательным значением, но в Delphi не работает.

Как я могу преобразовать значение цвета, полученное в формате D3DCOLORVALUE, в TColor Delphi?

Значения используются для получения цветов объектов в
D3DMATERIAL9, D3DCOLORVALUE Ambient (Ambient color 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, показывающее, что содержимое массива одинаково, а значение полученное с использованием приведения также то же самое, но при преобразовании этих чисел в цвета они не дают одинакового результата.

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) для учета обратного порядка цветов.

2

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]