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


220

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

opengl 

2
使用しているOpenGLのバージョンをより具体的にしてください。
Vertexwahn 2016年

ではModernGLあなたは単純化を使用することができ、ワイヤフレームの属性コンテキストクラス
サボルチDombi

ワイヤーフレーム描画するGL_LINESを使用
オキシン

回答:


367
glPolygonMode( GL_FRONT_AND_BACK, GL_LINE );

スイッチを入れる

glPolygonMode( GL_FRONT_AND_BACK, GL_FILL );

通常に戻ります。

テクスチャマッピングやライティングなどが有効になっている場合は、ワイヤーフレームラインに引き続き適用されることに注意してください。


2
私はあなたが好きです。あと4つです。
Jo So

37

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

75
2つの呼び出しを行うことは冗長です。GL_FRONT_AND_BACKを使用してください
shoosh

6
@shooshのコメントへの補足として、Red BookはGL_FRONTとGL_BACKが非推奨になり、OpenGL 3.1以降から削除されたと述べています。現在、互換性拡張機能を介してそれらを使用できますが、前方互換性と後方互換性のどちらかを選択できる場合は、前者を使用することをお勧めします。
Fouric '26年

1
この回答が戻る404内のリンク
オンドレイSlinták

1
@OndrejSlintákそれは現在修正されています。
MaxiMouse

24

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)(順序は潜在的に容易に三角形ストリップに梱包せた、本当に問題ではない)3つの三角形の頂点のために。

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


これは有望に見えると思いましたが、これはOpenGL 3.2(非ES)でどのように機能しても動作しないようです。私は何かをめちゃくちゃにした可能性はありますが、私はこれをかなりいじってみましたが、これがどのように使用されることさえ意図されているのか本当にわかりません。これらのシェーダーを使用して実際にレンダリングしようとしているものに関する詳細情報があれば役立ちます。塗りつぶし以外のものがどのように役立つかはわかりませんが、gl_FragColorのアルファ値がOpenGL 3.2で完全に無視されているように見える場合は機能しません...
user1167662

2
もちろんそうです。stackoverflow.com/questions/7361582/…で、同じアイデアの誰かの実装を参照できます。

1
私が提案された実装を使用しようとするときに遭遇する問題は、シェーダーが輪郭を描かれるオブジェクトの外側に描画されることは決してないだろうと私は思います。したがって、これにより、輪郭が描かれているオブジェクトの上に輪郭が描かれますか?言い換えると、アウトラインは、描画される元のオブジェクト内に純粋に含まれますか?
user1167662 2016年

1
@BrunoLevyあなたはwebGLで追加の調整を得ることができますか?運が良ければ、非常に単純なモデルがあればtexcoordsからこれらの座標を取得できる可能性がありますが、それ以外の場合は新しい座標を追加するだけで済みます。それなしで動作した場合、あまりにもいいでしょう:) 必要なのは、頂点ごとに1つのスカラーを渡すことです(次に、頂点シェーダーでそれを3つのベクトルに展開します)。
ブタは

2
ああ、今はわかります...この点で、f_width()は私の友人です。ありがとう
Neil Gatenby

5

固定パイプライン(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

それ以外の場合は、描画メソッド(glDrawElements、glDrawArraysなど)内でポリゴンモードを変更する必要があります。頂点データが三角形用であり、線を出力しているため、おおまかな結果が得られる場合があります。最良の結果を得るには、ジオメトリシェーダーを使用するか、ワイヤーフレームの新しいデータを作成することを検討してください。


3

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

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

それがGL_TRIANGLESの束である場合ではありません。それらの間に線が表示されます。OpenGL 1.xまたはレガシーでは、glPolygonModeを使用します。最近のOpenGLでは、ジオメトリシェーダーを操作します。
Fabrice NEYRET、2015年

これは、置き去りにする必要があることを行う古代の方法です。
ベニーマクニー

2

最新の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();
}

お知らせ:


1

次のようなglutライブラリを使うことができます:

  1. 球の場合:

    glutWireSphere(radius,20,20);
    
  2. シリンダーの場合:

    GLUquadric *quadratic = gluNewQuadric();
    gluQuadricDrawStyle(quadratic,GLU_LINE);
    gluCylinder(quadratic,1,1,1,12,1);
    
  3. キューブの場合:

    glutWireCube(1.5);
    

0

アンチエイリアス処理されていないレンダーターゲットにアンチエイリアス処理された線を描画するための優れたシンプルな方法は、アルファチャネル値が{0.、1.、1.、0。}の1x4テクスチャーで幅4ピクセルの長方形を描画することです。 、そしてミップマッピングをオフにして線形フィルタリングを使用します。これにより、線が2ピクセルの太さになりますが、異なる太さのテクスチャを変更できます。これは、重量計算よりも速くて簡単です。


0

次の関数を使用します。void glPolygonMode(GLenum face、GLenum mode);

face:モードが適用されるポリゴンを指定します。ポリゴンの表側はGL_FRONT、裏側はGL_BACK、両方はGL_FRONT_AND_BACKにすることができます。

mode:3つのモードが定義されており、modeで指定できます。

GL_POINT:境界エッジの開始としてマークされているポリゴンの頂点は、ポイントとして描画されます。

GL_LINE:ポリゴンの境界エッジが線分として描画されます。(あなたのターゲット)

GL_FILL:ポリゴンの内部が塗りつぶされます。

PS:glPolygonModeは、グラフィックスパイプラインでのラスタライズのためのポリゴンの解釈を制御します。

詳細については、khronosグループのOpenGLリファレンスページをご覧ください。https://www.khronos.org/registry/OpenGL-Refpages/gl4/html/glPolygonMode.xhtml


-1

それの場合のOpenGL ES 2.0あなたが扱っている、あなたはから描画モード定数のいずれかを選択できます。

GL_LINE_STRIP, GL_LINE_LOOP, GL_LINES, 線を引く

GL_POINTS (頂点のみを描画する必要がある場合)、または

GL_TRIANGLE_STRIP、、GL_TRIANGLE_FANおよびGL_TRIANGLES黒三角を描画します

あなたの最初の引数として

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

または

glDrawArrays(GLenum mode, GLint first, GLsizei count) 呼び出します。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.