отсутствует возврат в функции, которая, как ожидается, вернет 'Double' | Что делать?

Предполагая, что в OpenGL 3 и выше есть перекрестно-совместимый контекст, вы можете использовать glPolygonMode, как упоминалось ранее, но обратите внимание, что строки с толщиной более 1px теперь устарели. Поэтому, пока вы можете рисовать треугольники как проволочные рамки, они должны быть очень тонкими. В OpenGL ES вы можете использовать GL_LINES с тем же ограничением.

В OpenGL можно использовать геометрические шейдеры, чтобы принимать входящие треугольники, дизассемблировать их и отправлять их для растеризации как квадранты (пары треугольников действительно ), эмулируя толстые линии. Довольно просто, правда, за исключением того, что геометрические шейдеры печально известны плохим масштабированием производительности.

Что вы можете сделать вместо этого, и что также будет работать в OpenGL ES, это использовать шейдер фрагмент . Подумайте о применении текстуры треугольника с проволочной рамкой к треугольнику. За исключением того, что текстуры не нужны, ее можно создать процедурно. Но достаточно поговорим, давайте сделаем код. Фрагментный шейдер:

in vec3 v_barycentric; // barycentric coordinate inside the triangle
uniform float f_thickness; // thickness of the rendered lines

void main()
{
    float f_closest_edge = min(v_barycentric.x,
        min(v_barycentric.y, v_barycentric.z)); // see to which edge this pixel is the closest
    float f_width = fwidth(f_closest_edge); // calculate derivative (divide f_thickness by this to have the line width constant in screen-space)
    float f_alpha = smoothstep(f_thickness, f_thickness + f_width, f_closest_edge); // calculate alpha
    gl_FragColor = vec4(vec3(.0), f_alpha);
}

И вершинный шейдер:

in vec4 v_pos; // position of the vertices
in vec3 v_bc; // barycentric coordinate inside the triangle

out vec3 v_barycentric; // barycentric coordinate inside the triangle

uniform mat4 t_mvp; // modeview-projection matrix

void main()
{
    gl_Position = t_mvp * v_pos;
    v_barycentric = v_bc; // just pass it on
}

Здесь барицентрические координаты - это просто (1, 0, 0), (0, 1, 0) и (0, 0, 1) для трех треугольных вершин (порядок не имеет значения, что делает упаковку на треугольные полосы потенциально проще).

Очевидным недостатком этого подхода является то, что он будет есть некоторые координаты текстуры, и вам нужно изменить массив вершин. Может быть решена с помощью очень простого геометрического шейдера, но я все же подозреваю, что он будет медленнее, чем просто загрузка GPU с большим количеством данных.

0
задан rmaddy 19 March 2019 в 19:33
поделиться

1 ответ

Проблема в том, что в вашем операторе if отсутствует блок else, возвращаемое значение не определено для случая, когда self == 0. Вы можете просто изменить ветку else if на else, потому что вы также хотите вернуть self для 0.

var absoluteValue: Double {
    if self < 0 {
        return self * -1
    } else {
        return self
    }
}

Вы также можете написать это как однонаправленный, используя троичный оператор:

var absoluteValue: Double {
    return self < 0 ? self * -1 : self
}
0
ответ дан Dávid Pásztor 19 March 2019 в 19:33
поделиться
Другие вопросы по тегам:

Похожие вопросы: