chap83.cpp
上传用户:hayco9999
上传日期:2022-08-09
资源大小:183k
文件大小:4k
- // chap83.cpp : Defines the entry point for the console application.
- //模拟生成山地景象,以动画方式显示一只环绕着最高山峰飞行的鸟所看到的景象。
- //第一圈飞行时太阳是固定在天上的,之后每一次环绕中随着飞鸟而行。
- #include "stdafx.h"
- #include<gl/glut.h>
- #include<stdlib.h>
- #include <math.h>
- GLfloat pos[]={-2,6,5,0}; //光源位置
- GLfloat amb[]={0.2,0.2,0.2,1.0}; //环境光
- GLfloat front_amb_diff[]={0.7,0.75,0.75,1.0};
- float theta=0,dt=0.4,p=3.141593/180;
- bool flag=true;
- int landscape[400][400];
- /*计算v1和v2的叉乘,n是结果*/
- void vxv(float *n,float *v1,float *v2){
- n[0]=v1[1]*v2[2]-v1[2]*v2[1];
- n[1]=v1[2]*v2[0]-v1[0]*v2[2];
- n[2]=v1[0]*v2[1]-v1[1]*v2[0];
- }
- /*山峰高度计算*/
- void elevation( int seed, int n){
- //
- int i,j,k,centerx=200,centery=200,stepx,stepy,xmin,xmax,ymin, ymax,xsq,ysq,radius=25,radius_sq=radius*radius,maxh=0;
- srand(seed); //根据seed计算随机数
- for(k=0;k<n;k++){ //循环处理每一次圆盘移动后引起的山峰高度变化
- stepx=(rand()>RAND_MAX/2)?3:-3; //随机确定stepx和stepy(圆盘中心移动的步幅)
- stepy=(rand()>RAND_MAX/2)?3:-3;
- centerx += stepx; //圆盘中心移动
- centery += stepy;
- if(centerx<0||400<=centerx) centerx=200; //如果圆盘中心越界,则恢复至初始圆心(200,200)
- if(centery<0||400<=centery) centery=200;
- xmin=(0<=centerx-radius)? centerx-radius:0; //以下4句确定圆盘所在正方形区域上下左右边界
- xmax=(400<=centerx+radius)?399:centerx+radius;
- ymin=(0<=centery-radius)? centery-radius:0;
- ymax=(40<=centery+radius)? 399:centery+radius;
- for (i=xmin;i<=xmax;i++) //检查正方形区域中的点是否落在圆盘内,是则高度+1
- for(j=ymin;j<=ymax;j++){
- xsq=i-centerx;
- xsq *= xsq;
- ysq=j-centery;
- ysq*=ysq;
- if((xsq+ysq)<=radius_sq) landscape[i][j]++;
- }
- }//end of for 圆盘移动结束
- for(i=0;i<400;i++)
- for(j=0;j<400;j++)
- if(landscape[i][j]>maxh) maxh=landscape[i][j]; //找海拔最高点,记在maxh中
- float scale=255.0/(float)maxh; //将最高高度规范在0-255内
- for(i=0;i<400;i++)
- for(j=0;j<400;j++) landscape[i][j] *= scale; //所有点均按比例缩小
- }
- void display(void){
- float v1[3],v2[3],v3[3],n[3];
- int step=3; //?
- glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
- glPushMatrix();
- gluLookAt(400*sin(theta*p),400,400*cos(theta*p),0,50,0,0,1,0); //定义视角
- if(flag) glLightfv(GL_LIGHT0,GL_POSITION,pos); //建立光源
- glTranslated(-200,0,200); //平移?
- v1[0]=step; v1[2]=0; ///???向量个分量如何确定?含义?
- v2[0]=step; v2[2]=-step;
- v3[0]=0.0; v3[2]=-step;
- glBegin(GL_TRIANGLES);
- for(int i=0;i<400-step;i+=step)
- for(int j=0;j<400-step; j+=step){
- v1[1]=landscape[i+step][j]-landscape[i][j];
- v2[1]=landscape[i+step][j+step]-landscape[i][j];
- v3[1]=landscape[i][j+step]-landscape[i][j];
- vxv(n,v1,v2);
- glNormal3fv(n); //画第一个三角形
- glVertex3i(i,landscape[i][j],-j);
- glVertex3i(i+step,landscape[i+step][j],-j);
- glVertex3i(i+step,landscape[i+step][j+step],-j-step);
- vxv(n,v2,v3);
- glNormal3fv(n); //画第二个三角形 ?? 为什么画着两个三角形??
- glVertex3i(i+step,landscape[i+step][j+step],-j-step);
- glVertex3i(i,landscape[i][j+step],-j-step);
- glVertex3i(i,landscape[i][j],-j);
- }
- glEnd();
- glPopMatrix();
- glutSwapBuffers();
- }
- void idle(void){
- if(theta>=360) flag=!flag; //修改角度
- theta=(theta<360)?theta+dt:dt;
- glutPostRedisplay();
- }
- int main(int argc, char* argv[])
- {
- glutInit(&argc,argv);
- glutInitDisplayMode(GLUT_DOUBLE|GLUT_RGB|GLUT_DEPTH);
- glutInitWindowSize(600,600);
- glutInitWindowPosition(200,100);
- glutCreateWindow("Mountains");
- glClearColor(0.0,0.0,0.0,0.0);
- glMaterialfv(GL_FRONT,GL_AMBIENT_AND_DIFFUSE,front_amb_diff);//ka=kd
- glLightfv(GL_LIGHT0,GL_AMBIENT,amb);//定义环境光Ia
- glEnable(GL_NORMALIZE); //规范向量
- glEnable(GL_LIGHTING); //启动光照
- glEnable(GL_LIGHT0); //启动灯光
- glEnable(GL_DEPTH_TEST); //启动双缓冲
- glMatrixMode(GL_PROJECTION); //设置当前为投影矩阵
- glLoadIdentity();
- gluPerspective(45,1.0,10,800); //定义观察域
- glMatrixMode(GL_MODELVIEW); // 设置当前为建模观察矩阵
- glLoadIdentity();
- glutDisplayFunc(display); //调用display
- glutIdleFunc(idle); //调用idle
- elevation(1234,5000); //调用elevation(种子,圆盘移动次数)
- glutMainLoop();
- return 0;
- }