openGL+VS2010的例程--旋转彩球(三维)

时间:2021-12-14 05:55:35

openGL+VS2010的例程--旋转彩球(三维)

效果图如上:

步骤:略。

实现代码如下:

  1 /**********************************************************************
  2 
  3   VertexArray Tutorial
  4 
  5   June, 10th, 2000
  6 
  7   This tutorial was written by Philipp Crocoll
  8   Contact: 
  9     philipp.crocoll@web.de
 10     www.codecolony.de
 11 
 12   Every comment would be appreciated.
 13 
 14   If you want to use parts of any code of mine:
 15     let me know and
 16     use it!
 17 ***********************************************************************
 18 
 19   p : switches between line and point mode
 20 
 21 ***********************************************************************/
 22 
 23 #include <GL\glut.h>
 24 #include <math.h>
 25 #include <vector>
 26 using namespace std;
 27 #define PI 3.1415265359
 28 struct SVertex
 29 {
 30     GLfloat x,y,z;
 31     GLfloat r,g,b;
 32 };
 33 
 34 //Data for the sphere vertices:
 35 SVertex * Vertices;
 36 int NumVertices;  //size of the vertex array
 37 vector <GLuint> IndexVect;  //we first put the indices into this vector, then copy them to the array below
 38 GLuint * Indices;
 39 int NumIndices;   //size of the index array
 40 
 41 GLfloat ChangeY = 0.025;//Indicates how much the y values of the highest and deepest vertex
 42                         //in the sphere are changed each time it is rendered
 43 float yRotated = 0.0;
 44 bool PointsOnly = false;//Indicated, if the triangles or only points are drawn
 45 
 46 // 参数1:水平点的个数;参数2:纵向点的个数;
 47 void CreateSphere(int PointRows, int PointsPerRow) 
 48 {
 49     NumVertices = (PointRows-2)*PointsPerRow + 2; // 总点数
 50     Vertices = new SVertex[NumVertices];
 51     free(Indices);
 52     IndexVect.clear();  //to be sure it is empty 清空
 53     float x,y,z;
 54     int i,j;
 55     double r;
 56     for (i = 1; i < (PointRows-1); i++)
 57     {
 58         for (j = 0; j < PointsPerRow; j++)
 59         {
 60             y = 1.0 - float(i) / float(PointRows-1)*2.0; 
 61             r = sin (acos(y));  //  这个以Y为轴的圆的半径。
 62             x = r * sin(float(j) / float(PointsPerRow)*PI*2.0);   // 这个以X为轴的圆与上面的圆的交点的X坐标
 63             
 64             z = r * cos(float(j) / float(PointsPerRow)*PI*2.0); // 这个以Z为轴的圆与上面的圆的交点的Z坐标
 65             Vertices[(i-1)*PointsPerRow+j].x = x;
 66             Vertices[(i-1)*PointsPerRow+j].y = y;
 67             Vertices[(i-1)*PointsPerRow+j].z = z;
 68             Vertices[(i-1)*PointsPerRow+j].r = (float)(i) / float(PointRows);
 69             Vertices[(i-1)*PointsPerRow+j].g = 0.6;
 70             Vertices[(i-1)*PointsPerRow+j].b = (float)(j) / float(PointsPerRow);
 71         }
 72 
 73     }
 74     //The highest and deepest vertices:   // 最值点 --上下各1个。
 75     Vertices[(PointRows-2)*PointsPerRow].x = 0.0;
 76     Vertices[(PointRows-2)*PointsPerRow].y = 1.0;
 77     Vertices[(PointRows-2)*PointsPerRow].z = 0.0;
 78     Vertices[(PointRows-2)*PointsPerRow].r = 1.0;
 79     Vertices[(PointRows-2)*PointsPerRow].g = 0.7;
 80     Vertices[(PointRows-2)*PointsPerRow].b = 1.0;
 81     Vertices[(PointRows-2)*PointsPerRow+1].x = 0.0;
 82     Vertices[(PointRows-2)*PointsPerRow+1].y = -1.0;
 83     Vertices[(PointRows-2)*PointsPerRow+1].z = 0.0;
 84     Vertices[(PointRows-2)*PointsPerRow+1].r = 1.0;
 85     Vertices[(PointRows-2)*PointsPerRow+1].g = 0.7;
 86     Vertices[(PointRows-2)*PointsPerRow+1].b = 1.0;
 87     
 88     for (i = 1; i < (PointRows-2); i++)
 89     {
 90         for (j = 0; j < (PointsPerRow-1); j++)
 91         { // 当PointsPerRow= 8 ,首次赋的值是??
 92             IndexVect.push_back((i-1)*PointsPerRow+j);            // 0 1
 93             IndexVect.push_back((i-1)*PointsPerRow+j+1);        // 1 2
 94             IndexVect.push_back((i)*PointsPerRow+j);                // 8 9
 95 
 96             IndexVect.push_back((i-1)*PointsPerRow+j+1);        // 1 2
 97             IndexVect.push_back((i)*PointsPerRow+j+1);            // 9 10
 98             IndexVect.push_back((i)*PointsPerRow+j);                // 8 9
 99         }
100         // 连接左右两侧的线结构
101         IndexVect.push_back((i-1)*PointsPerRow+PointsPerRow-1); // 7
102         IndexVect.push_back((i-1)*PointsPerRow);  // 0
103         IndexVect.push_back((i)*PointsPerRow+j); // 16
104 
105         IndexVect.push_back((i)*PointsPerRow); // 8
106         IndexVect.push_back((i-1)*PointsPerRow); // 0
107         IndexVect.push_back((i)*PointsPerRow+j); // 16
108     }        
109 
110     //The triangles to the highest and deepest vertices: // 连接三角形的最高和最深的顶点
111     for (j = 0; j< (PointsPerRow-1); j++)
112     {
113         IndexVect.push_back(j);
114         IndexVect.push_back(j+1);
115         IndexVect.push_back((PointRows-2)*PointsPerRow);
116     }
117     IndexVect.push_back(j);
118     IndexVect.push_back(0);
119     IndexVect.push_back((PointRows-2)*PointsPerRow);
120 
121     for (j = 0; j< (PointsPerRow-1); j++)
122     {
123         IndexVect.push_back((PointRows-3)*PointsPerRow+j);
124         IndexVect.push_back((PointRows-3)*PointsPerRow+j+1);
125         IndexVect.push_back((PointRows-2)*PointsPerRow+1);
126     }
127     IndexVect.push_back((PointRows-3)*PointsPerRow+j);
128     IndexVect.push_back((PointRows-3)*PointsPerRow);
129     IndexVect.push_back((PointRows-2)*PointsPerRow+1);
130 
131     Indices = new GLuint[IndexVect.size()];  //allocate the required memory
132     for (i = 0; i < IndexVect.size(); i++)
133     {
134         Indices[i] = IndexVect[i]; // 复制顶点数组到临时空间。
135     }
136     NumIndices = IndexVect.size();
137     IndexVect.clear();  //no longer needed, takes only memory  释放空间
138 }
139 
140 void DrawSphere(void)
141 {
142     if (!PointsOnly)
143         glDrawElements(    GL_TRIANGLES, //mode 三角形 
144                         NumIndices,  //count, ie. how many indices 绘制图元的数量乘上一个图元的顶点数 (*3)
145                         GL_UNSIGNED_INT, //type of the index array 索引值的类型
146                         Indices);  // 指向索引存贮位置的指针
147     else 
148         glDrawArrays(GL_POINTS,0,NumVertices);
149 
150 }
151 
152 void Display(void)
153 {
154     glClear(GL_COLOR_BUFFER_BIT);
155     glLoadIdentity();
156     glTranslatef(0.0,0.0,-3.2); // 为了显示全部图像
157     glRotatef(yRotated, 0.0, 1.0, 0.0); // 旋转图像
158     DrawSphere(); // 用户自定义绘制函数
159     glFlush();            //Finish rendering
160     glutSwapBuffers();
161 }
162 
163 void Reshape(int x, int y)
164 {
165     if (y == 0 || x == 0) return;  //Nothing is visible then, so return
166     //Set a new projection matrix
167     glMatrixMode(GL_PROJECTION);  
168     glLoadIdentity();
169     //Angle of view:40 degrees
170     //Near clipping plane distance: 0.5
171     //Far clipping plane distance: 20.0
172     gluPerspective(60.0,(GLdouble)x/(GLdouble)y,0.5,20.0);
173     glViewport(0,0,x,y);  //Use the whole window for rendering
174     glMatrixMode(GL_MODELVIEW);
175     
176 }
177 
178 static long long times = 0;
179 void Idle(void)
180 {
181     times++; // 延迟
182     if(times>500000)
183         times =0;
184     if(times% 500000== 0)
185     {
186          Vertices[NumVertices-2].y += ChangeY; // 最高点变化
187         Vertices[NumVertices-1].y -= ChangeY;// 最低点变化
188 
189         if (Vertices[NumVertices-2].y> 1.5 || Vertices[NumVertices-2].y< 0.5)
190             ChangeY *= -1; // 变化值的取反
191         yRotated += 0.3; // 以Y为轴的旋转角度
192         Display();
193     }
194 }
195  
196 void Keyboard(unsigned char key, int x, int y)
197 {
198     switch(key)
199     {
200     case 'p': 
201         PointsOnly = !PointsOnly;
202         break;
203     }
204 }
205 
206 int main (int argc, char **argv)
207 {
208     //Initialize GLUT
209     glutInit(&argc, argv);
210     glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);
211     glutInitWindowSize(300,300);
212     //Create a window with rendering context and everything else we need
213     glutCreateWindow("Vertex Arrays");
214     //compute the vertices and indices
215     CreateSphere(16,16);
216     //as we do not yet use a depth buffer, we cannot fill our sphere
217     glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
218     //Enable the vertex array functionality:
219     glEnableClientState(GL_VERTEX_ARRAY); // 开启“顶点数组”
220     glEnableClientState(GL_COLOR_ARRAY); // 开启“颜色数组”
221     glVertexPointer(    3,   //3 components per vertex (x,y,z)
222                         GL_FLOAT,
223                         sizeof(SVertex),
224                         Vertices);
225     glColorPointer(        3,   //3 components per vertex (r,g,b)
226                         GL_FLOAT,
227                         sizeof(SVertex),
228                         &Vertices[0].r);  //Pointer to the first color
229     glPointSize(3.0); // 点大小
230     glClearColor(0.0,0.0,0.0,0.0); // 黑色
231     //Assign the two used Msg-routines
232     glutDisplayFunc(Display);
233     glutReshapeFunc(Reshape);
234     glutKeyboardFunc(Keyboard);
235     glutIdleFunc(Idle);
236     //Let GLUT get the msgs
237     glutMainLoop();
238     return 0;
239 }