im currently writing a 2D window framework (gui engine). Every control (window, button, panels, ..) is painted on a seperate surface. These surfaces are merged together, after all controls in the tree are painted.
For example (window contains panel and button 3, panel contains button 1 and button 2):
Paint Window
Paint Panel
Paint Button 1
Merge Button 1 surface with Panel surface
Paint Button 2
Merge Button 2 surface with Panel surface
Paint Button 3
Merge Button 3 surface with Panel surface
Merge Panel surface with Window surface
Our problem is the correct alpha blend calculation while merging the surfaces. We tried different configurations, but the alpha values did behave "strange" for all of them. The biggest problem are alpha holes (fully transparent pixels, even if the top level surface (window) is nearly opaque).
Device->SetRenderState (D3DRS_ALPHABLENDENABLE, 1 );
Device->SetRenderState (D3DRS_BLENDOP, D3DBLENDOP_ADD );
Device->SetRenderState (D3DRS_SRCBLEND, D3DBLEND_SRCALPHA );
Device->SetRenderState (D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
As a quick fix, we are currently using the following render states:
Device->SetRenderState (D3DRS_ALPHABLENDENABLE, 1 );
Device->SetRenderState (D3DRS_BLENDOP, D3DBLENDOP_ADD );
Device->SetRenderState (D3DRS_SEPARATEALPHABLENDENABLE, 1 );
Device->SetRenderState (D3DRS_SRCBLEND, D3DBLEND_SRCALPHA );
Device->SetRenderState (D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
Device->SetRenderState (D3DRS_SRCBLENDALPHA, D3DBLEND_ONE );
Device->SetRenderState (D3DRS_DESTBLENDALPHA, D3DBLEND_ONE );
But these are obviously incorrect, because the alpha values of two overlaying controls are added (making two 127 alpha controls fully opaque).
Is it possible to blend the surfaces like this:
A = AlphaValue * (ParentAlphaBlend / 255);
Best regards
Zacherl
Related
I'm exploring PowerAutomate and am stuck with a relatively simple issue;
I want to click-and-drag to draw a yellow circle in Ms paint.
Currently, my flow looks like this:
start Paint ( Run application )
Select Yellow ( Click UI Element in Window)
Click mouse
Drag?
The last two points are not working / don't know how to do.
What is the best approach?
I draw a path consisting of 2 lines going up and then back down to the same spot, or almost the same spot, but the first line is drawn too high. If I then draw the same lines using DrawLine I don't see the issue. Why is this happening?
Below is an example. Just drop a 400x400 TImage on a blank multiplatform form. The code draws 2 red paths, one with close to a 180 degree angle between the lines and one with less of an angle. The same lines are then drawn using DrawLine in blue. If the DrawPath function works correctly then the blue lines should completely cover the red lines, but they don't. In this example with a scale of 1.5 the path extends 7 pixels too high for the first path. The extent of the error reduces as the lines get further apart. The issue still happens with a scale of 1, but is less obvious.
procedure TForm1.FormActivate(Sender: TObject);
var
LPath1, LPath2 : TPathData;
i : Integer;
begin
// A path of 2 lines going up and then back down to almost the same spot
LPath1 := TPathData.Create;
LPath1.MoveTo(PointF(100,200));
LPath1.LineTo(PointF(100,50 ));
LPath1.LineTo(PointF(105,200));
// A path of 2 lines going up and then back down at a wider angle
LPath2 := TPathData.Create;
LPath2.MoveTo(PointF(200,200));
LPath2.LineTo(PointF(200,50 ));
LPath2.LineTo(PointF(260,200));
Image1.Bitmap.BitmapScale := 1.5; // The issue shows up more at larger scales
Image1.Bitmap.SetSize(Trunc(Image1.Width), Trunc(Image1.Height));
with Image1.Bitmap.Canvas do if BeginScene then begin
Clear(TAlphaColorRec.White);
// Draw the paths using DrawPath in red
Stroke.Color := TAlphaColorRec.Red;
Stroke.Thickness := 1;
DrawPath(LPath1, 1);
DrawPath(LPath2, 1);
// Draw the paths using DrawLine in blue over the top
// The red lines should be completely hidden under the blue
Stroke.Color := TAlphaColorRec.Blue;
for i := 1 to LPath1.Count - 1 do
DrawLine(LPath1.Points[i-1].Point, LPath1.Points[i].Point, 1);
for i := 1 to LPath2.Count - 1 do
DrawLine(LPath2.Points[i-1].Point, LPath2.Points[i].Point, 1);
EndScene;
end;
LPath1.Free;
LPath2.Free;
Image1.Bitmap.SaveToFile('test.png');
end;
Result of the code when run in Windows 10. I'm using Delphi 11, but the same issue happens with Delphi 10. I've tried switching GPU but the same issue occurs.
Enlarged view:
I've come to the conclusion that this isn't a glitch at all. It's because the default setting of TCanvas.Stroke.Join is TStrokeJoin.Miter. The artefact seen is just the sharp spike of the mitred corner. Using MoveTo before each line segment when constructing the path does solve the issue (because there's no join between the separate line segments) but so does setting the TCanvas.Stroke.Join parameter to TStrokeJoin.Round or TStrokeJoin.Bevel.
Note that at very sharp angles approaching 180 degrees, the miter join would become infinite. However, it appears to be limited somehow, perhaps in proportion to the stroke thickness. I don't think there's a way to change this miter limit in delphi.
This is because by default TPath is making smooth transitions between different path segments. I'm guessing it might be using Quadratic interpolation for making these smooth transitions.
Yes making smooth transition between two lines doesn't seem logical but it looks this is how it is implemented.
Now you can avoid this by telling the TPath that your two lines are not connected and thus should be treated as two separate lines even thou in reality they are connected. And you can do this by simply calling Path.MoveTo which is intended to shift position so you can create another unconnected line that dos not continue from your last path point.
Here is how modified code for your first sharp cornered line would look like:
NOTE that I'm specifying the exact same position for MoveTo command that was used for rendering of previous path line since you don't want the new line to start at new position.
// A path of 2 lines going up and then back down to almost the same spot
LPath1 := TPathData.Create;
LPath1.MoveTo(PointF(100,200));
LPath1.LineTo(PointF(100,50 ));
//Add move to command to prevent Path from trying to make smooth transitions between two lines
LPath1.MoveTo(PointF(100,50));
LPath1.LineTo(PointF(105,200));
I know how to draw an object arrow on the chart, which I usually do like this:
ObjectCreate(0,"prevHigh",OBJ_ARROW_DOWN,0,Time[0],High[highestCandle]);
ObjectSetInteger(0, "prevHigh", OBJPROP_COLOR, clrRed);
Now I have an indicator which (I didn't code myself and is a .ex4 file which) draws up/down arrows on the chart as seen in the image (https://imgur.com/a/8yG0suw).
How can I when for example a Magenta down arrow has been drawn and the candle (index) at which it is drawn?
Please note that the arrows not in the list of objects on the chart
Q : "How can I recognise programmatically when an up/down arrow is drawn on a chart?"
Given the facts above, your test ought evaluate the moment the CustomIndicator ( via a published / used iCustom()-call signature ) by checking it as it goes from EMPTY_VALUE to any value != EMPTY_VALUE.
Given the CustomIndicator is a closed source ( *.ex4 ) you may need to check, if it did set its own ( hidden from our sight ) value, other than a current visible EMPTY_VALUE, yet this "re-calibration" will work, after you get a few manual tests of the CustomIndicator values for bars, that do not show any arrow - like for the 2020-Apr-08 09:30 et al v/s the displayed arrows are not the MQL4-Objects on their own, they are the closed-source CustomIndicator's SetIndexStyle() / SetIndexArrow() by-products, thus not inspectable either in the Object-List, or in the *.mq4 source-code.
Yet, detectable
Is there anyway to remove the black border from a TColorbutton ? Delphi xe5, developing for iOSdelp
There are actually three black or gray borders.
First, add a custom stylebook to your app. The docwiki tells how to do this:
http://docwiki.embarcadero.com/RADStudio/XE5/en/Customizing_the_Design_of_a_FireMonkey_Application
Follow step #2 (Step 3 doesn't work for mobile applications.)
Open the style editor and locate ColorButtonStyle.
Expand the tree node and click on "background" in the structure.
In the object inspector locate Fill and expand that node.
Change the fill Kind to bkNone.
That removes the wide gray bordered, leaving two dark gray 1px borders.
Further down the list of properties just below Sides is Stroke.
Change it's Kind to bkNone. That removes the outer gray line.
Depending on your app you may need to also edit the color animations below the background rectangle. I did this by erasing (blanking out) the triggers since I was unable to delete the animations.
Next go the Fill component and set the stroke kind to bkNone. That removes the inner gray line.
You may also also want to set the Fill Margins to 0 so the color extends to the outside of the object. (i.e no padding now that the gray is not there.)
Gary
I've created a simple DirectX app that renders a field of vertices. Vertices are rendered like this (if viewed from top):
|\|\|\|\|
|\|\|\|\|
Each triangle is rendered like this:
1
|\
2 3
Which should mean that the polygon is counterclockwise and not be rendered, but it is. Anyway when viewed from top the plane is perfect.
However, when viewed from another level some polygons are sort of transparent and you can see geometry behind them. I've highlighted some of the place where this is happening.
I am thinking this is some of the basic, beginner problems. What am I missing? My rasterizer description is such:
new RasterizerStateDescription
{
CullMode = CullMode.Front,
IsAntialiasedLineEnabled = true,
IsMultisampleEnabled = true,
IsDepthClipEnabled = true,
IsFrontCounterclockwise = false,
IsScissorEnabled = true,
DepthBias = 1,
DepthBiasClamp = 1000.0f,
FillMode = FillMode.Wireframe,
SlopeScaledDepthBias = 1.0f
};
This is by design. FillMode.Wireframe only draws edges of each triangle as lines. That's all.
Do a first pass with a solid fill mode and depth writes on and a color mask (RenderTargetWriteMask in D3D11 terminology), and a second one with depth test on (but depth writes off) and wireframe mode on. You will probably need depth bias too since lines and triangles are not rasterized the same way (and their z can differ at equal fragment position).
BTW, this technique is known as hidden line removal. You can check this presentation for more details.
Turned out I just had no depth-stencil buffer set up. Oh well.