Array ( )
Вход:




Главная | OpenGL | GLSL | AI | Сеть | Примеры | Библиотека

OpenGL: Программирование под linux: SDL+OpenGL






По просьбе на форуме решил написать простенькую статью о программировании графики под linux.
Собственно, оснавная часть графического (openGL) кода в разных ОС остаётся практически без изменений.
Различаются только способы инициализации программы (точнее, окна). В windows собственно есть только winAPI
и различные обёртки под него. В linux же есть две основные оконные библиотеки: gtk и qt4. Если вам интересно,
вы можете найти в интернете способы инициализации окна под них. Я же опишу более простой способ: библиотека SDL.

SDL - это кроссплатформенная библиотека, предоставляющая доступ к видео, аудио, сетевому и другому оборудованию.
Нам SDL понадобится для простого создания окна, чтобы нам не пришлось заботится об установленных библиотеках:
мы скажем SDL "создай нам окошко", и оно создаст, независимо от того, какая графическая оболочка активна у пользователя:
QT или gtk. Мало того, установив эту библиотеку под windows, вы сможете практически без изменения использовать один и тот же
код инициализации в обоих системах.


Где её взять?
[a=http://www.libsdl.org/:a]http://www.libsdl.org/ - официальный сайт проекта, где можно найти всё необходимое.
Но я использую Gentoo Linux, поэтому мне достаточно набрать "emerge libsdl", и библиотека будет установлена. В большинстве
других дистрибутивов есть свои менеджеры пакетов, также позволяющие установить что-либо довольно просто.


Начинаем программировать.
Создадим один файлик, main.cpp.
Заметьте, кода для простой инициализации здесь гораздо меньше, чем в windows =)
#include <SDL.h>        // Хидер библиотеки SDL
#include <GL/gl.h>      // Хидеры OpenGL & glu
#include <GL/glu.h>

// Сначала напишем простую функцию, которая будет отрисовывать
// цветной треугольник
void Draw()
{
    // Перемещаем камеру назад
    glTranslatef(0,0,-5);
    // Рисуем треугольник
    glBegin(GL_TRIANGLES);
        glColor3f(0,1,1);
        glVertex3f(-1,0,0);
        glColor3f(1,0,1);
        glVertex3f(1,-1,0);
        glColor3f(1,1,0);
        glVertex3f(1,0,0);
    glEnd();
}

int main()
{
    // Инициализируем SDL. В качестве параметра передаём, какие именно
    // подсистемы нужно инициализировать. Например, можно указать SDL_INIT_AUDIO
    // или SDL_INIT_JOYSTICK для доступа к звуку и джойстику соответственно.
    // Ниже я приведу список возможных флагов.

    // Если произошла ошибка, SDL_Init вернёт "-1"
    if(SDL_Init(SDL_INIT_VIDEO) < 0){
        // Выводим ошибку
        printf("Error while initializing SDL: %sn",SDL_GetError());
        // и выходим из программы
        exit(1);
    }

    // устанавливаем аттрибуты OpenGL. Их больше, чем здесь, но пока
    // нам нужно только эти:
    SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);    // использовать двойной буфер
    SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 5);    // размер в битах цветовых составляющих буфера
    SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 6);  // *---
    SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 5);   // *---

    // Далее создаём окно, указывая его размер, глубину цвета, и флаги.
    // Возможные флаги я также перечислю ниже. Для указания нескольких флагов сразу
    // перечисляйте их как 'SDL_FULLSCREEN | SDL_OPENGL | ......'
    if(SDL_SetVideoMode(640,480,32,SDL_OPENGL) == NULL)
    {
        printf("Error while setting up video mode: %sn", SDL_GetError());
        exit(1);
    }

    // Ну а дальше оперируем стандартными функциями OpenGL, которые вам должны
    // быть знакомы:
    glClearColor(0,0,0,0);
    glClearDepth(1.0);
    glDepthFunc(GL_LESS);
    glEnable(GL_DEPTH_TEST);
    glShadeModel(GL_PROJECTION);
    glLoadIdentity();
    gluPerspective(45.0f, 640/480,0.1f,100.0f);
    glMatrixMode(GL_MODELVIEW);

    // Небольшой цикл программы. Ничего не делает, ждёт нажатия
    // escape для завершения.
    bool done=false;
    SDL_Event event;
    while(!done)
    {
        while(SDL_PollEvent(&event)){
            if(event.type == SDL_QUIT)
                done=true;
            if(event.type == SDL_KEYDOWN)
            {
                if(event.key.keysym.sym == SDLK_ESCAPE)
                    done=true;
            }
        }
    Draw();
    glFlush();
    SDL_GL_SwapBuffers();
    }

    // Завершаем работу SDL,
    SDL_Quit();

    return 0;
}



Теперь нужно откомпилировать написанное. Возможно, это будет немного сложновато, если вы раньше не
программировали под *nix.
Войдите в шелл (терминал, xterm/console), перейдите в директорию, где лежит файл main.cpp
Строка для компиляции:
g++ main.cpp -lGL -lGLU -lSDL -I/usr/include/SDL -o prog


Разберём по пунктам.
g++ - Команда компилятору
main.cpp - только что написанный файл
-lGL - линковка библиотеки GL
-lGLU - линковка библиотеки GLU
-lSDL - линковка библиотеки SDL
-I/usr/include/SDL - указываем путь к инклудам SDL. Он может различатся в разных системах,
в таком случае вам нужно найти его самостоятельно.
-o prog - Указываем, как должен называтся обьект на выходе.

После выполнения этой команды, если не произошло ошибок, в этой же директории должен появится
бинарный файл "prog". Запустите его, набрав "./prog", и любуйтесь своей программой =)





Возможные флаги SDL_Init():
SDL_INIT_TIMER
SDL_INIT_AUDIO
SDL_INIT_VIDEO
SDL_INIT_CDROM
SDL_INIT_JOYSTICK
SDL_INIT_EVERYTHING
SDL_INIT_NOPARACHUTE
SDL_INIT_EVENTTHREAD




Возможные флаги SDL_SetVideoMode():
SDL_SWSURFACE - создает видео поверхность в оперативной памяти.
SDL_HWSURFACE - создает видео поверхность в памяти видеокарты.
SDL_ASYNCBLIT - использование асинхронного обновления экрана. Обычно это замедляет работу
на обычных компьютерах, но значительно ускоряет на многопроцессорных системах.
SDL_ANYFORMAT - обчно, когда указанная глубина цвета невозможна на видеокарте, SDL эмулирует
ее с помощью специальной теневой поверхности. Это замедляет работу программы.
Указывая этот флаг, вы запрещаете библиотеке делать такие преобразования и
застявляете использовать "неправильную" поверхность в любом случае.
SDL_HWPALETTE - предоставляет программе эксклюзивный доступ к палитре. Без этого флага вы
не всегда сможете получить доступ к цветам функциями SDL_SetColors и SDL_SetPalette
SDL_DOUBLEBUF - включает двойной буфер. Это возможно только вместе с флагом SDL_HWSURFACE.
Функция SDL_Flip перключает буферы, обновляя экран. То есть, когда вы рисуете
что-либо, то все это отображается на невидимом буфере, а потом буферы переключаются
и невидимый становится видимым. Когда двойной буфер недоступен, функция SDL_Flip
вызывает функцию SDL_UpdataRects.
SDL_FULLSCREEN - SDL пытается переключиться в полноэкранный режим. Если по каким-либо причинам
запрошеный размер экрана не может установиться, то будет выбран следующий больший
режим, а изображение будет отцентровано на черном экране.
SDL_OPENGL - создает контекст OpenGL. Перед этим необходимо установить видео атрибуты
OpenGL с помощью функции SDL_GL_SetAttribute.
SDL_OPENGLBLIT - также создает контекст OpenGL, но позволяет blitting-операции. Экранная
поверхность (2D) может иметь альфа-канал (прозрачность) и должна обновляться
только при помощи SDL_UpdateRects.
SDL_RESIZABLE - создает изменяемое окно. Когда пользователь изменяет размер окна, возникает
событие SDL_VIDEORESIZE и можно опять вызвать функцию SDL_SetVideoMode,
чтобы установить новые размеры окна.
SDL_NOFRAME - если возможно, создает окно без рамки и заголовка. Полноэкранный режим
автоматически устанавливает этот флаг.









Комментарии:

Войдите, чтобы оставить комментарий:












Яндекс.Метрика
 Яндекс цитирования.