-
Notifications
You must be signed in to change notification settings - Fork 0
/
Example1.cpp
184 lines (156 loc) · 4.9 KB
/
Example1.cpp
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
// Model-View matrix and Projection matrix
// Orthogonal or Orthographic projection
// Windows Events - Keyboard & Mouse
// Rotate Rectangle
#include "header/Angel.h"
#include "Common/CQuad.h"
#include "Common/CQuadEX1.h"
#define SPACE_KEY 32
// 必須在 glewInit(); 執行完後,在執行物件實體的取得
CQuad *g_pQuad; // 宣告 Quad 指標物件,結束時記得釋放
// For Model View and Projection Matrix
mat4 g_mxModelView(1.0f);
mat4 g_mxProjection;
// For Rotation
int g_iAxis = 2; // 旋轉軸,0:X, 1:Y, 2:Z
GLfloat g_fAngle = 0; // X/Y/Z 三軸的旋轉角度
GLfloat g_fDir = 1; // 旋轉方向
bool m_bAutoRotation = false; // Controlled by Space Key
//----------------------------------------------------------------------------
// 函式的原型宣告
void IdleProcess();
void init( void )
{
// 必須在 glewInit(); 執行完後,在執行物件實體的取得
g_pQuad = new CQuad;
// 產生 projection 矩陣,此處為產生正投影矩陣
g_mxProjection = Ortho(-2.0f, 2.0f, -2.0f, 2.0f, -2.0f, 2.0f);
g_pQuad->setShader(g_mxModelView, g_mxProjection);
glClearColor( 0.0, 0.0, 0.0, 1.0 ); // black background
}
void AutomaticRotation(void){
mat4 mxRot;
g_fAngle += g_fDir * 0.025f; // 旋轉角度遞增(遞減) 0.025 度
if( g_fAngle > 360.0 ) g_fAngle -= 360;
else if (g_fAngle < 0.0) g_fAngle += 360.0;
else ;
// 計算旋轉矩陣並更新到 Shader 中
if( g_iAxis == 0 ) mxRot = RotateX(g_fAngle);
else if( g_iAxis == 1 ) mxRot = RotateY(g_fAngle);
else mxRot = RotateZ(g_fAngle);
g_pQuad->setTRSMatrix(mxRot);
}
//----------------------------------------------------------------------------
void GL_Display( void )
{
glClear( GL_COLOR_BUFFER_BIT ); // clear the window
g_pQuad->draw();
glutSwapBuffers(); // 交換 Frame Buffer
}
void onFrameMove(float delta)
{
if( m_bAutoRotation ) AutomaticRotation();
//GL_Display();
}
//----------------------------------------------------------------------------
void reset()
{
g_iAxis = 2;
g_fAngle = 0;
g_fDir = 1;
m_bAutoRotation = false;
g_pQuad->setTRSMatrix(g_mxModelView);
}
//----------------------------------------------------------------------------
void Win_Keyboard( unsigned char key, int x, int y )
{
switch ( key ) {
case SPACE_KEY:
m_bAutoRotation = !m_bAutoRotation;
break;
case 68: // D key
case 100: // d key
g_fDir = -1 * g_fDir;
break;
case 82: // R key
case 114: // r key
reset();
break;
case 033:
delete g_pQuad;
exit( EXIT_SUCCESS );
break;
}
}
//----------------------------------------------------------------------------
void Win_Mouse(int button, int state, int x, int y) {
switch(button) {
case GLUT_LEFT_BUTTON: // 目前按下的是滑鼠左鍵
if ( state == GLUT_DOWN ) { // 目前的滑鼠狀態是按住,換成 X 軸
if( g_iAxis != 0 ) { g_iAxis = 0; g_fAngle = 0; } // 換軸就重設
}
break;
case GLUT_MIDDLE_BUTTON: // 目前按下的是滑鼠中鍵 ,換成 Y 軸
if ( state == GLUT_DOWN ) {
if( g_iAxis != 1 ) { g_iAxis = 1; g_fAngle = 0; }
}
break;
case GLUT_RIGHT_BUTTON: // 目前按下的是滑鼠右鍵
if ( state == GLUT_DOWN ){ // 目前按下的是滑鼠右鍵,換成 Z 軸
if( g_iAxis != 2 ) { g_iAxis = 2; g_fAngle = 0; }
}
break;
default:
break;
}
}
//----------------------------------------------------------------------------
void Win_SpecialKeyboard(int key, int x, int y) {
mat4 mxRot;
if( !m_bAutoRotation ) { // 沒有自動旋轉下才有作用
switch(key) {
case GLUT_KEY_LEFT: // 目前按下的是向左方向鍵
g_fAngle += 2.0; // 逆時針為正方向
break;
case GLUT_KEY_RIGHT: // 目前按下的是向右方向鍵
g_fAngle -= 2.0; // 順時針為負方向
break;
default:
break;
}
// 計算旋轉矩陣並更新到 Shader 中
if( g_iAxis == 0 ) mxRot = RotateX(g_fAngle);
else if( g_iAxis == 1 ) mxRot = RotateY(g_fAngle);
else mxRot = RotateZ(g_fAngle);
g_pQuad->setTRSMatrix(mxRot);
}
}
//----------------------------------------------------------------------------
void GL_Reshape(GLsizei w, GLsizei h)
{
glViewport(0, 0, w, h);
}
//----------------------------------------------------------------------------
int main( int argc, char **argv )
{
glutInit(&argc, argv);
glutInitDisplayMode( GLUT_RGBA | GLUT_DOUBLE );
glutInitWindowSize( 512, 512 );
// If you use freeglut the two lines of code can be added to your application
glutInitContextVersion( 3, 2 );
glutInitContextProfile( GLUT_CORE_PROFILE );
glutCreateWindow( "OpenGL_Example1" );
// The glewExperimental global switch can be turned on by setting it to GL_TRUE before calling glewInit(),
// which ensures that all extensions with valid entry points will be exposed.
glewExperimental = GL_TRUE;
glewInit();
init();
glutMouseFunc(Win_Mouse);
glutKeyboardFunc( Win_Keyboard ); // 處理 ASCII 按鍵如 A、a、ESC 鍵...等等
glutSpecialFunc( Win_SpecialKeyboard); // 處理 NON-ASCII 按鍵如 F1、Home、方向鍵...等等
glutDisplayFunc( GL_Display );
glutReshapeFunc( GL_Reshape );
glutIdleFunc( IdleProcess );
glutMainLoop();
return 0;
}