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

Вниз

Проблема с 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 вся ветка

Текущий архив: 2004.10.31;
Скачать: CL | DM;

Наверх




Память: 0.49 MB
Время: 0.03 c
14-1097259853
DeadMeat
2004-10-08 22:24
2004.10.31
Раз уж дело зашло о старом железе...


4-1095756933
HDD
2004-09-21 12:55
2004.10.31
Индификатор окна


6-1092825898
ctranik
2004-08-18 14:44
2004.10.31
как скачать Web-страницу которая лежит в другой "Папке"


4-1095945717
shelest
2004-09-23 17:21
2004.10.31
работа с TService


1-1097561439
-=SS=-
2004-10-12 10:10
2004.10.31
Изменение цвета кнопки