【问题标题】:How to fill polygon with different color than boundary?如何用与边界不同的颜色填充多边形?
【发布时间】:2011-02-28 18:49:38
【问题描述】:

我需要绘制一个具有一种颜色的边界线并用另一种颜色填充内部的多边形。是否有捷径可寻 ?我目前绘制了两个多边形,一个用于内部颜色,一个用于边界。我认为必须有更好的方法来做到这一点。感谢您的帮助。

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相当陌生,正在寻找一个简单问题的简单答案。答案似乎没有那么简单,可能需要花一个学期的时间来学习。

【问题讨论】:

    标签: c opengl


    【解决方案1】:

    更现代的方法是通过几何着色器来实现这一点。这将适用于作为核心功能的一部分的 OpenGL 3.2 及更高版本,或者适用于扩展名为 GL_EXT_geometry_shader4 的 OpenGL 2.1。

    本文有所有相关理论:Shader-Based wireframe drawing。它还提供了 GLSL 中最简单技术的示例实现。

    这是我自己的尝试,基本上是他们为 OpenGL 3.3 实现的一个端口,仅限于三角形基元:

    顶点着色器:(将输入替换为您用于传递顶点数据和 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();
    }
    

    顶点着色器:(用您需要的任何颜色替换颜色!)

    #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 不保证多边形的边缘将被光栅化为与线完全相同的像素。因此,如果没有明确的偏移,由于深度测试失败,您可能会被多边形隐藏线。

      【讨论】:

      • 这个方法不是和我做的一样吗?看起来网格被绘制了两次。我错了吗?
      • @蝌蚪。您写道,您正在绘制 2 个多边形。我假设您两次覆盖内部多边形区域,这会使光栅化器上的负载加倍。我的建议是调用两次绘制过程,为 GL 设置不同的填充模式。
      • 我认为我们在谈论同样的事情。我更新了问题以包含我的代码。我希望不必那样做。这只是一个简单的多边形,但真正的代码可能包含数亿到数百万个多边形。
      • @蝌蚪。哦,这是一个定义更好的问题 :) 在这种情况下,请考虑阅读 www2.imm.dtu.dk/pubdb/views/edoc_download.php/4884/pdf/…
      【解决方案3】:

      有两种方法可以做到这一点:

      • 你现在做的那个(2个多边形,一个比另一个大一点或者在后面绘制)

      • 纹理

      据我所知,没有其他可能性,从性能的角度来看,这两种可能性,尤其是第一种可能性,只要您只进行颜色填充,速度非常快。

      【讨论】:

        【解决方案4】:

        我认为你应该看到这个答案: fill and outline

        首先使用 glPolygonMode(GL_FRONT_AND_BACK,GL_FILL) 并使用您想要的颜色。 然后使用再次绘制三角形 glPolygonMode(GL_FRONT_AND_BACK,GL_LINE) 使用你的轮廓颜色。

        【讨论】:

          猜你喜欢
          • 2013-04-20
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2013-02-21
          相关资源
          最近更新 更多