123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850 |
- //
- // The multimedia graphics platform GLScene https://github.com/glscene
- //
- unit GLS.Blur;
- (* Applies a blur effect over the viewport *)
- interface
- {$I GLScene.inc}
- uses
- Winapi.OpenGL,
- Winapi.OpenGLext,
- System.Classes,
- System.SysUtils,
- VCL.Graphics,
- GLS.VectorTypes,
- GLS.VectorGeometry,
- GLS.BaseClasses,
- GLS.Scene,
- GLS.Objects,
- GLS.BitmapFont,
- GLS.Texture,
- GLS.Material,
- GLS.HudObjects,
- GLS.Color,
- GLS.Graphics,
- GLS.Context,
- GLS.XOpenGL,
- GLS.State,
- GLS.TextureFormat,
- GLS.RenderContextInfo;
- type
- TGLBlurPreset = (pNone, pGlossy, pBeastView, pOceanDepth, pDream, pOverBlur, pAdvancedBlur);
- TGLBlurkind = (bNone, bSimple, bAdvanced);
-
- TRGBPixel = record
- R, G, B: TGLubyte;
- end;
-
- TRGBPixelBuffer = array of TRGBPixel;
- TGLAdvancedBlurImagePrepareEvent = procedure(Sender: TObject; BMP32: TGLImage; var DoBlur: boolean) of object;
- EGLMotionBlurException = class(Exception);
- TGLBlur = class(TGLHUDSprite)
- private
- FViewer: TGLMemoryViewer;
- OldTime: Double;
- FDoingMemView: boolean;
- FBlurDeltaTime: Double;
- FBlurTop: Single;
- FBlurBottom: Single;
- FBlurLeft: Single;
- FBlurRight: Single;
- FRenderHeight: Integer;
- FRenderWidth: Integer;
- FPreset: TGLBlurPreset;
- FTargetObject: TGLbaseSceneObject;
- FOnAdvancedBlurImagePrepareEvent: TGLAdvancedBlurImagePrepareEvent;
- FBlur: TGLBlurKind;
- Pixelbuffer: TRGBPixelBuffer;
- FAdvancedBlurPasses: integer;
- FOnAfterTargetRender: TNotifyEvent;
- FOnBeforeTargetRender: TNotifyEvent;
- FAdvancedBlurAmp: single;
- FBlurSelf: boolean;
- FAdvancedBlurLowClamp: byte;
- FAdvancedBlurHiClamp: byte;
- FRenderBackgroundColor: TColor;
- procedure DoMemView(baseObject: TGLBaseSceneObject);
- procedure SetRenderHeight(const Value: Integer);
- procedure SetRenderWidth(const Value: Integer);
- procedure UpdateImageSettings;
- procedure SetPreset(const Value: TGLBlurPreset);
- function StoreBlurBottom: Boolean;
- function StoreBlurDeltaTime: Boolean;
- function StoreBlurRight: Boolean;
- function StoreBlurTop: Boolean;
- function StoreBlurLeft: Boolean;
- procedure SetTargetObject(const Value: TGLbaseSceneObject);
- procedure SetOnAdvancedBlurImagePrepareEvent(const Value: TGLAdvancedBlurImagePrepareEvent);
- procedure SetBlur(const Value: TGLBlurKind);
- procedure SetAdvancedBlurPasses(const Value: integer);
- procedure SetOnAfterTargetRender(const Value: TNotifyEvent);
- procedure SetOnBeforeTargetRender(const Value: TNotifyEvent);
- procedure SetAdvancedBlurAmp(const Value: single);
- procedure SetBlurSelf(const Value: boolean);
- procedure SetAdvancedBlurLowClamp(const Value: byte);
- procedure SetAdvancedBlurHiClamp(const Value: byte);
- procedure SetRenderBackgroundColor(const Value: TColor);
- public
- constructor Create(AOwner: TComponent); override;
- destructor Destroy; override;
- procedure DoProgress(const progressTime: TGLProgressTimes); override;
- procedure DoRender(var ARci: TGLRenderContextInfo;
- ARenderSelf, ARenderChildren: Boolean); override;
- procedure Notification(AComponent: TComponent; Operation: TOperation); override;
- published
- property Blur: TGLBlurKind read FBlur write SetBlur;
- property BlurDeltaTime: Double read FBlurDeltaTime write FBlurDeltaTime stored StoreBlurDeltaTime;
- property BlurLeft: Single read FBlurLeft write FBlurLeft stored StoreBlurLeft;
- property BlurTop: Single read FBlurTop write FBlurTop stored StoreBlurTop;
- property BlurRight: Single read FBlurRight write FBlurRight stored StoreBlurRight;
- property BlurBottom: Single read FBlurBottom write FBlurBottom stored StoreBlurBottom;
- property RenderWidth: Integer read FRenderWidth write SetRenderWidth default 256;
- property RenderHeight: Integer read FRenderHeight write SetRenderHeight default 256;
- property Preset: TGLBlurPreset read FPreset write SetPreset stored false;
- property TargetObject: TGLbaseSceneObject read FTargetObject write SetTargetObject;
- property AdvancedBlurPasses: integer read FAdvancedBlurPasses write SetAdvancedBlurPasses;
- property AdvancedBlurAmp: single read FAdvancedBlurAmp write SetAdvancedBlurAmp;
- property AdvancedBlurLowClamp: byte read FAdvancedBlurLowClamp write SetAdvancedBlurLowClamp;
- property AdvancedBlurHiClamp: byte read FAdvancedBlurHiClamp write SetAdvancedBlurHiClamp;
- property BlurSelf: boolean read FBlurSelf write SetBlurSelf;
- property RenderBackgroundColor: TColor read FRenderBackgroundColor write SetRenderBackgroundColor;
- property OnAdvancedBlurImagePrepareEvent: TGLAdvancedBlurImagePrepareEvent read FOnAdvancedBlurImagePrepareEvent write SetOnAdvancedBlurImagePrepareEvent;
- property OnBeforeTargetRender: TNotifyEvent read FOnBeforeTargetRender write SetOnBeforeTargetRender;
- property OnAfterTargetRender: TNotifyEvent read FOnAfterTargetRender write SetOnAfterTargetRender;
- end;
- (*This component blurs everything thatis rendered BEFORE it. So if you want part
- of your scene blured, the other not blured, make sure that the other part is
- rendered after this component. It is fast and does not require shaders.
- Note: it is FPS-dependant. Also also can produce a "blury trail effect", which
- stays on the screen until something new is rendered over it. It can be overcome
- by changing the Material.FrontProperties.Diffuse property. This, however, also
- has a drawback - the picture becomes more blured altogether. For example, if
- your backgroud color is Black, set the Material.FrontProperties.Diffuse to White.
- If it is White, set Material.FrontProperties.Diffuse to Black. I haven't tried
- any others, but I hope you get the idea ;)
- I've seen this effect in different Bruring components, even in shaders, but if
- anyone knows another way to fix this issue - please post it on the glscene
- newsgroup. *)
- TGLMotionBlur = class(TGLCustomSceneObject, IGLInitializable)
- private
- FIntensity: Single;
- function StoreIntensity: Boolean;
- protected
- procedure DoOnAddedToParent; override;
- procedure InitializeObject(ASender: TObject; const ARci: TGLRenderContextInfo); virtual;
- public
- // This function is only valid AFTER OpenGL has been initialized.
- function SupportsRequiredExtensions: Boolean;
- procedure DoRender(var ARci: TGLRenderContextInfo; ARenderSelf, ARenderChildren: Boolean); override;
- constructor Create(aOwner: TComponent); override;
- procedure Assign(Source: TPersistent); override;
- published
- // The more the intensity, the more blur you have.
- property Intensity: Single read FIntensity write FIntensity stored StoreIntensity;
- // From TGLBaseSceneObject.
- property Visible;
- property OnProgress;
- property Behaviours;
- property Effects;
- property Hint;
- end;
- //------------------------------------------------------------------------
- implementation
- //------------------------------------------------------------------------
- uses
- GLS.Coordinates,
- GLS.PersistentClasses,
- GLS.Strings,
- GLS.OpenGLAdapter;
- const
- EPS = 0.001;
- constructor TGLBlur.Create(AOwner: TComponent);
- begin
- inherited;
- FBlurDeltaTime := 0.02;
- FBlurTop := 0.01;
- FBlurLeft := 0.01;
- FBlurRight := 0.01;
- FBlurBottom := 0.01;
- FRenderHeight := 256;
- FRenderWidth := 256;
- FViewer := TGLMemoryViewer.Create(Self);
- FPreset := pNone;
- Material.Texture.Disabled := False;
- FAdvancedBlurPasses := 1;
- FAdvancedBlurAmp := 1.1;
- FBlurSelf := true;
- FAdvancedBlurLowClamp := 0;
- FAdvancedBlurHiClamp := 255;
- FRenderBackgroundColor := ClBlack;
- end;
- destructor TGLBlur.Destroy;
- begin
- FViewer.Free;
- inherited;
- end;
- procedure TGLBlur.UpdateImageSettings;
- var
- B: TBitmap;
- begin
- if Material.Texture.Image is TGLBlankImage then
- with TGLBlankImage(Material.Texture.Image) do
- begin
- Width := RenderWidth;
- Height := Renderheight;
- end
- else if Material.Texture.Image is TGLPersistentImage then
- begin
- B := TGLPersistentImage(Material.Texture.Image).Picture.Bitmap;
- B.Width := 0;
- B.Height := 0;
- B.Width := RenderWidth;
- B.Height := RenderHeight;
- end;
- with FViewer do
- begin
- Width := RenderWidth;
- Height := Renderheight;
- end;
- SetLength(Pixelbuffer, RenderWidth * RenderHeight);
- end;
- procedure TGLBlur.DoProgress(const progressTime: TGLProgressTimes);
- begin
- inherited;
- if self.Visible and (progressTime.newTime - OldTime > FBlurDeltaTime) then
- begin
- OldTime := progressTime.newTime;
- if TargetObject <> nil then
- DoMemView(TargetObject);
- end;
- end;
- procedure TGLBlur.DoMemView(baseObject: TGLBaseSceneObject);
- var
- OldFocalLength: single;
- refsiz: single;
- BMP: TGLImage;
- x, y: integer;
- line: PGLPixel32Array;
- by: Integer;
- bp: Integer;
- DoBlur: Boolean;
- procedure ApplyBlur(const passes: integer);
- var
- t: integer;
- x, y: integer;
- lin, linu, lind, linuu, lindd: PGLPixel32Array;
- r, g, b: single;
- procedure ApplyBlurClampAndSetPixel;
- var
- ir, ig, ib: Smallint;
- begin
- // 0.1111 = 1/7 (where 7 is the times each pixel is summed with neighbours or self)
- ir := round(r * FAdvancedBlurAmp * 0.1111);
- ig := round(g * FAdvancedBlurAmp * 0.1111);
- ib := round(b * FAdvancedBlurAmp * 0.1111);
- // Hi Clamp
- if ir > FAdvancedBlurHiClamp then
- ir := FAdvancedBlurHiClamp;
- if ig > FAdvancedBlurHiClamp then
- ig := FAdvancedBlurHiClamp;
- if ib > FAdvancedBlurHiClamp then
- ib := FAdvancedBlurHiClamp;
- lin^[x].r := ir;
- lin^[x].g := ig;
- lin^[x].b := ib;
- end;
- begin
- for t := 0 to passes do
- begin
- for y := 2 to BMP.Height - 3 do
- begin
- linuu := BMP.ScanLine[y - 2];
- linu := BMP.ScanLine[y - 1];
- lin := BMP.ScanLine[y];
- lind := BMP.ScanLine[y + 1];
- lindd := BMP.ScanLine[y + 2];
- by := y * BMP.Height;
- // X = 0 PART:
- x := 0;
- r := lin^[x].r + lin^[x + 1].r + lin^[x + 2].r + linu^[x].r + lind^[x].r + linuu^[x].r + lindd^[x].r;
- g := lin^[x].g + lin^[x + 1].g + lin^[x + 2].g + linu^[x].g + lind^[x].g + linuu^[x].g + lindd^[x].g;
- b := lin^[x].b + lin^[x + 1].b + lin^[x + 2].b + linu^[x].b + lind^[x].b + linuu^[x].b + lindd^[x].b;
- ApplyBlurClampAndSetPixel;
- // X = 1 PART:
- x := 1;
- r := lin^[x].r + lin^[x + 1].r + lin^[x - 1].r + lin^[x + 2].r + linu^[x].r + lind^[x].r + linuu^[x].r + lindd^[x].r;
- g := lin^[x].g + lin^[x + 1].g + lin^[x - 1].g + lin^[x + 2].g + linu^[x].g + lind^[x].g + linuu^[x].g + lindd^[x].g;
- b := lin^[x].b + lin^[x + 1].b + lin^[x - 1].b + lin^[x + 2].b + linu^[x].b + lind^[x].b + linuu^[x].b + lindd^[x].b;
- ApplyBlurClampAndSetPixel;
- // ALL X IN MIDDLE PART:
- for x := 2 to BMP.Width - 3 do
- begin
- r := lin^[x].r + lin^[x + 1].r + lin^[x - 1].r + lin^[x + 2].r + lin^[x - 2].r + linu^[x].r + lind^[x].r + linuu^[x].r + lindd^[x].r;
- g := lin^[x].g + lin^[x + 1].g + lin^[x - 1].g + lin^[x + 2].g + lin^[x - 2].g + linu^[x].g + lind^[x].g + linuu^[x].g + lindd^[x].g;
- b := lin^[x].b + lin^[x + 1].b + lin^[x - 1].b + lin^[x + 2].b + lin^[x - 2].b + linu^[x].b + lind^[x].b + linuu^[x].b + lindd^[x].b;
- ApplyBlurClampAndSetPixel;
- end;
- //X = NEXT TO LAST PART:
- x := BMP.Width - 2;
- r := lin^[x].r + lin^[x + 1].r + lin^[x - 1].r + lin^[x - 2].r + linu^[x].r + lind^[x].r + linuu^[x].r + lindd^[x].r;
- g := lin^[x].g + lin^[x + 1].g + lin^[x - 1].g + lin^[x - 2].g + linu^[x].g + lind^[x].g + linuu^[x].g + lindd^[x].g;
- b := lin^[x].b + lin^[x + 1].b + lin^[x - 1].b + lin^[x - 2].b + linu^[x].b + lind^[x].b + linuu^[x].b + lindd^[x].b;
- ApplyBlurClampAndSetPixel;
- //X = LAST PART:
- x := BMP.Width - 1;
- r := lin^[x].r + lin^[x - 1].r + lin^[x - 2].r + linu^[x].r + lind^[x].r + linuu^[x].r + lindd^[x].r;
- g := lin^[x].g + lin^[x - 1].g + lin^[x - 2].g + linu^[x].g + lind^[x].g + linuu^[x].g + lindd^[x].g;
- b := lin^[x].b + lin^[x - 1].b + lin^[x - 2].b + linu^[x].b + lind^[x].b + linuu^[x].b + lindd^[x].b;
- ApplyBlurClampAndSetPixel;
- end;
- end;
- end;
- begin
- if FViewer.Camera <> Scene.CurrentGLCamera then
- FViewer.Camera := Scene.CurrentGLCamera;
- if FViewer.Camera <> nil then
- begin
- FDoingMemView := true;
- //Scene.RenderScene(FViewer.Buffer,FViewer.Width,FViewer.Height,dsRendering,baseObject);
- FViewer.Camera.BeginUpdate;
- OldFocalLength := FViewer.Camera.FocalLength;
- // CALCULATE SCALED FOCAL LENGTH FOR VIEWER
- if SCene.CurrentBuffer.Width > SCene.CurrentBuffer.height then
- refsiz := Scene.CurrentBuffer.Width
- else
- refsiz := Scene.CurrentBuffer.height;
- FViewer.Camera.FocalLength := FViewer.Camera.FocalLength * FViewer.Buffer.Width / refsiz;
- if FViewer.Buffer.BackgroundColor <> FRenderBackgroundColor then
- FViewer.Buffer.BackgroundColor := FRenderBackgroundColor;
- try
- case FBlur of
- bNone:
- begin
- // do nothing
- end;
- bSimple:
- begin
- if Assigned(FOnBeforeTargetRender) then
- FOnBeforeTargetRender(self);
- // RENDER
- FViewer.Render(baseObject);
- // Copy to texture (unfortunatelly, after this, the bitmap cannot be red back from the hardware.. i think)
- FViewer.CopyToTexture(Material.Texture);
- if Assigned(FOnAfterTargetRender) then
- FOnAfterTargetRender(self);
- end;
- bAdvanced:
- begin
- if Assigned(FOnBeforeTargetRender) then
- FOnBeforeTargetRender(self);
- // RENDER
- FViewer.Render(baseObject);
- // Read pixels from buffer. This is slow, but ok with reasonably small render size.
- FViewer.Buffer.RenderingContext.Activate;
- try
- gl.ReadPixels(0, 0, FViewer.Buffer.Width, FViewer.Buffer.Height, GL_RGB, GL_UNSIGNED_BYTE, Pixelbuffer);
- except
- FViewer.Buffer.RenderingContext.Deactivate;
- end;
- if Assigned(FOnAfterTargetRender) then
- FOnAfterTargetRender(self);
- BMP := Material.Texture.Image.GetBitmap32;
- BMP.Narrow;
- FViewer.Buffer.RenderingContext.Deactivate;
- // FILLS THE BITMAP with the pixelbuffer captured from the internal memoryViewer
- for y := 0 to RenderHeight - 1 do
- begin
- line := BMP.ScanLine[y];
- by := y * RenderHeight;
- for x := 0 to RenderWidth - 1 do
- begin
- bp := x + by;
- line^[x].r := Pixelbuffer[bp].R;
- line^[x].g := Pixelbuffer[bp].G;
- line^[x].b := Pixelbuffer[bp].B;
- // Low clamp
- if line^[x].r < FAdvancedBlurLowClamp then
- line^[x].r := 0;
- if line^[x].g < FAdvancedBlurLowClamp then
- line^[x].g := 0;
- if line^[x].b < FAdvancedBlurLowClamp then
- line^[x].b := 0;
- end;
- end;
- DoBlur := true;
- if Assigned(FOnAdvancedBlurImagePrepareEvent) then
- begin
- FOnAdvancedBlurImagePrepareEvent(self, BMP, DoBlur);
- end;
- if DoBlur then
- ApplyBlur(FAdvancedBlurPasses);
- Material.Texture.Image.NotifyChange(self);
- end;
- end;
- finally
- FViewer.Camera.FocalLength := OldFocalLength;
- FViewer.Camera.EndUpdate;
- FDoingMemView := false;
- end;
- end;
- end;
- {$WARNINGS Off} //Suppress "unsafe" warning
- procedure TGLBlur.DoRender(var ARci: TGLRenderContextInfo;
- ARenderSelf, ARenderChildren: Boolean);
- var
- vx, vy, vx1, vy1, f: Single;
- offsx, offsy: single;
- MaxMeasure: integer;
- begin
- if FDoingMemView and (FBlurSelf = false) then
- Exit;
- if (csDesigning in ComponentState) then
- begin
- if Count > 0 then
- Self.RenderChildren(0, Count - 1, ARci);
- exit;
- end;
- if ARci.ignoreMaterials then
- Exit;
- gl.CheckError;
- Material.Apply(ARci);
- gl.CheckError;
- repeat
- if AlphaChannel <> 1 then
- ARci.GLStates.SetGLMaterialAlphaChannel(GL_FRONT, AlphaChannel);
- // Prepare matrices
- gl.MatrixMode(GL_MODELVIEW);
- gl.PushMatrix;
- gl.LoadMatrixf(@TGLSceneBuffer(ARci.buffer).BaseProjectionMatrix);
- if ARci.renderDPI = 96 then
- f := 1
- else
- f := ARci.renderDPI / 96;
- gl.Scalef(2 / ARci.viewPortSize.cx, 2 / ARci.viewPortSize.cy, 1);
- // center of viewport:
- gl.Translatef(0, 0, Position.Z);
- if Rotation <> 0 then
- gl.Rotatef(Rotation, 0, 0, 1);
- gl.MatrixMode(GL_PROJECTION);
- gl.PushMatrix;
- gl.LoadIdentity;
- ARci.GLStates.Disable(stDepthTest);
- ARci.GLStates.DepthWriteMask := False;
- // calculate offsets in order to keep the quad a square centered in the view
- if ARci.viewPortSize.cx > ARci.viewPortSize.cy then
- begin
- offsx := 0;
- offsy := (ARci.viewPortSize.cx - ARci.viewPortSize.cy) * 0.5;
- MaxMeasure := ARci.viewPortSize.cx;
- end
- else
- begin
- offsx := (ARci.viewPortSize.cy - ARci.viewPortSize.cx) * 0.5;
- offsy := 0;
- MaxMeasure := ARci.viewPortSize.cy;
- end;
- // precalc coordinates
- vx := -ARci.viewPortSize.cx * 0.5 * f;
- vx1 := vx + ARci.viewPortSize.cx * f;
- vy := +ARci.viewPortSize.cy * 0.5 * f;
- vy1 := vy - ARci.viewPortSize.cy * f;
- vx := vx - offsx;
- vx1 := vx1 + offsx;
- vy := vy + offsy;
- vy1 := vy1 - offsy;
- // Cause the radial scaling
- if FDoingMemView then
- begin
- vx := vx - FBlurLeft * MaxMeasure;
- vx1 := vx1 + FBlurRight * MaxMeasure;
- vy := vy + FBlurTop * MaxMeasure;
- vy1 := vy1 - FBlurBottom * MaxMeasure;
- end;
- // issue quad
- gl.Begin_(GL_QUADS);
- gl.Normal3fv(@YVector);
- gl.TexCoord2f(0, 0);
- gl.Vertex2f(vx, vy1);
- gl.TexCoord2f(XTiles, 0);
- gl.Vertex2f(vx1, vy1);
- gl.TexCoord2f(XTiles, YTiles);
- gl.Vertex2f(vx1, vy);
- gl.TexCoord2f(0, YTiles);
- gl.Vertex2f(vx, vy);
- gl.End_;
- // restore state
- gl.PopMatrix;
- gl.MatrixMode(GL_MODELVIEW);
- gl.PopMatrix;
- until not Material.UnApply(ARci);
- if Count > 0 then
- Self.RenderChildren(0, Count - 1, ARci);
- end;
- procedure TGLBlur.Notification(AComponent: TComponent; Operation: TOperation);
- begin
- inherited;
- if Operation = opRemove then
- if AComponent = FTargetObject then
- FTargetObject := nil;
- inherited;
- end;
- {$WARNINGS On}
- procedure TGLBlur.SetRenderBackgroundColor(const Value: TColor);
- begin
- FRenderBackgroundColor := Value;
- end;
- procedure TGLBlur.SetRenderHeight(const Value: integer);
- begin
- FRenderHeight := Value;
- UpdateImageSettings;
- end;
- procedure TGLBlur.SetRenderWidth(const Value: integer);
- begin
- FRenderWidth := Value;
- UpdateImageSettings;
- end;
- procedure TGLBlur.SetTargetObject(const Value: TGLbaseSceneObject);
- begin
- FTargetObject := Value;
- end;
- procedure TGLBlur.SetAdvancedBlurAmp(const Value: single);
- begin
- FAdvancedBlurAmp := Value;
- end;
- procedure TGLBlur.SetAdvancedBlurHiClamp(const Value: byte);
- begin
- FAdvancedBlurHiClamp := Value;
- end;
- procedure TGLBlur.SetAdvancedBlurLowClamp(const Value: byte);
- begin
- FAdvancedBlurLowClamp := Value;
- end;
- procedure TGLBlur.SetAdvancedBlurPasses(const Value: integer);
- begin
- FAdvancedBlurPasses := Value;
- end;
- procedure TGLBlur.SetBlur(const Value: TGLBlurKind);
- begin
- if FBlur <> Value then
- begin
- case Value of
- bnone:
- begin
- // do Nothing
- end;
- bSimple:
- begin
- Material.Texture.ImageClassName := TGLBlankImage.ClassName;
- end;
- bAdvanced:
- begin
- Material.Texture.ImageClassName := TGLPersistentImage.ClassName;
- end;
- end;
- UpdateImageSettings;
- end;
- FBlur := Value;
- end;
- procedure TGLBlur.SetBlurSelf(const Value: boolean);
- begin
- FBlurSelf := Value;
- end;
- procedure TGLBlur.SetOnAdvancedBlurImagePrepareEvent(const Value: TGLAdvancedBlurImagePrepareEvent);
- begin
- FOnAdvancedBlurImagePrepareEvent := Value;
- end;
- procedure TGLBlur.SetOnAfterTargetRender(const Value: TNotifyEvent);
- begin
- FOnAfterTargetRender := Value;
- end;
- procedure TGLBlur.SetOnBeforeTargetRender(const Value: TNotifyEvent);
- begin
- FOnBeforeTargetRender := Value;
- end;
- procedure TGLBlur.SetPreset(const Value: TGLBlurPreset);
- begin
- FPreset := Value;
- case FPreset of
- pNone:
- begin
- // do nothing
- end;
- pAdvancedBlur:
- begin
- Blur := bAdvanced;
- Material.BlendingMode := bmAdditive;
- Material.FrontProperties.Diffuse.SetColor(1, 1, 1, 1);
- BlurTop := 0;
- BlurLeft := 0;
- BlurRight := 0;
- BlurBottom := 0;
- BlurDeltaTime := 0;
- BlurSelf := false;
- AdvancedBlurPasses := 1;
- AdvancedBlurAmp := 1.2;
- RenderWidth := 64;
- RenderHeight := 64;
- end;
- pGlossy:
- begin
- Material.BlendingMode := bmAdditive;
- Material.FrontProperties.Diffuse.SetColor(1, 1, 1, 0.7);
- BlurTop := 0.02;
- BlurLeft := 0.02;
- BlurRight := 0.02;
- BlurBottom := 0.02;
- BlurDeltaTime := 0.02;
- BlurSelf := true;
- end;
- pBeastView:
- begin
- Blur := bSimple;
- Material.BlendingMode := bmAdditive;
- Material.FrontProperties.Diffuse.SetColor(1, 0, 0, 0.8);
- BlurTop := 0.001;
- BlurLeft := 0.03;
- BlurRight := 0.03;
- BlurBottom := 0.001;
- BlurDeltaTime := 0.02;
- BlurSelf := true;
- end;
- pOceanDepth:
- begin
- Blur := bSimple;
- Material.BlendingMode := bmTransparency;
- Material.FrontProperties.Diffuse.SetColor(0.2, 0.2, 1, 0.99);
- BlurTop := 0.04;
- BlurLeft := 0.02;
- BlurRight := 0.02;
- BlurBottom := 0.04;
- BlurDeltaTime := 0.02;
- BlurSelf := true;
- end;
- pDream:
- begin
- Blur := bSimple;
- Material.BlendingMode := bmTransparency;
- Material.FrontProperties.Diffuse.SetColor(1, 1, 1, 0.992);
- BlurTop := 0.02;
- BlurLeft := 0.02;
- BlurRight := 0.02;
- BlurBottom := 0.02;
- BlurDeltaTime := 0.1;
- BlurSelf := true;
- end;
- pOverBlur:
- begin
- Blur := bSimple;
- Material.BlendingMode := bmAdditive;
- Material.FrontProperties.Diffuse.SetColor(0.95, 0.95, 0.95, 0.98);
- BlurTop := 0.01;
- BlurLeft := 0.01;
- BlurRight := 0.01;
- BlurBottom := 0.01;
- BlurDeltaTime := 0.02;
- BlurSelf := true;
- end;
- end;
- end;
- function TGLBlur.StoreBlurBottom: Boolean;
- begin
- Result := Abs(FBlurBottom - 0.01) > EPS;
- end;
- function TGLBlur.StoreBlurDeltaTime: Boolean;
- begin
- Result := Abs(FBlurDeltaTime - 0.02) > EPS;
- end;
- function TGLBlur.StoreBlurLeft: Boolean;
- begin
- Result := Abs(FBlurLeft - 0.01) > EPS;
- end;
- function TGLBlur.StoreBlurRight: Boolean;
- begin
- Result := Abs(FBlurRight - 0.01) > EPS;
- end;
- function TGLBlur.StoreBlurTop: Boolean;
- begin
- Result := Abs(FBlurTop - 0.01) > EPS;
- end;
- //-------------------------------------------------
- { TGLMotionBlur }
- //-------------------------------------------------
- procedure TGLMotionBlur.Assign(Source: TPersistent);
- begin
- inherited;
- if Source is TGLMotionBlur then
- begin
- FIntensity := TGLMotionBlur(Source).FIntensity;
- end;
- end;
- constructor TGLMotionBlur.Create(aOwner: TComponent);
- begin
- inherited Create(aOwner);
- Material.FrontProperties.Diffuse.Initialize(clrBlack);
- Material.MaterialOptions := [moNoLighting, moIgnoreFog];
- Material.Texture.Disabled := False;
- Material.BlendingMode := bmTransparency;
- FIntensity := 0.975;
- end;
- procedure TGLMotionBlur.DoOnAddedToParent;
- begin
- inherited;
- // Request to be initialized on next render.
- if Scene <> nil then
- Scene.InitializableObjects.Add(Self);
- end;
- procedure TGLMotionBlur.DoRender(var ARci: TGLRenderContextInfo; ARenderSelf, ARenderChildren: Boolean);
- begin
- if not (ARci.ignoreMaterials or (csDesigning in ComponentState) or
- (ARci.drawState = dsPicking)) then
- with ARci.GLStates do
- begin
- ARci.ignoreDepthRequests := True;
- Material.Apply(ARci);
- ActiveTextureEnabled[ttTextureRect] := True;
- gl.MatrixMode(GL_PROJECTION);
- gl.PushMatrix;
- gl.LoadIdentity;
- gl.Ortho(0, ARci.viewPortSize.cx, ARci.viewPortSize.cy, 0, 0, 1);
- gl.MatrixMode(GL_MODELVIEW);
- gl.PushMatrix;
- gl.LoadIdentity;
- Disable(stDepthTest);
- DepthWriteMask := False;
- gl.Begin_(GL_QUADS);
- gl.TexCoord2f(0.0, ARci.viewPortSize.cy);
- gl.Vertex2f(0, 0);
- gl.TexCoord2f(0.0, 0.0);
- gl.Vertex2f(0, ARci.viewPortSize.cy);
- gl.TexCoord2f(ARci.viewPortSize.cx, 0.0);
- gl.Vertex2f(ARci.viewPortSize.cx, ARci.viewPortSize.cy);
- gl.TexCoord2f(ARci.viewPortSize.cx, ARci.viewPortSize.cy);
- gl.Vertex2f(ARci.viewPortSize.cx, 0);
- gl.End_;
- gl.PopMatrix;
- gl.MatrixMode(GL_PROJECTION);
- gl.PopMatrix;
- gl.MatrixMode(GL_MODELVIEW);
- ActiveTextureEnabled[ttTextureRect] := False;
- Material.UnApply(ARci);
- ARci.ignoreDepthRequests := False;
- gl.CopyTexImage2D(GL_TEXTURE_RECTANGLE, 0, GL_RGB, 0, 0, ARci.viewPortSize.cx, ARci.viewPortSize.cy, 0);
- Material.FrontProperties.Diffuse.Alpha := FIntensity;
- end;
- if Count <> 0 then
- Self.RenderChildren(0, Count - 1, ARci);
- end;
- procedure TGLMotionBlur.InitializeObject(ASender: TObject;
- const ARci: TGLRenderContextInfo);
- begin
- // If extension is not supported, silently disable this component.
- if not (csDesigning in ComponentState) then
- if not SupportsRequiredExtensions then
- Visible := False;
- end;
- function TGLMotionBlur.StoreIntensity: Boolean;
- begin
- Result := Abs(FIntensity - 0.975) > EPS;
- end;
- function TGLMotionBlur.SupportsRequiredExtensions: Boolean;
- begin
- Result :=
- gl.ARB_texture_rectangle or gl.EXT_texture_rectangle or gl.NV_texture_rectangle;
- end;
- // ------------------------------------------------------------------
- initialization
- // ------------------------------------------------------------------
- RegisterClass(TGLBlur);
- RegisterClass(TGLMotionBlur);
- end.
|