©
Георгиевский Анатолий,
23.01.2008
Пример интеграции интерфейса OpenGL в SDL
Пример создания простого приложения с интерфейсом OpenGL.
// описания библиотеки SDL
#include <SDL/SDL.h>
// описаниe функций OpenGL
#include <GL/gl.h>
#include <GL/glu.h>
int main(int argc, char **argv)
{
// инициализация всего-всего
SDL_Init(SDL_INIT_EVERYTHING);
// задать атрибуты цветности
SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8);
SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8);
SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8);
SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, 8);
// запросить использование двойной буферизации
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
// создание контекста для вывода OpenGL
SDL_Surface* drawContext;
drawContext = SDL_SetVideoMode(1024, 768, 0,
SDL_OPENGL | SDL_FULLSCREEN);
DrawInit(); // инициализация нашей модели
/*
* На этом окно уже раскрылось, надо придумать зачем
*/
// цикл обработки событий
SDL_Event event;
while (1){
DrawScene(); // прорисовка модели
// обработка событий от клавиатуры и мышки
while( SDL_PollEvent( &event ) ){
swicth (event.type){
// ... обработка событий от мышки и клавки ...
case SDL_QUIT: // выход из программы
SDL_Quit(); // завершение работы
exit(0);
default:
break;
}
}
SDL_Delay(interval); // ожидание между сценами 30fps
SDL_GL_SwapBuffers(); // смена экранов
}
}
Теперь в модели взаимодействия с OpenGL предлагается сделать две функции:
функцию инициализация и функцию обновления прорисовки сцены.
Инициализация происходит один раз во время создания окна и задает
параметры OpenGL, которые остаются неизменными в процессе работы приложения.
Функция прорисовки сцены должна запускаться периодически по таймеру или
по готовности данных.
В частности, при инициализации настраивается цвет фона и
перспектива изображения.
void DrawInit()
{
glClearColor (0.0, 0.0, 0.0, 0.0); // цвет фона
glClearDepth (1.0);
glMatrixMode (GL_PROJECTION);
glLoadIdentity ();
gluPerspective (64.0, aspect, zNear, zFar);
}
Простейшая трехмерная сцена будет состоять из цветного треугольника.
Для каждой вершины задается свой цвет.
void DrawScene()
{
// отображение сцены начинается с очистки буфера экрана
glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// инициализация матрицы преобразования координат
glMatrixMode (GL_MODELVIEW);
glLoadIdentity (); // загрузка единичной матрицы
// набор преобразований координат для просмотра модели
// приблизить/удалить модель
glTranslatef (0,0,-sdepth);
// наклон плоскости XY относительно оси Х
glRotatef (-stheta, 1.0, 0.0, 0.0);
// поворот плоскости XY относительно оси Z
glRotatef (sphi, 0.0, 0.0, 1.0);
// смещение изображения в плоскости XY
glTranslatef (-offsetX,-offsetY,0);
// масштабирование координат
glScalef(scale,scale,scale);
// построить модель
GLfloat red[] ={1.0,0,0,1.0};
GLfloat green[]={0,1.0,0,1.0};
GLfloat blue[] ={0,0,1.0,1.0};
GLfloat v0[] = {-1.0,-0.7, 0};
GLfloat v1[] = { 0, 1.0, 0};
GLfloat v2[] = { 1.0,-0.7, 0};
glBegin(GL_TRIANGLS);
glColor3fv(red); glVertex3fv(v0);
glColor3fv(green); glVertex3fv(v1);
glColor3fv(blue); glVertex3fv(v2);
glEnd();
}
Фиг.1. Построенная модель треугольника.
Замечания
Мы успешно протестировали наше приложение в Windows 2000/XP и Linux.
При отображении openGL с кластера мы столкнулись с ограничением производительности сети,
которая выражается в существенной задержке доставки данных на удаленный терминал, особенно через сеть интернет.
Причем, если пропускная способность сети низкая, запросы на прорисовку сцен могут становится в очередь
и таким образом задержка прорисовки сцены накапливается. Видимо, с точки зрения приложения если запрос на прорисовку
данных отправлен на удаленный терминал, данные считаются доставленными.
Чтобы избежать такой ситуации мы рекомендуем не использовать прорисовку сцен по таймеру,
а обновлять только по событиям пользовательского интерфейса: по вводу или кнопкам мышки, или по готовности данных.
()
|