반응형

본 포스팅을 보기 전에 아래 포스팅을 참고하세요..

[그래픽스&컴퓨터비전/OpenGL & Augmented Reality] - OpenGL 강좌 - 정사각형 그리기


OpenGL 프로그래밍을 위한 준비는 다음 포스팅을 참고하세요.

[그래픽스&컴퓨터비전/OpenGL & Augmented Reality] - Ubuntu 16.04에서 OpenGL( freeGLUT ) 프로그래밍

[그래픽스&컴퓨터비전/OpenGL & Augmented Reality] - OpenGL( freeGLUT ) 을 Visual Studio 2015에 연동하기



이번엔 삼각형의 중앙이 원점(0,0)에 오도록해서 그리는 예제입니다. 주의 할 점은 삼각형을 구성하는 세 개의 vertex를 지정해줄 때 반드시 반시계 방향으로 차례대로 지정해줘야 합니다.

1
2
3
4
5
6
7
8
    glBegin(GL_TRIANGLES); //3점이 하나의 삼각형을 구성한다. 반시계 방향으로 3점의 vertex를 지정해줘야 한다.
    glColor3f(1.0f, 0.0f, 0.0f); //빨간색 지정
    glVertex3f(-0.5f, -0.5f, 0.0f);    // 왼쪽 아래 vertex
    glColor3f(0.0f, 1.0f, 0.0f); //녹색 지정
    glVertex3f(0.5f, -0.5f, 0.0f);    // 오른쪽 아래 vertex
    glColor3f(0.0f, 0.0f, 1.0f); //파란색 지정
    glVertex3f(0.0f, 0.5f, 0.0f);    // 위쪽 vertex
    glEnd();
cs




애니메이션을 구현하기 위해서는 타이머 콜백 함수를 등록해야 합니다.  타이머 콜백 함수는 지정해준 시간이 지나면 호출됩니다. 처음에는 바로 호출되도록 타이머 이벤트 대기 시간을 0으로 지정해줍니다.

1
2
    //타이머 콜백 함수 등록, 처음에는 바로 호출됨.
    glutTimerFunc(0, timer, 0);
cs

타이머 콜백 함수에서 glutPostRedisplay 함수를 호출합니다. glutPostRedisplay 함수는 윈도우를 다시 그리도록 요청합니다.  요청하자마자 바로 디스플레이 콜백 함수가 호출되지는 않고 메인 루프에서 호출 시점을 결정하게 됩니다.  다음 타이머 이벤트 대기시간을 30밀리세컨트로 지정해줍니다.

1
2
3
4
5
void timer(int value) {
    glutPostRedisplay();      //윈도우를 다시 그리도록 요청
    glutTimerFunc(30, timer, 0); //다음 타이머 이벤트는 30밀리세컨트 후  호출됨.
}
 
cs


또한 화면 그리는 성능을 높이기 위해 더블 버퍼를 설정해주어야 합니다.

1
    glutInitDisplayMode(GLUT_DOUBLE); //더블 버퍼를 사용하도록 설정
cs


display 콜백 함수 마지막에  glutSwapBuffers 함수를 호출함으로써 프론트 버퍼와 백 버퍼간의 교환이 이루어집니다.

1
2
3
4
5
6
    //더블 버퍼링을 하고 있다면, 프론트 버퍼와 백 버퍼 2개가 사용된다.현재 화면에 보여지는 것은 프론트 버퍼에 있는 내용이다.
    //백 버퍼는 다음 장면을 위해 렌더링을 하고 있는 곳이다.백 버퍼의 렌더링이 완료되면 두 개의 버퍼를 교환(swap)한다.
    //화면에 업데이트된 프론트 버퍼에 있는 내용이 출력된다.
 
    //싱글 버퍼라면 버퍼에 있는 것을 화면에 출력한다.
    glutSwapBuffers();
cs




굵은 글씨가 이전 포스팅에서 수정된 부분들입니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
//상대경로로 헤더파일을 지정합니다.
#include ".\include\GL\freeglut.h"
#include <iostream>
 
//사용할 라이브러리를 지정해줍니다.
#pragma comment(lib, "freeglut.lib")
#pragma comment(lib, "glew32.lib")
 
using namespace std;
 
 
GLfloat current_angle = 0.0f; //삼각형의 현재 회전 각도
 
void keyboard(unsigned char key, int x, int y)
{
    cout << "다음 키가 눌러졌습니다. \"" << key << "\" ASCII: " << (int)key << endl;
 
    //ESC 키가 눌러졌다면 프로그램 종료
    if (key == 27)
    {
        exit(0);
    }
}
 
 
void drawBitmapText(char *str, float x, float y, float z)
{
    glRasterPos3f(x, y, z); //문자열이 그려질 위치 지정
 
    while(*str)
    {
        //GLUT_BITMAP_TIMES_ROMAN_24 폰트를 사용하여 문자열을 그린다.
        glutBitmapCharacter(GLUT_BITMAP_TIMES_ROMAN_24, *str);
 
        str++;
    }
}
 
 
void display() 
{
    glClearColor(0.0f, 0.0f, 0.0f, 0.0f); //glClear에서 컬러 버퍼 지운 후 윈도우를 채울 색을 지정, 검은색
    glClear(GL_COLOR_BUFFER_BIT); //컬러 버퍼를 지운다.
 
    glMatrixMode(GL_MODELVIEW); //이후 계산은 modelview matrix에 영향을 주게됨
    glLoadIdentity(); //modleview matrix를 초기화
 
    //z축을 중심으로 설정된 current_angle로 회전한다.
    glRotatef(current_angle, 0.0f, 0.0f, 1.0f);
    
    //중앙이 원점에 오도록 삼각형을 그린다. 
    glBegin(GL_TRIANGLES); //3점이 하나의 삼각형을 구성한다. 반시계 방향으로 3점의 vertex를 지정해줘야 한다.
    glColor3f(1.0f, 0.0f, 0.0f); //빨간색 지정
    glVertex3f(-0.5f, -0.5f, 0.0f);    // 왼쪽 아래 vertex
    glColor3f(0.0f, 1.0f, 0.0f); //녹색 지정
    glVertex3f(0.5f, -0.5f, 0.0f);    // 오른쪽 아래 vertex
    glColor3f(0.0f, 0.0f, 1.0f); //파란색 지정
    glVertex3f(0.0f, 0.5f, 0.0f);    // 위쪽 vertex
    glEnd();
 
    glColor3f(1.0f, 1.0f, 1.0f);//흰색 지정
    drawBitmapText("-0.5, -0.5"-0.5f, -0.5f, 0.0f);// 지정한 좌표에 문자열 출력
    drawBitmapText("0.5, -0.5"0.5f, -0.5f, 0.0f);
    drawBitmapText("0.0, 0.5"0.0f, 0.5f, 0.0f);
    
    //display 함수 호출될때마다 회전각도 증가시킴
    current_angle += 0.5;
    cout << current_angle << endl;
 
 
    //더블 버퍼링을 하고 있다면, 프론트 버퍼와 백 버퍼 2개가 사용된다.현재 화면에 보여지는 것은 프론트 버퍼에 있는 내용이다.
    //백 버퍼는 다음 장면을 위해 렌더링을 하고 있는 곳이다.백 버퍼의 렌더링이 완료되면 두 개의 버퍼를 교환(swap)한다.
    //화면에 업데이트된 프론트 버퍼에 있는 내용이 출력된다.
 
    //싱글 버퍼라면 버퍼에 있는 것을 화면에 출력한다.
    glutSwapBuffers();
}
 
 
void reshape(GLsizei width, GLsizei height) 
{  
    if (height == 0) height = 1;                // 0으로 나누는 것 방지
    GLfloat aspect = (GLfloat)width / (GLfloat)height;
 
    //변경된 윈도우크기로 viewport를 설정한다.
    glViewport(00, width, height);
 
    glMatrixMode(GL_PROJECTION);  //뒤에 오는 계산들은 Projection matrix에 영향을 주도록 설정
    glLoadIdentity();             //projection matrix 초기화
    if ( width >= height) {
        // aspect >= 1 이면, height를 [-1,1]로 설정하고 width는 [-1*aspect, 1*aspect]로 설정한다.
        // left, right, top, bottom
        gluOrtho2D(-1.0 * aspect, 1.0 * aspect, -1.01.0);
    }
    else {
        // aspect < 1이면, width를 [-1,1]로 설정하고 height를  [-1/aspect, 1/aspect]로 설정한다.
        gluOrtho2D(-1.01.0-1.0 / aspect, 1.0 / aspect);
    }
 
    //뒤에 오는 계산들은 Modelview Matrix에 영향을 주도록 설정한다. 
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity(); //Modelview matrix 초기화
}
 
 
void timer(int value) {
    glutPostRedisplay();      //윈도우를 다시 그리도록 요청
    glutTimerFunc(30, timer, 0); //다음 타이머 이벤트는 30밀리세컨트 후  호출됨.
}
 
 
int main(int argc, char** argv) 
{
    glutInit(&argc, argv);  //GLUT 초기화
 
    glutInitDisplayMode(GLUT_DOUBLE); //더블 버퍼를 사용하도록 설정
    glutInitWindowSize(500500);   //윈도우의 width와 height
    glutInitWindowPosition(100100); //윈도우의 위치 (x,y)
    glutCreateWindow("OpenGL Example"); //윈도우 생성
 
    //디스플레이 콜백 함수 등록, display함수는 윈도우 처음 생성할 때와 화면 다시 그릴 필요 있을때 호출된다. 
    glutDisplayFunc(display); 
    //키보드 콜백 함수 등록, 키보드가 눌러지면 호출된다. 
    glutKeyboardFunc(keyboard);
    //reshape 콜백 함수 등록, reshape함수는 윈도우 처음 생성할 때와 윈도우 크기 변경시 호출된다.
    glutReshapeFunc(reshape);
    //타이머 콜백 함수 등록, 처음에는 바로 호출됨.
    glutTimerFunc(0, timer, 0);
 
    //GLUT event processing loop에 진입한다.
    //이 함수는 리턴되지 않기 때문에 다음줄에 있는 코드가 실행되지 않는다. 
    glutMainLoop();          
 
    return 0;
}
cs


반응형

문제 발생시 지나치지 마시고 댓글 남겨주시면 가능한 빨리 답장드립니다.

도움이 되셨다면 토스아이디로 후원해주세요.
https://toss.me/momo2024


제가 쓴 책도 한번 검토해보세요 ^^

+ Recent posts