c-smile / sciter-sdk

Sciter is an embeddable HTML/CSS/scripting engine
http://sciter.com
Other
2.11k stars 223 forks source link

Sciter.Lite: Custom gfx layers/rendering backends #217

Open bugproof opened 2 years ago

bugproof commented 2 years ago

Wanted to try sciter-lite in a game using vulkan but this backend is not supported

https://github.com/c-smile/sciter-sdk/blob/264ea65254d289fa62479d5c705ed73c07d12370/include/sciter-x-types.h#L32-L40

Is there any api that returns vertices and other stuff to draw?

Currently I'm using RmlUi and it's very good you can implement your own RenderInterface SystemInterface and even font engine. I'm probably staying with RmlUi but it would be interesting to integrate sciter and compare these 2 as sciter seems to support more CSS features

One option would be to create an overlay window and do the rendering there but this way it wouldn't be possible to integrate it more tightly with the game's rendering system e.g. draw 3d models on top of sciter UI

pravic commented 2 years ago

https://github.com/c-smile/sciter-js-sdk/tree/next Sciter.JS supports Vulkan. It's an early build (hence an alternative branch), but eventually it will come: https://sciter.com/vulkan-metal-dx12/, https://sciter.com/sciter-on-linux-with-vulkan/.

bugproof commented 2 years ago

It it possible to add custom elements though? Like I would like to add element for rendering models <modelrenderer src="mymodel.3ds" /> and add my rendering code in vulkan.

Also, is it possible to implement custom file interface so it could read custom texture formats from game archives without unpacking the files? This is possible in RmlUi and wonder if you could do the same with Sciter.Lite.

pravic commented 2 years ago

You don't need Sciter.Lite for that.

Like I would like to add element for rendering models

Where does your Vulkan requirement come from? Is your entire app in Vulkan or just your model renderer?

Create a regular Sciter app, add UI and everything. Implement your renderer using Vulkan and connect it via CSS via something like

modelrenderer { display: block; size: *; behavior: your-vulkan-renderer; }

Render your stuff using Vulkan and pass it to Sciter as a DirectX texture (I am assuming you're on Windows). Also Sciter UI can be rendered on top of (or in the background of) a 3D scene, so again - you don't need Sciter.Lite for that.

Sciter.Lite is used when the entire app is written without windows/widgets thus doesn't have or doesn't use standard keyboard/mouse input. Or other extreme cases when you need to render your UI as a single bitmap and pass it somewhere to display.

pravic commented 2 years ago

Also, is it possible to implement custom file interface so it could read custom texture formats from game archives without unpacking the files?

Of course, see the corresponding notifications: https://github.com/c-smile/sciter-sdk/blob/9f1724a45f5a53c4d513b02ed01cdbdab08fa0e5/include/sciter-x-host-callback.h#L129

pravic commented 2 years ago

One option would be to create an overlay window and do the rendering there but this way it wouldn't be possible to integrate it more tightly with the game's rendering system e.g. draw 3d models on top of sciter UI

Check these demos: sciter-dx and sciter-opengl in https://github.com/c-smile/sciter-sdk/tree/master/demos.win/ You'll get the idea of possible approaches.

bugproof commented 2 years ago

You don't need Sciter.Lite for that. Where does your Vulkan requirement come from? Is your entire app in Vulkan or just your model renderer?

The game uses vulkan for rendering everything. I actually need Sciter.Lite because I need windowless sciter, I'm using SDL2 for all window related stuff.

Create a regular Sciter app, add UI and everything. Implement your renderer using Vulkan and connect it via CSS via something like

modelrenderer { display: block; size: *; behavior: your-vulkan-renderer; }

It's not very clear to me. What behavior actually is and how can I implement a behaviour that draws my 3d models using vulkan instance? It's not very obvious.

Render your stuff using Vulkan and pass it to Sciter as a DirectX texture (I am assuming you're on Windows). Also Sciter UI can be rendered on top of (or in the background of) a 3D scene, so again - you don't need Sciter.Lite for that.

I want it to be rendered on top of a 3D scene but I also want a control over the rendering process so I can also render 3d stuff on top of Sciter. For example let's say I wanted to implement an inventory and display actual 3d models of items in the inventory. It seems like Sciter doesn't give you any option to control the rendering process.

It also seems like there's no way to add handlers for custom image formats so I could do stuff like <img src="myimage.tex"/> where .tex is a custom texture format.

pravic commented 2 years ago

I actually need Sciter.Lite because I need windowless sciter, I'm using SDL2 for all window related stuff.

Okay, fair enough.

What behavior actually is and how can I implement a behaviour that draws my 3d models using vulkan instance?

For example, especially in the end of the file: https://github.com/c-smile/sciter-sdk/blob/master/include/behaviors/behavior_drawing-opengl.cpp

pravic commented 2 years ago

It also seems like there's no way to add handlers for custom image formats so I could do stuff like where .tex is a custom texture format.

Well, there are two approaches. The first is to use custom loaders to feed Sciter with known resources (HTML/CSS/images). For example, if converting your "image.tex" to a PNG or similar is achievable, just do it on the fly in a custom loader.

Another way is to create or generate an Image and bind it as an in-memory image.

pravic commented 2 years ago

I want it to be rendered on top of a 3D scene but I also want a control over the rendering process so I can also render 3d stuff on top of Sciter. For example let's say I wanted to implement an inventory and display actual 3d models of items in the inventory. It seems like Sciter doesn't give you any option to control the rendering process.

I guess, it's feasible. Render your scene, render Sciter as UI on top of the scene, but your inventory can be displayed as a table of icons where an icon is your "actual 3d models of items in the inventory" - or your inventory can be just a part of the scene, and Sciter is just for UI. It depends.

c-smile commented 2 years ago

I want it to be rendered on top of a 3D scene but I also want a control over the rendering process so I can also render 3d stuff on top of Sciter. For example let's say I wanted to implement an inventory and display actual 3d models of items in the inventory. It seems like Sciter doesn't give you any option to control the rendering process.

You can do that by using layered painting:

layers

And explanation.

Here we have back layer (HTML element with content) and fore layer (HTML element - that sidebar) and 3D rendering sandwiched between them.

Let's assume that your document looks like this:

<style>
   body { flow:stack; }
   body > section { size:*; /*spans whole body*/ }
</style>
<body >
    <section id="back-layer"> ... </section>
    <!-- your 3D stuff will go visually  here -->
    <section id="fore-layer"> ... </section>
</body >

Note: we have there two layer elements - back and fore.

Then in order to render such sandwich we can use following drawing code:

{
      // draw background layer if needed
     SCITER_X_MSG_PAINT pc(back_layer, FALSE);
     SciterProcX(handle, pc);
 }

  draw_3d();

 {
    // draw foreground layer on top of 3d
     SCITER_X_MSG_PAINT pc(fore_layer, TRUE);
    SciterProcX(handle, pc);
}

where back/fore_layer are sciter::dom::element's set to section id="back-layer" and section id="fore-layer"

c-smile commented 2 years ago

As of native support of Vulkan in Sciter...

Sciter version 5.X.X.X will be able to run on Vulkan natively. Note that mainstream Sciter is SciterJS: https://github.com/c-smile/sciter-js-sdk and 5.X.X.X is derived from it.

In SciterJS SDK 5.0.0.0 the list of backends looks like this:

enum GFX_LAYER
  {
    GFX_LAYER_GDI = 1, GFX_LAYER_CG = 1, /*Mac OS*/ GFX_LAYER_CAIRO = 1, /*GTK*/
#ifdef WINDOWS
    GFX_LAYER_WARP = 2, GFX_LAYER_D2D_WARP = GFX_LAYER_WARP,
    GFX_LAYER_D2D = 3,
#endif
    GFX_LAYER_SKIA = 4,
    GFX_LAYER_SKIA_RASTER = GFX_LAYER_SKIA,
    GFX_LAYER_SKIA_OPENGL = 5,
    GFX_LAYER_SKIA_VULKAN = 6,
#ifdef OSX
    GFX_LAYER_SKIA_METAL = 7,
#endif
#ifdef WINDOWS
    GFX_LAYER_SKIA_DX12 = 8,
#endif
    GFX_LAYER_AUTO = 0xFFFF,
  };