14 engine improvements from June/July — window sizing docs, TCastleAbstractPrimitive and TCastleImageTransform extensions, cubemaps and 3D textures in all texture slots, VS Code integration improved, rendering optimizations…

Posted on

Window with castle model
Cubes test
Cubes test

Presenting a big batch of engine improvements done last ~month. Lots of small things. Everyone, pick what you like ๐Ÿ™‚ Upgrade to the latest engine version and enjoy them all!

If you like what you see, we appreciate your support on Patreon (we also have other ways to donate).

  1. We added a new documentation page Window size and fullscreen. Nicely explains how to change window size, fullscreen mode, anti-aliasing, and even (not recommended, we explain why) the OS-wide screen resolution.

    This is also linked from the new projects’ gameinitialize.pas template code. Previous template placed there a long comment — now it’s just a short concise comment with a link to the above page.

  2. Added TCastleAbstractPrimitive.TextureScale property, useful to easily scale the texture (in descendants like TCastlePlane, TCastleBox).

  3. TCastleImageTransform has new properties to make it lit and configure other options: TCastleImageTransform.Material, TCastleImageTransform.UrlNormalMap, TCastleImageTransform.RenderOptions. Details:

    • Material, can be pmPhysical or pmPhong or (as default, backward-compatible) pmUnlit.

    • UrlNormalMap allows to specify a normal map (for bump mapping).

    • RenderOptions allow to specify some rendering details. E.g. adjust bump mapping algorithm by RenderOptions.BumpMapping is useful.

    See this forum thread that caused these improvements and contains some testcases.

    And yes, we are fully aware that TCastleImageTransform and TCastlePlane features bring them closer and closer to each other. They both can display a textured rectangle in 3D or 2D, be lit or unlit, support various display options. For now, we think it makes sense to have both components, as they start from a different approach to sizing — it’s whether “image size determines the geometry size” (TCastleImageTransform) or “image is just an optional decoration, and never affects the geometry size” (TCastlePlane). It seems combining all their features would result in a complicated API… but we will keep an eye on this.

  4. We have enabled using cubemaps and 3D textures (nodes like TImageTexture3D, ImageCubeMapTexture) to be used in any material “texture slot”. For example, they can be used to define a TPhysicalMaterialNode.EmissiveTexture, TMaterialNode.SpecularTexture and more now.

    Previously, some of the material texture slots supported only 2D textures and the 3D / cubemaps were allowed only in the “main” slot (which was: TPhysicalMaterialNode.BaseTexture, TMaterialNode.DiffuseTexture, TUnlitMaterialNode.EmissiveTexture). This limitation no longer exists, all material slots allow 3D and cubemaps.

    Note: There is still some special code for the “main” slots, so e.g. ShaderTexture is still not supported in all slots. With time, we want to get rid of all such constraints, feel welcome to submit issues / ping us about it.

    See this issue for sample testcase.

  5. We allow customizing the proposed_unit_prefix in project settings. This makes sense if you don’t want your unit names to start with Game (e.g. because you’re not making a game).

  6. We have improved physics interaction with TCastleTransformReference. We warn when collider / bodies are inside. We calculate bounding box properly when collider is at TCastleTransformReference.

    See this forum thread for some notes and tests that caused this.

  7. Our pasls (used for the code completion by our VS Code extension) has been improved:

  8. I spend some time with Valgrind optimizing a few engine low-level operations. This was fruitful. Per-frame work (rendering) is in one testcase now 0.579 fraction of the old one (so it’s almost ~2x faster).

    For this work, I used the “many cubes” testcase on GitHub – michaliskambi/many-cubes which followed from the “Drawing Many Cubes Faster” forum thread.

    The gains do not translate to all possible applications that easily, so don’t expect a 2x FPS increase in your applications now… but maybe you will notice some speedup ๐Ÿ™‚ So give new engine a try, let us know (e.g. in the forum thread) about your tests and speed. You’re also welcome to provide us “testcases to optimize” (though try to keep them real-life, not contrived :). This helps, when I can just run profiler on some something concrete, and advise what to adjust (in your code and/or in the engine).

  9. Moving / resizing window (TCastleWindow) on WinAPI is now fixed to be smooth.

    For details what we do, what was wrong, and how we fixed it see this GitHub issue.

  10. We have internally a nice WinAPI messages debugging feature. Compile with CASTLE_DEBUG_WINAPI_MESSAGES symbol defined.

  11. We had to bump requirements of our Raspberry Pi 32-bit (Arm) builds. They require now Bookworm OS version. This matches now builds on all other systems (Linux on regular x86_64, and Raspberry Pi 64-bit (Aarch64)).

    Before 2025-06-13, we provided binaries for 32-bit Raspberry Pi (Arm CPU) in a version compatible with older GLIBC, including the one in Debian’s bullseye (to support older Raspberry Pi 4 32-bit installations). However, this gets hard, as DietPi removed some old images which we relied on, by this GHA action. We migrated to use official images from raspberrypi.org.

  12. We expose now TX3DNode.WaitForRelease and NodeRelease, simpler and with more obvious names alternatives to TX3DNode.KeepExistingBegin, TX3DNode.KeepExistingEnd, FreeIfUnusedAndNil.

  13. Fixes to castle-editor-portable editing 2D game template with Spine, and more general: DataDirectoryInformation and ApplicationDataOverride interaction fixed.

  14. To improve the comfort of cloning from GIT the engine, we now limit our paths to 130 (previously, our longest path reached 165). This decreases changes you will run into trouble on Windows, with Windows long paths or GIT on Windows long paths disabled.

    See resources like How To Fix โ€˜Filename too longโ€™ Errors in Git on Windows for details, linked also from our compiling from sources. These problems can be avoided by better Windows and GIT configuration, but it’s not default, so we improved the engine to minimize the chances you run into this.

Comments on the forum โžค

More scenes are shadow casters for shadow volumes out-of-the-box, because of the auto-detection of 2-manifold scenes

Posted on

Demo from Delphi Summit 2025, with shadows
Demo from Delphi Summit 2025, with shadows
Alpaca, bull, shadows and WholeSceneManifold
Throwing chickens demo

(Yes, it’s a 3rd news about Castle Game Engine in 3 days. More to come — we have a backlog of things to announce! Brace yourselves ๐Ÿ™‚ )

We introduced an algorithm to detect 2-manifold scenes better, meaning that all scenes that are really 2-manifold (even if not all shapes inside are 2-manifold) are automatically shadow casters for shadow volumes.

This improves shadow volumes usage experience. You no longer have to mark such scenes with TCastleRenderOptions.WholeSceneManifold.

OK, I can see that the above description, while correct, may be confusing if you’re not familiar with how shadow volumes work. Let’s unpack this slowly ๐Ÿ™‚

  • Shadow volumes is one of the algorithms to achieve shadows using Castle Game Engine. It’s right now the simplest one to use, you only need to have 2-manifold models and then flip the Shadows checkbox at the light source to true.
    • Note: The “simplest shadows algorithm to use” award will likely change to shadow maps in the future, once we implement a few improvements to it. See also recent news post about shadow maps plans.

    • But even then, both algorithms (shadow volumes and shadow maps) will remain useful and available and in our engine. They both have their advantages and disadvantages (how shadows look, performance and possible optimizations, what is valid shadow caster…).

  • For shadow volumes, only 3D objects that are 2-manifold can cast shadows. 2-manifold means that each edge has 2 neighbor faces. This is the most natural state for 3D models that represent real things, that have a volume and are watertight, though in practice many 3D models have only most edges with 2 neighbors. The shadow volumes algorithm strictly requires that all the edges of things that cast shadows have 2 neighbors.

  • We allowed already 2 ways to cope with 2-manifold requirement: either make all shapes 2-manifold, or use TCastleRenderOptions.WholeSceneManifold to treat whole scene (unchecked) as 2-manifold.

    • BTW, what is a “shape”? Shape is part of the scene, the simplest unit passed to the GPU.
      • In glTF, it’s a primitive.
      • n Blender, it’s a subset of Blender’s object with a single material.
      • In X3D, it’s literally the X3D Shape node, loaded to TShapeNode instance in our engine.

The new improvements means that you don’t need to touch TCastleRenderOptions.WholeSceneManifold if the scene is already 2-manifold.

Now, using the TCastleRenderOptions.WholeSceneManifold is only necessary if:

  • You want to force the scene to be shadow caster for shadow volumes, even if it was not detected as 2-manifold, Beware that rendering artifacts are possible in this case. However, we did find a number of cases when this forcing actually works properly (at least for the camera position/orientations that mattered in a given demo), despite scene not being a correct 2-manifold.

  • Or if you just want to speed up loading. Marking scene as TCastleRenderOptions.WholeSceneManifold avoids any automatic detection, the appropriate check “passes automatically”.

We took care to check that this auto-detection doesn’t cause any issues:

  • We checked it doesn’t cause unnecessary slowdown. We time it, showing in log if it would take more time > 0.01 sec (it never did in our tests).

  • We checked it doesn’t cause problems due to per-shape TCastleScene.DistanceCulling being disabled on scenes that are 2-manifold, but when shapes are not 2-manifold. The per-shape TCastleScene.DistanceCulling check is now really only done when shadow volumes are used, and scene is shadow caster, and whole scene is 2-manifold (but some shapes are not 2-manifold).

We have updated example on examples/viewport_and_scenes/shadow_volumes_whole_scene_manifold, along with README description and screenshots inside. Part of this demo now works “out of the box”, alpaca model is automatically a shadow caster.

We also updated documentation about shadow volumes. Many things have been upgraded, and naturally the section about 2-manifold objects (when they are detected, and when is RenderOptions.WholeSceneManifold useful) has been rewritten to reflect the current state.

We also updated the Castle Model Viewer menu “Help -> 2-Manifold Information (Shadow Volumes Casting)”. New colors of edges:

  • yellow: manifold edges in the same shape, so this edge connects 2 faces within the same shape.
  • white: manifold edges in the whole scene, so this edge connects 2 faces from different shapes.
  • blue: border edge that doesn’t have 2 face neighbors. If you have this, this scene cannot be (reliably) a shadow caster for shadow volumes, because it is not 2-manifold.

Testing shows that this detection makes sense in many cases (and avoids you having to toggle dangerous TCastleRenderOptions.WholeSceneManifold) but also it fails in many cases (so TCastleRenderOptions.WholeSceneManifold still has a use-case, there are often no noticeable artifacts despite model not being 2-manifold).

All in all, testing shows it’s a benefit, and doesn’t have any drawbacks ๐Ÿ™‚

Sadly, it doesn’t mean we can get rid of TCastleRenderOptions.WholeSceneManifold (it would be nice to get rid of this dangerous checkbox, but it still makes sense).

Test it on your own projects and let us know (e.g. in the comments on the forum) how it works for you!

And if you like this work, please support us on Patreon. Thank you!

Comments on the forum (1) โžค

Register for the upcoming Pascal Conference in Germany (Early Bird price until 31.07)

Posted on

Walking around Sundern

I will be at the Pascal Conference 2025 in Germany, in September this year. And you can be there too ๐Ÿ™‚

The schedule has been announced on the conference site. A number of great people, influential in both FPC and Delphi development, will be giving talks, so this is going to be very interesting.

I will also be presenting. On Friday I will talk about a real use-case of our IFC integration for Sorpetaler window construction. And on Thursday, we will have plenty of time to discuss everything about Castle Game Engine during the Expert Q&A session!

The conference takes place in Sundern (Sauerland), Germany. I’ve actually been there twice already, and it’s quite a beautiful place. Let me attach a nice real photo (from my walk there about 2 months ago) to this post, instead of the typical screenshot from some 3D rendering you usually see on this blog ๐Ÿ™‚

The dates are September 18th to 21st, 2025. The first 2 days feature English talks. There’s an early bird price for attending (see details) available until the end of July, so I advise you to book your tickets now ๐Ÿ™‚

See you there!

Comments on the forum โžค

Delphi advancements: groundwork for more platforms (Android, macOS, iOS), Castle Model Viewer + Delphi, cli Delphi tools on macOS, fixes for C++ Builder, Delphi 64-bit IDE

Posted on

Castle Game Engine on FMX form
Delphi application on macOS using Castle Game Engine

We have a few treats for Delphi users in this post:

  1. Base engine units (but not yet rendering!) are now compatible with more Delphi platforms. To opens the door to make our engine compatible with more platforms with Delphi.

    This means we have a “groundwork” to add support for more targets with Delphi:

    • Android (tested both “Android 64-bit” and “Android 32-bit” now)
    • macOS (tested both “macOS 64-bit” and “macOS ARM 64-bit”)
    • iOS (tested both “iOS Device 64-bit” and _”iOS Simulator 64-bit”)
    • To remind: above platforms are in addition to already-supported platforms with Delphi, which are Windows and Linux. And this is in addition to all platforms (all desktops, Android, iOS, and web, and Nintendo Switch) supported with FPC.

    This “groundwork” means that base units compile for the aforementioned platforms. If you try compiling a full game, it will compile until the ContextCreateBestInstance compilation with message Define how to create OpenGL context for this platform.. This is OK, this means that basic units compiled OK.

    We have initial documentation about Delphi + macOS, Android, iOS here.

  2. The above “groundwork” already achieves something useful: you can write various 3D and 2D processing tools with the engine on the new platforms. For example, command-line applications, or regular FMX applications that invoke our engine to do some processing (just not using yet our engine for display).

    An example is in scene_information_cli_tool in our examples. See the screenshot on the side of this post — built by Delphi, working as a command-line tool on macOS.

  3. Castle Model Viewer (source code here on GitHub) compiles now with Delphi (as well as FPC). This improves our ability to test everything, we like to have every part of our engine working with both FPC and Delphi.

  4. Thanks to Adrian Gallero, our Delphi design-time packages install our “Tools โ†’ Castle Game Engine” menu also in 64-bit Delphi IDE version.

  5. Finally, since we’re on topic of Delphi, let’s add that we also fixed compilation of the latest code with C++ Builder. We had accumulated 2 small bugs since the last time we checked it, see this GH issue. All good now. Thank you Zatupitel for reporting!

Comments on the forum โžค

Support for new Tangent node in X3D, with vectors as 4D, better aligned with glTF

Posted on

Bump mapping with explicit tangent vectors. See https://github.com/castle-engine/demo-models/tree/master/gltf/tangents for info and credits.
Bump mapping with explicit tangent vectors. See https://github.com/castle-engine/demo-models/tree/master/gltf/tangents for info and credits.
Bump mapping with explicit tangent vectors. See https://github.com/castle-engine/demo-models/tree/master/gltf/tangents for info and credits.
Tangent vectors test from Khronos sample assets

The short version of this post, if you don’t want to go into technical details, is that one aspect of using bump mapping is now better in Castle Game Engine. Our data transfer and logic is more efficient and more aligned with glTF and latest X3D specifications.

And if you still don’t want to go into technical details, you can clone our demo-models repository and open the models in subdirectory bump_mapping/tangents/. There are 3 models there, and they are all available in both glTF and X3D model formats (scene.gltf, scene.x3d). Open them using the latest Castle Model Viewer snapshot (5.3.0) and they should work equally well and pretty.

You can also clone glTF-Sample-Assets and open the testcase NormalTangentMirrorTest there and observe that we handle it correctly (well, as much as we can without environment lighting).

You can also watch our old video about using normalmaps with Blender and Castle Game Engine. When using normal maps, you do bump mapping and then exporting your models with tangent vectors makes sense. It’s literally one checkbox when doing Blender->glTF export.

An if you’re still reading, time’s out! Now I assume you want to go into technical details ๐Ÿ™‚ So what are tangents and what’s going on?

  • To make bump mapping look good, the 3D models may provide explicit information about the tangent vectors at the surface.

  • Our proposal of Tangent node contains a good explanation what tangent vectors are and why do we recommend to provide them in 3D models (if you use bump mapping). In short, tangent vectors, along with normal vectors, define the tangent coordinate space in which the values of the normal map are provided. Whatever process you use to create normal maps (most of you bake normal maps), it’s best to provide to the rendering engine the same tangent vectors as have been assumed when creating the normal map. In other words, simplifying, it’s best if Blender calculates tangent vectors, and uses the same tangent vectors for normalmap baking and passes the same vectors to glTF.

  • glTF standard defines how to store tangent vectors, Blender->glTF exporter can generate them, and we read the information from glTF, and convert it into X3D Tangent node.

  • We already had Tangent node in our engine for some time, but with a definition that had a small simplification: I defined the vectors there as 3D, right-handed. In contrast, glTF defines them as 4D, with XYZ designating direction, and W designating the handedness. We think the glTF idea is quite smart and useful ๐Ÿ™‚

  • We have recently recommended to add Tangent node to the X3D spec, the proposal is here. While adding to X3D, we also proposed to add them in a version more aligned with glTF, so 4D.

  • Of note is that X_ITE, another cool open-source X3D viewer, also has compatible Tangent node. With 4D, matching also glTF. So after this, we’re all better aligned.

  • The new X3D prose about Tangent node is here.

  • And to close the circle, the Castle Game Engine has now adopted this Tangent node specification with 4D vectors. This means we display X3D models with the new Tangent node, and when reading glTF we convert the glTF -> X3D information in the trivial way (glTF 4D tangents -> X3D 4D tangents).

Does anyone still follow? ๐Ÿ™‚ Hopefully above was a good summary and link to hopefully useful resources.

If you like what we do, in Castle Game Engine but also around standardization efforts like X3D, we always appreciate your donations. Thank you!

Comments on the forum โžค

URL improvements: castle-config:/ protocol, use UriExists and FindFiles on any URL (including e.g. zip), TCastleMemoryFileSystem

Posted on

Scene inspired by Metal Gear Solid from Sketchfab https://sketchfab.com/3d-models/chibi-gear-solid-a4ca0e3864e143af9bf1dffc7fc8029b

We present a number of improvements to our URL system, which is the basis for all engine resource loading and saving:

  1. We introduced castle-config:/ URL protocol, to save files in a system-specific place (directory) that is “persistent” for given user.
    • It points to a specific directory that is by convention writeable and should be used to save user data. For example, something like C:/Users/<username>/AppData/Local/<application_name>/ on Windows or /home/<username>/.config/<application_name>/ on Linux and FreeBSD. We follow system-specific conventions and APIs.
    • This replaces previous ApplicationConfig routine.
    • It is consistent with castle-data:/ which is read-only location with your application data.
  2. We added TCastleMemoryFileSystem – useful to create a temporary filesystem, living only in memory, registered at given URL.

    It is, for now, our implementation of castle-config:/ on the web — so the data is not persistent if you reload the page, but at least it makes sense within a single session. This made our portable editor possible. Of course it is a TODO to actually persist the data using WWW browser mechanisms.

    That said, TCastleMemoryFileSystem may be useful for your own purposes too, if you want a temporary virtual filesystem in your application.

  3. RegisterUrlProtocol exposes now a class that allows to configure URL behavior. (So we can extend the functionality offered by custom URLs, aka virtual file systems, without adding more and more parameters to RegisterUrlProtocol.)

  4. Many built-in URLs, and URLs pointing to ZIP (using TCastleZip), and URLs pointing to TCastleMemoryFileSystem, use above, so their resources can be tested using UriExists and searched using FindFiles.

  5. Queries like UriExists('castle-data:/my_texture.png') on the web are also useful now, as we use castle-data:/auto_generated/CastleDataInformation.xml to test data files existence.

What’s the image shown at this news post? Chibi Gear Solid by glenatron on Sketchfab, cool 3D scene rendered using our Castle Model Viewer. It has no relation to this news post (except that’s it’s rendered using our engine and you can download it too and turn into a game right now!), just something pretty I wanted to show ๐Ÿ™‚

Comments on the forum (4) โžค

Slides and example from Delphi Day 2025 presentation and after-thoughts (Afterwarp, shadow maps, BGFX and deferred rendering)

Posted on

Throw chickens

I’m traveling back home after enjoying Delphi Day 2025 in Piacenza.

  1. I think I’ve made a nice presentation about the engine features.

    Slides are available here and one new (simple and fun ๐Ÿ™‚ ) example is part of the engine now: examples/physics/physics_throw_chickens.

    During the talk, I also showed a number of existing projects, including platformer, fps_game, complete FPS game using Blender, Sketchfab, Quaternius models, TCastleMoveAttack (shown first at Zlot 2024).

  2. I also watched a number of inspiring presentations from fellow Delphi users. It was really good to see so much activity around Delphi and Pascal!

  3. One talk that in particular remains in my memory was about the Afterwarp Framework by Yuriy Kotsarenko. I was truly amazed by some features he shown, in particular the deferred shading implementation combined with shadow maps that allows to have 65k dynamic light sources casting shadows (and he showed demos really proving it — one demo with really ridiculous 65k dynamic lights, one demo with over a thousand lights casting shadows and car with headlights moving through them). Really impressive, and it makes me jealous, and I told him about it ๐Ÿ™‚

    To make it happen, deferred rendering is the key (in contrast to the current CGE forward rendering). I was looking into this in the past… but there was never enough time to “attack” it, as it’s a bigger task.

    Edit 1: My intention here is not “let’s just switch to deferred rendering”. The cited Wikipedia page about deferred rendering already mentions disadvantages of this approach, and Afterwarp that inspired me is actually using a hybrid approach (“uses a hybrid forward, deferred rendering using clustered shading”). My intention here is to explore our options for lots of dynamic lights and shadows in the engine, and I note 2 things: 1. it’s high time to focus on shadow maps, as I already wrote in roadmap (see more below) and 2. I want to experiment with deferred rendering.

    Edit 2:: Originally I wrote here that our optimal path to deferred rendering may be to speedup BGFX renderer integration, as BGFX will give us deferred rendering, and we want to have BGFX as alternative renderer anyway. However, while BGFX indeed allows for deferred rendering, it’s a manual approach (not a simple toggle “forward / deferred rendering”). So: 1. we still want to have BGFX!, 2. but it’s independent from deferred rendering, as we can introduce deferred rendering either on top of BGFX or CGE current renderer, with ~similar work.

  4. I had a few “nudges” recently to focus more on our shadow maps as a preferred shadows algorithm, and maybe leave the shadow volumes as… maintained, but not default.

    To explain more:

    • In the current engine version, shadow volumes are more comfortable to setup (just click 1 checkbox, if only your models are 2-manifold), while we have a few TODOs to make shadow maps comfortable.

    • But the shadow maps have likely a brighter future: more performance, because you can control the shadow map resolution and frequency of updates, which was pointed both by Afterwarp presentation and recent forum thread where Erik Johnson managed to use our shadow maps with great performance gain. Also, shadow maps work out-of-the-box with our upcoming (not yet merged to master) skinned animation on GPU, while shadow volumes… in short, require fallback to animate skin on CPU (see TODO there for more details). So, again, shadow maps seem to give “more performance, easily”.

    • And of course shadow maps “just work” with any geometry, 2-manifold or not, and even account for alpha testing (e.g. precise shadows cast by typical leaf textures). So there’s no need to worry about whether your 3D model is 2-manifold, and no need to tweak RenderOptions.WholeSceneManifold either.

  5. So, thoughts coming from the above:

    • shadow maps improvements are important (and don’t be afraid to make shadow maps, not shadow volumes, default),

    • deferred rendering is important (to experiment with, and maybe come up with a hybrid approach),

    • BGFX renderer is important, albeit independent from us “getting deferred rendering option”.

    OK, this mostly validates our roadmap, with shadow maps before 7.0, and BGFX after ๐Ÿ™‚

Have fun everyone! Stay tuned for more technical announcements next week. And if you like what we do please support us e.g. by subscribing on Patreon.

Comments on the forum (3) โžค

Shaders! Large new documentation how to use shaders with Castle Game Engine, and new “shader libraries” (for now: to convert world<->eye space comfortably), and new SetEffects methods

Posted on

Animated volumetric fog shader effect
Color change effect
Fog shader effect
Fresnel and toon shading effects combined

We’ve done a number of improvements to our shaders support, and it starts with one big thing:

We have a new documentation how to use shaders with Castle Game Engine. Recommended reading! This documentation shows the most recommended way to use shaders in Castle Game Engine, combining simplicity with power:

  • It starts with up-to-date explanation of why we recommend to use “shader effects” (TEffectNode) to express your shaders.

  • It goes through simple practical examples: the most trivial shader, passing time to shader, passing texture to shader, converting eye<->world space (and what does it even mean).

  • Points interested readers to all the “advanced” topics and alternative ways to use shaders (sometimes more complicated).

We’ve also improvements to our engine API around shaders, to actually enable everything documented above:

  1. We added new SetEffects methods to easily connect TEffectNode with higher-level components that are core of our engine (like TCastleScene) in the simplest possible way. These are:
  2. We have improved our examples:
  3. We added property shaderLibraries (string list) to our TEffectNode. In Pascal you set it like this:

    Right now, the castle-shader:/EyeWorldSpace.glsl is the only possible value you can put there. But the system may be more flexible in the future, allowing us to expose more GLSL libraries (from the engine, using castle-shader:/; other ideas may appear; note that you don’t need this to reuse shader setup in your own application, since you can just reuse own TEffectPartNode multiple times).

    Each “shader library” may define additional GLSL functions. It can also use PLUG_xxx of the shader, thus augmenting the rendering or computation. The uniform values necessary for the library are automatically passed by the engine, so you don’t need to know/do anything more to use it.

    The castle-shader:/EyeWorldSpace.glsl, in particular, defines 4 new GLSL functions, available in both fragment and vertex stages:

    Use them in your own shader code. Just make “forward declaration” for them first, like this (effect makes fog depending on point height in world space):

    The X3D file demonstrating this feature is here.

    The Pascal example demonstrating this feature is here. The “Effect: cube map” is using this to get 3D direction from camera to rendered point, in world space, and then use this direction to query a cubemap (loaded from DDS).

    This deprecates: our Viewpoint.camera*Matrix events. Their usage in practice was only to pass new uniforms to the shaders, but they were complicated to use, needed X3D Viewpoint node, routes, passing events… The new thing is trivial to setup if you already have code dealing with shaders using TEffectPartNode, in Pascal or in X3D. And it is trivial to implement too, it just does literally what you expect, i.e. adds extra GLSL code and makes sure it receives proper input (uniforms).

Have fun using shaders! And if you like it, please consider donating to support the engine development.

Comments on the forum โžค

Game controllers (gamepads, joysticks) – new comfortable API, and example of walking and talking using gamepad from Delphi Summit 2025

Posted on

Xbox Controller used to control our Castle Game Engine demo
Xbox Controller used to control our Castle Game Engine demo
Game Controller example
Doom gamepad layout
Fortnite gamepad layout

We’re proud to present a completely new comfortable API to handle game controllers (which includes gamepads, joysticks and similar devices). Everything is documented, with links to examples, in the dedicated manual page about game controllers.

Highlights of the new support:

  1. You receive information about pressing / releasing gamepad buttons by overriding TCastleUserInterface.Press and TCastleUserInterface.Release methods. Usually you define these overridden methods in your view and handling the gamepad buttons is similar to handling key and mouse button presses.

    The simplest example looks like this:

    Follow the documentation for examples.

  2. Buttons are expressed using controller-agnostic enumerated values. In particular, the 4 face buttons (sometimes labeled A B X Y, sometimes square triangle circle cross, and occurring in various order on different pads) are called gbNorth, gbEast, gbSouth, gbWest. You can also access buttons’ caption (which is a name to display to user, like A or B) and meaning (which corresponds to the typical meaning of the button, like gmConfirm, gmCancel).

    Note: While the API is ready to support any gamepad in the future, the current mapping on PC (Windows, Linux) just assumes Xbox Controller. Because it seems to be the most common controller. Support to properly detect e.g. PlayStation gamepads connected to PC is coming. This week, we focused on having a simple and future-proof API to make it possible.

  3. The axes of controllers are available as simple TGameController functions:

    Observe them using e.g. Update method of your view. Again, follow the documentation for many examples ๐Ÿ™‚

  4. The example examples/game_controllers allows to test all this. Shows detected game controllers, reports pressed / released buttons, visualized axes of the selected controller.

    It is a “resurrected” version of the old example examples/deprecated_to_upgrade/joysticsks. But practically almost whole code of that example changed ๐Ÿ™‚

  5. On top of that, we have expanded our TInputShortcut to accept game controller button press or axis move (and report “how much” it was moved above the dead zone).

  6. And on top on the new TInputShortcut capabilities, we give you TCastleWalkNavigation.UseGameController method: a 1-liner to make your TCastleWalkNavigation follow the typical 3D FPS games behaviors. So left stick moves, right stick rotates, you can jump / crouch / run using the typical button layout.

  7. New example walk_3d_game_controllers, that Michalis showed at the Delphi Summit 2025 this week, shows a simple demo of a game where you can walk with gamepad and have simple interactions with horses and other weird NPCs ๐Ÿ™‚

  8. Also our examples/fps_game/ was adjusted to use controllers. We just added the 2 lines below to adjust the game to use the game controller:

  9. We started this feature as an upgrade of our old CastleJoysticks unit. We were changing and changing old API (which was somewhat over-complicated, exposing internal system/controller-specific numbers, and weirdly inconsistent with how you handle keys/mouse)… until practically nothing remained.

    So we decided to just break compatibility. Old API was really uncomfortable, and maintaining the backward-compatible “crutches” would risk that we confuse everyone what is the “proper non-deprecated way” of doing things. We also suspect not many people actually used the old API — since you needed to account for internal button and axis numbers that were both system-specific and controller-specific, it was very difficult to make cross-platform applications using the old API.

    Of course, report if you have used old CastleJoysticks and have trouble upgrading. Tell us which exactly things you miss.

  10. We also did some important fixes uncovered during code refactors. Disconnecting / reconnecting no longer crashes. It was crashing in at least 2 ways on Windows (free in the middle of iteration, mixed ids on the list vs Windows ids).

  11. As you see, our naming changed from “joysticks” to “game controllers”. This follows most of modern naming and APIs.

    • We looked at Steam, Godot, Android and web APIs for gamepads and tries to take the best.
    • We considered using
    • None of above are really perfect.
      • “Joystick” and “gamepad” are both too narrow, as APIs support both things, because for software they are generally the same thing, just with different physical shape.
      • “Game controller” sounds a bit too wide, as Wikipedia says that even mouse+keyboard is in principle “a kind of a game controller”.
      • In the end, we choose “game controller”, because that’s what Steam and Android call them. Though on web they are gamepads.
      • We know, it’s the longest name possible. If Steam and Android APIs can handle it, so can we ๐Ÿ™‚
      • In many places, we shorten “game controller” to just “controller”.
  12. Note that this is not the end. We list a number of TODOs at the end of the doc page. They include new TCastleInputAxis and actual support for more gamepad types. But the current work provides a solid foundation for it: we have API that is comfortable to use (simple press/receive, axes) and future-proof (makes sense on various platforms and with various devices).

Enjoy! And as always, if you like the new development, please donate. Your support keep us going.

Comments on the forum โžค

Meet me in Netherlands (Amsterdam), Italy (Piacenza), Germany (Sundern) at the upcoming Pascal conferences

Posted on

Castle Game Engine at Delphi Day

As many of you know, I looove talking about Castle Game Engine and our many features. But my wife, though she loves me dearly, eventually says “enough” ๐Ÿ™‚ So I learned to travel around the world and speak at various conferences. Catch me at these upcoming events:

  1. I will be at the Delphi Summit, in Amsterdam (Netherlands), 5-6 June 2025 (next week!). With big thanks to Blaise Pascal Magazine and Detlef Overbeek, we should have a demo of the engine running and available to interact with.

  2. I will speak at Delphi Day in Piacenza, Italy, on June 20. I will show our engine for Delphi developers, introducing the engine and showcasing latest developments like IFC, mORMot demos, improved comfortable shader effects (stay tuned for upcoming news post about the details of this!).

  3. I will speak at Pascal Conference organized by Sorpetaler, in Sundern (Sauerland, Germany) on 18-21 September 2025.

    • We plan a larger demo of our IFC support to design windows. This will use our engine combined with the Sorpetaler software to achieve something very cool ๐Ÿ™‚
    • I will also present other features of the engine, including the web platform.

Please catch me at these events if you’re there! I was serious when I said that I love talking about Castle Game Engine ๐Ÿ™‚ Whatever you do with the engine, whatever questions you have, I will be happy to look and talk.

If you cannot attend these events, but live nearby and want to connect — I’m also open to this. Just drop me a mail ([email protected]) and we’ll coordinate it.

Be seeing you!

Comments on the forum โžค