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

时间:2008-09-26 03:39:30

标签: opengl

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

10 个答案:

答案 0 :(得分:333)

glPolygonMode( GL_FRONT_AND_BACK, GL_LINE );

开启,

glPolygonMode( GL_FRONT_AND_BACK, GL_FILL );

恢复正常。

请注意,如果启用了线框线,纹理映射和光照等内容仍将应用于线框线,这看起来很奇怪。

答案 1 :(得分:30)

来自http://cone3d.gamedev.net/cgi-bin/index.pl?page=tutorials/ogladv/tut5

// 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);

答案 2 :(得分:18)

假设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提供更多数据更慢。

答案 3 :(得分:5)

最简单的方法是将基元绘制为GL_LINE_STRIP

glBegin(GL_LINE_STRIP);
/* Draw vertices here */
glEnd();

答案 4 :(得分:4)

如果您使用的是固定管道(OpenGL< 3.3)或兼容性配置文件,则可以使用

//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

来更改线宽

否则你需要在draw方法中改变多边形模式(glDrawElements,glDrawArrays等),你可能会得到一些粗略的结果,因为你的顶点数据是针对三角形而你正在输出线条。为获得最佳效果,请考虑使用Geometry shader或为线框创建新数据。

答案 5 :(得分:1)

您可以使用这样的过量库:

  1. 表示球体:

    glutWireSphere(radius,20,20);
    
  2. 对于圆柱:

    GLUquadric *quadratic = gluNewQuadric();
    gluQuadricDrawStyle(quadratic,GLU_LINE);
    gluCylinder(quadratic,1,1,1,12,1);
    
  3. 表示立方体:

    glutWireCube(1.5);
    

答案 6 :(得分:1)

在Modern OpenGL(OpenGL 3.2及更高版本)中,您可以使用几何着色器:

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

通知:

答案 7 :(得分:0)

如果您正在处理 OpenGL ES 2.0 ,您可以从

中选择一种绘制模式常量

GL_LINE_STRIP, GL_LINE_LOOP, GL_LINES,画线,

GL_POINTS(如果您只需要绘制顶点)或

GL_TRIANGLE_STRIPGL_TRIANGLE_FANGL_TRIANGLES绘制实心三角形

作为

的第一个参数
glDrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid * indices)

glDrawArrays(GLenum mode, GLint first, GLsizei count)来电。

答案 8 :(得分:0)

在非抗锯齿渲染目标上绘制抗锯齿线的一种好简单方法是绘制具有1x4纹理,alpha通道值为{0.,1.,1。, 0.},并在不使用mip-mapping的情况下使用线性过滤。这将使线条2像素粗,但是您可以更改纹理的厚度。 这比重量计算更快,更容易。

答案 9 :(得分:0)

使用此功能: void glPolygonMode(GLenum face,GLenum mode);

face:指定模式应用于的多边形。多边形的正面可以是GL_FRONT,背面可以是GL_BACK,两者都可以是GL_FRONT_AND_BACK。

mode:定义了三种模式,可以在mode中指定:

GL_POINT:将标记为边界边起点的多边形顶点绘制为点。

GL_LINE:将多边形的边界线绘制为线段。 (您的目标)

GL_FILL:多边形的内部已填充。

P.S:glPolygonMode控制图形管线中栅格化的多边形解释。

有关更多信息,请查看khronos组中的OpenGL参考页面: https://www.khronos.org/registry/OpenGL-Refpages/gl4/html/glPolygonMode.xhtml