2
// This unit is part of the GLScene Engine https://github.com/glscene
5
A shader that renders hidden (back-faced) lines differently from visible
6
(front) lines. Polygon offset is used to displace fragments depths a little
7
so that there is no z-fighting in rendering the same geometry multiple times.
10
23/08/10 - Yar - Added OpenGLTokens to uses, replaced OpenGL1x functions to OpenGLAdapter
11
22/04/10 - Yar - Fixes after GLState revision
12
05/03/10 - DanB - More state added to TGLStateCache
13
06/06/07 - DaStr - Added $I GLScene.inc
14
Added GLColor to uses (BugtrackerID = 1732211)
15
25/02/07 - DaStr - Moved registration to GLSceneRegister.pas
16
25/09/04 - NelC - Fixed bug of disabled blend (thx Carlos)
17
05/02/04 - NelC - Fixed memory leak in TGLHiddenLineShader.Destroy (thx Achim Hammes)
18
13/12/03 - NelC - Added SurfaceLit, ShadeModel
19
05/12/03 - NelC - Added ForceMaterial
20
03/12/03 - NelC - Creation. Modified from the HiddenLineShader in
24
unit GLHiddenLineShader;
32
GLMaterial, OpenGLTokens, GLCrossPlatform, GLScene, GLColor,
33
GLBaseClasses, GLRenderContextInfo, GLState, GLContext;
36
TGLLineSettings = class(TGLUpdateAbleObject)
43
FForceMaterial: Boolean;
45
procedure SetPattern(const value: TGLushort);
46
procedure SetColor(const v: TGLColor);
47
procedure SetWidth(const Value: Single);
48
procedure SetForceMaterial(v: boolean);
52
constructor Create(AOwner: TPersistent); override;
53
destructor Destroy; override;
54
procedure Apply(var rci: TGLRenderContextInfo);
55
procedure UnApply(var rci: TGLRenderContextInfo);
59
property Width: Single read FWidth write SetWidth;
60
property Color: TGLColor read FColor write SetColor;
61
property Pattern: TGLushort read FPattern write SetPattern default $FFFF;
62
{ Set ForceMaterial to true to enforce the application of the line settings
63
for objects that sets their own color, line width and pattern. }
64
property ForceMaterial: Boolean read FForceMaterial write SetForceMaterial
68
TGLHiddenLineShader = class(TGLShader)
75
FBackGroundColor: TGLColor;
77
FFrontLine: TGLLineSettings;
78
FBackLine: TGLLineSettings;
81
FShadeModel: TGLShadeModel;
83
procedure SetlineSmooth(v: boolean);
84
procedure SetSolid(v: boolean);
85
procedure SetBackgroundColor(AColor: TGLColor);
86
procedure SetLighting(v: boolean);
87
procedure SetShadeModel(const val: TGLShadeModel);
90
procedure DoApply(var rci: TGLRenderContextInfo; Sender: TObject); override;
91
function DoUnApply(var rci: TGLRenderContextInfo): Boolean; override;
95
constructor Create(AOwner: TComponent); override;
96
destructor Destroy; override;
100
property FrontLine: TGLLineSettings read FFrontLine write FFrontLine;
101
property BackLine: TGLLineSettings read FBackLine write FBackLine;
102
{ Line smoothing control }
103
property LineSmooth: Boolean read FlineSmooth write SetlineSmooth default
105
{ Solid controls if you can see through the front-line wireframe. }
106
property Solid: Boolean read FSolid write SetSolid default false;
107
{ Color used for solid fill. }
108
property BackgroundColor: TGLColor read FBackgroundColor write
110
{ When Solid is True, determines if lighting or background color is used. }
111
property SurfaceLit: Boolean read FLighting write SetLighting default true;
113
Default is "Smooth". }
114
property ShadeModel: TGLShadeModel read FShadeModel write SetShadeModel
118
// ------------------------------------------------------------------
119
// ------------------------------------------------------------------
120
// ------------------------------------------------------------------
122
// ------------------------------------------------------------------
123
// ------------------------------------------------------------------
124
// ------------------------------------------------------------------
126
// ------------------ TGLLineSettings ------------------
132
constructor TGLLineSettings.Create(AOwner: TPersistent);
135
FColor := TGLColor.Create(Self);
136
FColor.Initialize(clrGray20);
139
ForceMaterial := false;
145
destructor TGLLineSettings.Destroy;
154
procedure TGLLineSettings.SetPattern(const value: TGLushort);
156
if FPattern <> value then
166
procedure TGLLineSettings.SetColor(const v: TGLColor);
168
FColor.Color := v.Color;
175
procedure TGLLineSettings.SetWidth(const Value: Single);
182
IgnoreMatSave: boolean;
187
procedure TGLLineSettings.Apply(var rci: TGLRenderContextInfo);
189
rci.GLStates.LineWidth := Width;
190
GL.Color4fv(Color.AsAddress);
191
if Pattern <> $FFFF then
193
rci.GLStates.Enable(stLineStipple);
194
rci.GLStates.LineStippleFactor := 1;
195
rci.GLStates.LineStipplePattern := Pattern;
198
rci.GLStates.Disable(stLineStipple);
200
if ForceMaterial then
202
IgnoreMatSave := rci.ignoreMaterials;
203
rci.ignoreMaterials := true;
210
procedure TGLLineSettings.UnApply(var rci: TGLRenderContextInfo);
212
if ForceMaterial then
213
rci.ignoreMaterials := IgnoreMatSave;
219
procedure TGLLineSettings.SetForceMaterial(v: boolean);
221
if FForceMaterial <> v then
229
// ------------------ TGLHiddenLineShader ------------------
235
constructor TGLHiddenLineShader.Create(AOwner: TComponent);
238
FFrontLine := TGLLineSettings.Create(self);
239
FBackLine := TGLLineSettings.Create(self);
242
FBackgroundColor := TGLColor.Create(Self);
243
FBackgroundColor.Initialize(clrBtnFace);
245
FLineSmooth := False;
247
FShadeModel := smDefault;
253
destructor TGLHiddenLineShader.Destroy;
257
FBackgroundColor.Free;
264
procedure TGLHiddenLineShader.DoApply(var rci: TGLRenderContextInfo; Sender:
272
// draw filled front faces in first pass
273
PolygonMode := pmFill;
274
CullFaceMode := cmBack;
279
smDefault, smSmooth: GL.ShadeModel(GL_SMOOTH);
280
smFlat: GL.ShadeModel(GL_FLAT);
286
GL.Color4fv(FBackgroundColor.AsAddress); // use background color
288
// enable and adjust polygon offset
289
Enable(stPolygonOffsetFill);
295
// draw back lines in first pass
296
FBackLine.Apply(rci);
297
CullFaceMode := cmFront;
298
PolygonMode := pmLines;
299
// enable and adjust polygon offset
300
Enable(stPolygonOffsetLine);
303
rci.GLStates.SetPolygonOffset(1, 2);
309
function TGLHiddenLineShader.DoUnApply(var rci: TGLRenderContextInfo): Boolean;
311
procedure SetLineSmoothBlend;
315
LineStippleFactor := 1;
316
LineStipplePattern := $FFFF;
319
LineSmoothHint := hintNicest;
320
Enable(stLineSmooth);
323
Disable(stLineSmooth);
325
if LineSmooth or (FBackLine.FColor.Alpha < 1)
326
or (FFrontLine.FColor.Alpha < 1) then
329
SetBlendFunc(bfSrcAlpha, bfOneMinusSrcAlpha);
339
with rci.GLStates do begin
340
// draw front line in 2nd pass
343
FBackLine.UnApply(rci);
344
FFrontLine.Apply(rci);
348
if solid and FLighting then
351
PolygonMode := pmLines;
352
CullFaceMode := cmBack;
355
rci.GLStates.Disable(stPolygonOffsetFill)
357
rci.GLStates.Disable(stPolygonOffsetLine);
363
FFrontLine.UnApply(rci);
364
rci.GLStates.PolygonMode := pmFill;
376
procedure TGLHiddenLineShader.SetBackgroundColor(AColor: TGLColor);
378
FBackgroundColor.Color := AColor.Color;
385
procedure TGLHiddenLineShader.SetlineSmooth(v: boolean);
387
if FlineSmooth <> v then
397
procedure TGLHiddenLineShader.SetLighting(v: boolean);
399
if FLighting <> v then
409
procedure TGLHiddenLineShader.SetSolid(v: boolean);
421
procedure TGLHiddenLineShader.SetShadeModel(const val: TGLShadeModel);
423
if FShadeModel <> val then