chap83.cpp
上传用户:hayco9999
上传日期:2022-08-09
资源大小:183k
文件大小:4k
源码类别:

图形图象

开发平台:

Visual C++

  1. // chap83.cpp : Defines the entry point for the console application.
  2. //模拟生成山地景象,以动画方式显示一只环绕着最高山峰飞行的鸟所看到的景象。
  3. //第一圈飞行时太阳是固定在天上的,之后每一次环绕中随着飞鸟而行。
  4. #include "stdafx.h"
  5. #include<gl/glut.h>
  6. #include<stdlib.h> 
  7. #include <math.h>
  8. GLfloat pos[]={-2,6,5,0};     //光源位置
  9. GLfloat amb[]={0.2,0.2,0.2,1.0};  //环境光
  10. GLfloat front_amb_diff[]={0.7,0.75,0.75,1.0};
  11. float theta=0,dt=0.4,p=3.141593/180;
  12. bool flag=true;
  13. int landscape[400][400];
  14. /*计算v1和v2的叉乘,n是结果*/
  15. void vxv(float *n,float *v1,float *v2){
  16. n[0]=v1[1]*v2[2]-v1[2]*v2[1];
  17. n[1]=v1[2]*v2[0]-v1[0]*v2[2];
  18. n[2]=v1[0]*v2[1]-v1[1]*v2[0];
  19. }
  20. /*山峰高度计算*/
  21. void elevation( int seed, int n){
  22. //
  23. int i,j,k,centerx=200,centery=200,stepx,stepy,xmin,xmax,ymin, ymax,xsq,ysq,radius=25,radius_sq=radius*radius,maxh=0;
  24. srand(seed);    //根据seed计算随机数
  25. for(k=0;k<n;k++){  //循环处理每一次圆盘移动后引起的山峰高度变化
  26. stepx=(rand()>RAND_MAX/2)?3:-3; //随机确定stepx和stepy(圆盘中心移动的步幅)
  27. stepy=(rand()>RAND_MAX/2)?3:-3;
  28. centerx += stepx;              //圆盘中心移动
  29. centery += stepy;
  30. if(centerx<0||400<=centerx) centerx=200;   //如果圆盘中心越界,则恢复至初始圆心(200,200)
  31. if(centery<0||400<=centery) centery=200;
  32. xmin=(0<=centerx-radius)? centerx-radius:0;  //以下4句确定圆盘所在正方形区域上下左右边界
  33. xmax=(400<=centerx+radius)?399:centerx+radius;
  34. ymin=(0<=centery-radius)? centery-radius:0;
  35. ymax=(40<=centery+radius)? 399:centery+radius;
  36. for (i=xmin;i<=xmax;i++)        //检查正方形区域中的点是否落在圆盘内,是则高度+1
  37. for(j=ymin;j<=ymax;j++){
  38. xsq=i-centerx;
  39. xsq *= xsq;
  40. ysq=j-centery;
  41. ysq*=ysq;
  42. if((xsq+ysq)<=radius_sq) landscape[i][j]++;
  43. }
  44. }//end of for 圆盘移动结束
  45. for(i=0;i<400;i++)
  46. for(j=0;j<400;j++)
  47. if(landscape[i][j]>maxh) maxh=landscape[i][j];  //找海拔最高点,记在maxh中
  48. float scale=255.0/(float)maxh;     //将最高高度规范在0-255内
  49. for(i=0;i<400;i++)
  50. for(j=0;j<400;j++) landscape[i][j] *= scale;  //所有点均按比例缩小
  51. }
  52. void display(void){
  53. float v1[3],v2[3],v3[3],n[3];
  54. int step=3;                        //?
  55. glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
  56. glPushMatrix();
  57. gluLookAt(400*sin(theta*p),400,400*cos(theta*p),0,50,0,0,1,0);  //定义视角
  58. if(flag) glLightfv(GL_LIGHT0,GL_POSITION,pos);   //建立光源
  59. glTranslated(-200,0,200);     //平移?
  60. v1[0]=step; v1[2]=0;  ///???向量个分量如何确定?含义?
  61. v2[0]=step; v2[2]=-step;
  62. v3[0]=0.0;  v3[2]=-step;
  63. glBegin(GL_TRIANGLES);
  64. for(int i=0;i<400-step;i+=step)
  65. for(int j=0;j<400-step; j+=step){
  66. v1[1]=landscape[i+step][j]-landscape[i][j];
  67. v2[1]=landscape[i+step][j+step]-landscape[i][j];
  68. v3[1]=landscape[i][j+step]-landscape[i][j];
  69. vxv(n,v1,v2);
  70. glNormal3fv(n);        //画第一个三角形
  71. glVertex3i(i,landscape[i][j],-j);
  72. glVertex3i(i+step,landscape[i+step][j],-j);
  73. glVertex3i(i+step,landscape[i+step][j+step],-j-step);
  74. vxv(n,v2,v3);
  75. glNormal3fv(n);      //画第二个三角形   ?? 为什么画着两个三角形??
  76. glVertex3i(i+step,landscape[i+step][j+step],-j-step);
  77. glVertex3i(i,landscape[i][j+step],-j-step);
  78. glVertex3i(i,landscape[i][j],-j);
  79. }
  80. glEnd();
  81. glPopMatrix();
  82. glutSwapBuffers();
  83. }
  84. void idle(void){
  85. if(theta>=360) flag=!flag;    //修改角度
  86. theta=(theta<360)?theta+dt:dt;   
  87. glutPostRedisplay();
  88. }
  89. int main(int argc, char* argv[])
  90. {
  91. glutInit(&argc,argv);
  92. glutInitDisplayMode(GLUT_DOUBLE|GLUT_RGB|GLUT_DEPTH);
  93. glutInitWindowSize(600,600);
  94. glutInitWindowPosition(200,100);
  95. glutCreateWindow("Mountains");
  96. glClearColor(0.0,0.0,0.0,0.0);
  97. glMaterialfv(GL_FRONT,GL_AMBIENT_AND_DIFFUSE,front_amb_diff);//ka=kd
  98. glLightfv(GL_LIGHT0,GL_AMBIENT,amb);//定义环境光Ia
  99. glEnable(GL_NORMALIZE);  //规范向量
  100. glEnable(GL_LIGHTING);  //启动光照
  101. glEnable(GL_LIGHT0);    //启动灯光
  102. glEnable(GL_DEPTH_TEST);  //启动双缓冲
  103. glMatrixMode(GL_PROJECTION); //设置当前为投影矩阵
  104. glLoadIdentity();
  105. gluPerspective(45,1.0,10,800);  //定义观察域
  106. glMatrixMode(GL_MODELVIEW);  // 设置当前为建模观察矩阵
  107. glLoadIdentity();
  108. glutDisplayFunc(display);   //调用display
  109. glutIdleFunc(idle);          //调用idle
  110. elevation(1234,5000);        //调用elevation(种子,圆盘移动次数)
  111. glutMainLoop();
  112. return 0;
  113. }