Graphics/OpenGL

OpenGL 기초 - 점, 선, 삼각, 사각, 다각형

MOLOKINI 2014. 5. 17. 18:35

모든 디지털 그래픽의 기본은 점입니다.

선이나, 면도 아시다시피 모두 점의 집합입니다.
하지만, 3차원 그래픽의 가장 원시적인 요소는 정점(Vertex)입니다.
 
정점 : 위치정보만 갖는다.
점 : 위치 + 색깔 + 크기 등
 
정점은 다음 두 블록 사이에 정의됩니다.
 
void glBegin(GLenum mode);
void glEnd(void);
 
아시죠잉?
 
정점을 찍어내는 함수는
glVertex[2,3,4][s,i,f,d][v](x,y,z,w);
 
블록내의 정점들로 무엇을 어떻게 그려낼까는 glBegin으로 전달되는 모드값에 따라 달라집니다.
 
모드                                설명
GL_POINTS                              독립적인 점
GL_LINE_STRIP                        연결된 선분
GL_LINE_LOOP                        시작점과 끝점을 이은 선분
GL_LINES                                두개의 정점들을 이은 선분
GL_TRIANGLES                        세개씩 연결한 삼각형
GL_TRIANGLE_STRIP                연결된 삼각형
GL_TRIANGLE_FAN                   중심을 공유하는 삼각형
GL_QUADS                              정점 4개씩을 연결하여 사각형을 그린다
GL_QUAD_STRIP                      연결된 사각형
GL_POLYGON                          연결된 블록 다각형
 

 

void DoDisplay()
{
glClear(GL_COLOR_BUFFER_BIT);
 
glColor3f(1,0,0);                        // 정점의 색은 빨간색
glBegin(GL_POINTS);                // 점만 찍어낸다.
glVertex2f(0.0, 0.5);
glVertex2f(-0.5, -0.5);
glVertex2f(0.5, -0.5);
glEnd();
glFlush();
}
 
결과화면을 스샷하려다가 점세개만 딸랑 나오는걸 보고 스샷해도 안보이겠다싶어서 화면은 스킵했습니다.
다른부분은 첫번째 삼각형 그릴때의 부분과 같기 때문에, 디스플레이부분만 실어 보았습니다.
 
그래서 이 작은 점을 확대하는 함수가 있습니다.
 
void glPointSize(GLFloat size);
 
void DoDisplay()
{
glClear(GL_COLOR_BUFFER_BIT);
 
glColor3f(1,0,0);                        // 정점의 색은 빨간색
        glPointSize(10.0);                     // 점의 크기는 10
glBegin(GL_POINTS);                // 점만 찍어낸다.
glVertex2f(0.0, 0.5);
glVertex2f(-0.5, -0.5);
glVertex2f(0.5, -0.5);
glEnd();
glFlush();
}
 

GL_POINTS

 

점의 크기가 10으로 커져서 눈에 보이게 됐습니다.

이 점의 크기는 1.0 ~ 63.375까지의 범위를 가지며, 범위를 넘어가더라도 가장 가까운 값이 선택되면서 에러는 나지 않습니다. 똑똑하죠?

안티엘리어싱을 하지 않아서 점이 사각형으로 나온 것인데, 이건 나중에..

 

GL_LINE_STRIP

 

 

GL_LINE_LOOP

 

GL_LINES : 정점을 두개씩 한 조로 선을 그어준다. 홀수면 마지막 정점은 무시됩니다.

선을 더 굵게 그리고싶다구요?

 

void glLineWidth(GLFloat width);

 

width에 설정된 숫자대로 선의 굵기가 변형됩니다.

 

 

void DoDisplay()

{

glClear(GL_COLOR_BUFFER_BIT);

 

glColor3f(1,0,0);

glLineWidth(10.0);                    // 너비 10짜리 선

glBegin(GL_LINE_LOOP);         

// 삼각형

glVertex2f(0.0, 0.5);

glVertex2f(-0.5, -0.5);

glVertex2f(0.5, -0.5);

glEnd();

glFlush();

}

 

 

 

실선이 아닌 선을 그리고 싶을 땐 어쩔까요?

점선같은거

 

void glLineStipple(GLint factor, GLushort pattern);

 

그닥 중요하지 않으니까, 예제로 만들지는 않고 이론으로 짤막하게 설명드리겠습니다.

 

요 기능을 사용하려면 일단 

glEnable(GL_LINE_STIPPLE);

로 켜줘야하고, glDisable하면 됩니다.

 

pattern은 2진수로 표현된 점의 모양입니다.

대응되는 비트가 1이면 점이 찍히고 0이면 찍히지 않습니다.

 

이런겁니다.

0x33ff를 패턴 자리에 넣으면 선 모양은 맨 아래처럼 나오게 됩니다.

 

 

 

이제 삼각형을 그려보겠습니다.

 

 

void DoDisplay()

{

    glClear(GL_COLOR_BUFFER_BIT);

    glColor3f(1,0,0);

    glBegin(

GL_TRIANGLES

);

    GLfloat x = -0.8;

    GLfloat y = 0.4;

    for (int i = 0; i < 6; i++) {

         glVertex2f(x, y);

         x += 0.3;

         y *= -1;                      

 // +1과 -1의 반복 (곱하기니까)

    }

    glEnd();

    glFlush();

}

 

GL_TRIANGLES

 : 정점을 세개씩 짝지어 삼각형을 그린다, 3의 배수에서 남는 점은 무시됩니다.

 

void DoDisplay()

{

     glClear(GL_COLOR_BUFFER_BIT);

     glShadeModel(GL_FLAT);            

  // 단색으로 채색, 나중에 자세하게 하겠습니다^^

 

     glBegin(GL_TRIANGLE_STRIP);

     GLfloat x = -0.8;

     GLfloat y = 0.4;

     for (int i = 0; i < 6; i++) {

          if (i % 2 == 0) {

              glColor3f(1.0, 0.0, 0.0);     

  // 삼각형을 구별하기위해 색상처리만 다르게

          } else {

              glColor3f(0.0, 1.0, 0.0);

          }

          glVertex2f(x, y);

          x += 0.3;

          y *= -1;

     }

     glEnd();

     glFlush();

}

 

GL_TRIANGLE_STRIP 

: 삼각형을 이어서 그립니다.

 

void DoDisplay()

{

     glClear(GL_COLOR_BUFFER_BIT);

     glShadeModel(GL_FLAT);

 

     glBegin(GL_TRIANGLE_FAN);

     glColor3f(1.0, 0.0, 0.0);

     glVertex2f(0.0, 0.0);

     glVertex2f(0.0, 0.5);

     glVertex2f(-0.35, 0.35);

 

     glColor3f(0.0, 1.0, 0.0);

     glVertex2f(-0.5, 0.0);

    

     glColor3f(1.0, 0.0, 0.0);

     glVertex2f(-0.35, -0.35);

    

     glColor3f(0.0, 1.0, 0.0);

     glVertex2f(0.0, -0.5);

     glEnd();

     glFlush();

}

 

GL_TRIANGLE_FAN

 : 첫번째 정점을 기준으로 부채꼴모양으로 삼각형을 그려줍니다, 

                                  이걸 아주 작은 삼각형을 만들게되면 원모양이 됩니다.

 

 

이제 사각형을 그려보겠습니다.

 

사각형은 완전 독립된 함수이기 때문에, glBegin ~ glEnd사이에 들어가 있지 않더라도 작성 가능합니다.

 

 

void DoDisplay()

{

     glClear(GL_COLOR_BUFFER_BIT);

 

   glRectf(-0.8, 0.8, 0.8, -0.8);  

        

  // 사각형그려! (왼쪽 위, 오른쪽 아래)

     glFlush();

}

심플허니 아름답지요?

 

왼쪽 위와, 오른쪽 아래를 꼭지점으로 하는 사각형이 만들어집니다.

 

대각선의 두 점을 지정하는 방식이라 각 변이 수직인 직사각형만 그릴 수 있습니다.

평행사변형이나 사다리꼴 처럼 직각이 아닌 사각형은 그릴 수 없습니다.

불규칙한 사각형은 정점을 직접 지정하여 다각형으로 그려야 합니다.

 

 

void DoDisplay()

{

     glClear(GL_COLOR_BUFFER_BIT);

 

     glBegin(GL_QUADS);

     glVertex2f(0.0, 0.5);

     glVertex2f(-0.5, 0.0);

     glVertex2f(0.0, -0.5);

     glVertex2f(0.5, 0.0);

     glEnd();

     glFlush();

}

 

GL_QUADS

 : 정점을 4개씩 묶어서 사각형을 그립니다.

                     마찬가지로 네개가 넘어가는 나머지 정점은 무시됩니다.

 

GL_QUAD_STRIP

은 GL_TRIANGLE_STRIP처럼 사각형을 이어서 그립니다.

6개의 정점만으로 두개의 사각형을 그릴 수 있습니다.

그래서 따로 예제를 만들지는 않았고요.

 

 

자, 이제 마지막으로 다각형을 그려보겠습니다.

 

GL_POLYGON으로 그리는데, 모든 정점을 연결하여 다각형을 그려냅니다.

그런데 다각형이라고 다 그려지는게 아닙니다.

좀 까다롭습니다.

 

  * 정점의 선이 교차해서는 안된다.

  * 다각형은 볼록해야 한다.

  * 모든 정점은 같은 평면 내에 있어야 한다.

 

 

왼쪽이 볼록한 다각형, 오른쪽이 오목하거나 선분이 교차하는 다각형입니다.

왼쪽 같은 경우만 가능합니다,

 

모든 정점이 같은 평면 내에 있다는 조건이 애매하게 들릴 지 모르겠습니다.

 

 

왼쪽 그림은 종이를 책상위에 놓은것이고, 

오른쪽 그림은 책상 위에 둔 종이의 

오른쪽 아래 귀퉁이를 살짝 들어 올린 형태

입니다.

 

이렇게 되면, 왼쪽은 책상이라는 같은 평면에 있게된 사각형인데,

오른쪽은 오른쪽 아래 귀퉁이를 위로 올려버리는 바람에 책상이라는 평면에 있지 않게 되었습니다.

 

이게 바로 모든 정점이 같은 평면에 있어야 한다는 조건입니다. 따라서 오른쪽의 다각형은 그려낼 수 없습니다.

  - 물론, 같은 평면 내에서 정점의 위치를 다르게 잡아서 하는 경우엔 가능합니다. 보이기에는 오른쪽 도형과 같을 지 모르겠지만, 같은 평면에서 정점 위치만 달라진 것이기 때문에 같은 평면에 있는 조건을 만족시켜서 그려지는 것입니다.

 

 

 

void DoDisplay()

{

     glClear(GL_COLOR_BUFFER_BIT);

 

     glBegin(

GL_POLYGON

);      

 // 다각형을 그려내기 위해 변경

     glVertex2f(0.0, 0.5);              

  // 가장 꼭대기 정점

     glVertex2f(-0.5, 0.0);            

  // 왼쪽 정점

     glVertex2f(0.5, 0.0);               

 // 마름모 예제와 3, 4번 정점의 위치를 바꾸었다.

     glVertex2f(0.0, -0.5);            

  // 아래 정점

     glEnd();

     glFlush();

}

 

GL_POLYGON

 : 다각형

 

 

OpenGL이 인정하지 않는 오목한 다각형이 나왔습니다. 어쨋든..

 

 

OpenGL ES에서는 사각형 함수가 없다는 것 잊지말자.

  - 삼각형 두개로 사각형을 그려내야합니다.

'Graphics > OpenGL' 카테고리의 다른 글

OpenGL 기초 - 안티앨리어싱  (0) 2014.05.17
OpenGL 기초 - 블렌딩  (0) 2014.05.17
OpenGL 기초 - 상태머신, 버전조사  (0) 2014.05.16
OpenGL 기초 - 색상변경  (0) 2014.05.16
OpenGL 기초 - 기본타입, 함수형식  (0) 2014.05.16