如何在OpenGL中将基元渲染为线框?

How do you render primitives as wireframes in OpenGL?

如何在OpenGL中将基本体渲染为线框?


1
glPolygonMode( GL_FRONT_AND_BACK, GL_LINE );

一个开关,

1
glPolygonMode( GL_FRONT_AND_BACK, GL_FILL );

去回到正常。

注意,这样纹理映射和照明负载应用到线框保持安静,如果他们连接线,它可以看起来奇怪。


从http:/ / / / index.pl cone3d.gamedev.net的CGI斌?ogladv =教程/页/ tut5

1
2
3
4
5
6
7
8
9
10
// Turn on wireframe mode
glPolygonMode(GL_FRONT, GL_LINE);
glPolygonMode(GL_BACK, GL_LINE);

// Draw the box
DrawBox();

// Turn off wireframe mode
glPolygonMode(GL_FRONT, GL_FILL);
glPolygonMode(GL_BACK, GL_FILL);


如果a前向兼容OpenGL上下文中3和化妆,你可以使用之前提到glPolygonMode是AS,但注意一个1px的线层比现在是过时的。因此,你可以画三角形线框一样,他们需要非常瘦。在OpenGL ES的,你可以使用一个GL_LINES一样的限制。

在OpenGL中使用它是可能的,以输入的三角形几何shaders拆卸,他们给他们的四边形(三角形光栅化为对emulating厚线(真的)。很简单,真的,但那是臭名昭著的shaders几何缩放性能差。

你可以做的好,所以我想和OpenGL ES是雇用工作中的片段着色器。想申请大学A线框纹理三角形到三角形。除了没有纹理是必要的,它可以生成procedurally。但足够的谈话,让我们的代码。片段着色器。

1
2
3
4
5
6
7
8
9
10
11
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);
}

和顶点着色器。

1
2
3
4
5
6
7
8
9
10
11
12
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)barycentric坐标,(0, 1, 0)(0, 0, 1)的三角顶点(三阶不真物,这使得更容易为三角带包装的挑战。

本方法的缺点是显而易见的,它要吃一些纹理坐标和你需要修改你的顶点数组。可能是我一个非常简单的几何着色器,但我怀疑它会悄悄的将不只是更多的GPU和喂养的数据。


这是最简单的方式为GL_LINE_STRIP推拉。

1
2
3
glBegin(GL_LINE_STRIP);
/* Draw vertices here */
glEnd();


如果你是使用固定管道(OpenGL(3.3)或您可以使用兼容剖面

1
2
3
4
5
6
7
8
//Turn on wireframe mode
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);

//Draw the scene with polygons as lines (wireframe)
renderScene();

//Turn off wireframe mode
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);

本案例中,你可以通过调用gllinewidth线宽度的变化

如果你需要改变多边形的绘制方法(gldrawelements模式里面,你可以gldrawarrays等),最终的结果,因为有一些粗糙的三角形和顶点数据是你的输出线。最好的结果是通过使用几何着色器的数据或创建新的线框。


在现代(OpenGL和OpenGL 3.2高等),你可以使用几何着色器本:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#version 330

layout (triangles) in;
layout (line_strip /*for lines, use"points" for points*/, max_vertices=3) out;

in vec2 texcoords_pass[]; //Texcoords from Vertex Shader
in vec3 normals_pass[]; //Normals from Vertex Shader

out vec3 normals; //Normals for Fragment Shader
out vec2 texcoords; //Texcoords for Fragment Shader

void main(void)
{
    int i;
    for (i = 0; i < gl_in.length(); i++)
    {
        texcoords=texcoords_pass[i]; //Pass through
        normals=normals_pass[i]; //Pass through
        gl_Position = gl_in[i].gl_Position; //Pass through
        EmitVertex();
    }
    EndPrimitive();
}

注意事项:

  • 为改变一点,layout (line_strip, max_vertices=3) out;layout (points, max_vertices=3) out;
  • 阅读更多关于几何shaders


你可以使用这样的GLUT库:

  • 一个球:

    1
    glutWireSphere(radius,20,20);
  • 一个缸:

    1
    2
    3
    GLUquadric *quadratic = gluNewQuadric();
    gluQuadricDrawStyle(quadratic,GLU_LINE);
    gluCylinder(quadratic,1,1,1,12,1);
  • 一个立方体:

    1
    glutWireCube(1.5);

  • 如果它的OpenGL ES 2.0与你交易,你可以选择从一个常数绘制模式

    GL_LINE_STRIP, GL_LINE_LOOP, GL_LINES,到画线,

    GL_POINTS(如果你需要绘制的顶点,或只读)

    GL_TRIANGLE_STRIPGL_TRIANGLE_FANto draw,三角形,和GL_TRIANGLES钢管混凝土

    第一个参数是你的

    1
    glDrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid * indices)

    glDrawArrays(GLenum mode, GLint first, GLsizei count)调用。