Recent

Author Topic: BGRA Controls  (Read 222381 times)

circular

  • Hero Member
  • *****
  • Posts: 4196
    • Personal webpage
Re: BGRA-Controls
« Reply #195 on: October 22, 2016, 10:28:36 pm »
Hmmm... maybe you can create a second canvas the same way it is done in TCustomOpenGLContext.Create:
Code: Pascal  [Select][+][-]
  1. if (csDesigning in ComponentState) then begin
  2.     FMyCanvas := TControlCanvas.Create;
  3.     FMyCanvas.Control := Self;
  4.   end

Also I suppose you need to redefine the LM_PAINT handler:
Code: Pascal  [Select][+][-]
  1. procedure MyWMPaint(var Message: TLMPaint); message LM_PAINT;
Conscience is the debugger of the mind

circular

  • Hero Member
  • *****
  • Posts: 4196
    • Personal webpage
Re: BGRA-Controls
« Reply #196 on: October 23, 2016, 07:54:35 am »
Another solution would be to have a container that is a sort of TPanel and that at runtime, it creates an OpenGL controlinside itself with Align:=clClient and transfers all its subcontrols into this OpenGL control. So at design time, you would not have anything to do for the regular OnPaint to be called.
Conscience is the debugger of the mind

lainz

  • Hero Member
  • *****
  • Posts: 4460
    • https://lainz.github.io/
Re: BGRA-Controls
« Reply #197 on: October 23, 2016, 01:54:30 pm »
I have it working. Thanks for your help.

Try it here:
https://github.com/bgrabitmap/bgracontrolsfx

A challenge: Is possible to have the FXMaterialDesignButton at full speed when you maximize the window? Maybe I don't know how to optimize it more, maybe you can see the code and find a speed improvement.
« Last Edit: October 23, 2016, 05:24:33 pm by lainz »

circular

  • Hero Member
  • *****
  • Posts: 4196
    • Personal webpage
Re: BGRA-Controls
« Reply #198 on: October 23, 2016, 05:27:49 pm »
Wonderful.  :)

About the invalidate problem, you can for example call Invalidate of the container.

It can be optimised to use OpenGL speedup. In FXDraw, the content of fx (TBGLBitmap) variable is changed each time even if the bitmap FBGRA is not updated. So image data is transmitted to video memory each time. But that's not necessary because the content does not always change.

Instead you can use TBGLBitmap only. Indeed you can draw a TBGLBitmap on a regular canvas.

Otherwise, if you would like your control to work also without the container, with the regular canvas and without OpenGL, you can continue using TBGRABitmap, but not TBGLBitmap. Only keep a texture variable. When the bitmap is changed, for example set the texture to nil, so you know you need to create it again in case you draw it in the container. The texture can be created using BGLTexture(...). At that time it will be transferred to video memory.

When computing the shadow you can use rbBox:
Code: Pascal  [Select][+][-]
  1.     BGRAReplace(FBGRAShadow, FBGRAShadow.FilterBlurRadial(FShadowSize/sqrt(2),
  2.       FShadowSize/sqrt(2), rbBox) as TBGRABitmap);  

Here attached is a patch example. Note that there may be some problems when the texture is freed, in particular if there are multiple OpenGL contexts. It would be safe to add some FXFree procedure that would be called when the context is freed. The container could call those functions. Note that the function MakeCurrent of the OpenGL context must be called to ensure the correct context is selected.

For the background gradient of the container, as OpenGL is fast for gradients, you can simply do:
Code: Pascal  [Select][+][-]
  1.   BGLCanvas.FillRectLinearColor(0,0,FXContainer1.Width,FXContainer1.Height,BGRABlack,BGRABlack,BGRAWhite,BGRAWhite);  
« Last Edit: October 23, 2016, 06:11:48 pm by circular »
Conscience is the debugger of the mind

lainz

  • Hero Member
  • *****
  • Posts: 4460
    • https://lainz.github.io/
Re: BGRA-Controls
« Reply #199 on: October 23, 2016, 06:39:06 pm »
Many thanks!

I've improved it a lot with two new properties. Please see the new test. So now the DoOnPaint are called only by only a control when needed, doing an improvement of speed on controls with animations (like FXMaterialDesignButton). Run the demo and click faster each control, everything will be smooth as always. Also it can be smoother defining with an external timer the refresh rate of all controls in the form. Is really fast now.

circular

  • Hero Member
  • *****
  • Posts: 4196
    • Personal webpage
Re: BGRA-Controls
« Reply #200 on: October 23, 2016, 07:04:05 pm »
Hi!

Wait. When you set FTexture := nil in the FXDraw procedure, it means the texture will be transferred next time. But that's not necessary if the bitmap has not changed. That's why I've put it in the Draw function. Or, even better, instead of directly setting FNeedDraw to False, you can make a protected function "DiscardBitmap" that will set FNeedDraw to false and set FTexture to nil.

The "ReceivePaintFrom" will not always work. Suppose you have one button with a long animation, and then a second button with a short animation. The short animation will end before the end of the long animation. As said above, you can simply call Parent.Invalidate.
Conscience is the debugger of the mind

lainz

  • Hero Member
  • *****
  • Posts: 4460
    • https://lainz.github.io/
Re: BGRA-Controls
« Reply #201 on: October 23, 2016, 07:22:59 pm »
Ok I need to fix that. The need draw is set to false only once so I'll put in there.

I need to try with invalidate.

Edit: I've applied all your suggestions and works well  :D

I've keept the "ReceivePaintFrom", but with a different use, I don't know if it's ok or not so I ask you. For example instead of using the timer inside the MaterialDesignButton or any control it will use an external timer like for a videogame, so the entire window will be redrawn in a specified interval and will not be invalidated by the controls even when there is user interaction.
« Last Edit: October 23, 2016, 09:01:07 pm by lainz »

circular

  • Hero Member
  • *****
  • Posts: 4196
    • Personal webpage
Re: BGRA-Controls
« Reply #202 on: October 23, 2016, 09:07:34 pm »
You could do that, however it means it will use CPU even if nothing happens. For a game, that does not really happen because the game is always doing something, but for an interface, sometimes nothing happens.
Conscience is the debugger of the mind

lainz

  • Hero Member
  • *****
  • Posts: 4460
    • https://lainz.github.io/
Re: BGRA-Controls
« Reply #203 on: October 23, 2016, 09:11:00 pm »
It's ok suppose that I want to animate the background constantly and in top of it have the ui (animated or not), instead of creating a separate control i can use the container. I will left it as an option. By default is not used and for the controls it only adds a line or two so there is no problem.

circular

  • Hero Member
  • *****
  • Posts: 4196
    • Personal webpage
Re: BGRA-Controls
« Reply #204 on: October 23, 2016, 09:30:13 pm »
I see what you're saying. Yes indeed that's no problem.

I am a bit confused though how to use ReceivePaintFrom. If I understand what you're saying, it would be something like a boolean?
Conscience is the debugger of the mind

lainz

  • Hero Member
  • *****
  • Posts: 4460
    • https://lainz.github.io/
Re: BGRA-Controls
« Reply #205 on: October 23, 2016, 09:42:29 pm »
Is like a boolean, but instead of using a boolean uses a control.

Take a look at this code, if ReceivePaintFrom is nil it will paint, since there is no control that has set the ReceivePaintFrom. In the case the ReceivePaintFrom control is set it will not call Parent.Invalidate.

With the use we well do from now is not neccessary to be a control and can be a boolean. But as is you can actually two things: if there is activated the option and wich control activated that. Also you can check if your specific control is the one that uses that setting. As I said it was prepared for the other use, but still works for the new use.

Code: Pascal  [Select][+][-]
  1. if Parent is TFXContainer then
  2.   begin
  3.     if TFXContainer(Parent).ReceivePaintFrom = nil then
  4.       Parent.Invalidate;
  5.   end
  6.   else
  7.     Invalidate;

The other property was intended for the previous use that I explained. LockReceivePaint will lock the change of the control that's actually the one that does ReceivePaintFrom. So if a control like an external timer set that property, then no other control can change that.

Changes in git: Now the controls are Hybrid, so you can put them in a form or in a FXContainer. Of course in a form will be painted in canvas and in the other case with OpenGL
« Last Edit: October 23, 2016, 09:48:38 pm by lainz »

circular

  • Hero Member
  • *****
  • Posts: 4196
    • Personal webpage
Re: BGRA-Controls
« Reply #206 on: October 23, 2016, 09:53:55 pm »
Ok so a control can take control of the repaint process.  :)

What glitch?
Conscience is the debugger of the mind

lainz

  • Hero Member
  • *****
  • Posts: 4460
    • https://lainz.github.io/
Re: BGRA-Controls
« Reply #207 on: October 23, 2016, 09:57:46 pm »
Ok so a control can take control of the repaint process.  :)

What glitch?

Nothing I fixed that.

lainz

  • Hero Member
  • *****
  • Posts: 4460
    • https://lainz.github.io/
Re: BGRA-Controls
« Reply #208 on: October 24, 2016, 01:13:50 am »
Well after two days of work here it is the first release, thanks for your help!:
http://forum.lazarus-ide.org/index.php/topic,34534.0.html

For some reason AutoSize is not working inside the FXContainer at runtime, any ideas? The control is resized but not the painting. When put in a form it works..
« Last Edit: October 24, 2016, 02:15:26 am by lainz »

Josh

  • Hero Member
  • *****
  • Posts: 1271
Re: BGRA-Controls
« Reply #209 on: October 24, 2016, 08:22:26 am »
HI
Just upgraded to 9.2.1 and bgracontrols 4.3 and have a problem on cocoa

As soon as I resize my form, all text with bclabel and bcbutton disappears.

The resize routine; adjust the controls dimensions and proportionally the font size.  The controls dimension adjusts as the borders etc are adjusting, but the text vanishes.

This is working fine with win32 LCL and carbon; bit now cocoa is not rendering the resized font. Could it be x64 related?

No errors are shown if run in console.

ANy ideas?
The best way to get accurate information on the forum is to post something wrong and wait for corrections.

 

TinyPortal © 2005-2018