Форум: "Игры";
Текущий архив: 2004.11.14;
Скачать: [xml.tar.bz2];
ВнизМипмэппинг ( mipmapping) в DirectX 8 (можно 9) Найти похожие ветки
← →
Колбасьев © (2004-07-13 21:04) [0]У меня есть текстура. Хочу чтоб осуществлялся мипмэппинг (т.е. на большем расстоянии рисовались текстуры худшего качества (меньшего размера).
Какими командами и в какой последовательности этого достич.
← →
Sapersky (2004-07-14 11:24) [1]Во-первых, текстура должна быть с мип-уровнями. Стандартные D3DX-функции загрузки (D3DXCreateTextureFromFileEx и пр.) могут их генерировать. Можно и вручную - Device.CreateTexture, Texture.GetSurfaceLevel, Surface.LockRect и т.д.
Ну и включить -
Device.SetTextureStageState(0, D3DTSS_MIPFILTER, D3DTEXF_LINEAR);
← →
Колбасьев © (2004-07-14 11:47) [2]Спасибо, а можно поточнее с генерацией мипуровня?
← →
NailMan © (2004-07-14 12:20) [3]Скажем так функции
D3DXCreateTextureFromFile
D3DXCreateTextureFromFileInMemory
D3DXCreateTextureFromResource
Создают все 9 уровней мип по умолчанию.
Все остальные, т.е.
D3DXCreateTextureFromFileEx
D3DXCreateTextureFromFileInMemoryEx
D3DXCreateTextureFromResourceEx
могут создавать произвольно число мип-уровней, какое им скажешь в параметре MipLevels.
Только учти, что для подсчета полного размера текстуры в видеопамяти(если понадобится для статистики), тебе придется сумировать размеры всех мип-уровней.
Совет: всегда создавай текстуры с -Ex-овыми функциями. 9-мип уровней порой бывае очень расточительно!
А автоматический мип-маппинг включается как и сказал Sapersky.
---
WBR, NailMan aka 2:5020/3337.13
← →
Колбасьев © (2004-07-14 15:30) [4]Пожалуйста приведи пример создания текстуры с 4-5 мип уровнями с помощью D3DXCreateTextureFromFileEx.
Я понял, почему у меня не работало. Вместо D3DXCreateTextureFromFile, которую использую везде, в одном месте у меня была собственная функция загрузки текстуры => отсутствия мип уровней.
А мипмэппинг (с 9-ю текстурами) вообще как-то ужасно выглядит. То есть, конечно, нет мельтишения пикселей, зато "детализация" низкая: текстуры песка похожи на желтые квадраты.
> Только учти, что для подсчета полного размера текстуры в
> видеопамяти(если понадобится для статистики), тебе придется
> сумировать размеры всех мип-уровней.
>
> Совет: всегда создавай текстуры с -Ex-овыми функциями. 9-мип
> уровней порой бывае очень расточительно!
Я замеряю объем занимаемый моей программой в памяти (Память для процесса - Память доступная процессу). И самое интересное, как было 31 Мб (ужас, да %-[ ), так и осталось.
← →
NailMan © (2004-07-14 16:19) [5]Конкретно -FromFileEx Не могу, так как юзаю ресурсы из спакованного рес-файла, но исправить ннесложно - достаточно вместо поинтера и размера кэша сунуть pChar(TexFileName).
Вот кусок моего загрузчика текстуры(пользуется некий "системный кэш", который есть просто выделенный Pointer-у кусок памяти и ресурсный контейнер, который валяется в исходнике на сайте):Function TResourceManager.LoadTextureToCache(Const TName : String;
Const LODs : LongWord;
Compressed : Boolean) : Integer;
var fmt:TD3DFormat;ZIndex,fSize:integer;
begin
Result:=NULL_INDEX;
//Заранее готовим формат нащей будущей текстуры как произвольный(директ сам разберется)
fmt:=D3DFMT_UNKNOWN;
//Если нашли наш текстурный файло то грузим его(просто копируем
//содержимое файла 1 к 1 в системный кэш)
if Resource.FindResData(TName,Zindex)=ERR_NOERROR then
BEGIN
Resource.LoadResData(Zindex,SystemCache);
//Если поддерживаются аппаратно сжатые текстуры и они разрешены
//в настройках, то выбираем наиболее подходящий формат текстуры
If UseCompressedTextures and Compressed and CompressedTexturesSupported then fmt:=D3DFMT_DXT3;
//типа чтобы меньше писать :-))
fsize:=Resource.GetResourceInfo(Zindex)^.SIZE;
ZIndex:=FindFreeTexture;
//Грузим одновременно с проверкой на ошибку(описание пишется в лог)
Check(D3DXCreateTextureFromFileInMemoryEx(Dev, //устройство
SystemCache^, //поинтер кэша и размер
fsize, //в твоем случае будет pchar(имя файла)
D3DX_DEFAULT, //ну не знаем мы исходной ширины
D3DX_DEFAULT, //ну не знаем мы исходной высоты
LODs, // ;-) нужное нам число мип-уровней
0, //Типа Билли рекомендует ставить "0"
fmt, //указываем выбранный нами формат
D3DPOOL_MANAGED, //Говорим что текстура наша будет
//управляться директовским манагером
//тоесть либо в AGP либо в локалке
D3DX_DEFAULT, //Фильтр у нас по умолчанию(трилинейка)
D3DX_FILTER_LINEAR, (мип-фильтр билинейный)
$FF000000, (цвет Color-Key типа черный)
nil, //непринципиальный левак
nil, //непринципиальный левак(палитра для 8-битных текстур)
Textures[Zindex])); //Оно самое - конечная текстура
Textures[Zindex].PreLoad; //прелоадим текстуру в локалку, или как там сам разберется директ
//остальное чисто примочки моего ресурсного манагера.
TextureList^[Zindex]:=uppercase(TName);
result:=ZIndex;
END;
end;
---
WBR, NailMan aka 2:5020/3337.13
← →
Колбасьев © (2004-07-14 16:34) [6]Сделал, но теперь видно мельтешение пикселей. Лучше конечно, чем совсем без мипа, но все же. А как ты с этим борешся (ведь в норальных играх некокого мелькания и мельтишения на экране нет!!!)?
А зачем из ресурсов грузишь?(Может есть в этом какая-то оффигенная выгода)Или не хочеться, чтобы кто попало текстуры менял, игру уродовал?
← →
NailMan © (2004-07-14 17:55) [7]Колбасьев ©
> Сделал, но теперь видно мельтешение пикселей. Лучше конечно,
> чем совсем без мипа, но все же. А как ты с этим борешся
> (ведь в норальных играх некокого мелькания и мельтишения
> на экране нет!!!)?
Собсно фильтрацию я делаю таким макаром(стейт блоки)://RS_BILINEAR_FILTER
dev.CreateStateBlock(D3DSBT_PIXELSTATE,States[RS_BILINEAR_FILTER]);
dev.BeginStateBlock;
dev.SetSamplerState(0,D3DSAMP_MAGFILTER,D3DTEXF_LINEAR);
dev.SetSamplerState(0,D3DSAMP_MINFILTER,D3DTEXF_LINEAR);
dev.SetSamplerState(0,D3DSAMP_MIPFILTER,D3DTEXF_POINT);
dev.EndStateBlock(States[RS_BILINEAR_FILTER]);
//RS_TRILINEAR_FILTER
dev.CreateStateBlock(D3DSBT_PIXELSTATE,States[RS_ANISO_FILTER]);
dev.BeginStateBlock;
dev.SetSamplerState(0,D3DSAMP_MAGFILTER,D3DTEXF_LINEAR);
dev.SetSamplerState(0,D3DSAMP_MINFILTER,D3DTEXF_LINEAR);
dev.SetSamplerState(0,D3DSAMP_MIPFILTER,D3DTEXF_LINEAR);
dev.EndStateBlock(States[RS_ANISO_FILTER]);
//RS_ANISO_FILTER
dev.CreateStateBlock(D3DSBT_PIXELSTATE,States[RS_ANISO_FILTER]);
dev.BeginStateBlock;
dev.SetSamplerState(0,D3DSAMP_MAGFILTER,D3DTEXF_ANISOTROPIC);
dev.SetSamplerState(0,D3DSAMP_MINFILTER,D3DTEXF_ANISOTROPIC);
dev.SetSamplerState(0,D3DSAMP_MIPFILTER,D3DTEXF_LINEAR);
dev.SetSamplerState(0,D3DSAMP_MAXANISOTROPY,AnisotropyLevel);
dev.EndStateBlock(States[RS_ANISO_FILTER]);
Устанавливаю нужный фильтр только когда фильтрация должна изменяться(довольно редко выключается и в основном установлен тот фильтр который установлен в настройках игры)
В целом мип-маппинг включен автоматом, когда заданы фильтры D3DSAMP_MIPFILTER для уровней. Можно их заранее в стейт закатать и легко юзать.
Просто задай при инициализации рендера скажем трилинейку(смотри соответствующий стейт) и смотри. У меня автоматически текстура деградируется как собсно и положено.
---
WBR, NailMan aka 2:5020/3337.13
← →
Колбасьев © (2004-07-14 20:16) [8]Ладно. Еще поразбираюсь думаю. NailMan, спасибо!!!
И еще, ты используешь блоки состояний, и ,что интересно, переключаешь фильтрацию на ходу: зачем? Что это тебе дает? Может мне тоже полезно было бы.
← →
Колбасьев © (2004-07-14 20:17) [9]Sapersky также выражаю благодарность.
← →
Dimaxx (2004-07-14 21:06) [10]Зайди сюда - правда, на Си, но разжевано...
http://www.gamedev.ru/articles/read.shtml?id=10101
← →
NailMan © (2004-07-18 23:25) [11]Колбасьев ©
> И еще, ты используешь блоки состояний, и ,что интересно,
> переключаешь фильтрацию на ходу: зачем? Что это тебе дает?
> Может мне тоже полезно было бы.
Дело в том что не всегда фильтрация полезна. Скажем у меня наблюдается такой эффект:
при рендере GUI выводятся экранным спрайтом(моим аналогом ID3DXSprite-а) горизонтальные или вертикальные линии(скажем рамка моего TPanel). При масштабировании маленького куска текстуры на большую протяженность и при заложенном в Директ несоответствии текстурынх координат(так называемое смещение координат) при включенной фильтрации происходит затухание конечной картинки ближе к правому краю. Это происходит в том случае если текстура примерно такая:
|WWWWWWWW|BBBWWWW
|WWWWWWWW|BBBWWWW
|WWWWWWWW|BBBWWWW
|WWWWWWWW|BBBWWWW
|BBBBBBBBBBBBB|BBBWWWW
|BBBBBBBBBBBBB|BBBWWWW
|BBBBBBBBBBBBB|BBBWWWW
|BBBBBBBBBBBBB|BBBWWWW
B - черный пиксель
W - белый пиксель
| - условная граница ректа(прямоугольной области)
Скажем наша область ограниченная символами "|" есть маленький кусочек горизонтальной линии шириной(на экране это высота) в 4 пикселя(белый) и для выравнивания на текстуре остальное у нас черное(тоже 4 пикселя в высоту).
Вот этот вот кусочек текстуры у нас граничит с какой-нить другой байдой, которая в области границы с нашей текстурой линии имеет черные или около-того пиксели.
Так как в директ заложен некий механизм смещения текстурных координат
(есть такое выражение Texel Alignment), то все координаты необходимо задавать дробными с убавлением этого смещения. Скажем я текстурю прямоугольник на который натягивается половина какой-то текстуры, по идее я должен задать текстурные координаты так:
0,0 - левый верхний угол
1,0 - правый верхний угол
0,1 - левый нижний угол
1,1 - правый нижний угол
Но если у меня текстурный WRAP стоит как Mirror, то буде видно что по краям у меня есть некая черные или белые полоски(в полпикселя растянутого порой до большой видимой величины). С этой батвой я столкнулся при создании кубического скайбокса.
Поэтому в SDK рекомендуют задавать координаты с некоторым смещением от краев. Таким обазом правильно будлет задавать так:
0.05,0.05 - левый верхний угол
0.95,0.05 - правый верхний угол
0.05,0.95 - левый нижний угол
0.95,0.95 - правый нижний угол
Величину смещения(0.05) в данном случае надо подобрать. В некоторых случаях может быть и больше.
Короче как это к фильтрации касается: да очень просто - когда я рисую через экранный спрайт элемент меню, который в текстуре находится в очень
тесной зависимости с другими кусочками элементов, то я передаю в Draw(у меня почти полный аналог D3DX8-го ID3DXSprite-А, так как наиболее удобный для GUI) соответсвенно структуру TRect в качестве текстурных координат(выраженных в координатах пикселей как например в фотожопе). Тут ты никак не сделаешь те самые 0.05 смещения. Посему если не учитывать эту баййду при большом пролольном растягивании у тебя получится что справо налево текстура примерно 95 процентов нужного цвета, а к концу переходит в черный, а так как горизонтальная линия переходит в уголок(которые не масштабируется, а посему всегда ровного цвета), то получится хрен знает что а не рамка. Будет типа прогала.
Соответсвенно если перед нужным мне кусочком текстуры будет тоже черный пиксель То он тоже повлияет на конечный вид рамки, только прогал будет и слева.
Если перед выводом выключить фильтрацию, то такого бреда не будет.
Вот потому то я и выключаю ее перед выводом подобной хренотени, а потом включаю ту фильтрацию что установлена по дефолту в настройках игры.
---
WBR, NailMan aka 2:5020/3337.13
Страницы: 1 вся ветка
Форум: "Игры";
Текущий архив: 2004.11.14;
Скачать: [xml.tar.bz2];
Память: 0.52 MB
Время: 0.034 c