Разработка приложения с использованием OpenGL для динамического изображения трехмерной модели изображения
Курсовая работа, 11 Января 2015, автор: пользователь скрыл имя
Описание работы
Целью данной курсовой работы является создание трехмерной сцены, на которой изображены фигуры (треугольники и квадраты с общей вершиной), вращающиеся вокруг одной точки. Работа должна быть выполнена в среде разработки 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 Входные и выходные данные
Ввод исходных данных в программу не предусмотрен. Все необходимые действия инициализации переменных происходят без вмешательства пользователя.
Заключение
При выполнении курсового проекта были выполнены следующие работы:
- Анализ предметной области.
- Анализ требований к программе.
- Проектирование программных средств.
- Реализация программы.
- Тестирование программы.
В результате было разработано приложение, иллюстрирующее имитацию движения треугоников относительно общей стороны в пространстве.
Тестирование показало, что программа полностью соответствует всем разработанным требованиям.
Список использованных источников
- Ву М., Девис Т., Дж. Нейдер, Шрайнер Д. OpenGL. Руководство по программированию./пер. с англ. – СПб.:”Питер” 2006
- Косников Ю.Н. Геометрические преобразования в компьютерной графике. Конспект лекций. - Пенза.: "ПГУ", 2010.
Краснов М.В. OpenGL графика в проектах Delphi. 2002
Тихомиров Ю.В.Программирование трехмерной графики. –
СПб.:”БХВ” 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(
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(
Image: TglTexture): boolean;
implementation
function LoadFileToMemStream(const Filename: string): TMemoryStream;
var FileStream: TFileStream;
begin
Result:=TMemoryStream.Create;
try
FileStream:=TFileStream.
try
Result.CopyFrom(FileStream,
Result.Position:=0;
finally
FileStream.Free;
end;
except
Result.Free;
Result:=nil;
end;
end;
function LoadglTexImage2DFromPNG(
): boolean;
var
png: TPortableNetworkGraphic;
IntfImg: TLazIntfImage;
y: Integer;
x: Integer;
c: TFPColor;
p: PByte;
begin
Result:=false;
png:=TPortableNetworkGraphic.
IntfImg:=nil;
try
png.LoadFromFile(PNGFilename);
IntfImg:=png.CreateIntfImage;
Image.Width:=IntfImg.Width;
Image.Height:=IntfImg.Height;
GetMem(Image.Data,Image.Width*
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(
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:=
ExitButton1:=TButton.Create(
with ExitButton1 do begin
Name:='ExitButton1';
Parent:=Self;
SetBounds(320,10,80,25);
Caption:='Exit';
OnClick:=@ExitButton1Click;
end;
MoveCubeButton1:=TButton.
with MoveCubeButton1 do begin
Name:='MoveCubeButton1';
Parent:=Self;
SetBounds(320,10,80,25);
Caption:='Move';
Checked:=false;
OnClick:=@
end;
// resize the components first, because the opengl context needs some time to setup
FormResize(Self);
OpenGLControl1:=
with OpenGLControl1 do begin
Name:='OpenGLControl1';
Parent:=Self;
SetBounds(10,90,380,200);
OnPaint:=@OpenGLControl1Paint;
OnResize:=@
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(
if not LoadglTexImage2DFromPNG(
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.
end;
{loading the texture and setting its parameters}
LoadglTexture('data/particle.
LoadglTexture('data/texture2.
LoadglTexture('data/texture3.
end;
// ------------------------------
//
// ------------------------------
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.
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/
else
xspawn:=xspawn-0.0002*(timer/
Particle[i].x:=xspawn;
Particle[i].y:=-0.5;
Particle[i].z:=0;
Particle[i].vx:=-0.005+
Particle[i].vy:=0.035+GLFloat(
Particle[i].vz:=-0.005+
Particle[i].life:=GLFloat(
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].
Particle[i].x:=Particle[i].x+
Particle[i].vy:=Particle[i].
Particle[i].y:=Particle[i].y+
Particle[i].z:=Particle[i].z+
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;
// ------------------------------
//
// ------------------------------
procedure TExampleForm.
begin
if lighted then glDisable(GL_LIGHTING) else glEnable(GL_LIGHTING);
lighted:=not lighted;
OpenGLControl1.Invalidate;// not need
end;
procedure TExampleForm.
begin
blended:=not blended;
OpenGLControl1.Invalidate;
end;
procedure TExampleForm.
begin
MoveCube:=not MoveCube;
OpenGLControl1.Invalidate;
end;
procedure TExampleForm.
begin
MoveBackground:=not MoveBackground;
OpenGLControl1.Invalidate;
end;
procedure TExampleForm.
begin
ParticleEngine.Start;
OpenGLControl1.Invalidate;
end;
procedure TExampleForm.
begin
ParticleBlended:=not ParticleBlended;
OpenGLControl1.Invalidate;
end;
// ++++++++++++++++++++++++++++++
// ------------------------------
procedure TExampleForm.FormResize(
begin
if OpenGLControl1<>nil then
OpenGLControl1.SetBounds(10, 30, Width-120, Height-40);
ExitButton1.SetBounds(Width-
MoveCubeButton1.SetBounds(
end;
procedure TExampleForm.ExitButton1Click(
begin
Close;
end;
procedure TExampleForm.
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_
glLightfv(GL_LIGHT1,GL_
glLightfv(GL_LIGHT2,GL_
glLightfv(GL_LIGHT2,GL_
glLightfv(GL_LIGHT3,GL_
glLightfv(GL_LIGHT3,GL_
glLightfv(GL_LIGHT4,GL_
glLightfv(GL_LIGHT4,GL_
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,
glTexParameterf(GL_TEXTURE_2D,
glTexParameteri(GL_TEXTURE_2D,
glTexParameteri(GL_TEXTURE_2D,
glTexImage2D(GL_TEXTURE_2D,0,
,GL_RGB,GL_UNSIGNED_BYTE,
end;
glTexEnvf(GL_TEXTURE_ENV,GL_
{instead of GL_MODULATE you can try GL_DECAL or GL_BLEND}
glEnable(GL_TEXTURE_2D);
glClearColor(0.0,0.0,0.0,1.0);
glClearDepth(1.0);
glDepthFunc(GL_LEQUAL);
glEnable(GL_DEPTH_TEST);
glShadeModel(GL_SMOOTH);
{blending}
glColor4f(1.0,1.0,1.0,0.5);
glBlendFunc(GL_SRC_ALPHA, GL_ONE);
glLightModeli(GL_LIGHT_MODEL_
{}
glHint(GL_LINE_SMOOTH_HINT,GL_
glHint(GL_POLYGON_SMOOTH_HINT,
glHint(GL_PERSPECTIVE_
// 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);