Разработка приложения с использованием OpenGL для динамического изображения трехмерной модели изображения

Автор работы: Пользователь скрыл имя, 11 Января 2015 в 13:17, курсовая работа

Описание работы

Целью данной курсовой работы является создание трехмерной сцены, на которой изображены фигуры (треугольники и квадраты с общей вершиной), вращающиеся вокруг одной точки. Работа должна быть выполнена в среде разработки Lazarus.
В результате выполнения данной курсовой работы изучены правила создания сцен на компьютере и приобретены навыки работы с графической библиотекой.

Содержание работы

Введение ……………………………………………………………………..….….. 5
1 Анализ предметной области …………………………………………………... 6
2 Техническое задание ………….………………………………..………………...7
2.1 Основание для разработки ……................……………………………….7
2.2 Назначение разработки ………………...…………………………………7
2.3 Требования к программе ……………………………………………………7
2.3.1 Требования к функциональным характеристикам ……….……..7
2.3.2 Требования к составу и параметрам технических средств…...... 7
2.3.3 Требования к информационной и программной совместимости… 8
2.4 Требования к программной документации……….………………… ......8
3. Описание программы ……….………………………………………………….9
3.1 Общие сведения ………………..………… ...................................................9
3.2 Функциональное назначение.………………………………………..….... 9
3.3 Описание логической структуры…………………………………..….…. 9
3.4 Используемые технические средства…………………………….….........11
3.5 Вызов и загрузка…………………………………....................................11
4. Описание программы ……….…………………………..………………….…12
4.1 Объект испытаний ……..……………………..……………………...........12
4.2 Цель испытаний.………………………………..........................................12
4.3 Требования к программе…………….…………….……. ........................12
4.4 Требования к программной документации……………..………………..12
4.5 Средства и порядок испытаний……….……….……. …….....................12
5. Описание применения……............................................................................14
5.1 Назначение программы...……………..………………..………………… 14
5.2 Условия применения…………….……………….....................................14
5.3 Описание задачи…….……. ....................................................................14
5.4 Входные и выходные данные………………...........................................14
Заключение …………………………………………….…………………...….…. 15
Список использованных источников ………

Файлы: 1 файл

OpenGL курсовой.docx

— 1.96 Мб (Скачать файл)

Программа разработана в среде Lazarus работающей под управлением операционной системы Windows 7.

 

5.3 Описание задачи

Для пересчёта координат используется параметрическое уравнение эллипса. При срабатывании таймера через определенный интервал времени происходит перерасчет координат.

 

5.4 Входные и выходные данные

Ввод исходных данных в программу не предусмотрен. Все необходимые действия инициализации переменных происходят без вмешательства пользователя.

 

Заключение

 

При выполнении курсового проекта были выполнены следующие работы:

  1. Анализ предметной области.
  2. Анализ требований к программе.
  3. Проектирование программных средств.
  4. Реализация программы.
  5. Тестирование программы.

В результате было разработано приложение, иллюстрирующее имитацию движения треугоников относительно общей стороны в пространстве.

Тестирование показало, что программа полностью соответствует всем разработанным требованиям.

 

Список использованных источников

  1. Ву М., Девис Т., Дж. Нейдер, Шрайнер Д. OpenGL. Руководство по                         программированию./пер. с англ. – СПб.:”Питер” 2006
  2. Косников Ю.Н. Геометрические преобразования в компьютерной графике. Конспект лекций. - Пенза.: "ПГУ", 2010.
  1. Краснов М.В. OpenGL графика в проектах Delphi. 2002

  1. Тихомиров Ю.В.Программирование трехмерной графики. –

СПб.:”БХВ” 1998

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

ТЕКСТ ПРОГРАММЫ

Приложение А

(обязательное)

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Файл ExampleForm.pp

unit ExampleForm;

 

{$mode objfpc}{$H+}

 

interface

 

uses

  Classes, SysUtils, FileUtil, LCLProc, Forms, LResources, Buttons,

  StdCtrls, Dialogs, Graphics, IntfGraphics, GL, FPimage, OpenGLContext;

 

const

  GL_CLAMP_TO_EDGE = $812F;

 

type

  TglTexture = class

  public

    Width,Height: longint;

    Data        : pointer;

    destructor Destroy; override;

  end;

 

type

 

  { TExampleForm }

 

  TExampleForm = class(TForm)

    OpenGLControl1: TOpenGLControl;

    ExitButton1: TButton;

    LightingButton1: TButton;

    BlendButton1: TButton;

    MoveCubeButton1: TButton;

    MoveBackgroundButton1: TButton;

    RotateZButton1: TButton;

    RotateZButton2: TButton;

    HintLabel1: TLabel;

    procedure IdleFunc(Sender: TObject; var Done: Boolean);

    procedure FormResize(Sender: TObject);

    procedure ExitButton1Click(Sender: TObject);

    procedure LightingButton1Click(Sender: TObject);

    procedure BlendButton1Click(Sender: TObject);

    procedure MoveCubeButton1Click(Sender: TObject);

    procedure MoveBackgroundButton1Click(Sender: TObject);

    procedure RotateZButton1Click(Sender: TObject);

    procedure RotateZButton2Click(Sender: TObject);

    procedure OpenGLControl1Paint(Sender: TObject);

    procedure OpenGLControl1Resize(Sender: TObject);

 

  public

    constructor Create(TheOwner: TComponent); override;

    destructor Destroy; override;

    procedure LoadTextures;

 

  private

    AreaInitialized: boolean;

  end;

 

  TParticle = class

    x, y, z: GLfloat;

    vx, vy, vz: GLfloat;

    life: single;

  end;

 

  TParticleEngine = class

    xspawn: GLfloat;

    Particle: array [1..2001] of TParticle;

    procedure MoveParticles;

    procedure DrawParticles;

    procedure Start;

  public

    constructor Create;

    destructor Destroy; override;

  private

    procedure RespawnParticle(i: integer);

  end;

 

var AnExampleForm: TExampleForm;

    front, left1: GLuint;

    rx, ry, rz, rrx, rry, rrz: single;

    LightAmbient : array [0..3] of GLfloat;

    checked, blended, lighted, ParticleBlended, MoveCube, MoveBackground: boolean;

    textures       : array [0..2] of GLuint;    // Storage For 3 Textures

    MyglTextures   : array [0..2] of TglTexture;

    lightamb, lightdif, lightpos, light2pos, light2dif,

    light3pos, light3dif, light4pos, light4dif, fogcolor: array [0..3] of GLfloat;

    ParticleEngine: TParticleEngine;

    ParticleList, CubeList, BackList: GLuint;

 

var direction: boolean;

    timer: single;

    LastMsecs: integer;

 

function LoadFileToMemStream(const Filename: string): TMemoryStream;

function LoadglTexImage2DFromPNG(PNGFilename:string;

  Image: TglTexture): boolean;

 

implementation

 

 

function LoadFileToMemStream(const Filename: string): TMemoryStream;

var FileStream: TFileStream;

begin

  Result:=TMemoryStream.Create;

  try

    FileStream:=TFileStream.Create(UTF8ToSys(Filename), fmOpenRead);

    try

      Result.CopyFrom(FileStream,FileStream.Size);

      Result.Position:=0;

    finally

      FileStream.Free;

    end;

  except

    Result.Free;

    Result:=nil;

  end;

end;

 

function LoadglTexImage2DFromPNG(PNGFilename: string; Image: TglTexture

  ): boolean;

var

  png: TPortableNetworkGraphic;

  IntfImg: TLazIntfImage;

  y: Integer;

  x: Integer;

  c: TFPColor;

  p: PByte;

begin

  Result:=false;

  png:=TPortableNetworkGraphic.Create;

  IntfImg:=nil;

  try

    png.LoadFromFile(PNGFilename);

    IntfImg:=png.CreateIntfImage;

    Image.Width:=IntfImg.Width;

    Image.Height:=IntfImg.Height;

    GetMem(Image.Data,Image.Width*Image.Height * 3);

    p:=PByte(Image.Data);

    for y:=0 to IntfImg.Height-1 do begin

      for x:=0 to IntfImg.Width-1 do begin

        c:=IntfImg.Colors[x,y];

        p^:=c.red shr 8;

        inc(p);

        p^:=c.green shr 8;

        inc(p);

        p^:=c.blue shr 8;

        inc(p);

      end;

    end;

  finally

    png.Free;

    IntfImg.Free;

  end;

  Result:=true;

end;

 

{ TExampleForm }

 

constructor TExampleForm.Create(TheOwner: TComponent);

begin

  inherited CreateNew(TheOwner);

  if LazarusResources.Find(ClassName)=nil then begin

    SetBounds((Screen.Width-800) div 2,(Screen.Height-600) div 2,800,600);

    Caption:='LCL example for the TOpenGLControl';

   

    Application.OnIdle:=@IdleFunc;

    OnResize:=@FormResize;

    blended:=false;

    lighted:=false;

    ParticleEngine:=TParticleEngine.Create;

   

    ExitButton1:=TButton.Create(Self);

    with ExitButton1 do begin

      Name:='ExitButton1';

      Parent:=Self;

      SetBounds(320,10,80,25);

      Caption:='Exit';

      OnClick:=@ExitButton1Click;

    end;

 

    MoveCubeButton1:=TButton.Create(Self);

    with MoveCubeButton1 do begin

      Name:='MoveCubeButton1';

      Parent:=Self;

      SetBounds(320,10,80,25);

      Caption:='Move';

      Checked:=false;

      OnClick:=@MoveCubeButton1Click;

    end;

 

    // resize the components first, because the opengl context needs some time to setup

    FormResize(Self);

 

    OpenGLControl1:=TOpenGLControl.Create(Self);

    with OpenGLControl1 do begin

      Name:='OpenGLControl1';

      Parent:=Self;

      SetBounds(10,90,380,200);

      OnPaint:=@OpenGLControl1Paint;

      OnResize:=@OpenGLControl1Resize;

    end;

 

  end;

 

  LoadTextures;

 

  // now resize

  FormResize(Self);

end;

 

destructor TExampleForm.Destroy;

var i: integer;

begin

  for i:=0 to 2 do begin

    Textures[i]:=0;

    FreeAndNil(MyglTextures[i]);

  end;

  FreeAndNil(ParticleEngine);

 

  inherited Destroy;

end;

 

procedure TExampleForm.LoadTextures;

 

  procedure LoadglTexture(Filename:string; Image:TglTexture);

  begin

    Filename:=ExpandFileNameUTF8(Filename);

    if not LoadglTexImage2DFromPNG(Filename,Image) then begin

      MessageDlg('File not found',

        'Image file not found: '+Filename,

        mtError,[mbOk],0);

      raise Exception.Create('Image file not found: '+Filename);

    end;

  end;

 

var

  i: Integer;

begin

  for i:=0 to 2 do begin

    Textures[i]:=0;

    MyglTextures[i]:=TglTexture.Create;

  end;

  {loading the texture and setting its parameters}

 

  LoadglTexture('data/particle.png',MyglTextures[0]);

  LoadglTexture('data/texture2.png',MyglTextures[1]);

  LoadglTexture('data/texture3.png',MyglTextures[2]);

end;

 

// --------------------------------------------------------------------------

//                              Particle Engine

// --------------------------------------------------------------------------

 

constructor TParticleEngine.Create;

var i: integer;

begin

  for i:=1 to 2001 do Particle[i]:=TParticle.Create;

  xspawn:=0;

end;

 

destructor TParticleEngine.Destroy;

var i: integer;

begin

  for i:=1 to 2001 do FreeAndNil(Particle[i]);

  inherited Destroy;

end;

 

procedure TParticleEngine.DrawParticles;

var i: integer;

begin

  for i:=1 to 2001 do begin

    glPushMatrix;

    glTranslatef(Particle[i].x, Particle[i].y, Particle[i].z);

    glCallList(ParticleList);

    glPopMatrix;

  end;

end;

 

procedure TParticleEngine.RespawnParticle(i: integer);

begin

  if (xspawn>2) and (direction=true) then direction:=false;

  if (xspawn<-2) and (direction=false) then direction:=true;

  if direction then

    xspawn:=xspawn+0.0002*(timer/10)

  else

    xspawn:=xspawn-0.0002*(timer/10);

  Particle[i].x:=xspawn;

  Particle[i].y:=-0.5;

  Particle[i].z:=0;

  Particle[i].vx:=-0.005+GLFloat(random(2000))/200000;

  Particle[i].vy:=0.035+GLFloat(random(750))/100000;

  Particle[i].vz:=-0.005+GLFloat(random(2000))/200000;

  Particle[i].life:=GLFloat(random(1250))/1000+1;

end;

 

procedure TParticleEngine.MoveParticles;

var i: integer;

begin

  for i:=1 to 2001 do begin

    if Particle[i].life>0 then begin

      Particle[i].life:=Particle[i].life-0.01*(timer/10);

      Particle[i].x:=Particle[i].x+Particle[i].vx*(timer/10);

     

      Particle[i].vy:=Particle[i].vy-0.00035*(timer/10); // gravity

      Particle[i].y:=Particle[i].y+Particle[i].vy*(timer/10);

     

      Particle[i].z:=Particle[i].z+Particle[i].vz*(timer/10);

    end else begin

      RespawnParticle(i);

    end;

  end; 

end; 

procedure TParticleEngine.Start;

var i: integer;

begin

  for i:=1 to 2001 do begin

    RespawnParticle(i);

  end;

end;

 

// ---------------------------------------------------------------------------

// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

// ---------------------------------------------------------------------------

 

procedure TExampleForm.IdleFunc(Sender: TObject; var Done: Boolean);

begin

  OpenGLControl1.Invalidate;

  //OpenGLControl1Paint(Self);

  Done:=false; // tell lcl to handle messages and return immediatly

end;

 

// --------------------------------------------------------------------------

//                                 Buttons

// --------------------------------------------------------------------------

 

procedure TExampleForm.LightingButton1Click(Sender: TObject);

begin

  if lighted then glDisable(GL_LIGHTING) else glEnable(GL_LIGHTING);

  lighted:=not lighted;

  OpenGLControl1.Invalidate;// not need

end;

 

procedure TExampleForm.BlendButton1Click(Sender: TObject);

begin

  blended:=not blended;

  OpenGLControl1.Invalidate;

end;

 

procedure TExampleForm.MoveCubeButton1Click(Sender: TObject);

begin

  MoveCube:=not MoveCube;

  OpenGLControl1.Invalidate;

end;

 

procedure TExampleForm.MoveBackgroundButton1Click(Sender: TObject);

begin

  MoveBackground:=not MoveBackground;

  OpenGLControl1.Invalidate;

end;

 

procedure TExampleForm.RotateZButton1Click(Sender: TObject);

begin

  ParticleEngine.Start;

  OpenGLControl1.Invalidate;

end;

 

procedure TExampleForm.RotateZButton2Click(Sender: TObject);

begin

  ParticleBlended:=not ParticleBlended;

  OpenGLControl1.Invalidate;

end;

 

// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

// ---------------------------------------------------------------------------

 

procedure TExampleForm.FormResize(Sender: TObject);

begin

  if OpenGLControl1<>nil then

    OpenGLControl1.SetBounds(10, 30, Width-120, Height-40);

  ExitButton1.SetBounds(Width-90, 5, 80, 25);

  MoveCubeButton1.SetBounds(Width-90, 50, 80, 25);

end;

 

procedure TExampleForm.ExitButton1Click(Sender: TObject);

begin

  Close;

end;

 

procedure TExampleForm.OpenGLControl1Paint(Sender: TObject);

 

  procedure myInit;

  begin

    {init lighting variables}

    {ambient color}

    lightamb[0]:=0.5;

    lightamb[1]:=0.5;

    lightamb[2]:=0.5;

    lightamb[3]:=1.0;

    {diffuse color}

    lightdif[0]:=0.8;

    lightdif[1]:=0.0;

    lightdif[2]:=0.0;

    lightdif[3]:=1.0;

    {diffuse position}

    lightpos[0]:=0.0;

    lightpos[1]:=0.0;

    lightpos[2]:=3.0;

    lightpos[3]:=1.0;

    {diffuse 2 color}

    light2dif[0]:=0.0;

    light2dif[1]:=0.8;

    light2dif[2]:=0.0;

    light2dif[3]:=1.0;

    {diffuse 2 position}

    light2pos[0]:=3.0;

    light2pos[1]:=0.0;

    light2pos[2]:=3.0;

    light2pos[3]:=1.0;

    {diffuse 3 color}

    light3dif[0]:=0.0;

    light3dif[1]:=0.0;

    light3dif[2]:=0.8;

    light3dif[3]:=1.0;

    {diffuse 3 position}

    light3pos[0]:=-3.0;

    light3pos[1]:=0.0;

    light3pos[2]:=0.0;

    light3pos[3]:=1.0;

    {fog color}

   

    fogcolor[0]:=0.5;

    fogcolor[1]:=0.5;

    fogcolor[2]:=0.5;

    fogcolor[3]:=1.0;

      end; 
const GLInitialized: boolean = false;

 

procedure InitGL;

var

  i: Integer;

begin

  if GLInitialized then exit;

  GLInitialized:=true;

  {setting lighting conditions}

  glLightfv(GL_LIGHT0,GL_AMBIENT,lightamb);

  glLightfv(GL_LIGHT1,GL_AMBIENT,lightamb);

  glLightfv(GL_LIGHT2,GL_DIFFUSE,lightdif);

  glLightfv(GL_LIGHT2,GL_POSITION,lightpos);

  glLightfv(GL_LIGHT3,GL_DIFFUSE,light2dif);

  glLightfv(GL_LIGHT3,GL_POSITION,light2pos);

  glLightfv(GL_LIGHT4,GL_POSITION,light3pos);

  glLightfv(GL_LIGHT4,GL_DIFFUSE,light3dif);

  glEnable(GL_LIGHT0);

  glEnable(GL_LIGHT1);

  glEnable(GL_LIGHT2);

  glEnable(GL_LIGHT3);

  glEnable(GL_LIGHT4);

 

  glGenTextures(3, @textures[0]);

  for i:=0 to 2 do begin

    glBindTexture(GL_TEXTURE_2D, Textures[i]);

    glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_CLAMP_TO_EDGE);

    glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_CLAMP_TO_EDGE);

    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);

    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);

    glTexImage2D(GL_TEXTURE_2D,0,3,MyglTextures[i].Width,MyglTextures[i].Height,0

        ,GL_RGB,GL_UNSIGNED_BYTE,MyglTextures[i].Data);

  end;

  glTexEnvf(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_MODULATE);

  {instead of GL_MODULATE you can try GL_DECAL or GL_BLEND}

  glEnable(GL_TEXTURE_2D);          // enables 2d textures

  glClearColor(0.0,0.0,0.0,1.0);    // sets background color

  glClearDepth(1.0);

  glDepthFunc(GL_LEQUAL);           // the type of depth test to do

  glEnable(GL_DEPTH_TEST);          // enables depth testing

  glShadeModel(GL_SMOOTH);          // enables smooth color shading

  {blending}

  glColor4f(1.0,1.0,1.0,0.5);       // Full Brightness, 50% Alpha ( NEW )

  glBlendFunc(GL_SRC_ALPHA, GL_ONE);

  glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, GL_TRUE);

  {}

  glHint(GL_LINE_SMOOTH_HINT,GL_NICEST);

  glHint(GL_POLYGON_SMOOTH_HINT,GL_NICEST);

  glHint(GL_PERSPECTIVE_CORRECTION_HINT,GL_NICEST);   

 

  // creating display lists

 

  ParticleList:=glGenLists(1);

  glNewList(ParticleList, GL_COMPILE);

    glBindTexture(GL_TEXTURE_2D, textures[0]);

    glBegin(GL_TRIANGLE_STRIP);

      glNormal3f( 0.0, 0.0, 1.0);

      glTexCoord2f( 1.0, 1.0);     glVertex3f(+0.025, +0.025, 0);

      glTexCoord2f( 0.0, 5.0);     glVertex3f(-0.025, +0.025, 0);

      glTexCoord2f( 1.0, 0.0);     glVertex3f(+0.025, -0.025, 0);

      glTexCoord2f( 0.0, 0.0);     glVertex3f(-0.025, -0.025, 0);

    glEnd;

  glEndList; 
  BackList:=ParticleList+1;

  glNewList(BackList, GL_COMPILE);

    glBindTexture(GL_TEXTURE_2D, textures[2]);

    glBegin(GL_QUADS);

      {Front Face}

      glNormal3f( 0.0, 0.0, 1.0);

      glTexCoord2f( 1.0, 1.0);     glVertex3f( 2.5, 2.5, 2.5);

      glTexCoord2f( 0.0, 1.0);     glVertex3f(-2.5, 2.5, 2.5);

      glTexCoord2f( 0.0, 0.0);     glVertex3f(-2.5,-2.5, 2.5);

      glTexCoord2f( 1.0, 0.0);     glVertex3f( 2.5,-2.5, 2.5);

      {Back Face}

      glNormal3f( 0.0, 0.0,-1.0);

      glTexCoord2f( 0.0, 1.0);     glVertex3f( 2.5, 2.5,-2.5);

      glTexCoord2f( 0.0, 0.0);     glVertex3f( 2.5,-2.5,-2.5);

      glTexCoord2f( 1.0, 0.0);     glVertex3f(-2.5,-2.5,-2.5);

      glTexCoord2f( 1.0, 1.0);     glVertex3f(-2.5, 2.5,-2.5);     

      {Left Face}

      glNormal3f(-1.0, 0.0, 0.0);

      glTexCoord2f( 1.0, 1.0);     glVertex3f(-2.5, 2.5, 2.5);

Информация о работе Разработка приложения с использованием OpenGL для динамического изображения трехмерной модели изображения