How to fill polygon with different color than boundary?

前端 未结 4 2313
暗喜
暗喜 2021-02-20 09:11

I need to draw a polygon that has the boundary lines with one color and fill the interior with another color. Is there an easy way to do this ? I currently draw two polygon

4条回答
  •  刺人心
    刺人心 (楼主)
    2021-02-20 09:47

    A more modern approach would be to implement this via geometry shaders. This would work for OpenGL 3.2 and above as part of the core functionality, or for OpenGL 2.1 with extension GL_EXT_geometry_shader4.

    This paper has all the relevant theory : Shader-Based wireframe drawing. It also provides a sample implementation of the simplest technique in GLSL.

    Here is my own stab at it, basically a port of their implementation for OpenGL 3.3, limited to triangle primitives:

    Vertex shader: (replace the inputs with whatever you use to pass in vertex data an m, v and p matrices)

    #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;
    }
    

    Geometry shader:

    #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: (replace the colors with whatever you needed !)

    #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);
    }
    

提交回复
热议问题