Как конвертировать D3DCOLORVALUE в Delphi Tcolor - PullRequest
0 голосов
/ 11 июня 2018

У меня есть список целых чисел, полученных с помощью кода 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's TColor?

что значения используются для получения цветов объектов в 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:

Слева: Цвет получен Справа: Желаемый цвет

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 голосов
/ 11 июня 2018

Похоже, что оригинальный 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) для учета обратного порядка цветов.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...