计算机图形学 实验一 旋转的圆与三角形(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 }
原文地址:https://www.cnblogs.com/PRCdefender/p/14606224.html