![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Непокорный FPS, или о том как FPS не хочет меняться... [D7, WinXP]
NOX © (2004-07-29 12:13:00)Здраствуйте. Помогите плз решить такой вопрос: при использовании DirectDraw независимо от количества спрайтов на экране
(от 1 до 1000) количество кадров (FPS) равно 64 и не меняется вообще. Такое ощущение как-будто операционка чем-то
мешает, ведь при одном маленьком спрайтике на экране выдавать 64 кадра, в то время как тот же FarCry местами больше
выдавал, это не правильно. FPS начинают по-тихоньку падать только когда спрайтов больше тысячи (1000~1500) и на отметке
примерно в полторы тысячи FPS равно примерно 40. Если надо могу показать код, но он довольно таки стандартный и ничего
особенного там нет. Вывожу всё как обычно: сначала очищаю вторичную поверхность (заполняю белым цветом), потом
копирую на неё поверхность с картинкой и переключаю первичную и вторичную поверхности.
Может кто с подобным сталкивался? Подскажите что делать.
Спасибо.
NOX (2004-07-30 19:03:00) [1]Спасибо большое!!!
VMcL (2004-07-30 18:18:00) [2]>> NOX (30.07.04 11:41) [8]
"Рисовать" следует не по таймеру (см. [9]), а в обработчике события Application.OnIdle.
Sapersky (2004-07-30 15:41:00) [3]избавляйся от таймера
Это да. И ещё на некоторых видеокартах нужно к флагам флипинга добавлять DDFLIP_DONOTWAIT.
cyborg (2004-07-30 12:07:00) [4]Видимо таймер 85 раз в секунду вызывается, избавляйся от таймера
NOX (2004-07-30 11:41:00) [5]Флажок поставил, но ситуация не изменилась ! (Частота развёртки у монитора стоит 85Гц) Что делать?
Помогите плиз! Вот код:
procedure TForm1.FormCreate(Sender: TObject);
var hRet : HResult;
ddsd : TDDSurfaceDesc2;
ddscaps : TDDSCaps2;
begin
ScrWidth:=800;
ScrHeight:=600;
ScrBitDepth:=32;
MainGraph:=nil;
Primary:=nil;
Back:=nil;
hRet := DirectDrawCreateEx (nil, MainGraph, IDirectDraw7, nil);
if hRet <> DD_OK then Application.Terminate;
hRet := MainGraph.SetCooperativeLevel(Handle, DDSCL_FULLSCREEN or DDSCL_EXCLUSIVE);
if hRet <> DD_OK then Application.Terminate;
hRet := MainGraph.SetDisplayMode (ScrWidth, ScrHeight, ScrBitDepth, 0, 0);
if hRet <> DD_OK then Application.Terminate;
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 := MainGraph.CreateSurface(ddsd, Primary, nil);
if hRet <> DD_OK then Application.Terminate;
FillChar(ddscaps, SizeOf(ddscaps), 0);
ddscaps.dwCaps := DDSCAPS_BACKBUFFER;
hRet := Primary.GetAttachedSurface(ddscaps, Back);
if hRet <> DD_OK then Application.Terminate;
ImgSurf:=DDLoadBitmap(MainGraph, 'C:\ForImgSurf.bmp', 0 ,0);
timer1.Enabled:=true;
timer2.Enabled:=true;
end;
procedure TForm1.FormKeyPress(Sender: TObject; var Key: Char);
begin
if Key = #27 then
begin
Timer1.Enabled:=false;
Timer2.Enabled:=false;
Back:=nil;
Primary:=nil;
MainGraph:=nil;
Close;
end;
end;
function Flip : HRESULT;
var
hRet : HRESULT;
begin
hRet := DD_OK;
while TRUE do
begin
hRet := Primary.Flip(nil, {0}DDFLIP_NOVSYNC);
if hRet = DD_OK then Break
else if hRet = DDERR_SURFACELOST then
begin
// hRet := Restore;
if Failed (hRet) then Break;
end;
if hRet <> DDERR_WASSTILLDRAWING then Break;
end;
Result := hRet;
end;
procedure ScrClean;
var
hRet : HRESULT;
ddbltfx : TDDBLTFX;
begin
ZeroMemory(@ddbltfx, SizeOf(ddbltfx));
ddbltfx.dwSize := SizeOf(ddbltfx);
ddbltfx.dwFillColor := RGB(0, 255, 0);
while True do
begin
hRet := Back.Blt(nil, nil, nil, DDBLT_COLORFILL or DDBLT_WAIT, @ddbltfx);
if hRet = DDERR_SURFACELOST then
begin
// if Failed(Restore) then Exit;
end
else Break;
end;
end;
procedure Draw;
var DC : HDC;
str : PAnsiChar;
begin
Back.BltFast(100, 100, ImgSurf, nil, DDBLTFAST_WAIT);
Back.GetDC(DC);
str:=PChar('FPS=' + inttostr(FPS));
TextOut(DC, 400, 50, str, Length(str));
Back.ReleaseDC(DC);
end;
procedure TForm1.Timer1Timer(Sender: TObject);
begin
inc(Count);
ScrClean;
Draw;
Flip;
end;
procedure TForm1.Timer2Timer(Sender: TObject);
begin
FPS:=Count;
Count:=0;
end;
cyborg (2004-07-29 20:23:00) [6]Используй флаг DDFLIP_NOVSYNC при вызове флипинга, будет тебе ПАРАТЫЩ кадров с тремя спрайтами ;).
NOX (2004-07-29 19:31:00) [7]В настройках драйвера видюхи стоит что вертикальная синхронизация всегда выключена, а где её можно выключить при инициализации DirectDraw не знаю. :0(
NOX (2004-07-29 18:58:00) [8]А где это можно сделать?
VMcL (2004-07-29 16:55:00) [9]>>NOX (29.07.04 12:13)
Вертикальную синхронизацию отключил?
Ertong (2004-07-29 12:35:00) [10]Ну тогда незнаю :)
NOX (2004-07-29 12:28:00) [11]
procedure ScrClean;
var
hRet : HRESULT;
ddbltfx : TDDBLTFX;
begin
ZeroMemory(@ddbltfx, SizeOf(ddbltfx));
ddbltfx.dwSize := SizeOf(ddbltfx);
ddbltfx.dwFillColor := RGB(255, 255, 255);
while True do
begin
hRet := Back.Blt(nil, nil, nil, DDBLT_COLORFILL or DDBLT_WAIT, @ddbltfx);
if hRet = DDERR_SURFACELOST then
begin
// if Failed(Restore) then Exit;
end
else Break;
end;
end;
Ertong (2004-07-29 12:22:00) [12]
> сначала очищаю вторичную поверхность (заполняю белым цветом),
Этот кусок кода покажи. Возможно из-за этого