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

     

     

     

     

     

         
     
    OpenGL і Delphi на практиці
         

     

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

    OpenGL і Delphi на практиці

    Видавничий Дім "Комиздат"

    Будь-яка теорія гарна, якщо вона може бути реалізована на Delphi :-). Тому пропоную не відкладаючи в довгий ящик написати першу програму на OpenGL - а потім, окрилити успіхом, повернутися до теорії і як слід простудіювати всі книги і сайти з сабжу, щоб вже стати справжніми монстрами тривимірного моделювання.

    Для початку доведеться виконати підготовчу роботу:

    налаштувати формат пікселів з урахуванням інформації, що відображається;

    створити контекст OpenGL і підготувати сам движок OpenGL до роботи.

    Формат пікселів зручно винести в окрему процедуру, яку ми оформимо наступним так:

    procedure SetDCPixelFormat (dc: HDC);

    var pfd: TPixelFormatDescriptor;

    nPixelFormat: Integer;

    begin

    FillChar (pfd, SizeOf (pfd), 0);

    with pfd do

    begin

    nSize: = sizeof (pfd);

    nVersion: = 1;

    dwFlags: = PFD_DRAW_TO_WINDOW or

    PFD_SUPPORT_OPENGL or

    PFD_DOUBLEBUFFER;

    iPixelType: = PFD_TYPE_RGBA;

    cColorBits: = 16;

    cDepthBits: = 64;

    iLayerType: = PFD_MAIN_PLANE;

    end;

    nPixelFormat: = ChoosePixelFormat (DC, @ pfd);

    SetPixelFormat (DC, nPixelFormat, @ pfd);

    end;

    Тут при заповненні структури TPixelFormatDescriptor ми задаємо параметри майбутнього графічного відображення, в тому числі кількість колірних біт, а також тип пікселів (iPixelType). Ми також ставимо прапори, які, як видно з назви, вказують, що наша програма буде підтримувати OpenGL, а також що ми будемо малювати у вікні і використовувати подвійну буферизацію (параметр, необхідний для відтворення рухомих об'єктів).

    Далі за допомогою виклику ChoosePixelFormat система вибирає підходящий формат пікселя - І ми присвоюємо його (через SetPixelFormat) нашому вікна.

    Тепер потрібно ініціалізувати контекст самого OpenGL за допомогою функцій, що містяться в модулі Windows, і провести додаткову настройку движка:

    procedure TForm1.FormCreate (Sender: TObject);

    begin

    H: = Handle;

    DC: = GetDC (H);

    SetDCPixelFormat (DC);

    RC: = wglCreateContext (DC);

    wglMakeCurrent (DC, RC);

    glClearColor (0.6,0.6,0.6,1.0);

    glMatrixMode (GL_PROJECTION);

    glLoadIdentity;

    glFrustum (-1,1, -1,1,2,20);

    glMatrixMode (GL_MODELVIEW);

    glLoadIdentity;

    glTranslatef (0.0, -1.0, -6.0);

    BeginPaint;

    end;

    Як бачимо, спочатку ми поставили для нашої графіки необхідний формат пікселів. Тепер за допомогою функції wglCreateContext створюємо OpenGL-контекст, а згодом робимо його поточним контекстом. Далі, використовуючи вже універсальні функції **, зробимо налаштування "світу", який будемо створювати. Для цього через glClearColor очистимо контекст і заповнимо її 60-відсотковим чорним кольором. Далі виберемо матрицю проекцій, яка визначає, як будуть проектуватися тривимірні об'єкти на площину екрану (у віконні координати) і через glLoadIdentity встановимо одиничну матрицю і задамо кордону плану в "світових координатах" за допомогою виклику glFrustum. Після чого завантажимо модельно видову матрицю і проведемо її зсув (glTranslatef).

    Що будемо малювати

    Звичайно, можна було намалювати просту піраміду або ж куб. Але ми зробимо більше - намалюємо "освідчення в коханні" ** (рис. 1). Спеціально для цього методом "наукового перебору" була розроблена модель, що описує відповідну криву:

    Залишається тільки перевести її з мови математики на нормальний людський.

    Промальовування сцени

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

    Далі в FormPaint використовуємо підготовлені заздалегідь методи DrawFace і DrawElement (див. лістинг нижче) для відтворення згаданого об'єкта. А для надання йому ще більшої "спеки" використовуємо можливості OpenGL з висвітлення сцени.

    Підсумок

    З точки зору складності освоєння OpenGL можна порівняти з іншими подібними бібліотеками. Так що з одного боку немає різниці, в чому розбиратися і що вивчати. Але з точки зору розумного підходу будь-який проект тривимірної графіки повинен як мінімум підтримувати OpenGL в якості однієї з опцій. Адже серйозні речі вважаються і візуалізуються, як правило, під Unix/IRIX/Linux/FreeBSD, і в той же час було б неправильно ігнорувати користувачів Windows. Так що OpenGL як раз і є тим універсальним мовою і спільним знаменником, що дозволяє вашим додаткам вільно мігрувати з однієї платформи на іншу.

    Лістинг програми

    Лістинг

    ========

    unit MainForm;

    interface

    uses

    Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,

    Dialogs, OpenGL, StdCtrls, ExtCtrls;

    type

    TForm1 = class (TForm)

    Timer1: TTimer;

    Label1: TLabel;

    Label2: TLabel;

    Label3: TLabel;

    Label4: TLabel;

    procedure FormCreate (Sender: TObject);

    procedure FormDestroy (Sender: TObject);

    procedure Timer1Timer (Sender: TObject);

    procedure FormPaint (Sender: TObject);

    procedure FormResize (Sender: TObject);

    private

    RC: HGLRC;

    DC: HDC;

    H: THandle;

    procedure BeginPaint;

    (Private declarations)

    public

    (Public declarations)

    end;

    var

    Form1: TForm1;

    const mat1_dif: Array [0 .. 2] of Single = (0.8,0.8,0.0);

    const mat1_amb: Array [0 .. 2] of Single = (0.2,0.2,0.2);

    const mat1_spec: Array [0 .. 2] of Single = (0.6,0.6,0.6);

    const mat1_shininess = 0.5 * 128;

    procedure DrawElement (A, b, R0, r1: Single);

    procedure DrawFace (A, R: Single; Normal: Boolean);

    implementation

    procedure SetDCPixelFormat (dc: HDC);

    var pfd: TPixelFormatDescriptor;

    nPixelFormat: Integer;

    begin

    FillChar (pfd, SizeOf (pfd), 0);

    with pfd do

    begin

    nSize: = sizeof (pfd);

    nVersion: = 1;

    dwFlags: = PFD_DRAW_TO_WINDOW or

    PFD_SUPPORT_OPENGL or

    PFD_DOUBLEBUFFER;

    iPixelType: = PFD_TYPE_RGBA;

    cColorBits: = 16;

    cDepthBits: = 64;

    iLayerType: = PFD_MAIN_PLANE;

    end;

    nPixelFormat: = ChoosePixelFormat (DC, @ pfd);

    SetPixelFormat (DC, nPixelFormat, @ pfd);

    end;

    procedure TForm1.BeginPaint;

    begin

    glEnable (GL_LIGHTING);

    glEnable (GL_LIGHT0);

    glEnable (GL_DEPTH_TEST);

    glEnable (GL_NORMALIZE);

    glEnable (GL_COLOR_MATERIAL);

    timer1.enabled: = true;

    end;

    ($ R *. dfm)

    procedure TForm1.FormCreate (Sender: TObject);

    begin

    H: = Handle;

    DC: = GetDC (H);

    SetDCPixelFormat (DC);

    RC: = wglCreateContext (DC);

    wglMakeCurrent (DC, RC);

    glClearColor (0.6,0.6,0.6,1.0);

    glMatrixMode (GL_PROJECTION);

    glLoadIdentity;

    glFrustum (-1,1, -1,1,2,20);

    glMatrixMode (GL_MODELVIEW);

    glLoadIdentity;

    glTranslatef (0.0, -1.0, -6.0);

    BeginPaint;

    end;

    procedure TForm1.FormDestroy (Sender: TObject);

    begin

    wglMakeCurrent (0,0);

    wglDeleteContext (RC);

    ReleaseDC (H, DC);

    DeleteDC (DC);

    end;

    procedure TForm1.Timer1Timer (Sender: TObject);

    begin

    glRotatef (4.0,0.0,1.0,0.0);

    SwapBuffers (DC);

    InvalidateRect (H, nil, False);

    end;

    procedure DrawElement (a, b, r0, r1: Single);

    var x1b, y1b: Single;

    x1e, y1e: Single;

    x0b, y0b: Single;

    x0e, y0e: Single;

    t0, t1: Single;

    dt: single;

    begin

    t0: =- 3; t1: = 3;

    dt: = 0.06;

    while t0 <= t1 do

    begin

    x0b: = a * sin (t0) * sin (t0) * sin (t0) * sin (t0) * cos (t0);

    y0b: = a * abs (sin (t0) * cos (t0 ));

    x0e: = a * sin (t0 + dt) * sin (t0 + dt) * sin (t0 + dt) * sin (t0 + dt) * cos (t0 + dt);

    y0e: = a * abs (sin (t0 + dt) * cos (t0 + dt ));

    x1b: = b * sin (t0) * sin (t0) * sin (t0) * sin (t0) * cos (t0);

    y1b: = b * abs (sin (t0) * cos (t0 ));

    x1e: = b * sin (t0 + dt) * sin (t0 + dt) * sin (t0 + dt) * sin (t0 + dt) * cos (t0 + dt);

    y1e: = b * abs (sin (t0 + dt) * cos (t0 + dt ));

    glBegin (GL_TRIANGLE_STRIP);

    glNormal ((x0b + x1e)/2, (y0b + y1e)/2, (r1 + r0)/2);

    glVertex3f (x0b, y0b, r0);

    glVertex3f (x0e, y0e, r0);

    glVertex3f (x1e, y1e, r1);

    glVertex3f (x1b, y1b, r1);

    glEnd;

    t0: = t0 + dt;

    end;

    end;

    procedure DrawFace (A, R: Single; Normal: Boolean);

    var x, y: single; t0, t1, dt: Single;

    begin

    t0: =- 3; t1: = 3;

    dt: = 0.06;

    glBegin (GL_POLYGON);

    while t0 <= t1 do

    begin

    x: = a * sin (t0) * sin (t0) * sin (t0) * sin (t0) * cos (t0);

    y: = a * abs (sin (t0) * cos (t0 ));

    glVertex3F (x, y, r);

    t0: = t0 + dt;

    end;

    t0: = 0;

    x: = a * sin (t0) * sin (t0) * sin (t0) * sin (t0) * cos (t0);

    y: = a * abs (sin (t0) * cos (t0 ));

    if Normal then glNormal3f (x, y, r-) else glNormal3f (x, y, r);

    glEnd;

    end;

    procedure TForm1.FormPaint (Sender: TObject);

    var m, n: single; dm: Single; a: Single; df: Single;

    begin

    a: = 25;

    df: = 10;

    glClear (GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);

    glColor (1.0,0.0,0.0,0.0);

    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);

    m: =- 1; n: = 1; dm: = 0.5;

    while m <= n do

    begin

    DrawElement (Sqrt (am * m), Sqrt (a-(m + dm) * (m + dm)), m/df, (m + dm)/df);

    m: = m + dm;

    end;

    DrawFace (Sqrt (a-(m) * (m)), (m)/df, True);

    m: =- 1;

    DrawFace (Sqrt (a-(m) * (m)), (m)/df, True);

    end;

    procedure TForm1.FormResize (Sender: TObject);

    const lm: Array [0 .. 3] of Single = (0.5,0.5,0.5,1.0);

    const

    light_ambient: array [0 .. 3] of glfloat = (0.0,0.0,0.0,1.0);

    light_diffuse: array [0 .. 3] of glfloat = (1.0,1.0,1.0,1.0);

    light_specular: array [0 .. 3] of glfloat = (2.0,2.0,2.0,1.0);

    light_position: array [0 .. 3] of glfloat = (2.0,1.0,3.0,1.0);

    light_emission: array [0 .. 3] of glfloat = (1.0,1.0,1.0,1.0);

    light_spotdirection: array [0 .. 3] of glfloat = (1.0,1.0,1.0,1.0);

    begin

    wglMakeCurrent (0,0);

    wglDeleteContext (RC);

    ReleaseDC (H, DC);

    DC: = GetDC (H);

    SetDCPixelFormat (DC);

    RC: = wglCreateContext (DC);

    wglMakeCurrent (DC, RC);

    glClearColor (0.6,0.6,0.6,0.0);

    glMatrixMode (GL_PROJECTION);

    glLoadIdentity;

    glFrustum (-1,1, -1,1,2,20);

    glMatrixMode (GL_MODELVIEW);

    glLoadIdentity;

    glTranslatef (0.0, -1.0, -6.0);

    glLightModel (GL_LIGHT_MODEL_LOCAL_VIEWER, Ord (True ));

    glLightModelfv (GL_LIGHT_MODEL_AMBIENT, @ lm);

    glLightfv (GL_LIGHT0, GL_AMBIENT, @ light_ambient);

    glLightfv (GL_LIGHT0, GL_DIFFUSE, @ light_diffuse);

    glLightfv (GL_LIGHT0, GL_SPECULAR, @ light_specular);

    glLightfv (GL_LIGHT0, GL_POSITION, @ light_position);

    glLightf (GL_LIGHT0, GL_SPOT_EXPONENT, 8);

    glLightf (GL_LIGHT0, GL_SPOT_CUTOFF, 170);

    glLightfv (GL_LIGHT0, GL_SPOT_DIRECTION, @ light_spotdirection);

    glEnable (GL_LIGHTING);

    glEnable (GL_LIGHT0);

    glEnable (GL_DEPTH_TEST);

    glEnable (GL_NORMALIZE);

    glEnable (GL_COLOR_MATERIAL);

    end;

    end.

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

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

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

     

     

     

     

     

     

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