#include <GL/glut.h>
#include<math.h>
#include<windows.h>
#include<stdlib.h>
#include <stdio.h>
//---------------喷泉相关------------------------------------
struct particle
{
float t; // 粒子的寿命
float v; // 粒子的运动速度
float d; // 粒子的运动方向
float x, y, z; // 粒子的位置坐标
float xd, zd; // X 和 Z 方向上的增量
char type; // 粒子的状态(移动或淡化)
float a; // 粒子淡化的 alpha 值
struct particle *next, *prev;
};
struct particle *fn=NULL; /* Fountains 链表结构*/
int timep=17;//微秒
//--------------------------------------------------------------------
float flag=1.0;
GLfloat theta=3.1415*0.2,fai=3.1415*0.7;
GLfloat P0X=120.0*sin(theta)*sin(fai),P0Y=120*cos(fai),P0Z=120.0*cos(theta)*sin(fai);
GLfloat fog=0;
static GLint fogMode=GL_EXP;
BOOL TurnOn=GL_FALSE;
BOOL On=GL_TRUE;
int xz=0;
int windoww,windowh; //窗口的宽和高
static GLuint texName; //纹理组的名称
//依序为太阳、侧面、地面
GLuint drawwalllist,sunlist,rooflist,treelist; //贴环境纹理的显示列表
GLUquadricObj *qobj;
//------------------------------------------------------------
GLfloat ctrlpoints[4][4][3];
GLfloat texpts[2][2][2] = {{{0.7, 0.7}, {0.7, 1}},
{{1, 0.7}, {1, 1}}};
void outputfont(GLfloat x,GLfloat y, char *format,...)//屏幕文字的输出
{
va_list args;//定义一具VA_LIST型的变量,这个变量是指向参数的指针
char buffer[200],*p;
va_start(args,format);//用VA_START宏初始化变量刚定义的VA_LIST变量
vsprintf(buffer,format,args);//送格式化输出到串中 用 法: int vsprintf(char *string, char *format, va_list param); // 将param 按格式format写入字符串string中
va_end(args);//用VA_END宏结束可变参数的获取
glPushMatrix();
glTranslatef(x,y,0);
for(p=buffer;*p;p++)
glutStrokeCharacter(GLUT_STROKE_ROMAN,*p);//一种等间距的Roman Simplex字体,仅包括32到127的ASCII字符
// glutBitmapCharacter(GLUT_BITMAP_TIMES_ROMAN_24,'D');
glPopMatrix();
}
//-----------------------喷泉相关-----------------------------
void AddParticles()
{
struct particle *tempp;
int i;
for (i=0; i<6; i++)
{
tempp = (struct particle *)malloc(sizeof(struct particle));
if (fn) fn->prev = tempp;
tempp->next = fn;
fn = tempp;
tempp->t = -10;
tempp->v = (float)(rand() % 200)/100+1; //速度
tempp->d = (float)(rand() % 628)/100 - 3.14; // 方向角度
// 开始运动的坐标
tempp->x = 40+i*3;
tempp->y = 0;
tempp->z = 15+i*2;//将水柱沿Z向排列
if(i==2||i==4||i==0)
tempp->xd = -cos(tempp->d)*tempp->v/3;//与喷泉方向相关
else
tempp->xd = cos(tempp->d)*tempp->v/1.5;
tempp->zd = sin((tempp->d*3.14159)/180)*tempp->v*20;
tempp->type = 0;
tempp->a = 1;
}
for (i=0; i<6; i++)
{
tempp = (struct particle *)malloc(sizeof(struct particle));
if (fn) fn->prev = tempp;
tempp->next = fn;
fn = tempp;
tempp->t = -10;
tempp->v = (float)(rand() % 200)/100+1; //速度
tempp->d = (float)(rand() % 628)/100 - 3.14; // 方向角度
// 开始运动的坐标
tempp->x = 40+i*3;
tempp->y = 0;
tempp->z = -70+i*2;//将水柱沿Z向排列
if(i==2||i==4||i==0)
tempp->xd = -cos(tempp->d)*tempp->v/3;//与喷泉方向相关
else
tempp->xd = cos(tempp->d)*tempp->v/1.5;
tempp->zd = sin((tempp->d*3.14159)/180)*tempp->v*20;
tempp->type = 0;
tempp->a = 1;
}
}
// 移动粒子
void MoveParticles()
{
struct particle *tempp;
{
tempp = fn;
while (tempp)
{
if (tempp->type == 0) // 如果粒子是运动的
{
tempp->x += tempp->xd;
tempp->z += tempp->zd;
tempp->t += 0.1; // 寿命递增
tempp->y = -(10*(tempp->t*tempp->t/4))/2+125; // 计算高度
if (tempp->y < 0) tempp->type = 1; // 如果粒子落到地上,则粒子淡化
}
else // 粒子落到地上
{
tempp->a -= 0.5;
}
tempp = tempp->next; //进行下一个粒子的计算
}
}
}
// 删除粒子
void DeleteParticles()
{
struct particle *tempp, *temp1;
{
tempp = fn;
while (tempp)
{
if ((tempp->type == 1) && (tempp->a <= 0)) // 粒子死亡
{
// 删除粒子
temp1 = tempp->prev;
tempp->prev->next = tempp->next;
if (tempp->next) tempp->next->prev = temp1;
free(tempp);
tempp = temp1;
}
tempp = tempp->next;
}
}
}
void timf(int value)//定时器
{
glutPostRedisplay();//指定窗口重新绘制
glutTimerFunc(timep, timf, 0);//注册按一定时间间隔触发的定时器回调函数
}
//-------------------------------------------------------------
void readimage(char* filename,BYTE* imagedata)//所读图片均为24位bmp,且宽度补齐至四字节边界
{
BITMAPFILEHEADER bf; //文件头
BITMAPINFOHEADER bi; //信息头
int m_ImageWidth; //图象宽度
int m_ImageHeight; //图象高度
FILE *fp1; //文件指针,fp1为源文件
//打开文件,到文件指针
if((fp1=fopen(filename,"rb"))==NULL)
{
MessageBox(NULL,"文件打开错误","warning",MB_OK);
}
fread((LPSTR)&bf,sizeof(BITMAPFILEHEADER),1,fp1); //读取文件头,读取以后文件指针在文件头末尾(即信息头)
fread((LPSTR)&bi,sizeof(BITMAPINFOHEADER),1,fp1); //读取信息头
m_ImageWidth=bi.biWidth; //给图象宽度赋值
m_ImageHeight=bi.biHeight; //给图象高度赋值
fread(imagedata,m_ImageHeight*m_ImageWidth*3,1,fp1); //读取图象数据
fclose(fp1);
}
//----------------由于读进来的图记录顺序为BGR---------------------------
void adjustimage(BYTE* imagedata,int w,int h)//转换为RGB
{
BYTE temp;
for(int i=0;i<w*h;i++)
{
temp=imagedata[i*3];
imagedata[i*3]=imagedata[i*3+2];
imagedata[i*3+2]=temp;
}
}
//------------------------设置纹理----------------------------------
void loadtexture()
{ //侧面的纹理
glGenTextures(6, &texName);//生成纹理的数量
glBindTexture(GL_TEXTURE_2D, texName);
{
BYTE imagesun[256][256][3]; //太阳的纹理
readimage("sun.bmp",&imagesun[0][0][0]);
adjustimage(&imagesun[0][0][0],256,256);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);//REPEAT为重复模式 如用CLAMP 截断模式则会出现单色多块填充
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,GL_LINEAR);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 256,256, 0, GL_RGB, GL_UNSIGNED_BYTE, imagesun);//几维 多分辨率层数 纹理元素的哪些分量被使用 纹理的宽 高 边框大小 图像的数据格式 数据类型 内存中指定的纹理图像数据
}
{
BYTE imagehouse[128][128][3]; //风车的纹绠
readimage("house.bmp",&imagehouse[0][0][0]);
adjustimage(&imagehouse[0][0][0],128,128);
glBindTexture(GL_TEXTURE_2D, texName+1);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,GL_LINEAR);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 128,128, 0, GL_RGB, GL_UNSIGNED_BYTE, imagehouse);
}
{
BYTE imagefloor[256][256][3]; //地面的纹绠
readimage("floor.bmp",&imagefloor[0][0][0]);
adjustimage(&imagefloor[0][0][0],256,256);
glBindTexture(GL_TEXTURE_2D, texName+2);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,GL_LINEAR);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 256,256, 0, GL_RGB, GL_UNSIGNED_BYTE, imagefloor);//纹理映射函数 定义一个二维的纹理图
}
{
BYTE imagewall[256][256][3]; //空间的纹理
readimage("wall.bmp",&imagewall[0][0][0]);
adjustimage(&imagewall[0][0][0],256,256);
glBindTexture(GL_TEXTURE_2D, texName+3);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXT
- 1
- 2
- 3
前往页