Добавил:
ivanov666
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз:
Предмет:
Файл:Системы автоматизированного проектирования. Моделирование в машиностроении. Учебное пособие
.pdf
Обработчик кнопки Button3 будет содержать код, реализующий визу-
procedure TForm1.Button3Click(Sender: TObject);
var
lbX,lbY:TLabel;
i:integer;
begin
wglMakeCurrent(Canvas.Handle, hrc);// Устанавливаем текущий кон-
текст воспроизведения
glViewPort (-250, -400, 1100, 830); // Устанавливаем область отображе-
ния
glClearColor (255, 255, 255, 1); // Устанавливаем цвет фона
glClear (GL_COLOR_BUFFER_BIT); // Очистка экрана
glEnable(GL_POINT_SMOOTH); // Устанавливаем режим сглажива-
ния
//Оси
glBegin (GL_LINES);
glColor3f (255, 0, 0); glVertex2f(-0.53, 0); glVertex2f(0.54, 0); //X
glColor3f (0, 255, 0); glVertex2f(0, 0); glVertex2f(0, 1); //Y
glEnd;
//Cтрелки
glBegin (GL_POLYGON);
glVertex2f (0,1);
glVertex2f (-0.01,0.95);
glVertex2f (0,0.96);
glVertex2f (0.01,0.95);
glEnd;
glColor3f (255, 0, 0);
glBegin (GL_POLYGON);
glVertex2f (0.58,0);
glVertex2f (0.53,-0.01);
glVertex2f (0.54,0);
glVertex2f (0.53,0.01);
glEnd;
//Подписи осей
//Y
lbY:=TLabel.Create(form1);
lbY.Parent:=form1;
lbY.Left:=310;
lbY.Top:=20;
lbY.Caption:='Y';
lbY.Font.Color:=$00FF00;
//X
ализацию параболы по данным из таблицы (рисунок 5.13):
51

lbX:=TLabel.Create(form1);
lbX.Parent:=form1;
lbX.Left:=595;
lbX.Top:=405;
lbX.Caption:='X';
lbX.Font.Color:=$0000FF;
//Построение параболы по координатам из таблицы
glColor3f (0, 0, 0);
glBegin (GL_LINE_STRIP);
for i:=-15 to 15 do glVertex2f(StrToFloat(stringgrid1.Cells[0,i+16]),
StrToFloat(stringgrid1.Cells[1,i+16]));
glEnd;
SwapBuffers(Canvas.Handle); // Выводим сцену на экран
wglMakeCurrent(0, 0); // Обнуляем текущий контекст воспроиз-
ведения
end;
здание координат для построения гиперболы и записи их в таблицу (рисунок
5.14):
Обработчик кнопки Button4 будет содержать код, реализующий со-
Рисунок 5.13 – Построение параболы
52

procedure TForm1.Button4Click(Sender: TObject);
var
i:integer;
begin
for i:=1 to 100 do
begin
stringgrid1.RowCount:=100; // Увеличиваем количество строк таблицы
до 100
stringgrid1.Cells[0,i]:=FloatToStr(i/100); // Координаты "Х"
string-
grid1.Cells[1,i]:=FloatToStrF(1/StrToFloat(stringgrid1.Cells[0,i])*0.01,
ffFixed, 4, 4); // Координаты "Y"
end;
button5.Enabled:=true;//Делаем активной кнопку "Построить" для ги-
перболы
button3.Enabled:=false;//Делаем неактивной кнопку "Построить" для
параболы
end;
procedure TForm1.Button5Click(Sender: TObject);
var
i:integer;
begin
AxisXY; // Строим оси
// Строим гиперболу по координатам из таблицы
glColor3f (0, 0, 0);
glBegin (GL_LINE_STRIP);
for i:=1 to 100 do
glVertex2f(StrToFloat(stringgrid1.Cells[0,i]),
StrToFloat(stringgrid1.Cells[1,i]));
glEnd;
SwapBuffers(Canvas.Handle); // Выводим сцену на экран
wglMakeCurrent(0, 0);// Обнуляем текущий контекст воспроизведения
end;
Обработчик кнопки Button5 будет содержать код, реализующий визу-
ализацию гиперболы по данным из таблицы (рисунок 5.14):
53

Рисунок 5.14 – Построение гиперболы
5.3.4 Задание на выполнение работы
Проверить программный код выполнить изменения в нем, по указанию
преподавателя. Содержание отчета:
– название работы;
– цель работы;
– перечень используемых команд;
– экранные формы;
– листинг программы.
5.3.5 Контрольные вопросы
Что такое уравнение параметрического вида?
Как можно представить линию?
Перечислите используемые компоненты при создании формы.
Перечислите моделируемые объекты, представленные в данной работе.
С помощью какой формулы реализуется построение параболы (гипер-
болы)?
54

5.4 Текстурированные объектов
5.4.1 Цель работы
Целью работы является приобретение навыков наложения текстур на
примитивы, используя графическую библиотеку OpenGL.
5.4.2 Понятие о текстуре
Текстура - растровое изображение, накладываемое на поверхность полигона, из которых состоят 3D-модели, для придания ей цвета, окраски или
иллюзии рельефа. Понятие «текстура» является одним из столпов ЗЭ-
моделирования, поскольку позволяет воспроизвести малые объекты поверхности, создание которых полигонами оказалось бы чрезмерно ресурсоёмким.
Например, шрамы на коже, складки на одежде, мелкие камни и прочие пред-
меты на поверхности стен и почвы.
Качество поверхности текстуры определяется пикселями - количеством
пикселей на минимальную единицу текстуры. Так как сама по себе текстура
является изображением, разрешение текстуры и ее формат играют большую
роль, которая впоследствии сказывается на общем впечатлении от качества
графики в 3D-приложении.
Текстура подобна обоям, наклеиваемым на поверхность (рисунок 5.15).
Созданные в трехмерном редакторе объекты выглядят, как каменные скульп-
туры с однотонным цветом, и совсем не похожи на настоящие. Чтобы «раскрасить» все элементы, а также наделить их такими физическими свойствами
материалов, как прозрачность, шершавость, способностью отражать и пре-
ломлять свет и так далее, необходимо для каждого объекта установить характеристики материала, или текстурировать объект.
Текстура бывает одномерной и двумерной. Одномерная текстура может
использоваться только для нанесения узора в виде полосок, двумерная поз-
воляет наносить прямоугольные образы.
5.4.3 Ход работы
Создайте в среде программирования Delphi новый проект. Переместите
в каталог с программой файлы DGLUT.dcu, DGLUT.pas. В разделе uses программы подключите библиотеку OpenGL.
55

Рисунок 5.15 – Наложение текстуры на грань
private
{ Private declarations }
DC: HDC; // контекст воспроизведения
hrc: HGLRC; // ссылка на контекст воспроизведения OpenGL
procedure Init;
procedure SetDCPixelFormat; // установка формата пикселей
procedure Idle (Sender:TObject; var Done:boolean);
procedure SetupGL;
protected
procedure WMPaint(var Msg: TWMPaint);
message WM_PAINT;
end;
var
Form1: TForm1;
obj : 1..3 = 1;
Angle: GLfloat = 0;
time: LongInt;
TexWidth : GLint = 16; // ширина текстуры
GenSOn : Boolean = True; // генерировать ли координату s
// параметром процедуры является требуемая ширина текстуры,
В разделе private и protected инициализировать следующие перемен-
ные и процедуры:
Добавить в раздел const Sphere=1.
В разделе объявления глобальных переменных инициализировать
следующие переменные:
56

// число должно быть степенью двойки
implementation
uses DGLUT;
{$R *.dfm}
procedure TForm1.SetupGL;
begin
glClearColor(1,1,1,1);
glEnable(GL_DEPTH_TEST);
glEnable(GL_CULL_FACE);
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
DC:= GetDC(Handle); // получаем контекст воспроизведения Windows
SetDCPixelFormat; // задаем формат пикселей
hrc:= wglCreateContext(DC); // создаем контекст воспроизведения
OpenGL
wglMakeCurrent(DC, hrc); // делаем его текущим
Init;
time:=GetTickCount;
Application.OnIdle:= Idle;
SetupGL; //установка режимов OpenGL
end;
Подключаем библиотеку DGLUT:
Добавим процедуру SetupGL, данная процедура позволяет менять
фон экранной формы:
Перейдите к конструктору и сделайте двойной щелчок клавишей
мыши на форме – создастся функция обработчика события загрузки формы
FormCreate. В ней мы поместим следующий код:
Инициализировать обработчики событий OnCreate, OnDestroy,
OnKeyDown, OnResize. Для этого необходимо в Object Inspector перейти на
вкладку Events, где щелкнуть по вышеперечисленным событиям два раза.
В обработчики событий добавить следующий код:
OnCreate:
57

procedure TForm1.FormCreate(Sender: TObject);
begin
DC:= GetDC(Handle); // получаем контекст воспроизведения Windows
SetDCPixelFormat; // задаем формат пикселей
hrc:= wglCreateContext(DC); // создаем контекст воспроизведения
OpenGL
wglMakeCurrent(DC, hrc); // делаем его текущим
Init;
time:=GetTickCount;
Application.OnIdle:= Idle;
SetupGL; //установка режимов OpenGL
end;
procedure TForm1.FormDestroy(Sender: TObject);
begin
glDeleteLists (sphere, 1);
wglMakeCurrent(0, 0);
wglDeleteContext(hrc);
ReleaseDC(Handle, DC);
DeleteDC (DC);
end;
procedure TForm1.FormKeyDown(Sender: TObject; var Key: Word;
Shift: TShiftState);
begin
If Key = VK_ESCAPE then Close;
end;
procedure TForm1.FormResize(Sender: TObject);
begin
glViewport(0, 0, ClientWidth, ClientHeight );
glMatrixMode(GL_PROJECTION);
glLoadIdentity;
glFrustum( -0.75, 0.75, -0.75, 0.75, 5.0, 15.0 );
glMatrixMode( GL_MODELVIEW );
glLoadIdentity;
glTranslatef( 0.0, 0.0, -12.0 );
glRotatef(45.0, 1.0, 0.0, 0.0);
OnDestroy:
OnKeyDown:
OnResize:
58

InvalidateRect(Handle, nil, False);
end;
procedure TForm1.SetDCPixelFormat;
var
nPixelFormat: Integer;
pfd: TPixelFormatDescriptor;
begin
FillChar(pfd, SizeOf(pfd), 0);
pfd.dwFlags := PFD_DRAW_TO_WINDOW or
PFD_SUPPORT_OPENGL or
PFD_DOUBLEBUFFER; // множество битовых фла-
гов,определяющих устройство и интерфейс
nPixelFormat := ChoosePixelFormat(DC, @pfd); // устанавливаем фор-
мат пикселей в контексте устройства
SetPixelFormat(DC, nPixelFormat, @pfd);
end;
procedure TForm1.MakeTexImage (TexImageWidth : GLint);
const
TexParams : Array [0..3] of GLfloat = (0.0, 0.0, 1.0, 0.0);
var
TexImage : Array [0..128 * 3] of GLUbyte;
j : GLint;
begin
j := 0;
While j < TexImageWidth * 3 - 1 do
begin
TexImage [j] := 255; // R
TexImage [j + 1] :=0 ; // G
TexImage [j + 2] :=0 ; // B
TexImage [j + 3] :=0 ; // R
TexImage [j + 4] :=0 ; // G
TexImage [j + 5] :=255 ; // B
Inc (j, 6);
end;
glTexParameteri (GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER,
GL_NEAREST);
Зададим формат пиксела:
В пользовательской процедуре MakeTexImage подготавливается массив образа текстур, а также задаются все связанные с ней параметры:
59

glTexParameteri (GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER,
GL_NEAREST);
glTexImage1D (GL_TEXTURE_1D, 0, 3, TexImageWidth, 0, GL_RGB,
GL_UNSIGNED_BYTE, @TexImage );
glEnable (GL_TEXTURE_1D);
If GenSOn then glEnable (GL_TEXTURE_GEN_S) else glDisable
(GL_TEXTURE_GEN_S);
glTexGeni (GL_S, GL_TEXTURE_GEN_MODE,
GL_OBJECT_LINEAR);
glTexGenfv (GL_S, GL_OBJECT_PLANE, @TexParams); end;
Добавить следующие процедуры:
procedure TForm1.Init;
var
Quadric : GLUquadricObj;
begin
//освещение
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glEnable(GL_DEPTH_TEST);
MakeTexImage(TexWidth);
Quadric:= gluNewQuadric;
gluQuadricTexture (Quadric, TRUE);
glNewList (Sphere, GL_COMPILE);
glRotatef (45, 1.0, 0.0, 0.0);
gluSphere (Quadric, 1.0, 24, 12);
//gluCylinder (Quadric, 0.0, 1.0, 1.0, 20, 30); //конус
//gluCylinder (Quadric, 1.0, 1.0, 2.0, 20, 10); //цилиндр
glEndList;
gluDeleteQuadric (Quadric);
end;
procedure TForm1.Idle (Sender:TObject;var Done:boolean);
begin
Angle := Angle + 0.1 * (GetTickCount - time) * 360 / 1000;
If Angle >= 360.0 then Angle := 0.0;
time := GetTickCount;
InvalidateRect(Handle, nil, False);
end;
procedure TForm1.WMPaint(var Msg: TWMPaint);
var
Визуализация:
60
Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]
