Last refactor before CGE 7.0 release: Say hello to TCastleViewport and TCastleWindowBase, say goodbye to TCastleSceneManager and TCastleWindow

Posted on

multiple_viewports

This week I finished the last big engine API change before the next release! TCastleSceneManager is now deprecated: instead you should use TCastleViewport to display 3D models. This makes things much simpler, and it allowed me to make TCastleViewport defaults much better.

1. TCastleViewport

A simplest working source code demonstrating this (it will compile — get the engine and test it!) looks like this:

See the CGE examples: 3d_rendering_processing/view_3d_model_basic.lpr for a complete code with some additional comments.

The advantages of the new approach:

  1. The API is simpler (easier to explain and use).

    Previously, TCastleViewport was in most practical cases reserved for “secondary viewport”, that shows something also visible in the “primary viewport”. The “primary viewport” was TCastleSceneManager with DefaultViewport = true. This entire complication (and complication of terminology – “how is scene manager different from viewport”) no longer exists.

    Now you just use TCastleViewport to display a world (composed from a tree of TCastleTransform and TCastleScene). Period.

    To display the same world from two cameras, just copy one TCastleViewport.Items to another. Or assign the same TCastleRootTransform instance to two TCastleViewport.Items.

    To have multiple viewports (cameras) display the same world, simply assign the Items property of one TCastleViewport to another. You can also create your own TCastleRootTransform instance and assign it to as many TCastleViewport.Items properties as you want. Demo of this is inside CGE examples: 3d_rendering_processing/multiple_viewports.lpr.

    So all previous use-cases are covered in a more natural way.

  2. Moreover, this allowed me to minimize compatibility break while still changing some defaults. Since TCastleViewport was so seldom used, we change it’s default properties:

    The FullSize=false default is consistent with all other UI controls. This way it is less surprising (when instantiating from code or in CGE editor).

    The AutoCamera=false and AutoNavigation=false are better defaults after recent camera refactor. The “false” default on these properties makes more sense — while the auto-detection is nice for quick demos, it is bothersome and sometimes surprising for non-trivial applications, so it’s best to have the auto-detection “off” by default.

    On TCastleSceneManager these defaults do not change (as it would undoubtedly cause a lot of breakage, since you use TCastleSceneManager so much in existing applications).

2. TCastleWindowBase, TCastleControlBase

Also TCastleWindow and TCastleControl are deprecated, in favour of their “Base” counterparts: TCastleWindowBase and TCastleControlBase. Why:

  • This way you don’t have a default viewport (scene manager) instance, which avoids some traps (the default navigation may catch some keys), and it is often not necessary.
  • This way you create the TCastleViewport yourself, as many as you need. So you have more power over the engine. This way it is clear that TCastleViewport is just a regular user-interface class: you can create it as many times as needed, you can position and resize it however you like.

  • This way you can create and adjust the TCastleViewport using CGE editor, just like any other UI control.

Many parts of the manual and examples have been updated to show “the new approach”. I’m working to finish updating the manual now.

Comments on the forum ➤

Bumpcars-2019 – gamejam racing game by Rafael Campos

Posted on

bumpcars1
bumpcars2
bumpcars3

Rafael Campos submitted a new game using Castle Game Engine. Race against the clock to complete the three tracks: park, city and beach. In order to win you will must evade the obstacles and your competitors.

Download the game for free from itch.io!

This game was submitted to the game jam “I’m using a lot of assembly language” also hosted by Rafael. 50% of game code is assembler (14000 lines of ASM code), which main objective is the subdivision of 3D triangles.

By the way, I also reworked our Gallery, and added various missing entries. It is now split into:

Comments on the forum (1) ➤

Engine improvements: GtkGLExt no longer used, new TCastleInspectorControl, loading optimizations, TwoSidedMaterial node

Posted on

cge_inspector

November/December engine improvements:

Comments on the forum ➤

Bricks Color Pick – free Android game made using Castle Game Engine

Posted on

bricks_color_pick

We’re proud to present a new game made using Castle Game Engine: Bricks Color Pick. It’s a new approach to the classic arkanoid games, with a twist: there is no paddle. The challenge is to switch the color of the ball to match the bricks. You need to do it quickly — because the ball will bounce all around the level using physics.

Made by Andrzej Kilijański who also wrote a lot of articles about Castle Game Engine. Andrzej also submitted a number of pull requests related to our physics support (based on Kraft) — and now we know why 🙂

Check out the game on your Android, it’s completely free!

Comments on the forum ➤

Engine improvements – Spine improvements, dragging demo, package formats

Posted on

The Unholy Society - sister talk

We were incredibly busy lately, preparing the release of The Unholy Society for PC (Windows, Linux) and Nintendo Switch. It’s a game by Cat-astrophe Games, using Castle Game Engine, programming by two of CGE developers — Michalis Kamburelis and Eugene Loza. Check out our trailer and game information on the game page and wishlist us on Steam!.

In the meantime, we have a number of improvements to the engine from November:

  • We have exposed methods to perform “mouse look”. They can be used to make mouse dragging without being constrained by window borders. New demo of both dragging methods is available in examples/2d_standard_ui/dragging_test.

  • We support a new Spine feature to export a single atlas for multiple skeletons. It’s quite cool, often allows to significantly reduce the total necessary atlas sizes. To use it, you need to open Spine file through an URL like this: my_animation.json#atlas:my_atlas_name instead of just my_animation.json. See our Spine documentation for details.

  • New OrientationInterpolation2D allows more efficient 2D rotation interpolation. It is automatically used by Spine animations.

  • Our build tool allows to configure package format by --package-format option (allowed values for now are: default, directory, zip, targz). You can also configure whether version number appears in the resulting filename by --package-name-no-version option.

  • Programs using Application.ParseStandardParameters will now automatically handle the --log-file command-line option, that allows the user the configure output log file. Note that, in order to make this work, you should not call InitializeLog before command-line options are parsed. Our examples, like portable_game_skeleton, show how to do this.

  • The default sound “importance” is now 10, instead of “maximum”. This seems much more reasonable. See our new docs of sounds XML files.

Comments on the forum ➤

Huge Camera and Navigation Improvements – Thank You Patrons!

Posted on

Castle Game Engine editor with 3 viewports (scene managers)
Castle Game Engine editor with scene manager menu

To celebrate #ThankYouPatrons day in the weirdest and most-programmer-friendly way possible, today we merge into the “master” branch of Castle Game Engine a big refactor of the camera code! This is a huge work, started 4 months ago, and causing 110 new commits.

It includes a number of new inter-connected features:

  1. The API to control the camera (viewer position, direction, up, projection etc.) and navigation is now much simpler. Check out API docs about new TCastleAbstactViewport.Camera and TCastleAbstactViewport.Navigation.

  2. You can now configure both camera and navigation visually, using the CGE editor.

    When you select a viewport (most usually a TCastleSceneManager instance), or anything inside a viewport (like a TCastleScene), there will appear a new set of buttons on the toolbar. The “hamburger” button there contains a menu with useful operations to configure camera and navigation. The “initial” camera vectors will be stored in the design, as well as the chosen navigation component.

    (The buttons to translate/rotate/scale scenes are not yet handled — coming soon!)

  3. We split previous camera class into two concepts, TCastleCamera (“what is current viewer position/orientation and projection”) and TCastleNavigation (“how to handle user input to change the viewer position/orientation”).

    This caused a lot of work to make it right, and also to keep backward-compatibility as much as possible. I’ll list reasons for making it in another post — it’s a story in itself.

  4. We provide easy means to turn off “auto-detection” of camera and navigation. Just set AutoCamera and/or AutoNavigation to false.

    I recognize now that this “auto-detection” is sometimes undesired or even surprising. I would advise most games to set both AutoCamera and AutoNavigation to false right after creating TCastleSceneManager. CGE editor will do it by default too, soon.

  5. TCastle2DSceneManager is now deprecated, as it is useless. You can now easily request orthographic camera with TCastleSceneManager (call Setup2D method, or just set yourself Camera.ProjectionType = ptOrthographic and configure Camera.Orthographic properties). This makes things much simpler. We never needed any special class for 2D, our TCastleSceneManager is for both 2D and 3D — now it’s obvious 🙂

  6. It is now configurable which camera (from which viewport) controls “central” features like headlight, X3D ProximitySensor, audio listener. Set TCastleSceneManager.MainCamera for this.

  7. CGE editor received a number of smaller improvements along the way. E.g. you can now duplicate (Ctrl + D) transformations/scenes too, assigning SceneManager.MainScene and other references works.

Comments on the forum ➤

Triggers (detecting collisions) and physics settings

Posted on

Collision trigger

Thanks to Andrzej Kilijański and our physics engine Kraft, we add two features to our physics support:

  1. We now support triggers. A trigger is a rigid body through which other objects “pass through”, but it still reports a collision. This is useful to observe when something passes through something else.

    E.g. coins in “Mario” games could be implemented as triggers — when player collides with them, they are consumed, and player does not “bounce off” them like from a wall.

    An example of using trigger is available in examples/physics/physics_2d_collisions, the green rectangle acts as a trigger there.

  2. You can adjust physics properties by adjusting SceneManager.PhysicsProperties.Xxx. See the TPhysicsProperties docs.

Comments on the forum ➤

Numerous optimizations and dynamic batching

Posted on

Effects of dynamic batching

Thanks to many sessions dedicated to optimizing CGE rendering and animation, we have a number of new optimizations (some enabled by default, some experimental — you need to enable them yourself) and new ways to profile your applications.

  1. Various “bottlenecks” (things that noticeably affect the speed) are now drastically optimized. This includes iterating over shapes (it now uses a cache and is instant), transforming frustum (uses a different algorithm that is > 2x faster), avoiding unnecessary preparing of resources (when everything is prepared), avoiding useless passes when shadow volumes are not used.

    You’re most encouraged to test your code with the new engine version, and report the results 🙂

  2. A new optimization, enabled by default: frustum culling of the whole scene (TCastleScene.SceneFrustumCulling). This works hand-in-hand with the existing per-shape frustum culling, which can be improved when using an octree (if ssRendering is in TCastleScene.Spatial).

  3. A new experimental powerful optimization called “dynamic batching” is implemented. Multiple X3D shapes (with the same appearance) can be merged into one, and rendered using one “draw call” to OpenGL/OpenGLES. In some applications, this offers incredible speedup — if you have a lot of simple shapes with the same appearance.

    You need to activate this optimization explicitly by setting DynamicBatching (global Boolean variable) to true. See also the the relevant section in the manual.

    Please treat this optimization as “experimental” for now. There are many corner cases, and I’m not yet sure whether I covered them all. IOW, it is (temporarily) possible that this optimization will break rendering in some cases. It is also certain that we don’t use all merging possibilities, yet. This will be extended, and hardened, in the future.

    Also be aware that this optimization is not guaranteed to be beneficial. We will spend some time, each frame, analyzing which shapes are “good candidates for merging”. While I tried to make this analysis very fast, but there are definitely cases when we will waste more time than we gain. If you have thousands of shapes, all using a completely different appearance, then “dynamic batching” will not merge anything, and will only waste time trying.

  4. Another new experimental powerful optimization is implemented for animations that heavily transform the shapes (e.g. typical Spine animations). You can activate it by assigning the global variable InternalFastTransformUpdate to true.

    See the documentation of InternalFastTransformUpdate for the risks. This optimization assumes that your animations only transform shapes. If you use X3D animations to transform e.g. lights, then they will fail. I will fix it at some point, and then enable this optimization by default, always.

  5. A new simple way to observe what is rendered: just display somewhere (e.g. using TCastleLabel) SceneManager.Statistics.ToString.

  6. A new FrameProfiler, to observe what is eating time per-frame (e.g. whether the problem is in OnRender or OnUpdate).

  7. On Nintendo Switch, we are integrated with a cool profiler from Nintendo.

  8. To activate risky optimization on Aarch64, you can define CASTLE_ENGINE_ENABLE_AARCH64_OPTIMIZER symbol to true. We’re working on making them non-risky (we need to reproduce and submit some cases to FPC), at which point we will activate them automatically.

The manual page about optimizations was updated to describe various features mentioned here.

Comments on the forum ➤

Configurable FPC and Lazarus location in the editor

Posted on

cge-editor-location
cge-editor-location-warning

The CGE editor now has a “Preferences” window where you can configure the location of FPC / Lazarus.

Basically, if you use the CGE editor, you no longer have to worry about adjusting your environment variables. No need to place FPC / Lazarus in $PATH anymore, and no need to define $CASTLE_ENGINE_PATH. This should make the editor more user-friendly — I’m aware that editing environment variables isn’t comfortable for everyone on all operating systems 🙂

The editor now also displays more prominently whether it detected FPC (and what version it detected), and the “Preferences” window includes a helpful text leading to Lazarus + FPC download. All this will hopefully lead to more straightforward experience for people new to Lazarus/FPC.

(The next step will be, one day, to bundle FPC/Lazarus with CGE editor… but it’s not something I want to attempt now, for nearest release. Especially since advanced users would like to have an “unbundled” download anyway, as you probably want more control over FPC/Lazaus version.)

Comments on the forum ➤

Big improvements to camera API coming soon, and check out our game on Nintendo Switch

Posted on

"Escape from the Universe" space map
  1. If you have Nintendo Switch console, by sure to check out Escape from the Universe on Nintendo Switch, a game released last month by Cat-astrophe Games.

    The game uses our Castle Game Engine for everything, of course. It depends on CGE Nintendo Switch support. A Japanese version of the game is also coming, using CGE UI localization system.

  2. I’m working on a big refactor of camera and navigation API in the engine. It is not merged yet, but you can see the in-progress work in camera-refactor branch (or see the differences from master branch).

    The current API of camera has a few drawbacks that the refactor addresses:

    • Current camera settings (“what do you see in a viewport”) are mixed with navigation logic (“how do you use keyboard/mouse to change the camera”). They are mixed within the TCamera class, and this causes various headaches when setting or auto-detecting them. All games need the same camera API, but various games need wildly different navigation logic. Many games want to just “roll their own” navigation code.

      This is addressed in the new branch, by splitting into SceneManager.Camera and SceneManager.Navigation instances. The mechanism to auto-detect their settings (based on scene bounding box, X3D nodes etc.) can be now easily disabled by SceneManager.AutoDetectCamera and SceneManager.AutoDetectNavigation .

    • Currently SceneManager.Camera may not be created before the first rendering, which is not comfortable. It causes the need for methods like SceneManager.RequiredCamera or checking SceneManager.Camera <> nil.

      In the new branch, it’s simpler. The SceneManager.Camera is never nil. In contrast, SceneManager.Navigation may be nil, and it may even remain nil forever, unless you want to use some built-in navigation logic.

    • Changing projection parameters using SceneManager.OnProjection is not comfortable. Changing projection parameters using CGE editor was not possible.

      In the new branch, you can just use SceneManager.Camera.ProjectionXxx parameters. It’s natural both in code, and in CGE editor.

    • Ideally, the class TCastle2DSceneManager should be deprecated and later removed. It should be trivially easy to get the same effect (orthographic camera, projection API comfortable for 2D games) with the base TCastleSceneManager.

    • I want to create an easy class for 3rd-person navigation. This means that input drives some character, while camera follows this character. This was requested by Robert Daniel Murphy on Patreon.

    Stay tuned for more information about this:)

Comments on the forum ➤