Автор: Пользователь скрыл имя, 12 Декабря 2011 в 11:48, курсовая работа
Моделирование водных поверхностей является сложной, но интересной задачей. Здесь можно выделить такие подзадачи, как моделирование небольших водоемов (с видимыми границами), для которых характерны небольшие изменения поверхности, то есть небольшие колебания, а также интерференция колебаний от нескольких всплесков и отраженных колебаний от границ; большие водные поверхности: здесь рассматривают небольшие поверхностные колебания (как правило, в этом случае можно обойтись изменениями лишь текстуры или нескольких текстур поверхности (Bump Mapping и др., см. далее) не деформируя непосредственно саму поверхность), небольшие колебания: в этом случае поверхность разбивается на треугольники, но достаточно большого размера и над поверхностью производят небольшие колебания, которые соответствуют, например, небольшим волнам, большие колебания: этот большие волны, брызги и др., здесь происходят значительные деформации водных поверхностей, которые достаточно сложно физически описываются, поэтому большие волны практически никогда не визуализируются.
FMass:Double;
FCompressCoef:Double;
FDempfCoef:Double;
FMaxForce:Double;
FMaxForce_Y:Double;
FRandomForceTime:Integer;
FRandomForceRemainedTime:
FUseRandomForce:Boolean;
FUseBumping:Boolean;
FHitsSize:Double;
FGravity:Double;
FHitsCount:Byte;
FHits:THits;
FPosition:TVector3D;
FWidth:Double;
FHeight:Double;
FTexWater:TGLTexture;
FTexHits:TGLTexture;
FTexBump1:TGLTexture;
FTexBump2:TGLTexture;
FAlpha:Double;
protected
procedure SetSegments(Value:Byte);
procedure SetMass(Value:Double);
procedure SetRandomForceTime(Value:
procedure SetAlpha(Value:Double);
public
constructor Create(WaterTex,HitsTex,
destructor Destroy; override;
procedure Animation(const Deltatime_ms:Integer);
procedure AddHits(Pos_X,Pos_Y,Pos_Z,
procedure RandomForce;
procedure Draw(Cam_X,Cam_Y,Cam_Z:Double)
procedure DrawWithHits(Cam_X,Cam_Y,Cam_
property Nodes:TNodes
property Segments:Byte
property Mass:Double
property CompressCoef:Double
property DempfCoef:Double
property MaxForce:Double
property MaxForce_Y:Double
property RandomForceTime:Integer
property RandomForceRemainedTime:
property UseRandomForce:Boolean read FUseRandomForce write FUseRandomForce;
property UseBumping:Boolean
property HitsSize:Double
property Gravity:Double
property HitsCount:Byte
property Hits:THits read FHits write FHits;
property Position:TVector3D
property Width:Double
property Height:Double
property TexWater:TGLTexture
property TexHits:TGLTexture
property TexBump1:TGLTexture
property TexBump2:TGLTexture
property Alpha:Double
end;
procedure SetVector(var Vector:TVector3D;const NewX,NewY,NewZ:Double);
implementation
procedure SetVector(var Vector:TVector3D;const NewX,NewY,NewZ:Double);
begin
Vector.X:=NewX;
Vector.Y:=NewY;
Vector.Z:=NewZ;
end;
constructor TGLWater.Create(WaterTex,
begin
//Инициализация атрибутов
FUseRandomForce:=false;
Segments:=32;
Mass:=4;
CompressCoef:=7;
DempfCoef:=0.05;
MaxForce:=0.25;
MaxForce_Y:=1000;
RandomForceTime:=1000;
FUseRandomForce:=true;
FUseBumping:=true;
FHitsSize:=2;
FGravity:=-100;
FHitsCount:=128;
SetVector(FPosition, 0, 0, 0);
Width:=200;
Height:=200;
FTexWater:=TGLTexture.
FTexHits:=TGLTexture.
FTexBump1:=TGLTexture.
FTexBump2:=TGLTexture.
Alpha:=0.7;
end;
destructor TGLWater.Destroy;
begin
SetLength(FNodes,0);
SetLength(FHits,0);
FTexWater.Free;
FTexHits.Free;
FTexBump1.Free;
FTexBump2.Free;
end;
procedure TGLWater.SetSegments(Value:
var
i,j: Integer;
begin
if (FSegments<>Value)and(Value>1)
then begin
FSegments:=Value;
SetLength(FNodes,FSegments,
for i:=0 to Segments-1 do
for j:=0 to Segments-1 do
begin
SetVector(FNodes[i,j].F, 0, 0, 0);
SetVector(FNodes[i,j].F_ext, 0, 0, 0);
SetVector(FNodes[i,j].Coord, j/(Segments-1), 0, i/(Segments-1));
SetVector(FNodes[i,j].a, 0, 0, 0);
SetVector(FNodes[i,j].v, 0, 0, 0);
end;
if FUseRandomForce
then RandomForce;
end;
end;
procedure TGLWater.SetMass(Value:Double)
begin
if (FMass<>Value)and(Value>0)
then FMass:=Value;
end;
procedure TGLWater.SetRandomForceTime(
begin
if
(FRandomForceTime<>Value)and(
then begin
FRandomForceTime:=Value;
FRandomForceRemainedTime:=
end;
end;
procedure TGLWater.SetAlpha(Value:
begin
if
(FAlpha<>Value)and(Value>=0)
then FAlpha:=Value;
end;
procedure TGLWater.Draw(Cam_X,Cam_Y,Cam_
var
i,j: Integer;
Alph: TGLArrayf4;
Vec_X,Vec_Y,Vec_Z,len:Double;
begin
//Запомнем матрицу
glPushMatrix;
//Определим прозрачность
Alph[0]:=1;
Alph[1]:=1;
Alph[2]:=1;
Alph[3]:=Alpha;
glMaterialfv(GL_FRONT_AND_
//Переместим воду в заданные координаты
if UseBumping
then begin
glTranslatef(Position.X,
//Применим текстуру
TexBump1.ApplyTexture;
glDisable(GL_BLEND);
glDisable(GL_LIGHTING);
//Нарисуем треугольниками bump1
glBegin(GL_TRIANGLES);
for i:=0 to Segments-2 do
for j:=0 to Segments-2 do
begin
glTexCoord(j/(Segments-1),i/(
glVertex3d((-0.5+FNodes[i,j].
glTexCoord(j/(Segments-1),(i+
glVertex3d((-0.5+FNodes[i+1,j]
glTexCoord((j+1)/(Segments-1),
glVertex3d((-0.5+FNodes[i+1,j+
//----------------------------
glTexCoord(j/(Segments-1),i/(
glVertex3d((-0.5+FNodes[i,j].
glTexCoord((j+1)/(Segments-1),
glVertex3d((-0.5+FNodes[i,j+1]
glTexCoord((j+1)/(Segments-1),
glVertex3d((-0.5+FNodes[i+1,j+
end;
glEnd;
glTranslatef(0,0.1,0);
//Определим вектор смещения
Vec_X:=Cam_X-Position.X;
Vec_Y:=Cam_Y-Position.Y;
Vec_Z:=Cam_Z-Position.Z;
//Нормируем вектор и домножаем на коэффициент
len:=sqrt(sqr(Vec_X)+sqr(Vec_
Vec_X:=Vec_X/len*0.1;
Vec_Y:=Vec_Y/len*0.1;
//Применим текстуру
TexBump2.ApplyTexture;
glEnable(GL_BLEND);
glBlendFunc(GL_ONE,GL_ONE);
glDepthFunc(GL_LEQUAL);
//Нарисуем треугольниками bump2
glBegin(GL_TRIANGLES);
for i:=0 to Segments-2 do
for j:=0 to Segments-2 do
begin
glTexCoord(Vec_X+j/(Segments-
glVertex3d((-0.5+FNodes[i,j].
glTexCoord(Vec_X+j/(Segments-
glVertex3d((-0.5+FNodes[i+1,j]
glTexCoord(Vec_X+(j+1)/(
glVertex3d((-0.5+FNodes[i+1,j+