본 포스팅을 보기 전에 아래 포스팅을 참고하세요..
[그래픽스&컴퓨터비전/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(0, 0, 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.0, 1.0); } else { // aspect < 1이면, width를 [-1,1]로 설정하고 height를 [-1/aspect, 1/aspect]로 설정한다. gluOrtho2D(-1.0, 1.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(500, 500); //윈도우의 width와 height glutInitWindowPosition(100, 100); //윈도우의 위치 (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 |
'OpenGL' 카테고리의 다른 글
OpenCV로 얻은 Camera 영상을 OpenGL 배경으로 사용하기 (7) | 2016.12.30 |
---|---|
OpenGL 강좌 - 키보드로 3D 큐브(Cube) 움직이기 (0) | 2016.12.29 |
OpenGL 강좌 - 정사각형 그리기 (7) | 2016.12.20 |
Intel HD 4600에서 벌칸(Vulkan) API 사용해보기 (4) | 2016.11.15 |
Ubuntu 16.04에서 OpenGL( freeGLUT ) 프로그래밍 (2) | 2016.11.10 |
시간날때마다 틈틈이 이것저것 해보며 블로그에 글을 남깁니다.
블로그의 문서는 종종 최신 버전으로 업데이트됩니다.
여유 시간이 날때 진행하는 거라 언제 진행될지는 알 수 없습니다.
영화,책, 생각등을 올리는 블로그도 운영하고 있습니다.
https://freewriting2024.tistory.com
제가 쓴 책도 한번 검토해보세요 ^^
그렇게 천천히 걸으면서도 그렇게 빨리 앞으로 나갈 수 있다는 건.
포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!