Recent

Author Topic: I ported CNPacks "OpenGL Paintbox" to Lazarus, if anyone's interested...  (Read 7192 times)

Akira1364

  • Hero Member
  • *****
  • Posts: 543
I also converted the example demo and translated the Chinese captions to English the best I could (aka I ran them through Google translate and then fixed the grammar.) Both the package and the demo are in the 7Zip file I've attached, in two separate folders. You'll want to modify the build options for each to reflect your platform/CPU architecture, obviously.

I'm on 64-Bit Windows 10 here (win32 widgetset) and everything works perfectly for me, but it would be cool if users of other platforms could confirm that it works on them as well. 

EDIT: I guess there are a few Windows-specific types in the code as well, like HBITMAP, e.t.c... If you're on another platform feel free to reupload the file with the appropriate platform-specific defines/changes (I'm not sure what they would be, unfortunately.)

EDIT #2: Ok, it seems that for whatever reason Lazarus needs you to manually orient bitmaps before doing GL stuff with them, so I added a global procedure called CorrectLineOrder that you can/could call from your code as necessary. I thought this made more sense than making it something that was built into the PaintBox drawing procedures, as there may be circumstances where you DIDN'T want to flip a bitmap from its default orientation.

I've attached a 7z file with an updated copy of the main package source, as well as an updated copy of the demo application source that uses the bitmap flipping procedure.
« Last Edit: March 06, 2016, 11:21:58 pm by Akira1364 »

GetMem

  • Hero Member
  • *****
  • Posts: 4004
@Akira1364
Out of curiosity I did try the component. The compile/install was successful, but after rebuild Lazarus won't start. Here is the backtrace:
Quote

C:\Lazarus>gdb lazarus
GNU gdb (GDB) 7.2
Copyright (C) 2010 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "mingw32".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>...
Reading symbols from C:\Lazarus/lazarus.exe...d
one.
(gdb) run
Starting program: C:\Lazarus/lazarus.exe
[New Thread 5196.0x1188]

Program received signal SIGILL, Illegal instruction.
0x00becb94 in CNOPENGLPAINTBOX_$$_PREPARESINCOSCACHE$array_of_SINGLE$array_of_SI
NGLE$SINGLE$SINGLE ()
(gdb) bt
#0  0x00becb94 in CNOPENGLPAINTBOX_$$_PREPARESINCOSCACHE$array_of_SINGLE$array_o
f_SINGLE$SINGLE$SINGLE ()
#1  0x00bece68 in INIT$_$CNOPENGLPAINTBOX ()
#2  0x00411934 in fpc_initializeunits ()
#3  0x0040364d in main () at lazarus.pp:80
(gdb)

Lazarus trunk/FPC 3.0.0/Windows 7(32 bit)

Akira1364

  • Hero Member
  • *****
  • Posts: 543
PrepareSinCosCache is just a math function... not sure how it could prevent the IDE from starting. Weird!

Code: Pascal  [Select][+][-]
  1. procedure PrepareSinCosCache(var s, c: array of single; startAngle, stopAngle: single);
  2. var
  3.   i: integer;
  4.   d, alpha, beta: single;
  5. begin
  6.   stopAngle := stopAngle + 1E-5;
  7.   if High(s) > Low(s) then
  8.     d := PiDiv180 * (stopAngle - startAngle) / (High(s) - Low(s))
  9.   else
  10.     d := 0;
  11.   if High(s) - Low(s) < 1000 then
  12.   begin
  13.     alpha := 2 * Sqr(Sin(d * 0.5));
  14.     beta := Sin(d);
  15.     SinCos(startAngle * PiDiv180, s[Low(s)], c[Low(s)]);
  16.     for i := Low(s) to
  17.       High(s) - 1 do
  18.     begin
  19.       c[i + 1] := c[i] - alpha * c[i] - beta * s[i];
  20.       s[i + 1] := s[i] - alpha * s[i] + beta * c[i];
  21.     end;
  22.   end
  23.   else
  24.   begin
  25.     startAngle := startAngle * PiDiv180;
  26.     for i := Low(s) to High(s) do
  27.       SinCos((i - Low(s)) * d + startAngle, s[i], c[i]);
  28.   end;
  29. end;

Did you adjust the custom build options in the LPK like I mentioned? I had it set to -CfAVX2 -CpCOREAVX2 -FcUTF8 -g- -OpCOREAVX2 -Xs, which might not be suitable for everyone obviously, if you're not using a Haswell processor... If not, could that perhaps be the problem? Some internal math/bitness/archictecture thing in FPC?

Again, I'm on Windows 10 64-Bit... Lazarus trunk like you, but also FPC trunk, not 3.0.0.
« Last Edit: March 04, 2016, 11:50:24 pm by Akira1364 »

Leledumbo

  • Hero Member
  • *****
  • Posts: 8319
  • Programming + Glam Metal + Tae Kwon Do = Me
Did you adjust the custom build options in the LPK like I mentioned? I had it set to -CfAVX2 -CpCOREAVX2 -FcUTF8 -g- -OpCOREAVX2 -Xs, which might not be suitable for everyone obviously, if you're not using a Haswell processor... If not, could that perhaps be the problem? Some internal math/bitness/archictecture thing in FPC?
Those optimization flags will certainly generate instructions for respective capable processors. Better not force that for portability, then the code will work on every platform rather than only rather new Intel processors.

GetMem

  • Hero Member
  • *****
  • Posts: 4004
@Akira1364
After playing with the "custom options" and "config/target", I did manage to install the component and run the demo application. Works well(see screenshot)!
You fine tuned everything according to your hardware, in my opinion you should leave the defaults and let the user adjust the settings according to his/her needs.
To make it cross platform it would require a huge effort!

PS: Thanks for your effort and thanks for sharing!

marcov

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 9235
  • FPC developer.
Some remarks

  • the text option uses windows only font calls WGL* afaik. If you want text multiplatform you need to use some library or do it yourself like in the url below
  • Curve and arc and rotational/displacement etc options in comprehensive test segfault (win32)

The multiplatform text is in an application that is roughly a similar effort, but drawing the  (opengl canvas primitives using shaders).

which is a whole lot faster (in general more like several 1ms for the simple primitives, a bit more for circle and text), but less flexible (just the bare primitives, and much less options like linestyles, rotations and that kind of stuff, I use it to draw overlays over live camera images), and also has higher minimal requirements.

I tested text my way, (which could be interesting because more portable and without dependencies) and 25000 texts (450000 characters) takes about 50-100ms too the shader way. Probably because I need a whole lot of data to upload.
« Last Edit: March 05, 2016, 03:42:33 pm by marcov »

Akira1364

  • Hero Member
  • *****
  • Posts: 543
Yeah, as I edited my original post to say, I realized afterwards that the code contained some "Windows-only" function calls and types (which makes sense since CNPack is a Delphi component pack, and Delphi only runs on Windows.) Again, I'm not too familiar with Linux/Mac OpenGL usage, but I might "dive in" and see if I can get things going on those platforms. (Any help from a "native" user would be much appreciated!)

EDIT: One other thing... I just realized that the "Image" test displays the Bitmap upside down and mirrored. It displays correctly when running the original demo built with Delphi, however, with no functions significantly altered, just "used units" and some GL type names. Does this have something to do with the way Lazarus TBitmap.LoadFromFile works compared to Delphi TBitmap.LoadFromFile, perhaps? (Delphi 10 Seattle.)
« Last Edit: March 05, 2016, 05:17:34 pm by Akira1364 »

marcov

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 9235
  • FPC developer.
Yeah, as I edited my original post to say, I realized afterwards that the code contained some "Windows-only" function calls and types (which makes sense since CNPack is a Delphi component pack, and Delphi only runs on Windows.) Again, I'm not too familiar with Linux/Mac OpenGL usage, but I might "dive in" and see if I can get things going on those platforms. (Any help from a "native" user would be much appreciated!)

Well, the problem is that there is no direct substitute for wgl* functions. The common solution is to go for freetype, but this is afaik not very performant, and adds a dependency.

Signed distance fonts are an alternative.

Quote
EDIT: One other thing... I just realized that the "Image" test displays the Bitmap upside down and mirrored. It displays correctly when running the original demo built with Delphi, however, with no functions significantly altered, just "used units" and some GL type names. Does this have something to do with the way Lazarus TBitmap.LoadFromFile works compared to Delphi TBitmap.LoadFromFile, perhaps? (Delphi 10 Seattle.)

Or it might be the way you get the pointer to the bitmap data (getobject?). The image is bottom up on disk, so being in memory bottom up seems valid.

Akira1364

  • Hero Member
  • *****
  • Posts: 543
Or it might be the way you get the pointer to the bitmap data (getobject?). The image is bottom up on disk, so being in memory bottom up seems valid.

I'll look into that, thanks. I just wasn't sure if Lazarus's TBitmap.LoadFromFile possibly didn't perform some kind of reordering of bits that Delphi TBitmap.LoadFromFile maybe did. Not exactly "me" alone getting the pointer though, don't want to receive any undue credit for the (majority of) the code, haha... I just ported it, as I stated.
« Last Edit: March 06, 2016, 11:21:11 pm by Akira1364 »

 

TinyPortal © 2005-2018