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

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

· Всего пользователей: 7,142
· Новый пользователь: Sarahseato
Последние фото
Thurs Puzzle
Thurs Puzzle
Альбом: XNA Games

Thurs Puzzle
Thurs Puzzle
Альбом: XNA Games

Thurs Puzzle
Thurs Puzzle
Альбом: XNA Games

Блоги
general
» Unity3D – Chunky ...
general
» Unity3D: Simple p...
dampirik
» Записки программи...
dampirik
» Локализация прило...
dampirik
» Эффективность рас...
general
» HLSL: Шейдер воды
general
» Unity 3D: Управле...
general
» Unity 3D: FPS scr...
yavshoke
» XboxOne - интерес...
dampirik
» Push уведомления ...
Поддержка
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
Добавить комментарий
Пожалуйста, залогиньтесь для добавления комментария.
Рейтинги
Рейтинг доступен только для пользователей.

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

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

Пароль



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

11.12.2023

11.12.2023
[img]https://x.pin
-up-world.com/imag
es/img4.jpg[/img]
[url=https://ofoi.
cenditt.loan/new-k
atiana-kay-fucking
-with-lucky-fan-p1
-porn-scenes/]133K
67% New Katiana

11.12.2023
[img]https://wwt.s
sgameadmin2.com/im
ages/img4.jpg[/img
]
[url=https://k.smi
letaxservice.com/r
edirect/SFpEdDR1cG
V4czNKMmxlQi9tVytI
d3dxWW9GWTd5Zk52TD
VVMG1mc3YvUmlDMWUw

11.12.2023

11.12.2023

10.12.2023
[img]https://ey.os
prey-holidays.uk/i
mages/img10.jpg[/i
mg]
[url=https://nby.h
ighlyresponsible.c
om/696488/sexyfeet
girl2020-gotta-kee
p-them-soft-lookin
g-

30.11.2023
[img]https://nuggi
e.army/images/img1
5.jpg[/img]
German Porno kostenlos - Deutsche Pornos &amp; Pornofilme. [url=ht

30.11.2023

30.11.2023
[img]https://where
ijoin.com/images/i
mg8.jpg[/img]
Voir Films VF VOSTFR - . [url=http://mvig.j
ulieemontelaro.com
/]omegleX

30.11.2023
[img]https://steam
unlocked.tangobliv
ion.com/images/img
14.jpg[/img]
Top - Rated Live Sex Cam Videos to Watch Online. [

29.11.2023

29.11.2023
[img]https://chaii
t.com/images/img8.
jpg[/img]
Ottmaza.live - Ottmaza.Com Official Website | Ottmaza | Ottmaza.Net | Ottmaz

29.11.2023
[img]https://ezyja
mb.co.uk/images/im
g10.jpg[/img]
Free Porn - Sex, Tube Videos, XXX Pics, Pussy in Porno

29.11.2023
[img]https://launc
hbusinessloans.org
/images/img15.jpg[
/img]
Asyalı - Koreli Japon Seks Filmleri Türkçe A

29.11.2023
[img]https://panen
poker.org/images/i
mg8.jpg[/img]
[url=http://watchm
ovies.seoullittlem
all.com/]Junkie Musik Lossless &#ff7dee MГєsica ElectrГіnica p

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