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

16.2. Компиляция шейдеров на HLSL

16.2.1. Таблица констант

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

Сейчас мы приведем сокращенный список методов, реализуемых интерфейсом ID3DXConstantTable. Если вам необходим полный список, обратитесь к документации Direct3D.

16.2.1.1. Получение дескриптора константы

Чтобы установить значение какой-нибудь переменной шейдера из кода нашего приложения, необходим способ сослаться на эту переменную. Для этой цели применяется тип D3DXHANDLE. Приведенный ниже метод возвращает значение типа D3DXHANDLE, указывающее на переменную шейдера с заданным именем:

D3DXHANDLE ID3DXConstantTable::GetConstantByName(
     D3DXHANDLE hConstant, // область видимости
     LPCSTR pName          // имя
);

Например, если имя переменной в коде шейдера ViewProjMatrix и это переменная верхнего уровня, то для получения дескриптора следует написать:

// Получение дескриптора переменной шейдера ViewProjMatrix
D3DXHANDLE h0;
h0 = ConstTable->GetConstantByName(0, "ViewProjMatrix");

16.2.1.2. Установка констант

Как только наше приложение получило значение D3DXHANDLE, ссылающееся на требуемую переменную в коде шейдера, мы можем установить значение этой переменной из нашего приложения с помощью метода ID3DXConstantTable::SetXXX, где XXX заменяется на название типа переменной, значение которой устанавливается. Например, если мы хотим установить значения массива векторов, следует воспользоваться методом SetVectorArray.

Общий синтаксис всех методов ID3DXConstantTable::SetXXX выглядит так:

HRESULT ID3DXConstantTable::SetXXX(
     LPDIRECT3DDEVICE9 pDevice,
     D3DXHANDLE hConstant,
     XXX value
);

Если мы инициализируем массив, то у метода SetXXX появляется дополнительный четвертый параметр, задающий количество элементов массива. Например, прототип метода для установки значений массива четырехмерных векторов, выглядит так:

HRESULT ID3DXConstantTable::SetVectorArray(
     LPDIRECT3DDEVICE9 pDevice,  // связанное устройство
     D3DXHANDLE hConstant,       // дескриптор переменной шейдера
     CONST D3DXVECTOR4* pVector, // указатель на массив
     UINT Count                  // количество элементов массива
);

Приведенный ниже список описывает типы, которые мы можем инициализировать с помощью интерфейса ID3DXConstantTable. Подразумевается, что корректное устройство (Device) и корректный дескриптор переменной (handle) уже получены.

16.2.1.3. Установка значений по умолчанию для констант

Приведенный ниже метод присваивает всем константам значения по умолчанию, то есть те значения, которые были заданы при объявлении переменных. Метод должен вызываться один раз при инициализации данных приложения.

HRESULT ID3DXConstantTable::SetDefaults(
     LPDIRECT3DDEVICE9 pDevice
);

16.2.2. Компиляция HLSL-шейдера

Мы можем скомпилировать шейдер, код которого хранится в текстовом файле, с помощью следующей функции:

HRESULT D3DXCompileShaderFromFile(
     LPCSTR               pSrcFile,
     CONST D3DXMACRO*     pDefines,
     LPD3DXINCLUDE        pInclude,
     LPCSTR               pFunctionName,
     LPCSTR               pTarget,
     DWORD                Flags,
     LPD3DXBUFFER*        ppShader,
     LPD3DXBUFFER*        ppErrorMsgs,
     LPD3DXCONSTANTTABLE* ppConstantTable
);

Вот пример вызова функции D3DXCompileShaderFromFile:

//
// Компиляция шейдера
//
ID3DXConstantTable* TransformConstantTable = 0;
ID3DXBuffer* shader = 0;
ID3DXBuffer* errorBuffer = 0;

hr = D3DXCompileShaderFromFile(
      "transform.txt",  // имя файла шейдера
      0,
      0,
      "Main",           // имя точки входа
      "vs_2_0",         // версия шейдеров
      D3DXSHADER_DEBUG, // компиляция для отладки
      &shader,
      &errorBuffer,
      &TransformConstantTable);

// Выводим сообщения об ошибках
if(errorBuffer)
{
     ::MessageBox(0, (char*)errorBuffer->GetBufferPointer(), 0, 0);
     d3d::Release<ID3DXBuffer*>(errorBuffer);
}

if(FAILED(hr))
{
     ::MessageBox(0, "D3DXCreateEffectFromFile() - FAILED", 0, 0);
     return false;
}

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

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