OpenGL'de ilkelleri telkafes olarak nasıl oluşturuyorsunuz?


220

OpenGL'de ilkelleri telkafes olarak nasıl oluşturuyorsunuz?

opengl 

2
Kullandığınız OpenGL sürümü hakkında daha net olun.
Vertexwahn

ModernGL ile Context sınıfının tel kafes niteliğini basit bir şekilde kullanabilirsiniz
Szabolcs Dombi

tel kafes çizmek için GL_LINES kullanın
oxine

Yanıtlar:


367
glPolygonMode( GL_FRONT_AND_BACK, GL_LINE );

açmak için,

glPolygonMode( GL_FRONT_AND_BACK, GL_FILL );

normale dönmek için.

Doku eşleme ve aydınlatma gibi şeylerin, etkinleştirildikleri takdirde tel kafes hatlarına uygulanacağını ve tuhaf görünebileceğini unutmayın.


2
Seni sevdim. 4 tane daha kaldı.
Jo So

37

Gönderen 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
iki çağrı yapmak gereksizdir. GL_FRONT_AND_BACK kullanın
shoosh

6
@ Shoosh'un yorumuna ek olarak, Kırmızı Kitap GL_FRONT ve GL_BACK'in kullanımdan kaldırıldığını ve OpenGL 3.1 ve sonraki sürümlerden kaldırıldığını belirtir. Şimdi, bunları uyumluluk uzantısı aracılığıyla kullanmaya devam edebilirsiniz, ancak ileriye dönük ve geriye dönük uyumlu arasında bir seçiminiz varsa, öncekine gitmenizi tavsiye ederim.
fouric

1
Bu
yanıttaki

1
@ OndrejSlinták Şimdi düzeltildi.
MaxiMouse

24

OpenGL 3 ve sonraki sürümlerde ileri uyumlu bir içerik varsayarsak glPolygonMode, daha önce belirtildiği gibi kullanabilirsiniz , ancak kalınlığı 1 pikselden fazla olan satırların artık kullanımdan kaldırıldığını unutmayın. Dolayısıyla üçgenleri tel çerçeve olarak çizebilmenize rağmen, çok ince olmaları gerekir. OpenGL ES'de GL_LINESaynı sınırlama ile kullanabilirsiniz .

OpenGL'de, gelen üçgenleri almak, sökmek ve kalın çizgiler taklit eden dörtlü (gerçekten üçgen çiftleri) olarak rasterleştirme için göndermek için geometri gölgelendiricileri kullanmak mümkündür. Geometri gölgelendiricilerin kötü performans ölçeklemesi için kötü şöhretleri dışında oldukça basit.

Bunun yerine ne yapabileceğiniz ve OpenGL ES'de de işe yarayacak olan şey parça gölgelendirici kullanmaktır . Üçgene tel çerçeve üçgen dokusunu uygulamayı düşünün. Herhangi bir dokuya ihtiyaç duyulmadığı sürece, prosedürel olarak üretilebilir. Ama yeterince konuşalım, kodlayalım. Parça gölgelendirici:

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

Ve köşe gölgelendirici:

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
}

Burada, barycentric koordinatlar sade (1, 0, 0), (0, 1, 0)ve (0, 0, 1)üç üçgen köşeler için (sipariş, gerçekten önemli değil potansiyel olarak daha kolay üçgen şeritler halinde ambalaj kılan).

Bu yaklaşımın bariz dezavantajı, bazı doku koordinatlarını yiyeceği ve köşe dizinizi değiştirmeniz gerektiğidir. Çok basit bir geometri gölgelendirici ile çözülebilir ama hala GPU'yu daha fazla veri ile beslemekten daha yavaş olacağından şüpheleniyorum.


Bunun umut verici göründüğünü düşündüm, ancak bu OpenGL 3.2 (ES olmayan) ile herhangi bir kapasitede çalışmıyor gibi görünüyor. Mümkün olsa da, bir şeyleri berbat ettim, bununla biraz oynadım ve bunun nasıl kullanılacağından bile emin değilim. Bu gölgelendiricilerle gerçekte ne yapmak istediğinize dair daha fazla bilgi yardımcı olacaktır; Ben bir dolgu dışında başka bir şey yararlı bir şey üretmek nasıl görmüyorum, ama gl_FragColor alfa değeri tamamen OpenGL 3.2 göz ardı gibi göründüğü göz önüne alındığında bile işe yaramaz ...
user1167662

2
Tabii ki öyle. Birinin aynı fikri stackoverflow.com/questions/7361582/… 'de uygulamasına başvurabilirsiniz .
domuz

1
Önerilen uygulamanızı kullanmaya çalışırken karşılaştığım sorun, gölgelendiricinin ana hatlarıyla çizilecek nesnenin dışına asla çizim yapmayacağıdır. Bu nedenle anahat, ana hatlarıyla çizilen nesnenin üzerine mi çizilir? Başka bir deyişle, taslak çizilecek orijinal nesnenin içinde mi yer alacak?
user1167662

1
@BrunoLevy webGL'de ek koordinasyon alabilirsiniz, değil mi? Şanslıysanız, çok basit modelleriniz varsa bu koordinatları texcoord'lardan alabilirsiniz, ancak aksi takdirde yeni koordinatlar eklemeniz gerekir. O olmadan çalıştı çok güzel olurdu :). Tek ihtiyacınız olan, köşe başına tek bir skaler geçirmektir (ve ardından köşe gölgeleyicisindeki 3 vektörüne genişletir).
domuz

2
Ah, şimdi görüyorum ... f_width () bu konuda arkadaşım. Teşekkürler
Neil Gatenby

5

Sabit boru hattını (OpenGL <3.3) veya kullanabileceğiniz uyumluluk profilini kullanıyorsanız

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

Bu durumda, glLineWidth'i çağırarak çizgi genişliğini değiştirebilirsiniz

Aksi takdirde, çizim yönteminizdeki (glDrawElements, glDrawArrays, vb.) Çokgen modunu değiştirmeniz gerekir ve köşe verileriniz üçgenler için olduğundan ve satırlar çıkardığınız için bazı kaba sonuçlar elde edebilirsiniz. En iyi sonuçlar için bir Geometri gölgelendiricisi kullanmayı veya tel kafes için yeni veriler oluşturmayı düşünün .


3

En kolay yol, ilkelleri olduğu gibi çizmektir GL_LINE_STRIP.

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

bir grup GL_TRIANGLES ise: aralarında çizgiler elde edersiniz. OpenGL 1.x veya eski sürümlerde glPolygonMode kullanırsınız. Son OpenGL'de geometri gölgelendiricisi ile oynuyorsunuz.
Fabrice NEYRET

Bu, geride bırakılması gereken şeyleri yapmanın eski bir yoludur.
Benny Mackney

2

Modern OpenGL'de (OpenGL 3.2 ve üstü), bunun için bir Geometri Gölgelendirici kullanabilirsiniz:

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

Bildirimler:


1

Bunun gibi glut kütüphanelerini kullanabilirsiniz:

  1. bir küre için:

    glutWireSphere(radius,20,20);
    
  2. Silindir için:

    GLUquadric *quadratic = gluNewQuadric();
    gluQuadricDrawStyle(quadratic,GLU_LINE);
    gluCylinder(quadratic,1,1,1,12,1);
    
  3. bir Küp için:

    glutWireCube(1.5);
    

0

Kenar yumuşatılmamış oluşturma hedefi üzerine kenar yumuşatılmış çizgiler çizmenin iyi ve basit bir yolu, 1 × 0 dokuya sahip 4 piksel genişliğinde, {0, 1, 1., 0.} Alfa kanalı değerlerine sahip dikdörtgenler çizmektir. ve mip eşlemesi kapalıyken doğrusal filtreleme kullanın. Bu, çizgileri 2 piksel kalınlığında yapar, ancak dokuyu farklı kalınlıklar için değiştirebilirsiniz. Bu, barymetrik hesaplamalardan daha hızlı ve daha kolaydır.


0

bu işlevi kullanın: void glPolygonMode (GLenum yüzü, GLenum modu);

face: Modun uygulanacağı çokgenleri belirtir. çokgenin ön tarafı için GL_FRONT ve sırtı için GL_BACK ve her ikisi için GL_FRONT_AND_BACK olabilir.

modu: Üç mod tanımlanmıştır ve modda belirtilebilir:

GL_POINT: Sınır kenarının başlangıcı olarak işaretlenmiş çokgen köşeleri nokta olarak çizilir.

GL_LINE: Çokgenin sınır kenarları çizgi parçaları olarak çizilir. (senin hedefin)

GL_FILL: Çokgenin içi dolu.

PS: glPolygonMode, grafik boru hattında rasterleştirme için çokgenlerin yorumlanmasını kontrol eder.

daha fazla bilgi için khronos grubundaki OpenGL referans sayfalarına bakın: https://www.khronos.org/registry/OpenGL-Refpages/gl4/html/glPolygonMode.xhtml


-1

Karşılaştığınız OpenGL ES 2.0 ise, çizim modu sabitlerinden birini

GL_LINE_STRIP, GL_LINE_LOOP, GL_LINES, çizgi çizmek,

GL_POINTS (yalnızca köşe noktası çizmeniz gerekiyorsa) veya

GL_TRIANGLE_STRIP, GL_TRIANGLE_FANVeGL_TRIANGLES dolgulu üçgenler çizmek için

ilk argüman olarak

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

veya

glDrawArrays(GLenum mode, GLint first, GLsizei count) çağırır.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.