Подскажите, пожалуйста, планируете ли вы возобновление программ высшего образования? Если да, есть ли какие-то примерные сроки? Спасибо! |
Устранение эффекта ступенчатости
Ниже приведено содержание модуля на 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.