Автор: Пользователь скрыл имя, 12 Декабря 2011 в 11:48, курсовая работа
Моделирование водных поверхностей является сложной, но интересной задачей. Здесь можно выделить такие подзадачи, как моделирование небольших водоемов (с видимыми границами), для которых характерны небольшие изменения поверхности, то есть небольшие колебания, а также интерференция колебаний от нескольких всплесков и отраженных колебаний от границ; большие водные поверхности: здесь рассматривают небольшие поверхностные колебания (как правило, в этом случае можно обойтись изменениями лишь текстуры или нескольких текстур поверхности (Bump Mapping и др., см. далее) не деформируя непосредственно саму поверхность), небольшие колебания: в этом случае поверхность разбивается на треугольники, но достаточно большого размера и над поверхностью производят небольшие колебания, которые соответствуют, например, небольшим волнам, большие колебания: этот большие волны, брызги и др., здесь происходят значительные деформации водных поверхностей, которые достаточно сложно физически описываются, поэтому большие волны практически никогда не визуализируются.
glGetDoublev (GL_MODELVIEW_MATRIX, @mvMatrix);
glGetDoublev (GL_PROJECTION_MATRIX, @ProjMatrix);
// viewport[3] - высота окна в пикселях
RealY := viewport[3] - Y - 1;
glReadPixels(X, RealY, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, @Zval);
gluUnProject (X, RealY, Zval,@mvMatrix, @ProjMatrix, @Viewport, wx, wy, wz);
if (wx<100) and (wx>-100) and (wz<100) and (wz>-100)
then begin
if (MainForm.ShowBoxCheckBox.
then exit;
if MainForm.ShowGroundCheckBox.
then begin
//Определим в какую ячейку
земли попадает точка (wx,wy,
tx:=wx;
tz:=wz;
g:=0;
while tx>-100+200/(GroundSegment-1) do
begin
end;
h:=0;
while tz>-100+200/(GroundSegment-1) do
begin
end;
//Точка должна быть выше земли
if (wy<GroundMas[g,h]+1)and(
then exit;
end;
//Чтобы всплески были видны, иначе они будут сразу же исчезать
if wy<1
then wy:=1;
Water.AddHits(wx,wy,wz,Power,
end;
end;
procedure TMainForm.FormMouseDown(
Shift: TShiftState; X, Y: Integer);
begin
if
(ssRight in Shift)and(HitsEnableCheckBox.
then AddHits(X,Y,HitsPowerEdit.
end;
procedure TMainForm.FormMouseMove(
Y: Integer);
begin
if ssLeft in Shift
then begin
//Поворот камеры
Cam_Angle_X:=Cam_Angle_X+x-mx;
Cam_Angle_Y:=Cam_Angle_Y+y-my;
if Cam_Angle_Y<-89
then Cam_Angle_Y:=-89;
if Cam_Angle_Y>89
then Cam_Angle_Y:=89;
ResetCamCoords;
Resize;
end;
mx:=X;
my:=Y;
end;
procedure TMainForm.FormResize(Sender: TObject);
begin
//Устанавливае размер окна OpenGL
glViewport(0, 0, ClientWidth-PageControl.Width, ClientHeight);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(30, 1.25, 1,1000);
//Ставим камеру
GLULookAt(Cam_X,Cam_Y,Cam_Z,
glMatrixMode(GL_MODELVIEW);
end;
procedure TMainForm.HitsCountEditChange(
begin
Water.HitsCount:=round(
end;
procedure TMainForm.
begin
Water.Gravity:=
end;
procedure TMainForm.HitsSizeEditChange(
begin
Water.HitsSize:=HitsSizeEdit.
end;
procedure TMainForm.KeyTimerTimer(
var
speed:Single;
Vect,Temp:TGLArrayf3;
Rad:Single;
begin
//Клавиши управления камерой
Vect[0]:=Target_X-Cam_X;
Vect[1]:=0;
Vect[2]:=Target_Z-Cam_Z;
Rad:=Sqrt(Sqr(Cam_X-Target_X)+
Vect[0]:=Vect[0]/Rad;
Vect[1]:=Vect[1]/Rad;
Vect[2]:=Vect[2]/Rad;
if IsKeyDown(VK_SHIFT)
then speed:=5
else if IsKeyDown(VK_Control)
then speed:=1
else speed:=3;
if IsKeyDown('Q')
then begin
Cam_Y:=Cam_Y+speed;
Target_Y:=Target_Y+speed;
Resize;
MainForm.SetFocus;
end;
if IsKeyDown('E')
then begin
Cam_Y:=Cam_Y-speed;
Target_Y:=Target_Y-speed;
Resize;
end;
if IsKeyDown('W')
then begin
Cam_X:=Cam_X+Vect[0]*speed;
Cam_Z:=Cam_Z+Vect[2]*speed;
Target_X:=Target_X+Vect[0]*
Target_Z:=Target_Z+Vect[2]*
Resize;
end;
if IsKeyDown('S')
then begin
Cam_X:=Cam_X-Vect[0]*speed;
Cam_Z:=Cam_Z-Vect[2]*speed;
Target_X:=Target_X-Vect[0]*
Target_Z:=Target_Z-Vect[2]*
Resize;
end;
Temp[0]:=-Vect[2];
Temp[2]:=Vect[0];
Vect[0]:=Temp[0];
Vect[2]:=Temp[2];
if IsKeyDown('D')
then begin
Cam_X:=Cam_X+Vect[0]*speed;
Cam_Z:=Cam_Z+Vect[2]*speed;
Target_X:=Target_X+Vect[0]*
Target_Z:=Target_Z+Vect[2]*
Resize;
end;
if IsKeyDown('A')
then begin
Cam_X:=Cam_X-Vect[0]*speed;
Cam_Z:=Cam_Z-Vect[2]*speed;
Target_X:=Target_X-Vect[0]*
Target_Z:=Target_Z-Vect[2]*
Resize;
end;
end;
procedure TMainForm.
begin
Water.Alpha:=WaterAlphaEdit.
end;
procedure TMainForm.
begin
Water.CompressCoef:=
end;
procedure TMainForm.
begin
Water.DempfCoef:=
end;
procedure TMainForm.WaterMassEditChange(
begin
Water.Mass:=WaterMassEdit.
end;
procedure TMainForm.
begin
Water.MaxForce:=
end;
procedure TMainForm.
begin
Water.MaxForce_Y:=
end;
procedure TMainForm.
begin
Water.RandomForceTime:=round(
end;
procedure TMainForm.WaterRelaxBtnClick(
var
i,j: Integer;
begin
for i:=0 to Water.Segments-1 do
for j:=0 to Water.Segments-1 do
begin
SetVector(Water.Nodes[i,j].F,
SetVector(Water.Nodes[i,j].F_
SetVector(Water.Nodes[i,j].
SetVector(Water.Nodes[i,j].a,
SetVector(Water.Nodes[i,j].v,
end;
end;
procedure TMainForm.
begin
Water.Segments:=round(
end;
procedure TMainForm.
begin
Water.UseBumping:=
end;
procedure TMainForm.
begin
Water.UseRandomForce:=
end;
procedure TMainForm.DrawTimerTimer(
var
NewTime : cardinal;
begin
//Определим время между кадрами
NewTime := TimeGetTime;
Water.Animation(NewTime-
Draw;
CurTime:=NewTime;
end;
procedure DrawBox(Pos_X,Pos_Y,Pos_Z,
begin
glPushMatrix;
//Рисует кубик
glTranslatef(Pos_X,Pos_Y,Pos_
glBegin(GL_QUADS);
//Низ
glTexCoord(0,0);
glVertex(-Width, 0, -Depth);
glTexCoord(1,0);
glVertex( Width, 0, -Depth);
glTexCoord(1,1);
glVertex( Width, 0, Depth);
glTexCoord(0,1);
glVertex(-Width, 0, Depth);
//Верх
glTexCoord(0,0);
glVertex(-Width, Height, -Depth);
glTexCoord(1,0);
glVertex( Width, Height, -Depth);
glTexCoord(1,1);
glVertex( Width, Height, Depth);
glTexCoord(0,1);
glVertex(-Width, Height, Depth);
//Лево
glTexCoord(0,0);