Easy mirrors on flat surfaces: more progress

Posted on

The implementation of our “easy mirrors on flat surfaces” is more-or-less complete now. I’ll be working on a documentation and better demos soon. For now, see the description below.


  • Setting up the mirror is a matter of using X3D node ViewpointMirror with RenderedTexture (to get a texture containing mirror), and applying this texture with generated coordinates by TextureCoordinateGenerator { mode "MIRROR-PLANE" }.
  • A working demo is in viewpoint_mirror.x3dv. Just get the demo-models repository and open viewpoint_mirror.x3dv inside with view3dscene from snapshots or any Castle Game Engine 3D example. A better demo will follow shortly, showing also how to use this with Blender and Pascal, without hand-crafting an X3D file.

  • Multiple mirrors work nicely and can produce recursive reflections (when a mirror is visible in a mirror). Each frame updates the mirrors based on their previous contents, so the recursion depth is practically unlimited with zero cost.

  • A mirror texture can be mixed with material and other textures using multi-texturing, just like any other texture.

  • The mirror geometry can be any complicated shape. It doesn’t have to be a simple quad! However, it should be more-or-less planar (we automatically calculate a best fit plane looking at geometry) in order to get sensible results.

  • The texture mapping TextureCoordinateGenerator is done by shaders on GPU. So it remains fast even for complicated objects. The mirror itself is rendered using FBO.

This work is sponsored by the Castle Game Engine supporters on Patreon, in particular thanks go to Robert Daniel Murphy for requesting this feature. If you like what I’m doing, please consider supporting me! Thank you.

Comment on this post ➤

New trailer of “The Unholy Society”

Posted on


We proudly present a new trailer for our game “The Unholy Society”:

It’s all in-game footage, everything is done using Castle Game Engine. Most of the graphics is done in Spine, and rendered and animated using TCastle2DScene (see more info about using Spine in Castle Game Engine). The UI (fight symbols, items) is using standard CGE UI (TUIControl descendants). We have a simple custom language for conversations and scripting (see also Google Doc version of this post).

You can wishlist the game on Steam!

The game is developed by Cat-astrophe Games, an indie game studio in which Michalis is the main (and only, although that may change soon) developer. Coincidentally, we’re doing all our projects using Castle Game Engine 🙂

Comment on this post ➤

NURBS, simplified license (just LGPL out-of-the-box)

Posted on

  1. The need to define symbol CASTLE_ENGINE_LGPL to get LGPL engine (otherwise you only had GPL) disappears. The whole engine can be used on a permissive LGPL terms out-of-the-box now, there is no point in defining the CASTLE_ENGINE_LGPL symbol anymore.

    I have clarified and simplified our license terms on https://github.com/castle-engine/castle-engine/blob/master/COPYING.md . In short: we’re exactly like FPC and Lazarus. Yes, you can make closed-source applications using CGE.

  2. We have a new NURBS implementation, developed by Michalis from scratch. I deleted the old (GPL-only, copyright by White Dune developers) implementation in this commit, and later implemented new one (LGPL, copyright by me) in subsequent commits. So the LGPL engine supports NURBS now.

    The new implementation also got some serious optimizations (utilizing the fact that we usually calculate not one point on a curve/surface, but a number of such points in a series).

    The new implementation also features a helper method TNurbsCurveNode.Point. See this test for a quick usage example. This allows you to use NURBS curves calculation for any purposes, not necessarily by placing the NURBS nodes inside TCastleScene.

Comment on this post ➤

Fixes, demo switching projection, website and API documentation improvements

Posted on


Busy month! Partially due to developing the last chapter of our game The Unholy Society, in which a certain-special-someone is scheduled to appear 🙂

New stuff in the engine:

  • Important bugfix: Changing the FullScreen property of the window is now more reliable. The actual change (which may involve recreating OpenGL context) happens with delay, not immediately at the point you assign the “FullScreen” property. This makes it safe to use always, even during Window.OnOpen / Application.OnInitialize. Thanks for Ninjamida from Discord for finding this nasty bug.
  • SceneManager.OnProjection event along with a demo switch_projection.lpr showing how to use it to toggle between orthographic/perspective projection.

  • TAbstractBindableNode.Bound property.

  • More reliable on-screen keyboard on Android thanks to Benedikt Magnus!

New website improvements:

  • You can now comfortably switch between viewing API documentation for engine stable version (6.4) and unstable (6.5). The currently viewed version is clearly visible, and when switching we try to show the same identifier (if it exists in the other version).

  • The “search” in our documentation is better now (highlights found terms, no messed up HTML) as I improved the “tipue search” functionality in PasDoc.

  • I have adjusted our analytics (Piwik) settings to be compliant with GDPR and anonymize the IP addresses and delete old data. Our privacy policy was reflected about this.

    P.S. Have you seen a new pretty webpage of our studio Cat-astrophe Games ? 🙂 My cats are there!

Retired: GitHub -> SourceForge SVN synchronization

Our GitHub -> SourceForge SVN synchronization (using forked sync2git) started to have problems.

(Details: The synchronization repository got into a state unexpected for git-svn. Possibly the underlying reason was a random SourceForge connectivity issue, but that’s speculation.)

Since I don’t think anyone is using SourceForge SVN anymore, I just turned it off, and I made sure no links to SourceForge SVN repository exist anymore on our website. Please use only CGE repositories on GitHub from now on, in particular the main Castle Game Engine repository.

Note that you can still use either GIT or SVN client to get Castle Game Engine. GitHub supports doing “svn checkout” on a GitHub repository (or a subdirectory of it).

Comment on this post ➤

Engine improvements: CommonSurfaceShader with shadow maps fix, demo of mouse picking 3D/2D objects, view3dscene without console

Posted on

  1. We added a simple demo how to detect which scene (TCastleScene) was clicked with the mouse: https://github.com/castle-engine/castle-engine/blob/master/examples/3d_rendering_processing/detect_scene_clicks.lpr .

  2. The behavior of shadow maps when combined with CommonSurfaceShader is now correct. Testcase: https://github.com/castle-engine/demo-models/blob/master/shadow_maps/primitives_with_commonsurfaceshader.x3dv

  3. view3dscene no longer uses console for various messages. Instead we display our own message box, with contents that can be copied to clipboard with Ctrl+C. This makes it more comfortable to use as a normal GUI program, in particular on Windows. Remember that you can always download the latest view3dscene snapshots from here. (Or you can compile view3dscene from source, of course.)

  4. Our website supports now IPV6, HTTP/2, has better redirects (from www domain to non-www), and is HTTPS-only (non-secure HTTP merely redirects to HTTPS, and we use HSTS). Thanks to Raul Tambre for suggesting and testing these improvements!

Comment on this post ➤

Engine improvements: Prettier lighting with SeparateDiffuseTexture, cross-platform TCP client/server classes, EnablePhysics

Posted on


To finish the week of many annoucements, here are 3 more engine features added lately.

BTW, I also wrote a wiki page documenting common properties to “make rendering prettier”. Check it out:)

New engine features:

  1. Scene.Attributes.SeparateDiffuseTexture allows to get a prettier lighting behavior. The textures (in Appearance.texture or CommonSurfaceShader.diffuseTexture) will then really affect only the diffuse lighting term. This is generally better and prettier (specular highlights are then brighter), and it’s also more correct (according to X3D spec). But note that it is only possible in Phong shading (when Scene.Attributes.PhongShading is also true), and it makes rendering a little more expensive (for now).

    In view3dscene (see view3dscene from snapshots) you can use menu item View -> Separate Diffuse Texture (When Phong Shading) in addition to View -> Phong Shading on Everything. By default it is false, to be compatible with previous look, and also because it’s more consistent with Gouraud shading behavior. (And the Gouraud shading is default, in turn, for speed.)

  2. Client and server classes for implementing TCP client/server communication in Castle Game Engine games are available. See the unit CastleClientServer, and the demos in examples/tcp_connection. Thanks go to Benedikt Magnus for implementing this!

  3. You can now instantly disable/enable physics by setting SceneManager.Items.EnablePhysics to false/true.

Comment on this post ➤

Engine improvements: generating compressed/downscaled textures is smarter

Posted on


Since a long time, you can automatically generate compressed and/or downscaled textures versions using our build tool.

This process is now smarter. Instead of detecting which files to update looking at file modifications times, it now looks at file contents (using fast MD5 checksums), and automatically creates/updates a castle_engine_auto_generated.xml file. The castle_engine_auto_generated.xml is automatically created and maintained in your data/ directory when you call castle-engine auto-generate-textures.

We plan to extend this feature even more, to store more information inside the automatically-maintained castle_engine_auto_generated.xml. In the future, this file can be used to:

  1. Track the size of the texture. This allows to avoid trying to load non-square compressed texture on iOS, which is not possible — thanks to weird Apple limitations. Currently we just avoid using any auto-generated compressed textures on iOS.
  2. Track the DXT* version generated, for the case when we automatically choose the best DXT* version depending on the image alpha channel. This would complete a currently unfinished-and-undocumented feature of <format name="DXT_AutoDetect" /> in material_properties.xml.
Comment on this post ➤

Engine improvements: Localization

Posted on


You can now comfortably localize (translate) your game.

Two approaches are possible:

  1. Use our own localization class from the CastleLocalization unit. It can read from a number of translation formats (XML, JSON, CSV, GetText MO). It can translate user-interface controls, like TCastleLabel. The demo is inside examples/localization/custom/.

    For advanced users, the system allows to aid in localizing your custom classes too (see OnUpdateLocalization) and to add your own translation formats (see FileLoader).

    Thousand thanks go to Benedikt Magnus for developing this!

  2. Use the standard GetText unit from FPC. You use GetText formats for translating (PO, MO), utilizing tools like PoEdit. The resourcestrings are translated automatically. The demo is inside examples/localization/gettext/.

    The engine uses resourcestrings for some internally-generated messages (and it will use them more), so these can be translated too.

In both cases, you can use a cross-platform CastleSystemLanguage unit that tells you the preferred user language.

Note that, while both approaches (GetText, our own) provide some infrastructure to aid you in translating (resourcestrings, special handling for UI controls), you can also translate things “explicitly” in both cases. Using the TMOFile.Translate(‘my_id’) in GetText, or Localization.Items[‘my_id’] in CastleLocalization.

So both systems are really flexible, and should fill all your needs 🙂

A related feature is also new TInputPressRelease.KeyString. This expresses key press as a string with UTF-8 encoding, and allows us to accept input of international characters across Castle Game Engine (for example in TCastleEdit). Many thanks go to Eugene Loza for this!

Comment on this post ➤