netlib.narod.ru< Назад | Оглавление | Далее >

4.1. Представление цвета

В Direct3D цвета задаются путем указания тройки значений RGB. То есть мы указываем интенсивность красного, зеленого и синего цветов. Последующее смешивание этих трех компонентов дает в результате итоговый цвет. С помощью комбинаций красного, зеленого и синего мы можем представить миллионы цветов.

Для хранения информации о цвете мы будем использовать две различные структуры. Первая — это тип D3DCOLOR, который представляется значением DWORD и является 32-разрядным. Отдельные разряды в типе D3DCOLOR делятся на четыре 8-разрядных секции, каждая из которых хранит интенсивность отдельного компонента. Распределение значений показано на рис. 4.1.


Рис. 4.1. 32-разрядное представление цвета

Рис. 4.1. 32-разрядное представление цвета, где для каждого основного компоненнта (красного, зеленого и синего) выделено по одному байту. Четвертый байт отведен для альфа-канала


Поскольку для каждого цвета выделено по байту памяти, его интенсивность может принимать значения от 0 до 255. Чем ближе значение к 0, тем меньше интенсивность цвета, и чем ближе значение к 255 — тем больше интенсивность.

ПРИМЕЧАНИЕ
Сейчас не следует беспокоиться об альфа-составляющей, она используется для альфа-смешивания, о котором мы поговорим в главе 7.

Если задавать каждый компонент цвета и затем помещать его в требуемую позицию значения типа D3DCOLOR, потребуется выполнить несколько поразрядных операций. Direct3D предоставляет макрос с именем D3DCOLOR_ARGB, который выполнит все эти действия за нас. У макроса есть по одному параметру для каждой цветовой составляющей и один параметр для альфа-канала. Значение каждого параметра может быть от 0 до 255, а использование макроса выглядит так:

D3DCOLOR brightRed = D3DCOLOR_ARGB(255, 255, 0, 0);
D3DCOLOR someColor = D3DCOLOR_ARGB(255, 144, 87, 201);

Альтернативным способом является использование макроса D3DCOLOR_XRGB, который работает почти так же, но не получает значение для альфа-канала; вместо этого значение альфа-канала всегда устанавливается равным 0xff (255).

#define D3DCOLOR_XRGB(r,g,b) D3DCOLOR_ARGB(0xff,r,g,b)

Вторым способом хранения данных цвета в Direct3D является структура D3DCOLORVALUE. В этой структуре для задания интенсивности каждого компонента цвета применяются значения с плавающей точкой. Доступный диапазон значений от 0 до 1; 0 соответствует отсутствию даного цвета, а 1 — его максимальной интенсивности.

typedef struct _D3DCOLORVALUE {
     float r;   // красная составляющая, диапазон 0.0-1.0
     float g;   // зеленая составляющая, диапазон 0.0-1.0
     float b;   // синяя составляющая, диапазон 0.0-1.0
     float a;   // альфа-составляющая, диапазон 0.0-1.0
} D3DCOLORVALUE;

Кроме того, мы можем использовать структуру D3DXCOLOR, которая содержит те же самые члены, что и D3DCOLORVALUE, но предоставляет дополнительные конструкторы и перегруженные операторы, упрощающие работу с цветами. А поскольку две структуры содержат одинаковые члены данных, можно выполнять преобразование типов из одного в другой и обратно. Определение D3DXCOLOR выглядит так:

typedef struct D3DXCOLOR
{
#ifdef __cplusplus
public:
     D3DXCOLOR() {}
     D3DXCOLOR(DWORD argb);
     D3DXCOLOR(CONST FLOAT *);
     D3DXCOLOR(CONST D3DXFLOAT16 *);
     D3DXCOLOR(CONST D3DCOLORVALUE&);
     D3DXCOLOR(FLOAT r, FLOAT g, FLOAT b, FLOAT a);

     // приведение типов
     operator DWORD () const;

     operator FLOAT* ();
     operator CONST FLOAT* () const;
     operator D3DCOLORVALUE* ();
     operator CONST D3DCOLORVALUE* () const;

     operator D3DCOLORVALUE& ();
     operator CONST D3DCOLORVALUE& () const;

     // операторы присваивания
     D3DXCOLOR& operator += (CONST D3DXCOLOR&);
     D3DXCOLOR& operator -= (CONST D3DXCOLOR&);
     D3DXCOLOR& operator *= (FLOAT);
     D3DXCOLOR& operator /= (FLOAT);

     // унарные операторы
     D3DXCOLOR operator + () const;
     D3DXCOLOR operator - () const;

     // бинарные операторы
     D3DXCOLOR operator + (CONST D3DXCOLOR&) const;
     D3DXCOLOR operator - (CONST D3DXCOLOR&) const;
     D3DXCOLOR operator * (FLOAT) const;
     D3DXCOLOR operator / (FLOAT) const;

     friend D3DXCOLOR operator * (FLOAT, CONST D3DXCOLOR&);

     BOOL operator == (CONST D3DXCOLOR&) const;
     BOOL operator != (CONST D3DXCOLOR&) const;

#endif //__cplusplus
     FLOAT r, g, b, a;
} D3DXCOLOR, *LPD3DXCOLOR;

 

ПРИМЕЧАНИЕ
Обратите внимание, что в структурах D3DCOLORVALUE и D3DXCOLOR имеется по четыре значения с плавающей точкой. Это позволяет предствить цвет как четырехмерный вектор (rgba). Цветовые векторы могут складываться, вычитаться и масштабироваться как обычные. В то же время скалярное и векторное произведение цветовых векторов не имеют смысла. Однако, перемножение отдельных компонент для цветовых векторов имеет смысл. Так что оператор умножения цвета на цвет в классе D3DXCOLOR перемножает отдельные компоненты. Символ означает перемножение отдельных компонентов, которое определяется следующим образом:
(c1c2c3c4 (k1k2k3k4) = (c1k1c2k2c3k3c4k4)

Мы дополним наш файл d3dUtility.h следующими глобальными цветовыми константами:

namespace d3d
{
     .
     .
     .
     const D3DXCOLOR     WHITE(D3DCOLOR_XRGB(255, 255, 255));
     const D3DXCOLOR     BLACK(D3DCOLOR_XRGB(  0,   0,   0));
     const D3DXCOLOR       RED(D3DCOLOR_XRGB(255,   0,   0));
     const D3DXCOLOR     GREEN(D3DCOLOR_XRGB(  0, 255,   0));
     const D3DXCOLOR      BLUE(D3DCOLOR_XRGB(  0,   0, 255));
     const D3DXCOLOR    YELLOW(D3DCOLOR_XRGB(255, 255,   0));
     const D3DXCOLOR      CYAN(D3DCOLOR_XRGB(  0, 255, 255));
     const D3DXCOLOR   MAGENTA(D3DCOLOR_XRGB(255,   0, 255));
}

netlib.narod.ru< Назад | Оглавление | Далее >

Сайт управляется системой uCoz