Автор: Пользователь скрыл имя, 12 Декабря 2011 в 11:48, курсовая работа
Моделирование водных поверхностей является сложной, но интересной задачей. Здесь можно выделить такие подзадачи, как моделирование небольших водоемов (с видимыми границами), для которых характерны небольшие изменения поверхности, то есть небольшие колебания, а также интерференция колебаний от нескольких всплесков и отраженных колебаний от границ; большие водные поверхности: здесь рассматривают небольшие поверхностные колебания (как правило, в этом случае можно обойтись изменениями лишь текстуры или нескольких текстур поверхности (Bump Mapping и др., см. далее) не деформируя непосредственно саму поверхность), небольшие колебания: в этом случае поверхность разбивается на треугольники, но достаточно большого размера и над поверхностью производят небольшие колебания, которые соответствуют, например, небольшим волнам, большие колебания: этот большие волны, брызги и др., здесь происходят значительные деформации водных поверхностей, которые достаточно сложно физически описываются, поэтому большие волны практически никогда не визуализируются.
end;
procedure TGLWater.AddHits(Pos_X,Pos_Y,
var
i,j:Byte;
len:Double;
Vec:TVector3D;
begin
SetLength(FHits,Length(FHits)+
for i:=1 to FHitsCount do
begin
SetVector(FHits[Length(FHits)-
SetVector(FHits[Length(FHits)-
end;
for i:=0 to Segments-1 do
for j:=0 to Segments-1 do
begin
len:=sqrt(Sqr(Pos_X-(-0.5+
if len<Radius
then begin
SetVector(Vec,((-0.5+FNodes[i,
SetVector(FNodes[i,j].F_ext,
end;
end;
end;
end.
unit MainUnit;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, ExtCtrls, OpenGL, Menus, ComCtrls, ActnList, XPStyleActnCtrls,
ActnMan, StdCtrls, Spin, JPEG, FileCtrl, Buttons, Math, keyboard, MMSystem,
TextureUnit, WaterUnit, GrisSpinEdit;
type
TMainForm = class(TForm)
DrawTimer: TTimer;
PageControl: TPageControl;
WaterTabSheet: TTabSheet;
KeyTimer: TTimer;
WaterSegmentsLabel: TLabel;
WaterSegmentsEdit: TGrisSpinEdit;
WaterMassLabel: TLabel;
WaterMassEdit: TGrisSpinEdit;
WaterCompressCoefLabel: TLabel;
WaterCompressCoefEdit: TGrisSpinEdit;
WaterDempfCoefLabel: TLabel;
WaterDempfCoefEdit: TGrisSpinEdit;
WaterMaxForceLabel: TLabel;
WaterMaxForceEdit: TGrisSpinEdit;
WaterMaxForceYLabel: TLabel;
WaterMaxForceYEdit: TGrisSpinEdit;
WaterRandomForceTimeLabel: TLabel;
WaterRandomForceTimeEdit: TGrisSpinEdit;
WaterAlphaLabel: TLabel;
WaterAlphaEdit: TGrisSpinEdit;
GeneralTabSheet: TTabSheet;
ShowWaterCheckBox: TCheckBox;
ShowGroundCheckBox: TCheckBox;
ShowBoxCheckBox: TCheckBox;
ShowLightCheckBox: TCheckBox;
WaterLineCheckBox: TCheckBox;
GroundLineCheckBox: TCheckBox;
BoxLineCheckBox: TCheckBox;
LightLineCheckBox: TCheckBox;
HitsTabSheet: TTabSheet;
HitsEnableCheckBox: TCheckBox;
HitsCountLabel: TLabel;
HitsCountEdit: TGrisSpinEdit;
HitsSizeLabel: TLabel;
HitsSizeEdit: TGrisSpinEdit;
HitsGravityLabel: TLabel;
HitsGravityEdit: TGrisSpinEdit;
HitsPowerLabel: TLabel;
HitsPowerEdit: TGrisSpinEdit;
HitsRadiusLabel: TLabel;
HitsRadiusEdit: TGrisSpinEdit;
WaterUseRandomForceCheckBox: TCheckBox;
CaustTimer: TTimer;
CaustLabel: TLabel;
CaustEdit: TGrisSpinEdit;
ShowCaustCheckBox: TCheckBox;
CaustLineCheckBox: TCheckBox;
WaterUseBumpCheckBox: TCheckBox;
WaterRelaxBtn: TButton;
procedure FormCreate(Sender: TObject);
procedure FormResize(Sender: TObject);
procedure DrawTimerTimer(Sender: TObject);
procedure Draw;
procedure FormMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer);
procedure KeyTimerTimer(Sender: TObject);
procedure
WaterSegmentsEditChange(
procedure WaterMassEditChange(Sender: TObject);
procedure
WaterCompressCoefEditChange(
procedure
WaterDempfCoefEditChange(
procedure
WaterMaxForceEditChange(
procedure
WaterMaxForceYEditChange(
procedure
WaterRandomForceTimeEditChange
procedure WaterAlphaEditChange(Sender: TObject);
procedure FormMouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
procedure HitsCountEditChange(Sender: TObject);
procedure HitsSizeEditChange(Sender: TObject);
procedure HitsGravityEditChange(Sender: TObject);
procedure
WaterUseRandomForceCheckBoxCli
procedure CaustTimerTimer(Sender: TObject);
procedure CaustEditChange(Sender: TObject);
procedure
WaterUseBumpCheckBoxClick(
procedure WaterRelaxBtnClick(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
MainForm: TMainForm;
ghRC:HGLRC;
ghDC:HDC;
Light_pos: TGLArrayf4 = (-100,100,-100,1); //Положение источника света
Light_dif: TGLArrayf4 = (1,1,1,1); //Диффузия света
Light_amb: TGLArrayf4 = (0.7,0.7,0.7,1); //Свет окружающей среды
mx,my:Integer;
CurCaust:Byte=0;
CurTime : cardinal;
Cam_X:Single = 100;
Cam_Y:Single = 100;
Cam_Z:Single = 100;
Cam_Radius:Single;
Cam_Angle_X:Single;
Cam_Angle_Y:Single;
Target_X:Single = 99.9;
Target_Y:Single = 99.9;
Target_Z:Single = 99.9;
//Текстуры
TexGround:TGLTexture;
TexWater:TGLTexture;
TexCaust1:TGLTexture;
TexCaust2:TGLTexture;
TexCaust3:TGLTexture;
TexCaust4:TGLTexture;
TexCaust5:TGLTexture;
//Вода
Water:TGLWater;
const
GroundSegment=64;
var
GroundMas:array
[0..GroundSegment-1,0..
implementation
{$R *.dfm}
function bSetupPixelFormat(DC:HDC):
var
pfd:PIXELFORMATDESCRIPTOR;
pixelformat:integer;
begin
//Настраиваем видео-режим
pfd.dwFlags := PFD_DRAW_TO_WINDOW or PFD_SUPPORT_OPENGL or PFD_DOUBLEBUFFER;
{Тип пикселя}
pfd.iPixelType := PFD_TYPE_RGBA;
{Глубина цвета}
pfd.cColorBits := 32;
{Размер буфера глубины}
pfd.cDepthBits := 32;
//Выбираем видео-режим
pixelformat := ChoosePixelFormat(dc, @pfd);
if pixelformat=0
then begin
Showmessage('Error. Не могу обнаружить видео-режим');
bSetupPixelFormat:=false;
exit;
end;
if not SetPixelFormat(dc, pixelformat, @pfd)
then begin
Showmessage('Error. Видео-режим не запускается');
bSetupPixelFormat:=false;
exit;
end;
bSetupPixelFormat:=true;
end;
procedure ResetCamAngles;
begin
//Переводим декартовые координаты камеры в сферические
Cam_Radius:=sqrt(sqr(Cam_X-
Cam_Angle_Y:=arcsin((Cam_Y-
if Cam_X>0
then Cam_Angle_X:=arcsin((Cam_Z-
else if Cam_Z>0
then Cam_Angle_X:=arccos((Cam_X-
else Cam_Angle_X:=180-arcsin((Cam_
end;
procedure ResetCamCoords;
begin
//Переводим сферические координаты камеры в декартовые
Cam_Y:=Target_Y+Cam_Radius*
Cam_X:=Target_X+Cam_Radius*
Cam_Z:=Target_Z+Cam_Radius*
end;
procedure TMainForm.FormCreate(Sender: TObject);
var
f:TFileStream;
i,j: Integer;
begin
//Нужно для включения OpenGL
ghDC := GetDC(Handle);
if not bSetupPixelFormat(ghDC)=false
then close;
ghRC := wglCreateContext(ghDC);
wglMakeCurrent(ghDC, ghRC);
glEnable(GL_DEPTH_TEST); //Включаем проверку глубины
glEnable(GL_LIGHTING); //Включаем отражение света
//Установка источника света
glEnable(GL_LIGHT0);
glLightfv(GL_LIGHT0,GL_
//Установка цветов
glLightfv(GL_LIGHT0, GL_DIFFUSE, @Light_dif);
glLightfv(GL_LIGHT0, GL_AMBIENT, @Light_amb);
//Активируем текстурирование
glEnable(GL_TEXTURE_2D);
//Настройка текстуры
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glLineWidth(5);
//Загрузка текстур
TexGround:=TGLTexture.
TexCaust1:=TGLTexture.
TexCaust2:=TGLTexture.
TexCaust3:=TGLTexture.
TexCaust4:=TGLTexture.
TexCaust5:=TGLTexture.
Water:=TGLWater.Create('Water.
Water.UseRandomForce:=false;
ResetCamAngles;
//Загрузка поверхности земли
f:=TFileStream.Create('
for i:=0 to GroundSegment-1 do
for j:=0 to GroundSegment-1 do
f.ReadBuffer(GroundMas[i,j],
f.Free;
CurTime := timeGetTime;
end;
procedure AddHits(X,Y:Integer;Power,
var
Viewport : Array [0..3] of GLInt;
mvMatrix, ProjMatrix : Array [0..15] of GLDouble;
RealY : GLint ; // позиция OpenGL y - координаты
wx, wy, wz: Double ; // возвращаемые мировые x, y, z координаты
Zval : GLfloat;
tx,tz:Double;
g,h:Integer;
begin
if (X<0) or
(Y<0) or
(X>MainForm.ClientWidth-
(Y>MainForm.ClientHeight-1)
then exit;
glGetIntegerv (GL_VIEWPORT, @Viewport);