OpenGL для начинающих
OpenGL для начинающих Решив разобраться с OpenGL и просмотрев DRBK, я увидел печальную картину - то что там есть никак не дает пинка в нужном направлении для написания программ,использующих OpenGL. Ниже я постарался собрать в пучок результаты моих исследований и получил этот текст и MyOpenGL.pas. Я совсем не претендую на правильность терминов в описании и на то, как надо писать OpenGL-программы. Но простую OpenGL-программу вы точно сможете написать, использовав MyOpenGL.pas, после прочтения нижеследующего, как на VCL, так и на чистом WinAPI.Может кому пригодится для начала - написанное достаточно просто >:-)Были использованы следующие источники* Исходники Jan Horn (http://www.sulaco.co.za, http://home.global.co.za/~jhorn)В частности Skyboxes и Гаусово размытие. Второе уже есть в DRKB без имени автораРабота с графикой и мультимедиа > DerectX, OpenGL > OpenGL - радиальное размытие (названия функций, основа программы и много другое взяты оттуда).* Учебник по OpenGL (главы 1.3, 1.5) с www.ru-coding.com.* MS SDK > OpenGL Programmer's Reference, поставляемый вместе с Delphi (общая справка)* модуль EasyGL.pas Данилова Андрея (http://dasoft.land.ru)(своровал пару идей по оформлению VCL).* Статья по рисованию вращающего сердечка на OpenGL (не помню где брал).* Перевод Народного учебника по OpenGL от NeHe (http://nehe.gamedev.net). Брать тут - http://pmg.org.ru/nehe/nehehtml.zip(ну очень хороший учебник, хоть и на C; must see).01 Контексты устройства и воспроизведения========================================="DC (Device Context - контекст устройства). Это то, на чём мы рисуем, и в Delphi контекст устройства представлен как TCanvas" (см. 1)Получить его можно следующим образом
DC: hDC;
...
DC := GetDC(Form1.Hanle);
или
DC := Form1.Canvas.Handle;
...
var
DC: hDC;
RC: hGLRC;
...
DC := GetDC(Form1.Handle); // получаем контекст устройства
SetDCPixelFormat(DC); // устанавливаем формат точки (см. 2)
RC := wglCreateContext(DC); // создать новый контекст воспроизведения
wglMakeCurrent(DC, RC); // устанавливаем его текущим
{ Инициализация OpenGL }
{------------------------------------------------------------------}
procedure glInit(Wnd: hWND);
const
// Константы, задающие свойства материала фигур
mat1_amb : array [0..2] of Single = (0.2, 0.2, 0.2);
mat1_dif : array [0..2] of Single = (0.8, 0.8, 0.0);
mat1_spec: array [0..2] of Single = (0.6, 0.6, 0.6);
mat1_shininess = 10;
// Константы для источника света
light_pos : array [0..3] of glFloat=(100.0, 100.0, 0.0, 1.0);
light_amb : array [0..3] of glFloat=(0.6, 0.6, 0.6, 1.0);
light_dif : array [0..3] of glFloat=(1.0, 1.0, 1.0, 1.0);
light_spec : array [0..3] of glFloat=(1.0, 1.0, 1.0, 1.0);
light_spot_direction : array [0..3] of glFloat=(1.0, 1.0, 1.0, 1.0);
// Цвет тумана
fogColor: array [0..3] of GLfloat = (0, 1.0, 0, 1.0);
var
fogMode: GLint;
begin
// Инициализация контекста воспроизведения OpenGL
DC := GetDC(Wnd); // Получить контекст устройства для окна
SetDCPixelFormat(DC); // Установить формата пикселов
RC := wglCreateContext(DC); // создать новый контекст воспроизведения
wglMakeCurrent(DC, RC); // Установить его текущим
// Свойства материала для режима glEnable(GL_COLOR_MATERIAL)
glMaterialfv(GL_FRONT, GL_AMBIENT, @mat1_amb);
glMaterialfv(GL_FRONT, GL_DIFFUSE, @mat1_dif);
glMaterialfv(GL_FRONT, GL_SPECULAR, @mat1_spec);
glMaterialf (GL_FRONT, GL_SHININESS,mat1_shininess);
// Свойства источника света GL_LIGHT1 для режима glEnable(GL_LIGHTING)
// Стандартный источник одна команда: glEnable(GL_LIGHT0);
glLightfv(GL_LIGHT1, GL_POSITION,@light_pos);
glLightfv(GL_LIGHT1, GL_AMBIENT, @light_amb); // направленность
glLightfv(GL_LIGHT1, GL_DIFFUSE, @light_dif); // рассеивание
glLightfv(GL_LIGHT1, GL_SPECULAR, @light_spec);
glLightfv(GL_LIGHT1, GL_SPOT_DIRECTION, @light_spot_direction);
// разрешить источник света GL_LIGHT1
glEnable(GL_LIGHT1);
// Свойства тумана для режима glEnable(GL_FOG)
fogMode := GL_EXP; // GL_EXP2, GL_LINEAR
glFogi(GL_FOG_MODE, fogMode); // установить режим
glFogfv(GL_FOG_COLOR, @fogColor); // цвет тумана
glFogf(GL_FOG_DENSITY, 0.002); // плотность - 0.2%
glHint(GL_FOG_HINT, GL_DONT_CARE); // GL_NICEST, GL_FASTEST.
glClearColor(0.0, 0.0, 0.2, 1.0); // Установить цвет фона - синий
glClearDepth(1.0); // Очистить буфер глубины
glDepthFunc(GL_LESS); // Тип теста глубины
glShadeModel(GL_SMOOTH); // плавное цветовое сглаживание
// glEnable(..) - включить режим, glDisable(..) - отключить
glEnable(GL_LIGHTING); // разрешить осещенность
//glEnable(GL_FOG); // разрешить тумана
glEnable(GL_DEPTH_TEST); // разрешить тест глубины, с использованием
// функции определенной в glDepthFunc
glEnable(GL_NORMALIZE); // разрешить нормали (различение передней
// и задней сторон плоских объектов)
glEnable(GL_COLOR_MATERIAL); // разрешить использование материалов на объектах
glEnable(GL_TEXTURE_2D); // разрешить наложение текстур
//glEnable(GL_BLEND); // разрешить смешивание (напр. прозрачность)
// не совместимо с glEnable(GL_DEPTH_TEST)
glLoadTexture('1.bmp', Texture); // загружаем текстуру
end;
{------------------------------------------------------------------}
{ Обработчик на изменение размеров окна }
{------------------------------------------------------------------}
procedure glOnResize(Width, Height: Integer);
begin
if (Height = 0) then Height := 1; // Предупреждаем деление на 0
glViewport(0, 0, Width, Height); // Устанавливаем область отображения
// на все окно
// Настройка матрицы проекции
glMatrixMode(GL_PROJECTION); // Выбираем матрицу проекции
glLoadIdentity(); // Устанавливаем ее единичной
// Устанавливаем тип проеции - Ортогональный
glOrtho(-Width div 2, Width div 2, -Height div 2, Height div 2, -800, 800);
// Настройка видовой матрицы
glMatrixMode(GL_MODELVIEW); // Выбираем матрицу проекции
glLoadIdentity(); // Устанавливаем ее единичной
end;
{ Завершение работы с OpenGL }
{------------------------------------------------------------------}
procedure glKill(Wnd: hWND);
begin
wglMakeCurrent(DC, 0);
wglDeleteContext(RC);
ReleaseDC(Wnd, DC);
end;
{ Создание объектов под отрисовку }
{------------------------------------------------------------------}
procedure glDraw();
var
Obj: GLUquadricObj;
begin
// очистка Экрана и буфера глубины
glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);
...
// Пример рисования разноцветного треугольника
glBegin(GL_POLYGON);
glColor(0.0, 0.5, 0.0, 0.0);
glVertex3F(-50, -sqrt(3)*50, 0); // 1-я вершина
glColor(0.5, 0.0, 0.0, 0.0);
glVertex3F(-100, -sqrt(3)*100, 0); // 2-я вершина
glColor(0.0, 0.0, 0.5, 0.0);
glVertex3F(-125, -sqrt(3)*100, 0); // 3-я вершина
glEnd;
...
// Пример рисования сферы
glColor(1.0, 1.0, 1.0, 0.5); // установить цвет объекта
Obj := gluNewQuadric;
gluSphere(Obj, 100, 25, 25); // создать сферу R = 100, детализация - 25х25
...
// Выводим на экран подготовленную сцену
SwapBuffers(DC);
end;
Obj : GLUquadricObj;
...
Obj := gluNewQuadric;
// Режимы отображения фигуры
gluQuadricDrawStyle(Obj, GLU_FILL); // GLU_POINT, GLU_LINE, GLU_SILHOUETTE
gluQuadricOrientation (Obj, GLU_INSIDE); // GLU_OUTSIDE
gluQuadricNormals (Obj, GLU_SMOOTH); // - нормаль для каждой точки
// GLU_FLAT - для сегмента
// GLU_NONE - не строить нормалей
gluQuadricTexture(Obj, GL_TRUE); // - разрешить наложение текущей текстуры
// Создание фигуры
gluSphere(Obj, 100, 25, 25); // сфера R = 100, детализация - 25х25
или
gluCylinder(Obj, 10, 100, 150, 30, 1); // цилиндр - R0 = 10, R1 = 100, H = 150, детализация - 30 плоскостей
или
gluDisk(Obj, 10, 100, 30, 1); // Диск - R0 = 10, R1 = 100, детализация - 100
или
gluPartialDisk(Obj, 10, 100, 30, 100, 0, 120); // треть диска с параметрами как у верхнего
...
//Освобождаем память
gluDeleteQuadric(Obj);
Очень сильно помогло для вывода текста. Спасибо.
Отправить комментарий