학기 중 배웠던 내용을 바탕으로 미니 프로젝트를 제작해보았다. 전체적인 내용은 여러 개의 teapot들이 놀이공원의 기구처럼 돌아가는 것이고, 여기에 주전자의 모양이나 배경색을 변경할 수 있도록 구현하였다. 그리고 이 프로젝트의 목표는 '학기 중 배웠던 기능들을 빠짐없이 구현하기'로 잡았다. 

 

기본적인 화면 구성의 모습은 다음과 같다.

 

기본 화면

지금부터 프로젝트에서 구현한 기능들에 대해서 설명하겠다.

 

첫 번째, 윈도우의 크기가 변하더라도 화면의 오브젝트들에는 영향을 끼치지 않도록 화면 왜곡 제거 기능을 구현했다.

기본 화면 (왼쪽)          /          화면 크기가 변경된 모습 (오른쪽)

두 번째, 실제 놀이기구처럼 모든 teapot들이 함께 움직이도록 구현하였다. 이는 '계층 구조 모델링'을 이용하여 모든 오브젝트들이 동시에 움직이도록 할 수 있었다.

 

세 번째, teapot의 움직임은 키보드 콜백과 타이머 콜백을 이용하여 구현하였다. 같은 기능이지만, 각각의 루트로 기능을 실행하기 위해서는 키보드와 메뉴를 통해 할 수 있도록 해놓았기 때문에 겹침을 없게 하였다.

 

네 번째, 화면의 색상을 변경할 수 있도록 하였다. 이것은 마우스 콜백을 이용하여 구현하였다. 또한 IsBlue라는 boolean형의 변수를 이용하여, true일 경우에 (=왼쪽 마우스 버튼이 눌림) 베경이 하늘색으로 바뀌고, false일 경우에 (=눌리지 않은 경우)기본 옵션인 하얀색으로 설정되도록 하였다.

 

다음은 더 많은 기능을 구현하기 위해 메뉴 기능을 구현하였다. 메인 메뉴의 구성은 밑의 이미지와 같고, Exit항목을 제외한 나머지는 서브메뉴가 있다. 서브메뉴는 teapot을 자동으로 움직이게 하는 기능과 형태를 변경하는 기능을 수행한다.

자동 움직임은 IsAuto라는 Boolean형 변수를 사용하였는데, false를 디폴트로 하여 메뉴 항목을 선택하지 않았을 경우에는 정지된 상태를 유지하게 하였다. 또한 teapot의 형태는 Wire나 Solid를 선택할 수 있게 하였고, 각 메뉴를 선택했을 시 변경이 되도록 IsWire라는 Boolean형 변수를 이용하였다.

 

메인 메뉴
2가지 서브 메뉴

마지막으로 현재 teapot의 형태가 무엇인지 출력하는 문자열을 구현하였다. 이는 티스토리의 '멈춤보단 천천히라도'의 글을 참고하였다. 자세한 주소는 다음과 같다. https://webnautes.tistory.com/1092

 

OpenGL 강좌 - 정사각형 그리기

OpenGL 프로그래밍을 위한 준비과정은 다음 포스팅을 참고하세요. [그래픽스&컴퓨터비전/Augmented Reality] - OpenGL( freeGLUT ) 을 Visual Studio 2015에 연동하기 [그래픽스&컴퓨터비전/Augmented Reality] -..

webnautes.tistory.com

완성된 코드는 다음 cpp파일을 통해 확인할 수 있다.

Spin_Teapot.cpp
0.00MB

'OpenGL' 카테고리의 다른 글

[OpenGL] 5. 선형보간  (0) 2019.07.19
[OpenGL] 4. 메뉴 콜백  (0) 2019.07.16
[OpenGL] 3. 키보드 콜백  (0) 2019.07.10
[OpenGL] 2. 마우스 콜백  (0) 2019.07.05
[OpenGL] 1. 삼각형 그리기  (0) 2019.07.05

메인 메뉴
서브 메뉴
작은 원구와 환원체
큰 원구와 원환체

메뉴 콜백을 이용해보았다. 프로그램을 실행시켰을 때 바로 나오는 기본 화면은 작은 원구의 모습이다.

오른쪽 마우스를 클릭하면 메인 메뉴가 나오는데, 여기서 오브젝트의 모양과 크기를 변경할 수 있다. 변경하고 싶은 사항이 있으면 메뉴의 항목에 마우스를 두면 세부사항에 대한 서브 메뉴가 나타난다.

 

#include <GL/glut.h>
#include  <iostream>

GLboolean IsSphere = true;
GLboolean IsSmall = true;

void MyDisplay() {
glClear(GL_COLOR_BUFFER_BIT);
glColor3f(1.0, 1.0, 1.0);
if ((IsSphere) && (IsSmall))
glutWireSphere(0.2, 15, 15); // 작은 원구
else if ((IsSphere) && (!IsSmall))
glutWireSphere(0.4, 15, 15); // 큰 원구
else if ((!IsSphere) && (IsSmall))
glutWireTorus(0.1, 0.3, 40, 20); // 작은 원환체
else glutWireTorus(0.2, 0.5, 40, 20); // 큰 원환체
glFlush();
}

void MyMainMenu (int entryID) {
if (entryID == 1)
exit(0);
glutPostRedisplay(); // 프로그램 종료
}

void MySubMenu_shape (int entryID) {
if (entryID == 1)
IsSphere = true; // 원구 그리기
else if (entryID == 2)
IsSphere = false; // 원환체 그리기
glutPostRedisplay();
}

void MySubMenu_size (int entryID) {
if (entryID == 1)
IsSmall = true; // 작은 크기로 그리기
else if (entryID == 2)
IsSmall = false; // 큰 크기로 그리기
glutPostRedisplay();
}

int main(int argc, char** argv) {
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGB);
glutInitWindowSize(300, 300);
glutInitWindowPosition(0, 0);
glutCreateWindow("Menu Callback");

glClearColor(0.0, 0.0, 0.0, 1.0);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(-1.0, 1.0, -1.0, 1.0, -1.0, 1.0);

//Change Shape 서브 메뉴의 콜백 함수 등록
GLint MySubMenuID_shape = glutCreateMenu(MySubMenu_shape);
glutAddMenuEntry("Draw Sphere", 1);
glutAddMenuEntry("Draw Torus", 2);

//Change Size 서브 메뉴의 콜백 함수 등록
GLint MySubMenuID_size = glutCreateMenu(MySubMenu_size);
glutAddMenuEntry("Small One", 1);
glutAddMenuEntry("Big One", 2);

GLint MyMainMenuID = glutCreateMenu(MyMainMenu);
glutAddSubMenu("Change Shape", MySubMenuID_shape);
glutAddSubMenu("Change Size", MySubMenuID_size);
glutAddMenuEntry("Exit", 1);

glutAttachMenu(GLUT_RIGHT_BUTTON);
glutDisplayFunc(MyDisplay);
glutMainLoop();

return 0;
}

'OpenGL' 카테고리의 다른 글

[OpenGL] 5. 선형보간  (0) 2019.07.19
[OpenGL] 미니 프로젝트  (0) 2019.07.17
[OpenGL] 3. 키보드 콜백  (0) 2019.07.10
[OpenGL] 2. 마우스 콜백  (0) 2019.07.05
[OpenGL] 1. 삼각형 그리기  (0) 2019.07.05

기본 화면

키보드 콜백을 이용해보았다. 방향키로 회색 사각형 오브젝트를 이동시키고, ESC키를 누르면 프로그램을 종료할 수 있도록 구현했다.

 

#include  <iostream>
#include <gl/glut.h>

double trans_left = 0, trans_up = 0;      //오브젝트 이동을 위한 변수 (좌우/위아래)

 

//디스플레이 콜백함수 
void MyDisplay() {
glClear(GL_COLOR_BUFFER_BIT); 
glColor3f(0.5, 0.5, 0.5);
glBegin(GL_POLYGON); 
glVertex3f(-0.5 + trans_left, -0.5 + trans_up, 0.0);
glVertex3f(0.5 + trans_left, -0.5 + trans_up, 0.0);
glVertex3f(0.5 + trans_left, 0.5 + trans_up, 0.0);
glVertex3f(-0.5 + trans_left, 0.5 + trans_up, 0.0);
glEnd();
glFlush();
}

void MyReshape (int NewWidth, int NewHeight) {
glViewport(0, 0, NewWidth, NewHeight);
GLfloat WidthFactor = (GLfloat)NewWidth / (GLfloat)300;
GLfloat HeightFactor = (GLfloat)NewHeight / (GLfloat)300;
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(-1.0 * WidthFactor, 1.0 * WidthFactor,
-1.0 *HeightFactor, 1.0 * HeightFactor, -1.0, -1.0);
}

void MyKeyboard (unsigned char KeyPressed, int X,int Y) {
switch (KeyPressed) {
case 27:
exit(0);
break;
}
}

void MySpecialKey(int Key,int X, int Y)
{
switch (Key) {
case GLUT_KEY_LEFT:     //왼쪽 키
trans_left = trans_left - 0.1;
glutPostRedisplay();
break;
case GLUT_KEY_RIGHT:     //오른쪽 키
trans_left = trans_left + 0.1;
glutPostRedisplay();
break;
case GLUT_KEY_UP:      //위 키
trans_up = trans_up + 0.1;
glutPostRedisplay();
break;
case GLUT_KEY_DOWN:      //아래 키
trans_up = trans_up - 0.1;
glutPostRedisplay();
break;
}
}

int main(int argc, char** argv) {
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGB);
glutInitWindowSize(300, 300);
glutInitWindowPosition(0, 0);
glutCreateWindow("Keyboard Callback");
glClearColor(1.0, 1.0, 1.0, 1.0);      // 배경색 
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(-1.0, 1.0, -1.0, 1.0, -1.0, 1.0);


glutDisplayFunc(MyDisplay);
// ESC 키에 대한 이벤트
glutKeyboardFunc(MyKeyboard);
//방향 키에 대한 이벤트
glutSpecialFunc(MySpecialKey);
glutMainLoop();

return 0;
}

'OpenGL' 카테고리의 다른 글

[OpenGL] 5. 선형보간  (0) 2019.07.19
[OpenGL] 미니 프로젝트  (0) 2019.07.17
[OpenGL] 4. 메뉴 콜백  (0) 2019.07.16
[OpenGL] 2. 마우스 콜백  (0) 2019.07.05
[OpenGL] 1. 삼각형 그리기  (0) 2019.07.05

행사 입구 모습. 오른쪽에 행사 데스크가 있다.
Hall B는 안쪽에 위치해있다.

이 행사는 작년 전공 수업을 통해 알게 되었고, 연례행사로 진행되는 것인지 운이 좋게도 바로 다음 해인 올해 참가할 수 있었다. 사전등록을 한 후, 행사 첫 날인 5월 30일에 참가하였다. 사전등록은 개최일 3주 전에 해놓았는데, 그 덕분에 7,000원의 입장료를 내고 참가하였다. 만약, 사전등록을 하지 않은 경우는 20,000원의 입장료가 생기는 것으로 알고 있다. 입장 전에 사전등록 데스크에서 확인을 받았는데, 명찰표와 함께 안대를 받았다. 이 안대는 우리가 흔히 알고 있는 형태가 아니라, vr 안경을 쓸 때 오염물이 묻지 않도록 하기 위한 것으로 눈 쪽에는 구멍이 뚫여 있어 앞을 볼 수 있다.

 

이 부스에서는 4명의 사람들이 체험할 수 있도록 해놓았다.
화면 구성이 요즘 PC게임들과 유사하다.

입장했을 때의 첫 느낌은 마치 게임방에 온 것 같았다. 왜냐하면 전체적으로 어두운데, 부스 쪽에는 여러 색의 조명이 비추고 있었고 모니터를 통한 게임 화면이 흥미를 이끌었기 때문이다. 이 중에서 가장 기억에 남는 것은 'VR기술을 이용한 FPS' 게임이다. 요즘 "오버워치"라는 FPS 게임에 빠져있다보니 비슷한 화면 구성에 처음 눈이 갔다. 그렇기 때문에 체험해보고 싶다는 생각이 들었지만 VR기기를 쓰고, 컨트롤러를 들고 게임을 즐기는 자신의 모습을 상상해보았을 때 다른 사람들이 보기에 이상해보이겠다는 생각이 선듯 도전하지 못하게했다. 이렇게 다른 사람들의 시선때문에 해보고 싶은 것을 못하는 버릇은 스스로 고쳐야 할 부분이라고 생각한다. 그러나 한편으로는 VR기술은 게임을 더 현실감있게 즐기게 해주기는 하지만, VR기기를 사용하는데 있어서 큰 동작이 이용되지 않아도 그 장점을 그대로 유지하는 방법은 없는 것일까라는 생각도 했다. 그렇게 된다면 더 다양한 장소에서 더 많은 사람들이 이 기술을 이용할 수 있을 것으로 예상된다.

 

또 한때 선풍적인 인기를 끌었던 "POCKETMON GO"와 유사한 형태의 AR 게임도 있었고, 무엇보다 교육을 VR·AR기술에 접목한 것도 많았다. 그 범위는 영어 교육부터 시작해서 요즘 한창 대두되고 있는 코딩 교육을 위한 것들까지 다양했다. 이 중에서 어린이들에게 동화를 들려주는 콘텐츠를 만드는 부스에서 체험해보았다. 이 콘텐츠는 동화책의 내용을 연극으로 재구성하여 내레이션과 함께 보여주는 것이었다. 체험을 하면서 느낀 점은 호기심이 많은 아이들이 VR기기를 통해 연극을 볼 수 있다는 점에 흥미를 갖고 동화책을 자발적으로 읽게 되겠다고 생각했다. 그리고 반면 그 기기가 안경처럼 가볍지 않다보니 10분 정도의 콘텐츠를 이용하면서 목에 무리가 가는 단점도 있겠다는 생각하게 되었다. 

 

MOSTER VR의 모습. 많은 사람들이 줄서있다.

전시장 안으로 들어가보면 "MONSTER VR"이라는 코너가 있다. 이곳은 VR기술과 함께 실제로 바이킹과 자이로드롭 같은 놀이기구를 탈 수 있도록 해놓은 곳이다. 행사 데스크에서 여기서 이용할 수 있는 자유이용권 교환권을 주었는데, 놀이기구를 좋아하지 않는 편이라 이용은 하지 않았다. 하지만 놀이기구를 좋아한다면 적극 추천한다!

 

행사 데스크에서 나눠준 안대의 모습.

마지막으로 "THIRTEENTH FLOOR"라는 부스에 가보았다. 여기는 행사 데스크에서 주었던 안대가 자체적으로 준비되어 있기 때문에, 고양이 귀 모양의 안대가 부담스러운 분들은 체험을 하고 받아가는 것도 좋을 것같다. 체험 장소를 둘러보고 있을 때, 바로 체험 도우미께서 오셔서 안내를 해주었기 때문에 편리하게 이용할 수 있었다. 여기서 제공하는 콘텐츠는 여러가지가 있는데, 실제로 체험해본 것은 엔터테인먼트 SM의 연예인들과 에버랜드의 여러 공간을 함께 즐기는 것이었다. 화면뿐만 아니라 연예인의 목소리도 들리기 때문에 실제로 함께 있는 것같은 느낌을 경험할 수 있었다. 또한 콘텐츠 속 실감나는 연예인의 연기도 이것에 한 몫 했다고 생각한다. 

 

처음 이 EXPO에 대해 들었을 때는 평소에 잘 경험해보지 못한 기술들을 체험할 수 있다는 것이 기대를 불러일으켰으나 기대만큼 크지 않은 규모에 실망하기도 하였다. 하지만 일상생활에서 경험해볼 수 없는 VR·AR기술을 만나볼 수 있고, 나아가 다양한 분야에 접목된 사례를 한 자리에서 살펴볼 수 있기 때문에 이 행사의 가치는 스스로에게 컸다고 생각한다. 그리고 마지막 날인 6월 1일을 제외한 나머지 행사 기간은 기업인이나 대학생들을 대상으로 진행되기 때문에 재미보다는 기술적 정보를 알리는 것이 우선이었을 것이다. 그렇기 때문에 만약 게임을 즐겨보는데 목적이 있다면, 주말에 참가하는 것이 좋을 것이다. 

 

# 스스로 찾아보고, 혼자 참가해본 첫 행사로, 앞으로 여러 행사에 참가해 경험을 길러야겠다 :)

결과 화면 1
결과 화면 2

마우스 콜백을 이용해 드래그를 하면 사각형을 그릴 수 있도록 구현하였다.

 

#include <GL/glut.h>

GLint TopLeftX, TopLeftY, BottomRightX, BottomRightY;

void MyDisplay() {
glViewport(0, 0, 500, 500);
glClear(GL_COLOR_BUFFER_BIT);
glColor3f(1.0, 1.0, 1.0);
glBegin(GL_POLYGON);
glVertex3f(TopLeftX/500.0, (500-TopLeftY)/500.0, 0.0);
glVertex3f(TopLeftX/500.0, (500-BottomRightY)/500.0, 0.0);
glVertex3f(BottomRightX/500.0, (500-BottomRightY)/500.0, 0.0);
glVertex3f(BottomRightX/500.0, (500-TopLeftY)/500.0, 0.0);
glEnd();
glFlush();
}

void MyMouseClick(GLint Button, GLint State, GLint X, GLint Y) {
if (Button== GLUT_LEFT_BUTTON && State == GLUT_DOWN) {
TopLeftX = X;
TopLeftY = Y;
}
}

void MyMouseMove (GLint X, GLint Y) {
BottomRightX = X;
BottomRightY = Y;
glutPostRedisplay();
}

int main(int argc, char** argv) {
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGB);
glutInitWindowSize(500, 500);
glutInitWindowPosition(0, 0);
glutCreateWindow("Mouse Callback");

glClearColor(0.0, 0.0, 0.0, 1.0);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0.0, 1.0, 0.0, 1.0, -1.0, 1.0);

glutDisplayFunc(MyDisplay);
//마우스 콜백 함수 등록
glutMouseFunc(MyMouseClick);
glutMotionFunc(MyMouseMove);
glutMainLoop();

return 0;
}

'OpenGL' 카테고리의 다른 글

[OpenGL] 5. 선형보간  (0) 2019.07.19
[OpenGL] 미니 프로젝트  (0) 2019.07.17
[OpenGL] 4. 메뉴 콜백  (0) 2019.07.16
[OpenGL] 3. 키보드 콜백  (0) 2019.07.10
[OpenGL] 1. 삼각형 그리기  (0) 2019.07.05

결과 화면

검은색 바탕에 빨간 삼각형을 그려보았다.

삼각형은 glColor3f()으로 색상을 정하였고, glVertex3f()으로 모양을 표현하였다. 또한, 바탕은 glClearColor()의 매개변수를 0.0, 0.0, 0.0로 지정해 검은색을 나타내었다.


코드는 다음과 같다.

 

#include <gl/glut.h>

 

void MyDisplay() {

glClear(GL_COLOR_BUFFER_BIT);

glViewport(0, 0, 300, 300);

glColor3f(1.0, 0.0, 0.0);                    // 삼각형 그리기

glBegin(GL_POLYGON);

glVertex3f(-0.5, -0.5, 0.0);

glVertex3f(0.5, -0.5, 0.0);

glVertex3f(0.0, 0.5, 0.0);

glEnd();

glFlush();

}

 

int main(int argc, char** argv) {

glutInit(&argc, argv);

glutInitDisplayMode(GLUT_RGB);

glutInitWindowSize(300, 300);

glutInitWindowPosition(0, 0);

glutCreateWindow("Triangle");

 

glClearColor(0.0, 0.0, 0.0, 1.0);      // 배경색 지정

glMatrixMode(GL_PROJECTION);

glLoadIdentity();

glOrtho(-1.0, 1.0, -1.0, 1.0, -1.0, 1.0);

 

glutDisplayFunc(MyDisplay);

glutMainLoop();

return 0;

}

'OpenGL' 카테고리의 다른 글

[OpenGL] 5. 선형보간  (0) 2019.07.19
[OpenGL] 미니 프로젝트  (0) 2019.07.17
[OpenGL] 4. 메뉴 콜백  (0) 2019.07.16
[OpenGL] 3. 키보드 콜백  (0) 2019.07.10
[OpenGL] 2. 마우스 콜백  (0) 2019.07.05

+ Recent posts