计算机图形学 实验一 旋转的圆与三角形(OPEN_GL入门第一战)
图形学的实验。
实验内容 实验一:OpenGL 基本使用
实验目的: 自行配置 OpenGL 环境,熟悉使用 OpenGL
基本要求:
在屏幕上绘制出一个三角形和一个圆形,分别填充上你喜欢的颜色
可以使用鼠标分别拖动和旋转他们。
实现:
左键平移,右键旋转,Q退出。如果想立体旋转可以选择将display中的glRotate函数改成x,y轴旋转。查一下该函数用法就知道怎么改了。
1 #include<GL/glut.h> 2 #define EXIT_SUCCESS 0 3 #include<stdio.h> 4 #include<math.h> 5 // later Edition 6 bool mouseLeftDown; // 实时记录鼠标左键状态 7 bool mouseRightDown; // 实时记录鼠标左键状态 8 float mouseX, mouseY; // 实时记录鼠标位置,与下一次鼠标位置之间形成微分 9 float triangleAngleX=0; // 存储三角形的X角度积分 10 float triangleAngleY=0; // 存储三角形的Y角度积分 11 12 float CircleAngleX=0; // 存储圆形的X角度积分 13 float CircleAngleY=0; // 存储圆形的Y角度积分 14 15 float PI = 3.415926535; 16 17 float triangleBiasX = 0.6;//三角形偏倚X 18 float triangleBiasY = 0.6;//三角形偏倚Y 19 20 int selected = 0; // -0:未选中 -1:选中三角形 -2:选中圆形 21 float circleBiasX = 0.0;//圆形偏倚X 22 float circleBiasY = 0.0;//圆形偏倚Y 23 24 int added_z_mode =-1; 25 26 void init(void) 27 { 28 glClearColor(0.0, 0.0, 0.0, 0.0); 29 glMatrixMode(GL_MODELVIEW); 30 } 31 32 33 void reshape(int w, int h) 34 { 35 glViewport(0, 0, (GLsizei)w, (GLsizei)h); 36 37 glMatrixMode(GL_PROJECTION); 38 39 glLoadIdentity(); 40 41 if (w <= h) 42 43 glOrtho(-1.5, 1.5, -1.5 * (GLfloat)h / (GLfloat)w, 1.5 * (GLfloat)h / (GLfloat)w, -10.0, 10.0); 44 45 else 46 47 glOrtho(-1.5 * (GLfloat)w / (GLfloat)h, 1.5 * (GLfloat)w / (GLfloat)h, -1.5, 1.5, -10.0, 10.0); 48 49 glMatrixMode(GL_MODELVIEW); 50 51 glLoadIdentity(); 52 53 } 54 55 void display(void) 56 { 57 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 58 glColor3f(1.0, 1.0, 0); 59 60 //进行视角的初始化 61 glLoadIdentity(); 62 gluLookAt(0.0, 0.0, 5.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0); 63 64 // ========================圆形的部分========================== 65 glPushMatrix(); 66 // 移动 67 glTranslatef(circleBiasX, circleBiasY, 0); // 相对于世界原点移动 68 69 //对圆形所在的 模型坐标系 执行旋转,翻转操作 70 71 glRotatef(CircleAngleX+CircleAngleY, 0, 0, 1);// 取消了Z轴旋转功能 72 73 74 75 // 绘制圆形 76 float R = 0.25f; 77 int n = 80; 78 glBegin(GL_POLYGON); 79 for (int i = 0; i < n; i++) // 通过数学计算来画多边形 拟合圆 80 { 81 glColor3f(1- sin(4.0 * i * PI / 80),sin(2.0 * i * PI / 80),0); 82 glVertex2f(R * cos(2* PI * i / n), R * sin(2 * PI * i / n)); 83 } 84 glEnd(); 85 glTranslatef(-circleBiasX, -circleBiasY, 0); // 复位动 86 glPopMatrix(); // 将当前圆形状态区压栈,并且切换回原来的坐标远原点 87 88 89 90 91 //============================================================= 92 93 94 // ==========================三角形============================ 95 glPushMatrix(); 96 glTranslatef(triangleBiasX, triangleBiasY, 0); // 相对于世界原点移动 97 98 99 // 对三角型所在的 模型坐标系 执行旋转,翻转操作 100 101 glRotatef(triangleAngleX+triangleAngleY, 0, 0, 1); // 取消又恢复了Z轴旋转 102 103 104 105 106 107 // 绘制三角形 108 glBegin(GL_TRIANGLES); 109 glColor3f(1.0, 1.0, 0.7); 110 glVertex3f(0, 2.0 / 4, 0); 111 glColor3f(0.0, 1.0, 0); 112 glVertex3f(-1.732 / 4, -1.0 / 4, 0); 113 glColor3f(1.0, 1.0, 0.0); 114 glVertex3f( 1.732 / 4, -1.0 / 4, 0); 115 glEnd(); 116 117 glTranslatef(-triangleBiasX, -triangleBiasY, 0); // 复位 118 glPopMatrix(); 119 // ============================================================ 120 // 将状态全部弹出 121 122 123 glutSwapBuffers(); 124 } 125 int saveStack = 0; 126 int firstSaveFlag = -1; 127 void keyboard(unsigned char key, int x, int y) 128 129 { 130 switch (key) { 131 case 033: case 'q': case 'Q':// 退出 132 exit(EXIT_SUCCESS); 133 break; 134 } 135 } 136 137 138 void mouse_process(int button, int state, int x, int y) 139 { 140 mouseX = x; 141 mouseY = y; 142 if (button == GLUT_LEFT_BUTTON) 143 { 144 if (state == GLUT_DOWN) 145 { 146 mouseLeftDown = true; 147 } 148 else if (state == GLUT_UP) 149 mouseLeftDown = false; 150 } 151 152 else if (button == GLUT_RIGHT_BUTTON) 153 { 154 if (state == GLUT_DOWN) 155 { 156 mouseRightDown = true; 157 } 158 else if (state == GLUT_UP) 159 mouseRightDown = false; 160 } 161 162 163 164 // ==================================判断选中========================================================= 165 // 三角形以外接圆为范围,圆以半径为范围 166 float Y = -10.0 * (x- 0.5 * glutGet(GLUT_WINDOW_WIDTH)) / 3.0 / glutGet(GLUT_WINDOW_WIDTH); 167 float X = -10.0 * (y - 0.5 * glutGet(GLUT_WINDOW_HEIGHT)) / 3.0 / glutGet(GLUT_INIT_WINDOW_HEIGHT); 168 float mouseToTriangle = (triangleBiasX - X) * (triangleBiasX - X) + (triangleBiasY - Y) * (triangleBiasY - Y); 169 float mouseToCircle = (circleBiasX - X) * (circleBiasX - X) + (circleBiasY - Y) * (circleBiasY - Y); 170 if (mouseToTriangle < 0.25 && mouseToCircle < 0.11)selected = 1; 171 else if (mouseToTriangle < 0.25)selected = 1; 172 else if (mouseToCircle < 0.11)selected = 2; 173 else selected = 0; 174 // =================================================================================================== 175 176 } 177 178 void mouse_process_active(int x, int y) 179 { 180 181 if (mouseLeftDown){// 进行平移,为了实现鼠标追踪,需要在窗口坐标系和世界坐标系之间进行转换 182 //==================================移动======================================== 183 if (selected==1) { 184 triangleBiasY -= 3*((float)x - mouseX)/ glutGet(GLUT_WINDOW_WIDTH); 185 triangleBiasX -= 3*((float)y - mouseY)/ glutGet(GLUT_WINDOW_HEIGHT); 186 //printf("(%.2f ,%.2f)", triangleBiasX, triangleBiasY); 187 } 188 else if (selected == 2) { 189 circleBiasY -= 3 * ((float)x - mouseX) / glutGet(GLUT_WINDOW_WIDTH); 190 circleBiasX -= 3 * ((float)y - mouseY) / glutGet(GLUT_WINDOW_HEIGHT); 191 //printf("(% .2f, % .2f)", circleBiasX, circleBiasY); 192 } 193 194 mouseX = x; 195 mouseY = y; 196 //printf("(%d,%d)", x, y);// 检查屏幕坐标系的分布情况 197 // ============================================================================ 198 } 199 if(mouseRightDown) 200 { // 实时改变被选中图形的旋转积分量 201 //============================旋转、翻转======================================= 202 if (selected == 1) { 203 triangleAngleY += (y - mouseY) * 0.2f; 204 triangleAngleX += (x - mouseX) * 0.2f; 205 } 206 else if (selected == 2) { 207 CircleAngleY += (y - mouseY) * 0.2f; 208 CircleAngleX += (x - mouseX) * 0.2f; 209 } 210 // ============================================================================ 211 mouseX = x; 212 mouseY = y; 213 } 214 215 glutPostRedisplay(); 216 217 } 218 void mouse_process_passtive(int x, int y) {} 219 220 221 int main(int argc, char** argv) 222 { 223 glutInit(&argc, argv); 224 glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH); 225 glutInitWindowSize(512, 512); 226 glutCreateWindow("右键旋转 左键平移 Q退出"); 227 228 init(); 229 230 glutDisplayFunc(display); 231 glutReshapeFunc(reshape); 232 // later Edition 233 glutMouseFunc(mouse_process); 234 glutMotionFunc(mouse_process_active); 235 glutPassiveMotionFunc(mouse_process_passtive); 236 237 238 glutKeyboardFunc(keyboard); 239 glutMainLoop(); 240 241 return 0; 242 }