Можно ли оптимизировать этот алгоритм рисования линий? - SDL

Для проекта, над которым я работал, возможность рисовать линии с градиентом (т.е. они меняют цвет в течение интервала, который они рисуют) была бы очень полезна. У меня есть алгоритм для этого, как я вставлю ниже, но он оказывается УЖАСНО медленным. Я использую алгоритм Брезенхэма, чтобы найти каждую точку, но боюсь, что я достиг пределов программного рендеринга. До сих пор я использовал SDL2, и мой алгоритм рисования линий выглядит в 200 раз медленнее, чемSDL_RenderDrawLine, Это приблизительная оценка, полученная из сравнения времен двух функций, чтобы нарисовать 10000 линий. Моя функция займет около 500 мс, иSDL_RenderDrawLine сделал это за 2-3мс на моей машине. Я даже протестировал функции с горизонтальными линиями, чтобы убедиться, что это не просто неуклюжий алгоритм Брезенхэма, и заштрихована похожая медленность. К сожалению, SDL не имеет API для рисования линий с градиентом (или, если он есть, я слепой). Я знал, что любой программный рендеринг будет значительно медленнее, чем аппаратный, но сдвиговая величина медлительности застала меня врасплох. Есть ли способ, который можно использовать для ускорения этого? Я только что испортил систему рисования без причины? Я подумал о том, чтобы сохранить массив пикселей, которые я хочу нарисовать, и затем сразу же перенести их на экран, но я не знаю, как это сделать с SDL2, и я не могу найти API в вики. или документация, которая позволяет это. Будет ли это даже быстрее?

Спасибо за внимание!

void DRW_LineGradient(SDL_Renderer* rend, SDL_Color c1, int x1, int y1, SDL_Color c2, int x2, int y2){
Uint8 tmpr, tmpg, tmpb, tmpa;
SDL_GetRenderDrawColor(rend, &tmpr, &tmpg, &tmpb, &tmpa);

int dy = y2 - y1;
int dx = x2 - x1;

/* Use doubles for a simple gradient */
double d = (abs(x1 - x2) > abs(y1 - y2) ? abs(x1 - x2) : abs(y1 - y2));
double dr = (c2.r - c1.r) / d;
double dg = (c2.g - c1.g) / d;
double db = (c2.b - c1.b) / d;
double da = (c2.a - c1.a) / d;

double r = c1.r, g = c1.g, b = c1.b, a = c1.a;

/* The line is vertical */
if (dx == 0) {
    int y;
    if (y2 >= y1) {
        for (y = y1; y <= y2; y++) {
            SDL_SetRenderDrawColor(rend, r, g, b, a);
            SDL_RenderDrawPoint(rend, x1, y);
            r += dr;
            g += dg;
            b += db;
            a += da;
        }
        return;
    }
    else{
        for (y = y1; y >= y2; y--) {
            SDL_SetRenderDrawColor(rend, r, g, b, a);
            SDL_RenderDrawPoint(rend, x1, y);

            r += dr;
            g += dg;
            b += db;
            a += da;
        }
        return;
    }
}
/* The line is horizontal */
if (dy == 0) {
    int x;
    if (x2 >= x1) {
        for (x = x1; x <= x2; x++) {
            SDL_SetRenderDrawColor(rend, r, g, b, a);
            SDL_RenderDrawPoint(rend, x, y1);
            r += dr;
            g += dg;
            b += db;
            a += da;
        }
        return;
    }
    else{
        for (x = x1; x >= x2; x--) {
            SDL_SetRenderDrawColor(rend, r, g, b, a);
            SDL_RenderDrawPoint(rend, x, y1);

            r += dr;
            g += dg;
            b += db;
            a += da;
        }
        return;
    }
}
/* The line has a slope of 1 or -1 */
if (abs(dy) == abs(dx)) {
    int xmult = 1, ymult = 1;
    if (dx < 0) {
        xmult = -1;
    }
    if (dy < 0) {
        ymult = -1;
    }
    int x = x1, y = y1;
    do {
        SDL_SetRenderDrawColor(rend, r, g, b, a);
        SDL_RenderDrawPoint(rend, x, y);
        x += xmult;
        y += ymult;
        r += dr;
        g += dg;
        b += db;
        a += da;
    } while (x != x2);
    return;
}

/* Use bresenham's algorithm to render the line */

int checky = dx >> 1;
int octant = findOctant((Line){x1, y1, x2, y2, dx, dy});

dy = abs(dy);
dx = abs(dx);
x2 = abs(x2 - x1) + x1;
y2 = abs(y2 - y1) + y1;

if (octant == 1 || octant == 2 || octant == 5 || octant == 6) {
    int tmp = dy;
    dy = dx;
    dx = tmp;
}

int x, y = 0;
for (x = 0; x <= dx; x++) {
    SDL_SetRenderDrawColor(rend, r, g, b, a);
    switch (octant) {
        case 0:
            SDL_RenderDrawPoint(rend, x + x1, y + y1);
            break;
        case 1:
            SDL_RenderDrawPoint(rend, y + x1, x + y1);
            break;
        case 2:
            SDL_RenderDrawPoint(rend, -y + x1, x + y1);
            break;
        case 3:
            SDL_RenderDrawPoint(rend, -x + x1, y + y1);
            break;
        case 4:
            SDL_RenderDrawPoint(rend, -x + x1, -y + y1);
            break;
        case 5:
            SDL_RenderDrawPoint(rend, -y + x1, -x + y1);
            break;
        case 6:
            SDL_RenderDrawPoint(rend, y + x1, -x + y1);
            break;
        case 7:
            SDL_RenderDrawPoint(rend, x + x1, -y + y1);
            break;
        default:
            break;
    }

    checky += dy;
    if (checky >= dx) {
        checky -= dx;
        y++;
    }

    r += dr;
    g += dg;
    b += db;
    a += da;
}

SDL_SetRenderDrawColor(rend, tmpr, tmpg, tmpb, tmpa);
}

ПРИМЕЧАНИЕ:

Я неохотно просто перехожу к использованию OpenGL 3.0+ (который, как я слышал, поддерживает SDL2), потому что я не знаю, как его использовать. Большинство учебных пособий, которые я нашел, объясняли процесс настройки контекстов с помощью SDL, а затем окрашивали экран одним сплошным цветом, но затем остановились, прежде чем объяснять, как рисовать фигуры и тому подобное. Если бы кто-то мог предложить хорошее место, чтобы начать узнавать об этом, это также было бы чрезвычайно полезно.

Ответы на вопрос(1)

Ваш ответ на вопрос