Визуализация воды

Автор: Пользователь скрыл имя, 12 Декабря 2011 в 11:48, курсовая работа

Описание работы

Моделирование водных поверхностей является сложной, но интересной задачей. Здесь можно выделить такие подзадачи, как моделирование небольших водоемов (с видимыми границами), для которых характерны небольшие изменения поверхности, то есть небольшие колебания, а также интерференция колебаний от нескольких всплесков и отраженных колебаний от границ; большие водные поверхности: здесь рассматривают небольшие поверхностные колебания (как правило, в этом случае можно обойтись изменениями лишь текстуры или нескольких текстур поверхности (Bump Mapping и др., см. далее) не деформируя непосредственно саму поверхность), небольшие колебания: в этом случае поверхность разбивается на треугольники, но достаточно большого размера и над поверхностью производят небольшие колебания, которые соответствуют, например, небольшим волнам, большие колебания: этот большие волны, брызги и др., здесь происходят значительные деформации водных поверхностей, которые достаточно сложно физически описываются, поэтому большие волны практически никогда не визуализируются.

Работа содержит 1 файл

kurs.doc

— 428.50 Кб (Скачать)

           FMass:Double;

           FCompressCoef:Double;

           FDempfCoef:Double;

           FMaxForce:Double;

           FMaxForce_Y:Double;

           FRandomForceTime:Integer;

           FRandomForceRemainedTime:Integer;

           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:Integer);

             procedure SetAlpha(Value:Double);

    public

          constructor Create(WaterTex,HitsTex,BumpTex:String);

          destructor  Destroy; override;

          procedure   Animation(const Deltatime_ms:Integer);

          procedure   AddHits(Pos_X,Pos_Y,Pos_Z,Power,Radius:Double);

          procedure   RandomForce;

          procedure   Draw(Cam_X,Cam_Y,Cam_Z:Double);

          procedure   DrawWithHits(Cam_X,Cam_Y,Cam_Z,Normal_X,Normal_Y,Normal_Z:Double);

          property    Nodes:TNodes                     read FNodes                   write FNodes;

          property    Segments:Byte                    read FSegments                write SetSegments;

          property    Mass:Double                      read FMass                    write SetMass;

          property    CompressCoef:Double              read FCompressCoef            write FCompressCoef;

          property    DempfCoef:Double                 read FDempfCoef               write FDempfCoef;

          property    MaxForce:Double                  read FMaxForce                write FMaxForce;

          property    MaxForce_Y:Double                read FMaxForce_Y              write FMaxForce_Y;

          property    RandomForceTime:Integer          read FRandomForceTime         write SetRandomForceTime;

          property    RandomForceRemainedTime:Integer  read FRandomForceRemainedTime write FRandomForceRemainedTime;

          property    UseRandomForce:Boolean           read FUseRandomForce          write FUseRandomForce;

          property    UseBumping:Boolean               read FUseBumping              write FUseBumping;

          property    HitsSize:Double                  read FHitsSize                write FHitsSize;

          property    Gravity:Double                   read FGravity                 write FGravity;

          property    HitsCount:Byte                   read FHitsCount               write FHitsCount;

          property    Hits:THits                       read FHits                    write FHits;

          property    Position:TVector3D               read FPosition                write FPosition;

          property    Width:Double                     read FWidth                   write FWidth;

          property    Height:Double                    read FHeight                  write FHeight;

          property    TexWater:TGLTexture              read FTexWater;

          property    TexHits:TGLTexture               read FTexHits;

          property    TexBump1:TGLTexture              read FTexBump1;

          property    TexBump2:TGLTexture              read FTexBump2;

          property    Alpha:Double                     read FAlpha                   write SetAlpha;

  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,HitsTex,BumpTex:String);

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.CreateWithPrep(WaterTex);

     FTexHits:=TGLTexture.CreateWithPrep(HitsTex);

     FTexBump1:=TGLTexture.CreateWithPrepDiv2(BumpTex);

     FTexBump2:=TGLTexture.CreateWithPrepDiv2_Inv(BumpTex);

     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:Byte);

var

   i,j: Integer;

begin

     if (FSegments<>Value)and(Value>1)

       then begin

                 FSegments:=Value;

                 SetLength(FNodes,FSegments,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(Value:Integer);

begin

     if (FRandomForceTime<>Value)and(Value>0)

       then begin

                 FRandomForceTime:=Value;

                 FRandomForceRemainedTime:=Value;

            end;

end;

procedure   TGLWater.SetAlpha(Value:Double);

begin

     if (FAlpha<>Value)and(Value>=0)and(Value<=1)

       then FAlpha:=Value;

end;

procedure   TGLWater.Draw(Cam_X,Cam_Y,Cam_Z:Double);

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_BACK, GL_DIFFUSE, @Alph);

       //Переместим воду в заданные координаты

       if UseBumping

         then begin

                   glTranslatef(Position.X,Position.Y-0.2,Position.Z);

                   //Применим текстуру

                   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/(Segments-1));

                        glVertex3d((-0.5+FNodes[i,j].Coord.X)*Width,     FNodes[i,j].Coord.Y,     (-0.5+FNodes[i,j].Coord.Z)*Height);

                        glTexCoord(j/(Segments-1),(i+1)/(Segments-1));

                        glVertex3d((-0.5+FNodes[i+1,j].Coord.X)*Width,   FNodes[i+1,j].Coord.Y,   (-0.5+FNodes[i+1,j].Coord.Z)*Height);

                        glTexCoord((j+1)/(Segments-1),(i+1)/(Segments-1));

                        glVertex3d((-0.5+FNodes[i+1,j+1].Coord.X)*Width, FNodes[i+1,j+1].Coord.Y, (-0.5+FNodes[i+1,j+1].Coord.Z)*Height);

                        //----------------------------------------------------------------

                        glTexCoord(j/(Segments-1),i/(Segments-1));

                        glVertex3d((-0.5+FNodes[i,j].Coord.X)*Width,     FNodes[i,j].Coord.Y,     (-0.5+FNodes[i,j].Coord.Z)*Height);

                        glTexCoord((j+1)/(Segments-1),i/(Segments-1));

                        glVertex3d((-0.5+FNodes[i,j+1].Coord.X)*Width,   FNodes[i,j+1].Coord.Y,   (-0.5+FNodes[i,j+1].Coord.Z)*Height);

                        glTexCoord((j+1)/(Segments-1),(i+1)/(Segments-1));

                        glVertex3d((-0.5+FNodes[i+1,j+1].Coord.X)*Width, FNodes[i+1,j+1].Coord.Y, (-0.5+FNodes[i+1,j+1].Coord.Z)*Height);

                   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_Y)+sqr(Vec_Z));

                 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-1),Vec_Y+i/(Segments-1));

                        glVertex3d((-0.5+FNodes[i,j].Coord.X)*Width,     FNodes[i,j].Coord.Y,     (-0.5+FNodes[i,j].Coord.Z)*Height);

                        glTexCoord(Vec_X+j/(Segments-1),Vec_Y+(i+1)/(Segments-1));

                        glVertex3d((-0.5+FNodes[i+1,j].Coord.X)*Width,   FNodes[i+1,j].Coord.Y,   (-0.5+FNodes[i+1,j].Coord.Z)*Height);

                        glTexCoord(Vec_X+(j+1)/(Segments-1),Vec_Y+(i+1)/(Segments-1));

                        glVertex3d((-0.5+FNodes[i+1,j+1].Coord.X)*Width, FNodes[i+1,j+1].Coord.Y, (-0.5+FNodes[i+1,j+1].Coord.Z)*Height);

Информация о работе Визуализация воды