Antichat снова доступен.
Форум Antichat (Античат) возвращается и снова открыт для пользователей.
Здесь обсуждаются безопасность, программирование, технологии и многое другое.
Сообщество снова собирается вместе.
Новый адрес: forum.antichat.xyz
OpenGL. От детского сада до гуру |

17.01.2008, 22:07
|
|
Постоянный
Регистрация: 29.05.2006
Сообщений: 356
Провел на форуме: 1900547
Репутация:
576
|
|
OpenGL. От детского сада до гуру
OpenGL. От детского сада до гуру.
Вступление.
Итак, начну серию своих «мирных» статей по CG(computer graphics). Здесь я попытаюсь рассказать вам о программировании под OpenGL и DirectX, о WinAPI и двойной буферизации, о физике твердых тел(Rigid Body) и построении высоко фотореалистичных изображений методом трассировки лучей(Ray Tracing). Надеюсь, это станет интересным для многих, а некоторые и вовсе найдут в себе таланты CG`шников.
Для затравки я решил начать с цикла по программированию на С под OpenGL. Хоть приведенный код будет и на С(С++ в данном курсе использовать не обязательно, так что не буду придумывать сложности, мне-то все равно на чем писать, но многих может отпугнуть. Поклонникам ООП, для вас следующие статьи, стоит, например, лишь сказать, что Ray Tracing считается классической и лучшей задачей на С++), но я постараюсь снабжать его максимально понятными и подробными комментариями, всвязи с чем код будет абсолютно портируемым хоть на Delphi, хоть на Python, хоть на Haskell.
«Цикл» будет состоять из следующих частей:
Часть 1. Базовый макет GLUT-приложения
Простейшие OpenGL программы с использованием OpenGL Utility Toolkit для любой операционной системы.
Часть 2. Освещение и тени
Создание источников света, физические коэффициенты, тени.
Часть 3. Рисование полигонов. Текстурирование и прозрачность
Рисование собственных фигур. Наложение текстур. Создание прозрачности и полупрозрачности.
Часть 4. Мультитекстурирование. OpenGL Shaders. OpenGL Shader Language
Наложение нескольких текстур. Инициализация шейдеров. Работа с шейдерами. Язык программирования GLSL.
Часть 5. Пример базового макета системы анимации на WinAPI, двойной буферизации и OpenGL
«Взрослое» программирование под OpenGL. Пишем без GLUT под Windows.
Часть 6. Пример базового макета системы анимации на Qt4 и OpenGL
«Взрослое» программирование под OpenGL. Пишем без GLUT кроссплатформенные приложения с использование Qt4.
Часть 7. Загрузка моделей из редактора Maya
Работать со стандартными моделями и полигонами не интересно. Так что завершим весь цикл загрузкой моделей из популярного редактора 3D графики Maya.
Часть 1. Базовый макет GLUT-приложения
Начинать, разумеется стоит с самых основ. А потому эту статью я посвящу самой простой части OpenGL.- GLUT или OpenGL Utility Toolkit. Но начнем разбираться по порядку.
OpenGL (Open Graphics Library — открытая графическая библиотека) — спецификация, определяющая независимый от языка программирования кросс-платформенный программный интерфейс для написания приложений, использующих двумерную и трехмерную компьютерную графику. (с) Википедия
OpenGL работает по принципу клиент-серверной системы, где в роли клиента выступает оформленная программа с использованием специального API, а в роли сервера обрабатывающая OpenGL часть графического процессора(GPU) видеокарты. Нашей задачей будет на протяжении цикла научиться пользоваться API для реализации любой проблемы, а так же понимать, на что идут ресурсы нашей видеокарты и как свести их трату к минимуму..
Вплоть до частей 5 и 6 мы будем пользоваться кроссплатформенной библиотекой GLUT. Это позволит нам не совершать дополнительных инициализаций и писать простой, понятный и кроссплатформенный код. Практически, 99% всех задач можно реализовать с использованием GLUT. Почему же лучше писать на «чистом» API и как это делать мы разберем уже в 5 и 6 частях, когда откажемся от его использования. Пока же начнем разбираться, с чем нам работать ближайшее время.
Перед тем, как начнем писать программу, скажу, что GLUT а так же все необходимые библиотеки и файлы заголовков берутся с сайта _http://opengl.org.
Итак, после этого вступления начнем писать программу.
PHP код:
/* Подключаем необходимые файл заголовков. Зачем нам stdio, stdlib и time - дальше */
#include <GL/glut.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
/* Объявляем главную функцию. Использование аргументов крайне желательно */
int main( int argc, char *argv[] )
{
/* Инициализация GLUT API от параметров командной строки. */
glutInit(&argc,argv);
/* Инициализация системы анимации
* GLUT_DOUBLE — включение двойного буфера(подробнее в следующих статьях, сейчас отмечу,
* что это избавит нас от мерцания изображения)
* GLUT_RGB — Red, Green, Blue гамма, без комментариев
* GLUT_DEPTH — использование окна с буфером глубины для реалистичной объемности
*/
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
/* Тут все элементарно — выставляем размеры окна. Сначала ширину, потом высоту. */
glutInitWindowSize(512, 512);
/* Создание окна. Параметр — заголовок окна. Для недоуменных гуру коддинга напоминаю, что мы идем от простого к сложному */
glutCreateWindow("My window");
/* Устанавливаем цвет очистки экрана. R, G, B, Alpha. Впоследствии, когда вам нужно будет инициализировать многие вещи, такие как свет, шейдера и проч, где-то здесь будет вызываться ваша функция инициализации всего этого */
glClearColor(0,0,0,0);
/* Функция обработки изменения размеров окна. Параметр — указатель на функцию обработки */
glutReshapeFunc(Reshape);
/* Функция вывода сцены на экран. Параметр — указатель на функцию обработки */
glutDisplayFunc(Display);
/* Функция «простоя» системы. Параметр — указатель на функцию обработки */
glutIdleFunc(Idle);
/* Функция обработки клавиатуры. Параметр — указатель на функцию обработки */
glutKeyboardFunc(Keyboard);
/* Запускает работу GLUT */
glutMainLoop();
/* Выход в систему с кодом 0, т.е. все супер */
return 0;
}
Думаю, тут все предельно просто и ясно. Такая инициализация будет в большинстве ваших GLUT-программ. Для полной ясности рассмотрим описанные функции. Я использовал лишь обязательные и те, по аналогии с которыми можно понять работу с другими, о которых вы уже узнаете подробнее из манов, или которые мы будем использовать в следующих статьях. Первая функция, которая нам встретилась — Reshape, с нее и начнем.
PHP код:
/* Функция принимает 2 параметра — новую ширину и новую высоту окна */
void Reshape( int W, int H )
{
/* Задаем область просмотра в виде прямоугольника с диагонально противоположными вершинами (x1;y1) и (x2;y2). В нашем случае (0;0) и (W;H) */
glViewport(0, 0, W, H);
/* Задаем матрицу проекционной */
glMatrixMode(GL_PROJECTION);
/* Переходим на установленную проекционную матрицу */
glLoadIdentity();
/* Как известно, существуют 2 вида проекции: ортогональная и перспективная. В ортогональной лучи идут параллельными, в перспективе сходятся в некой точке. Мы будем использовать матрицу перспективы, как более удобную. Параметры — угол обзора, коэффициент отношения ширины к высоте и, так называемые, zNear и zFar или границы отсечения изображения, т.е. Изображение будет показываться в промежутке от zNear до zFar */
gluPerspective(60, (double)W / H, 1, 500);
/* Откуда и куда смотрим. Первые 3 аргумента — точка, куда направлена камера, следующие 3 — точка расположения камеры, последние 3 — вектор «на макушку», т.е. задающий вектор ориентированный на верх камеры */
gluLookAt(0, 0, 15, 0, 0, 0, 0, 1, 0);
/* Устанавливаем «видовую» матрицу и переходим на нее */
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
Следующая функция, которая очевидно должна быть рассмотрена — это сама функция Display.
PHP код:
/* Функция не принимает аргументов. Тут все просто */
void Display( void )
{
/* Перед рисованием нового кадра очищаем буферы цвета и глубины */
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
/* Вызываем функцию непосредственно отрисовки, ее опишем в последнюю очередь */
Draw();
/* Так как мы используем двойной буфер нам надо скинуть информацию на экран */
glutSwapBuffers();
}
Далее рассмотрим функцию Idle, выполняющуюся во время простоя программы. Давайте заведем еще какую-нибудь глобальную переменную static double SyncTime и будем с помощью этой функции делать синхронизацию по времени.
PHP код:
/* Как и Display, функция ничего не получает */
void Idle( void )
{
/* Заведем пару переменных для просчета времени */
long Time;
static long OldTime = -1;
/* При первом запуске стартуем таймер */
if(OldTime == -1)
OldTime = clock();
/* Считаем число «клоков» на данное время с момента запуска программы */
Time = clock() - OldTime;
/* В SyncTime записываем уже секунды */
SyncTime = (double)Time/CLOCKS_PER_SEC;
/* Перерисовываем кадр */
glutPostRedisplay();
}
Последнее, что мы разберем перед самой прорисовкой кадра, это обработка клавиатуры. Тут даже ничего комментировать не стану, все и так предельно ясно. Напомню только, что 27 — это код ESC. 
Абсолютно аналогично будет строится обработка мыши и прочих устройств ввода.
PHP код:
void Keyboard( unsigned char Ch, int Mx, int My )
{
if (Ch == 27)
exit(0);
}
И последнее на сегодня. Нарисуем что-нибудь в нашей сцене. Предлагаю сделать это зеленым тором в wireframe. Почему wire? Т.к. Мы пока не сделали освещения, залитая фигура будет смотреться не эстетично и не красиво. Почему тор? Просто мне нравится эта фигура, да еще она и есть среди стандартных GLUT фигур. Отрисовывать свои фигуры начнем со следующей статьи. А пока разбираем несложную функцию Draw.
PHP код:
/* Ничего не получаем */
void Draw( void )
{
/* Сохраняем текущую матрицу преобразований в стек */
glPushMatrix();
/* Устанавливаем цвет всех последующих объектов на зеленый. D в конце функции означает, что будут использоваться double числа. Есть еще вариант с float. Цвета задаются дробными числами в отрезке [0..1] */
glColor3d(0,1,0);
/* Поворачиваем сцену на 30*SyncTime градусов вокруг вектора (0;1;0) */
glRotated(30*SyncTime, 0, 1, 0);
/* Рисуем тор. Параметры: размер внутреннего кольца, размер внешнего кольца и 2 параметра полигонизации, т.е. качества отрисовки */
glutWireTorus(2, 5, 50, 50);
/* Восстанавливаем сохраненную матрицу из стека */
glPopMatrix();
}
На этом, думаю, моя первая статья из цикла OpenGL будет завершена. Надеюсь, вам она покажется интересной, а меня за нее сильно не будут пинать. Ждите новых статей из цикла OpenGL и других тем CG. Творите! Удачи!
|
|
|
|
|
Здесь присутствуют: 1 (пользователей: 0 , гостей: 1)
|
|
|
|