LINUX.ORG.RU

OpenGL Fullscreen [how]


0

1

Решил из своего приложения убрать glut, возникла проблема, не смог найти каким образом вывод сделать на весь экран (в GLUT есть для этого glutGameMod), каким образом можно это осуществить ?
Рассмотрю любые варианты и советы (желательно с примером)
Спасибо

★★★★★

glut проприетарный блоб? *пичяль*
man glXCreateContext

hizel ★★★★★
()

Вот еще возник вопрос, каким образом можно сделать переход от полноэкранного режима к оконному ?

deterok ★★★★★
() автор топика
Ответ на: комментарий от Reset

Нет, но поковырял чуть-чуть tuxracer :)
Сейчас попробую поковырять glut

deterok ★★★★★
() автор топика
Ответ на: комментарий от deterok

В glut всё есть и есть исходники соответствующих функций. Каждая функция в glut занимает пару строк поэтому разобраться не сложно.

Reset ★★★★★
()

Разрешение экрана можешь менять через XRandR(в частности функция XRRSetScreenConfig), а окну надо менять атом _NET_WM_STATE_FULLSCREEN. Распространенный метод блокировки всего и вся(как сделано в SDL) - только для мудаков, не вздумай им пользоваться :)

Andru ★★★★
()

Может лучше заменить Glut на SDL, чем писать велосипед?

anonymous
()
Ответ на: комментарий от Andru

> Распространенный метод блокировки всего и вся(как сделано в SDL) - только для мудаков

Мне одно непонятно — почему бы им не сделать по-человечески наконец?

pevzi ★★★★★
()
Ответ на: комментарий от pevzi

Мне одно непонятно — почему бы им не сделать по-человечески наконец?

Я тоже в недоумении... помнится когда-то хотел было там переписать эту часть(насколько помню, там вместо XRandR используется xf86vm), но глянув на те дебри, я решил не связываться с этим всем ) Но одна из причин, почему они это не сделают «по-человечески» еще заключается в том, что Catalyst до недавнего времени окно с атомом _NET_WM_STATE_FULLSCREEN делал всегда OnTop и при попытке сделать Alt-Tab всё зависало. Правда в Catalyst 10.12 уже пофиксили.

Andru ★★★★
()
Ответ на: комментарий от Andru

Не могли бы вы привести пример работы с XRandR и атомами (всего месяц под linux программирую :))

deterok ★★★★★
() автор топика
Ответ на: комментарий от deterok

Для себя я программирую на Pascal'е, так что мои куски кода могут только больше запутать, ввиду того, что типы там по другому называются. Поэтому приведу только ссылки. Про атомы можешь почерпнуть инфу из wiki на самом ЛОР'е. Но когда будешь менять атом _NET_WM_STATE_FULLSCREEN придется еще позаботиться о том, что бы через XSetWMNormalHints убрать заголовок окна и т.д.:

void wnd_SetHints()
{
  XSizeHints sizehints;
  memset( &sizehints, 0, sizeof( XSizeHints ) );
  if ( wnd_FullScreen )
    sizehints.flags    = PBaseSize | PWinGravity;
  else
    sizehints.flags    = PPosition | PSize | PMinSize | PMaxSize;
  sizehints.x          = wnd_X;
  sizehints.y          = wnd_Y;
  sizehints.width      = wnd_Width;
  sizehints.height     = wnd_Height;
  sizehints.min_width  = wnd_Width;
  sizehints.max_width  = wnd_Width;
  sizehints.min_height = wnd_Height;
  sizehints.max_height = wnd_Height;
  XSetWMNormalHints( scr_Display, wnd_Handle, &sizehints );
}
где wnd_FullScreen - состояние fullscreen'а, wnd_X/wnd_Y - позиция окна, wnd_Width/wnd_Height - размеры окна, scr_Display - твой результат XOpenDisplay, wnd_Hanle - хендл окна. Надеюсь код на си взлетит :)

С XRandR я даже не знаю... googlecode наверное в помощь :)

Andru ★★★★
()
Ответ на: комментарий от Andru

Спасибо, сейчас попробую
Еще один вопрос созрел: Допустим я получил окно с opengl, так как это все же окно, возможно, что всплывающие сообщения будут перекрывать мое окно, как это можно решить ?
(я предполагаю, что его можно сделать «всегда сверху», а когда оно теряет фокус свернуть его и остановить все действия)

deterok ★★★★★
() автор топика
Ответ на: комментарий от deterok

я предполагаю, что его можно сделать «всегда сверху»

ага, и тут опять же надо смотреть в сторону атомов, которые позволяют указать данное свойство окну :)

Andru ★★★★
()
Ответ на: комментарий от Andru

Чет с атомами никак не могу справится, 3 часа просидел, но не врубился как их присваивать вообще

deterok ★★★★★
() автор топика
Ответ на: комментарий от deterok

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

anonymous
()
Ответ на: комментарий от deterok

Очень похабный код, но работающий(«жрет» процессор и меняет состояние окна при нажатии любой кнопки)... enjoy :) Конпеляется так

gcc demo.c -lX11

И не вздумай его юзать не прочитав man'ы.

#include <memory.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>

typedef unsigned char boolean;

Display* scr_Display;

Window wnd_Handle, wnd_Root;
XSetWindowAttributes wnd_Attr;
unsigned int wnd_ValueMask;
boolean wnd_FullScreen;
int wnd_X = 0, wnd_Y = 0, wnd_Width = 800, wnd_Height = 600;

void wnd_SetHints()
{
  XSizeHints sizehints;
  memset( &sizehints, 0, sizeof( XSizeHints ) );
  if ( wnd_FullScreen )
    sizehints.flags    = PBaseSize | PWinGravity;
  else
    sizehints.flags    = PPosition | PSize | PMinSize | PMaxSize;
  sizehints.x          = wnd_X;
  sizehints.y          = wnd_Y;
  sizehints.width      = wnd_Width;
  sizehints.height     = wnd_Height;
  sizehints.min_width  = wnd_Width;
  sizehints.max_width  = wnd_Width;
  sizehints.min_height = wnd_Height;
  sizehints.max_height = wnd_Height;
  XSetWMNormalHints( scr_Display, wnd_Handle, &sizehints );
}

int main()
{
  XEvent event;

  scr_Display = XOpenDisplay( NULL );
  wnd_Root    = DefaultRootWindow( scr_Display );

  wnd_Attr.event_mask = KeyPressMask | StructureNotifyMask;
  wnd_ValueMask       = CWEventMask | CWOverrideRedirect | CWBorderPixel | CWBackPixel;
  wnd_Handle          = XCreateWindow( scr_Display, wnd_Root, wnd_X, wnd_Y, wnd_Width, wnd_Height, 0, CopyFromParent, InputOutput, CopyFromParent, wnd_ValueMask, &wnd_Attr );
  XMapWindow( scr_Display, wnd_Handle );
  // один раз надо бы инициализировать
  wnd_SetHints();

  while ( 1 )
  {
    while ( XPending( scr_Display ) != 0 )
    {
      XNextEvent( scr_Display, &event );

      if ( event.type == KeyPress )
      {
        XEvent eventChange;

        // меняем сперва "стиль" окна
        wnd_FullScreen = !wnd_FullScreen;
        XSync( scr_Display, 1 );
        wnd_SetHints();

        // устанвливаем значение атому через отсылку сообщения
        memset( &event, 0, sizeof( XEvent ) );
        eventChange.type                 = ClientMessage;
        eventChange.xclient.type         = ClientMessage;
        eventChange.xclient.send_event   = 1;
        eventChange.xclient.window       = wnd_Handle;
        eventChange.xclient.message_type = XInternAtom( scr_Display, "_NET_WM_STATE", 0 );
        eventChange.xclient.format       = 32;
        eventChange.xclient.data.l[ 0 ]  = wnd_FullScreen;
        eventChange.xclient.data.l[ 1 ]  = XInternAtom( scr_Display, "_NET_WM_STATE_FULLSCREEN", 0 );
        XSendEvent( scr_Display, wnd_Root, 0, SubstructureRedirectMask | SubstructureNotifyMask, &eventChange );
      }
    }
  };

  return 0;
}

Andru ★★★★
()
Ответ на: комментарий от Andru

Код рабочий. Хотел бы удостоверится что все понял и одновременно задать пару вопросов (в коде)

#include <memory.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>

//немного не понятно, зачем нужно переопределять тип ?
typedef unsigned char boolean;

// тут создаем указатель на структуру дисплея
Display* scr_Display;

Window wnd_Handle, wnd_Root; /*Идентификатор моего окна и главного (ачто является главным окном ?)*/
XSetWindowAttributes wnd_Attr; /*Какие то настройки окна*/
unsigned int wnd_ValueMask; /*Какие то маски атрибутов (не понял зачем нужны)*/
boolean wnd_FullScreen;
/*Координаты левого верхнего угла окна и его размеры*/
int wnd_X = 0, wnd_Y = 0, wnd_Width = 800, wnd_Height = 600; 

void wnd_SetHints() 
{
  XSizeHints sizehints;/*Рекомендации о размерах окна (Почему только рекомендации ? Могут быть обстоятельства когда они не выполняются ?)*/
  memset( &sizehints, 0, sizeof( XSizeHints ) ); /* Инициализируем рекомендации (Никогда раньше ни работал с памятью так, но как понял все байты sizehints заполняются 0, тем самым подготавливая пространство) */
  if ( wnd_FullScreen )
    sizehints.flags    = PBaseSize | PWinGravity; /*указываем какие атрибуты будем использовать*/
  else
    sizehints.flags    = PPosition | PSize | PMinSize | PMaxSize;
  sizehints.x          = wnd_X; /*Написано что болше не используется указание координат и ширина с высотой (http://www.asvcorp.ru/tech/linux/xwinprg/structs/XSizeHints.html)*/
  sizehints.y          = wnd_Y;
  sizehints.width      = wnd_Width;
  sizehints.height     = wnd_Height;
  sizehints.min_width  = wnd_Width;
  sizehints.max_width  = wnd_Width;
  sizehints.min_height = wnd_Height;
  sizehints.max_height = wnd_Height;
  XSetWMNormalHints( scr_Display, wnd_Handle, &sizehints );
}

int main()
{
  XEvent event;

  scr_Display = XOpenDisplay( NULL ); /*Связываем наш дисплей*/
  wnd_Root    = DefaultRootWindow( scr_Display ); /*указываем корневое окно*/

  wnd_Attr.event_mask = KeyPressMask | StructureNotifyMask;/*Указываем какого типа события будем отправлять ( или принимать ? )*/
  wnd_ValueMask       = CWEventMask | CWOverrideRedirect | CWBorderPixel | CWBackPixel; /*Что то со свойствами окна, CWOverrideRedirect вроде запрещает оконному менеджеру работать с окном, а дальше не очень понял*/
  wnd_Handle          = XCreateWindow( scr_Display, wnd_Root, wnd_X, wnd_Y, wnd_Width, wnd_Height, 0, CopyFromParent, InputOutput, CopyFromParent, wnd_ValueMask, &wnd_Attr ); /*Наконец таки создаем окно (три раза перекрестившись :))*/
  XMapWindow( scr_Display, wnd_Handle ); /*Отображаем его*/
  // один раз надо бы инициализировать
  wnd_SetHints();

  while ( 1 )
  {
    while ( XPending( scr_Display ) != 0 )/*пока есть сообщения в очереди дисплея выполнять*/
    {
      XNextEvent( scr_Display, &event );/*Берем событие из очереди*/

      if ( event.type == KeyPress )/*Сравниваем тип события*/
      {
        XEvent eventChange;

        // меняем сперва "стиль" окна
        wnd_FullScreen = !wnd_FullScreen;
        XSync( scr_Display, 1 ); /*Не понимаю эту запись, точнее что она делает/
        wnd_SetHints(); 

        // устанвливаем значение атому через отсылку сообщения
        memset( &event, 0, sizeof( XEvent ) );
        eventChange.type                 = ClientMessage; /*Не понял что за тип, к чему он относится и зачем нужен*/
        eventChange.xclient.type         = ClientMessage;/*Тоже что и предыдущий*/
        eventChange.xclient.send_event   = 1;/*Послать событие (А что, можно и не посылать ?)*/
        eventChange.xclient.window       = wnd_Handle; /*Окно приемник*/
        eventChange.xclient.message_type = XInternAtom( scr_Display, "_NET_WM_STATE", 0 ); /*Строка не ясна*/
        eventChange.xclient.format       = 32;/* Не понял что за формат, для чего он нужен и как влияет на работу*/
        eventChange.xclient.data.l[ 0 ]  = wnd_FullScreen;
        eventChange.xclient.data.l[ 1 ]  = XInternAtom( scr_Display, "_NET_WM_STATE_FULLSCREEN", 0 ); /*информация о состояние атома, которую отправляем, только при чем тут wnd_FullScreen;*/
        XSendEvent( scr_Display, wnd_Root, 0, SubstructureRedirectMask | SubstructureNotifyMask, &eventChange ); /*Вот теперь отправляем*/
      }
    }
  };

  return 0; /*Не понятно как из бесконечного цикла выходит программа*/
}
Спасибо за исходник, но почему он жрет проц и в какую сторону смотреть, что бы улучшить его ?

deterok ★★★★★
() автор топика
Ответ на: комментарий от Andru

Ужас! Тока заметил как нагружает систему это окошко! Буду пробовать исправить бесконечныйцикл

deterok ★★★★★
() автор топика
Ответ на: комментарий от deterok

Ужас! Тока заметил как нагружает систему это окошко! Буду пробовать исправить бесконечныйцикл

исправить можно только вертикальной синхронизацией при использовании OpenGL, либо вставлять sleep'ы, но это не лучшая идея. Да и не заморачивайся - игра должна использовать ресурсы )

По поводу вопросов - я думал ты хоть какое-то представление имеешь, а тут... рекомендую тебе таки юзать glut дальше, т.к. я не ходячая энциклопедия и не «руководство как освоить Xlib за несколько постов на форуме» :)

Andru ★★★★
()
Ответ на: комментарий от deterok

А почему вы glut не хотите использовать? Ведь если привязываться к иксам напрямую, есть шанс, что после очередного обновления иксов в вашей программе что-нибудь да отвалится...

Eddy_Em ☆☆☆☆☆
()
Ответ на: комментарий от Eddy_Em

Ведь если привязываться к иксам напрямую, есть шанс, что после очередного обновления иксов в вашей программе что-нибудь да отвалится...

Для нужд ТС'а API уже устаканилось много-много лет назад, и шанс его смены ничтожно мал, это тебе не ядро )

Andru ★★★★
()

Извините что отвлекаю, но скажите, почему не использовать SDL, и я отстану. Просто никаких «против» не видно. Одни только профиты. Там и звук, картинки можно, джойстики. А зависимость очень легковесная и лицензия хорошая, LGPL еще никому не мешал. Тем более SDL+OpenGL одно из наиболее проверенных и удачных решений

vertexua ★★★★★
()
Ответ на: комментарий от deterok

Как вы относитесь к этим руководствам: http://tronche.com/gui/x/
Они еще актуальны ?

Актуальность таких мануалов вряд ли будет потеряна с течением времени до того момента, пока не выпустят X12, иначе пришлось бы переписывать весь софт :) Я конечно не читал то, что там по ссылке, но если там на первых порах доходчиво описано как создавать окошки, обрабатывать их сообщения и т.д. - думаю стоит ознакомится с этой базой. Правда в этих мануалах, как правило, нет связующего с OpenGL момента. Т.е. описание как использовать visual info, как инициализировать сам OpenGL контекст и т.д. И это придётся отдельно ещё где читать. Если охота всю эту системщину понять - дерзай. Но как только захочется портировать своё приложение ещё куда - придётся тратить время на другие API... мороки много, и количество граблей просто неописуемо на первых порах :) Так что если самоцель - написание приложения, то лучше посвятить время ему, а не изобретению своего велосипеда.

И да, не надо ко мне на «вы» :)

Andru ★★★★
()
Ответ на: комментарий от Andru

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

deterok ★★★★★
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.