![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
D3D fullscreen [Delphi, Windows]
nexxiss © (2004-05-25 13:49:00)Добрый день. Вы не могли бы подсказать: как правильно создать полноэкранное приложение под D3D с разрешением 800х600 ?
nexxiss (2004-05-29 13:28:00) [1]Ну теперь все сомненения пропали, буду step by step продвигаться дальше. Спасибо за инф-цию. Я примерно это так все и предполагал, только хотел использовать не массив объектов, а динамические структуры данных, на мой взгляд это будет несколько быстрее. Теперь дело осталось за немногим: научиться правильно ( сточки зрения оптимизации) натягивать текстуру на квадрат.
NailMan (2004-05-27 17:47:00) [2]Пардон хабыл добавить сам объект:
For i:=0 to КоличествоОбъектов-1 do
begin
if ТекущееВремя-Объект[i].ПредыдущееВремя>=Объект[i].ВремяЗадержки then
Begin
...изменяем состояние объекта
Объект[i].ПредыдущееВремя:=ТекущееВремя;
end;
end;
---
WBR, NailMan aka 2:5020/3337.13
NailMan (2004-05-27 17:37:00) [3]Ок, а обработку процессов и различных данных от которых зависит рендеринг ?
Это делается по тикам, т.е. для каждого объекта, который должен как-то изменять состояние, надо сделать некий промежуток времени(тик) в который он будет обновлять свое состояние.
Скажем такая схема:
У каждого ИО(игровой объект) есть переменные которые отвечают за
его ТИК:
var ПредыдущееВремя:Cardinal;
ВремяЗадержки:Cardinal;
------- основной цикл(onIdle) -------------
For i:=0 to КоличествоОбъектов-1 do
begin
if ТекущееВремя-ПредыдущееВремя>=ВремяЗадержки then
Begin
...изменяем состояние объекта
ПредыдущееВремя:=ТекущееВремя;
end;
end;
------- основной цикл(onIdle) -------------
Итак "ТекущееВремя" - это функция получения значения системного таймера.
Может использоваться как GetTickCount, так и QueryPerformanceCounter. Второй предпочтительней, так как очень высокая точность, но для его использования необходимо еще и вычислить разрешение таймера(на разных тачках оно слегка колеблется по значению).
"ВремяЗадержки" - это значение периода бездействия для объекта. Иными словами - это период через которое будет происходить следующее изменение состояния. Скажем если выставить это значение =20, то это будет 50 раз в сек(50*20=1000мс).
Т.о. у тебя для каждого объекта будет время на обработку. Идеал - когда эти тики случаются в разное время и равномерно случаются в течение секунды.
---
WBR, NailMan aka 2:5020/3337.13
nexxiss (2004-05-27 17:17:00) [4]Ок, а обработку процессов и различных данных от которых зависит рендеринг ?
Bryke (2004-05-27 17:14:00) [5]
> Спасибо за совет. Все отлично работает. Какого твое мнение,
> где лучше всего проводить рендеринг сцены:
> 1 - В onIdle
> 2 - В onTimer
> ?
Лучше в OnIdle
nexxiss (2004-05-27 16:35:00) [6]Спасибо за совет. Все отлично работает. Какого твое мнение, где лучше всего проводить рендеринг сцены:
1 - В onIdle
2 - В onTimer
?
NailMan (2004-05-27 14:30:00) [7]nexxiss ©
Чтобы проверить поддерживается ли плоскость нужного формата, после создания IDirect3D8 вытащи Caps-ы дефолтного девайса. и смотри в них какие поддерживаются форматы для бэкбуффера.
Как правило, видеокарты не умеют 32-битный режим с альфой, а умеют X8R8G8B8(нормальный 32-bit) или S8X8R8B8(со стенсилом).
Так что устанавливай X8R8G8B8 и радуйся жизни.
---
WBR, NailMan aka 2:5020/3337.13
nexxiss (2004-05-27 14:05:00) [8]Да, твои догадки правильны, я использую D3D8. Глядя на твой код, решил тоже организовать подробный логгинг. В результате были найдены места, где наделано ошибок. Я делал почти все правильно, девайс не создавался из-за неправильного формата пикселей для бэкбуффера. Не могу понять, почему не подходит формат с альфасоставляющей ? Есть подозрение что карточка не поддерживает. Или проблема может быть в чем-то другом ?
NailMan (2004-05-26 14:58:00) [9]Да пример на D3D9, так что где-то могут быть несовпадения в параметрах создания с D3D8(если конечно его юзаешь).
---
WBR, NailMan aka 2:5020/3337.13
nexxiss (2004-05-26 14:08:00) [10]Спасибо за примерчик, доберусь до дома попробую сделать исходя из твоего кода. Вечером сообщу результат страданий. :)
NailMan (2004-05-26 09:16:00) [11]Окно создается вручную.
Насколько я понял, то можно изменить разрешение рабочего стола на 800х600 и тогда уже создавать объект D3D, а при завершении работы приложения восстановить старые атрибуты рабочего стола. Или это не правильная мысля ?
Неправильная конечно. Точнее почти неправильная - когда происходит создание Д3Д в полноэкранном режиме, то разрешение автоматически переключатеся на заданное пр создании девайса, а при разрушении ег возвращается обратно.
Вобщем как я создаю окно и девайс(прошу логику кода не критиковать):
Procedure CreateMainWindow(FullScreen:Boolean);
begin
with WndClass do begin
style := CS_VREDRAW or CS_HREDRAW;
lpfnWndProc := @WndProc;
cbClsExtra := 0;
cbWndExtra := 0;
WndClass.hInstance := HInstance;
hIcon := LoadIcon(HInstance, IDI_APPLICATION);
hCursor := LoadCursor(HInstance, IDC_ARROW);
hbrBackground := GetStockObject(BLACK_BRUSH);
lpszMenuName := nil;
lpszClassName:= @AppName;
end;
RegisterClass(WndClass);
If FullScreen then
Handle:=CreateWindowEx(WS_EX_TOPMOST, @AppName, 'Universal Traveller', WS_POPUP, 0, 0,
ScreenWidth, ScreenHeight, 0, 0, HInstance, nil)
else
Handle:=CreateWindow(@AppName,'Universal Traveller',CW_USEDEFAULT, 0, 0, ScreenWidth, ScreenHeight, 0, 0, HInstance, nil);
end;
Function TGameRender.InitializeDirect3DFullScreenMode:Boolean;
var pMode: TD3DDisplayMode;
begin
D3D:=nil;
dev:=nil;
FPSFont:=nil;
D3D := Direct3DCreate9(D3D_SDK_VERSION);
If d3d=nil then begin LOG.Add(log_warningid,'Direct3D interface creating error');result:=false;exit;end;
D3D.GetDeviceCaps(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,D3Dcaps);
D3D.GetAdapterDisplayMode(D3DADAPTER_DEFAULT,pMode);
D3DPP.BackBufferWidth:=ScreenWidth;
D3DPP.BackBufferHeight:=ScreenHeight;
D3DPP.BackBufferFormat:=GetFormatFromBPP(ColorDepth,False);
D3DPP.BackBufferCount:=1;
D3DPP.MultiSampleType:=GetSampleTypeFromString(AntialiasingSampling);
D3DPP.SwapEffect:=D3DSWAPEFFECT_DISCARD;
D3DPP.Windowed:=False;
D3DPP.EnableAutoDepthStencil:=true;
D3DPP.AutoDepthStencilFormat:=GetFormatFromBPP(ZBufferDepth,True);
If VSync then
begin
D3DPP.FullScreen_RefreshRateInHz:=pMode.RefreshRate;
D3DPP.PresentationInterval:=D3DPRESENT_INTERVAL_DEFAULT;
end
else
D3DPP.PresentationInterval:=D3DPRESENT_INTERVAL_IMMEDIATE;
Result:=InitializeDirect3D;
end;
Function TGameRender.InitializeDirect3D:Boolean;
var hr:hresult;
iFlag:Cardinal;
begin
result:=true;
LOG.Add(log_infoId,'Creating Direct3D device with following parameters:');
If Fullscreen=False then tempstring:='Windowed' else tempstring:='Fullscreen';
LOG.Add(log_infoId,'Resolution: '+inttostr(d3dpp.BackBufferWidth)+' X '+
inttostr(d3dpp.BackBufferHeight)+', ColorDepth: '+inttostr(ColorDepth)+' BPP, Z-Buffer Depth: '+
inttostr(ZBufferDepth)+' BPP, Display Mode: '+TempString);
If FullScreen and VSync then
LOG.Add(log_infoId,'Fullscreen refreshrate = '+inttostr(d3dpp.FullScreen_RefreshRateInHz));
LOG.Add(log_infoId,'Antialiasing multisample type: '+GetSampleTypeFromFormat(d3dpp.MultiSampleType));
iflag:=D3DCREATE_SOFTWARE_VERTEXPROCESSING;
If UseHardWareTL and checkflag(D3Dcaps.DevCaps,D3DDEVCAPS_HWTRANSFORMANDLIGHT) then
begin
iflag := D3DCREATE_HARDWARE_VERTEXPROCESSING;
if ForceMixedTLProcessing then iflag := D3DCREATE_MIXED_VERTEXPROCESSING else
if CheckFlag(D3Dcaps.DevCaps,D3DCREATE_PUREDEVICE) then
iflag:=iflag or D3DCREATE_PUREDEVICE;
end;
Case iFlag of
D3DCREATE_HARDWARE_VERTEXPROCESSING or
D3DCREATE_PUREDEVICE : begin
tempstring:='Use hardware Transform and Lightning (Pure HW TnL)';
HWTnLSupported:=true;
end;
D3DCREATE_HARDWARE_VERTEXPROCESSING : begin
tempstring:='Use hardware Transform and Lightning (TnL)';
HWTnLSupported:=true;
end;
D3DCREATE_SOFTWARE_VERTEXPROCESSING : tempstring:='Use software Transform and Lightning(TnL)';
D3DCREATE_MIXED_VERTEXPROCESSING : tempstring:='Use mixed vertex processing (HW TnL and software vertex shaders)';
end;
LOG.Add(log_infoId,'Vertex Processing : '+TempString);
hr:=D3D.CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, Handle, IFlag, @D3DPP, Dev);
if failed(Hr) then
begin
LOG.Add(LOG_Warningid,'Direct3D Device creating error code: '+DXGetErrorString9(hr)); result:=false;exit;
end;
LOG.MidLogseparator;
CompressedTexturesSupported:=CheckTextureFormat(D3DFMT_DXT3,d3dpp.BackBufferFormat);
If dword(MaxActiveLights)>D3DCaps.MaxActiveLights then MaxActiveLights:=D3DCaps.MaxActiveLights;
ShowWindow(Handle, SW_NORMAL);
CursorShow(False);
InitializeDXFont(FPSFont,FPSLogFont,12,'Arial',False);
FPSRect:=ssrect(5,ScreenHeight-16,200,ScreenHeight);
InfoRect:=ssrect(5,8,screenwidth,128);
CreateStates;
dev.GetCreationParameters(CP);
AddDirect3DRenderToLog;
end;
Вобщем вот так. В примере конечно много лишнего(связанного со спецификой моего подхода к оформлению логгинга), так что всякие такие рюшки смело игнорируй.
---
WBR, NailMan aka 2:5020/3337.13
nexxiss (2004-05-26 03:00:00) [12]А как ты создаешь хэндл окна? Вручную или формой пользуешься?
Окно создается вручную.
Насколько я понял, то можно изменить разрешение рабочего стола на 800х600 и тогда уже создавать объект D3D, а при завершении работы приложения восстановить старые атрибуты рабочего стола. Или это не правильная мысля ?
to smb>
мне нужно 800х600 разрешение, там по ссылке находится классический пример, это я могу сделать без проблем.
NailMan (2004-05-25 18:26:00) [13]Тьфу, тоесть Windowed:=False, конечно же.
А как ты создаешь хэндл окна? Вручную или формой пользуешься?
---
WBR, NailMan aka 2:5020/3337.13
smb (2004-05-25 17:49:00) [14]http://www.firststeps.ru/mfc/directx/dr3d/dr3d1.html
Шаг №7
nexxiss (2004-05-25 14:29:00) [15]>Перед созданием девайса, в PRESENT_PARAMETERS указываешь Windowed:=true и все должно быть пучком.
Мне нужно приложение на весь экран, а разрешение должно быть 800х600.
nexxiss (2004-05-25 14:29:00) [16]>Перед созданием девайса, в PRESENT_PARAMETERS указываешь Windowed:=true и все должно быть пучком.
Мне нужно приложение на весь экран, а разрешение должно быть 800х600.
NailMan (2004-05-25 14:20:00) [17]Перед созданием девайса, в PRESENT_PARAMETERS указываешь Windowed:=true и все должно быть пучком.
---
WBR, NailMan aka 2:5020/3337.13