Навигация
· XNA FAQ
· С чего начать
· Конкурсы
· Обратная связь
· XNA Блоги
Сейчас на сайте
· Гостей: 1

· Пользователей: 0

· Всего пользователей: 3,684
· Новый пользователь: headron
Последние фото
Эх, чуть не проспал закрытие.
Эх, чуть не проспал ...
Альбом: XNA Engine

GB
GB
Альбом: XNA Engine

South Park Coon & Friends
South Park Coon & Fr...
Альбом: XNA Games

Блоги
yavshoke
» XboxOne - интерес...
dampirik
» Push уведомления ...
dampirik
» Реклама,статистик...
Chort
» XNA и StartCoroutine
Chort
» Curve Class
dampirik
» Реклама, статисти...
dampirik
» Увеличение скорос...
dampirik
» Реклама, статисти...
general
» Распаковка DxtCom...
general
» Как работать с XN...
Поддержка
microsoft.com
1gb.ru - Дом для вашего сайта
Статистика посещений:

Урок 7. Как загружать и использовать текстуры
Загрузка текстуры из файла. Передача текстуры в шейдер и использование HLSL для наложения текстуры на 3D-объект.

Шаг 1. Начнём с изменения типа используемых вершин. Раньше мы использовали вершины в которых можно было указывать позицию и цвет. Теперь же нам нужны текстурные координаты и цвет соответственно не нужен, так как цвет будет определяться текстурой. Изменим тип массива вершин с VertexPositionColor на VertexPositionTexture.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
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
private void С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() так же нужно внести изменения связанные со сменой типа используемых вершин.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
void DrawCube()
{
// использовать для отрисовки эффект BasicEffect
effect.Begin();
 
// начать отрисовку первого прохода
effect.CurrentTechnique.Passes[0].Begin();
 
// указать описание формата вершин
graphics.GraphicsDevice.VertexDeclaration = vertexDeclaration;
 
// отключить отсечение невидимых поверхностей
graphics.GraphicsDevice.RenderState.CullMode = CullMode.None;
 
// нарисовать куб используя массив вершин и индексов
graphics.GraphicsDevice.DrawUserIndexedPrimitives<VertexPositionTexture>(
PrimitiveType.TriangleList, // тип примитивов
vertexList, // массив вершин
0, // позиция первой используемой вершины
 8, // кол-во используемых вершин
indexList, // массив индексов
0, // позиция первого используемого индекса
12); // кол-во выводимых примитивов
 
// завершить первый проход
effect.CurrentTechnique.Passes[0].End();
 
// завершить использование эффекта BasicEffect
effect.End();
}

 

Шаг 4. Начнём наконец работать с текстурой. Добавте в класс Program поле texture типа Texture2D. В этом поле будет храниться двухмерная текстура.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
class Program : Game
{
// графический компонент
GraphicsDeviceManager graphics;
 
// массив вершин
VertexPositionTexture[] vertexList;
 
// массив индексов
int[] indexList;
 
// описание формата вершин
VertexDeclaration vertexDeclaration;
 
// эффект (шейдер)
Effect effect;
 
// счетчик времени
float time;
 
// текстура
Texture2D texture;

 

Шаг 5. В метод LoadContent() добавте вызов метода СreateTexture(), в котором позже мы будем загружать текстуру из файла.
1
2
3
4
5
6
7
8
9
10
11
12
protected override void LoadContent()
{
СreateVertexList(); // создать вершины
СreateIndexList(); // создать индексы
СreateEffect(); // загрузить шейдер
СreateTexture(); // загрузить текстуру
 
// создать описание формата вершин
vertexDeclaration = new VertexDeclaration(
graphics.GraphicsDevice,
VertexPositionTexture.VertexElements);
}

 

Шаг 6. Добавте в класс Program метод СreateTexture().
1
2
3
private void СreateTexture()
{
}

 

Шаг 7. Добавте в метод СreateTexture() код загрузки текстуры из файла с помощью статического метода FromFile() классаTexture2D.
1
2
3
4
5
6
7
private void СreateTexture()
{
// загрузить текстуру из файла
texture = Texture2D.FromFile(
graphics.GraphicsDevice,
"texture.jpg");
}

 

Шаг 8. Добавте в метод СreateTexture() код передачи загруженной текстуры в шейдер в параметр tex - этот параметр мы опишем позже в файле шейдера.
1
2
3
4
5
6
7
8
9
10
private void СreateTexture()
{
// загрузить текстуру из файла
texture = Texture2D.FromFile(
graphics.GraphicsDevice,
"texture.jpg");
 
// передаём текстуру в шейдер
effect.Parameters["tex"].SetValue(texture);
}

 

Шаг 9. Добавте в файл шейдера effect.fx объявление переменных текстуры tex и семплера для текстуры textureSampler.
1
2
3
4
5
6
7
8
9
10
11
// матрица трансформации вершин
Matrix worldViewProj;
 
// текстура
Texture tex;
 
// семплер для текстуры
sampler textureSampler = sampler_state
{
texture=<tex>;
};

 

Шаг 10. Измените в файле effect.fx вершинный шейдер с учетом того что теперь в него приходит не цвет вершины, а текстурные координаты. Соответственно выйти из шейдера тоже должны текстурные координаты.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
// вершинный шейдер
void VS(
 
// входящие параметры - позиция и цвет вершины координаты текстуры
in float4 inPos : POSITION,
in float4 inColor : COLOR0,
in float2 inTex : TEXCOORD0,
 
// исходящие параметры - позиция и цвет вершины координаты текстуры
out float4 outPosition : POSITION,
out float4 outColor : COLOR0
out float2 outTex : TEXCOORD0 )
{
// трансформируем позицию вершины с помощью матрицы
outPosition = mul(inPos, worldViewProj);
 
// копируем цвет вершины
outColor = inColor;
 
// копируем координаты текстуры
outTex = inTex;
}

 

Шаг 11. Измените в файле effect.fx входящий параметр пиксельного шейдера с цвета пикселя на координаты текстуры.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// пиксельный шейдер
void PS(
 
// входящий параметр - цвет пикселя
in float4 inColor : COLOR0,
 
// входящий параметр - координаты текстуры
in float2 inTex : TEXCOORD0,
 
// исходящий параметр - цвет пикселя
out float4 outColor : COLOR0 )
{
// копируем цвет пикселя
outColor = inColor;
}

 

Шаг 12. Измените в файле effect.fx логику пиксельного шейдера: теперь вместо простого копирования цвета пикселя нужно выполнить запрос к двухмерной текстуре для определения цвета текущего пикселя с помощью функции tex2D. Эта функция принимает семплер и текстурные координаты.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// пиксельный шейдер
void PS(
 
// входящий параметр - координаты текстуры
in float2 inTex : TEXCOORD0,
 
// исходящий параметр - цвет пикселя
out float4 outColor : COLOR0 )
{
// копируем цвет пикселя
outColor = inColor;
 
// выполняем запрос к текстуре используя координаты текстуры
outColor = tex2D(textureSampler, inTex);
}

 

Шаг 13. Теперь нехватает самого главного - собственно текстуры. Кликните правой кнопкой по имени проекта в окне "Solution Explorer". В появившемся меню выберите команду "Add -> Existing Item...". С помощью открывшегося окна выберите любой графический файл и добавьте его в проект.

Шаг 14. Назовите дабавленный файл texture.jpg и измените значение опции "Copy to Output Directory" с "Do not copy" на "Copy always" в окне "Properties".


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


В секции загрузок лежит архив с исходным кодом этого и других уроков.


Комментарии
#1 | freeExec 21.07.2009 09:20:52
Почему-то срока
// передаём текстуру в шейдер
effect.Parameters["tex"].SetValue(texture);
вызывает ошибку - "В экземпляре объекта не задана ссылка на объект."
Гружу текстуру texture = Content.Load<Texture2D>("texture"Wink; как в файловом примере, а не как на странице тут.
Хотя может загвозка в том, что я постепенно модифицировал свой пример начиная с первого урока. Но до этого всё работало.
#2 | Zloy_Tip 18.02.2011 23:44:49
Мдя, та ж проблема возниклаSmile и, хоть автору предидущего коммента это уже скорее всего не нужно:
У меня было так..
СreateTexture(); // загрузить текстуру
// создать объект Effect используя контент менеджер
effect = Content.Load<Effect>("Effect1"Wink;

А надо сначала создать эффект, а потом текстуру Smile
Добавить комментарий
Пожалуйста, залогиньтесь для добавления комментария.
Рейтинги
Рейтинг доступен только для пользователей.

Пожалуйста, залогиньтесь или зарегистрируйтесь для голосования.

Нет данных для оценки.
Авторизация
Логин

Пароль



Вы не зарегистрированы?
Нажмите здесь для регистрации.

Забыли пароль?
Запросите новый здесь.
Мини-чат
Вы должны авторизироваться, чтобы добавить сообщение.

27.08.2014
Я умею немного на asp.net + html и css

22.08.2014
на ASP mvc 3 есть пару проектов. Могу помочь, если нужно. Обидно, если закроется Frown

21.08.2014
я тоже ноль

21.08.2014
Я в вебе только с php занимался да и то на уровне чтоб работало.

21.08.2014
Я в вебе полный ноль…

21.08.2014
Переводить его надо, хоть на ту же азуру. И двиг менять на что-то современное. Если есть веб-разрабы - можем скооперироваться. Один делать не буду.

21.08.2014
не знаю всех нюансов по оплате и все хорошее когда нибудь заканчивается

21.08.2014
А что случилось?

21.08.2014
похоже сайт будет работать до 28го числа

09.08.2014
Апи пока не видел. Но есть приложение в магазине Live Lock Screen BETA, так что думаю скоро будет

08.08.2014
Я про API для Update1. На нем работает это

08.08.2014
А что именно нужно? Чтото и сейчас открыто http://msdn.micro.
...105).aspx

06.08.2014
Кто-нибудь слышал об открытии доступа к Lock Screen Api?

31.07.2014
VPDExpress на базе MVS 2012, ни в какую не ловит исключения. Даже если их сам создаешь. И всех так?

25.07.2014
С днем системного администратора причастных к этой профессии! По случаю - тортик от жены

RSS каналы сайта
XNA - Новости
XNA - Статьи
XNA - Форум
XNA - Галерея
XNA - Файлы
Время загрузки: 0,05 секунд 8,709,565 уникальных посетителей