Наложение текстур Direct3D

С помощью технологии наложения текстур мы можем сопоставить данные изображения с треугольными единицами. Эта функция может значительно повысить детализацию и реалистичность нарисованной сцены. Например, создание куба, а затем наложение текстуры доски на каждую грань приведет к тому, что куб станет ящиком. В Direct3D текстура представлена ​​интерфейсом IDirect3DTexture9 . Текстура представляет собой пиксельную матрицу, аналогичную поверхности. В отличие от поверхности, она может быть отображена в треугольные блоки.

Координаты текстуры

Система координат текстуры, используемая блокировкой Direct3D, состоит из оси u в горизонтальном направлении и оси v в вертикальном направлении. Элемент текстуры, идентифицируемый парой координат (u, v), называется элементом текстуры. Обратите внимание, что положительное направление оси v вертикально.

Чтобы иметь возможность обрабатывать текстуры разных масштабов, Direct3D нормализует координаты текстуры так, чтобы они были ограничены интервалом [0,1].Для каждой единицы 3D-треугольника мы можем определить соответствующую область треугольника в текстуре, а затем Map текстуру в области треугольника в блок 3D-треугольника.Чтобы добиться такого сопоставления, необходимо снова изменить структуру вершин и добавить к ней пару координат текстуры для идентификации вершин в текстуре.

struct TextureVertex
{
	TextureVertex(){}
	TextureVertex()
	{

	}
	float _x, _y, _z;
	float _nx, _ny, _nz;
	float _u, _v;			//纹理坐标
	static const DWORD FVF;
};
const DWORD TextureVertex::FVF = D3DFVF_XYZ | D3DFVF_NORMAL | D3DFVF_TEX1; //D3DFVF_TEX1表示顶点结构中包含了一对纹理坐标

Теперь каждому треугольнику, образованному 3-мя вершинными объектами, соответствует соответствующий треугольник текстуры, определенный в этой системе координат текстуры. Несмотря на то, что это указано, текстура не будет использоваться до растеризации, когда 3D-треугольник будет преобразован в систему координат экрана. Отображение будет иметь место .

Создание и включение текстур

Данные текстуры обычно считываются из файла изображения на диске, а затем загружаются в объект IDirect3DTexture9. Этого можно добиться с помощью функции D3DXCreateTextureFromFile, которая может загружать изображения в следующих форматах: BMP, DDS, DIB, JPG, PNG и TGA.

HRESULT D3DXCreateTextureFromFile(
	LPDIRECT3DDEVICE9         pDevice,
	LPCSTR                    pSrcFile,
	LPDIRECT3DTEXTURE9*       ppTexture
);
IDirect3DTexture9* _stonewall;
D3DXCreateTextureFromFile(Device, "stonewall.bmp", &_stonewall);

HRESULT IDirect3DDevice9::SetTexture(
	DWORD Stage,	//纹理层
	IDirect3DBaseTexture9* pTexture
);

//禁用某一纹理层,可将pTexture参数设为0,绘制物体时若不想使用纹理可以这样做
Device->SetTexture(0, 0);
renderObjectWithoutTexture();

//如果场景中的各个三角形所使用的纹理均不相同
Device->SetTexture(0, tex0);
drawTrisUsingTex0();

Device->SetTexture(0, tex1);
drawTrisUsingTex1();

В Direct3D можно настроить до 8 слоев текстур , которые можно комбинировать для создания более детального изображения.Это называется мультитекстурированием .

текстурный фильтр

Обычно размер треугольника текстуры и треугольника экрана не совпадают.Когда размер треугольника текстуры и треугольника экрана несовместимы, чтобы адаптироваться к последнему, треугольник текстуры необходимо увеличить или уменьшить.В обоих случаях , происходит искажение.Чтобы в некоторой степени его преодолеть. Для этого типа искажений Direct использует технологию, называемую фильтрацией текстур .

Direct3D предоставляет 3 типа фильтров текстур: чем выше качество фильтра, тем больше вычислительные затраты и медленнее скорость обработки. Метод фильтрации текстур можно задать с помощью метода SetSamplerState .

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

Линейный фильтр текстур : этот тип фильтрации может дать довольно хорошие результаты и работает быстро при текущих конфигурациях оборудования.

Анизотропная фильтрация текстур : этот тип фильтрации может дать наилучшие результаты, но скорость обработки также самая медленная.При использовании этой фильтрации необходимо установить значение уровня D3DSAMP_MAXANISOTROPIC, которое определяет качество анизотропной фильтрации.уровень. Чем больше значение, тем лучше эффект изображения. Вызовите функцию IDirect3DDevice::GetDeviceCaps, чтобы проверить возвращаемые параметры структуры D3DCAPS9, чтобы получить допустимый диапазон значений значения, поддерживаемого оборудованием.

//设置最近点采样纹理过滤
Device->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
Device->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_POINT);

//设置线性纹理过滤
Device->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
Device->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);

//设置各向异性纹理过滤
Device->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_ANISOTROPIC);
Device->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_ANISOTROPIC);

//将各向异性过滤的质量水平设置为4
Device->SetSamplerState(0, D3DSAMP_MAXANISOTROPY, 4);

Многоуровневая прогрессивная текстура

Треугольники на экране обычно не имеют того же размера, что и треугольники текстуры.Чтобы минимизировать влияние, вызванное разницей в размерах между ними, мы можем создать многоуровневую прогрессивную цепочку текстур для текстуры, создав серию постепенно уменьшение разрешения определенной текстуры. Изображение текстуры и фильтр, используемый для текстуры в каждом разрешении, должны быть настроены, чтобы сохранить более важные детали. Очень легко использовать многоуровневые прогрессивные текстуры в Direct3D. Если оборудование поддерживает многоуровневые прогрессивные текстуры, функция D3DXCreateTextureFromFile создаст Многоуровневую прогрессивную цепочку текстур.Кроме того, Direct3D автоматически выберет из цепочки текстур текстуру первого уровня, которая лучше всего соответствует треугольнику экрана.Поэтому, поскольку она может быть установлена ​​автоматически Direct3D, а затраты времени и пространства при обработке относительно невелики, широко используются многоуровневые прогрессивные текстуры.

Многоуровневый прогрессивный фильтр текстур.

Многоуровневый прогрессивный фильтр текстур в основном используется для управления тем, как Direct3D использует многоуровневые прогрессивные текстуры.Вы можете установить многоуровневый прогрессивный фильтр текстур следующим образом.

Device->SetSamplerState(0, D3DSAMP_MIPFILTER, Filter);

Фильтр может принимать следующие значения

D3DTEXF_NONE : отключить многоуровневый фильтр прогрессивной текстуры.
D3DTEXF_POINT : используя этот фильтр, Direct3D выберет уровень текстуры, размер которого ближе всего к треугольнику экрана. После выбора уровня текстуры Direct3D будет использовать указанный фильтр усиления и Фильтр уменьшения фильтрует текстуру этого уровня.
D3DTEXF_LINEAR : используя этот фильтр, Direct3D возьмет два уровня текстуры, наиболее близкие к размеру треугольника экрана, будет использовать указанный фильтр увеличения и фильтр уменьшения для фильтрации каждого уровня текстуры, а затем эти два уровня затем текстуры линейно комбинируются для формирования окончательного значения цвета.

Режим адресации

В предыдущем разделе мы говорили, что координаты текстуры должны быть ограничены интервалом [0,1].С технической точки зрения это проблематично, поскольку иногда координаты могут выходить за этот диапазон.Direct3D определяет 4 метода для обработки значений координат текстуры. Режим наложения текстур с интервалом, превышающим [0,1]. Это режим повторной адресации (wrap), режим адресации по цвету рамки (border color), режим фиксированной адресации (clamp) и режим зеркальной адресации (mirror).

//set wrap address mode
if (::GetAsyncKeyState('W') & 0x8000f)
{
	//表示对纹理的u方向或v方向设置纹理寻址模式
	Device->SetSamplerState(0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
	Device->SetSamplerState(0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP); 
	//D3DTADDRESS_CLAMP、D3DTADDRESS_MIRROR
}

//set border color address mode
if (::GetAsyncKeyState('B') & 0x8000f)
{
	//表示对纹理的u方向或v方向设置纹理寻址模式
	Device->SetSamplerState(0, D3DSAMP_ADDRESSU, D3DTADDRESS_BORDER);
	Device->SetSamplerState(0, D3DSAMP_ADDRESSV, D3DTADDRESS_BORDER);
	Device->SetSamplerState(0, D3DSAMP_BORDERCOLOR, 0x000000ff);
}

Текстурированная четверная программа

1. Постройте вершины, составляющие объект, и укажите для них координаты текстуры.
2. Используйте функцию D3DXCreateTextureFromFile, чтобы загрузить текстуру для интерфейса IDirect3DTexture9.
3. Установите фильтр уменьшения/усиления и многоуровневый прогрессивный фильтр текстур.
4 . Перед рисованием объекта используйте функцию IDirect3DDevice9::SetTexture, чтобы установить текстуру, связанную с объектом.

bool SetUpTextureQuad()
{
	Device->CreateVertexBuffer(6 * sizeof(TextureVertex), D3DUSAGE_WRITEONLY, TextureVertex::FVF, D3DPOOL_MANAGED, &Quad, 0);
	TextureVertex* v;
	Quad->Lock(0, 0, (void**)&v, 0);
	v[0] = TextureVertex(-1.0f, -1.0f, 1.25f, 0.0f, 0.0f, -1.0f, 0.0f, 3.0f);
	v[1] = TextureVertex(-1.0f, 1.0f, 1.25f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f);
	v[2] = TextureVertex(1.0f, 1.0f, 1.25f, 0.0f, 0.0f, -1.0f, 3.0f, 0.0f);

	v[3] = TextureVertex(-1.0f, -1.0f, 1.25f, 0.0f, 0.0f, -1.0f, 0.0f, 3.0f);
	v[4] = TextureVertex(1.0f, 1.0f, 1.25f, 0.0f, 0.0f, -1.0f, 3.0f, 0.0f);
	v[5] = TextureVertex(1.0f, -1.0f, 1.25f, 0.0f, 0.0f, -1.0f, 3.0f, 3.0f);
	Quad->Unlock();
	
	D3DXCreateTextureFromFile(Device, "dx5_logo.bmp", &Tex);
	//启用纹理
	Device->SetTexture(0, Tex);
	//设置放大/缩小过滤器
	Device->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
	Device->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
	//设置渐进纹理过滤器
	Device->SetSamplerState(0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);

	//不使用光照
	Device->SetRenderState(D3DRS_LIGHTING, false);

	D3DXMATRIX proj;
	D3DXMatrixPerspectiveFovLH(&proj, D3DX_PI * 0.5f, (float)Width / (float)Height, 1.0f, 1000.0f);
	Device->SetTransform(D3DTS_PROJECTION, &proj);
	return true;
}

bool DisplayTextureQuad(float timeDelta)
{
	if (Device)
	{
		Device->Clear(0, 0, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 1.0f, 0);
		Device->BeginScene();
		Device->SetStreamSource(0, Quad, 0, sizeof(TextureVertex));
		Device->SetFVF(TextureVertex::FVF);
		Device->DrawPrimitive(D3DPT_TRIANGLELIST, 0, 2);
		Device->EndScene();
		Device->Present(0, 0, 0, 0);
	}
	return true;
}

Supongo que te gusta

Origin blog.csdn.net/SwordArcher/article/details/132803354
Recomendado
Clasificación