컴퓨터 공학/Qt

[ Qt 프로그래밍 ] OpenGL 로 큐브 만들기

혼새미로 2015. 11. 26. 23:46
반응형

이번에는 Qt로 OpenGL을 이용한 큐브를 만들어보겠습니다.

Qt에서 제공하는 OpenGL은 대부분의 기능을 지원합니다.

GL.h을 사용하고, glut.h 혹은 glu.h는 사용하지 않습니다.

그래서 glut로 시작하는 함수 혹은 glu로 시작하는 함수는 읽지 못합니다.

 

다음은 프로젝트의 일부분 소스코드입니다.

 

Colored By Color Scripter

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
#ifndef GLWIDGET_H
#define GLWIDGET_H
 
#include <QGLWidget>
 
class QTimer;
 
class GLWidget : public QGLWidget
{
    Q_OBJECT
public:
    GLWidget();
    ~GLWidget();
 
private:
    void paintGL(); //실제 그래픽을 그린다.
    void initializeGL(); //Opengl 초기화
    void resizeGL(int w, int h); //위젯 크기 변했을때 발생하는 함수
    void mousePressEvent(QMouseEvent *event); //마우스클릭 이벤트
    void mouseMoveEvent(QMouseEvent *event); //마우스이동이벤트
 
    QTimer* timer; //타이머 0.01초마다 발생
 
    GLfloat xRot,yRot,zRot; //회전을 위한 변수
 
 
    GLfloat windowWidth; //위젯 길이
    GLfloat windowHeight; //위젯 높이
    QPoint lastPos; //마우스 이동을 위한 변수
 
signals:
     void xRotationChanged(int angle); //X축 회전했을때
     void yRotationChanged(int angle); //Y축 회전했을때
     void zRotationChanged(int angle); //Z축 회전했을때
 
private slots:
    void timerFunction(); //0.01초 지나면 이함수 실행
    void setXRotation(int angle); //X축으로 회전하기
    void setYRotation(int angle); //Y축으로 회전하기
    void setZRotation(int angle); //Z축으로 회전하기
 
};
 
#endif // GLWIDGET_H
 

 

 

 

Colored By Color Scripter

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
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
#include "glwidget.h"
#include <QTimer>
#include <math.h>
#include <QMouseEvent>
 
GLWidget::GLWidget()
{
    xRot=yRot=zRot=0.0f;
 
    timer=new QTimer(this); //타이머 생성
    timer->setInterval(10); //0.01초 간격으로 타이머 발생
    connect(timer,SIGNAL(timeout()),this,SLOT(timerFunction())); //타이머와 함수를 연결
    timer->start(); //타이머 시작
 
 
}
 
GLWidget::~GLWidget() //소멸자
{
    delete timer; //프로그램 종료할때 타이머 제거
}
 
void GLWidget::timerFunction()
{
    xRot+=0.9f; //0.01초마다 xRot 변수에 0.9f 씩 더함
    yRot+=0.8f;
 
 
    updateGL(); //GL 업데이트
}
 
void GLWidget::initializeGL() //GL 초기화
{
    glEnable(GL_DEPTH_TEST); //깊이값 반영
}
 
void GLWidget::resizeGL(int w, int h) //위젯 크기 변했을때
{
    GLfloat aspectRatio; //화면 비율
 
    if(h==0)
        h=1;
 
    glViewport(0,0,w,h); //뷰포트 설정
 
    glMatrixMode(GL_PROJECTION); //행렬모드지정
    glLoadIdentity(); //좌표계 초기화
 
    aspectRatio=(GLfloat)w/(GLfloat)h; //화면비율 지정
    if(w<=h)
    {
        windowWidth=1;
        windowHeight=1/aspectRatio;
        glFrustum(-1.0,1.0,-windowHeight,windowHeight,5.0,300.0);//3D
        //glOrtho(-100.0,100.0,-windowHeight,windowHeight,1.0,-1.0);//2D
    }
    else
    {
        windowWidth=1*aspectRatio;
        windowHeight=1;
        glFrustum(-windowWidth,windowWidth,-1.0,1.0,5.0,3000.0);
        //glOrtho(-windowWidth,windowWidth,-100.0,100.0,1.0,-1.0);
    }
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
}
 
void GLWidget::paintGL() //실제 그리는 함수
{
    glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); //화면을 지워준다.
 
 
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    glTranslatef(0.0f,0.0f,-1500.0f); //move along z-axis// 카메라 이동
    glRotatef(yRot,0.0,1.0,0.0); //rotate 30 degress around y-axis
    glRotatef(xRot,1.0,0.0,0.0); //rotate 15 degress around x-axis
 
 
    /* create 3D-Cube */
    glBegin(GL_QUADS); //사각형
 
        //front
        glColor3f(1.0,0.0,0.0);
 
        glVertex3f(101.0,101.0,101.0);
        glVertex3f(-101.0,101.0,101.0);
        glVertex3f(-101.0,-101.0,101.0);
        glVertex3f(101.0,-101.0,101.0);
 
 
        //back
 
        glColor3f(0.0,1.0,0.0);
 
        glVertex3f(101.0,101.0,-101.0);
        glVertex3f(-101.0,101.0,-101.0);
        glVertex3f(-101.0,-101.0,-101.0);
        glVertex3f(101.0,-101.0,-101.0);
 
 
        //top
        glColor3f(0.0,0.0,1.0);
 
        glVertex3f(-101.0,101.0,101.0);
        glVertex3f(101.0,101.0,101.0);
        glVertex3f(101.0,101.0,-101.0);
        glVertex3f(-101.0,101.0,-101.0);
 
 
        //bottom
        glColor3f(0.0,1.0,1.0);
 
        glVertex3f(101.0,-101.0,101.0);
        glVertex3f(101.0,-101.0,-101.0);
        glVertex3f(-101.0,-101.0,-101.0);
        glVertex3f(-101.0,-101.0,101.0);
 
        //right
        glColor3f(1.0,0.0,1.0);
 
        glVertex3f(101.0,101.0,101.0);
        glVertex3f(101.0,-101.0,101.0);
        glVertex3f(101.0,-101.0,-101.0);
        glVertex3f(101.0,101.0,-101.0);
 
 
        //left
        glColor3f(1.0,1.0,0.0);
 
        glVertex3f(-101.0,101.0,101.0);
        glVertex3f(-101.0,-101.0,101.0);
        glVertex3f(-101.0,-101.0,-101.0);
        glVertex3f(-101.0,101.0,-101.0);
 
 
    glEnd();
}
 
static void qNormalizeAngle(int &angle)
{
     while (angle < 0)
         angle += 360 * 16;
     while (angle > 360 * 16)
         angle -= 360 * 16;
}
 
 
void GLWidget::setXRotation(int angle)
 {
     qNormalizeAngle(angle);
     if (angle != xRot) {
         xRot = angle;
         emit xRotationChanged(angle);
         updateGL();
     }
 }
 
 void GLWidget::setYRotation(int angle)
 {
     qNormalizeAngle(angle);
     if (angle != yRot) {
         yRot = angle;
         emit yRotationChanged(angle);
         updateGL();
     }
 }
 
 void GLWidget::setZRotation(int angle)
 {
     qNormalizeAngle(angle);
     if (angle != zRot) {
         zRot = angle;
         emit zRotationChanged(angle);
         updateGL();
     }
 }
 
void GLWidget::mousePressEvent(QMouseEvent *event)
 {
     lastPos = event->pos();
 }
 
 void GLWidget::mouseMoveEvent(QMouseEvent *event)
 {
     int dx = event->x() - lastPos.x();
     int dy = event->y() - lastPos.y();
 
     if (event->buttons() & Qt::LeftButton) {
         setXRotation(xRot + 1 * dy);
         setYRotation(yRot + 1 * dx);
     } else if (event->buttons() & Qt::RightButton) {
         setXRotation(xRot + 1 * dy);
         setZRotation(zRot + 1 * dx);
     }
     lastPos = event->pos();
}
 

 

 

 

 

다음은 첨부파일에 올려둔 프로젝트를 실행한 결과입니다.

마우스로 드래그해서 큐브를 회전할 수도 있습니다.

가만히 두면 자동으로 회전합니다.

필요하신분은 자유롭게 사용해도 됩니다.


 

반응형