DKey, Он не мой он мелкософта .
| Цитата | На этот раз мы немного отвлечемся от 2D в сторону модного нынче 3D. Не нужно говорить, что на сегодняшний день единственным API для трехмерной графики под Linux является OpenGL. Думаю вы уже знакомы с этой библиотекой, хотя бы немного. Если же нет, то предлагаю сначала почитать основы работы с этой библиотекой (благо в интернете множество документации для начинающих). Данный урок - не самый лучше источник для знакомства с OpenGL. Разработчики SDL - люди неординарного ума. Поэтому неудивительно, что они выбрали гениальную позицию: не создавать свой 3D API, а использовать отточенный годами интерфейс OpenGL. Но не просто использовать, а создали замечательные средства для интеграции OpenGL в SDL приложение. Таким образом мы получаем в распоряжение множество дополнительных средств (таймеры, загрузка изображений, потоки, звук, сеть и т.п.). В прошлом уроке мы разобрали, что расширение DGA2 добавляет аппаратное ускорение к 2D программам. Но на некоторых системах было замечено, что это расширение не работает из-по обычного пользователя. Один из выходов - не использовать средства блиттинга SDL, а использовать OpenGL для отображения 2D. В принципе не сложно переписать например нашу библиотеку для спрайтов с поддержкой OpenGL, т.к. у многих пользователей стоят драйверы, обеспечивающие аппаратное ускорение 3D. Можно дать выбор при компиляции проекта: использовать OpenGL или же средства SDL. Создание OpenGL контекста средствами библиотеки SDL в действительности почти не отличается от инициализации обычного приложения SDL. Во-первых, вы должны указать флаг SDL_OPENGL для функции SDL_SetVideoMode(), Во-вторых, необходимо задать несколько параметров для OpenGL приложения (например размеры буфера глубины и буфера кадров) используя специальную функцию SDL_GL_SetAttribute, и наконец, если необходимо использовать двойной буфер, то необходимо установить его при помощи специального GL атрибута, но не нужно указывать флаг SDL_DOUBLEBUF функции SDL_SetVideoMode(), как для 2D приложения, поскольку он не будет работать для контекста OpenGL. Для начала необходимо включить нужные файлы заголовков:
| Код | #include "SDL.h" #include "gl.h" #include "glu.h"
|
Пути к этим файлам могут различаться в разных системах, поэтому может потребоваться изменить пути в Makefile (опция I). С самого начала необходимо инициализировать подсистемы:
| Код | if ( SDL_Init(SDL_INIT_TIMER|SDL_INIT_VIDEO) < 0 ){ printf("Unable to init SDL: %s\n", SDL_GetError()); exit(1); } atexit(SDL_Quit);
|
В нашем случае это видео подсистема и подсистема таймера для расчета FPS. Также не забываем вызывать функцию SDL_Quit() при выходе из программы.Далее устанавливаем GL атрибуты программы: | Код | 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_GL_SetAttribute в качестве параметров принимает название атрибута и его значение. В нашем случае мы указали использовать двойной буфер (1 - использовать, 0 - не использовать) и указали размеры составляющих каждого цвета для буфера кадров. На самом деле атрибутов несколько больше:
SDL_GL_RED_SIZE Размер красной составляющей буфера кадров, бит SDL_GL_GREEN_SIZE Размер зеленой составляющей буфера кадров, бит SDL_GL_BLUE_SIZE Размер синей составляющей буфера кадров, бит SDL_GL_ALPHA_SIZE Размер альфа (прозрачности) составляющей буфера кадров, бит SDL_GL_DOUBLEBUFFER 0 или 1, использовать или не использовать двойной буфер SDL_GL_BUFFER_SIZE Размер буфера кадров, бит SDL_GL_DEPTH_SIZE Размер буфера глубины, бит SDL_GL_STENCIL_SIZE Размер буфера шаблона, бит SDL_GL_ACCUM_RED_SIZE Размер красной составляющей буфера аккумулятора, бит SDL_GL_ACCUM_GREEN_SIZE Размер зеленой составляющей буфера аккумулятора, бит SDL_GL_ACCUM_BLUE_SIZE Размер синей составляющей буфера аккумулятора, бит SDL_GL_ACCUM_ALPHA_SIZE Размер альфа составляющей буфера аккумулятора, бит
Обратите внимание, что при необходимости использования двойного буфера просто укажите GL атрибут SDL_GL_DOUBLEBUFFER. Установка флага SDL_DOUBLEBUF не оказывает влияния на OpenGL контекст. Чтобы атрибуты начали действовать, далее необходимо установить видеорежим и задать флаг | Код | SDL_OPENGL: if ( SDL_SetVideoMode(640,480,32,SDL_OPENGL) == NULL ){ printf("Unable to set 640x480 video: %s\n", SDL_GetError()); exit(1); }
|
Здесь мы создаем окно 640х480 с глубиной цвета 32 бита. Можете установить флаг SDL_FULLSCREEN для рабоы в полноэкранном режиме. На этом инициализация OpenGL контекста закончена! Далее устанавливаем необходимые режимы стандартными функциями GL и GLU, такие как например цвет очищения экрана и тип проекции. В главном цикле программы мы обрабатываем нажатие клавиш и рисуем сцену. Обратите внимание, что для обновления экрана при использовании двойного буфера (в большинстве своем программы его используют) необходимо использовать специальную функцию SDL_GL_SwapBufers() вместо стандартной функции GL. Это очень важно!
| Код | glClearColor(0.0f, 0.0f, 0.0f, 0.0f); glClearDepth(1.0); glDepthFunc(GL_LESS); glEnable(GL_DEPTH_TEST); glShadeModel(GL_SMOOTH); glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective(45.0f,640/480,0.1f,100.0f); glMatrixMode(GL_MODELVIEW); SDL_TimerID my_timer_id = SDL_AddTimer(1000, my_callbackfunc, my_callback_param);
|
Устанавливаем режимы OpenGL и инициализируем таймер. int done=0; while(done == 0){ | Код | SDL_Event event; while ( SDL_PollEvent(&event) ){ if ( event.type == SDL_QUIT ){ done = 1; } if ( event.type == SDL_KEYDOWN ){ if ( event.key.keysym.sym == SDLK_ESCAPE ){ done = 1; } } } DrawGLScene(); glFlush(); SDL_GL_SwapBuffers(); fps++; }
|
В главном цикле обрабатываем события и рисуем сцену. Обратите внимание на SDL_GL_SwapBuffers()! Функция glFlush() - посылает сцену на конвейер. Функция рисования сцены DrawGLScene() на самом деле не представляет никакой сложности. В ней рисуется куб с разноцветными гранями. Глобальные переменные xrf, yrf и zrf - так называемые rotate factors, т.е. угол поворота по соответствующим осям. Каждый фрейм мы изменяем эти значения, создавая интересный эффект вращения куба.
|
Добавлено @ 13:21 DKey,ЭТО OpenGL+SDL = много платформ .Желаю удачи. |