Скачиваний:
82
Добавлен:
16.07.2022
Размер:
1.8 Mб
Скачать
    1. Реализация метода последовательной отрисовки

Алгоритм последовательной отрисовки уже приводился на рисунке 1.4. При переводе его в программный код, к примеру, функции отрисовки окружности, получится следующий код:

void gfCircle(int32 x, int32 y, int32 radius) {

float32 circleCoords[circlePred * 2 + 2];

int32 i;

circleCoords[0] = x / (ww / 2.f);

circleCoords[1] = y / (wh / 2.f);

for (i = 1; i < circlePred + 1; ++i) {

circleCoords[2 * i] =

(x + (mfCos(360.f/circlePred * i)*radius))/(ww/2.f);

circleCoords[2 * i + 1] =

(y + (mfSin(360.f/circlePred * i)*radius))/(wh/2.f);

}

circleCoords[(circlePred + 1) * 2] = circleCoords[2];

circleCoords[(circlePred + 1) * 2 + 1] = circleCoords[3];

glVertexPointer(2, GL_FLOAT, 0, &circleCoords[2]);

glDrawArrays(GL_LINE_LOOP, 0, circlePred);

}

Функция gfCircle принимает на вход 3 целочисленных параметра – координаты центра окружности и её радиус.

В начале выполнения функции создаётся массив для хранения координат окружности – circleCoords. Размер массива зависит от заданного количества отрезков, которыми рисуется окружность.

Далее в цикле происходит расчёт координат окружности и запись этих координат в массив circleCoords.

После расчёта всех координат с помощью функций glVertexPointer и glDrawArrays происходит отправка данных на графический процессор и отрисовка примитивов (в данном случае - закольцованной последовательности отрезков) в кадровый буфер.

    1. Реализация метода единовременной отрисовки

Алгоритм единовременной отрисовки приведён на рисунке 1.5. Функция реализации отрисовки окружности будет практически такой же, за исключением нескольких моментов:

  • Массив координат будет создан до вызова функции и не будет локальной переменной данной функции

  • Рассчитанные координаты будут помещены в этот общий массив координат и переданы на ГП только в конце расчёта кадра, либо в момент максимального заполнения буфера

Код функции отрисовки окружности при единовременной отрисовке:

float32 Points[PointsCount][3];

float32 PointColors[PointsCount][4];

void gfCircle(int32 x, int32 y, int32 radius) {

int32 i;

struct Vertexf center = {x, y};

struct Vertexf circleCoords[2] =

{{center.x + radius, center.y}, {0, 0}};

struct Vertexf edgingCoords[2] =

{{center.x + radius + edgingWidth, center.y}, {0, 0}};

for (i = 1; i <= circlePred; ++i) {

circleCoords[1].x = center.x + mfCos(360.f / circlePred * i) * radius;

circleCoords[1].y =

center.y + mfSin(360.f / circlePred * i) * radius;

gfLine(circleCoords[0].x, circleCoords[0].y, circleCoords[1].x, circleCoords[1].y);

--currentDepth;

circleCoords[0] = circleCoords[1];

}

++currentDepth;

}

В данном случае после расчёта координат очередного отрезка окружности вызывается функция отрисовки линии:

void gfLine(int32 x1, int32 y1, int32 x2, int32 y2) {

struct Vertexf points[2] = {{x1, y1}, {x2, y2}};

pushLine(points[0], points[1]);

++currentDepth;

}

Функция pushLine, вызываемая в функции отрисовки линии, помещает координаты рисуемого отрезка в массив Points, а цвет координат – в массив PointColors. В конце цикла формирования кадра эти массивы отправляются на видеокарту функциями glVertexPointer, glColorPointer и glDrawArrays.