ANTICHAT.XYZ    VIDEO.ANTICHAT.XYZ    НОВЫЕ СООБЩЕНИЯ    ФОРУМ  
Баннер 1   Баннер 2
Antichat снова доступен.
Форум Antichat (Античат) возвращается и снова открыт для пользователей. Здесь обсуждаются безопасность, программирование, технологии и многое другое. Сообщество снова собирается вместе.
Новый адрес: forum.antichat.xyz
Вернуться   Форум АНТИЧАТ > ИНФО > Статьи > Авторские статьи
   
 
 
Опции темы Поиск в этой теме Опции просмотра

OpenGL. От детского сада до гуру
  #1  
Старый 17.01.2008, 22:07
Аватар для MacTep
MacTep
Постоянный
Регистрация: 29.05.2006
Сообщений: 356
Провел на форуме:
1900547

Репутация: 576
Отправить сообщение для MacTep с помощью ICQ
По умолчанию 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 argcchar *argv[] )
{
  
/* Инициализация GLUT API от параметров командной строки. */
  
glutInit(&argc,argv);

  
/* Инициализация системы анимации
   * GLUT_DOUBLE — включение двойного буфера(подробнее в следующих статьях, сейчас отмечу,
   *   что это избавит нас от мерцания изображения)
   * GLUT_RGB — Red, Green, Blue гамма, без комментариев
   * GLUT_DEPTH — использование окна с буфером глубины для реалистичной объемности 
   */
  
glutInitDisplayMode(GLUT_DOUBLE GLUT_RGB GLUT_DEPTH);

  
/* Тут все элементарно — выставляем размеры окна. Сначала ширину, потом высоту. */
  
glutInitWindowSize(512512);
  
  
/* Создание окна. Параметр — заголовок окна. Для недоуменных гуру коддинга напоминаю, что мы идем от простого к сложному */
  
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 Reshapeint Wint H )
{
  
/* Задаем область просмотра в виде прямоугольника с диагонально противоположными вершинами (x1;y1) и (x2;y2). В нашем случае (0;0) и (W;H) */
  
glViewport(00WH);

  
/* Задаем матрицу проекционной */
  
glMatrixMode(GL_PROJECTION);

  
/* Переходим на установленную проекционную матрицу */
  
glLoadIdentity();

  
/* Как известно, существуют 2 вида проекции: ортогональная и перспективная. В ортогональной лучи идут параллельными, в перспективе сходятся в некой точке. Мы будем использовать матрицу перспективы, как более удобную. Параметры — угол обзора, коэффициент отношения ширины к высоте и, так называемые, zNear и zFar или границы отсечения изображения, т.е. Изображение будет показываться в промежутке от zNear до zFar */
  
gluPerspective(60, (double)H1500);

  
/* Откуда и куда смотрим. Первые 3 аргумента — точка, куда направлена камера, следующие 3 — точка расположения камеры, последние 3 — вектор «на макушку», т.е. задающий вектор ориентированный на верх камеры */
  
gluLookAt(0015000010);

  
/* Устанавливаем «видовую» матрицу и переходим на нее */
  
glMatrixMode(GL_MODELVIEW);
  
glLoadIdentity();

Следующая функция, которая очевидно должна быть рассмотрена — это сама функция Display.

PHP код:
/* Функция не принимает аргументов. Тут все просто */
void Displayvoid )
{
  
/* Перед рисованием нового кадра очищаем буферы цвета и глубины */
  
glClear(GL_COLOR_BUFFER_BIT GL_DEPTH_BUFFER_BIT);

  
/* Вызываем функцию непосредственно отрисовки, ее опишем в последнюю очередь */
  
Draw();

  
/* Так как мы используем двойной буфер нам надо скинуть информацию на экран */
  
glutSwapBuffers();

Далее рассмотрим функцию Idle, выполняющуюся во время простоя программы. Давайте заведем еще какую-нибудь глобальную переменную static double SyncTime и будем с помощью этой функции делать синхронизацию по времени.

PHP код:
/* Как и Display, функция ничего не получает */
void Idlevoid )
{
  
/* Заведем пару переменных для просчета времени */
  
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 Keyboardunsigned char Chint Mxint My )
{
  if (
Ch == 27)
    exit(
0);

И последнее на сегодня. Нарисуем что-нибудь в нашей сцене. Предлагаю сделать это зеленым тором в wireframe. Почему wire? Т.к. Мы пока не сделали освещения, залитая фигура будет смотреться не эстетично и не красиво. Почему тор? Просто мне нравится эта фигура, да еще она и есть среди стандартных GLUT фигур. Отрисовывать свои фигуры начнем со следующей статьи. А пока разбираем несложную функцию Draw.

PHP код:
/* Ничего не получаем */
void Drawvoid )
{
  
/* Сохраняем текущую матрицу преобразований в стек */
  
glPushMatrix();

  
/* Устанавливаем цвет всех последующих объектов на зеленый. D в конце функции означает, что будут использоваться double числа. Есть еще вариант с float. Цвета задаются дробными числами в отрезке [0..1] */
  
glColor3d(0,1,0);

  
/* Поворачиваем сцену на 30*SyncTime градусов вокруг вектора (0;1;0) */
  
glRotated(30*SyncTime010);

  
/* Рисуем тор. Параметры: размер внутреннего кольца, размер внешнего кольца и 2 параметра полигонизации, т.е. качества отрисовки */
  
glutWireTorus(255050);
  
  
/* Восстанавливаем сохраненную матрицу из стека */
  
glPopMatrix();

На этом, думаю, моя первая статья из цикла OpenGL будет завершена. Надеюсь, вам она покажется интересной, а меня за нее сильно не будут пинать. Ждите новых статей из цикла OpenGL и других тем CG. Творите! Удачи!
 
Ответить с цитированием
 





Здесь присутствуют: 1 (пользователей: 0 , гостей: 1)
 


Быстрый переход




ANTICHAT.XYZ