Вы находитесь на странице: 1из 15

МІНІСТЕРСТВО ОСВІТИ І НАУКИ УКРАЇНИ

Національний аерокосмічний університет ім. М.Є. Жуковського


“Харківський авіаційний інститут”

Факультет програмної інженерії та бізнесу

Кафедра інженерії програмного забезпечення

ЛАБОРАТОРНА РОБОТА 5
з курсу «Компьютерная графика с OpenGL»
на тему: «КВАДРАТИЧНЫЕ ПРИМИТИВЫ.АФФИННЫЕ ПРЕОБРАЗОВАНИЯ В
ПРОСТРАНСТВЕ»

Виконав: студент 3 курсу групи № 632п


напряму підготовки (спеціальності)
121 «Інженерія програмного забезпечення»
(шифр і назва напряму підготовки (спеціальності))
Тука Я.Л.
(прізвище й ініціали студента)
Прийняв: доц. Лучшев П.О.
(посада, науковий ступінь, прізвище й ініціали)
Національна шкала:
Кількість балів:
Оцінка ECTS:
2

Харків – 2019
10 вариант
ЦЕЛЬ РАБОТЫ: научиться работать с трехмерными графическими примитивами
OpenGL и применять аффинные преобразования для размещения объектов в
пространстве.
ЗАДАНИЕ
Используя инструментальные средства, указанные преподавателем,
разработать программу с использованием средств OpenGL, которая
устанавливает изотропную систему координат, создает и выводит изображение
трехмерной сцены с такими элементами (система оценки приведена в табл. 5.1,
а варианты заданий – в табл.5.2):
⎯ оси координат с нулем в центре экрана и указанием оси и
положительного направления;
⎯ координатная сетка (grid) в одной из плоскостей (X0Y, X0Z или Y0Z);
⎯ три квадратичные фигуры – gluDisk / gluPartialDisk, gluSphere,
gluCylinder в режиме отображения каркаса и с упрощенной моделью
освещения glEnable(GL_COLOR_MATERIAL) длябазового уровня
сложности;
⎯ плоскость отсечения для одной из фигур (сфера, цилиндр или конус);
⎯ полноценная модель освещения и/или текстурами для реализации
задания с повышенной сложностью.
Минимальный интерфейс пользователя должен обеспечивать возможности
вращения сцены относительно осей OX и OY с помощью манипулятора «мышь»
и управления параметрами плоскости отсечения [1, 2]. Параметры детализации
объектов (slices, stacks), цвета, толщины и типа линий выбирают
самостоятельно.
3

ТЕОРЕТИЧЕСКИЕ СВЕДЕНИЯ
gluPerspective — set up a perspective projection matrix
C Specification
void gluPerspectiv
GLdouble fovy,
e(
GLdouble aspec
 
t,
GLdouble zNear
 
,
  GLdouble zFar);
 
Parameters
fovy
Specifies the field of view angle, in degrees, in the y direction.
aspect
Specifies the aspect ratio that determines the field of view in the x direction.
The aspect ratio is the ratio of x (width) to y (height).
zNear
Specifies the distance from the viewer to the near clipping plane (always
positive).
zFar
Specifies the distance from the viewer to the far clipping plane (always
positive).
gluLookAt — define a viewing transformation
C Specification
void gluLookAt
GLdouble eyeX,
(
  GLdouble eyeY,
  GLdouble eyeZ,
GLdouble center
 
X,
GLdouble center
 
Y,
GLdouble center
 
Z,
  GLdouble upX,
  GLdouble upY,
  GLdouble upZ);
 
4

Parameters
eyeX, eyeY, eyeZ
Specifies the position of the eye point.
centerX, centerY, centerZ
Specifies the position of the reference point.
upX, upY, upZ
Specifies the direction of the up vector.
Description
gluLookAt creates a viewing matrix derived from an eye point, a reference point
indicating the center of the scene, and an UP vector.
The matrix maps the reference point to the negative z axis and the eye point to the
origin. When a typical projection matrix is used, the center of the scene therefore
maps to the center of the viewport. Similarly, the direction described by the UP vector
projected onto the viewing plane is mapped to the positive y axis so that it points
upward in the viewport. The UP vector must not be parallel to the line of sight from
the eye point to the reference point.
Name
glLight — set light source parameters

C Specification
void glLightf
GLenum light,
(
GLenum pnam
 
e,
GLfloat param)
 
;
 
void glLighti
GLenum light,
(
GLenum pnam
 
e,
  GLint param);
 
Parameters
light
Specifies a light. The number of lights depends on the implementation, but at
least eight lights are supported. They are identified by symbolic names of the
form GL_LIGHT i, where i ranges from 0 to the value of GL_MAX_LIGHTS -
1.
5

pname
Specifies a single-valued light source parameter
for light. GL_SPOT_EXPONENT, GL_SPOT_CUTOFF, GL_CONSTANT_A
TTENUATION, GL_LINEAR_ATTENUATION,
and GL_QUADRATIC_ATTENUATION are accepted.

param
Specifies the value that parameter pname of light source light will be set to.

C Specification
void glLightfv
GLenum light,
(
  GLenum pname,
const GLfloat
 
* params);
 
void glLightiv
GLenum light,
(
  GLenum pname,
const GLint
 
* params);
 
Parameters
light
Specifies a light. The number of lights depends on the implementation, but at
least eight lights are supported. They are identified by symbolic names of the
form GL_LIGHT i, where i ranges from 0 to the value of GL_MAX_LIGHTS -
1.

pname
Specifies a light source parameter
for light. GL_AMBIENT, GL_DIFFUSE, GL_SPECULAR, GL_POSITION, 
GL_SPOT_CUTOFF, GL_SPOT_DIRECTION, GL_SPOT_EXPONENT, GL
_CONSTANT_ATTENUATION, GL_LINEAR_ATTENUATION,
and GL_QUADRATIC_ATTENUATION are accepted.

params
Specifies a pointer to the value or values that parameter pname of light
source light will be set to.
6

Description
glLight sets the values of individual light source parameters. light names the light and
is a symbolic name of the form GL_LIGHT i, where i ranges from 0 to the value
of GL_MAX_LIGHTS - 1. pname specifies one of ten light source parameters, again
by symbolic name. params is either a single value or a pointer to an array that
contains the new values.

To enable and disable lighting calculation, call glEnable and glDisable with


argument GL_LIGHTING. Lighting is initially disabled. When it is enabled, light
sources that are enabled contribute to the lighting calculation. Light source i is
enabled and disabled using glEnable and glDisable with argument GL_LIGHT i.

Name
glRotate — multiply the current matrix by a rotation matrix
C Specification
void glRotate GLdouble angl
d( e,
  GLdouble x,
  GLdouble y,
  GLdouble z);
 
void glRotate GLfloat angl
f( e,
  GLfloat x,
  GLfloat y,
  GLfloat z);
 
Parameters
angle
Specifies the angle of rotation, in degrees.
x, y, z
Specify the x, y, and z coordinates of a vector, respectively.
Description
glRotate produces a rotation of angle degrees around the vector x y z . The current
matrix (see glMatrixMode) is multiplied by a rotation matrix with the product
replacing the current matrix, as if glMultMatrix were called with the following matrix
as its argument:
x 2 ⁡ 1 - c + c x ⁢ y ⁡ 1 - c - z ⁢ s x ⁢ z ⁡ 1 - c + y ⁢ s 0 y ⁢ x ⁡ 1 - c + z ⁢ s y 2 ⁡ 1 - c + c y ⁢ z ⁡ 1 - c - x ⁢ s 0 
x ⁢ z ⁡ 1 - c - y ⁢ s y ⁢ z ⁡ 1 - c + x ⁢ s z 2 ⁡ 1 - c + c 0 0 0 0 1
7

Where c = cos ⁡ angle , s = sin ⁡ angle , and x y z = 1 (if not, the GL will normalize this


vector).
If the matrix mode is either GL_MODELVIEW or GL_PROJECTION, all objects
drawn after glRotate is called are rotated. Use glPushMatrix and glPopMatrix to save
and restore the unrotated coordinate system.
glTranslate — multiply the current matrix by a translation matrix
C Specification
void glTranslated
GLdouble x,
(
  GLdouble y,
GLdouble z
 
);
 
void glTranslatef
GLfloat x,
(
  GLfloat y,
GLfloat z)
 
;
 
Parameters
x, y, z
Specify the x, y, and z coordinates of a translation vector.
Description
glTranslate produces a translation by x y z . The current matrix (see glMatrixMode) is
multiplied by this translation matrix, with the product replacing the current matrix, as
if glMultMatrix were called with the following matrix for its argument:
1 0 0 x 0 1 0 y 0 0 1 z 0 0 0 1
If the matrix mode is either GL_MODELVIEW or GL_PROJECTION, all objects
drawn after a call to glTranslate are translated.
Use glPushMatrix and glPopMatrix to save and restore the untranslated coordinate
system.
8

РЕШЕНИЕ ПОСТАВЛЕННОЙ ЗАДАЧИ


МАШИННЫЙ ЛИСТИНГ
using System;
using System.ComponentModel;
using System.Data.Metadata.Edm;
using System.Drawing;
using System.Windows.Forms;

namespace glWinForm7
{
[ToolboxItem(true), ToolboxBitmap(typeof(RenderControl),
"RenderControl.bmp")]
public partial class RenderControl : OpenGL
{
private static double A = 0, B = 0, C = 0, D = 0;
bool canMove = false;
Point start;
double ax = 0;
double ay = 0;
double m = 1;
public uint mode = GLU_FILL;
private float WinWid = 10.0F;
private float WinHei = 10.0F;
bool clip = false;
double[] plane = new double[] { A, B, C, D };
bool onpers = false;

public bool OnPers


{
get
{
return onpers;
}
set
{
onpers = value;
Invalidate();
}
}
public uint Mode
{
get
{
return mode;
}
set
{
mode = value;
Invalidate();
}
}
public bool Clip
{
get
{
return clip;
}
9

set
{
clip = value;
Invalidate();
}
}
public double A1
{
get
{
return A;
}
set
{
A = value;
Invalidate();
}
}
public double B1
{
get
{
return B;
}
set
{
B = value;
Invalidate();
}
}
public double C1
{
get
{
return C;
}
set
{
C = value;
Invalidate();
}
}
public double D1
{
get
{
return D;
}
set
{
D = value;
Invalidate();
}
}
public RenderControl() : base(false)
{
InitializeComponent();
MouseWheel += RenderControl_MouseWheel;
10

}
private void RenderControl_MouseWheel(object sender, MouseEventArgs e)
{
m += (-e.Delta / 1000.0);
Invalidate();
}
public override void OnStartingOpenGL()
{
glClearColor(BackColor);
}
public override void OnFinishingOpenGL()
{
}
private void RenderControl_MouseDown(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
canMove = true;
start = e.Location;
}
if (e.Button == MouseButtons.Right)
{
mode = (mode == GL_FILL) ? GL_LINE : GL_FILL;
Invalidate();
}

}
private void RenderControl_MouseUp(object sender, MouseEventArgs e)
{
if (canMove && (e.Button == MouseButtons.Left))
canMove = false;
}
private void RenderControl_MouseMove(object sender, MouseEventArgs e)
{
if (canMove)
{
ax += (e.Location.Y - start.Y) / 2.0;
ay += (e.Location.X - start.X) / 2.0;
start = e.Location;
Invalidate();
}
}
public override void OnRender()
{
double size = 12;
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT |
GL_STENCIL_BUFFER_BIT);
glLoadIdentity();
glClearColor(Color.White);
glClear(GL_COLOR_BUFFER_BIT);

if (Width > Height)


glViewport((Width - Height) / 2, 0, Height, Height);
else
glViewport(0, (Height - Width) / 2, Width, Width);

glOrtho(-size, +size, -size, +size, -size, +size);


11

if (OnPers)
{
gluPerspective(45, Width / Height, -8, 0);
gluLookAt(4, 4, 4, 0, 0, 0, 0, 100, 0);
}

glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
float[] LitghtAmbient = new float[] { 0.25f, 0.25f, 0.25f, 1.0f };
float[] LitghtDiffuse = new float[] { 2.0f, 2.0f, 2.0f, 1.0f };
float[] LitghtSpecular = new float[] { 2.0f, 2.0f, 2.0f, 1.0f };
float[] LitghtPosition = new float[] { 2.5f, 2.5f, 2.5f, 1.0f };

glLightfv(GL_LIGHT0, GL_AMBIENT, LitghtAmbient);


glLightfv(GL_LIGHT0, GL_DIFFUSE, LitghtDiffuse);
glLightfv(GL_LIGHT0, GL_SPECULAR, LitghtSpecular);
glLightfv(GL_LIGHT0, GL_POSITION, LitghtPosition);

glEnable(GL_NORMALIZE);
glEnable(GL_COLOR_MATERIAL);

glShadeModel(GLU_FLAT);

glScaled(m, m, m);
glRotated(ax, 1, 0, 0);
glRotated(ay, 0, 1, 0);

glEnable(GL_DEPTH_TEST);

grid();
DrawAxes();
DrawSphere(mode);
DrawCon(mode);
DrawlDisk(mode);

glDisable(GL_DEPTH_TEST);
}

private void grid()


{
glColor(Color.Gray);
glLineWidth(0.1F);

glBegin(GL_LINES);

for (double ax = -10; ax < 10; ax += 1.0)


{
for (double bx = -10; bx < 10; bx += 1.0)
{
glVertex2d(ax + 1.0, WinHei);
glVertex2d(ax + 1.0, -WinHei);
glVertex2d(WinWid, -bx + 1.0);
glVertex2d(-WinWid, -bx + 1.0);
}
}
glEnd();
}
12

private void DrawAxes()


{
glLineWidth(2);
glColor3d(0, 0, 0);
glBegin(GL_LINES);
glVertex3d(-10, 0, 0); glVertex3d(10, 0, 0);
glVertex3d(0, -10, 0); glVertex3d(0, 10, 0);
glVertex3d(0, 0, -10); glVertex3d(0, 0, 10);
glEnd();

glColor(Color.Red);
OutText("X", 10.6, 0, 0);
OutText("Y", 0, 10.6, 0);
OutText("Z", 0, 0, 10.6);
}

private void DrawSphere(uint mode)


{

double radius = 2.5;


int slices = 10, stacks = 10;
IntPtr qobj;
qobj = gluNewQuadric();
double[] plane = new double[] { A, B, C, D };
glPushMatrix();
glColor(Color.BurlyWood);
gluQuadricDrawStyle(qobj, mode);
glTranslatef(-2.5f, 3f, 3f);

glClipPlane(GL_CLIP_PLANE0, plane);
if (Clip)
{
glEnable(GL_CLIP_PLANE0);
}
gluSphere(qobj, radius, slices, stacks);

glDisable(GL_CLIP_PLANE0);
glPopMatrix();

private void DrawCon(uint mode)


{
double radius = 2, r2 = 0, h = 1, angle = 90;
int slices = 10, stacks = 10;
IntPtr qobj1;
qobj1 = gluNewQuadric();
glPushMatrix();
glColor(Color.CadetBlue);
gluQuadricDrawStyle(qobj1, mode);

glTranslatef(+3.5f, +1f, -3.5f);//перемещение


glRotated(angle, 0, -1, 0);//поворот
gluCylinder(qobj1, radius, 0, h, slices, stacks);
glPopMatrix();
}
13

private void DrawlDisk(uint mode)


{

double radius = 2.5, r2 = 0, start = 90, sweep = 45, angle = 90;


int slices = 10, stacks = 10;
IntPtr qobj1;
qobj1 = gluNewQuadric();
glPushMatrix();
glColor(Color.DarkKhaki);
gluQuadricDrawStyle(qobj1, mode);
glTranslatef(-3.5f, -0.5f, -2.5f);
glRotated(angle, 1, 0, 0);
gluDisk(qobj1, r2, radius, slices, stacks);
glPopMatrix();

}
}
}
using System.Windows.Forms;

namespace glWinForm7
{
public partial class MainForm : Form
{
public MainForm()
{
InitializeComponent();
}
private void Mode(object sender, System.EventArgs e)
{
if (radioButton3.Checked)
{
renderControl1.Mode = RenderControl.GLU_FILL;
}
if (radioButton4.Checked)
{
renderControl1.Mode = RenderControl.GLU_LINE;
}
}
private void CheckBox1_CheckedChanged(object sender, System.EventArgs e)
{
renderControl1.Clip = checkBox1.Checked;
}

private void NumericUpDown1_ValueChanged(object sender, System.EventArgs


e)
{
this.renderControl1.A1 = (double)this.numericUpDown1.Value;
}

private void NumericUpDown2_ValueChanged(object sender, System.EventArgs


e)
{
this.renderControl1.B1 = (double)this.numericUpDown2.Value;
}
14

private void NumericUpDown3_ValueChanged(object sender, System.EventArgs


e)
{
this.renderControl1.B1 = (double)this.numericUpDown2.Value;
}

private void NumericUpDown4_ValueChanged(object sender, System.EventArgs


e)
{
this.renderControl1.D1 = (double)this.numericUpDown4.Value;
}

private void RadioButton2_CheckedChanged(object sender, System.EventArgs


e)
{
renderControl1.OnPers = radioButton2.Checked;
}
}
}
ЭКРАННАЯ ФОРМА

ТРЕБОВАНИЯ
№ Сложность Требования Баллы
1 Базовый Корректное (изотропное) отображение задания (при 1
изменении размеров окна) в ортографической проекции
2 При запуске приложения отображаются оси 0X, 0Y, 0Z, 1
координатная сетка и каркас квадратичных объектов
3 Интерфейс управления параметрами плоскости отсечения 1
4 Использование источников света для освещения объектов 1
сцены совместно с командой glColorMaterial
5 Создание изображения сцены в перспективной проекции 1
15

ВЫВОД: в данной лабораторной работе научился работать с трехмерными


графическими примитивами OpenGL и применять аффинные преобразования
для размещения объектов в пространстве.

Вам также может понравиться