До сих пор выводимые на экран примитивы строились только с помощью синтетических цветов. Для того чтобы придать им большей реалистичности можно прибегнуть к помощи текстур. Текстура представляет собой двумерное растровое изображение, которое накладывается (натягивается) на поверхность объекта, например на плоский треугольник. Текстуры, как правило, хранятся в графических файлах форматов bmp, jpeg, tiff, содержит богатый набор функций для работы с текстурами. Процесс наложения текстуры на объект называют текстурированием. Текстуры накладываются на объект с помощью так называемых текстурных координат. Текстурные координаты представляют собой пару чисел (u,v), изменяющихся в пределах от 0 до 1, и определяются в своей системе координат. Ось u направлена горизонтально вправо, ось v - вертикально вниз. Пара величин (u,v) однозначно указывает на элемент текстуры, называемый текселем.

Для каждой вершины треугольника мы должны определить текстурные координаты, тем самым, привязав его к некоторой треугольной области на текстуре.

Как уже стало ясным, текстурные координаты изменяют формат вершины. Поэтому данный факт может быть отражен в программе следующим образом.
| C++ | struct MYVERTEX
{
FLOAT x, y, z, rhw;
FLOAT u, v; // текстурные координаты
};
#define MY_FVF (D3DFVF_XYZRHW|D3DFVF_TEX1)
|
| Pascal | type
MyVertex = packed record
x, y, z, rhw: Single;
u,v: Single; // текстурные координаты
end;
const
MY_FVF = D3DFVF_XYZRHW or D3DFVF_TEX1;
|
Теперь при заполнении данных о вершинах необходимо также указывать и текстурные координаты для каждой вершины текстурируемого примитива. Работа с текстурами в осуществляется с помощью интерфейса IDirect3DTexture9. Для этого нужно объявить соответствующую переменную.
| C++ | LPDIRECT3DTEXTURE9 tex = NULL; |
| Pascal | var tex: IDirect3DTexture9; |
Следующий шаг заключается в загрузке текстуры из графического файла. Чтобы воспользоваться функцией загрузки текстуры необходимо вначале подключить нужные модули и библиотеки.
| C++ | #include <d3dx9.h> |
| Pascal | uses …, D3DX9,… |
Загрузка же текстуры из графического файла в память осуществляется с помощью функции D3DXCreateTextureFromFile, у которой имеется три параметра. Первый параметр определяет указатель на устройство вывода, второй аргумент представляет собой строку, содержащую путь до загружаемого файла на диске, и третий – определяет переменную, в которой будет храниться указатель на текстуру.
| C++ | D3DXCreateTextureFromFile( device, "texture.bmp", tex ) |
| Pascal | D3DXCreateTextureFromFile( device, 'texture.bmp', tex ); |
Последний шаг в работе с текстурами заключается в активации нужной текстуры перед выводом примитивов. Реализуется это с помощью вызова метода SetTexture интерфейса IDirect3DDevice9. Данный метод имеет два параметра: первый определяет номер так называемого текстурного уровня, а второй – указатель на загруженную текстуру. Библиотека поддерживает до восьми текстурных уровней, но если вы работаете только с одной текстурой, то номер текстурного уровня всегда должен быть нулем. Установка (загрузка текстуры в текстурный уровень) текущей текстуры осуществляется, как правило, в теле функции вывода (рендеринга).
| C++ | device->SetTexture ( 0, tex ); |
| Pascal | device.SetTexture( 0, tex ); |
Если в сцене присутствуют несколько объектов с различными текстурами, то процесс установки текстуры и вывода примитивов должен быть последовательным:
SetTexture ( 0, tex1 ); drawObject1(); SetTexture ( 0, tex2 ); drawObject2();
Для деактивации текстуры в некотором текстурном уровне достаточно вызвать метод SetTexture с нулевым (пустым) значением второго параметра.
| C++ | device->SetTexture ( 0, 0 ); |
| Pascal | device.SetTexture( 0, nil ); |
В большинстве случаях размер накладываемой текстуры и размер текстурируемого полигона (треугольника) не совпадают. Поэтому когда исходная текстура меньше чем полигон, на который она накладывается, то текстура должна быть увеличена (растянута) до размеров полигона. И наоборот, когда текстура больше чем полигон, то она должна быть уменьшена (сжата) до размеров полигона.
Фильтрация текстур – это механизм, с помощью которого библиотека производит наложение текстуры на полигоны отличающегося размера. Наиболее распространенными по использованию являются следующие типы фильтрации текстур:
Программно установить тот или ной тип фильтрации можно с помощью вызова метода SetSamplerState интерфейса IDirect3DDevice9:
SetSamplerState( 0, D3DSAMP_MINFILTER, <тип фильтрации> ) SetSamplerState( 0, D3DSAMP_MAGFILTER, <тип фильтрации> ),
где <тип фильтрации> – одна из следующих констант:
D3DTEXF_POINT – точечная фильтрация,
D3DTEXF_LINEAR – линейная фильтрация,
D3DTEXF_ANISOTROPIC – анизотропная фильтрация;
константы D3DSAMP_MAGFILTER и D3DSAMP_MINFILTER указывают на то, что размер текстуры меньше и больше размеров полигона соответственно.
Как правило, функции установки типа фильтрации для двух упомянутых выше случаев вызывают совместно. Ниже приведен пример фильтрации текстур с точечной и линейной интерполяцией.
![]() |
![]() |
| D3DTEXF_POINT | D3DTEXF_LINEAR |
На самом деле значения текстурных координат могут выходить за пределы отрезка [0,1]. Как при этом будет себя "вести" текстура зависит от установленного режима адресации. Существует 4 типа адресации текстур:
wrapborder colorclamp mirrorРазберем на примерах результат работы каждого типа. Пусть у нас имеется исходная текстура и квадрат, на который мы хотим наложить ее, причем вершины квадрата имеют текстурные координаты, показанные ниже:

В таблице представлены способы установки различных режимов адресации текстур, а также показан результат их действий.
SetSamplerState( 0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP ); SetSamplerState( 0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP ); ![]() |
SetSamplerState( 0, D3DSAMP_ADDRESSU, D3DTADDRESS_BORDER ); SetSamplerState( 0, D3DSAMP_ADDRESSV, D3DTADDRESS_BORDER ); SetSamplerState( 0, D3DSAMP_BORDERCOLOR, D3DCOLOR_XRGB(64,64,0) ); ![]() |
SetSamplerState( 0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP ); SetSamplerState( 0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP ); ![]() |
SetSamplerState( 0, D3DSAMP_ADDRESSU, D3DTADDRESS_MIRROR ); SetSamplerState( 0, D3DSAMP_ADDRESSV, D3DTADDRESS_MIRROR ); ![]() |
Вершина полигона может содержать одновременно и цвет и текстурные координаты. В этом случае итоговое значение каждого пикселя будет определяться как средневзвешенная сумма соответствующего пикселя и текселя текстуры.
| C++ | struct CUSTOMVERTEX
{
FLOAT x, y, z, rhw; // координаты вершины
DWORD color; // цвет вершин
FLOAT tu, tv; // текстурные координаты
};
#define MY_FVF (D3DFVF_XYZRHW | D3DFVF_ DIFFUSE | D3DFVF_TEX1)
|
| Pascal | type
MyVertex = packed record
x, y, z, rhw: Single; // координаты вершины
color: DWORD; // цвет вершин
u,v: Single; // текстурные координаты
end;
const
MY_FVF = D3DFVF_XYZRHW or D3DFVF_DIFFUSE or D3DFVF_TEX1;
|
Пример вывода квадрата, состоящего из двух треугольников, у которых вершины содержат как цвет, так и текстурные координаты показан ниже.
Вообще говоря, правила взаимодействия, по которым два пикселя будут формировать результирующий цвет, можно явно указывать с помощью состояний текстурных уровней. Каждый текстурный уровень принимает на вход два цветовых аргумента и определяет правило (операцию) по которому будут смешиваться эти цвета. Программно это реализуется с помощью вызова метода SetTextureStageState интерфейса IDirect3DDevice9.
Первый аргумент указывает номер текстурного уровня, второй аргумент задает название изменяемого параметра, а третий – его значение. Определить значения двух цветовых аргументов для нулевого текстурного уровня можно следующим образом:
SetTextureStageState( 0, D3DTSS_COLORARG{1,2}, <значение> ),
где <значение> в нашем случае может быть константой D3DTA_DIFFUSE либо D3DTA_TEXTURE. Определить операцию взаимодействия двух цветовых аргументов позволит следующий вызов:
SetTextureStageState( 0, D3DTSS_COLOROP, <операция> ),
где <операция> может принимать следующие значения:
| Вид операции | Описание |
|---|---|
D3DTOP_SELECTARG1 |
выбор в качестве результата первого цветового аргумента, при этом значение второго аргумента в рассмотрение не берется |
D3DTOP_SELECTARG2 |
выбор в качестве результата второго цветового аргумента, при этом значение первого аргумента в рассмотрение не берется |
D3DTOP_MODULATE |
покомпонентное перемножение первого и второго цветового аргумента |
D3DTOP_MODULATE2X |
покомпонентное перемножение первого и второго цветового аргумента и битовый сдвиг на 1 бит влево (умножение на 2) |
D3DTOP_MODULATE4X |
покомпонентное перемножение первого и второго цветового аргумента и битовый сдвиг на 2 бита влево (умножение на 4) |
D3DTOP_ADD |
покомпонентное сложение первого и второго цветового аргумента |
D3DTOP_SUBTRACT |
покомпонентное вычитание из первого цветового аргумента второго |
Сам процесс смешивания цветов может быть описан следующей блок-схемой.

Следует отметить, что все цветовые операции над пикселями производятся покомпонентно для каждого оттенка. Отдельно для красного, зеленого и синего цветов, причем диапазон принимаемых значений каждого цветового канала ограничен в пределах [0,1]. Пусть формат вершины содержит цвет и текстурные координаты. Ниже показаны примеры смешивания цветовой и текстурной составляющей вершины при использовании только нулевого текстурного уровня.
D3DTSS_COLORARG1 = D3DTA_TEXTURE D3DTSS_COLORARG2 = D3DTA_DIFFUSE D3DTSS_COLOROP = D3DTOP_SELECTARG1 |
![]() |
D3DTSS_COLORARG1 = D3DTA_TEXTURE D3DTSS_COLORARG2 = D3DTA_DIFFUSE D3DTSS_COLOROP = D3DTOP_SELECTARG2 |
![]() |
D3DTSS_COLORARG1 = D3DTA_TEXTURE D3DTSS_COLORARG2 = D3DTA_DIFFUSE D3DTSS_COLOROP = D3DTOP_MODULATE |
![]() |
D3DTSS_COLORARG1 = D3DTA_TEXTURE D3DTSS_COLORARG2 = D3DTA_DIFFUSE D3DTSS_COLOROP = D3DTOP_MODULATE2X |
![]() |
D3DTSS_COLORARG1 = D3DTA_TEXTURE D3DTSS_COLORARG2 = D3DTA_DIFFUSE D3DTSS_COLOROP = D3DTOP_MODULATE4X |
![]() |
D3DTSS_COLORARG1 = D3DTA_TEXTURE D3DTSS_COLORARG2 = D3DTA_DIFFUSE D3DTSS_COLOROP = D3DTOP_ADD |
![]() |
D3DTSS_COLORARG1 = D3DTA_TEXTURE D3DTSS_COLORARG2 = D3DTA_DIFFUSE D3DTSS_COLOROP = D3DTOP_SUBTRACT |
![]() |
D3DTSS_COLORARG1 = D3DTA_DIFFUSE D3DTSS_COLORARG2 = D3DTA_TEXTURE D3DTSS_COLOROP = D3DTOP_SUBTRACT |
![]() |
Если вершина не содержит цветовой составляющей, то по умолчанию выбирается белый цвет для D3DTA_DIFFUSE. Эта возможность позволяет реализовать негативное преобразование изображения (текстуры).
D3DTSS_COLORARG1 = D3DTA_DIFFUSE (белый) D3DTSS_COLORARG2 = D3DTA_TEXTURE D3DTSS_COLOROP = D3DTOP_SUBTRACT |
![]() |
Библиотека позволяет накладывать на один полигон не одну, а сразу несколько текстур. Наложение на грань нескольких текстур называется мультитекстурированием. На текущий момент поддерживается до 8 наложений (уровней) текстур на одну грань. Схему (принцип) мультитекстурирования можно описать следующим образом. Первый текстурный уровень (с индексом 0) принимает на вход два значения: цвет текселя и диффузный цвет вершины; производит с ними указанные операции и передает результат на следующий (нижний) уровень. Полученное на предыдущем уровне значение цвета используется в качестве одного из аргумента текущего уровня и т.д. Схематично данные шаги мультитекстурирования можно представить так:

Как уже стало ясно, при мультитекстурировании дело имеют уже с несколькими текстурами. При мультитекстурировании можно для каждого текстурного уровня назначить одни и те же текстурные координаты. В этом случае формат вершины и набор флагов FVF останутся неизмененными. Существует возможность указать, с какими текстурными координатами будет работать тот или иной текстурный уровень. Для этого можно воспользоваться следующими программными строками:
SetTextureStageState(<уровень>, D3DTSS_TEXCOORDINDEX, <номер координат>);
Так, например, чтобы указать, что второй уровень будет использовать текстурные координаты первого текстурного уровня, достаточно воспользоваться следующим вызовом метода: SetTextureStageState( 1, D3DTSS_TEXCOORDINDEX, 0 ). И затем нужно загрузить (установить) текстуры в соответствующие текстурные уровни.
SetTexture( 0, tex1 ); SetTexture( 1, tex2 );
Можно указать для каждого текстурного уровня свои собственные текстурные координаты. В этом случае должен корректно измениться формат вершины при описании и набор FVF флагов. Ниже приведен пример описания вершины и FVF флагов для мультитекстурирования с двумя уровнями (текстурами) и текстурными координатами.
| C++ | struct CUSTOMVERTEX
{
FLOAT x, y, z, rhw; // координаты вершины
FLOAT u1, v1; // текстурные координаты первого уровня
FLOAT u2, v2; // текстурные координаты второго уровня
};
#define MY_FVF (D3DFVF_XYZ | D3DFVF_TEX2)
|
| Pascal | type
MyVertex = packed record
x, y, z, rhw: Single; // координаты вершины
u1,v1: Single; // текстурные координаты первого уровня
u2,v2: Single; // текстурные координаты второго уровня
end;
const
MY_FVF = D3DFVF_XYZRHW or D3DFVF_TEX2;
|
Вообще, число во флаге D3DFVF_TEX как раз и показывает, сколько текстурных уровней планируется задействовать при мультитекстурировании (D3DFVF_TEX1 … D3DFVF_TEX8). Для хранения второй и последующих текстур необходимо объявить соответствующее количество нужных переменных, произвести загрузку текстур с помощью функции D3DXCreateTextureFromFile() и установить текстуры в соответствующие текстурные уровни вызовов метода SetTexture (<номер уровня>, <текстура>). Ниже приведен пример возможного использования двух текстур при мультитекстурировании.
| C++ | LPDIRECT3DTEXTURE9 tex, tex2; … D3DXCreateTextureFromFile( device, "texture.bmp", tex ); D3DXCreateTextureFromFile( device, "texture2.bmp", tex2 ); … device->SetTexture ( 0, tex ); device->SetTexture ( 1, tex2 ); |
| Pascal | var tex, tex2: IDirect3DTexture9; … D3DXCreateTextureFromFile( device, 'texture.bmp', tex ); D3DXCreateTextureFromFile( device, 'texture2.bmp', tex2 ); … device.SetTexture( 0, tex ); device.SetTexture( 1, tex2 ); |
При такой SetTextureStageState интерфейса IDirect3DDevice9:
SetTextureStageState( <номер уровня>, D3DTSS_COLORARG1, <значение> ), SetTextureStageState( <номер уровня>, D3DTSS_COLORARG2, <значение> ), SetTextureStageState( <номер уровня>, D3DTSS_COLOROP, <операция> ).
Помимо уже известных значений констант для цветовых аргументов в данном вызове может быть использована константа D3DTA_CURRENT, которая говорит, что в качестве значения будет браться цвет из предыдущего текстурного уровня.
Также мы можем указать требуемый тип фильтрации текстур для каждого в отдельности текстурного уровня, указав в качестве первого аргумента его номер и вызвав метод SetSamplerState интерфейса IDirect3DDevice9.
Вообще говоря, можно использовать даже одну текстуру для реализации механизма мультитекстурирования. Для этого необходимо в первый и во второй текстурный уровень загрузить одну и ту же текстуру, но при этом значения текстурных координат для них должны отличатся. Программный код для этого случая может выглядеть следующим образом:
… points[0].u1 = 0.0f; points[0].v1 = 1.0f; points[0].u2 = 0.0f; points[0].v2 = 3.0f; … device->SetTexture( 0, tex ); device->SetTexture( 1, tex ); …
Ниже приведен пример мультитекстурирования с помощью одной текстуры и двух текстурных уровней.
device->SetTexture(0, tex); device->SetTextureStageState(0, D3DTSS_TEXCOORDINDEX, 0); device->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE); device->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG1); device->SetTexture(1, tex); device->SetTextureStageState(1, D3DTSS_TEXCOORDINDEX, 1); device->SetTextureStageState(1, D3DTSS_COLORARG2, D3DTA_TEXTURE); device->SetTextureStageState(1, D3DTSS_COLORARG1, D3DTA_CURRENT); device->SetTextureStageState(1, D3DTSS_COLOROP, <operation>); |
|
![]() operation = D3DTOP_MODULATE4X |
![]() operation = D3DTOP_ADD |
До сих пор выводимые на экран примитивы строились только с помощью синтетических цветов. Для того чтобы придать им большей реалистичности можно прибегнуть к помощи текстур. Текстура представляет собой двумерное растровое изображение, которое накладывается (натягивается) на поверхность объекта, например на плоский треугольник. Текстуры, как правило, хранятся в графических файлах форматов bmp, jpeg, tiff, содержит богатый набор функций для работы с текстурами. Процесс наложения текстуры на объект называют текстурированием. Текстуры накладываются на объект с помощью так называемых текстурных координат. Текстурные координаты представляют собой пару чисел (u,v), изменяющихся в пределах от 0 до 1, и определяются в своей системе координат. Ось u направлена горизонтально вправо, ось v - вертикально вниз. Пара величин (u,v) однозначно указывает на элемент текстуры, называемый текселем.

Для каждой вершины треугольника мы должны определить текстурные координаты, тем самым, привязав его к некоторой треугольной области на текстуре.

Как уже стало ясным, текстурные координаты изменяют формат вершины. Поэтому данный факт может быть отражен в программе следующим образом.
| C++ | struct MYVERTEX
{
FLOAT x, y, z, rhw;
FLOAT u, v; // текстурные координаты
};
#define MY_FVF (D3DFVF_XYZRHW|D3DFVF_TEX1)
|
| Pascal | type
MyVertex = packed record
x, y, z, rhw: Single;
u,v: Single; // текстурные координаты
end;
const
MY_FVF = D3DFVF_XYZRHW or D3DFVF_TEX1;
|
Теперь при заполнении данных о вершинах необходимо также указывать и текстурные координаты для каждой вершины текстурируемого примитива. Работа с текстурами в осуществляется с помощью интерфейса IDirect3DTexture9. Для этого нужно объявить соответствующую переменную.
| C++ | LPDIRECT3DTEXTURE9 tex = NULL; |
| Pascal | var tex: IDirect3DTexture9; |
Следующий шаг заключается в загрузке текстуры из графического файла. Чтобы воспользоваться функцией загрузки текстуры необходимо вначале подключить нужные модули и библиотеки.
| C++ | #include <d3dx9.h> |
| Pascal | uses …, D3DX9,… |
Загрузка же текстуры из графического файла в память осуществляется с помощью функции D3DXCreateTextureFromFile, у которой имеется три параметра. Первый параметр определяет указатель на устройство вывода, второй аргумент представляет собой строку, содержащую путь до загружаемого файла на диске, и третий – определяет переменную, в которой будет храниться указатель на текстуру.
| C++ | D3DXCreateTextureFromFile( device, "texture.bmp", tex ) |
| Pascal | D3DXCreateTextureFromFile( device, 'texture.bmp', tex ); |
Последний шаг в работе с текстурами заключается в активации нужной текстуры перед выводом примитивов. Реализуется это с помощью вызова метода SetTexture интерфейса IDirect3DDevice9. Данный метод имеет два параметра: первый определяет номер так называемого текстурного уровня, а второй – указатель на загруженную текстуру. Библиотека поддерживает до восьми текстурных уровней, но если вы работаете только с одной текстурой, то номер текстурного уровня всегда должен быть нулем. Установка (загрузка текстуры в текстурный уровень) текущей текстуры осуществляется, как правило, в теле функции вывода (рендеринга).
| C++ | device->SetTexture ( 0, tex ); |
| Pascal | device.SetTexture( 0, tex ); |
Если в сцене присутствуют несколько объектов с различными текстурами, то процесс установки текстуры и вывода примитивов должен быть последовательным:
SetTexture ( 0, tex1 ); drawObject1(); SetTexture ( 0, tex2 ); drawObject2();
Для деактивации текстуры в некотором текстурном уровне достаточно вызвать метод SetTexture с нулевым (пустым) значением второго параметра.
| C++ | device->SetTexture ( 0, 0 ); |
| Pascal | device.SetTexture( 0, nil ); |
В большинстве случаях размер накладываемой текстуры и размер текстурируемого полигона (треугольника) не совпадают. Поэтому когда исходная текстура меньше чем полигон, на который она накладывается, то текстура должна быть увеличена (растянута) до размеров полигона. И наоборот, когда текстура больше чем полигон, то она должна быть уменьшена (сжата) до размеров полигона.

Фильтрация текстур – это механизм, с помощью которого библиотека производит наложение текстуры на полигоны отличающегося размера. Наиболее распространенными по использованию являются следующие типы фильтрации текстур:
Программно установить тот или ной тип фильтрации можно с помощью вызова метода SetSamplerState интерфейса IDirect3DDevice9:
SetSamplerState( 0, D3DSAMP_MINFILTER, <тип фильтрации> ) SetSamplerState( 0, D3DSAMP_MAGFILTER, <тип фильтрации> ),
где <тип фильтрации> – одна из следующих констант:
D3DTEXF_POINT – точечная фильтрация,
D3DTEXF_LINEAR – линейная фильтрация,
D3DTEXF_ANISOTROPIC – анизотропная фильтрация;
константы D3DSAMP_MAGFILTER и D3DSAMP_MINFILTER указывают на то, что размер текстуры меньше и больше размеров полигона соответственно.
Как правило, функции установки типа фильтрации для двух упомянутых выше случаев вызывают совместно. Ниже приведен пример фильтрации текстур с точечной и линейной интерполяцией.
![]() |
![]() |
| D3DTEXF_POINT | D3DTEXF_LINEAR |
На самом деле значения текстурных координат могут выходить за пределы отрезка [0,1]. Как при этом будет себя "вести" текстура зависит от установленного режима адресации. Существует 4 типа адресации текстур:
wrapborder colorclamp mirrorРазберем на примерах результат работы каждого типа. Пусть у нас имеется исходная текстура и квадрат, на который мы хотим наложить ее, причем вершины квадрата имеют текстурные координаты, показанные ниже:

В таблице представлены способы установки различных режимов адресации текстур, а также показан результат их действий.
SetSamplerState( 0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP ); SetSamplerState( 0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP ); ![]() |
SetSamplerState( 0, D3DSAMP_ADDRESSU, D3DTADDRESS_BORDER ); SetSamplerState( 0, D3DSAMP_ADDRESSV, D3DTADDRESS_BORDER ); SetSamplerState( 0, D3DSAMP_BORDERCOLOR, D3DCOLOR_XRGB(64,64,0) ); ![]() |
SetSamplerState( 0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP ); SetSamplerState( 0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP ); ![]() |
SetSamplerState( 0, D3DSAMP_ADDRESSU, D3DTADDRESS_MIRROR ); SetSamplerState( 0, D3DSAMP_ADDRESSV, D3DTADDRESS_MIRROR ); ![]() |
Вершина полигона может содержать одновременно и цвет и текстурные координаты. В этом случае итоговое значение каждого пикселя будет определяться как средневзвешенная сумма соответствующего пикселя и текселя текстуры.
| C++ | struct CUSTOMVERTEX
{
FLOAT x, y, z, rhw; // координаты вершины
DWORD color; // цвет вершин
FLOAT tu, tv; // текстурные координаты
};
#define MY_FVF (D3DFVF_XYZRHW | D3DFVF_ DIFFUSE | D3DFVF_TEX1)
|
| Pascal | type
MyVertex = packed record
x, y, z, rhw: Single; // координаты вершины
color: DWORD; // цвет вершин
u,v: Single; // текстурные координаты
end;
const
MY_FVF = D3DFVF_XYZRHW or D3DFVF_DIFFUSE or D3DFVF_TEX1;
|
Пример вывода квадрата, состоящего из двух треугольников, у которых вершины содержат как цвет, так и текстурные координаты показан ниже.

Вообще говоря, правила взаимодействия, по которым два пикселя будут формировать результирующий цвет, можно явно указывать с помощью состояний текстурных уровней. Каждый текстурный уровень принимает на вход два цветовых аргумента и определяет правило (операцию) по которому будут смешиваться эти цвета. Программно это реализуется с помощью вызова метода SetTextureStageState интерфейса IDirect3DDevice9.
Первый аргумент указывает номер текстурного уровня, второй аргумент задает название изменяемого параметра, а третий – его значение. Определить значения двух цветовых аргументов для нулевого текстурного уровня можно следующим образом:
SetTextureStageState( 0, D3DTSS_COLORARG{1,2}, <значение> ),
где <значение> в нашем случае может быть константой D3DTA_DIFFUSE либо D3DTA_TEXTURE. Определить операцию взаимодействия двух цветовых аргументов позволит следующий вызов:
SetTextureStageState( 0, D3DTSS_COLOROP, <операция> ),
где <операция> может принимать следующие значения:
| Вид операции | Описание |
|---|---|
D3DTOP_SELECTARG1 |
выбор в качестве результата первого цветового аргумента, при этом значение второго аргумента в рассмотрение не берется |
D3DTOP_SELECTARG2 |
выбор в качестве результата второго цветового аргумента, при этом значение первого аргумента в рассмотрение не берется |
D3DTOP_MODULATE |
покомпонентное перемножение первого и второго цветового аргумента |
D3DTOP_MODULATE2X |
покомпонентное перемножение первого и второго цветового аргумента и битовый сдвиг на 1 бит влево (умножение на 2) |
D3DTOP_MODULATE4X |
покомпонентное перемножение первого и второго цветового аргумента и битовый сдвиг на 2 бита влево (умножение на 4) |
D3DTOP_ADD |
покомпонентное сложение первого и второго цветового аргумента |
D3DTOP_SUBTRACT |
покомпонентное вычитание из первого цветового аргумента второго |
Сам процесс смешивания цветов может быть описан следующей блок-схемой.

Следует отметить, что все цветовые операции над пикселями производятся покомпонентно для каждого оттенка. Отдельно для красного, зеленого и синего цветов, причем диапазон принимаемых значений каждого цветового канала ограничен в пределах [0,1]. Пусть формат вершины содержит цвет и текстурные координаты. Ниже показаны примеры смешивания цветовой и текстурной составляющей вершины при использовании только нулевого текстурного уровня.
D3DTSS_COLORARG1 = D3DTA_TEXTURE D3DTSS_COLORARG2 = D3DTA_DIFFUSE D3DTSS_COLOROP = D3DTOP_SELECTARG1 |
![]() |
D3DTSS_COLORARG1 = D3DTA_TEXTURE D3DTSS_COLORARG2 = D3DTA_DIFFUSE D3DTSS_COLOROP = D3DTOP_SELECTARG2 |
![]() |
D3DTSS_COLORARG1 = D3DTA_TEXTURE D3DTSS_COLORARG2 = D3DTA_DIFFUSE D3DTSS_COLOROP = D3DTOP_MODULATE |
![]() |
D3DTSS_COLORARG1 = D3DTA_TEXTURE D3DTSS_COLORARG2 = D3DTA_DIFFUSE D3DTSS_COLOROP = D3DTOP_MODULATE2X |
![]() |
D3DTSS_COLORARG1 = D3DTA_TEXTURE D3DTSS_COLORARG2 = D3DTA_DIFFUSE D3DTSS_COLOROP = D3DTOP_MODULATE4X |
![]() |
D3DTSS_COLORARG1 = D3DTA_TEXTURE D3DTSS_COLORARG2 = D3DTA_DIFFUSE D3DTSS_COLOROP = D3DTOP_ADD |
![]() |
D3DTSS_COLORARG1 = D3DTA_TEXTURE D3DTSS_COLORARG2 = D3DTA_DIFFUSE D3DTSS_COLOROP = D3DTOP_SUBTRACT |
![]() |
D3DTSS_COLORARG1 = D3DTA_DIFFUSE D3DTSS_COLORARG2 = D3DTA_TEXTURE D3DTSS_COLOROP = D3DTOP_SUBTRACT |
![]() |
Если вершина не содержит цветовой составляющей, то по умолчанию выбирается белый цвет для D3DTA_DIFFUSE. Эта возможность позволяет реализовать негативное преобразование изображения (текстуры).
D3DTSS_COLORARG1 = D3DTA_DIFFUSE (белый) D3DTSS_COLORARG2 = D3DTA_TEXTURE D3DTSS_COLOROP = D3DTOP_SUBTRACT |
![]() |
Библиотека позволяет накладывать на один полигон не одну, а сразу несколько текстур. Наложение на грань нескольких текстур называется мультитекстурированием. На текущий момент поддерживается до 8 наложений (уровней) текстур на одну грань. Схему (принцип) мультитекстурирования можно описать следующим образом. Первый текстурный уровень (с индексом 0) принимает на вход два значения: цвет текселя и диффузный цвет вершины; производит с ними указанные операции и передает результат на следующий (нижний) уровень. Полученное на предыдущем уровне значение цвета используется в качестве одного из аргумента текущего уровня и т.д. Схематично данные шаги мультитекстурирования можно представить так:

Как уже стало ясно, при мультитекстурировании дело имеют уже с несколькими текстурами. При мультитекстурировании можно для каждого текстурного уровня назначить одни и те же текстурные координаты. В этом случае формат вершины и набор флагов FVF останутся неизмененными. Существует возможность указать, с какими текстурными координатами будет работать тот или иной текстурный уровень. Для этого можно воспользоваться следующими программными строками:
SetTextureStageState(<уровень>, D3DTSS_TEXCOORDINDEX, <номер координат>);
Так, например, чтобы указать, что второй уровень будет использовать текстурные координаты первого текстурного уровня, достаточно воспользоваться следующим вызовом метода: SetTextureStageState( 1, D3DTSS_TEXCOORDINDEX, 0 ). И затем нужно загрузить (установить) текстуры в соответствующие текстурные уровни.
SetTexture( 0, tex1 ); SetTexture( 1, tex2 );
Можно указать для каждого текстурного уровня свои собственные текстурные координаты. В этом случае должен корректно измениться формат вершины при описании и набор FVF флагов. Ниже приведен пример описания вершины и FVF флагов для мультитекстурирования с двумя уровнями (текстурами) и текстурными координатами.
| C++ | struct CUSTOMVERTEX
{
FLOAT x, y, z, rhw; // координаты вершины
FLOAT u1, v1; // текстурные координаты первого уровня
FLOAT u2, v2; // текстурные координаты второго уровня
};
#define MY_FVF (D3DFVF_XYZ | D3DFVF_TEX2)
|
| Pascal | type
MyVertex = packed record
x, y, z, rhw: Single; // координаты вершины
u1,v1: Single; // текстурные координаты первого уровня
u2,v2: Single; // текстурные координаты второго уровня
end;
const
MY_FVF = D3DFVF_XYZRHW or D3DFVF_TEX2;
|
Вообще, число во флаге D3DFVF_TEX как раз и показывает, сколько текстурных уровней планируется задействовать при мультитекстурировании (D3DFVF_TEX1 … D3DFVF_TEX8). Для хранения второй и последующих текстур необходимо объявить соответствующее количество нужных переменных, произвести загрузку текстур с помощью функции D3DXCreateTextureFromFile() и установить текстуры в соответствующие текстурные уровни вызовов метода SetTexture (<номер уровня>, <текстура>). Ниже приведен пример возможного использования двух текстур при мультитекстурировании.
| C++ | LPDIRECT3DTEXTURE9 tex, tex2; … D3DXCreateTextureFromFile( device, "texture.bmp", tex ); D3DXCreateTextureFromFile( device, "texture2.bmp", tex2 ); … device->SetTexture ( 0, tex ); device->SetTexture ( 1, tex2 ); |
| Pascal | var tex, tex2: IDirect3DTexture9; … D3DXCreateTextureFromFile( device, 'texture.bmp', tex ); D3DXCreateTextureFromFile( device, 'texture2.bmp', tex2 ); … device.SetTexture( 0, tex ); device.SetTexture( 1, tex2 ); |
При такой SetTextureStageState интерфейса IDirect3DDevice9:
SetTextureStageState( <номер уровня>, D3DTSS_COLORARG1, <значение> ), SetTextureStageState( <номер уровня>, D3DTSS_COLORARG2, <значение> ), SetTextureStageState( <номер уровня>, D3DTSS_COLOROP, <операция> ).
Помимо уже известных значений констант для цветовых аргументов в данном вызове может быть использована константа D3DTA_CURRENT, которая говорит, что в качестве значения будет браться цвет из предыдущего текстурного уровня.
Также мы можем указать требуемый тип фильтрации текстур для каждого в отдельности текстурного уровня, указав в качестве первого аргумента его номер и вызвав метод SetSamplerState интерфейса IDirect3DDevice9.
Вообще говоря, можно использовать даже одну текстуру для реализации механизма мультитекстурирования. Для этого необходимо в первый и во второй текстурный уровень загрузить одну и ту же текстуру, но при этом значения текстурных координат для них должны отличатся. Программный код для этого случая может выглядеть следующим образом:
… points[0].u1 = 0.0f; points[0].v1 = 1.0f; points[0].u2 = 0.0f; points[0].v2 = 3.0f; … device->SetTexture( 0, tex ); device->SetTexture( 1, tex ); …
Ниже приведен пример мультитекстурирования с помощью одной текстуры и двух текстурных уровней.
device->SetTexture(0, tex); device->SetTextureStageState(0, D3DTSS_TEXCOORDINDEX, 0); device->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE); device->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG1); device->SetTexture(1, tex); device->SetTextureStageState(1, D3DTSS_TEXCOORDINDEX, 1); device->SetTextureStageState(1, D3DTSS_COLORARG2, D3DTA_TEXTURE); device->SetTextureStageState(1, D3DTSS_COLORARG1, D3DTA_CURRENT); device->SetTextureStageState(1, D3DTSS_COLOROP, <operation>); |
|
![]() operation = D3DTOP_MODULATE4X |
![]() operation = D3DTOP_ADD |
Для получения официальных документов о завершении программы дополнительного профессионального образования (удостоверения о повышении квалификации, дипломов о профессиональной переподготовке и MBA) необходимо предоставить:
Внимание! Вы можете не заказывать доставку бумажной версии официального документы, а скачать его в электронном виде и распечатать самостоятельно. Информация о выданном документе в течение 1 месяца загружается в Федеральную информационную систему «Федеральный реестр сведений о документах об образовании и (или) о квалификации, документах об обучении» - ФИС ФРДО.
Доступ на новый сайт осуществляется с использованием адреса электронной почты, который был указан вами при регистрации на "старом". Мы постарались перенести все ваши данные с прежнего ресурса, однако не исключена вероятность потери части информации.
При возникновении проблемы со входом, воспользуйтесь функцией сброса пароля
Если вы обнаружите несоответствия, пожалуйста, сообщите нам.