Как заполнить многоугольник разного цвета, чем границы?

Мне нужно нарисовать многоугольник, который имеет граничные линии с одним цветом и заполняет интерьер другим цветом. Есть простой способ сделать это? В настоящее время я рисую два многоугольника один для внутреннего цвета и 1 для границы. Я думаю, что лучше сделать это. Благодарим за помощь.

       glColor3d (1, 1., .7);
        glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
        glBegin(GL_TRIANGLES);
                glVertex3f(-0.8f, 0.0f, 0.0f);
                glVertex3f(-0.6f, 0.0f, 0.0f);
                glVertex3f(-0.7f, 0.2f, 0.0f);
        glEnd();

        glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
        glColor3d (.5, .5, .7);
        glBegin(GL_TRIANGLES);
                glVertex3f(-0.8f, 0.0f, 0.0f);
                glVertex3f(-0.6f, 0.0f, 0.0f);
                glVertex3f(-0.7f, 0.2f, 0.0f);
        glEnd();

Спасибо всем за ответ на мой вопрос. Я новичок в openGL и искал простой ответ на простой вопрос. Ответ кажется не таким простым и, вероятно, может занять семестр.

Ответ 1

Более современным подходом было бы реализовать это через геометрические шейдеры. Это будет работать для OpenGL 3.2 и выше как часть основной функциональности или для OpenGL 2.1 с расширением GL_EXT_geometry_shader4.

В этой статье есть вся соответствующая теория: Рисунок каркаса на основе шейдеров. Он также предоставляет примерную реализацию простейшего метода в GLSL.

Вот мой собственный удар по нему, в основном порт их реализации для OpenGL 3.3, ограниченный примитивами треугольника:

Vertex shader: (замените входы тем, что вы используете для передачи в данных вершин, матриц m, v и p)

#version 330

layout(location = 0) in vec4 position;
layout(location = 1) in mat4 mv;

out Data
{
    vec4 position;
} vdata;

uniform mat4 projection;

void main()
{
    vdata.position = projection * mv * position;
}

Геометрический шейдер:

#version 330
layout(triangles) in;
layout(triangle_strip, max_vertices = 3) out;

in Data
{
    vec4 position;
} vdata[3];

out Data
{
    noperspective out vec3 dist;
} gdata;

void main()
{
    vec2 scale = vec2(500.0f, 500.0f); // scaling factor to make 'd' in frag shader big enough to show something
    vec2 p0 = scale * vdata[0].position.xy/vdata[0].position.w;
    vec2 p1 = scale * vdata[1].position.xy/vdata[1].position.w;
    vec2 p2 = scale * vdata[2].position.xy/vdata[2].position.w;

    vec2 v0 = p2-p1;
    vec2 v1 = p2-p0;
    vec2 v2 = p1-p0;
    float area = abs(v1.x*v2.y - v1.y*v2.x);

    gdata.dist = vec3(area/length(v0),0,0);
    gl_Position = vdata[0].position;
    EmitVertex();

    gdata.dist = vec3(0,area/length(v1),0);
    gl_Position = vdata[1].position;
    EmitVertex();

    gdata.dist = vec3(0,0,area/length(v2));
    gl_Position = vdata[2].position;
    EmitVertex();

    EndPrimitive();
}

Vertex shader: (замените цвета тем, что вам нужно!)

#version 330

in Data
{
    noperspective in vec3 dist;
} gdata;

out vec4 outputColor;

uniform sampler2D tex;

const vec4 wireframeColor = vec4(1.0f, 0.0f, 0.0f, 1.0f);
const vec4 fillColor = vec4(1.0f, 1.0f, 1.0f, 1.0f);

void main()
{
    float d = min(gdata.dist.x, min(gdata.dist.y, gdata.dist.z));
    float I = exp2(-2*d*d);
    outputColor = mix(fillColor, wireframeColor, I);
}

Ответ 2

Вы можете переключить режим заполнения между полигонами, линиями и точками, используя glPolygonMode.

Чтобы рисовать многоугольные линии разного цвета, вы можете сделать следующее:

glPolygonMode(GL_FRONT_AND_BACK,GL_FILL);
draw_mesh( fill_color );
glPolygonMode(GL_FRONT_AND_BACK,GL_LINE);
glEnable(GL_POLYGON_OFFSET_LINE);
glPolygonOffset(-1.f,-1.f);
draw_mesh( line_color );

Может потребоваться смещение линии, поскольку OpenGL не гарантирует, что края многоугольников будут растеризованы в тех же пикселях, что и линии. Таким образом, без явного смещения вы можете и вверх по линиям, скрытым полигонами, из-за неудачной проверки глубины.

Ответ 3

Есть два способа сделать это:

  • тот, который вы делаете в данный момент (2 многоугольника, один немного больше другого или нарисованный после)

  • текстуры

Насколько мне известно, других возможностей нет, и с точки зрения производительности эти две возможности, особенно первая, до тех пор, пока вы только заполняете цветом, очень быстры.

Ответ 4

Я думаю, вы должны увидеть этот ответ: заполнить и очертить

сначала нарисуйте треугольник, используя glPolygonMode (GL_FRONT_AND_BACK, GL_FILL) и используйте желаемый цвет. затем снова нарисуйте треугольник, используя glPolygonMode (GL_FRONT_AND_BACK, GL_LINE) с использованием цвета контуров.