파이썬 강의/openGL

파이썬 openGL 1. 기본 그리기(점, 선, 삼각형, 사각형, 다각형)

마리사라 2021. 4. 17. 23:13
반응형

파이썬 openGL 1번째 강의는 openGL을 통해서 삼각형과 사각형을 그리는 방법입니다.


0. openGL의 방식

openGL은 저수준 API로, 무언가를 그리기 위해서는 모든 것을 본인이 직접 지정해 주어야 합니다.

 

예를 들어 고수준 API는 도형을 만들기 위해 한 줄의 코드로 만들 수 있다면, 저수준 API인 openGL은 도형을 만들기 위해 기본 색깔을 선언하고, 각 꼭짓점의 위치를 선언하고, 화면에 띄우겠다는 코드를 넣어야 합니다.

 

그렇기에 이번 강의에서는 openGL의 모든 코드를 설명해 드리며, 다음 강의부터 중복되는 코드는 생략하도록 하겠습니다.


1. openGL의 기본 main함수

파이썬에서 openGL을 사용하기 위해서는 모듈을 import 해줄 필요가 있으며, 필요한 코드는 다음과 같습니다.

from OpenGL.GL import *
from OpenGL.GLUT import *
from OpenGL.GLU import *

만약 OpenGL만 import 하신다면 OpenGL.GL.~~ 의 방식으로 입력해야 하니 위의 방식으로 import하시는 것이 편리합니다.

 

이후 main함수를 선언해 줍니다. Python은 C언어와 달리 main함수를 꼭 선언해주지 않아도 되지만, 시인성과 통일성을 위해서 선언해주는 것이 좋습니다.

if __name__ == "__main__":

main 함수에는 openGL이 구동되기 위한 기본적인 함수가 포함됩니다.

 

우선 시작하기 위해 openGL을 초기화해주는 코드를 입력합니다.

glutInit()

해당 코드가 openGL을 초기화해주는 코드이며, 원래는 파라미터로 시스템의 정보 값이 들어가야 하지만 파이썬에서는 생략이 가능합니다.

 

이번에는 openGL에서 어떠한 모드를 사용할지를 선언해 줍니다. 이번에는 색공간을 RGB로 사용하도록 선언하며, 앞으로도 특별한 사유가 없다면 색공간은 RGB를 사용합니다.

glutInitDisplayMode(GLUT_RGB)

 

이후 프로그램이 실행되었을 때, 어떠한 위치에 어떠한 사이즈의 Window가 출력되는지를 결정합니다. 해당 값은 임의의 값을 사용해도 좋습니다.

glutInitWindowSize(300, 300)
glutInitWindowPosition(0, 0)

 

이제 Window를 생성합니다. 이때 파라미터로 타이틀을 byte형으로 전달하면 Window의 타이틀을 설정해줄 수 있습니다.

glutCreateWindow(b"OpenGl Drawing")

 

Window가 생성됬으면 어떠한 화면을 띄울지 지정해야 합니다.

glutDisplayFunc(MyDisplay)

glutDisplayFunc는 어떠한 화면을 띄울지 지정하는 코드로, 파라미터로 함수를 받습니다. MyDisplay라는 함수에 원하는 내용을 넣으면 glutDisplayFunc에 받아와서 Window에 띄우는 형태입니다. 이때 아무것도 그리지 않았다고 하더라도 glutDisplayFunc은 존재해야 하며, 파라미터로 빈 함수라도 지정해 주어야 합니다.

 

이후 프로그램이 별도의 조작이 있을 때까지 지속되도록 Loop함수를 사용합니다.

glutMainLoop()

 

이제 main함수의 준비는 끝났습니다. 이 부분은 대부분의 openGL글에서 공통으로 사용되는 부분이며, 이후부터 main함수에 코드를 추가하거나 여러 값을 변경하지 않는 이상은 이 main함수를 그대로 사용하시면 되겠습니다.

if __name__ == "__main__":
    glutInit()
    glutInitDisplayMode(GLUT_RGB)
    glutInitWindowSize(300, 300)
    glutInitWindowPosition(0, 0)
    glutCreateWindow(b"OpenGl Drawing")
    glutDisplayFunc(MyDisplay)
    glutMainLoop()

2. openGL에서의 점, 선, 면

우선 꼭짓점의 크기를 지정해 줍니다. 이때 크기는 float형으로 자유롭게 입력이 가능하며 점은 사각형으로 찍힙니다. 이번 강의에서는 적당한 사이즈의 10.0으로 정하겠습니다.

glPointSize(10.0)

 

이후 점의 크기를 정했으니 무엇을 그릴 지를 선언해야 합니다. 이때 필요한 코드가 glBegin이며, 이 코드를 통해 그리고 싶은 것들을 선언합니다.

glBegin(GL_POINTS)

 

glBegin에서 받을 수 있는 파라미터 중, 2차원으로 자주 쓰이는 파라미터는 다음과 같습니다.

  • GL_POINTS : 점. 개수의 제한이 없다.
  • GL_LINES : 선. 2의 배수만큼 선언해야 하며, 2의 배수를 뺀 나머지 점은 표시되지 않는다.
  • GL_LINE_STRIP : 선. LINES와 비슷하지만 모든 점들끼리 이어져 있으므로 사용되지 않는 점은 없다.
  • GL_TRIANGLES : 삼각형. 3의 배수만큼 선언해야 하며, 3의 배수를 뺀 나머지 점들은 표시되지 않는다.
  • GL_TRIANGLE_STRIP : 삼각형. TRIANGLES와 비슷하지만 선언된 모든 점을 사용하여 삼각형을 만들기에 3개 이상의 점에서 사용되지 않는 점은 없다.
  • GL_QUADS : 사각형. 4의 배수 만큼 선언해야 하며, 4의 배수를 뺀 나머지 점들은 표시되지 않는다. 이때 점의 선언 순서에 따라 사각형이 되지 않을 수도 있다.
  • GL_QUAD_STIRP : 사각형. QUADS와 비슷하지만 선언된 모든 점을 사용하여 사각형을 만들지만, TRIANGLE_STRIP과 달리 사각형이 만들어질 수 없는 상황일 경우가 있다.(점이 홀수개 선언된 경우)
  • GL_POLYGON : 다각형. 면의 조건(꼭짓점이 3개 이상)만 충족되면 모든 도형을 만들 수 있다.

 

이후 각각의 꼭짓점의 좌표를 설정해 줍니다. 이때 (0, 0)은 Window의 정 중앙을 말합니다.

glVertex2f(0.5, 0.5)
glVertex2f(-0.5, 0.5)
glVertex2f(0.5, -0.5)
glVertex2f(-0.5, -0.5)

이때 뒤에 붙은 2f의 뜻은 2차원의 좌표라는 뜻이며, 3f를 사용하면 3차원 좌표로도 나타낼 수 있습니다.

 

이후 더 이상 점을 선언하지 않겠다는 뜻으로 End 명령을 호출합니다.

glEnd()

 

마지막으로 이상의 것들을 화면에 출력하겠다는 코드를 작성함으로써 마무리됩니다.

glFlush()

 

이제 결과 화면입니다. 순서는 POINTS, LINES, TRIANGLES, QUADS, POLYGON입니다.

GL_POINTS
GL_LINES
GL_TRIANGLES
GL_QUADS
GL_POLYGON

위 사진들을 보면 예상과 다르게 나온 결과들이 있습니다. 그 이유를 하나씩 짚어보겠습니다.

 

① 10의 크기와는 맞지 않아 보이는 LINES

선의 크기는 PointSize가 아닌 LineWidth로 선언해야 합니다.

glLineWidth(10.0)

LineWidth 10.0으로 설정한 결과

 

② 사각형이 아닌 QUADS와 POLYGON

openGL에서 모든 도형은 점이 선언된 순서대로 그려집니다. 우상단(0.5, 0.5) 좌상단(-0.5, 0.5), 우하단(0.5, -0.5), 좌하단(-0.5, -0.5)의 순서로 꼭짓점을 선언하였기에 중간에 꼬인 부분이 나타나게 됩니다. 이를 바로잡기 위해서는 우상단, 좌상단, 좌하단, 우하단 등의 (0, 0)을 지나지 않도록 점을 선언하면 됩니다.

glVertex2f(0.5, 0.5)
glVertex2f(-0.5, 0.5)
glVertex2f(-0.5, -0.5)
glVertex2f(0.5, -0.5)

우상-좌상-좌하-우하의 순서로 선언


3. 마치며

파이썬에서의 PyOpenGL과 freeglut는 C나 C++의 openGL의 코드와 정확히 일치합니다. 그렇기 때문에 openGL강의에서 나오는 코드를 익혀두셨다가 C언어에서도 사용하시면 좋습니다. 감사합니다.

from OpenGL.GL import *
from OpenGL.GLUT import *
from OpenGL.GLU import *


def MyDisplay():
    glLineWidth(10.0)
    glBegin(GL_QUADS)
    glVertex2f(0.5, 0.5)
    glVertex2f(-0.5, 0.5)
    glVertex2f(-0.5, -0.5)
    glVertex2f(0.5, -0.5)
    glEnd()
    glFlush()


if __name__ == "__main__":
    glutInit()
    glutInitDisplayMode(GLUT_RGB)
    glutInitWindowSize(300, 300)
    glutInitWindowPosition(0, 0)
    glutCreateWindow(b"OpenGl Drawing")
    glutDisplayFunc(MyDisplay)
    glutMainLoop()
반응형

'파이썬 강의 > openGL' 카테고리의 다른 글

파이썬 openGL 0. openGL이란?  (0) 2021.04.15