ПЕРЕЛІК ДИСЦИПЛІН:
  • Адміністративне право
  • Арбітражний процес
  • Архітектура
  • Астрологія
  • Астрономія
  • Банківська справа
  • Безпека життєдіяльності
  • Біографії
  • Біологія
  • Біологія і хімія
  • Ботаніка та сільське гос-во
  • Бухгалтерський облік і аудит
  • Валютні відносини
  • Ветеринарія
  • Військова кафедра
  • Географія
  • Геодезія
  • Геологія
  • Етика
  • Держава і право
  • Цивільне право і процес
  • Діловодство
  • Гроші та кредит
  • Природничі науки
  • Журналістика
  • Екологія
  • Видавнича справа та поліграфія
  • Інвестиції
  • Іноземна мова
  • Інформатика
  • Інформатика, програмування
  • Юрист по наследству
  • Історичні особистості
  • Історія
  • Історія техніки
  • Кибернетика
  • Комунікації і зв'язок
  • Комп'ютерні науки
  • Косметологія
  • Короткий зміст творів
  • Криміналістика
  • Кримінологія
  • Криптология
  • Кулінарія
  • Культура і мистецтво
  • Культурологія
  • Російська література
  • Література і російська мова
  • Логіка
  • Логістика
  • Маркетинг
  • Математика
  • Медицина, здоров'я
  • Медичні науки
  • Міжнародне публічне право
  • Міжнародне приватне право
  • Міжнародні відносини
  • Менеджмент
  • Металургія
  • Москвоведение
  • Мовознавство
  • Музика
  • Муніципальне право
  • Податки, оподаткування
  •  
    Бесплатные рефераты
     

     

     

     

     

     

         
     
    Основи програмування OpenGL в Borland С + + Builder і Delphi. Найпростіші об'єкти
         

     

    Інформатика, програмування

    Основи програмування OpenGL в Borland С + + Builder і Delphi. Найпростіші об'єкти

    Луковкін Сергій

    Розглядаючи будь-який тривимірний об'єкт, ми завжди визначаємо його розташування і розміри щодо деякої звичної, і зручною зараз системи координат, пов'язаної з реальним світом. Така вихідна система координат в комп'ютерній графіці є правобічної і називається світовою системою координат ....

    Для того, щоб можна було зобразити об'єкт на екрані, його необхідно попередньо перевести (або перетворити) в іншу систему координат, яка пов'язана з точкою спостереження і носить назву видовий системи координат. Ця система координат є лівосторонньої. І, нарешті, будь-яке тривимірне зображення ми завжди малюємо на двовимірному екрані, який має свою екранну систему координат. (Цей абзац я списав у Ю. Тихомирова).        

    правостороння   система координат (світова)         

    лівостороння   система координат (видова)             

            

        

    За замовчуванням, площину xOy паралельна екрану, а вісь Z спрямована у світових координатах до нас, у видових - від нас.

    Перехід до нових координатах

    У OpenGL всі об'єкти малюються на початку координат, тобто в точці (0,0,0). Для того, щоб зобразити об'єкт в точці (x1, y1, z1), треба перемістити початок координат в цю точку, тобто перейти до нових координатах. Для цього в OpenGL визначені дві процедури:

    glTranslate [fd] (Dx, Dy, Dz) - зрушує початок координат на (Dx, Dy, Dz)

    glRotate [fd] (j, x, y, z) - повертає систему координат на кут j (в градусах) проти годинникової стрілки навколо вектора (x, y, z)

    ПРИМІТКА: [fd] - означає, що в кінці може бути або буква "f", або "d".

    Тепер варто сказати ще про дві процедури:

    glPushMatrix

    glPopMatrix

    Перша призначена, для збереження, а другий - для відновлення поточних координат. Дуже зручно за допомогою glPushMatrix зберегти поточні координати, потім зрушуватися і звертатися як завгодно, а після, викликом glPopMatrix, повернутися до вихідних координатах. Параметрів у цих процедур немає.

    Частина 2. Найпростіші фігури

    Найпростіші об'ємні фігури

    У прикладі з минулої статті ми створили сферу. Для цього ми використовували механізм з glu32.dll. Алгоритм був такий:

    1. Створюємо об'єкт типу GLUquadricObj

    2. Ініціалізіруем його функцією gluNewQuadric

    3. Встановлюємо стиль фігури функцією gluQuadricDrawStyle (quadObj, GLU_FILL). Стиль може бути GLU_FILL, GLU_LINE, GLU_SILHOUETTE або GLU_POINT. Що кожен з них означає, перевірте самі.

    4. Робимо з quadObj (об'єкта типу GLUquadricObj) сферу, циліндр, конус, диск або частину диска. Для цього визначені такі функції:

    · gluSphere (quadObj, radius, slices, loops). Три останніх параметри - це радіус і кількість розбиття впоперек і вздовж осі Z відповідно.

    · gluCylinder (quadObj, baseRadius, topRadius, height, slices, loops). Після quadObj йдуть наступні параметри: радіус нижньої основи, радіус верхнього підстави, висота і кількість розбиття впоперек і вздовж осі Z відповідно. Очевидно, що ця функція задає як циліндр, так і конус.

    · gluDisk (quadObj, innerRadius, outerRadius, slices, loops). Тут після quadObj вказуються внутрішній і зовнішній радіуси диска.

    · gluPartialDisk (quadObj, innerRadius, outerRadius, slices, loops, startAngle, sweepAngle). Тут додаються два параметри: кут (в градусах), з якого почнеться малювання диска, і кут, яким малювання закінчиться.

    5. Звільняємо пам'ять, зайняту під quadObj функцією gluDeleteQuadric (quadObj).

    Тепер ви можете малювати прості тривимірні фігури!

    Примітиви

    Будь-яку тривимірну фігуру, яка б складна вона не була, можна розбити на двомірні (плоскі) складові. Ці складові я і буду називати примітивами, хоча деякі автори вважають, що примітивами слід обізвати вищеперелічені тривимірні фігури.

    Примітиви визначаються однією або декількома точками, які в OpenGL задаються всередині командних дужок glBegin/glEnd:        

    С + +             

    void glBegin (mode);   

    void glEnd ();             

    Delphi             

    procedure glBegin (mode);   

    procedure glEnd;     

    Параметр mode показує, які примітиви будуть малюватися. Доступні наступні значення:        

    GL_POINTS         

    Кожна вершина - окрема точка             

    GL_LINES         

    Кожна пара вершин - окрема лінія. Якщо   число вершин непарній, то остання ігнорується             

    GL_LINE_STRIP         

    Послідовність пов'язаних відрізків.   Перші дві вершини - перший відрізок. Третя вершина визначає другий відрізок   з початком в кінці першого і кінцем в цій вершині і т.д             

    GL_LINE_LOOP         

    Аналогічний GL_LINE_STRIP, тільки остання   вершина з'єднується відрізком з перших.             

    GL_TRIANGLES         

    Кожна трійка вершин - окремий трикутник             

    GL_TRIANGLE_STRIP         

    Група пов'язаних трикутників. Перші три   вершини - перший трикутник. Друга, третя і четверта вершини - другий   трикутник і т.д.             

    GL_TRIANGLE_FAN         

    Також група пов'язаних трикутників. Перші   три вершини - перший трикутник. Перша, друга і четверта вершини - другий   трикутник і т.д.             

    GL_QUADS         

    Кожні чотири вершини - окремий   чотирикутник.             

    GL_QUAD_STRIP         

    Група пов'язаних чотирикутників. Перші   чотири вершини - першого чотирикутник. Третя, четверта, п'ята і шоста   вершини - другий чотирикутник і т.д.             

    GL_POLYGON         

    Малює окремий опуклий багатокутник   (один).     

    Особливу увагу потрібно приділити GL_QUAD_STRIP. Тут не зовсім зрозумілий, але дуже зручний порядок вказівки вершин:

    У кожного примітиву є мінімальне число вершин. Якщо вказане число вершин менше мінімального для даного примітиву, то примітив не малюється.

    Залишилося тільки сказати, як задати вершину. Для цього визначена наступна процедура:

    glVertex [2 3 4] [s i f d] [v] (coord)

    Вершина визначається чотирма параметрами: координати x, y, z і параметр w - коефіцієнт, на який ділиться кожна з координат, тобто w визначає масштаб. За замовчуванням z = 0, w = 1, тобто коли ви викликаєте, наприклад, glVertex2f (1,1) насправді викликається glVertex4f (1,1,0,1).

    З кожною вершиною пов'язані деякі дані:

    · Поточний колір - колір вершини (остаточний колір вираховується з урахуванням світла). Колір задається процедурою glColor *

    · Поточні координати текстури - координати текстури, відповідні цієї вершини. Задаються процедурою glTexCoord *

    · Поточна нормаль - вектор нормалі, що відповідає даній вершині. Здається процедурою glNormal *

    · Поточна позиція растру - використовується для визначення положення растра при роботі з пікселями і бітовими масивами. задається процедурою glRasterPos *

    ПРИМІТКА: замість зірочки '*' ставляться відповідні суфікси; таке скорочення прийнято в багатьох документація з OpenGL.

    Точки

    Намалювати точку дуже просто. Наступний код зображує 10 точок різного розміру.        

    С + +             

    void TForm1:: Draw ()   

    (   

    glClear (GL_DEPTH_BUFFER_BIT   or GL_COLOR_BUFFER_BIT);   

    glColor3f (1,1,1);      

    Byte i;   

    for (i = 0; i <10; i + +)      

    (   

    glPointSize ((i +1) * 4);      

    glBegin (GL_POINTS);      

    glVertex2f (i, i);      

    glEnd ();   

    )   

    SwapBuffers (ghDC);      

    )             

    Delphi             

    procedure TForm1.Draw;   

    var   

    i: byte;   

    begin   

    glClear (GL_DEPTH_BUFFER_BIT   or GL_COLOR_BUFFER_BIT);   

    glColor3f (1,1,1);      

    for i: = 0   to 9 do   

    begin   

    glPointSize ((i +1) * 4);      

    glBegin (GL_POINTS);      

    glVertex2f (i, i);      

    glEnd;   

    end;   

    SwapBuffers (ghDC);   

    end;     

    ПРИМІТКА: в FormResize я викликав glOrtho наступним чином - GlOrtho (-1,12, -1,12, 2,12). Це - для того, щоб всі крапки помістилися в вікні.

    Для зміни розміру точки використовується процедура glPointSize (size). Параметр size задає діаметр точки.

    У цьому прикладі всі крапки квадратні. У OpenGL дозволено згладжування (smoothening) як точок, так і більш складних об'єктів. Як і все в OpenGL, цей режим вмикається і вимикається процедурами glEnable/glDisable. Для точок це робиться так:

    glEnable (GL_POINT_SMOOTH);

    Вставивши цей рядок де-небудь перед малюванням точок, отримаємо:

    Відверто кажучи, у мене OpenGL робить це досить плохоL, можливо ваша реалізація справляється з цим краще.

    Лінії

    З лініями - не на багато складніше. Замість розміру у лінії вказується ширина:

    glLineWidth (width)

    згладжування дозволяється наступним чином:

    glEnable (GL_LINE_SMOOTH)

    Але на цьому можливості ліній не закінчуються. Я вже розповів, як можна намалювати два або навіть три лінії, вказавши лише три вершини (викликаємо glBegin з параметром GL_LINE_STRIP або GL_LINE_LOOP), а й це ще не все! У OpenGL можна вказати штрихування лінії! Робиться це процедурою glLineStipple (factor, pattern). Тут pattern - 16-розрядна бітова маска. Наприклад, щоб намалювати пунктирну лінію, маску треба задати рівний 255, що в шістнадцятковій системі числення відповідає 00FF, а в двійковій -- 0000000011111111. А ціле factor показує, скільки разів буде повторюватися кожний біт маски.

    Залишилося тільки вирішити Штрихована лінії: glEnable (GL_LINE_STIPPLE).

    Приклад.        

    С + +, Delphi             

    glEnable (GL_LINE_SMOOTH);   

    glLineStipple (1,255);      

    glEnable (GL_LINE_STIPPLE);      

    glBegin (GL_LINES);      

    glVertex2f (0,2);   

    glVertex2f (10,6);   

    glEnd;     

    Ось, що вийде:

    Полігони

    Тепер перейдемо до плоских фігур: трикутника, чотирикутника і довільним опуклим багатокутника. З ними можна робити все те ж, що і з лініями (тільки згладжування вмикається і вимикається процедурами glEnable/glDisable з параметром GL_POLYGON_SMOOTH), плюс ще одна процедура: glPolygonMode (face, mode). Другий параметр - mode - вказує, як буде малюватися полінгон (по русски - багатокутник). Він може приймати значення GL_POINT (малюються тільки точки), GL_LINE (тільки лінії) або GL_FILL (заповнений полігон). А перший параметр - face - показує, який стороні полігону застосовується режим mode: GL_FRONT (до лицьової), GL_BACK (до тильної) або GL_FRONT_AND_BACK (до обох).

    Давайте намалюємо трикутник. Ось як буде виглядати функція Draw:        

    С + +             

    void TForm1:: Draw ()   

    (   

    glClear (GL_DEPTH_BUFFER_BIT   or GL_COLOR_BUFFER_BIT);   

    glPolygonMode (GL_FRONT_AND_BACK, GL_FILL);      

    glBegin (GL_TRIANGLES);      

    glColor3f (1,0,0);      

    glVertex2f (0,2);      

    glColor3f (0,1,0);      

    glVertex2f (8,9);      

    glColor3f (0,0,1);      

    glVertex2f (10,4);      

    glEnd ();   

    SwapBuffers (ghDC);   

    )             

    Delphi             

    procedure TForm1.Draw;   

    begin   

    glClear (GL_DEPTH_BUFFER_BIT   or GL_COLOR_BUFFER_BIT);   

    glPolygonMode (GL_FRONT_AND_BACK, GL_FILL);      

    glBegin (GL_TRIANGLES);      

    glColor3f (1,0,0);      

    glVertex2f (0,2);      

    glColor3f (0,1,0);      

    glVertex2f (8,9);      

    glColor3f (0,0,1);      

    glVertex2f (10,4);      

    glEnd;   

    SwapBuffers (ghDC);   

    end;     

    Я вже говорив, що кожна вершина може мати свій колір, цим я тут і скористався. І ось що вийшло:

    Кожній вершині вказувати колір зовсім не обов'язково. Якщо ви хочете намалювати трикутник одного кольору, то цей колір вказується один раз - перед малюванням самого примітиву.

    Забігаючи наперед, скажу, що плавного перетікання кольорів як на малюнку може і не бути, якщо перед малюванням викликати процедуру glShadeModel (GL_FLAT), за замовчуванням її параметр - GL_SMOOTH. Ця процедура вказує, згладжувати чи ні кути між суміжними полігонами. Ось картинки для ілюстрації її дії:

    Раз вже я сказав про штрихування ліній, то потрібно сказати і про трафареті - штрихування для полігонів. Він включається командою glEnable (GL_POLYGON_STIPPLE). Також як і з лініями, трафарет задається масивом, який визначає бітову маску. Розмір трафарету - 32x32 біта, тобто розмір масиву буде 128 байт.

    Мені було ліньки прописувати кожен з 128 байт маски по окремо, і я сформував її в циклі, і ось результат:        

    С + +             

    void TForm1:: Draw ()   

    (   

    glClear (GL_DEPTH_BUFFER_BIT or   GL_COLOR_BUFFER_BIT);   

    //   формуємо маску   

    for (int   k = 0; k <16; k + +)   

    for (int i = 0; i <8; i + +)   

    stip [k] [i]: = k-i;   

    glEnable (GL_POLYGON_STIPPLE);   

    glPolygonStipple (@ stip);   

    glPolygonMode (GL_FRONT_AND_BACK, GL_FILL);      

    glColor3f (1,0,0);   

    glBegin (GL_TRIANGLES);   

    glVertex2f (0,2);   

    glVertex2f (8,9);   

    glVertex2f (10,4);   

    glEnd ();   

    SwapBuffers (ghDC);   

    )             

    Delphi             

    procedure TForm1.Draw;   

    var   

    stip: array [1 .. 16,1 .. 8] of   GLubyte;   

    i, k: byte;   

    begin   

    glClear (GL_DEPTH_BUFFER_BIT or   GL_COLOR_BUFFER_BIT);   

    // формуємо маску   

    for k: = 1 to 16 do   

    for i: = 1 to 8 do   

    stip [k] [i]: = k-i;   

    glEnable (GL_POLYGON_STIPPLE);   

    glPolygonStipple (@ stip);   

    glPolygonMode (GL_FRONT_AND_BACK, GL_FILL);      

    glColor3f (1,0,0);   

    glBegin (GL_TRIANGLES);   

    glVertex2f (0,2);   

    glVertex2f (8,9);   

    glVertex2f (10,4);   

    glEnd;   

    SwapBuffers (ghDC);   

    end;     

    Ось результат:

    Взагалі маска формується один раз, тому, якщо ви перенесете код її формування в інше місце (наприклад в FormCreate), то програма буде працювати швидше.

    Ще хотілося б сказати про масивах OpenGL. Цей метод дозволяє зберігати всі вершини об'єкта в масиві, причому в цьому масиві можна зберігати не тільки координати вершин, але і їх атрибути (іноді це буває корисно). Але з Borland'а товариші вирішили, що нам це не потрібно і не оголосили відповідні процедури і константи. Без цього легко можна обійтися, але все-таки обідноL.

    Паралелепіпед

    Не знаю, чи помітили ви чи ні, але GLU не дозволяє створювати паралелепіпеди. Давайте це виправимо: напишемо процедуру, рісующую паралелепіпед.        

    С + +             

    void piped (GLfloat a,   GLfloat b, GLfloat c)   

    (   

    glShadeModel (GL_FLAT);      

    glPolygonMode (GL_FRONT_AND_BACK, GL_FILL);      

    glBegin (GL_QUAD_STRIP);      

    glVertex3f (-a/2,-b/2,-c/2);      

    glVertex3f (-a/2,-b/2,   c/2);   

    glVertex3f (-a/2,   b/2,-c/2);   

    glVertex3f (-a/2,   b/2, c/2);   

    glVertex3f (   a/2, b/2,-c/2);   

    glVertex3f (   a/2, b/2, c/2);   

    glVertex3f (   a/2,-b/2,-c/2);   

    glVertex3f (   a/2,-b/2, c/2);   

    glVertex3f (-a/2,-b/2,-c/2);      

    glVertex3f (-a/2,-b/2,   c/2);   

    glEnd ();   

    glBegin (GL_QUADS);      

    glVertex3f (-a/2,-b/2,   c/2);   

    glVertex3f (-a/2,   b/2, c/2);   

    glVertex3f (   a/2, b/2, c/2);   

    glVertex3f (   a/2,-b/2, c/2);   

    glVertex3f (-a/2,-b/2,-c/2);      

    glVertex3f (-a/2,   b/2,-c/2);   

    glVertex3f (   a/2, b/2,-c/2);   

    glVertex3f (   a/2,-b/2,-c/2);   

    glEnd ();   

    )             

    Delphi             

    procedure   piped (a, b, c: GLfloat);   

    begin   

    glShadeModel (GL_FLAT);      

    glPolygonMode (GL_FRONT_AND_BACK, GL_FILL);      

    glBegin (GL_QUAD_STRIP);      

    glVertex3f (-a/2,-b/2,-c/2);      

    glVertex3f (-a/2,-b/2,   c/2);   

    glVertex3f (-a/2,   b/2,-c/2);   

    glVertex3f (-a/2,   b/2, c/2);   

    glVertex3f (   a/2, b/2,-c/2);   

    glVertex3f (   a/2, b/2, c/2);   

    glVertex3f (   a/2,-b/2,-c/2);   

    glVertex3f (   a/2,-b/2, c/2);   

    glVertex3f (-a/2,-b/2,-c/2);      

    glVertex3f (-a/2,-b/2,   c/2);   

    glEnd;   

    glBegin (GL_QUADS);      

    glVertex3f (-a/2,-b/2,   c/2);   

    glVertex3f (-a/2,   b/2, c/2);   

    glVertex3f (   a/2, b/2, c/2);   

    glVertex3f (   a/2,-b/2, c/2);   

    glVertex3f (-a/2,-b/2,-c/2);      

    glVertex3f (-a/2,   b/2,-c/2);   

    glVertex3f (   a/2, b/2,-c/2);   

    glVertex3f (   a/2,-b/2,-c/2);   

    glEnd;   

    end;     

    Можна перевіряти!

    glOrtho викличемо також, як і у прикладі зі сферою: glOrtho (-5,5, -5,5, 1,12).

    А в Draw напишемо наступне:        

    С + +, Delphi             

    glColor3f (0.6,0.7,0.9);   

    glPushMatrix;      

    glRotatef (10,   0,0,1);   

    glRotatef (25,   0,1,0);   

    glRotatef (20,   1,0,0);   

    piped (5,1.2,3.5);   

    glPopMatrix;     

    І отримаємо картинку:

    Список літератури

    Для підготовки даної роботи були використані матеріали з сайту http://bestcode.org/

         
     
         
    Реферат Банк
     
    Рефераты
     
    Бесплатные рефераты
     

     

     

     

     

     

     

     
     
     
      Все права защищены. Reff.net.ua - українські реферати ! DMCA.com Protection Status