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

Вниз

Полноэкранность в OpenGL   Найти похожие ветки 

 
Zeqfreed ©   (2004-10-25 17:14) [0]

Добрый вечер, уважаемые!
В книге М. Краснова "OpenGL, графика в проектах Delphi" сказано, что для создания полноэкранного приложения достаточно растянуть окно на весь экран и, при необходимости, сменить разрешение экрана. Так вот меня мучит вопрос, зачем тогда в Direct3D нужно выполнять специальные действия для установки полноэкранного режима? И за счет чего тогда увеличивается производительность в OpenGL-полноэкранных приложениях, если вообще увеличивается, только при растягивании окна до размера экрана?


 
cyborg ©   (2004-10-25 17:55) [1]


> растянуть окно на весь экран и, при необходимости, сменить
> разрешение экрана.

Расстрел с применением контрольного выстрела!
   [ОДОБРЕНО]
cyborg


 
П7   (2004-10-25 18:07) [2]


> Zeqfreed ©   (25.10.04 17:14)  

Ты уверен? Что в твоём понимании "растянуть окно на весь экран и, при необходимости, сменить разрешение экрана"? Не всё там так просто, как ты пишешь...


 
Zeqfreed ©   (2004-10-25 18:33) [3]


Полноэкранные приложения
Такие приложения достойны отдельного разговора в силу их особой значимости. Занять всю область экрана вам может потребоваться для того, чтобы повысить эффектность и зрелищность вашего проекта, особенно если на экране присутствует много объектов.
Прежде всего, необходимо сказать о том, что некоторые графические акселераторы поддерживают ускорение только в полноэкранном режиме и при определенных установках экрана, например, только при разрешении экрана 640x480 и цветовой палитре 16 бит на пиксел.
К сожалению, мне придется сообщить о наличии здесь некоторых проблем, впрочем, мы их успешно разрешим. Вернитесь к последнему примеру — проекту из подкаталога Ех27, где вывод средствами OpenGL осуществляется на окно без рамки и области заголовка. Поменяйте свойство windowstate формы на wsMaximized, чтобы окно после запуска раскрывалось на весь экран. Запустите проект или откомпилированный модуль. Что у вас получится, я предсказать не могу, он зависит от конкретной конфигурации машины. Если на вашем компьютере все происходит в ожидаемом режиме, т. е. весь экран занят окном голубоватого цвета, вы избавлены от множества проблем, если только не собираетесь распространять свои приложения. Дело в том, что я тестировал подобные проекты на компьютерах самой различной конфигурации и обнаружил, что чаще всего результат получается обескураживающий и неприятный: окно раскрывается некорректно, не полностью занимая экран. Причем неприятности появляются именно в связи с использованием OpenGL, простые проекты вполне справляются с задачей раскрывания на весь экран. Возможно, корень проблемы в несогласованности работы драйверов (как всегда!) или ошибках операционной системы.
Однако решение проблемы оказывается совсем простым.
Посмотрите пример из подкаталога Ех28. Это тот же пример, что и предыдущий, только немного измененный. Свойство windowstate окна формы установлено в wsNormal, а обработчик события onCreate дополнился строкой:
WindowState := wsMaximized;

Теперь все работает превосходно, окно действительно раскрывается на весь экран.
Свойство Formstyie окна можно задать как fsstayOnTop, и тогда приложение будет вести себя так, как многие профессиональные игры, не позволяя переключиться на другие приложения.
Другое решение проблемы очень похоже на предыдущее. Посмотрите пример Ех29 — модифицированный пример вывода на поверхность панели. Панель занимает всю клиентскую область окна (свойство Align имеет значение aiciient), а окно формы максимизировано и не имеет рамки.
Надеюсь, у вас теперь не будет неприятностей при попытке захватить всю область экрана, хотя нелегко объяснить, почему обычный метод не работает, а такой метод, по сути, ничем от него не отличающийся, работает.
Итак, полный экран отвоевывать мы научились. Теперь необходимо научиться менять программно, т. е. без перезагрузки, разрешение экрана: приложению может потребоваться другое, нежели установленное пользователем разрешение, к которому он привык в своей повседневной работе.
Проект FullScr из подкаталога ЕхЗО является упрощенным вариантом такой программы. После запуска приложения пользователю из списка предлагается выбрать желаемое разрешение экрана, которое устанавливается на время работы основного модуля — минимальной программы OpenGL. После окончания работы модуля возвращается первоначальное разрешение экрана.
Пример построен на использовании функции API CliangeDisplaySettings, первый аргумент которой — структура, описывающая требуемый режим. Второй аргумент — битовая комбинация констант, одна из которых задает тестирование режима без его установки.
Массив LowResModes заполняем перечислением всех возможных режимов, тестируем последовательно каждый из них и отмечаем те, тестирование для которых оказалось успешным. После пользовательского выбора действительно устанавливаем выбранный режим, а по завершению работы приложения возвращаем запомненный первоначальный режим.
Протестировав программу в различных режимах, вы можете выяснить, что не во всех из них возможно использование OpenGL, в некоторых режимах контекст воспроизведения не может быть получен.
В целом такой способ создания полноэкранного приложения я нахожу вполне удовлетворительным. При тестировании на компьютере без акселератора приложение в проблемных режимах выдавало сообщение о невозможности получения контекста, а при подключении акселераторов сообщение не появлялось, но в некоторых режимах окно и не окрашивалось. Акселераторы первых моделей могут искаженно передавать картинку в некоторых режимах.


Это цитата из книги, из которой лично я понял, что достаточно всего-лишь "растянуть окно на весь экран и, при необходимости, сменить разрешение экрана".

Если я не прав, пожалуйста объясните мне, как надо делать полноэкранные приложения в OpenGL!


 
Zeqfreed ©   (2004-10-25 18:39) [4]

2П7:
(Сначала не увидел вопроса)
>>Что в твоём понимании "растянуть окно на весь экран и, при >>необходимости, сменить разрешение экрана"?

В моем понимании это установить ширину и высоту окна, на которое производится вывод, равными соответственно ширине и высоте экрана.

А что ещё необходимо сделать?


 
Zeqfreed ©   (2004-10-25 19:06) [5]

Глянул 2 исходника, в каждом полноэкранный режим реализован одинаково:

1) Ставим необходимый режим ф-цией ChangeDisplaySettings со 2-ым параметром - CDS_FULLSCREEN.

2) Изменяем размеры главного окна в соответствии с шириной/высотой экрана

Это правильно? Может быть в Direct3d производятся эти же действия, только не явно?


 
Imp   (2004-10-25 21:28) [6]

imho Краснов - тупИца! я его книги вместо анекдотов читаю.
он у меня в чёрном списке литературы

например, я делал так:


procedure InitFullScreenOpenGL;
var i, ScrX, ScrY, bpp, Freq: Integer;
   NewMode: _devicemodeA;
begin
 if RC <> 0 then DestroyRenderingContext(RC);

 i := frmStart.comboResolution.ItemIndex + 1;
 case i of
   1: begin ScrX := 640;  ScrY := 480 end;
   2: begin ScrX := 800;  ScrY := 600 end;
   3: begin ScrX := 1024;  ScrY := 768 end;
   else raise Exception.Create("invalid resolution");
 end;

 i := frmStart.comboBPP.ItemIndex + 1;
 case i of
   1: bpp := 16;
   2: bpp := 32;
   else raise Exception.Create("invalid bpp");
 end;

 i := frmStart.comboFreq.ItemIndex + 1;
 case i of
   1: Freq := 60;
   2: Freq := 70;
   3: Freq := 75;
   4: Freq := 80;
   5: Freq := 85;
   else raise Exception.Create("invalid frequency");
 end;

 NewMode.dmSize := sizeof(NewMode);
 NewMode.dmPelsWidth := ScrX;
 NewMode.dmPelsHeight := ScrY;
 frmGameScreen.Width := ScrX;
 frmGameScreen.Height := ScrY;
 NewMode.dmBitsPerPel := bpp;
 NewMode.dmDisplayFrequency := Freq;
 NewMode.dmFields := DM_PELSWIDTH or DM_PELSHEIGHT or DM_BITSPERPEL or DM_DISPLAYFREQUENCY;
 ChangeDisplaySettingsA(NewMode, CDS_FULLSCREEN);

 RC:=CreateRenderingContext(frmGameScreen.Canvas.Handle, [opDoubleBuffered], bpp,0{, bpp});
 if RC = 0 then raise Exception.Create("Error Creating Rendering Context");
 ActivateRenderingContext(frmGameScreen.Canvas.Handle, RC);

 LoadTextures;
 frmGameScreen.Cursor := crNone;
 glViewport(0, 0, frmGameScreen.ClientWidth, frmGameScreen.ClientHeight);
end;


только не забудь сохранить предыдущие параметры и восстановить их при завершении работы


procedure TfrmGameScreen.SaveScreenMode;
begin
 SavedMode.dmSize := sizeof(SavedMode);
 SavedMode.dmPelsWidth := Screen.Width;
 SavedMode.dmPelsHeight := Screen.Height;
 SavedMode.dmBitsPerPel := 0;
 SavedMode.dmFields := DM_PELSWIDTH or DM_PELSHEIGHT or DM_BITSPERPEL;
end;

procedure TfrmGameScreen.RestoreScreenMode;
begin
 ChangeDisplaySettingsA(SavedMode, CDS_FULLSCREEN);
end;


 
NikeOLD ©   (2004-10-25 21:41) [7]

Если я правильно понял, то подхлд г-на Краснова - только пуля тебя спасет (и желаательно в висок).

Я бы рекомендовал использование комбинации OpenGL и DirectDraw. Последнее лишь для переключения экрана в требуемый режим. Кстати, этот подход избавляет от многих проблем, связанных с зависанием программы, переключенной в другой режим. Дело в том, что стандартная функция ChangeDisplaySettings при некорректном выходе из программы не восстанавливает исходный размер рабочего стола.

Для включения DirectDraw достаточно создать интерфейс, и вызвать методы интерфейса SetDisplayMode и SetCooperativeLevel. Дальше - убрать заголовок и развернуть окно (лучше средствами API) и наслаждаться.


 
Imp   (2004-10-25 21:46) [8]

а ты делай основной цикл программы в try / except;

try
  repeat
   ...
  until Finished;
except
 on E: Exception do RestoreScreenMode;
end


 
Magikan ©   (2004-10-26 02:49) [9]

Гы... При изменении разрешения экрана не означает, что я буду рисовать на весь экран. Я могу окошечко сделать на полэкрана и спокойно выводить в него. А чтобы выводить на весь экран, я и растягиваю окошко на всю площадь. Контекст OpenGL-рендеринга привязывается не к монитору, а к окну :)
А в DirectX такая фишка не возможна. Гы...


 
cyborg ©   (2004-10-26 10:41) [10]


> [9] Magikan ©   (26.10.04 02:49)
> Контекст OpenGL-рендеринга привязывается не к монитору, а к окну :)
> А в DirectX такая фишка не возможна. Гы...

Ты в этом уверен?


 
Zeqfreed ©   (2004-10-26 11:35) [11]

2Imp:
Спасибо.
Но, как я понял, предложенный тобой подход впринципе тот же самый, что описанный мною в [5]?

2NikeOLD:
Такой подход конечо может иметь место, но все-таки OpenGL + DirectDraw как-то "ненатурально".

И ещё, может быть кто-то подскажет, как отлавливать нажатия клавиш клавы и мыши кроме как сообщения Windows и не используя тот же DirectInput? И вообще имеет ли смысл это делать? (прибегать к методу, отличному от отловки сообщений)


 
Поручик ©   (2004-10-26 16:41) [12]

И ещё, может быть кто-то подскажет, как отлавливать нажатия клавиш клавы и мыши кроме как сообщения Windows и не используя тот же DirectInput?

Интересно, это как? На аппаратном уровне с портом работать, свой драйвер клавиатуры писать? Вспомнил. Вроде у Ла Мота что-то было подобное на Асме, но имхо не нужно это, твоя игра не настолько крута, чтоб заморачиваться по этому поводу. Вот когда напишешь что-нить стОящее, тогда будешь ломать голову над оптимизацией.
Так что, ловилку сообщений тебе в руки и удачной рыбаки


 
NikeOLD ©   (2004-10-26 17:07) [13]


> Такой подход конечо может иметь место, но все-таки OpenGL
> + DirectDraw как-то "ненатурально".

Натуральнее некуда. Хотя естественее OpenGL + Direct3D. Последний подход во всех играх.
Кроме того еще и DirectInput и DirectMusic практически во всех играх используется. Куда уж натуральнее?...

Без DirectInput - только return to DOS и на уровне прерываний :))
Желаю счастья в этом деле. У Ламота это было во времена DOS.


 
Zeqfreed ©   (2004-10-26 17:18) [14]

Ладно, спасибо за советы.
Буду пробовать, как лучше выйдет...


 
Zeqfreed ©   (2004-10-26 17:18) [15]

Ладно, спасибо за советы.
Буду пробовать, как лучше выйдет...


 
DeadMeat ©   (2004-10-26 19:09) [16]

А GetAsyncKeyState почему нельзя?

---
...Death Is Only The Begining...


 
Zeqfreed ©   (2004-10-26 19:34) [17]

Да можно наверно, некоторым, правда, религия не позволяет... ;)


 
NikeOLD ©   (2004-10-26 22:30) [18]

Ограничения там, вот и вся религия.


 
DeadMeat ©   (2004-10-26 22:53) [19]

Какие?
Я просто DirectInput никогда не пользовался, т.к. игр не пишу...

---
...Death Is Only The Begining...


 
Darthman ©   (2004-10-26 23:37) [20]

//OpenGL + DirectDraw как-то "ненатурально".
Отчего же? Очень даже. DirectInput и так далее тоже натурально и уместно использовать. OpenGL это кроссплатформенная библиотека. В Линуксе ты будешь использовать функции Иксов для перехвата управления и экрана, в Виндовсе ДирекИкс... помоему все верно и логично.


 
NikeOLD ©   (2004-10-27 09:34) [21]

MSDN - твой друг.

GetAsyncKeyState - только в NT различаются левый и правый SHIFT, CTRL, ALT, например. Опрашивает только одну клавишу за раз. Нажал две - проблема, для этого GetKeyboardState нужена. Но она работает не асинхронно, а только при извлечении сообщения из очереди, т.е. при интенсивной работе (в игре) - будут тормоза.

Этого в принципе достаточно.


 
П7   (2004-10-27 11:01) [22]

Да ну нафиг, ДиректИкс ещё юзать. По моему, правильнее не левые библиотеки использовать, а Апи твоей ОСи. И на этом успокоится.


 
Magikan ©   (2004-10-27 15:02) [23]

>cyborg ©   (26.10.04 10:41) [10]
>
>
>> [9] Magikan ©   (26.10.04 02:49)
>> Контекст OpenGL-рендеринга привязывается не к монитору, а к окну :)
>> А в DirectX такая фишка не возможна. Гы...
>
>Ты в этом уверен?

Абсолютно. Контекст OpenGL-рендеринга привязывается к окну. При выводе 3Д-графики в оконном режиме, драйвер видюхи через контекст окна узнает координаты, а видеокарта уже воспроизводит 3Д изображение (рендерит) непосредственно в этот участок экрана. Кстати, для тех, кто не знает - такая возможность впервые была реализована на X-сервере под Unix/Linux.
Старые видеокарты (3dfx) рендеринг в окно не поддерживали, поэтому они выводили 3Д только на весь экран.


 
DeadMeat ©   (2004-10-27 20:37) [24]


> [21] NikeOLD ©   (27.10.04 09:34)

Нуу... Я в своем "паратрупере" (на конкурсе) сделал именно через GetAsyncKeyState и все нормально... И до сих пор пользуюсь именно им. Хотя может быть и директ инпут тоже нормально. Надо будет глянуть.

---
...Death Is Only The Begining...


 
OSokin ©   (2004-11-07 17:04) [25]

<offtopic>
Zeqfreed, дать совет?
Если у тебя эта книга в электронном виде, лучшее, что можно сделать - отпечатать ее на мягкой бумаге и применить по назначению. Сравни примеры с последней страницы на http://www.sulaco.co.za с примерами Краснова.
</offtopic>


 
malij   (2004-11-08 18:47) [26]

Zeqfreed, дать совет?
Если у тебя эта книга в электронном виде, лучшее, что можно сделать - отпечатать ее на мягкой бумаге и применить по назначению. Сравни примеры с последней страницы на http://www.sulaco.co.za с примерами Краснова.

Примеры просто офигеть!!!!!!!!!!!!



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

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

Наверх





Память: 0.54 MB
Время: 0.039 c
8-1099143128
colonel
2004-10-30 17:32
2005.02.13
Не работает прога под win2k и XP


1-1107246266
Suvit
2005-02-01 11:24
2005.02.13
TMemo высота


3-1105879132
moonwell
2005-01-16 15:38
2005.02.13
удаление записей


10-1083094910
Netrix
2004-04-27 23:41
2005.02.13
Передача строки по COM идёт слишком медленно!


14-1106588144
kaZaNoVa
2005-01-24 20:35
2005.02.13
Unix дома миф или реальность ?





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