Recent

Author Topic: What's wrong ?  (Read 1863 times)

PeterX

  • Sr. Member
  • ****
  • Posts: 326
What's wrong ?
« on: March 26, 2019, 12:09:45 am »
Hi,

I played around with a OpenGL example.

But my derived component does not behave as the code in the MainForm.

What's wrong ?
usually using latest Lazarus release version
with Windows 10 at home
and Windows 7 on the job

Handoko

  • Hero Member
  • *****
  • Posts: 3152
  • My goal: build my own game engine using Lazarus
Re: What's wrong ?
« Reply #1 on: March 26, 2019, 04:32:00 am »
The issue can be solved simply by adding inherited; at the beginning of your TOpenGLcube.Paint method in myopenglcube.pas.

But I got SIGSEGV exception (see the image below) when closing the program. I found that setting Parent := Panel1; (or := Panel2) in your TForm1.FormCreate will trigger the exception. Unfortunately I haven't found solution for this.

Tested on Lazarus 1.8.4 GTK2 Linux 64-bit.

Thaddy

  • Hero Member
  • *****
  • Posts: 8870
Re: What's wrong ?
« Reply #2 on: March 26, 2019, 07:14:33 am »
Indeed, inherited. The second problem can be solved this way:
Two options
Code: Pascal  [Select]
  1.   // manually create the OpenGL object :
  2.   OpenGLControl1:= TOpenGLControl.Create(Panel1);  // panel1 becomes owner and parent. This is how it would be with auto create in the designer too.
  3.   with OpenGLControl1 do begin
  4.     Name     := 'OpenGLControl1';
  5.     Align    := alClient;
  6.     OnPaint  := @OpenGLControl1Paint;
  7.     OnResize := @OpenGLControl1Resize;
  8.     AutoResizeViewport:= true;
  9.   end;
  10.  
  11.   // manually create the OpenGL object :
  12.   OpenGLcube:= TOpenGLcube.Create(Panel2); // panel2 will become owner and parent.
  13.   with OpenGLcube do begin
  14.     Name     := 'OpenGLcube';
  15.     Align    := alClient;
  16.     OnPaint  := @Paint;
  17.     OnResize := @OpenGLControl1Resize;
  18.     AutoResizeViewport:= true;

Second option is to move that code to the subsequent  TPanelX onCreate.
Thus you do not set the Parent, but let the full initialization code run and the parent will be correct automatically.
It can be the case that here the Parent <> Owner if you do it the way you did.

IOW tthere's a logical problem in this code.
« Last Edit: March 26, 2019, 07:23:17 am by Thaddy »
Most people that want to use threading should learn to patch their jeans first: use a needle.

PeterX

  • Sr. Member
  • ****
  • Posts: 326
Re: What's wrong ?
« Reply #3 on: March 26, 2019, 09:24:47 am »
The issue can be solved simply by adding inherited; at the beginning of your TOpenGLcube.Paint method in myopenglcube.pas.

But I got SIGSEGV exception (see the image below) when closing the program. I found that setting Parent := Panel1; (or := Panel2) in your TForm1.FormCreate will trigger the exception. Unfortunately I haven't found solution for this.

Tested on Lazarus 1.8.4 GTK2 Linux 64-bit.

Thanks, Handoko !

Does not crash on Close under WINDOWS, so must be a Linux issue .. But I did not write
Quote
inherited;

because in TCustomOpenGLControl  (unit OpenGLContext)  the paint procedure is virtual:
Quote
    Procedure Paint; virtual; 

I thought when virtual, there is nothing to inherit ???
usually using latest Lazarus release version
with Windows 10 at home
and Windows 7 on the job

PeterX

  • Sr. Member
  • ****
  • Posts: 326
Re: What's wrong ?
« Reply #4 on: March 26, 2019, 09:26:48 am »
Okay ... even though it's virtual, there is code :
Code: Pascal  [Select]
  1. procedure TCustomOpenGLControl.Paint;
  2. begin
  3.   if IsVisible and HandleAllocated then begin
  4.     UpdateFrameTimeDiff;
  5.     if IsOpenGLRenderAllowed and ([csDestroying]*ComponentState=[]) then begin
  6.       if AutoResizeViewport then begin
  7.         if not MakeCurrent then exit;
  8.         LOpenGLViewport(Handle,0,0,Width,Height);
  9.       end;
  10.     end;
  11.     //LOpenGLClip(Handle);
  12.     DoOnPaint;
  13.   end;
  14. end;        
  15.  
usually using latest Lazarus release version
with Windows 10 at home
and Windows 7 on the job

PeterX

  • Sr. Member
  • ****
  • Posts: 326
Re: What's wrong ?
« Reply #5 on: March 26, 2019, 09:36:54 am »
Hi Thaddy,

I would prefer your "second option", indeed.


In my edited code now, without "Parent   := Panel2;" the right Cube does not appear.
Looks like "OpenGLcube:= TOpenGLcube.Create(Panel2)" does only set the owner, but not the parent  (under Windows.. ?)

Code: Pascal  [Select]
  1.   // manually create the SECOND OpenGL object :
  2.   //OpenGLcube:= TOpenGLcube.Create(Self);
  3.   OpenGLcube:= TOpenGLcube.Create(Panel2);
  4.   with OpenGLcube do begin
  5.     Name     := 'OpenGLcube';
  6.     Align    := alClient;
  7.     //Parent   := Panel2;
  8.     AutoResizeViewport:= true;
  9.  

And a remark (for people reading this):
it is not required to put the TOpenGLControl onto a panel,
TOpenGLControl itself is a Object with width and height.

But I wanted to put it onto a panel, in my future use not with Align:= alClient but with fixed dimensions ..
« Last Edit: March 26, 2019, 09:52:12 am by PeterX »
usually using latest Lazarus release version
with Windows 10 at home
and Windows 7 on the job

Thaddy

  • Hero Member
  • *****
  • Posts: 8870
Re: What's wrong ?
« Reply #6 on: March 26, 2019, 10:14:17 am »
It may be that you have to call invalidate once. If the control behaves correctly then the first example should set Owner and Parent to be the same (the panel).
Under windows, maybe a call to handleneeded (in the control code) if that is supported by Lazarus. (I am not sure).
Most people that want to use threading should learn to patch their jeans first: use a needle.

PeterX

  • Sr. Member
  • ****
  • Posts: 326
Re: What's wrong ?
« Reply #7 on: March 26, 2019, 10:29:29 am »
new ZIP archive of the edited OpenGL example ..
usually using latest Lazarus release version
with Windows 10 at home
and Windows 7 on the job

PeterX

  • Sr. Member
  • ****
  • Posts: 326
Re: What's wrong ?
« Reply #8 on: March 26, 2019, 10:37:47 am »
It may be that you have to call invalidate once. If the control behaves correctly then the first example should set Owner and Parent to be the same (the panel). Under windows, maybe a call to handleneeded (in the control code) if that is supported by Lazarus. (I am not sure).

I played around with this OpenGL example because a program I wrote,
under Lazarus 1.6, now does no more work, compiled with Lazarus 2.0

One issue is that an OpenGL object does not draw anymore.
Now I am sure OpenGL still works well, and I now have to find the errors in my code ..  :)
usually using latest Lazarus release version
with Windows 10 at home
and Windows 7 on the job

wp

  • Hero Member
  • *****
  • Posts: 6225
Re: What's wrong ?
« Reply #9 on: March 26, 2019, 10:39:45 am »
It may be that you have to call invalidate once. If the control behaves correctly then the first example should set Owner and Parent to be the same (the panel).
Under windows, maybe a call to handleneeded (in the control code) if that is supported by Lazarus. (I am not sure).
Thaddy, if I would talk such nonsense you would activate grumpy mode...

Owner and Parent are different things and they are not set simultaneously. When the Owner is destroyed all the components which have it as Parent are destroyed, too. Usually, the Owner is the form, but it also be a panel or so, but then you must be careful to set the component to nil when the panel is destroyed (because the component disappears with the panel, but the pointer to it still exists within the form).

The parent is the container which serves as a visual and organizational group. When the Parent is moved all contained components move along with it. When the panel is destroyed the contained components disappear from the screen since their parent now is nil. But it still exists within the form and can be made visible again by setting its parent to another valid container, e.g. the form.
Lazarus trunk / fpc 3.0.4 / all 32-bit on Win-10

Leledumbo

  • Hero Member
  • *****
  • Posts: 8108
  • Programming + Glam Metal + Tae Kwon Do = Me
Re: What's wrong ?
« Reply #10 on: March 26, 2019, 10:42:11 am »
I thought when virtual, there is nothing to inherit ???
Only virtual; abstract; has no body, virtual means it can be overriden by descendant classes, while the original (the one marked virtual) implementation can be called by using inherited.

Thaddy

  • Hero Member
  • *****
  • Posts: 8870
Re: What's wrong ?
« Reply #11 on: March 26, 2019, 11:54:47 am »
Thaddy, if I would talk such nonsense you would activate grumpy mode...
I know that, but component authors often mix them up.
Creating the component through its constructor with the right owner will also set the parent correctly in well written code.
This is exactly how the designer inserts controls in a parent control and it should not be necessary to set the parent.

This is NOT nonsense afaik. Changing the parent by setting the parent is another matter. That will not change the owner, but is usually not a good idea: owner gets free'd before parent... Boom.
« Last Edit: March 26, 2019, 11:56:37 am by Thaddy »
Most people that want to use threading should learn to patch their jeans first: use a needle.

wp

  • Hero Member
  • *****
  • Posts: 6225
Re: What's wrong ?
« Reply #12 on: March 26, 2019, 12:11:18 pm »
Creating the component through its constructor with the right owner will also set the parent correctly in well written code.
The attached demo shows that the control used as Owner in the constructor of a run-time created TEdit is NOT automatically used as Parent. The Parent must be set separately.
Lazarus trunk / fpc 3.0.4 / all 32-bit on Win-10

howardpc

  • Hero Member
  • *****
  • Posts: 3144
Re: What's wrong ?
« Reply #13 on: March 26, 2019, 04:34:37 pm »
Creating the component through its constructor with the right owner will also set the parent correctly in well written code.
This is exactly how the designer inserts controls in a parent control and it should not be necessary to set the parent.
This is nonsense, and irrelevant nonsense.
The OP's question was related not to how the Lazarus designer sets a Parent, but how controls such as TOpenGLControl and TOpenGLCube are parented when -- as here -- they are created in code. In the example only the Parents of the two panels have been set automatically by the Lazarus designer, and that is not the issue.

Creating a component with the right Owner is unrelated to setting its Parent. Hordes of components are non-visual and have no Parent. Even visual components descending from TControl that require a Parent for correct display should not routinely have their Parent set in their constructor (even if there are circumstances where that is an acceptable course of action). What about an on-the-fly control instantiated temporarily with a Nil Owner? You won't get very far equating its Parent with its Owner!
Set a control's Parent in its constructor if you must. But there is no requirement to do so, and this may be impossible if the Parent has not yet been created.
« Last Edit: March 26, 2019, 04:39:36 pm by howardpc »

PeterX

  • Sr. Member
  • ****
  • Posts: 326
Re: What's wrong ?
« Reply #14 on: March 26, 2019, 05:28:04 pm »
Beside this discussion ... Stop !


I found out that my own OpenGL component works again now
under Lazarus 2.0, with some changes and .. adding

Code: Pascal  [Select]
  1. AutoResizeViewport:= true;

On the other side, now OpenGL permanently fires "resize" events
(even though the object's size doesn't change ..)
and the .Resize function now is unusable ..

I'm not happy with that.
« Last Edit: March 26, 2019, 05:30:06 pm by PeterX »
usually using latest Lazarus release version
with Windows 10 at home
and Windows 7 on the job