1 /**
2 Copyright: Guillaume Piolat 2015-2017.
3 License:   $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)
4 */
5 module gui;
6 
7 import std.math;
8 
9 import gfm.math;
10 import dplug.gui;
11 import dplug.pbrwidgets;
12 import dplug.client;
13 
14 import main;
15 
16 // Plugin GUI, based on PBRBackgroundGUI.
17 // If you don't want to use PBR, you not inherit from it.
18 class DistortGUI : PBRBackgroundGUI!("basecolor.jpg", "emissive.png", "material.png",
19                                      "depth.png", "skybox.jpg",
20 
21                                      // Enter here the absolute path to the gfx directory.
22                                      // This will allow to reload images at debug-time with the press of ENTER.
23                                      `C:\Users\myuser\Products\distort\gfx\`)
24 {
25 public:
26 nothrow:
27 @nogc:
28 
29     DistortClient _client;
30 
31     UISlider inputSlider;
32     UIKnob driveKnob;
33     UISlider outputSlider;
34     UIOnOffSwitch onOffSwitch;
35     UIBargraph inputBargraph, outputBargraph;
36     UIColorCorrection colorCorrection;
37 
38     Font _font;
39 
40     this(DistortClient client)
41     {
42         _client = client;
43         int W = 620, H = 330;
44         super(W, H); // size
45 
46 
47         // Note: PBRCompositor default lighting might change in a future version (increase of light to allow white plastics).
48         //       So we keep the value.
49         PBRCompositor comp = cast(PBRCompositor)compositor;
50         comp.light1Color = vec3f(0.26, 0.24, 0.22f) * 0.98f;
51         comp.light2Dir = vec3f(-0.5f, 1.0f, 0.23f).normalized;
52         comp.light2Color = vec3f(0.36, 0.38f, 0.40) * 1.148;
53         comp.light3Dir = vec3f(0.0f, 1.0f, 0.1f).normalized;
54         comp.light3Color = vec3f(0.2f, 0.2f, 0.2f) * 0.84f;
55         comp.ambientLight = 0.042f;
56         comp.skyboxAmount = 0.56f;
57 
58         // Sets the number of pixels recomputed around dirtied controls.
59         // This is a tradeoff between Emissive light accuracy and speed.
60         // A typical value is between 15 and 30 pixels.
61         setUpdateMargin(30);
62 
63         // All resources are bundled as a string import.
64         // You can avoid resource compilers that way.
65         // The only cost is that each resource is in each binary, this creates overhead with
66         _font = mallocNew!Font(cast(ubyte[])( import("VeraBd.ttf") ));
67 
68         // Builds the UI hierarchy
69         // Note: when Dplug has resizeable UI, all positionning is going
70         // to move into a reflow() override.
71         // Meanwhile, we hardcode each position.
72 
73         RGBA litTrailDiffuse = RGBA(151, 119, 255, 100);
74         RGBA unlitTrailDiffuse = RGBA(81, 54, 108, 0);
75 
76         // Add knob
77         addChild(driveKnob = mallocNew!UIKnob(context(), cast(FloatParameter) _client.param(paramDrive)));
78         driveKnob.position = box2i.rectangle(250, 140, 120, 120);
79         driveKnob.knobRadius = 0.65f;
80         driveKnob.knobDiffuse = RGBA(255, 255, 238, 0);
81         driveKnob.knobMaterial = RGBA(0, 255, 128, 255);
82         driveKnob.numLEDs = 15;
83         driveKnob.litTrailDiffuse = litTrailDiffuse;
84         driveKnob.unlitTrailDiffuse = unlitTrailDiffuse;
85         driveKnob.LEDDiffuseLit = RGBA(40, 40, 40, 100);
86         driveKnob.LEDDiffuseUnlit = RGBA(40, 40, 40, 0);
87         driveKnob.LEDRadiusMin = 0.06f;
88         driveKnob.LEDRadiusMax = 0.06f;
89 
90         // Add sliders
91         addChild(inputSlider = mallocNew!UISlider(context(), cast(FloatParameter) _client.param(paramInput)));
92         inputSlider.position = box2i.rectangle(190, 132, 30, 130);
93         inputSlider.litTrailDiffuse = litTrailDiffuse;
94         inputSlider.unlitTrailDiffuse = unlitTrailDiffuse;
95 
96         addChild(outputSlider = mallocNew!UISlider(context(), cast(FloatParameter) _client.param(paramOutput)));
97         outputSlider.position = box2i.rectangle(410, 132, 30, 130);
98         outputSlider.litTrailDiffuse = litTrailDiffuse;
99         outputSlider.unlitTrailDiffuse = unlitTrailDiffuse;
100 
101         // Add switch
102         addChild(onOffSwitch = mallocNew!UIOnOffSwitch(context(), cast(BoolParameter) _client.param(paramOnOff)));
103         onOffSwitch.position = box2i.rectangle(90, 177, 30, 40);
104         onOffSwitch.diffuseOn = litTrailDiffuse;
105         onOffSwitch.diffuseOff = unlitTrailDiffuse;
106 
107         // Add bargraphs
108         addChild(inputBargraph = mallocNew!UIBargraph(context(), 2, -80.0f, 6.0f));
109         inputBargraph.position = box2i.rectangle(150, 132, 30, 130);
110         addChild(outputBargraph = mallocNew!UIBargraph(context(), 2, -80.0f, 6.0f));
111         outputBargraph.position = box2i.rectangle(450, 132, 30, 130);
112         static immutable float[2] startValues = [0.0f, 0.0f];
113         inputBargraph.setValues(startValues);
114         outputBargraph.setValues(startValues);
115 
116         // Global color correction.
117         // Very useful at the end of the UI creating process.
118         // As the sole Raw-only widget it is always on top and doesn't need zOrder adjustment.
119         {
120             mat3x4f colorCorrectionMatrix = mat3x4f(- 0.07f, 1.0f , 1.15f, 0.03f,
121                                                     + 0.01f, 0.93f, 1.16f, 0.08f,
122                                                     + 0.0f , 1.0f , 1.10f, -0.01f);
123             addChild(colorCorrection = mallocNew!UIColorCorrection(context()));
124             colorCorrection.setLiftGammaGainContrastRGB(colorCorrectionMatrix);
125             colorCorrection.position = box2i.rectangle(0, 0, W, H);
126         }
127     }
128 
129     ~this()
130     {
131         _font.destroyFree();
132     }
133 }