Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Игры";
Текущий архив: 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.032 c
1-1099347327
SpyBack
2004-11-02 01:15
2004.11.14
Запрос


4-1097141154
lightix
2004-10-07 13:25
2004.11.14
Узнать ID активного приложения


14-1098547072
ДоздраПерМа
2004-10-23 19:57
2004.11.14
Сколько лет надо учиться программировать?


3-1097844183
Vemer
2004-10-15 16:43
2004.11.14
Необходимость наличия Primary Key


4-1097075594
Newcomer
2004-10-06 19:13
2004.11.14
Resources





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский