Загрузка текстуры из файла. Передача текстуры в шейдер и использование HLSL для наложения текстуры на 3D-объект.
Шаг 1.
Начнём с изменения типа используемых вершин. Раньше мы использовали
вершины в которых можно было указывать позицию и цвет. Теперь же нам
нужны текстурные координаты и цвет соответственно не нужен, так как
цвет будет определяться текстурой. Изменим тип массива вершин с VertexPositionColor на VertexPositionTexture.
class Program : Game { // графический компонент GraphicsDeviceManager graphics; // массив вершин VertexPositionColor[] vertexList; VertexPositionTexture[] vertexList; // массив индексов int[] indexList; // описание формата вершин VertexDeclaration vertexDeclaration; // эффект (шейдер) Effect effect; // счетчик времени float time;
Шаг 2. В методе СreateVertexList() во-первых, так же нужно заменить тип вершин на VertexPositionTexture. Во-вторых, заметьте что у вершин типа VertexPositionTexture конструктор принимает не цвет вершины, а текстурные координаты описываемые структурой типа Vector2. Координаты текстуры задаются в диапазоне 0...1. Первая координата описывает Х, вторая - Y в двухмерной текстуре.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
privatevoid СreateVertexList() { // создать массив-контейнер для хранения трёх вершин vertexList =new VertexPositionTexture[8]; // нижний набор вершин vertexList[0]=new VertexPositionTexture(new Vector3(-1.0f, -1.0f, 1.0f), new Vector2(0, 1)); vertexList[1]=new VertexPositionTexture(new Vector3(1.0f, -1.0f, 1.0f), new Vector2(1, 1)); vertexList[2]=new VertexPositionTexture(new Vector3(-1.0f, -1.0f, -1.0f), new Vector2(0, 0)); vertexList[3]=new VertexPositionTexture(new Vector3(1.0f, -1.0f, -1.0f), new Vector2(1, 0)); // верхний набот вершин vertexList[4]=new VertexPositionTexture(new Vector3(-1.0f, 1.0f, 1.0f), new Vector2(1, 1)); vertexList[5]=new VertexPositionTexture(new Vector3(1.0f, 1.0f, 1.0f), new Vector2(0, 1)); vertexList[6]=new VertexPositionTexture(new Vector3(-1.0f, 1.0f, -1.0f), new Vector2(1, 0)); vertexList[7]=new VertexPositionTexture(new Vector3(1.0f, 1.0f, -1.0f), new Vector2(0, 0)); }
Шаг 3. В метод DrawCube() так же нужно внести изменения связанные со сменой типа используемых вершин.
Шаг 10. Измените в файле effect.fx
вершинный шейдер с учетом того что теперь в него приходит не цвет
вершины, а текстурные координаты. Соответственно выйти из шейдера тоже
должны текстурные координаты.
// вершинный шейдер void VS( // входящие параметры - позиция и цвет вершины координаты текстуры infloat4 inPos :POSITION, infloat4 inColor : COLOR0, infloat2 inTex :TEXCOORD0, // исходящие параметры - позиция и цвет вершины координаты текстуры outfloat4 outPosition :POSITION, outfloat4 outColor : COLOR0 outfloat2 outTex :TEXCOORD0) { // трансформируем позицию вершины с помощью матрицы outPosition = mul(inPos, worldViewProj); // копируем цвет вершины outColor = inColor; // копируем координаты текстуры outTex = inTex; }
Шаг 11. Измените в файле effect.fx входящий параметр пиксельного шейдера с цвета пикселя на координаты текстуры.
Шаг 12. Измените в файле effect.fx
логику пиксельного шейдера: теперь вместо простого копирования цвета
пикселя нужно выполнить запрос к двухмерной текстуре для определения
цвета текущего пикселя с помощью функции tex2D. Эта функция принимает семплер и текстурные координаты.
Шаг 13. Теперь нехватает самого главного - собственно текстуры. Кликните правой кнопкой по имени проекта в окне "Solution Explorer". В появившемся меню выберите команду "Add -> Existing Item...". С помощью открывшегося окна выберите любой графический файл и добавьте его в проект.
Шаг 14. Назовите дабавленный файл texture.jpg и измените значение опции "Copy to Output Directory" с "Do not copy" на "Copy always" в окне "Properties".
Теперь при запуске приложения вы увидите окно в котором будет нарисован куб покрытый текстурой. В секции загрузок лежит архив с исходным кодом этого и других уроков.