Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Media";
Текущий архив: 2004.10.31;
Скачать: [xml.tar.bz2];

Вниз

Проблема с 32 битами на DirectX JEDI, IDirectDraw7   Найти похожие ветки 

 
d10   (2004-07-31 01:22) [0]

Я делаю вывод графики средствами DirectX JEDI. Использую IDirectDraw7. Делаю около 500 фаст блиттингов маленькой (64*32 пикселя) поверхности на заднюю, потом флит задней на переднюю. Если использую 32бита все жутко тормозит, FPS<1 на глаз, при 8 битах FPS>50 на глаз. Это так и должно быть или я чтото делаю не так? И как можно ускорить вывод 32 бит?

вот методы иницилизации и вывода графики:

constructor TGraph.Create;
var hRet:HRESULT;
   ddsd:TDDSurfaceDesc2;//вспомогательная переменная для создания поверхностей
   ddscaps:TDDSCaps2;//вспомогательная переменная для приаттачивания поверхностей
begin
 inherited create;//конструктор родителя

 screen.x:=1024;screen.y:=768;screen.bit:=8;
 //обнуляем все
 FDDSBack:=nil;FDDSGround:=nil;FDDSHero:=nil;FDDSPrimary:=nil; FDD:=nil;

 //создание главного обьекта ДД
 hRet := DirectDrawCreateEx (nil, FDD, IDirectDraw7, nil);
 if hRet <> DD_OK then begin ErrorOut(hRet, "DirectDrawCreateEx");Exit;end;

 //задание уровня кооперации
 hRet := FDD.SetCooperativeLevel(Form1.Handle, DDSCL_FULLSCREEN + DDSCL_EXCLUSIVE);
 if hRet <> DD_OK then begin ErrorOut(hRet, "SetCooperativeLevel");Exit;end;

 //установка режима дисплея
 hRet := FDD.SetDisplayMode (screen.x,screen.y,screen.bit, 0, 0);
 if hRet <> DD_OK then begin ErrorOut(hRet, "SetDisplayMode");Exit;end;

 //создание главной поверхности
 FillChar (ddsd, SizeOf(ddsd), 0);
 ddsd.dwSize:=SizeOf(ddsd);
 ddsd.dwFlags:=DDSD_CAPS or DDSD_BACKBUFFERCOUNT;
 ddsd.ddsCaps.dwCaps:=DDSCAPS_PRIMARYSURFACE or DDSCAPS_FLIP or DDSCAPS_COMPLEX;
 ddsd.dwBackBufferCount := 1;
 hRet := FDD.CreateSurface(ddsd, FDDSPrimary, nil);
 if hRet <> DD_OK then begin ErrorOut(hRet, "Create Primary Surface");Exit;end;

 //приаттачиваем заднюю поверхность
 FillChar(ddscaps, SizeOf(ddscaps), 0);
 ddscaps.dwCaps := DDSCAPS_BACKBUFFER;
 hRet := FDDSPrimary.GetAttachedSurface(ddscaps, FDDSBack);
 if hRet <> DD_OK then begin ErrorOut(hRet, "GetAttachedSurface");Exit;end;

 //создание поверхности для поверхности карты
 FDDSGround := DDLoadBitmap(FDD, "bmps/ground.bmp", 0, 0);
 if FDDSGround = nil then begin ErrorOut(hRet, "DDLoadBitmap1");Exit;end;

 //создание поверхности для героя
 FDDSHero := DDLoadBitmap(FDD, "bmps/goblin.bmp", 0, 0);
 if FDDSHero = nil then begin ErrorOut(hRet, "DDLoadBitmap2");Exit;end;

 // Задаем цветовой ключ для поверхности
 hRet:=DDSetColorKey(FDDSGround,clWhite);if Failed (hRet)then ErrorOut(hRet,"DDSetColorKey");
 // Задаем цветовой ключ для героя
 hRet:=DDSetColorKey(FDDSHero,0);if Failed (hRet)then ErrorOut(hRet,"DDSetColorKey");

end;

Procedure TGraph.Draw;
const rad=25;
var hRet:HRESULT;
   x,y:integer;//координаты текущей клетки
   xs,ys:integer;//экранные координаты
   Center:TPointI;//
   ddbltfx:TDDBLTFX;
   rect:TRect;
begin
 if not activ then exit;
   //закрашиваем задник белым цветом
 FillChar (ddbltfx, SizeOf(ddbltfx),0);
 ddbltfx.dwSize:=SizeOf (ddbltfx);
 ddbltfx.dwFillColor:=clWhite; //Цвет заполнения - белый
 hRet:=FDDSBack.Blt(nil, nil, nil, DDBLT_COLORFILL or DDBLT_WAIT, @ddbltfx);

 SetRect(rect,0,0,64,32);

 Center:=World.MyHero^.PosC;
 //просматриваем карту в определенном радиусе
 for x:=center.x-rad to center.x+rad do
   for y:=center.y-rad to center.y+rad do
   begin
     Application.ProcessMessages;//обрабатываем сообщения
     //проверка чтоб не выйти за пределы мапы
     if (x<0)or(y<0)or(x>length(World.Map)-1)or(y>length(World.Map)-1) then continue;
     //расчет экранных координат верхнего левого угла текущей клетки
     xs:=trunc(screen.x/2)-32+32*((x-center.x)-(y-center.y));
     ys:=trunc(screen.y/2)-16+16*((x-center.x)+(y-center.y));
     //проверка входитли клетка в экран...
     if (xs<-32)or(xs>screen.x-32)or(ys<-32)or(ys>screen.y-32) then continue;
     //блитинг
     hRet := FDDSBack.BltFast (xs,ys,FDDSGround,@rect, DDBLTFAST_WAIT or DDBLTFAST_SRCCOLORKEY);
     if hRet = DDERR_SURFACELOST then begin if Failed (RestoreAll) then Exit;end;
   end;
 //флит на основную поверхность
 hRet := FDDSPrimary.Flip(nil, DDFLIP_WAIT);
 if hRet = DDERR_SURFACELOST then if Failed (RestoreAll) then Exit;
end;

вообще это код моей игрушки - РПГ.
Всем спасибо за помощь.


 
Dmk ©   (2004-07-31 12:30) [1]

>Application.ProcessMessages;//обрабатываем сообщения
Не делай это в Y цикле. Вынеси например, в X цикл, или
сделай счетчик и на каждые 20 - 50 спрайтов делай
ProcessMessages;
If (Counter mod 50) = 0 then ProcessMessages;


 
d10   (2004-07-31 13:51) [2]

Dmk, спасибо за совет конечно, но проблему это не решит. Сначала я вообще без этой строки делал, если программа висла то только ресетом выйти можно было, теперь просто альт+табом.

Да кстати, видео у меня Geforce4MX 440 128mb.


 
cyborg ©   (2004-07-31 20:33) [3]

допиши в функции, если уж её используешь, DDLoadBitmap в модуле ddutil где

... := DDSCAPS_OFFSCREENPLAIN;

замени на

... := DDSCAPS_OFFSCREENPLAIN or DDSCAPS_VIDEOMEMORY;

только учти, что когда видеопамяти не хватит, поверхность не создастся.

когда видеопамяти не хватает, возвращается ошибка DDERR_OUTOFVIDEOMEMORY, тогда пробуй грузить в оперативку, флаг DDSCAPS_SYSTEMMEMORY


 
d10   (2004-08-02 19:14) [4]

спасибо, щас попробую


 
d10   (2004-08-04 12:18) [5]

2cyborg
pohoje delo bilo ne v + DDSCAPS_VIDEOMEMORY. Raznici v skorosti ya ne zametil na glaz, navermo po defoltu v videomemory sozdayotsya poverhnost". Kstati na 16 bit FPS<2 toje. Mojet oshibka v drugom?


 
cyborg ©   (2004-08-04 12:59) [6]

значит так, начнём с того, что проверим стоят ли нормально дрова к видео, Детонатор стоит? Пуск-выполнить-dxdiag смотрим включены ли режимы ускорения, можешь понажимть кнопки теста, всё ли работает. Дальше смотри настройки видео в дровах. Если всё нормально, создавай минимальное приложение, которое очищает экран и делает флипинг, выводи ФПС, всё в цикле с максимальной скоростью при отключённой видеосинхронизацией, должно быть от нескольких сотен, до нескольких тысяч ФПС, если тут тормозит, то смотрим код инициализации, всё ли как положено? Если всё нормально и тормозит, то возвращаемся к дровам. Если летает идём дальше, выводи несколько сотен спрайтов рендомно, просто инициализируй ректангл и выводи один и тот же спрайт, если тут тормозит, то это значит либо не используется хардвар или всё сидит в оперативке, разбирайся почему так, либо просто спрайтов слишком много выводишь.



Страницы: 1 вся ветка

Форум: "Media";
Текущий архив: 2004.10.31;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.48 MB
Время: 0.051 c
4-1096040015
appendix
2004-09-24 19:33
2004.10.31
поток в Win98 и winXP


1-1098088027
IceT
2004-10-18 12:27
2004.10.31
Minimize приложения


6-1093256653
Nolf
2004-08-23 14:24
2004.10.31
Отправка писем (файлов).


14-1096217151
beginner707
2004-09-26 20:45
2004.10.31
TSplitter Neponyatka


3-1096557345
Vemer
2004-09-30 19:15
2004.10.31
отображение полей TimeStamp в IbExpert





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
Английский Французский Немецкий Итальянский Португальский Русский Испанский