|
Подскажите, пожалуйста, планируете ли вы возобновление программ высшего образования? Если да, есть ли какие-то примерные сроки? Спасибо! |
Устранение эффекта ступенчатости
Ниже приведено содержание модуля на Object Pascal, который содержит процедуры, выполняющие операции аналогичные классу Jitter на C# ( пример 11.2).
unit Jitter;
interface
uses OpenGL;
Type
TGLPointFloat = record
x,y: GLFloat;
End;
const
j2: array[0..1] of TGLPointFloat =
((x: 0.246490; y: 0.249999), (x: -0.246490; y: -0.249999));
j3: array[0..2] of TGLPointFloat =
((x: -0.373411; y: -0.250550), (x: 0.256263; y: 0.368119),
(x: 0.117148; y: -0.117570));
j4: array[0..3] of TGLPointFloat =
((x: -0.208147; y: 0.353730), (x: 0.203849; y: -0.353780),
(x: -0.292626; y: -0.149945), (x: 0.296924; y: 0.149994));
j8: array[0..7] of TGLPointFloat =
((x: -0.334818; y: 0.435331), (x: 0.286438; y: -0.393495),
(x: 0.459462; y: 0.141540), (x: -0.414498; y: -0.192829),
(x: -0.183790; y: 0.082102), (x: -0.079263; y: -0.317383),
(x: 0.102254; y: 0.299133), (x: 0.164216; y: -0.054399));
procedure AccFrustum(left,right,bottom,top: GLdouble; anear,afar,pdx,pdy: GLdouble);
procedure AccOrtho(left, right, bottom, top: GLdouble; anear, afar, pdx, pdy: GLdouble);
Implementation
procedure AccFrustum(left, right, bottom, top: GLdouble; anear, afar, pdx, pdy: GLdouble);
var
xwsize, ywsize: GLdouble;
dx, dy: GLdouble;
viewport: array[0..3] of GLint;
begin
glGetIntegerv (GL_VIEWPORT, @viewport);
xwsize := right - left;
ywsize := top - bottom;
dx := -(pdx*xwsize/viewport[2]);
dy := -(pdy*ywsize/viewport[3]);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glFrustum (left + dx, right + dx, bottom + dy, top + dy, anear, afar);
glMatrixMode(GL_MODELVIEW);
end;
procedure AccOrtho(left, right, bottom, top: GLdouble; anear, afar, pdx, pdy: GLdouble);
var
xwsize, ywsize : GLdouble;
dx, dy: GLdouble;
viewport: array[0..3] of GLint;
begin
glGetIntegerv (GL_VIEWPORT, @viewport);
xwsize := right - left;
ywsize := top - bottom;
dx := -(pdx*xwsize/viewport[2]);
dy := -(pdy*ywsize/viewport[3]);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(left + dx, right + dx, bottom + dy, top + dy, anear, afar);
glMatrixMode(GL_MODELVIEW);
end;
end.
Листинг
11.2.
Исходный текст модуля Jitter.pas
Для управления буфером аккумулятора используется команда Accum.
C#: void Accum(AccumOp op, float value); Object Pascal: procedure glAccum (op: GLenum; value: GLfloat);
Аргумент op определяет операцию, выполняемую над буфером, а параметр value – число, которое будет использоваться в этой операции. Возможные значения параметра op приведены в таблица 11.1.
В листинге 11.3 приведен фрагмент программы с использованием метода AccOrtho класса Jitter для формирования ортографической проекции сцены на языке программирования C#.
void DrawObjects()
{
// формирование изображения
GL.Enable(EnableCap.Lighting);
GL.Enable(EnableCap.Light0);
sphere(0.5, 20, 20);
GL.Disable(EnableCap.Lighting);
// завершение формирования изображения
}
void DrawScene(Jitter.PointPloat[] j)
{
GL.Clear(ClearBufferMask.AccumBufferBit);
for (int i = 0; i< j.Length-1; ++i)
{
GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit);
Jitter.AccOrtho(-1, 1, -1, 1, -1, 1, j[i].X, j[i].Y);
DrawObjects();
GL.Accum(AccumOp.Accum, 1.0f/j.Length);
}
GL.Accum(AccumOp.Return, 1.0f);
}
private void glControl1_Paint(object sender, PaintEventArgs e)
{
// очистка буферов цвета и глубины
GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit);
// поворот изображения
GL.LoadIdentity();
GL.Rotate(AngleX, 1.0, 0.0, 0.0);
GL.Rotate(AngleY, 0.0, 1.0, 0.0);
GL.Rotate(AngleZ, 0.0, 0.0, 1.0);
DrawScene(Jitter.j8);
GL.Flush();
GL.Finish();
glControl1.SwapBuffers();
}
Листинг
11.3.
Пример устранения эффекта ступенчатости на C# с использованием библиотеки OpenTK
В методе DrawScene вызывается метод DrawObjects, который должен формировать отображаемые объекты в видимой области сцены.
В листинге 11.4 приведен фрагмент программы с использованием процедуры AccOrtho для формирования ортографической проекции сцены на языке программирования Object Pascal.
procedure TForm1.DrawScene(j: array of TGLPointFloat);
var
i: Integer;
begin
glClear(GL_ACCUM_BUFFER_BIT);
for I := 0 to High(j) do
begin
glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);
AccOrtho(-2, 2, -2, 2, -2, 2, j[i].x, j[i].y);
DrawObjects;
glAccum(GL_ACCUM, 1.0/(High(j)+1));
end;
glAccum (GL_RETURN, 1.0);
end;
procedure TForm1.FormPaint(Sender: TObject);
begin
// очистка буфера цвета
glClear (GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT); glLoadIdentity;
// этот фрагмент нужен для придания трёхмерности
glRotatef(AngleX, 1.0, 0.0, 0.0);
glRotatef(AngleY, 0.0, 1.0, 0.0);
glRotatef(AngleZ, 0.0, 0.0, 1.0);
DrawScene(j8);
glFlush;
glFinish;
SwapBuffers(DC);
end;
procedure TForm1.DrawObjects;
begin
// формирование изображения
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
sphere(0.5, 20, 20);
glDisable(GL_LIGHTING);
// завершение формирования изображения
end;
Листинг
11.4.
Пример устранения эффекта ступенчатости на Object Pascal
Краткие итоги
Несмотря на то, что у примитивов есть ряд параметров, которые позволяют изменять визуальное качество изображения, но они не позволяют устанить эффект ступенчатости в изображении объектов сцены.
Для решения этой проблемы обычно применяется эффект "джиттеринга", для реализации которого используется буфер аккумулятора.
Изображение сцены формируется несколько раз с уменьшенной интенсивностью составляющих цвета в буфере аккумулятора и с некоторым смещением относительно реального положения объектов сцены. Результат "накапливается" в буфере аккумулятора и затем копируется в отображаемый буфер.
Для работы с буфером аккумурятора используется команда Accum.