238

OpenGLでプリミティブをワイヤフレームとしてレンダリングするにはどうすればよいですか?

4

10 に答える 10

392
glPolygonMode( GL_FRONT_AND_BACK, GL_LINE );

スイッチを入れ、

glPolygonMode( GL_FRONT_AND_BACK, GL_FILL );

通常に戻るために。

テクスチャ マッピングやライティングなどは、ワイヤフレーム ラインが有効になっている場合でも適用されるため、奇妙に見える可能性があることに注意してください。

于 2008-09-26T03:44:11.840 に答える
44

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);
于 2008-09-26T03:43:37.893 に答える
29

OpenGL 3 以降で前方互換性のあるコンテキストを想定すると、前述のように使用できますがglPolygonMode、1px を超える太さの線は非推奨になっていることに注意してください。したがって、三角形をワイヤーフレームとして描くことはできますが、非常に細くする必要があります。GL_LINESOpenGL ES では、同じ制限で使用できます。

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)、3 つの三角形の頂点に対して (順序は実際には重要ではないため、三角形のストリップへのパッキングが潜在的に容易になります)。

このアプローチの明らかな欠点は、いくつかのテクスチャ座標を消費し、頂点配列を変更する必要があることです。非常に単純なジオメトリ シェーダーで解決できますが、GPU により多くのデータを供給するよりも遅くなると思います。

于 2015-10-07T23:45:48.803 に答える
4

Modern OpenGL (OpenGL 3.2 以降) では、これに Geometry Shader を使用できます。

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

特記事項:

于 2017-10-31T14:08:28.673 に答える
2

最も簡単な方法は、プリミティブを として描画することGL_LINE_STRIPです。

glBegin(GL_LINE_STRIP);
/* Draw vertices here */
glEnd();
于 2014-03-19T06:24:14.223 に答える