#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <time.h>
#include <GL/glut.h>
#include "texture.h"
#define PI 3.14159
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 point
{
float x, y, z;
};
int WindW, WindH;
unsigned *teximage; // 粒子的纹理
GLuint texture[2]; // 纹理ID
float a=0;
struct particle *fn[3]; /* Fountains */
char temp[128]="FPS: 0.000000";
// 以下是用于计算帧率的变量
int frame_counter=0;
time_t curtime;
clock_t last_time;
float cur_time;
float total_frames;
struct point upv, cam; // 摄像机的位置和向上的方向矢量
// 初始化函数
void Init()
{
fn[0] = NULL;
fn[1] = NULL;
fn[2] = NULL;
upv.x = -5;
upv.y = 5;
upv.z = -5;
cam.x = 200;
cam.y = 200;
cam.z = 200;
glGenTextures(3, texture);
glClearColor(0, 0, 0, 0);
glBlendFunc(GL_SRC_ALPHA, GL_ONE);
glEnable(GL_BLEND);
glEnable(GL_TEXTURE_2D);
}
// 在屏幕上绘制字符串
void draw_string(void *font, const char* string)
{
while(*string)
glutStrokeCharacter(font, *string++);
}
static float gettime(void)
{
clock_t time_new, time_raz;
time_new=clock();
time_raz=time_new-last_time;
last_time=time_new;
return(time_raz/(float)CLOCKS_PER_SEC);
}
// 装入纹理
void LoadTexture(char *fn, int t_num)
{
int texwid, texht;
int texcomps;
teximage = read_texture(fn, &texwid, &texht, &texcomps);
if (!teximage)
{
printf("Sorry, can't read texture file...");
exit(0);
}
glBindTexture(GL_TEXTURE_2D, texture[t_num]);
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, texwid, texht, 0, GL_RGBA, GL_UNSIGNED_BYTE, teximage);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
if ((t_num == 0) || (t_num == 2)) glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); /* Special for particles */
if (t_num == 1)
{
// 设置地面的重复纹理参数
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
}
free(teximage);
}
void Reshape(int width, int height)
{
glViewport(0, 0, width, height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glFrustum(-0.5, 0.5, -0.5, 0.5, 1, 1000);
glMatrixMode(GL_MODELVIEW);
WindW = width;
WindH = height;
}
//添加新的粒子
void AddParticles()
{
struct particle *tempp;
int i, j;
for (j=0; j<3; j++)
for (i=0; i<2; i++)
{
tempp = (struct particle *)malloc(sizeof(struct particle));
if (fn[j]) fn[j]->prev = tempp;
tempp->next = fn[j];
fn[j] = tempp;
tempp->t = -9.9;
tempp->v = (float)(rand() % 200000)/100000+1; // 速度
tempp->d = (float)(rand() % 400)/100-2; // 方向角度
// 开始运动的坐标
tempp->x = 0;
tempp->y = 0;
tempp->z = 0;
tempp->xd = cos((tempp->d*3.14159)/180)*tempp->v/4;
tempp->zd = sin((tempp->d*3.14159)/180)*tempp->v;
tempp->type = 0; // 粒子的状态是运动的
tempp->a = 1; // 粒子的Alpha初始值是1
}
}
// 移动粒子
void MoveParticles()
{
struct particle *tempp;
int j;
for (j=0; j<3; j++)
{
tempp = fn[j]; // 选择喷泉
while (tempp)
{
if (tempp->type == 0) // 如果粒子是运动的
{
tempp->x += tempp->xd;
tempp->z += tempp->zd;
tempp->y = -(9.8*(tempp->t*tempp->t/4))/2+122.5; // 计算高度
tempp->t += 0.1; // 寿命递增
if (tempp->y < 0) tempp->type = 1; // 如果粒子落到地上,则粒子淡化
}
else // 粒子落到地上
{
tempp->y = -(9.8*(tempp->t*tempp->t/4))/2+122.5;
tempp->a -= 0.1; // 粒子淡化
}
tempp = tempp->next; //进行下一个粒子的计算
}
}
}
// 删除粒子
void DeleteParticles()
{
struct particle *tempp, *temp1;
int j;
for (j=0; j<3; j++)
{
tempp = fn[j];
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;
}
}
}
//求矢量差积 C = A x B
void vect_mult(struct point *A, struct point *B, struct point *C)
{
/* Vector multiply */
C->x = A->y*B->z - A->z*B->y;
C->y = A->z*B->x - A->x*B->z;
C->z = A->x*B->y - A->y*B->x;
}
// 矢量单位化
void normalize(struct point *V)
{
float d;
// 矢量长度
d = sqrt(V->x*V->x + V->y*V->y + V->z*V->z);
// 单位化
V->x /= d;
V->y /= d;
V->z /= d;
}
void DrawFountain()
{
int j;
struct particle *tempp;
struct point vectd, vectl;
float alpha, ttx, ttz;
glBindTexture(GL_TEXTURE_2D, texture[0]);
AddParticles();
MoveParticles();
DeleteParticles();
glPushMatrix();
for (j=0; j<3; j++)
{
glBegin(GL_QUADS);
tempp = fn[j];
while (tempp)
{
// 旋转喷泉
alpha = ((j*120+a)*PI)/180;
ttx = tempp->x*cos(alpha)-tempp->z*sin(alpha);
ttz = tempp->x*sin(alpha)+tempp->z*cos(alpha);
// 计算方向矢量A
vectd.x = ttx - cam.x;
vectd.y = tempp->y - cam.y;
vectd.z = ttz - cam.z;
vect_mult(&vectd, &upv, &vectl);
normalize(&vectl);
vectl.x *= 5;
vectl.y *= 5;
vectl.z *= 5;
glColor4f(0.5, 0.5, 1, tempp->a);
// 绘制粒子及纹理映射
glTexCoord2f(0, 0); glVertex3f((ttx-vectl.x), (tempp->y-upv.y), (ttz-vectl.z));
glTexCoord2f(1, 0); glVertex3f((ttx+vectl.x), (tempp->y-upv.y), (ttz+vectl.z));
glTexCoord2f(1, 1); glVertex3f((ttx+vectl.x), (tempp->y+upv.y), (ttz+vectl.z));
glTexCoord2f(0, 1); glVertex3f((ttx-vectl.x), (tempp->y+upv.y), (ttz-vectl.z));
tempp = tempp->next; // 下一个粒子
}
glEnd();
}
glPopMatrix();
}
// 场景绘制函数
void Draw(void)
{
glClear(GL_COLOR_BUFFER_BIT);
glLoadIdentity();
glBindTexture(GL_TEXTURE_2D, texture[1]);
a += 0.2;
gluLookAt(cam.x, cam.y, cam.z, 0, 0, 0, upv.x, upv.y, upv.z);
// 绘制地面
glColor3f(0.9, 0.9, 1);
glPushMatrix();
glRotatef(a, 0, -1, 0);
glBegin(GL_QUADS);
glTexCoord2f(0, 0); glVertex3f(-100, 0, -100);
glTexCoord2f(2, 0); glVertex3f(-100, 0, 100);
glTexCoord2f(2, 2); glVertex3f(100, 0, 100);
glTexCoord2f(0, 2); glVertex3f(100, 0, -100);
glEnd();
glPopMatrix();
// 绘制喷泉
DrawFountain();
glBindTexture(GL_TEXTURE_2D, texture[2]);
glColor4f(1, 1, 0, 0.8);
glPushMatrix();
glRotatef(a, 0, -1, 0);
glBegin(GL_QUADS);
glTexCoord2f(0, 0); glVertex3f(-100, 0, -100);
glTexCoord2f(1, 0); glVertex3f(-100, 0, 100);
glTexCoord2f(1, 1); glVertex3f(100, 0, 100);
glTexCoord2f(0, 1); glVertex3f(100, 0, -100);
glEnd();
glPopMatrix();
// 计算帧率
frame_counter++;
if((frame_counter % 40) == 0)
{
frame_counter = 0;
cur_time=gettime();
sprintf(temp, "FPS: %f", 40.0/cur_time);
}
// 绘制显示帧率的字符串
glColor3f(1, 1, 1);
glDisable(GL_TEXTURE_2D);
glLoadIdentity();
glTranslatef(-4.9, 4.5, -10);
glScalef(0.003, 0.003, 0.004);
draw_string(GLUT_STROKE_ROMAN, temp);
glEnable(GL_TEXTURE_2D);
glFlush();
glutSwapBuffers();
}
static void Key(unsigned char key, int x, int y)
{
switch (key)
{
case 27: exit(0);
break;
}
}
void timf(int value)
{
glutPostRedisplay();
glutTimerFunc(16, timf, 0);
}
int
没有合适的资源?快使用搜索试试~ 我知道了~
OpenGL 虚拟漫游
共49个文件
rgb:12个
c:4个
exe:4个
4星 · 超过85%的资源 需积分: 9 46 下载量 123 浏览量
2010-06-21
10:29:08
上传
评论
收藏 1.1MB RAR 举报
温馨提示
利用OpenGL技术设计的虚拟漫游场景,其中包括代码的编写,和实现。对初学者有很大帮助。
资源推荐
资源详情
资源评论
收起资源包目录
Chapter03.rar (49个子文件)
Chapter03
fountain3d
GROUND1.RGB 201KB
TEXTURE.C 6KB
fountain3d.c 8KB
fountain3d_src.zip 215KB
fountain3d.opt 48KB
Makefile.Unix 278B
fountain3d.ncb 49KB
Debug
GROUND1.RGB 201KB
fountain3d.exe 196KB
PARTICLE.RGB 4KB
GROUND2.RGB 200KB
PARTICLE.RGB 4KB
fountain3d.dsw 543B
TEXTURE.H 86B
fountain3d
GROUND1.RGB 201KB
fountain3d.exe 52KB
PARTICLE.RGB 4KB
GROUND2.RGB 200KB
GROUND2.RGB 200KB
fountain3d_src
GROUND1.RGB 201KB
TEXTURE.C 6KB
fountain3d.c 8KB
fountain3d.opt 48KB
Makefile.Unix 278B
fountain3d.ncb 49KB
Debug
fountain3d.pdb 513KB
VC60.PDB 52KB
fountain3d.exe 196KB
fountain3d.obj 24KB
TEXTURE.OBJ 12KB
PARTICLE.RGB 4KB
fountain3d.dsw 543B
TEXTURE.H 86B
GROUND2.RGB 200KB
fountain3d.plg 1KB
Makefile 441B
fountain3d.dsp 4KB
fountain3d.plg 1KB
Makefile 441B
fountain3d.dsp 4KB
Particles
Data
Particle.bmp 3KB
Particles.ncb 33KB
Particles.opt 48KB
Debug
Data
Particle.bmp 3KB
Particles.exe 212KB
Particles.plg 1KB
Particles.cpp 21KB
Particles.dsp 4KB
Particles.dsw 541B
共 49 条
- 1
资源评论
- lollipop12242014-05-11不知道什么原因,显示有一个错误,不能运行。
- heartandheart2012-12-29推荐使用,入门很好,代码工整,注释详细
wukunshe
- 粉丝: 1
- 资源: 3
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功