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

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

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

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

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

kurs.doc

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

Перед выводом  третей (последней плоскости) необходимо установить следующие параметры OpenGL:

Здесь также  выводится плоскость, которая параллельна  предыдущим, но "чуть-чуть" приподнята относительно них по вектору наблюдения, для избежания пересечений. На плоскость накладывается текстура (1), при этом координаты никак не пересчитываются (в отличии от предыдущей).

В итоге получается изображение, на котором виден "микрорельеф".

Расскажем теперь, как bump mapping применяется по отношению к моделированию водных поверхностей. Предположим, что необходимо моделировать большую водную поверхность, без видимых границ (граница - линия горизонта), на которой присутствуют лишь небольшие волны, то есть она достаточно "спокойна". Тогда можно не разбивать водную поверхность на множество плоскостей, а сделать одну большую плоскость, для которой применить bump mapping с динамически изменяемой картой поверхности. Обычно сразу загружается достаточное количество карт глубины (10-15), затем они меняют друг друга, в соответствие со временем изменения водной поверхности, а в конце происходит их зацикливание. Таким образом нам достаточно выводить только один полигон (то есть 3 - в нашей реализации bump mapping'а), а не разбивать поверхность на множество полигонов.

Реально же используют следующую модель: водную поверхность  разбивают на полигонов (но уже не так много как раньше) и с  помощью этих полигонов задают общую  модель поведения водной поверхности, например, в соответствии с алгоритмом рассказанным в самом начале. Затем для каждой плоскости производится bump mapping, для передачи более точных характеристик водной поверхности.

 

Текст программы

unit GrisSpinEdit; 

interface

uses Windows, Classes, StdCtrls, ExtCtrls, Controls, Messages, SysUtils,

  Forms, Graphics, Menus, Buttons,spin;

type

{ TGrisSpinEdit }

  TGrisSpinEdit = class(TCustomEdit)

  private

    FMinValue: Extended;

    FMaxValue: Extended;

    FIncrement: Extended;

    FButton: TSpinButton;

    FEditorEnabled: Boolean;

    FBackUp: Extended;

    function GetMinHeight: Integer;

    function GetValue: Extended;

    function CheckValue (NewValue: Extended): Extended;

    procedure SetValue (NewValue: Extended);

    procedure SetMinValue (Value:Extended);

    procedure SetMaxValue (Value:Extended);

    procedure SetEditRect;

    procedure WMSize(var Message: TWMSize); message WM_SIZE;

    procedure CMEnter(var Message: TCMGotFocus); message CM_ENTER;

    procedure CMExit(var Message: TCMExit);   message CM_EXIT;

    procedure WMPaste(var Message: TWMPaste);   message WM_PASTE;

    procedure WMCut(var Message: TWMCut);   message WM_CUT;

  protected

    procedure Change; override;

    procedure GetChildren(Proc: TGetChildProc; Root: TComponent); override;

    function IsValidChar(Key: Char): Boolean; virtual;

    procedure UpClick (Sender: TObject); virtual;

    procedure DownClick (Sender: TObject); virtual;

    procedure KeyDown(var Key: Word; Shift: TShiftState); override;

    procedure KeyPress(var Key: Char); override;

    procedure CreateParams(var Params: TCreateParams); override;

    procedure CreateWnd; override;

  public

    constructor Create(AOwner: TComponent); override;

    destructor Destroy; override;

    property Button: TSpinButton read FButton;

  published

    property Anchors;

    property AutoSelect;

    property AutoSize;

    property Color;

    property Constraints;

    property Ctl3D;

    property DragCursor;

    property DragMode;

    property EditorEnabled: Boolean read FEditorEnabled write FEditorEnabled default True;

    property Enabled;

    property Font;

    property Increment: Extended read FIncrement write FIncrement;

    property MaxLength;

    property MaxValue: Extended read FMaxValue write SetMaxValue;

    property MinValue: Extended read FMinValue write SetMinValue;

    property ParentColor;

    property ParentCtl3D;

    property ParentFont;

    property ParentShowHint;

    property PopupMenu;

    property ReadOnly;

    property ShowHint;

    property TabOrder;

    property TabStop;

    property Value: Extended read GetValue write SetValue;

    property Visible;

    property OnChange;

    property OnClick;

    property OnDblClick;

    property OnDragDrop;

    property OnDragOver;

    property OnEndDrag;

    property OnEnter;

    property OnExit;

    property OnKeyDown;

    property OnKeyPress;

    property OnKeyUp;

    property OnMouseDown;

    property OnMouseMove;

    property OnMouseUp;

    property OnStartDrag;

  end;

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

procedure Register;

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

implementation

procedure Register;

begin

  RegisterComponents('Gris''s Edits', [TGrisSpinEdit]);

end;

{ TGrisSpinEdit }

constructor TGrisSpinEdit.Create(AOwner: TComponent);

begin

  inherited Create(AOwner);

  FButton := TSpinButton.Create(Self);

  FButton.Width := 15;

  FButton.Height := 17;

  FButton.Visible := True;

  FButton.Parent := Self;

  FButton.FocusControl := Self;

  FButton.OnUpClick := UpClick;

  FButton.OnDownClick := DownClick;

  Text := '0';

  ControlStyle := ControlStyle - [csSetCaption];

  FIncrement := 1;

  FEditorEnabled := True;

  ParentBackground := False;

end;

destructor TGrisSpinEdit.Destroy;

begin

  FButton := nil;

  inherited Destroy;

end;

procedure TGrisSpinEdit.GetChildren(Proc: TGetChildProc; Root: TComponent);

begin

end;

procedure TGrisSpinEdit.KeyDown(var Key: Word; Shift: TShiftState);

begin

  if Key = VK_UP then UpClick (Self)

  else if Key = VK_DOWN then DownClick (Self);

  inherited KeyDown(Key, Shift);

end;

procedure TGrisSpinEdit.KeyPress(var Key: Char);

begin

  if not IsValidChar(Key) then

  begin

    Key := #0;

  end;

  if Key <> #0 then inherited KeyPress(Key);

end;

function TGrisSpinEdit.IsValidChar(Key: Char): Boolean;

begin

  Result := (Key in [DecimalSeparator, '-', '0'..'9']) or

    ((Key < #32) and (Key <> Chr(VK_RETURN)));

  if (Key='-')and(pos('-',Text)>0)

    then Result:=false;

  if not FEditorEnabled and Result and ((Key >= #32) or

      (Key = Char(VK_BACK)) or (Key = Char(VK_DELETE))) then

    Result := False;

end;

procedure TGrisSpinEdit.CreateParams(var Params: TCreateParams);

begin

  inherited CreateParams(Params);

{  Params.Style := Params.Style and not WS_BORDER;  }

  Params.Style := Params.Style or ES_MULTILINE or WS_CLIPCHILDREN;

end;

procedure TGrisSpinEdit.CreateWnd;

begin

  inherited CreateWnd;

  SetEditRect;

end;

procedure TGrisSpinEdit.SetEditRect;

var

  Loc: TRect;

begin

  SendMessage(Handle, EM_GETRECT, 0, LongInt(@Loc));

  Loc.Bottom := ClientHeight + 1;  {+1 is workaround for windows paint bug}

  Loc.Right := ClientWidth - FButton.Width - 2;

  Loc.Top := 0; 

  Loc.Left := 0;

  SendMessage(Handle, EM_SETRECTNP, 0, LongInt(@Loc));

  SendMessage(Handle, EM_GETRECT, 0, LongInt(@Loc));  {debug}

end;

procedure TGrisSpinEdit.WMSize(var Message: TWMSize);

var

  MinHeight: Integer;

begin

  inherited;

  MinHeight := GetMinHeight;

    { text edit bug: if size to less than minheight, then edit ctrl does

      not display the text }

  if Height < MinHeight then  

    Height := MinHeight

  else if FButton <> nil then

  begin

    if NewStyleControls and Ctl3D then

      FButton.SetBounds(Width - FButton.Width - 5, 0, FButton.Width, Height - 5)

    else FButton.SetBounds (Width - FButton.Width, 1, FButton.Width, Height - 3);

    SetEditRect;

  end;

end;

function TGrisSpinEdit.GetMinHeight: Integer;

var

  DC: HDC;

  SaveFont: HFont;

  I: Integer;

  SysMetrics, Metrics: TTextMetric;

begin

  DC := GetDC(0);

  GetTextMetrics(DC, SysMetrics);

  SaveFont := SelectObject(DC, Font.Handle);

  GetTextMetrics(DC, Metrics);

  SelectObject(DC, SaveFont);

  ReleaseDC(0, DC);

  I := SysMetrics.tmHeight;

  if I > Metrics.tmHeight then I := Metrics.tmHeight;

  Result := Metrics.tmHeight + I div 4 + GetSystemMetrics(SM_CYBORDER) * 4 + 2;

end;

procedure TGrisSpinEdit.UpClick (Sender: TObject);

begin

  if ReadOnly then MessageBeep(0)

  else Value := Value + FIncrement;

end;

procedure TGrisSpinEdit.DownClick (Sender: TObject);

begin

  if ReadOnly then MessageBeep(0)

  else Value := Value - FIncrement;

end;

procedure TGrisSpinEdit.WMPaste(var Message: TWMPaste);

begin

  if not FEditorEnabled or ReadOnly then Exit;

  inherited;

end;

procedure TGrisSpinEdit.WMCut(var Message: TWMPaste);

begin

  if not FEditorEnabled or ReadOnly then Exit;

  inherited;

end;

procedure TGrisSpinEdit.CMExit(var Message: TCMExit);

begin

  inherited;

  if CheckValue (Value) <> Value then

    SetValue (Value);

  Value:=FBackUp;

end;

function TGrisSpinEdit.GetValue: Extended;

begin

  try

     if (Text<>'')and(Text<>'-')

       then Result := StrToFloat (Text)

       else Result := FBackUp;

  except

    Result := FBackUp;

  end;

end;

procedure TGrisSpinEdit.SetValue (NewValue: Extended);

begin

  Text := FloatToStr (CheckValue (NewValue));

end;

function TGrisSpinEdit.CheckValue (NewValue: Extended): Extended;

begin

  Result := NewValue;

  if (FMaxValue <> FMinValue) then

  begin

    if NewValue < FMinValue then

      Result := FMinValue

    else if NewValue > FMaxValue then

      Result := FMaxValue;

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