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

iecba09b  于 2022-09-26  发布在  其他
关注(0)|答案(10)|浏览(215)

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

a14dhokn

a14dhokn1#

glPolygonMode( GL_FRONT_AND_BACK, GL_LINE );

若要开机,

glPolygonMode( GL_FRONT_AND_BACK, GL_FILL );

才能恢复正常。

请注意,如果线框线被启用,纹理Map和照明等内容仍将应用于线框线,这看起来可能会很奇怪。

lmyy7pcs

lmyy7pcs2#

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

rslzwgfq3#

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

vc9ivgsu

vc9ivgsu4#

在现代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();
}

注意事项:

p8h8hvxi

p8h8hvxi5#

如果您使用的是固定管道(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、glDrawArray等)中的多边形模式,最终可能会得到一些粗略的结果,因为您的顶点数据是针对三角形的,而您正在输出线。为了获得最佳效果,请考虑使用Geometry shader或为线框创建新数据。

t5zmwmid

t5zmwmid6#

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

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

1rhkuytd7#

您可以像这样使用GLUT库:

1.对于球体:

glutWireSphere(radius,20,20);

1.对于圆柱体:

GLUquadric *quadratic = gluNewQuadric();
gluQuadricDrawStyle(quadratic,GLU_LINE);
gluCylinder(quadratic,1,1,1,12,1);

1.对于多维数据集:

glutWireCube(1.5);
ukqbszuj

ukqbszuj8#

使用此函数:

void glPolygonMode(GLenum face, GLenum mode);

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

mode:定义了三种模式。

  • GL_POINT:标记为边界边起点的多边形顶点绘制为点。
  • GL_LINE:多边形的边界边绘制为线段。(您的目标)
  • GL_FILL:填充了多边形的内部。

备注:glPolygonMode控制图形管道中用于栅格化的多边形的解释。

有关更多信息,请查看Khronos组中的OpenGL reference pages

lrl1mhuk

lrl1mhuk9#

如果您正在处理的是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)呼叫。

fzsnzjdm

fzsnzjdm10#

在非抗锯齿渲染目标上绘制抗锯齿线的一个简单好方法是,使用1x4纹理绘制4像素宽度的矩形,Alpha通道值为{0.,1.,1.,0.},并在禁用MIPMap的情况下使用线性过滤。这将使线条变粗2个像素,但您可以更改不同粗细的纹理。这比重力计算更快、更容易。

相关问题