2
// This unit is part of the GLScene Engine https://github.com/glscene
5
Applies a blur effect over the viewport.
14
Classes, SysUtils, Graphics,
16
GLScene, GLVectorGeometry, GLObjects, GLBitmapFont, GLTexture, GLMaterial,
17
GLHudObjects, GLColor, GLGraphics, GLContext, OpenGLTokens,
18
XOpenGL, GLState, GLTextureFormat, GLBaseClasses, GLRenderContextInfo;
22
TGLBlurPreset = (pNone, pGlossy, pBeastView, pOceanDepth, pDream, pOverBlur, pAdvancedBlur);
23
TGLBlurkind = (bNone, bSimple, bAdvanced);
27
TRGBPixelBuffer = array of TRGBPixel;
28
TGLAdvancedBlurImagePrepareEvent = procedure(Sender: TObject; BMP32: TGLBitmap32; var DoBlur: boolean) of object;
30
EGLMotionBlurException = class(Exception);
32
TGLBlur = class(TGLHUDSprite)
34
FViewer: TGLMemoryViewer;
36
FDoingMemView: boolean;
37
FBlurDeltaTime: Double;
42
FRenderHeight: Integer;
43
FRenderWidth: Integer;
44
FPreset: TGLBlurPreset;
45
FTargetObject: TGLbaseSceneObject;
46
FOnAdvancedBlurImagePrepareEvent: TGLAdvancedBlurImagePrepareEvent;
48
Pixelbuffer: TRGBPixelBuffer;
49
FAdvancedBlurPasses: integer;
50
FOnAfterTargetRender: TNotifyEvent;
51
FOnBeforeTargetRender: TNotifyEvent;
52
FAdvancedBlurAmp: single;
54
FAdvancedBlurLowClamp: byte;
55
FAdvancedBlurHiClamp: byte;
56
FRenderBackgroundColor: TColor;
57
procedure DoMemView(baseObject: TGLBaseSceneObject);
58
procedure SetRenderHeight(const Value: Integer);
59
procedure SetRenderWidth(const Value: Integer);
60
procedure UpdateImageSettings;
61
procedure SetPreset(const Value: TGLBlurPreset);
63
function StoreBlurBottom: Boolean;
64
function StoreBlurDeltaTime: Boolean;
65
function StoreBlurRight: Boolean;
66
function StoreBlurTop: Boolean;
67
function StoreBlurLeft: Boolean;
68
procedure SetTargetObject(const Value: TGLbaseSceneObject);
69
procedure SetOnAdvancedBlurImagePrepareEvent(const Value: TGLAdvancedBlurImagePrepareEvent);
70
procedure SetBlur(const Value: TGLBlurKind);
71
procedure SetAdvancedBlurPasses(const Value: integer);
72
procedure SetOnAfterTargetRender(const Value: TNotifyEvent);
73
procedure SetOnBeforeTargetRender(const Value: TNotifyEvent);
74
procedure SetAdvancedBlurAmp(const Value: single);
75
procedure SetBlurSelf(const Value: boolean);
76
procedure SetAdvancedBlurLowClamp(const Value: byte);
77
procedure SetAdvancedBlurHiClamp(const Value: byte);
78
procedure SetRenderBackgroundColor(const Value: TColor);
80
constructor Create(AOwner: TComponent); override;
81
destructor Destroy; override;
83
procedure DoProgress(const progressTime: TProgressTimes); override;
84
procedure DoRender(var ARci: TGLRenderContextInfo;
85
ARenderSelf, ARenderChildren: Boolean); override;
86
procedure Notification(AComponent: TComponent; Operation: TOperation); override;
88
property Blur: TGLBlurKind read FBlur write SetBlur;
89
property BlurDeltaTime: Double read FBlurDeltaTime write FBlurDeltaTime stored StoreBlurDeltaTime;
90
property BlurLeft: Single read FBlurLeft write FBlurLeft stored StoreBlurLeft;
91
property BlurTop: Single read FBlurTop write FBlurTop stored StoreBlurTop;
92
property BlurRight: Single read FBlurRight write FBlurRight stored StoreBlurRight;
93
property BlurBottom: Single read FBlurBottom write FBlurBottom stored StoreBlurBottom;
94
property RenderWidth: Integer read FRenderWidth write SetRenderWidth default 256;
95
property RenderHeight: Integer read FRenderHeight write SetRenderHeight default 256;
96
property Preset: TGLBlurPreset read FPreset write SetPreset stored false;
97
property TargetObject: TGLbaseSceneObject read FTargetObject write SetTargetObject;
98
property AdvancedBlurPasses: integer read FAdvancedBlurPasses write SetAdvancedBlurPasses;
99
property AdvancedBlurAmp: single read FAdvancedBlurAmp write SetAdvancedBlurAmp;
100
property AdvancedBlurLowClamp: byte read FAdvancedBlurLowClamp write SetAdvancedBlurLowClamp;
101
property AdvancedBlurHiClamp: byte read FAdvancedBlurHiClamp write SetAdvancedBlurHiClamp;
102
property BlurSelf: boolean read FBlurSelf write SetBlurSelf;
103
property RenderBackgroundColor: TColor read FRenderBackgroundColor write SetRenderBackgroundColor;
104
property OnAdvancedBlurImagePrepareEvent: TGLAdvancedBlurImagePrepareEvent read FOnAdvancedBlurImagePrepareEvent write SetOnAdvancedBlurImagePrepareEvent;
105
property OnBeforeTargetRender: TNotifyEvent read FOnBeforeTargetRender write SetOnBeforeTargetRender;
106
property OnAfterTargetRender: TNotifyEvent read FOnAfterTargetRender write SetOnAfterTargetRender;
110
This component blurs everything thatis rendered BEFORE it. So if you want part
111
of your scene blured, the other not blured, make sure that the other part is
112
rendered after this component. It is fast and does not require shaders.
114
Note: it is FPS-dependant. Also also can produce a "blury trail effect", which
115
stays on the screen until something new is rendered over it. It can be overcome
116
by changing the Material.FrontProperties.Diffuse property. This, however, also
117
has a drawback - the picture becomes more blured altogether. For example, if
118
your backgroud color is Black, set the Material.FrontProperties.Diffuse to White.
119
If it is White, set Material.FrontProperties.Diffuse to Black. I haven't tried
120
any others, but I hope you get the idea ;)
122
I've seen this effect in different Bruring components, even in shaders, but if
123
anyone knows another way to fix this issue - please post it on the glscene
126
TGLMotionBlur = class(TGLCustomSceneObject, IGLInitializable)
129
function StoreIntensity: Boolean;
131
procedure DoOnAddedToParent; override;
132
procedure InitializeObject(ASender: TObject; const ARci: TGLRenderContextInfo); virtual;
134
{ This function is only valid AFTER OpenGL has been initialized. }
135
function SupportsRequiredExtensions: Boolean;
136
procedure DoRender(var ARci: TGLRenderContextInfo; ARenderSelf, ARenderChildren: Boolean); override;
137
constructor Create(aOwner: TComponent); override;
138
procedure Assign(Source: TPersistent); override;
140
// The more the intensity, the more blur you have.
141
property Intensity: Single read FIntensity write FIntensity stored StoreIntensity;
143
// From TGLBaseSceneObject.
156
constructor TGLBlur.Create(AOwner: TComponent);
159
FBlurDeltaTime := 0.02;
164
FRenderHeight := 256;
166
FViewer := TGLMemoryViewer.Create(Self);
168
Material.Texture.Disabled := False;
169
FAdvancedBlurPasses := 1;
170
FAdvancedBlurAmp := 1.1;
172
FAdvancedBlurLowClamp := 0;
173
FAdvancedBlurHiClamp := 255;
174
FRenderBackgroundColor := ClBlack;
177
destructor TGLBlur.Destroy;
183
procedure TGLBlur.UpdateImageSettings;
187
if Material.Texture.Image is TGLBlankImage then
188
with TGLBlankImage(Material.Texture.Image) do
190
Width := RenderWidth;
191
Height := Renderheight;
193
else if Material.Texture.Image is TGLPersistentImage then
195
B := TGLPersistentImage(Material.Texture.Image).Picture.Bitmap;
198
B.Width := RenderWidth;
199
B.Height := RenderHeight;
204
Width := RenderWidth;
205
Height := Renderheight;
208
SetLength(Pixelbuffer, RenderWidth * RenderHeight);
211
procedure TGLBlur.DoProgress(const progressTime: TProgressTimes);
214
if self.Visible and (progressTime.newTime - OldTime > FBlurDeltaTime) then
216
OldTime := progressTime.newTime;
217
if TargetObject <> nil then
218
DoMemView(TargetObject);
223
procedure TGLBlur.DoMemView(baseObject: TGLBaseSceneObject);
225
OldFocalLength: single;
229
line: PGLPixel32Array;
234
procedure ApplyBlur(const passes: integer);
238
lin, linu, lind, linuu, lindd: PGLPixel32Array;
240
ir, ig, ib: Smallint;
242
procedure ApplyBlurClampAndSetPixel;
244
// 0.1111 = 1/7 (where 7 is the times each pixel is summed with neighbours or self)
245
ir := round(r * FAdvancedBlurAmp * 0.1111);
246
ig := round(g * FAdvancedBlurAmp * 0.1111);
247
ib := round(b * FAdvancedBlurAmp * 0.1111);
250
if ir > FAdvancedBlurHiClamp then
251
ir := FAdvancedBlurHiClamp;
252
if ig > FAdvancedBlurHiClamp then
253
ig := FAdvancedBlurHiClamp;
254
if ib > FAdvancedBlurHiClamp then
255
ib := FAdvancedBlurHiClamp;
264
for t := 0 to passes do
266
for y := 2 to BMP.Height - 3 do
268
linuu := BMP.ScanLine[y - 2];
269
linu := BMP.ScanLine[y - 1];
270
lin := BMP.ScanLine[y];
271
lind := BMP.ScanLine[y + 1];
272
lindd := BMP.ScanLine[y + 2];
273
by := y * BMP.Height;
276
r := lin^[x].r + lin^[x + 1].r + lin^[x + 2].r + linu^[x].r + lind^[x].r + linuu^[x].r + lindd^[x].r;
277
g := lin^[x].g + lin^[x + 1].g + lin^[x + 2].g + linu^[x].g + lind^[x].g + linuu^[x].g + lindd^[x].g;
278
b := lin^[x].b + lin^[x + 1].b + lin^[x + 2].b + linu^[x].b + lind^[x].b + linuu^[x].b + lindd^[x].b;
279
ApplyBlurClampAndSetPixel;
282
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;
283
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;
284
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;
285
ApplyBlurClampAndSetPixel;
286
// ALL X IN MIDDLE PART:
287
for x := 2 to BMP.Width - 3 do
289
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;
290
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;
291
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;
292
ApplyBlurClampAndSetPixel;
294
//X = NEXT TO LAST PART:
296
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;
297
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;
298
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;
299
ApplyBlurClampAndSetPixel;
302
r := lin^[x].r + lin^[x - 1].r + lin^[x - 2].r + linu^[x].r + lind^[x].r + linuu^[x].r + lindd^[x].r;
303
g := lin^[x].g + lin^[x - 1].g + lin^[x - 2].g + linu^[x].g + lind^[x].g + linuu^[x].g + lindd^[x].g;
304
b := lin^[x].b + lin^[x - 1].b + lin^[x - 2].b + linu^[x].b + lind^[x].b + linuu^[x].b + lindd^[x].b;
305
ApplyBlurClampAndSetPixel;
311
if FViewer.Camera <> Scene.CurrentGLCamera then
312
FViewer.Camera := Scene.CurrentGLCamera;
314
if FViewer.Camera <> nil then
316
FDoingMemView := true;
318
//Scene.RenderScene(FViewer.Buffer,FViewer.Width,FViewer.Height,dsRendering,baseObject);
319
FViewer.Camera.BeginUpdate;
321
OldFocalLength := FViewer.Camera.FocalLength;
323
// CALCULATE SCALED FOCAL LENGTH FOR VIEWER
324
if SCene.CurrentBuffer.Width > SCene.CurrentBuffer.height then
325
refsiz := Scene.CurrentBuffer.Width
327
refsiz := Scene.CurrentBuffer.height;
329
FViewer.Camera.FocalLength := FViewer.Camera.FocalLength * FViewer.Buffer.Width / refsiz;
331
if FViewer.Buffer.BackgroundColor <> FRenderBackgroundColor then
332
FViewer.Buffer.BackgroundColor := FRenderBackgroundColor;
342
if Assigned(FOnBeforeTargetRender) then
343
FOnBeforeTargetRender(self);
345
FViewer.Render(baseObject);
346
// Copy to texture (unfortunatelly, after this, the bitmap cannot be red back from the hardware.. i think)
347
FViewer.CopyToTexture(Material.Texture);
348
if Assigned(FOnAfterTargetRender) then
349
FOnAfterTargetRender(self);
353
if Assigned(FOnBeforeTargetRender) then
354
FOnBeforeTargetRender(self);
357
FViewer.Render(baseObject);
358
// Read pixels from buffer. This is slow, but ok with reasonably small render size.
359
FViewer.Buffer.RenderingContext.Activate;
361
GL.ReadPixels(0, 0, FViewer.Buffer.Width, FViewer.Buffer.Height, GL_RGB, GL_UNSIGNED_BYTE, Pixelbuffer);
363
FViewer.Buffer.RenderingContext.Deactivate;
365
if Assigned(FOnAfterTargetRender) then
366
FOnAfterTargetRender(self);
368
BMP := Material.Texture.Image.GetBitmap32;
370
FViewer.Buffer.RenderingContext.Deactivate;
371
// FILLS THE BITMAP with the pixelbuffer captured from the internal memoryViewer
372
for y := 0 to RenderHeight - 1 do
374
line := BMP.ScanLine[y];
375
by := y * RenderHeight;
376
for x := 0 to RenderWidth - 1 do
379
line^[x].r := Pixelbuffer[bp].R;
380
line^[x].g := Pixelbuffer[bp].G;
381
line^[x].b := Pixelbuffer[bp].B;
384
if line^[x].r < FAdvancedBlurLowClamp then
386
if line^[x].g < FAdvancedBlurLowClamp then
388
if line^[x].b < FAdvancedBlurLowClamp then
394
if Assigned(FOnAdvancedBlurImagePrepareEvent) then
396
FOnAdvancedBlurImagePrepareEvent(self, BMP, DoBlur);
400
ApplyBlur(FAdvancedBlurPasses);
402
Material.Texture.Image.NotifyChange(self);
407
FViewer.Camera.FocalLength := OldFocalLength;
408
FViewer.Camera.EndUpdate;
409
FDoingMemView := false;
414
{$WARNINGS Off} //Suppress "unsafe" warning
416
procedure TGLBlur.DoRender(var ARci: TGLRenderContextInfo;
417
ARenderSelf, ARenderChildren: Boolean);
419
vx, vy, vx1, vy1, f: Single;
420
offsx, offsy: single;
423
if FDoingMemView and (FBlurSelf = false) then
425
if (csDesigning in ComponentState) then
428
Self.RenderChildren(0, Count - 1, ARci);
431
if ARci.ignoreMaterials then
434
Material.Apply(ARci);
437
if AlphaChannel <> 1 then
438
ARci.GLStates.SetGLMaterialAlphaChannel(GL_FRONT, AlphaChannel);
440
GL.MatrixMode(GL_MODELVIEW);
442
GL.LoadMatrixf(@TGLSceneBuffer(ARci.buffer).BaseProjectionMatrix);
443
if ARci.renderDPI = 96 then
446
f := ARci.renderDPI / 96;
447
GL.Scalef(2 / ARci.viewPortSize.cx, 2 / ARci.viewPortSize.cy, 1);
449
// center of viewport:
450
GL.Translatef(0, 0, Position.Z);
452
if Rotation <> 0 then
453
GL.Rotatef(Rotation, 0, 0, 1);
454
GL.MatrixMode(GL_PROJECTION);
457
ARci.GLStates.Disable(stDepthTest);
458
ARci.GLStates.DepthWriteMask := False;
460
// calculate offsets in order to keep the quad a square centered in the view
461
if ARci.viewPortSize.cx > ARci.viewPortSize.cy then
464
offsy := (ARci.viewPortSize.cx - ARci.viewPortSize.cy) * 0.5;
465
MaxMeasure := ARci.viewPortSize.cx;
469
offsx := (ARci.viewPortSize.cy - ARci.viewPortSize.cx) * 0.5;
471
MaxMeasure := ARci.viewPortSize.cy;
474
// precalc coordinates
475
vx := -ARci.viewPortSize.cx * 0.5 * f;
476
vx1 := vx + ARci.viewPortSize.cx * f;
477
vy := +ARci.viewPortSize.cy * 0.5 * f;
478
vy1 := vy - ARci.viewPortSize.cy * f;
485
// Cause the radial scaling
486
if FDoingMemView then
488
vx := vx - FBlurLeft * MaxMeasure;
489
vx1 := vx1 + FBlurRight * MaxMeasure;
490
vy := vy + FBlurTop * MaxMeasure;
491
vy1 := vy1 - FBlurBottom * MaxMeasure;
496
GL.Normal3fv(@YVector);
498
GL.Vertex2f(vx, vy1);
499
GL.TexCoord2f(XTiles, 0);
500
GL.Vertex2f(vx1, vy1);
501
GL.TexCoord2f(XTiles, YTiles);
502
GL.Vertex2f(vx1, vy);
503
GL.TexCoord2f(0, YTiles);
508
GL.MatrixMode(GL_MODELVIEW);
510
until not Material.UnApply(ARci);
512
Self.RenderChildren(0, Count - 1, ARci);
515
procedure TGLBlur.Notification(AComponent: TComponent; Operation: TOperation);
518
if Operation = opRemove then
519
if AComponent = FTargetObject then
520
FTargetObject := nil;
526
procedure TGLBlur.SetRenderBackgroundColor(const Value: TColor);
528
FRenderBackgroundColor := Value;
531
procedure TGLBlur.SetRenderHeight(const Value: integer);
533
FRenderHeight := Value;
537
procedure TGLBlur.SetRenderWidth(const Value: integer);
539
FRenderWidth := Value;
543
procedure TGLBlur.SetTargetObject(const Value: TGLbaseSceneObject);
545
FTargetObject := Value;
548
procedure TGLBlur.SetAdvancedBlurAmp(const Value: single);
550
FAdvancedBlurAmp := Value;
553
procedure TGLBlur.SetAdvancedBlurHiClamp(const Value: byte);
555
FAdvancedBlurHiClamp := Value;
558
procedure TGLBlur.SetAdvancedBlurLowClamp(const Value: byte);
560
FAdvancedBlurLowClamp := Value;
563
procedure TGLBlur.SetAdvancedBlurPasses(const Value: integer);
565
FAdvancedBlurPasses := Value;
568
procedure TGLBlur.SetBlur(const Value: TGLBlurKind);
570
if FBlur <> Value then
579
Material.Texture.ImageClassName := TGLBlankImage.ClassName;
583
Material.Texture.ImageClassName := TGLPersistentImage.ClassName;
591
procedure TGLBlur.SetBlurSelf(const Value: boolean);
596
procedure TGLBlur.SetOnAdvancedBlurImagePrepareEvent(const Value: TGLAdvancedBlurImagePrepareEvent);
598
FOnAdvancedBlurImagePrepareEvent := Value;
601
procedure TGLBlur.SetOnAfterTargetRender(const Value: TNotifyEvent);
603
FOnAfterTargetRender := Value;
606
procedure TGLBlur.SetOnBeforeTargetRender(const Value: TNotifyEvent);
608
FOnBeforeTargetRender := Value;
611
procedure TGLBlur.SetPreset(const Value: TGLBlurPreset);
623
Material.BlendingMode := bmAdditive;
624
Material.FrontProperties.Diffuse.SetColor(1, 1, 1, 1);
631
AdvancedBlurPasses := 1;
632
AdvancedBlurAmp := 1.2;
638
Material.BlendingMode := bmAdditive;
639
Material.FrontProperties.Diffuse.SetColor(1, 1, 1, 0.7);
644
BlurDeltaTime := 0.02;
650
Material.BlendingMode := bmAdditive;
651
Material.FrontProperties.Diffuse.SetColor(1, 0, 0, 0.8);
656
BlurDeltaTime := 0.02;
662
Material.BlendingMode := bmTransparency;
663
Material.FrontProperties.Diffuse.SetColor(0.2, 0.2, 1, 0.99);
668
BlurDeltaTime := 0.02;
674
Material.BlendingMode := bmTransparency;
675
Material.FrontProperties.Diffuse.SetColor(1, 1, 1, 0.992);
680
BlurDeltaTime := 0.1;
686
Material.BlendingMode := bmAdditive;
687
Material.FrontProperties.Diffuse.SetColor(0.95, 0.95, 0.95, 0.98);
692
BlurDeltaTime := 0.02;
699
function TGLBlur.StoreBlurBottom: Boolean;
701
Result := Abs(FBlurBottom - 0.01) > EPS;
704
function TGLBlur.StoreBlurDeltaTime: Boolean;
706
Result := Abs(FBlurDeltaTime - 0.02) > EPS;
709
function TGLBlur.StoreBlurLeft: Boolean;
711
Result := Abs(FBlurLeft - 0.01) > EPS;
714
function TGLBlur.StoreBlurRight: Boolean;
716
Result := Abs(FBlurRight - 0.01) > EPS;
719
function TGLBlur.StoreBlurTop: Boolean;
721
Result := Abs(FBlurTop - 0.01) > EPS;
726
procedure TGLMotionBlur.Assign(Source: TPersistent);
729
if Source is TGLMotionBlur then
731
FIntensity := TGLMotionBlur(Source).FIntensity;
735
constructor TGLMotionBlur.Create(aOwner: TComponent);
737
inherited Create(aOwner);
738
Material.FrontProperties.Diffuse.Initialize(clrBlack);
739
Material.MaterialOptions := [moNoLighting, moIgnoreFog];
740
Material.Texture.Disabled := False;
741
Material.BlendingMode := bmTransparency;
745
procedure TGLMotionBlur.DoOnAddedToParent;
748
// Request to be initialized on next render.
750
Scene.InitializableObjects.Add(Self);
753
procedure TGLMotionBlur.DoRender(var ARci: TGLRenderContextInfo; ARenderSelf, ARenderChildren: Boolean);
755
if not (ARci.ignoreMaterials or (csDesigning in ComponentState) or
756
(ARci.drawState = dsPicking)) then
757
with ARci.GLStates do
759
ARci.ignoreDepthRequests := True;
760
Material.Apply(ARci);
761
ActiveTextureEnabled[ttTextureRect] := True;
762
GL.MatrixMode(GL_PROJECTION);
765
GL.Ortho(0, ARci.viewPortSize.cx, ARci.viewPortSize.cy, 0, 0, 1);
766
GL.MatrixMode(GL_MODELVIEW);
769
Disable(stDepthTest);
770
DepthWriteMask := False;
773
GL.TexCoord2f(0.0, ARci.viewPortSize.cy);
775
GL.TexCoord2f(0.0, 0.0);
776
GL.Vertex2f(0, ARci.viewPortSize.cy);
777
GL.TexCoord2f(ARci.viewPortSize.cx, 0.0);
778
GL.Vertex2f(ARci.viewPortSize.cx, ARci.viewPortSize.cy);
779
GL.TexCoord2f(ARci.viewPortSize.cx, ARci.viewPortSize.cy);
780
GL.Vertex2f(ARci.viewPortSize.cx, 0);
784
GL.MatrixMode(GL_PROJECTION);
786
GL.MatrixMode(GL_MODELVIEW);
787
ActiveTextureEnabled[ttTextureRect] := False;
788
Material.UnApply(ARci);
789
ARci.ignoreDepthRequests := False;
791
GL.CopyTexImage2D(GL_TEXTURE_RECTANGLE, 0, GL_RGB, 0, 0, ARci.viewPortSize.cx, ARci.viewPortSize.cy, 0);
793
Material.FrontProperties.Diffuse.Alpha := FIntensity;
797
Self.RenderChildren(0, Count - 1, ARci);
800
procedure TGLMotionBlur.InitializeObject(ASender: TObject;
801
const ARci: TGLRenderContextInfo);
803
// If extension is not supported, silently disable this component.
804
if not (csDesigning in ComponentState) then
805
if not SupportsRequiredExtensions then
809
function TGLMotionBlur.StoreIntensity: Boolean;
811
Result := Abs(FIntensity - 0.975) > EPS;
814
function TGLMotionBlur.SupportsRequiredExtensions: Boolean;
817
GL.ARB_texture_rectangle or GL.EXT_texture_rectangle or GL.NV_texture_rectangle;
820
// ------------------------------------------------------------------
821
// ------------------------------------------------------------------
822
// ------------------------------------------------------------------
824
// ------------------------------------------------------------------
825
// ------------------------------------------------------------------
826
// ------------------------------------------------------------------
828
// class registrations
829
RegisterClass(TGLBlur);
830
RegisterClass(TGLMotionBlur);