raafal - a cross-platform 3d application framework project

Developed or developing a new product in PureBasic? Tell the world about it.
User avatar
idle
Always Here
Always Here
Posts: 5042
Joined: Fri Sep 21, 2007 5:52 am
Location: New Zealand

Re: raafal - a cross-platform 3d application framework proje

Post by idle »

grabiller wrote: The real issue we have here is that, in fact, by doing this, we loose the very beauty of PureBasic and its features. We loose all the integrated Events system, we loose all the Drawing features, etc.. And what is very frustrating is that PureBasic does not miss a lot of things to correct the situation.

In fact almost nothing: We just need either a hardware accelerated CanvasGadget or the possibility to have multiple resizeable WindowedScreens.

That's basically all we need, really, and we are set !
The glAreaGadget can be updated to provide a set of native pb events for both linux, windows and presumably osx
without to much effort

The remaining issue is how to integrate it with PB sprite lib to set the context so you can render to the surfaces
if that can be solved you should have what you need.
Which would give you the ability to use native Opengl and pb sprite functions
Windows 11, Manjaro, Raspberry Pi OS
Image
User avatar
grabiller
Enthusiast
Enthusiast
Posts: 309
Joined: Wed Jun 01, 2011 9:38 am
Location: France - 89220 Rogny-Les-Septs-Ecluses
Contact:

Re: raafal - a cross-platform 3d application framework proje

Post by grabiller »

The issue can be splitted in 3 parts:

1) Having a surface generating user Events.
2) Having a hardware accelerated surface onto we can blit images fast.
3) Having hardware accelerated 2D drawing functions.

For 1) & 2), I think it would be enough to either have a flag in the CanvasGadget to disable its automatic internal image handling/blitting - so it would not paint anything and we could set an OpenGL context on it - or subclass the CanvasGadget an shorcut the paint event to get the same result. This way it would not interfere with the OpenGL drawing but still return all the user events. I think this is much 'light' and simple than having to use something like glAreaGadget and at least we keep the PB Events integrated system. I will have to experiment with the second approach ( on Windows for now ).

For 3), actualy I'm not even sure the current PB 2D Drawing library use hardware acceleration when we draw (lines,boxes,..) onto a Sprite or an Image prior to blit those to the OpenGL hardware accelerated surface. Perhaps Fred can give some details here. In order to have full hardware acceleration I guess we would need to use something like OpenVG or Cairo, etc...
guy rabiller | radfac founder / ceo | raafal.org
User avatar
idle
Always Here
Always Here
Posts: 5042
Joined: Fri Sep 21, 2007 5:52 am
Location: New Zealand

Re: raafal - a cross-platform 3d application framework proje

Post by idle »

I don't think subclassing the canvas gadget would be a good solution right now
The event's aren't the problem, the current limitation is that you have to use native opengl since
you can't use the sprite lib drawing functions with manual gl contexts

so if we really want an accelerated canvas it's probably easier to write it ourselves
I don't see Fred or Freak delivering the functionality any time soon while they're busy bug hunting
but you never know!
I'd expect it would require changes to the sprite lib, 2d lib as well as the canvas gadget

If Fred could add the means to manually set the SpriteOutput it would at least facilitate
a means to utilize the current 2D functions onto sprites and use the sprite lib functions
that would at least address the main limitation

Using Cairo could be an option but it's probably more effective to implement accelerated 2D/3D
Drawing functions in opengl rather than adding more dependencies.
for windows and osx it would probably mean adding glib cairo & pango for text
On windows adding accelerated text is easy enough to do manually it has helper functions
but I don't think the same functions exist for linux OSX.

It's quite a bit of work when you stop and think about it.
Windows 11, Manjaro, Raspberry Pi OS
Image
User avatar
grabiller
Enthusiast
Enthusiast
Posts: 309
Joined: Wed Jun 01, 2011 9:38 am
Location: France - 89220 Rogny-Les-Septs-Ecluses
Contact:

Re: raafal - a cross-platform 3d application framework proje

Post by grabiller »

Well, if we really want to use the Sprite library - although only Fred knows the truth here - from an internal PB development point of view my guess is that implementing the possibility to have multiple/resizable WindowedScreen would require the least amount of work.
guy rabiller | radfac founder / ceo | raafal.org
User avatar
grabiller
Enthusiast
Enthusiast
Posts: 309
Joined: Wed Jun 01, 2011 9:38 am
Location: France - 89220 Rogny-Les-Septs-Ecluses
Contact:

Re: raafal - a cross-platform 3d application framework proje

Post by grabiller »

Hey Alexi,

Thanks for your kind words and yes, your Framework seems very interesting and efficient.

However, as mentioned in my first post, I intent to offer a free and open-source framework, so unless you intent to release your Framework free and open-source as well, I'm afraid it will be incompatible with what I'm trying to do.

I'm still hoping Fred will provide us with a solution to have either a hardware accelerated CanvasGadget or multiple, resizable WindowedScreen. If this happen then I'm set and I'll have everything I need (crossing fingers here).

With my current Canvas implementation, I don't get any flicker except with Window resizing, but no shame here, every 'professional' applications I've tested show the same issue. Yet its not really flickering it's the empty space discovered by larger size that is not covered immediately (and usually this kind of application is almost always used maximized anyway).

I don't have dockable panes in my implementation though. Yet :wink:

Cheers,
Guy.
guy rabiller | radfac founder / ceo | raafal.org
sec
Enthusiast
Enthusiast
Posts: 789
Joined: Sat Aug 09, 2003 3:13 am
Location: 90-61-92 // EU or ASIA
Contact:

Re: raafal - a cross-platform 3d application framework proje

Post by sec »

It does looks professional, i will use for sure.

Thanks much.
User avatar
zxtunes.com
Enthusiast
Enthusiast
Posts: 375
Joined: Wed Apr 23, 2008 7:51 am
Location: Saint-Petersburg, Russia
Contact:

Re: raafal - a cross-platform 3d application framework proje

Post by zxtunes.com »

Look fine.

On the blink when resizing I would not have paid attention. Because it really is today in all applications.

I've said nothing about what kind of slow interface such as Eclipse and yet it is used by Millions of people.

I like your project but at the same time, I have to say that the user experience for home-made interfaces are not very good.

When you launch the program and also thousands of unknown keys and do not even see the famous GUI ... it's scary.
User avatar
zxtunes.com
Enthusiast
Enthusiast
Posts: 375
Joined: Wed Apr 23, 2008 7:51 am
Location: Saint-Petersburg, Russia
Contact:

Re: raafal - a cross-platform 3d application framework proje

Post by zxtunes.com »

grabiller, you have any news?
User avatar
grabiller
Enthusiast
Enthusiast
Posts: 309
Joined: Wed Jun 01, 2011 9:38 am
Location: France - 89220 Rogny-Les-Septs-Ecluses
Contact:

Re: raafal - a cross-platform 3d application framework proje

Post by grabiller »

Hi,

Here are some news about raafal development.

I know raafal development is very slow, but as you may know, I'm doing it during my spare time and I would like - as much as possible - to make the right choices from the start and to keep things as simple and light as possible as well as as flexible and powerful as possible. This is not as simple as it sounds as I'm confronted to a lot of choices and possibilities. Yet I'm not really in a hurry, I prefer to take the time to do things properly. So far I've spent most of my time doing experiments and tests rather than actually coding raafal itself albeit the base of the framework is already in place.

That said, raafal will evolve more rapidly from now on as I've finally made final decisions about some key points of the framework:


1) OpenGL:

For a graphic oriented framework, hardware accelerated graphics is mandatory and PureBasic offers some options but not what's necessary to tackle professional applications. In fact, there is currently only one issue I've ranted a lot about already all over the forum but nothing changed so far on this matter: The ability to configure the OpenGL context creation, on all supported platform, so we can use Core OpenGL and its latest version where possible. I'm still puzzled why the OpenGLGadget does not offer such possibility but I've stopped asking myself why, it's like trying to discover the Meaning of Life and it drives me crazy.

To workaround this issue I've experimented and spent a lot of time with several known libraries, GLFW, FSML, SDL.. but I've stumbled on some very annoying issues especially regarding the "main loop" management, with interferences between PB one and the libraries one. Finally, and following the KISS principle (keep it simple..) I've gone back to the roots: using the PureBasic OpenGLGadget. To workaround the configuration issue, I'm now creating a custom OpenGL context that I "bind" to the OpenGLGadget window/view. Sound simple ? Well, as usual, it is dead simple *once you know how to do it* ! (especially in a cross-platform way). I've been stuck quite sometime on MacOSX with this, as I couldn't really find information about how to this with PureBasic.

Well, it is indeed dead simple once you know how to do it, here is the code for those interested:

Code: Select all

        ; ---[ Allocate Pixel Format Object ]---------------------------------
        Protected pfo.NSOpenGLPixelFormat = CocoaMessage( 0, 0, "NSOpenGLPixelFormat alloc" )
        ; ---[ Set Pixel Format Attributes ]----------------------------------
        Protected pfa.NSOpenGLPixelFormatAttribute
        With pfa
          \v[0] = #NSOpenGLPFAColorSize          : \v[1] = 24
          \v[2] = #NSOpenGLPFAAlphaSize          : \v[3] =  8
          \v[4] = #NSOpenGLPFAOpenGLProfile      : \v[5] = #NSOpenGLProfileVersion3_2Core ; will give 4.1 version (or more recent) if available
          \v[6] = #NSOpenGLPFADoubleBuffer
          \v[7] = #NSOpenGLPFAAcceleratedCompute ; I also want OpenCL available
          \v[8] = #Null
        EndWith
        ; ---[ Choose Pixel Format ]------------------------------------------
        CocoaMessage( 0, pfo, "initWithAttributes:", @pfa )
        ; ---[ Allocate OpenGL Context ]--------------------------------------
        Protected ctx.NSOpenGLContext = CocoaMessage( 0, 0, "NSOpenGLContext alloc" )
        ; ---[ Create OpenGL Context ]----------------------------------------
        CocoaMessage( 0, ctx, "initWithFormat:", pfo, "shareContext:", #Null )
        ; ---[ Associate Context With OpenGLGadget NSView ]-------------------
        CocoaMessage( 0, ctx, "setView:", GadgetID(oglcanvas_gadget) ) ; oglcanvas_gadget is your OpenGLGadget#
        ; ---[ Set Current Context ]------------------------------------------
        CocoaMessage( 0, ctx, "makeCurrentContext" )
        
        ; do your OpenGL drawing..
        
        ; ---[ Swap Buffers ]-------------------------------------------------
        ; CocoaMessage( 0, ctx, "flushBuffer" )
This code is extracted from the raafal code minus the error handling, it is supposed to be inside a Procedure (hence the use of "Protected").
For convenience in raafal, NSOpenGLPixelFormatAttribute is a hardcoded macro to a hardcoded fixed size structure..

Code: Select all

      ; ...[ array9_t ]......................................................
      Structure array9_t
        v.l[9]
      EndStructure
      ; ...[ NSOpenGLPixelFormatAttribute ]...................................
      Macro NSOpenGLPixelFormatAttribute
        array9_t
      EndMacro
      ; ...[ NSOpenGLPixelFormat ]............................................
      Macro NSOpenGLPixelFormat
        i
      EndMacro
      ; ...[ NSOpenGLContext ]................................................
      Macro NSOpenGLContext
        i
      EndMacro
As this issue is now solved, raafal GUI development is back on rails.


2) Scripting:

At first, I wanted to integrate the DAO scripting language into raafal. DAO was a very promising development, awesome language features, partly JIT accelerated. Unfortunately, its author decided to stop its development.. once I've been quite deep in integrating DAO with PureBasic.. So I've wasted a lot of time on this one, but the experience was very interesting. Finally I've decided to stick with a robust, well known and not soon to disappear scripting language :) I've narrowed down my choice to two options: Python and Lua (LuaJIT in fact). Python is the industry standard in the CGI industry, you can find it in Blender, Maya, Nuke, etc.. in almost every graphic application. But I don't like Python ;) It's slow and heavy, you need a specific installation, yet I don't like its ident formatting that can lead to catastrophic failures. I'm still puzzled why it became the industry standard but I don't want to think about it anymore (Meaning of Life syndrome again..).

KISS !! Again, keep it simple - yet powerful - enter LuaJIT. LuaJIT is too awesome to ignore. It is super light to embed, even as a static library with PB, and it is the fastest scripting language in the world, period. Plus with the recent development of Terra (terralang), a Lua extension using LLVM as a back end, you can envision some awesome developments and performances. So be it, raafal will use LuaJIT, case closed.

Except that I'm now confronted to a silly issue.. On x64 Mac OSX (again..), LuaJIT requires the application embedding it or using it to be compiled with the following linker flags:

Code: Select all

-pagezero_size 10000 -image_base 100000000
I've tried to use the linker option file from the PureBasic IDE, so far unsuccessfully (here is the thread link: http://www.purebasic.fr/english/viewtop ... 19&t=65866). If you can help on this one, you will be more than welcome !


There are other areas where choices have been made. On the data side and on the tasks side, but more on this in another post.

Thanks for your interest in this project,
Cheers,
Guy.
guy rabiller | radfac founder / ceo | raafal.org
DontTalkToMe
Enthusiast
Enthusiast
Posts: 334
Joined: Mon Feb 04, 2013 5:28 pm

Re: raafal - a cross-platform 3d application framework proje

Post by DontTalkToMe »

grabiller wrote:... I've ranted a lot about already all over the forum but nothing changed so far on this matter: The ability to configure the OpenGL context creation, on all supported platform, so we can use Core OpenGL and its latest version where possible. I'm still puzzled why the OpenGLGadget does not offer such possibility but I've stopped asking myself why, it's like trying to discover the Meaning of Life and it drives me crazy.
I agree :wink:
grabiller wrote: I'm now creating a custom OpenGL context that I "bind" to the OpenGLGadget window/view. Sound simple ?
That's interesting.
Just to see if I understood you, in Windows you create the OpenGLGadget , then the core 3.0+ context using API, then you do a

wglMakeCurrent_(hDC, hRC)

with hRC being your new RC, and hDC retrieved in some way from the existing ogl gadget (GetDC(something) ?)

And then you swap the buffer not with the #PB_OpenGL_FlipBuffers but SwapBuffers_(hDC) and still use all the mouse and keyboard events from the OpenGLGadget ?

Is this correct ? And is it enough ? Does it work ?

One thing lost using the OpenGLGadget() is the ability to have a fullscreen though (changing the current video mode), unless you have some idea for that too.
User avatar
grabiller
Enthusiast
Enthusiast
Posts: 309
Joined: Wed Jun 01, 2011 9:38 am
Location: France - 89220 Rogny-Les-Septs-Ecluses
Contact:

Re: raafal - a cross-platform 3d application framework proje

Post by grabiller »

DontTalkToMe wrote:../.. Just to see if I understood you, in Windows you create the OpenGLGadget , then the core 3.0+ context using API, then you do a
wglMakeCurrent_(hDC, hRC)
with hRC being your new RC, and hDC retrieved in some way from the existing ogl gadget (GetDC(something) ?)
And then you swap the buffer not with the #PB_OpenGL_FlipBuffers but SwapBuffers_(hDC) and still use all the mouse and keyboard events from the OpenGLGadget ?
Is this correct ? And is it enough ? Does it work ?../..
Yes this is exactly what I'm doing. So far it seems to work as expected.

A few years ago, I've tried to do that with the regular CanvasGadget, but unfortunately this gadget does behind the scene automatic drawing management and is interfering with custom context drawing. I've asked to add a flag to the CanvasGadget to disable automatic drawing management but never received a positive answer (actually I've never received any answer at all if I recall correctly ;) ). That would have solved the problem at that time, no need for an OpenGL Gadget then.

And this is why the situation is really ridiculous: We can know use the OpenGLGadget not because it is "OpenGL" but just because it does not do automatic drawing management so we can use our own OpenGL context (that we could have used years ago with the regular CanvasGadget if the flag had been implemented, and we wouldnt waste a useless context created by the OpenGLGadget).
DontTalkToMe wrote:../.. One thing lost using the OpenGLGadget() is the ability to have a fullscreen though (changing the current video mode), unless you have some idea for that too.
The tendency in the gaming industry is to consider switching video mode a bad practice. Nowadays game engines rather scale the graphics to cover the current user desktop resolution, Unity, Unreal, Godot, etc.. dont seem to have any problem doing that. It is a bit hard to understand why it would be really needed to actually change the desktop resolution, considering the current graphic cards power.

"fullscreen" is another matter, it simply means resizing the window so it cover the entire display and removing its decorations (like in a web browser when you go "fullscreen"). This is perfectly feasible through native API, and I think on OSX it is even automatic granted you can show the fullscreen button on the window (Wilbert showed how to do it in the Mac forum if I'm not mistaken).

What's certain is that raafal will never change the user desktop resolution, even for fullscreen views or applications.
guy rabiller | radfac founder / ceo | raafal.org
DontTalkToMe
Enthusiast
Enthusiast
Posts: 334
Joined: Mon Feb 04, 2013 5:28 pm

Re: raafal - a cross-platform 3d application framework proje

Post by DontTalkToMe »

grabiller wrote: Yes this is exactly what I'm doing. So far it seems to work as expected.
OK, thanks.

grabiller wrote: The tendency in the gaming industry is to consider switching video mode a bad practice. Nowadays game engines rather scale the graphics to cover the current user desktop resolution, Unity, Unreal, Godot, etc.. dont seem to have any problem doing that.
I'll take your word on that because I have no idea, but what I know is almost any game I play has an option to select the full screen resolution from a list of the supported ones, and it's not limited to the desktop resolution.

grabiller wrote: "fullscreen" is another matter, it simply means resizing the window so it cover the entire display and removing its decorations (like in a web browser when you go "fullscreen").
That one is a full screen mode exactly like the ones I'm talking about just above, the only difference is there is no mode switch, since you are using the current video mode (the one in which the desktop is).

According to the documentation PB should support that through #PB_Window_BorderLess, I don't know if it works reliably cross-platform.
User avatar
grabiller
Enthusiast
Enthusiast
Posts: 309
Joined: Wed Jun 01, 2011 9:38 am
Location: France - 89220 Rogny-Les-Septs-Ecluses
Contact:

Re: raafal - a cross-platform 3d application framework proje

Post by grabiller »

DontTalkToMe wrote:../.. According to the documentation PB should support that through #PB_Window_BorderLess, I don't know if it works reliably cross-platform.
Yes you are right but it is, afaik, a creation flag, which means if you want to switch from a windowed to a fullscreen mode then you have to destroy your current window and then creates a new borderless one, instead of doing that on the fly.

That said, destroying/creating new window is what some high-end applications are currently doing to switch from windowed to fullscreen mode, so I believe it is not a big issue after all.
guy rabiller | radfac founder / ceo | raafal.org
DontTalkToMe
Enthusiast
Enthusiast
Posts: 334
Joined: Mon Feb 04, 2013 5:28 pm

Re: raafal - a cross-platform 3d application framework proje

Post by DontTalkToMe »

grabiller wrote: Yes you are right but it is, afaik, a creation flag, which means if you want to switch from a windowed to a fullscreen mode then you have to destroy your current window and then creates a new borderless one, instead of doing that on the fly.
Yes good point, I didn't think of that when you said you were already doing that through api instead (if I understood you correctly).

Using OS api to remove decorations and resize the window shouldn't be a problem even cross platform. A problem may be there only when a mode switch is required, but you are not interested in doing that anyway so it's immaterial.

A mode switch is way more destructive and it's risky to implement that by also keeping the same RC and opengl state intact, since it may work on a platform but not on another. It's a luxury and it's better to not rely on that if it's possible, IMO.
User avatar
grabiller
Enthusiast
Enthusiast
Posts: 309
Joined: Wed Jun 01, 2011 9:38 am
Location: France - 89220 Rogny-Les-Septs-Ecluses
Contact:

Re: raafal - a cross-platform 3d application framework proje

Post by grabiller »

A word about data and tasks management in raafal.

Privately I've been asked several time: "../.. how will you handle data and tasks in raafal, you seem focused on gui and graphics only ../.."

Well, apparently I focus on gui and graphics because this is the most "exotic" part of raafal, by that I mean first in regard to PureBasic, how to properly handle OpenGL, the use or not of some external ui or drawing libraries, drawing custom controls and widget, handling system text input, etc.. and second because there are a lot of possibilities to experiment with, to provide something comfortable as well as innovative in order to support many kind of user interaction (office applications are good but clearly there is a need to provide better ui for many other specific uses that certainly dont need native ui looks..). GUI and graphics is clearly the area where most experimentations are done and where there is the most choices to make.

Handling data and tasks is more a "standard" domain, with well known approaches. These are areas where you better stick to something that work and is kind of "production proven" :)

raafal will handle data and tasks through two services: 'Cloud' and 'Storm'. raafal has several "services" which are entities that can be started, stopped, enabled/disabled, and added as plugins. The GUI part of raafal is a service, which means raafal will be able to start without a GUI, as a console application or even as a server. Nothing is clearly hardcoded in raafal. When raafal is launched a lot of decisions are taken depending on optional arguments, environment variables, user data/configuration, application data/configuration and even scripting of course (remember raafal is meant to create applications).


Cloud:
To give you an idea of how long I'm thinking about raafal, I've called the concept of handling data through a virtual file system 'Cloud' long before the word 'Cloud' hit the market and become a mainstream known word. I've been even tempted to rename it, but as the concepts are related, I've decided to keep it ;p

Cloud is the raafal service in charge of handling data storage and organization. It is a virtual file system loosely based on INode. Every data in raafal is a "node" with some metadata that is part of a hierarchical virtual file system. Some of those data are in-memory only, others are actually on file but some may be online through network, some data are tagged to be serialized some wont. Some are visible to the user some aren't. Etc.. But every node can be accessible through a standard path "/somefolderorcontainer/somefolderorcontainer/.../somenode". Some paths are hard-coded (like in a ROM), others are let at the liberty of the application creator, some may be freely handled by the user.

This is a very comfortable and intuitive approach. There is a tendency to use this approach in high end softwares (ie Houdini, Clarisse, etc..) and when you are used to this kind of system, when you go back to an application where you can't handle your data this way you feel a little lost because you don't have a clear vision of your data inside (or connected to) your application.

The alternative would be an Object Oriented approach (both can co-exist, in fact) where your Application is an Object and you get through some methods the other Objects from which you want to extract some data through other methods. This works, this is how works Softimage|XSI for instance, or Lightwave, etc.. and for some development tasks it may be more efficient, but from a user point of view, it is far more comfortable to present the data as a hierarchical file systems. With OOP you usually cant "dir" or "ls" on an Object to check its content, you have to know the API in advance. Through scripting, both approaches can be presented, actually. This is why in some application you get the concept of "Commands" which accept text path and input, aside the concept of OOP with Classes and Objects.

Internally though, even if raafal is extensively OOP through a custom (yet very simple) Class system, the data owned by Object are deferred to the Cloud service and referenced through it. This allow for easier global memory management (less fragmentation) and serialization. Of course, some data are procedurals and can be calculated on the fly through nodes that are actually callback instead of hard data.

The raafal Cloud service is not yet entirely implemented, but is well on its way.


Storm:
Storm is the raafal service that will handle multi-threaded tasks. Nowadays there is a tendency for concurrent programming where you create a procedure that will be automatically applied to a set of data, and this, of course, concurrently, meaning in a automatically multi-threaded managed way. This is good but personally I don't feel comfortable with this approach as it is hard to debug and you don't clearly control what's going on on the thread. Yet, doing that in PureBasic would certainly be challenging.

I prefer the well known concept of threads pool and tasks manager. The application knows the number of physical cores or virtual threads of its host computer so it can create the right number of threads in advance and dispatch the task with load-balancing in mind. This is simple and very efficient albeit not always easy to implement but it is clearly doable in PureBasic. The tricky part of this kind of tasks manager is the optional possibility to have lock-free queues where you insert/remove tasks from other threads without having to block any thread.

I have a Storm service with lock-free queues implemented in C in an earlier incarnation of raafal (in fact only Storm has been implemented in this version ;) ) in C that I did a long time ago. I'll have to check if I can easily port it to PureBasic as is but I suspect I will have to bind some as a static library compiled from C for the lock-free part.

So Storm is already working, but I have a lot of refactoring to do in order to integrate it inside the current incarnation of raafal in PureBasic.

I hope this will give you a better view of what is going on and of the inner parts of the raafal application framework.
guy rabiller | radfac founder / ceo | raafal.org
Post Reply