123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254 |
- unit fMultiPass;
- interface
- uses
- Winapi.OpenGL,
- System.SysUtils,
- System.Classes,
- Vcl.Graphics,
- Vcl.Controls,
- Vcl.Forms,
- Vcl.Dialogs,
- Vcl.StdCtrls,
- GLS.Scene,
- GLS.Objects,
- GLS.SceneViewer,
- GLS.Texture,
- GLS.Context,
- GLS.GeomObjects,
- GLS.State,
- GLS.Color,
- GLS.Material,
- GLS.Coordinates,
-
- GLS.RenderContextInfo,
- GLS.BaseClasses;
- type
- TFormMultiPath = class(TForm)
- GLScene1: TGLScene;
- GLSceneViewer1: TGLSceneViewer;
- GLCamera1: TGLCamera;
- GLLightSource1: TGLLightSource;
- Torus1: TGLTorus;
- BUBind: TButton;
- Sphere1: TGLSphere;
- GLMaterialLibrary1: TGLMaterialLibrary;
- GLAnnulus1: TGLAnnulus;
- GLAnnulus2: TGLAnnulus;
- GLCube1: TGLCube;
- GLSphere1: TGLSphere;
- procedure BUBindClick(Sender: TObject);
- procedure GLSceneViewer1MouseDown(Sender: TObject;
- Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
- procedure GLSceneViewer1MouseMove(Sender: TObject; Shift: TShiftState;
- X, Y: Integer);
- private
-
- public
-
- mx, my: Integer;
- end;
- var
- FormMultiPath: TFormMultiPath;
- implementation
- {$R *.dfm}
- type
- THiddenLineShader = class(TGLShader)
- private
- BackgroundColor, LineColor: TColorVector;
- PassCount: Integer;
- public
- procedure DoApply(var rci: TGLRenderContextInfo; Sender: TObject); override;
- function DoUnApply(var rci: TGLRenderContextInfo): Boolean; override;
- end;
- TOutLineShader = class(TGLShader)
- private
- BackgroundColor, LineColor: TColorVector;
- OutlineSmooth, Lighting: Boolean;
- OutlineWidth, Oldlinewidth: Single;
- PassCount: Integer;
- public
- procedure DoApply(var rci: TGLRenderContextInfo; Sender: TObject); override;
- function DoUnApply(var rci: TGLRenderContextInfo): Boolean; override;
- end;
- procedure THiddenLineShader.DoApply(var rci: TGLRenderContextInfo; Sender:
- TObject);
- begin
- // new object getting rendered, 1st pass
- PassCount := 1;
- with rci.GLStates do
- begin
- // disable lighting, this is a solid fill
- Disable(stLighting);
- PolygonMode := pmFill;
- // use background color
- gl.Color3fv(@BackgroundColor);
- // enable and adjust polygon offset
- Enable(stPolygonOffsetFill);
- SetPolygonOffset(1, 2);
- end;
- end;
- function THiddenLineShader.DoUnApply(var rci: TGLRenderContextInfo): Boolean;
- begin
- case PassCount of
- 1:
- with rci.GLStates do
- begin
- // 1st pass completed, we setup for the second
- PassCount := 2;
- // switch to wireframe and its color
- PolygonMode := pmLines;
- Disable(stPolygonOffsetLine);
- Disable(stLineStipple);
- Disable(stLineSmooth);
- LineWidth := 1;
- gl.Color3fv(@LineColor);
- Result := True;
- end;
- 2:
- with rci.GLStates do
- begin
- // restore state
- PolygonMode := pmFill;
- Disable(stPolygonOffsetFill);
- // we're done
- Result := False;
- end;
- else
- // doesn't hurt to be cautious
- Assert(False);
- Result := False;
- end;
- end;
- procedure TOutLineShader.DoApply(var rci: TGLRenderContextInfo; Sender: TObject);
- begin
- PassCount := 1;
- with rci.GLStates do
- begin
- Disable(stLighting);
- if outlineSmooth then
- begin
- Enable(stBlend);
- SetBlendFunc(bfSrcAlpha, bfOneMinusSrcAlpha);
- LineSmoothHint := hintNicest;
- Enable(stLineSmooth);
- end
- else
- Disable(stLineSmooth);
- LineStippleFactor := 1;
- LineStipplePattern := $FFFF;
- LineWidth := OutLineWidth;
- PolygonMode := pmLines;
- CullFaceMode := cmFront;
- DepthFunc := cfLEqual;
- gl.Color3fv(@lineColor);
- end;
- end;
- function TOutLineShader.DoUnApply(var rci: TGLRenderContextInfo): Boolean;
- begin
- case PassCount of
- 1:
- with rci.GLStates do
- begin
- PassCount := 2;
- if lighting then
- Enable(stLighting)
- else
- gl.Color3fv(@backGroundColor);
- DepthFunc := cfLess;
- PolygonMode := pmFill;
- CullFaceMode := cmBack;
- Result := True;
- end;
- 2:
- begin
- Result := False;
- end;
- else
- Assert(False);
- Result := False;
- end;
- end;
- procedure TFormMultiPath.BUBindClick(Sender: TObject);
- var
- shader1: THiddenLineShader;
- shader2, shader3: TOutLineShader;
- begin
- BUBind.Enabled := False;
- // instantiate our shaders
- shader1 := THiddenLineShader.Create(Self);
- shader1.BackgroundColor :=
- ConvertWinColor(GLSceneViewer1.Buffer.BackgroundColor);
- shader1.LineColor := clrBlue;
- shader2 := TOutLineShader.Create(Self);
- with shader2 do
- begin
- BackgroundColor := ConvertWinColor(GLSceneViewer1.Buffer.BackgroundColor);
- Outlinesmooth := true;
- OutLineWidth := 2;
- Lighting := false;
- LineColor := clrBlack;
- end;
- shader3 := TOutLineShader.Create(Self);
- with shader3 do
- begin
- BackgroundColor := ConvertWinColor(GLSceneViewer1.Buffer.BackgroundColor);
- Outlinesmooth := false;
- OutLineWidth := 4;
- Lighting := true;
- LineColor := clrRed;
- end;
- // binds the shaders to the materials
- GLMaterialLibrary1.Materials[0].Shader := shader1;
- GLMaterialLibrary1.Materials[1].Shader := shader2;
- GLMaterialLibrary1.Materials[2].Shader := shader3;
- end;
- //
- // Classic mouse movement bits
- //
- procedure TFormMultiPath.GLSceneViewer1MouseDown(Sender: TObject;
- Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
- begin
- mx := x;
- my := y;
- end;
- procedure TFormMultiPath.GLSceneViewer1MouseMove(Sender: TObject;
- Shift: TShiftState; X, Y: Integer);
- begin
- if Shift = [ssLeft] then
- GLCamera1.MoveAroundTarget(my - y, mx - x)
- else if Shift = [ssRight] then
- GLCamera1.RotateTarget(my - y, mx - x);
- mx := x;
- my := y;
- end;
- end.
|