{{notification.text}}

MirGames

Daimos
06.07.10 05:28
0
Доброе время суток!

Меня интересует технология перехода одного тайла к другому. Скажем grid залит каким то одним тайлом, есть еще несколько типов тайлов. Если на один блок (она же ячейка или полигон) один раз нанести другой тайл, то он будет очень прозрачным, если постепенно наносит на один и тот же тайл другую текстуру то она постепенно заменит основной тайл, а приближенные края четырех соседних блоков будут иметь смешанный тайл. В общем на скриншоте это показано.

Первая мысль которая пришла в голову: Имеется текстура состоящая из наборов основных тайлов, в процессе загрузки карты, создаются новая текстура под тайлы с переходами, там в реал-тайме делается blending(смешивание), т. е. один тайл превращается в несколько переходных видов тайлов. Ну тогда проблема состоит в том что слишком уж много может получиться комбинаций различных тайлов, что не есть хорошо.

Вторая мысль: генерировать большую текстуру, но во первых нельзя использовать jpg, только png, что соответственно скажется на количестве занимаемой памяти не только в оперативке но и в файле, т. к. планируются карты намного больше чем в HoMM (это будет в обще не стратегия).

Из методов текстурирования кроме как с простым UV-текстурированием больше не с чем не знаком (может есть какое нибудь мультитекстурирование, где как бы это выразить послойное текстурирование что-ли с blending'ом выполняемое скажем DirectX или OpenGL подсистемами?) или может это делается с помощью шейдеров(с которыми я так же пока не знаком)?

Вопросы:
Как это делается в HoMM5?
Есть ли еще другие способы сделать те же эффекты перехода?
Исходники? Статьи?

Прошу просветить меня :)
#1
06.07.10 11:45
0
1. хранить веса текстур в атрибутах вершин
2. хранить веса текстур в 1 больщой ( несколько маленьких ) текстуре

и смешивать все это дело в пиксельном шейдере

поищи про texture splatting

пс: очепятки
Отредактировано: 06.07.10 11:47
#3
06.07.10 21:39
0
Вот способ:
1) Для начала определимся с максимальным количеством тайлов участвующих в комбинации (допустим 2)
2) Пишем редактор с помощью которого рисуем на ландшафте такие вот красоты, на выходе получаем 2 карты первая - индексы тайлов (1 или 2 на ячейку) и 2ая здоровущая карта маски (весов текстур) ну и набор тайлов, 1ую сохраняем как есть а от второй нам нужны только векторные данные т.е. данные о том куда тыкал скока держал нажатой кнопку, радиус кисти, узор и так далее это полюбому будет меньше чем огромный 2мерный растр.
3) При рендеринге уже в игре интерпритируем векторную карту маски, но не в здоровый растр а в такую же таблицу тайлов (т.к. будет очень много абсолютно белых и черных тайлов) т.е. в процессе инициализации конечно проще в память шлепнуть здоровую карту но потом это все слегкостью оптимизируется(сжимается) в таблицу тайлов смешивания(маски) ну и текстурировать в шейдере как сказал товарищ rain, по сути это предложенный им 2ой способ только дополненный сжатием карты весов текстур
#4
06.07.10 22:28
0
Venum
что-то по моему какой-то бред)
Отредактировано: 06.07.10 22:36
#5
07.07.10 01:26
0
Цитата
что-то по моему какой-то бред)


Конкретней плз ^_^

Daimos
Еще можно ввести палитру тайлов смешивания и распознавать их в готовой маске учитывая смещения, будет конечно хуже но зато по памяти и быстродействию расход сократится очень ощутимо
#6
07.07.10 14:54
0
в героях вроде как и в варике 3. все ручками.
#7
Daimos
08.07.10 02:33
0
Спасибо всем кто ответил!

Еще не совсем разобрался :(

Вопросы:
Есть ограничения в шейдерах Texture Splatting (кол-во тайлов, и др.)?

Цитата(Куршак @ Сегодня, 06:54)
[snapback]104066[/snapback]
в героях вроде как и в варике 3. все ручками.

Как это ручками?

#8
08.07.10 10:32
0
Цитата(Venum @ Вчера, 03:26)
[snapback]104064[/snapback]
Конкретней плз


Цитата(RzCoDer @ 6.07.2010 - 17:54)
[snapback]104060[/snapback]
сохраняем как есть а от второй нам нужны только векторные данные т.е. данные о том куда тыкал скока держал нажатой кнопку, радиус кисти, узор и так далее это полюбому будет меньше чем огромный 2мерный растр.


Если дизайнер будет делать карту 15-20 часов, то таких данных накопится уйма просто и грузиться это будет очень не быстро.

Совершенно не понял зачем тебе здоровенный растр? При особом извращении в карту 1024x1024 RGBA можно ужать информацию о 8 различных типах земли. По моему не так много + можно использовать примитивное сжатие.
Отредактировано: 08.07.10 11:27
#9
08.07.10 23:25
0
Daimos
Можно попробовать реализовать подобное мульти-проходным рендерингом. Он заключается в том, что каждый новый тип накладываемой текстуры будет требовать отрисовки участка ландшафта на который эта текстура нанесена, и последующим сложением с результатом в фреймбуффере. В D3D можно без шейдеров:

Создается 1 общий VB, который хранит геометрию ландшафта (Pos + Normal).
Для каждого участка с оригинальной текстурой создается:
1 VB (TexCoord + D3DCOLOR) и 1 IB, который индексирует нужные треугольники из общего буффера для конкретного типа требуемой текстуры.
У каждого VB в TexCoord лежат затайленные текс. координаты, а в D3DCOLOR цвет + альфа(для плавного перехода, на границах поверхности).

Рисуется так:

- Включаем Depth.
- Первым проходом отрисовываем полностью весь ландшафт(поверхность) с дефолтной текстурой, например травой. Получаем большущий ландшафт, покрытый сплошной травой.
- Устанавливаем Depth только на чтение с режимом LESSEQUAL.
- Включаем аддитивный блендинг.
- Для каждого последующего участка с уникальной текстурой, ставим + 1 VB во второй стрим(в первом у нас уже забинден общий буффер), + свой IB. Рисуем участок.

Получится в какой-то степени тот же сплаттинг, но на FFP. Плюс такого метода в неограниченности текстурных слоев, правда всегда надо знать меру :)

Цитата(Daimos @ Вчера, 18:33)
[snapback]104077[/snapback]
Вопросы:
Есть ограничения в шейдерах Texture Splatting (кол-во тайлов, и др.)?

Скажем, для "чистого клинического" случая :) - 5 текстур(или тайлов). Данный метод предполагает использование "маски весов" для смешивания текстур:
Код

W = 1 - (Mask.R + Mask.G + Mask.B + Mask.A); //суммарный "вес" равен 1
Result = Texture1 * Mask.R + Texture2 * Mask.G + Texture3 * Mask.B + Texture4 * Mask.A + Texture5 * W;

Но как правило, в реальной жизни такого не бывает :). Т.к. в подобной жизни существуют еще и карты теней, и нормаль карты(в случае Normal Map'a + карты высот, в случае Parallax'a), etc... В общем, текстурных юнитов по-просту не хватит на все это.
Отредактировано: 08.07.10 23:30
#10
09.07.10 02:07
0
Цитата(JKot @ 8.07.2010 - 06:32) [snapback]104080[/snapback]

Если дизайнер будет делать карту 15-20 часов, то таких данных накопится уйма просто и грузиться это будет очень не быстро.

Совершенно не понял зачем тебе здоровенный растр? При особом извращении в карту 1024x1024 RGBA можно ужать информацию о 8 различных типах земли. По моему не так много + можно использовать примитивное сжатие.

Даже если он ее три дня будет делать, это будет весить меньше чем большой растр даже с 1 байтовыми пикселями (1024 это маленький) возьмем к примеру HOMM в среднюю карту вмещается три-четыре(даже скорее всего больше) экрана, допустим разрешение экрана 1024x768 таким образом имеем что минимальный размер текстуры 4096^2 = ~17мегабайт, а теперь представим трехдневную напряженную работу (в сутки средний человек бодрствует 16 часов это 960 минут, трое суток 2880 минут бодрствования) допустим наш дезигнер заводной и делает 1 действие в 3 секунды т.е. 20 действ./мин определимся сколько будем выделять памяти на 1 действие допустим идентификатор действия будет занимать 4 байта но нужны и параметры дадим на них 16байт (4 float'а) итого 20 байт (что даже больше похоже на максимум а не среднее кол-во занимаемой памяти одним действием) посчитаем
2880мин * 20действ/мин * 20байт = 1.2мегабайт против ~17мегабайт 4096^2 текстуры? ты же приводишь 15-20 часовую работу и 1024 карту (которая является очень маленькой при текстуринге больших ландшафтов), 15-20 часов это примерно 1/3 объема т.е. 0.4мб а 1024^2 карта это мегабайт, коэфф в пользу векторных данных равен двум с половиной. Сжатие опустил т.к. и векторные и растровые данные могут быть хорошо сжаты.

А различные типы земли и так имелись ввиду (карта индексов типов земли + большая карта смешивания этих типов, с 1 байтовыми пикселями).
Отредактировано: 09.07.10 02:18
#11
09.07.10 10:59
0
Цитата
в среднюю карту вмещается три-четыре(даже скорее всего больше) экрана, допустим разрешение экрана 1024x768 таким образом имеем что минимальный размер текстуры 4096^2 = ~17мегабайт


Зачем? O_o Это же не мегатекстура, это же просто карта атрибутов, её можно взять совсем маленькую, фильтрация все сделает за вас, а потом, по этой растянутой карте атрибутов уже накладывать текстуры поверхности с высоким разрешением, пусть даже способом, который описал Xander

А что ты скажешь, на счёт загрузки? Делать её будет в разы тяжелее это раз и грузиться будет не по мерно долго это 2.
#12
Daimos
11.07.10 07:14
0
Xander
DirectX я не изучал, копаю Irrlicht, посему следующие вопросы:

VB - VertexBuffer?
IB - IndexBuffer?
FFP - Fixed Function Pipeline?

Не хочу показаться наглым, но можно ли поподробней? И желательно языком для чайника :)

И еще - можно ли этот метод прикрутить к Irrlicht?
#13
13.07.10 15:52
0
Цитата
VB - VertexBuffer?
IB - IndexBuffer?
FFP - Fixed Function Pipeline?

Все верно.

Цитата
Не хочу показаться наглым, но можно ли поподробней?

Спрашивай конкретнее, что именно интересует.

Цитата
И еще - можно ли этот метод прикрутить к Irrlicht?

Я с этим движком никогда не работал. Но думаю можно без проблем - должно быть даже проще.

P.S. Раз ты уже готовый движок используешь, неужели там примеров с ландшафтом нет, чтобы разобраться?
#14
Daimos
14.07.10 04:15
0
Xander
Есть ландшафт: карта высот + detail карта, есть так же сплаттинг сделанный через шейдер (но это сторонняя реализация), т. е. красный, зеленый, синий и того три тайла, что собственно не есть гуд, вроде как я понял они только планируют добавить тайловые ландшафты. Но вот не знаю добавят ли, и как оно будет вообще работать. Поэтому решился сам разобраться со всеми недостающими элементами.

Интегрировать код DirectX под Irrlicht, оказалось проще простого. Но есть такие моменты: Octree, ведь ландшафт получается огромным, а камера показывает лишь небольшой участок (как в прочем в HoMM5, правда zoom покороче), поэтому надо сделать отрисовку только видимых полигонов.

Как я понял:
Создается один VB под весь ландшафт, где на все полигоны установлен дефолтный тайл, т. е. на каждые два треугольника образующие один quad накладывается координаты одного тайла.
Потом создается для каждого участка еще VB, но уже содержащий только координаты текстуры и цвет+альфа канал + IB(он должен индексировать текстуры на треугольники?)

Мне вот не все понятно с IndexBuffer, зачем он нужен? Зачем для каждого участка с уникальным тайлом создавать VB, не проще ли создать один VB который будет поставлен во второй стрим, и динамически менять в нем данные? Или есть нюансы? Или я не въехал в суть?
#15
14.07.10 21:45
0
Цитата
есть так же сплаттинг сделанный через шейдер (но это сторонняя реализация), т. е. красный, зеленый, синий и того три тайла, что собственно не есть гуд

Три тайла(можно четыре) - это на один дип(на один вызов процедуры DrawIndexedPrimive). Если ландшафт поделить на сектора, то тогда можно использовать 4 уникальные текстуры на каждый сектор. Об этом ниже.

Цитата
вроде как я понял они только планируют добавить тайловые ландшафты

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

Цитата
Интегрировать код DirectX под Irrlicht, оказалось проще простого. Но есть такие моменты: Octree, ведь ландшафт получается огромным, а камера показывает лишь небольшой участок (как в прочем в HoMM5, правда zoom покороче), поэтому надо сделать отрисовку только видимых полигонов.

Решение данной проблемы(?) заключается, как я уже выше писал, в разбиении ландшафта на небольшие сектора.
К примеру: имеем грид c размерами 256х256, разбиваем его на сектора с размерами 64х64. Получаем 4х4 сектора или в сумме - 16. На данной ноте можем вернуться к теме сплаттинга: Мы обладаем возможностью повесить 3(например) уникальные текстуры на сектор, а т.к. секторов у нас 16, то в сумме мы получаем 48 уникальных текстур на ландшафт! И это, конечно, еще не предел.

Вернемся к отсечению ненужных треугольников камерой. Для этого каждый сектор помещаем в узел Octree(на самом деле тут за глаза хватит QuadTree), перед отрисовкой проверяем на видимость все узлы дерева и делаем соответствующие выводы о том, стоит ли рисовать какой-либо сектор или нет.

Цитата
Создается один VB под весь ландшафт, где на все полигоны установлен дефолтный тайл, т. е. на каждые два треугольника образующие один quad накладывается координаты одного тайла.

Эм, как бы не совсем. И как мы уже договорились, "тайл" у нас - это клетка грида, а это(тайл в твоем понимании) - текстура. Так вот, в создании VB и установке "дефолтной текстуры" нет ничего общего.
VB создается и хранит только ГЕОМЕТРИЮ(Position + Normal) ландшафта, он понятия вообще никакого не имеет какие используются текстуры.
Кстати, если коэффициент затайленности текстур(проще говоря - текс. координаты) имеют одинаковую для всех вершин величину, то координаты эти можно поместить в 1 общий VB(Position + Normal + TexCoord).

Цитата
Мне вот не все понятно с IndexBuffer, зачем он нужен?

Он "говорит" DirectX'y какие вершины нужно взять из нашего общего буффера геометрии, чтобы сделать проход и отрисовать участок с оригинальной текстурой. Вот для примера: имеем грид ландшафта 4х4, он у нас покрыт только травой. По середине ландшафта у нас должна располагаться, например, текстура земли... В центре, с размерами 2х2 тайла... С помощью нашего метода, мы должны взять и отрисовать эти 2х2 тайла еще раз(первый раз они рисуются, когда ландшафт отрисовывается полностью с текстурой травы)! Поверх ландшафта с травой.
Для это IB и выбирает вершины(индексирует треугольники) из общего буффера, которые содержатся в этом участке 2х2.
Цитата
Зачем для каждого участка с уникальным тайлом создавать VB, не проще ли создать один VB который будет поставлен во второй стрим, и динамически менять в нем данные?

Так можно делать, но такого делать никакая религия не позволяет :). Т.к. Lock буффера перед каждой отрисовкой слоя(участок с оригинальной текстурой) очень сильно ударит по производительности!

P.S. Вообще, для начала попробуй все таки разбить ландшафт на сектора и реализовать в плане текстурирования - сплаттинг, он проще в реализации(особенно на движке + есть пример, и никто не мешает его доработать под свои нужды).
Оба этих метода имеют свои недостатки, лучшими свойствами обладает их гибрид (т.к. они очень похожи), но это означает фактически реализацию обоих этих методов, потому начни со сплаттинга :)
#16
Daimos
16.07.10 02:11
0
Вот как я написал:
Код

struct vertex
{
    float x, y, z;
    float u, v;
};

struct triangle
{
    unsigned v0, v1, v2;
};

vertex vertBuffer[] = {    {-1.5, 1.5, 0, 0, 0},
    {-0.5, 1.5, 0, 0.5, 0},
    {-0.5, 0.5, 0, 0.5, 0.5},
    {-1.5, 0.5, 0, 0, 0.5},
    {-0.5, 1.5, 0, 0, 0},
    {0.5, 1.5, 0, 0.5, 0},
    {0.5, 0.5, 0, 0.5, 0.5},
    {-0.5, 0.5, 0, 0, 0.5},
    {0.5, 1.5, 0, 0, 0},
    {1.5, 1.5, 0, 0.5, 0},
    {1.5, 0.5, 0, 0.5, 0.5},
    {0.5, 0.5, 0, 0, 0.5},
    {-1.5, 0.5, 0, 0, 0},
    {-0.5, 0.5, 0, 0.5, 0},
    {-0.5, -0.5, 0, 0.5, 0.5},
    {-1.5, -0.5, 0, 0, 0.5},
    {-0.5, 0.5, 0, 0, 0},
    {0.5, 0.5, 0, 0.5, 0},
    {0.5, -0.5, 0, 0.5, 0.5},
    {-0.5, -0.5, 0, 0, 0.5},
    {0.5, 0.5, 0, 0, 0},
    {1.5, 0.5, 0, 0.5, 0},
    {1.5, -0.5, 0, 0.5, 0.5},
    {0.5, -0.5, 0, 0, 0.5},
    {-1.5, -0.5, 0, 0, 0},
    {-0.5, -0.5, 0, 0.5, 0},
    {-0.5, -1.5, 0, 0.5, 0.5},
    {-1.5, -1.5, 0, 0, 0.5},
    {-0.5, -0.5, 0, 0, 0},
    {0.5, -0.5, 0, 0.5, 0},
    {0.5, -1.5, 0, 0.5, 0.5},
    {-0.5, -1.5, 0, 0, 0.5},
    {0.5, -0.5, 0, 0, 0},
    {1.5, -0.5, 0, 0.5, 0},
    {1.5, -1.5, 0, 0.5, 0.5},
    {0.5, -1.5, 0, 0, 0.5}
};
triangle indBuffer[] = {    {0, 1, 3}, {3, 1, 2},
    {4, 5, 7}, {7, 5, 6},
    {8, 9, 11}, {11, 9, 10},
    {12, 13, 15}, {15, 13, 14},
    {16, 17, 19}, {19, 17, 18},
    {20, 21, 23}, {23, 21, 22},
    {24, 25, 27}, {27, 25, 26},
    {28, 29, 31}, {31, 29, 30},
    {32, 33, 35}, {35, 33, 34}
};

vertex vertBuffer2[] = {
    {-0.5, 0.5, 0, 0.5, 0},
    {0.5, 0.5, 0, 1, 0},
    {0.5, -0.5, 0, 1, 0.5},
    {-0.5, -0.5, 0, 0.5, 0.5}
};
triangle indBuffer2[] = {
    {0, 1, 3},
    {3, 1, 2}
};

// количество элементов в массивах
const int VB_LEN = 36;
const int IB_LEN = 18;
const int VB2_LEN = 4;
const int IB2_LEN = 2;


vertBuffer - содержит вершины. Здесь чтобы правильно наложить текстуру мне пришлось не исключать дублирующие вершины (т. е. есть вершины дублируются по координатам в пространстве, а вот текстурные координаты отличаются)
indBuffer - содержит индексы треугольников.

vertBuffer2 - это 4-угольник со следующим тайлом (т. е. кусочком текстуры), так как я использовал для примера текстуру 512x512, где упакованы две текстуры по 256x256, а планирую использовать 1024x1024 где упакованы 16 текстур.

На даном этапе я использую DIPUP вместо DIP, потом можно будет заранее все запихать в видео память. Главное мне сейчас получить эффект смешивания кусочков текстур нанесенных на 4-угольники.

Перед просчетом отодвигаюсь от центра наблюдения на вектор (0.0, 0.0. -4.0), т. е. смотрю в вектор(0.0, 0.0, 0.0).

Вот просчет сцены:
Код

    d9dev->SetRenderState(D3DRS_LIGHTING, FALSE);
    d9dev->SetRenderState(D3DRS_ZENABLE, TRUE);

    d9dev->SetTexture(0, texture);
    d9dev->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
    d9dev->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
    d9dev->SetSamplerState(0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
        
    d9dev->SetFVF(D3DFVF_XYZ | D3DFVF_TEX1);

    // отображаем весь grid (ака terrain :))
    d9dev->DrawIndexedPrimitiveUP(D3DPT_TRIANGLELIST,
        0, VB_LEN, IB_LEN, indBuffer,
        D3DFMT_INDEX32, vertBuffer, 20);

    // сдесь надо отключить ZBUFFER, и настроить аддитивный блендинг?
    // отображаем 4-угольник со следующим кусочком текстуры
    d9dev->DrawIndexedPrimitiveUP(D3DPT_TRIANGLELIST,
        0, VB2_LEN, IB2_LEN, indBuffer2,
        D3DFMT_INDEX32, vertBuffer2, 20);


используемая мной текстура tiles.jpg 512x512, где в один ряд упакованы две текстуры по 256x256.

Я все сделал правильно?
Как настроить аддитивный блендинг?

Еще интересный результат, если отодвинуться от центра просмотра по оси Z меньше чем -4.0, к примеру на -3.0, то можно наблюдать белые полосы в переходе на следующий ряд. Это погрешность вещественного числа с одинарной точностью? Или что-то другое?

tiles.jpg - текстура с тайлами, scrShotNice4.jpg - скриншот где отодвинулся по Z на -4.0, scrShotBad3.jpg на -3.0
#17
19.07.10 22:40
0
Цитата
Еще интересный результат, если отодвинуться от центра просмотра по оси Z меньше чем -4.0, к примеру на -3.0, то можно наблюдать белые полосы в переходе на следующий ряд. Это погрешность вещественного числа с одинарной точностью? Или что-то другое?

Это результат "железной" фильтрации, связанный с использованием атласов(куча текстур в одной). Если используются MipMaps(3D ландшафт у нас) то от этого вообще никак не избавится(приемлимым способом), бороть можно пробовать путем добавления "бордюра" по краям текстур в атласе. Совет дня - забей на ландшафт с атласом ;)

Цитата
vertBuffer - содержит вершины. Здесь чтобы правильно наложить текстуру мне пришлось не исключать дублирующие вершины (т. е. есть вершины дублируются по координатам в пространстве, а вот текстурные координаты отличаются)

Такой способ - лишнее использование памяти, совсем не cache-friendly.
Вообще с чего появилась необходимость хранить в атласе? Очень много текстур? Для справки: в большинстве игр(3D которые) текстуры в атласах хранят очень редко.

Цитата
Я все сделал правильно?

Не совсем :). Ладно, раз главная цель - смешать два слоя, то пока буферы трогать не будем.
В описании вершины не хватает записи о цвете, которая будет хранить прозрачность в оной:

Код

struct vertex
{
    float x, y, z;
    float u, v;
    D3DCOLOR color;
};

Потом не забыть исправить:
Код

d9dev->SetFVF(D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_DIFFUSE);

Собссна далее придеться "немного" :) дописать инициализацию VB, добавив в первый: цвет D3DCOLOR_ARGB(255,255,255,255), а во второй, например: для двух верхних вершин также все по 255, а для двух нижних, установив альфу в 0 (D3DCOLOR_ARGB(0,255,255,255)).

Вместо комментов о Depth и блендинге:
Код

d9dev->SetRenderState(D3DRS_ZENABLE, D3DZB_TRUE); //это должно быть сделано при инициализации
d9dev->SetRenderState(D3DRS_ZFUNC, D3DCMP_LESSEQUAL); //оно установлено по дефолту, можно не делать или делать "на всякий случай" при инициализации
d9dev->SetRenderState(D3DRS_ZWRITEENABLE, FALSE); //не забыть выставить в "TRUE" перед началом отрисовки сцены
// но у тебя пока "плоский" =) случай, можешь с z-buffer'ом пока не заморачиваться и не ставить верхние стейты


d9dev->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_DIFFUSE); //говорим, что альфу берем из вершины

d9dev->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE); //включаем блендинг
d9dev->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
d9dev->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);

Отредактировано: 19.07.10 23:01
#18
19.07.10 23:02
0
P.S. Еще скорее всего вылезет z-fighting(если включен z-buf), побороть можно примерно так(на первое время :)):
Код

float Bias = -0.15f; //подобрать другое значение, если не спасет
d9dev->SetRenderState(D3DRS_SLOPESCALEDEPTHBIAS, *((DWORD*)&Bias));
#19
Daimos
20.07.10 21:36
0
Xander
Спасибо, мне удалось смешать текстуры. Правда у меня последовательность данных получилась такой:

Код

struct vertex
{
    float x, y, z;
    D3DCOLOR color;
    float u, v;
};

сначала цвет потом координаты текстур.

Цитата

Такой способ - лишнее использование памяти, совсем не cache-friendly.

А как мне правильно нанести текстуру на все 4-угольники?

Вот имеем к примеру буфер с исключенными дубликатами вершин(сетка 3x3):
0 1 2 3
4 5 6 7
8 9 10 11
12 13 14 15
Нумерация - это индексы в буфере (буфер 1-мерный, линейный). И имеем следующий треугольники: (0, 1, 4) (1, 5, 4), (1, 2, 5) (2, 6, 5), и т. д.

Я попробовал наложить текстуру так:
(0, 0) (1, 0) (0, 0) (1, 0)
(1, 0) (1, 1) (1, 0) (1, 1)
(0, 0) (1, 0) (0, 0) (1, 0)
(1, 0) (1, 1) (1, 0) (1, 1)

т. е. через одну вершину текстура накладывается задом на перед, с право на лево, с низу вверх. Но ей богу фигня получается какая-то :( Не очень как то.

А если одну текстуру положить на весь grid, то при 3x3 будет смотреться ничего, а вот на 256x256, 512x512 можно будет наблюдать пиксели а не текстуру.
#20
20.07.10 22:54
0
А если так?
Код

(0, 0) (1, 0) (2, 0) (3, 0)
(0, 1) (1, 1) (2, 1) (3, 1)
(0, 2) (1, 2) (2, 2) (3, 2)
(0, 3) (1, 3) (2, 3) (3, 3)


А вообще ведь, не удобно вот так ручками буферы заполнять. Можно например так:
Код

const int Width = 4;
const int Height = 4;

vertex VBuf[Width * Height]; //сетка 3х3 тайла

float Tile = 2.0f;
for (int x = 0; x < Width; x++)
    for (int y = 0; y < Height; y++) {
        int Idx = x * Width + y;
        
        VBuf[Idx].x = x * Tile;
        VBuf[Idx].y = y * Tile;
        VBuf[Idx].z = 0.0f;

        VBuf[Idx].u = x * Tile;
        VBuf[Idx].v = y * Tile;
}
#{{post.Index}}
{{post.Author.Login}}
{{post.CreatedDate | date:'dd.MM.yy HH:mm'}}
{{post.VotesRating}}
Отредактировано: {{post.UpdatedDate | date:'dd.MM.yy HH:mm'}}