|
|
小弟初学OpenGL,看不懂这个代码,哪位大哥能帮忙注释一下代码的意思。最好能详细点,每句都注释一下。因为小弟实在不怎么懂。。先谢谢了
#include <windows.h>
#include <gl\gl.h>
#include <gl\glu.h>
#include <gl\glaux.h>
#include <stdio.h>
#include <olectl.h>
#include <math.h>
#include <list>
int fps(72);
#include "Misc.h"
#include "Camera.h"
#include "3DS.h"
HDC hDC=NULL;
HGLRC hRC=NULL;
HWND hWnd=NULL;
HINSTANCE hInstance;
bool keys[256];
bool active=TRUE;
bool fullscreen=TRUE;
char* brand=NULL;
char* vendor=NULL;
char* version=NULL;
float Noise1(int x, int y);
float SmoothNoise_1(int x, int y);
float Cosine_Interpolate(float a, float b, float x);
float InterpolatedNoise_1(float x, float y);
float PerlinNoise_2D(float x, float y);
GLuint texgrass;
GLuint texlightspot;
GLuint texfire;
CCamera camera;
t3DModel skybox;
t3DModel firewood;
CVect3 EyePosition;
float angle;
vec axis;
float GetRandom(float minv, float maxv)
{
return (float)rand()/RAND_MAX*(maxv-minv)+minv;
}
struct Position
{
float x;
float y;
float z;
};
struct Color
{
float R;
float G;
float B;
};
class Particles
{
public:
Particles(float x, float y, float z);
void Render();
bool dead;
private:
Position Pos;
Color Col;
float speed;
float speed_acc;
float alpha;
float alpha_dec;
float size;
};
void Particles::Render()
{
if(dead==true) return;
glPushMatrix();
glTranslatef(Pos.x, Pos.y, Pos.z);
glPushMatrix();
glRotatef(angle, axis.x, axis.y, axis.z);
glDisable(GL_FOG);
glDisable(GL_LIGHTING);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE);
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, texfire);
glColor4f(Col.R, Col.G*alpha, Col.B*alpha/2.0f, alpha);
glDepthMask(GL_FALSE);
glBegin(GL_QUADS);
glTexCoord2i(0, 1); glVertex3f(-size, size, 0.0f);
glTexCoord2i(0, 0); glVertex3f(-size, -size, 0.0f);
glTexCoord2i(1, 0); glVertex3f(size, -size, 0.0f);
glTexCoord2i(1, 1); glVertex3f(size, size, 0.0f);
glEnd();
glDepthMask(GL_TRUE);
glDisable(GL_TEXTURE_2D);
glDisable(GL_BLEND);
//glEnable(GL_LIGHTING);
//glEnable(GL_FOG);
glPopMatrix();
glPopMatrix();
//数据更新
if(fps==0) fps=30;
speed+=speed_acc;
Pos.y +=speed;
alpha-=alpha_dec;
size-=0.05f*(30/fps);
Pos.x +=-Pos.x/30.0f;
Pos.z +=-Pos.z/30.0f;
if(alpha<=0.0f) dead=true;
}
Particles: articles(float x, float y, float z)
{
Pos.x = x;
Pos.y = y;
Pos.z = z;
Col.R = 1.0f;
Col.G = 1.0f;
Col.B = 0.8f;
speed = 0.2f;
speed_acc = GetRandom(0.013f, 0.015f);
alpha = 1.0f;
alpha_dec = GetRandom(0.033f, 0.03301f);
size=4.0f;
dead = false;
}
std::list< articles> fire;
void DrawFire()
{
std::list<Particles>::iterator pointer;
for(pointer=fire.begin();pointer!=fire.end();pointer++)
{
if(pointer->dead==true)
pointer=fire.erase(pointer);
}
for(pointer=fire.begin();pointer!=fire.end();pointer++)
{
glPushMatrix();
glTranslatef(56, 6, 56);
pointer->Render();
glPopMatrix();
}
if(fire.size()>2000) return;
float x=GetRandom(-1.6f, 1.6f);
float y=2.0f;
float z=GetRandom(-1.6f, 1.6f);
Particles p(x,y,z);
fire.push_back(p);
}
struct Terrain
{
float x, y, z;
float s, t;
float norx, nory, norz;
};
Terrain terrain[250][250];
void initTerrain()
{
for(int x=0;x<=249;x++)
for(int z=0;z<=249;z++)
{
terrain[x][z].x =(float)(x- 125)*4.0f;
terrain[x][z].y =25.0f*PerlinNoise_2D((x+10000)/10.0f, (z+10000)/10.0f);
terrain[x][z].z =(float)(z- 125)*4.0f;
terrain[x][z].s =x/15.0f;
terrain[x][z].t =z/15.0f;
}
for(x=0;x<=249;x++)
for(int z=0;z<=249;z++)
{
if(x>0 && z>0 && x<249 && z<249)
{
vec v1;
v1.x=terrain[x+1][z].y - terrain[x-1][z].y;
v1.y= 0.5f;
v1.z=terrain[x][z+1].y - terrain[x][z-1].y;
v1.Normalize();
terrain[x][z].norx =v1.x;
terrain[x][z].nory =v1.y;
terrain[x][z].norz =v1.z;
}
else
{
terrain[x][z].norx =0.0f;
terrain[x][z].nory =1.0f;
terrain[x][z].norz =0.0f;
}
}
}
//计算BILLBOARD, 算转角和转轴
void CalcTheBillboard()
{
vec eyepos(EyePosition.x-56, EyePosition.y-6, EyePosition.z-56);
vec face(0.0f, 0.0f, -1.0f);
eyepos.Normalize();
//计算转角
angle = acos(eyepos % face)*180.0f/3.14159f;
//计算转轴
axis = eyepos * face;
axis = -axis;
axis.Normalize();
}
void DrawModel(t3DModel& Model);
void DrawTerrain()
{
glEnable(GL_TEXTURE_2D);
glPushMatrix();
glTranslatef(56, 6, 56);
DrawModel(firewood);
glPopMatrix();
glBindTexture(GL_TEXTURE_2D, texgrass);
for(int z=0;z<=248;z++)
{
glBegin(GL_QUAD_STRIP);
for(int x=0;x<=249;x++)
{
glNormal3f(terrain[x][z].norx , terrain[x][z].nory , terrain[x][z].norz);
glTexCoord2f(terrain[x][z].s, terrain[x][z].t);
glVertex3f(terrain[x][z].x, terrain[x][z].y, terrain[x][z].z);
glNormal3f(terrain[x][z+1].norx , terrain[x][z+1].nory , terrain[x][z+1].norz);
glTexCoord2f(terrain[x][z+1].s, terrain[x][z+1].t );
glVertex3f(terrain[x][z+1].x, terrain[x][z+1].y, terrain[x][z+1].z);
}
glEnd();
}
//画那个光斑
glBindTexture(GL_TEXTURE_2D, texlightspot);
glBlendFunc(GL_SRC_ALPHA, GL_ONE);
glEnable(GL_BLEND);
glDisable(GL_LIGHTING);
glDisable(GL_FOG);
glDepthMask(GL_FALSE);
glColor4f(0.9f, 0.9f, 0.3f, 0.8f);
for(z=130;z<=148;z++)
{
glBegin(GL_QUAD_STRIP);
for(int x=130;x<=147;x++)
{
glTexCoord2f((x-130)/18.0f, (z-130)/18.0f);
glVertex3f(terrain[x][z].x, terrain[x][z].y, terrain[x][z].z);
glTexCoord2f((x-130)/18.0f, (z-129)/18.0f);
glVertex3f(terrain[x][z+1].x, terrain[x][z+1].y, terrain[x][z+1].z);
}
glEnd();
}
glDepthMask(GL_TRUE);
glEnable(GL_LIGHTING);
glEnable(GL_FOG);
glDisable(GL_BLEND);
glDisable(GL_TEXTURE_2D);
}
/////////////////////////////////////////////////////////////
// Perlin Noise Generator
/////////////////////////////////////////////////////////////
float persistence = 0.45f;
int Number_Of_Octaves = 3;
//一个噪声发生器
float Noise1(int x, int y)
{
x = x % 25;
y = y % 25;
int n = x + y * 57;
n = (n<<13) ^ n;
return ( 1.0f - ( (n * (n * n * 15731 + 789221) + 1376312589) & 0x7fffffff) / 1073741824.0f);
}
//一个光滑噪声发生器
float SmoothNoise_1(int x, int y)
{
float corners = ( Noise1(x-1, y-1)+Noise1(x+1, y-1)+Noise1(x-1, y+1)+Noise1(x+1, y+1) ) / 16.0f;
float sides = ( Noise1(x-1, y) +Noise1(x+1, y) +Noise1(x, y-1) +Noise1(x, y+1) ) / 8.0f;
float center = Noise1(x, y) / 4.0f;
return corners + sides + center;
}
//插值函数
float Cosine_Interpolate(float a, float b, float x)
{
double ft = x * 3.1415927;
double f = (1 - cos(ft)) * 0.5f;
return a*(1-f) + b*f;
}
//插值噪声发生器
float InterpolatedNoise_1(float x, float y)
{
int integer_X = int(x);
float fractional_X = x - integer_X;
int integer_Y = int(y);
float fractional_Y = y - integer_Y;
float v1 = SmoothNoise_1(integer_X, integer_Y);
float v2 = SmoothNoise_1(integer_X + 1, integer_Y);
float v3 = SmoothNoise_1(integer_X, integer_Y + 1);
float v4 = SmoothNoise_1(integer_X + 1, integer_Y + 1);
float i1 = Cosine_Interpolate(v1 , v2 , fractional_X);
float i2 = Cosine_Interpolate(v3 , v4 , fractional_X);
return Cosine_Interpolate(i1 , i2 , fractional_Y);
}
//最终的PERLIN NOISE
float PerlinNoise_2D(float x, float y)
{
float total = 0.0f;
float p = persistence;
int n = Number_Of_Octaves - 1;
for(int i=0;i<=n;i++)
{
float frequency = pow((float)2,i);
float amplitude = pow(p,i);
total = total + InterpolatedNoise_1(x * frequency, y * frequency) * amplitude;
}
return total;
}
/////////// 鼠标调整视野 /////////////////
float angle_x(45.0f);
float angle_y(45.0f);
void AnjustViewByMouse()
{
static int mouse_x=0;
static int mouse_y=0;
if(fullscreen == true)
{
POINT newpos;
GetCursorPos(&newpos);
angle_x+=(newpos.y - mouse_y)/360.0f;
angle_y+=(newpos.x - mouse_x)/360.0f;
//confine the movement
if(angle_x>3.14159f/2.0f) angle_x=3.14159f/2.0f;
if(angle_x<-3.14159f/2.0f) angle_x=-3.14159f/2.0f;
//newpos.x=320;
//newpos.y=240;
SetCursorPos(320, 240);
}
if(GetAsyncKeyState(VK_LBUTTON))
{
POINT newpos;
GetCursorPos(&newpos);
angle_x+=(newpos.y - mouse_y)/360.0f;
angle_y+=(newpos.x - mouse_x)/360.0f;
//confine the movement
if(angle_x>3.14159f/2.0f) angle_x=3.14159f/2.0f;
if(angle_x<-3.14159f/2.0f) angle_x=-3.14159f/2.0f;
}
POINT pos;
GetCursorPos(&pos);
mouse_x=pos.x;
mouse_y=pos.y;
} |
|