OpenGL에서 프리미티브를 와이어 프레임으로 어떻게 렌더링합니까?


220

OpenGL에서 프리미티브를 와이어 프레임으로 어떻게 렌더링합니까?

opengl 

2
사용중인 OpenGL 버전에 대해보다 구체적으로 설명하십시오.
Vertexwahn

ModernGL 당신은 단순화는 사용할 수있는 와이어 프레임 의 속성 컨텍스트 클래스
사볼 돔비

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
두 번의 통화는 중복됩니다. 사용 GL_FRONT_AND_BACK
shoosh

6
@shoosh의 의견에 대한 부록으로 Red Book은 GL_FRONT 및 GL_BACK이 더 이상 사용되지 않으며 OpenGL 3.1 이상에서 제거되었다고 말합니다. 이제 호환성 확장을 통해 계속 사용할 수 있지만 이전 버전과 이전 버전 중 하나를 선택할 수 있으면 이전 버전을 사용하는 것이 좋습니다.
fouric March

1
이 답변의 링크는 404를 반환합니다.
Ondrej 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)세 개의 삼각형의 정점 (순서는, 정말 중요합니까 잠재적으로 쉽게 삼각형 스트립으로 포장하게된다).

이 방법의 명백한 단점은 텍스처 좌표를 먹고 버텍스 배열을 수정해야한다는 것입니다. 매우 간단한 지오메트리 쉐이더로 해결할 수는 있지만 GPU에 더 많은 데이터를 공급하는 것보다 느릴 것이라고 생각합니다.


나는 이것이 유망한 것처럼 보이지만 OpenGL 3.2 (비 ES)의 용량에서는 작동하지 않는 것으로 보입니다. 무언가를 엉망으로 만들 수는 있지만, 이것으로 꽤 놀았으며 이것이 어떻게 사용되는지 확실하지 않습니다. 이 쉐이더로 실제로 렌더링하려는 것에 대한 더 많은 정보가 도움이 될 것입니다. 필 이외의 다른 것이 유용한 것을 생성하는 방법을 보지 못하지만 gl_FragColor의 알파 값이 OpenGL 3.2에서 완전히 무시 된 것처럼 보이면 작동하지 않습니다 ...
user1167662

2
물론 그렇습니다. stackoverflow.com/questions/7361582/… 에서 같은 아이디어를 구현 한 사람을 참조 할 수 있습니다 .
돼지

1
제안 된 구현을 사용하려고 할 때 발생하는 문제는 셰이더가 객체 외부에서 윤곽을 그리기 위해 절대 그려지지 않을 것입니다. 따라서 윤곽을 그리는 대상 위에 윤곽을 그립니다? 다시 말해서, 윤곽선은 그려 질 원본 객체 안에 순수하게 포함됩니까?
user1167662

1
@BrunoLevy webGL에서 추가로 조정할 수 있습니다. 운이 좋으면 매우 간단한 모델이 있으면 texcoord에서 해당 좌표를 얻을 수 있지만 그렇지 않으면 새 좌표를 추가해야합니다. 그것없이 작동한다면 너무 좋을 것입니다 :). 정점마다 단일 스칼라를 전달한 다음 정점 셰이더에서 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 를 호출하여 선 너비를 변경할 수 있습니다

그렇지 않으면 draw 메서드 내에서 다각형 모드 (glDrawElements, glDrawArrays 등)를 변경해야합니다. 정점 데이터가 삼각형이고 선을 출력하기 때문에 결과가 거칠어 질 수 있습니다. 최상의 결과를 얻으려면 형상 셰이더를 사용 하거나 와이어 프레임에 대한 새 데이터를 만드는 것이 좋습니다 .


3

가장 쉬운 방법은 프리미티브를로 그리는 것 GL_LINE_STRIP입니다.

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

그것이 GL_TRIANGLES의 무리라면 아닙니다. 그들 사이에 선이 생길 것입니다. OpenGL 1.x 또는 레거시에서는 glPolygonMode를 사용합니다. 최근 OpenGL에서는 지오메트리 셰이더를 사용합니다.
Fabrice NEYRET

이것은 남겨 두어야 할 일을하는 고대 방법입니다.
베니 맥니

2

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

공지 사항 :


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 픽셀이되지만 다른 두께로 텍스처를 변경할 수 있습니다. 이것은 Barymetric 계산보다 빠르고 쉽습니다.


0

이 기능을 사용하십시오 : void glPolygonMode (GLenum face, GLenum mode);

face : 모드가 적용되는 다각형을 지정합니다. 다각형의 앞면은 GL_FRONT, 등은 GL_BACK, 양쪽은 GL_FRONT_AND_BACK입니다.

mode : 세 가지 모드가 정의되어 있으며 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_FANGL_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.