Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2004.11.14;
Скачать: CL | DM;

Вниз

Мипмэппинг ( 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;
Скачать: CL | DM;

Наверх




Память: 0.53 MB
Время: 0.056 c
3-1097824819
NorthMan
2004-10-15 11:20
2004.11.14
Запрос из консольного приложения


14-1098455538
Кириешки
2004-10-22 18:32
2004.11.14
НОРТОН АНТИВИРУС завалил комп. Помогите пожалуйста!


4-1096978644
Delphi5.01
2004-10-05 16:17
2004.11.14
как программно поймать процесс изменения Modify


14-1098790139
Григорьев Антон
2004-10-26 15:28
2004.11.14
Ну китайцы дают!


14-1098882807
Yuri Btr
2004-10-27 17:13
2004.11.14
Intel Signal Processing Library