OpenGL'de ilkelleri telkafes olarak nasıl oluşturuyorsunuz?
OpenGL'de ilkelleri telkafes olarak nasıl oluşturuyorsunuz?
Yanıtlar:
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.
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);
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_LINES
aynı 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.
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 .
En kolay yol, ilkelleri olduğu gibi çizmektir GL_LINE_STRIP
.
glBegin(GL_LINE_STRIP);
/* Draw vertices here */
glEnd();
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:
layout (line_strip, max_vertices=3) out;
içinlayout (points, max_vertices=3) out;
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.
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
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_FAN
VeGL_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.