Thanks to Jan Adamec, you can also specify custom options on the build tool command-line: add something like --compiler-option=-dMY_SYMBOL to the castle-engine compile|simple-compile|package ... command.
New engine demo test_bump_mapping, to easily show bump mapping (with steep parallax, and self-shadowing) with animated light working everywhere — on mobile too.
GLFeatures.Memory to query GPU memory information. This way you can easily detect graphic cards with lower memory (e.g. test GLFeatures.Memory.LessTextureMemoryThan(1024)), to eventually load some alternative (e.g. smaller) textures.
When loading Spine JSON models, the atlas name is now more eagerly auto-detected. Loading various examples from official Spine installation will now (again) work.
New feature allows to apply fog from SceneManager.MainScene to the rest of SceneManager.Items . See UseGlobalFog. This is enabled by default, thus potentially changing the way your game looks. I decided to enable it by default, as it’s consistent with UseGlobalLights, which is also enabled by default.
RenderControlToImage is a new powerful function to easily render any TUIControl (like a scene manager, TCastleSceneManager!) into an RGBA image. It uses using off-screen rendering and FBO underneath (and thus you’re not limited to your window size).
Thanks to Jan Adamec, you can now associate files to open with iOS application. An equivalent for Android is in-progress 🙂 See the CastleEngineManifest.xml in view3dscene-mobile for example usage. The Window.OnDropFiles callback will be called when user will use our application to open a specified file type on a mobile device.
Creature corpses using TCreatureResoure by default no longer collide. Change TCreatureResoure.CollidesWhenDead (or collides_when_dead in resource.xml file of the creature) if necessary.
Fixes and a huge optimization for CastleCreatures if you have many (like > 50) creatures on your level.
This class replaces previous classes T3D, T3DList,T3DTransform, T3DOrient, T3DCustomTransform, merging all their functionality. The ability to “group and transform” is so basic feature that the previous split into multiple classes was uncomfortable.
This way you can freely switch between adjusting rotation directly (using Rotation, as axis vector + angle) or Direction and Up (that specify rotation versus a default orientation of your models, which is of course configurable).
The TCastleTransform class is now an ancestor of TCastleScene. So you can easily transform TCastleScene e.g. by Scene.Translation := Vector3(1, 2, 3);.
The TCastleTransform class is also used as the ancestor of SceneManager.Items list. So you can easily transform your whole world, e.g. scale everything down by SceneManager.Items.Scale := Vector3(0.1, 0.1, 0.1);. (Be careful though — transforming the SceneManager.MainScene is not supported yet, so you cannot use the above example if you use SceneManager.MainScene for default camera.)
Also, TCastleTransform has a nice name, correctly suggesting that it’s useful for both 3D and 2D games 🙂 As usual, 2D in our engine is just a special case of 3D, and I’m writing everything to be comfortable for both use-cases.
The GLFeatures.EnableFixedFunction is now false on desktops with modern GPUs (with OpenGL >= 2.0). This means that the rendering, by default, uses modern implementation that is more flexible and can be even faster.
Remember that, in order to see even better shading, you can use “Phong shading”, either for the whole scene (Scene.Attributes.PhongShading := true;) or only for a particular shape (Shape.Shading := shPhong;), see shading methods documentation. By default we use Gouraud shading, which is uglier but faster.
The new rendering method (based purely on shaders) should generally produce the same or better results as the old method (which was using a mix of fixed-function and shader approaches). It is more flexible, and may be even faster on modern GPUs. But there are some possible “gotchas”:
If you have implemented custom rendering using immediate-mode OpenGL commands (in overridden LocalRender, or Window.OnRender) then you possibly depend on some deprecated state being set by the engine.
The simplest solution is this case will be to reenable GLFeatures.EnableFixedFunction for now. Just set GLFeatures.EnableFixedFunction := true in Window.OnOpen or Application.OnInitialize (you want to do this early, but after OpenGL context is created).
The more long-term solution is to upgrade your custom rendering to work with the new system. In most cases, you should not render things yourself using OpenGL — instead handle everything by loading appropriate 3D models into TCastleScene. The models can be in X3D format, with shader effects and many other fancy stuff. In general, let us know on the forum if you have a specialized need and are not sure how to upgrade.
The fixed-function Gouraud shading was using two-sided lighting. The new shader pipeline makes one-sided lighting in case of Gouraud shading, for speed.
One solution is to flip the side that receives lighting by flipping the ccw field at your geometry node (like IndexedFaceSet). The other solution is to use the “Phong shading” (that always does two-sided lighting), either for the whole scene or only for the particular shape — see instructions above.
Finally, some old GPUs with buggy OpenGL implementations may be affected by this. We tried to protect from this (GLFeatures.EnableFixedFunction remains true if OpenGL version is less than 2, even if GL supports extensions for GLSL)/ But if you find a case when GLFeatures.EnableFixedFunction really needs to be enabled even on OpenGL > 2 (because otherwise rendering using shaders is buggy), please submit it to us (through the forum or as an issue on GitHub).
And this means that I, as of today, can work 100% of my time on “Castle Game Engine” and games using it (“The Unholy Society”, and also “Escape from the Universe” for iOS soon). Many things will happen, in more-or-less this order:
Expect Delphi compatibility in CGE. I know I did not post about it lately, but it is still the main feature of the upcoming CGE 6.4. release! More plans about CGE are listed here — I “live by this list” since a long time, trying to prioritize my life to achieve these engine features.
Expect various engine improvements caused by “The Unholy Society”: Steam integration. Spine support improvements (animated meshes, shearing, probably Bezier curves). And I will make (probably as a separate project on GitHub) a Yarn dialogue reader and player (Yarn dialogue was used e.g. in a fantastic “Night In The Woods” game).
Engine improvements that happened lately:
(Work in progress) We have a new class TCastleTransform, that unifies and simplifies previous classes T3DTransform, T3DOrient, T3DCustomTransform. It is also the ancestor of TCastleScene, so finally you can just do Scene.Translation : ... without the need to wrapp the TCastleScene in a T3DTransform instance.
There are still some bits in-progress here. I’ll write more when it’s finished.
Improvements to setting X3D fields comfortably: SetXxx on various TMFNode classes, e.g. SetParts, SetShaders.
Partially workarounded Lazarus CodeTools problems with new generics. Unfortunately, Lazarus CodeTools do not handle Delphi generics OK, yet. So Generics.Collections cause problems. Also CastleUtils unit on FPC 3.0.x causes problems (but not with FPC 3.1.1.)
Sound engine sources are now updated better (without the need for TCastleSceneManager).
Lazarus packages always use inline now (it was disabled for some time). So things will be faster.
TCastlePrecalculatedAnimation was removed from the engine. It was deprecated before 6.0 release. Simply use TCastleScene to play *.castle-anim-frames or *.kanim files.
I sometimes get questions “Will there be another renderer available in the Castle Game Engine?”. My answer was always this: “Yes! Contributions for this are most welcome. It is just not my own priority now, because the current renderer (using OpenGL / OpenGLES) works great, and it works on all platforms.”
And if you have something (even just a start!) ready, don’t forget to post about it on our forum (bonus points if you will already show a CGE fork on GitHub where it can be tested). This will make Michalis extremely happy and it will avoid duplicating the work 🙂
2. OpenGLES: suggestions for new contributors
If you know your way around 3D coding, and you’re looking for interesting tasks to implement in the engine, please take a look at our OpenGL ES (Android and iOS) TODOs. This page describes 6 features that are implemented in OpenGL, but are not (yet!) implemented in the OpenGLES version.
Some of these tasks are “relatively easy (and fun!) with high reward“. You can make a cool graphic effect working on Android and iOS. The groundwork is already done (since it’s a feature already working for OpenGL), and your job is to adjust the code to work also on OpenGLES. E.g. you can activate shadow volumes on OpenGLES just by changing the current fixed-function shadow volume rendering to use shaders (the desktop OpenGL rendering will be upgraded by this too, of course — we don’t need a fixed-function implementation of shadow volumes at all).
3. Renderer improvements implemented lately
Gouraud shading in the shader pipeline now honors ccw field correctly. The Gouraud shading performs one-sided lighting, and now you can control which side receives the lighting using the ccw field, see the link for details.
2D rendering (TGLImage, DrawPrimitive) since some time uses shaders by default on desktop OpenGL.
Occlusion query (Scene.Attributes.UseOcclusionQuery) does not use the fixed-function pipeline anymore.
I have just finished a large rework of our rendering code 🙂 This unifies desktop (OpenGL) and mobile (OpenGLES) shader rendering better, and brings many new rendering features:
You can now choose between Gouraud or Phong shading, on both OpenGLES (mobile) or OpenGL (desktop). Our shaders support all combinations. By default we do Gouraud shading, but you can switch to Phong for the whole scene by Scene.Attributes.PhongShading := true or only for a particular shape using Shape.Shading := shPhong. See also the X3D Shape.shading field.
Bump mapping (even steep parallax bump mapping with self-shadowing), specular maps and other CommonSurfaceShader features are now fully available on OpenGLES (mobile platforms).
You can set global EnableFixedFunction variable to false on desktops, to force absolutely all rendering to go through shaders, without any fixed-function calls. This makes our desktop rendering 100% based on shaders, instead of the previous mix of shaders and fixed-function operations. This will be the default (on modern GPUs) soon, and you’re welcome to test it now. You can also test it using view3dscene, just pass command-line option --debug-disable-fixed-function.
Update: TODO: We still use fixed-function commands for shadow volume rendering and occlusion query features. This will be fixed (along with some OpenGLES upgrades), but until then: using these features will make your application call fixed-function commands, regardless of the EnableFixedFunction flag. Contributions to fix it rather sooner than later and most welcome! These are easy, local problems, they just need a dedicated person to handle them!
Details: I came to a realization that the TUniversalCamera class is a needless complication. We now expose NavigationType at TCastleAbstractViewport (ancestor of TCastleSceneManager and TCastleViewport).
We also expose methods ExamineCamera and WalkCamera at TCastleAbstractViewport. They create the camera instance, and can switch the navigation as requested.
So now you can do
SceneManager.NavigationType := ntWalk;
instead of the previous (ugly):
(SceneManager.RequiredCamera as TUniversalCamera).NavigationType := ntWalk;
And instead of
SceneManager.Camera := SceneManager.CreateDefaultCamera;
(SceneManager.Camera as TUniversalCamera).NavigationType := ntWalk;
(SceneManager.Camera as TUniversalCamera).Walk.MoveSpeed := 10;
now you can do
SceneManager.WalkCamera.MoveSpeed := 10;
This is much simpler, right? 🙂 It’s also safer, without these ugly typecasts.
More new stuff!
T3D.Visible to easily toggle object visibility, regardless of it’s collisions. This is consistent with T3D.Collides (that controls collisions, regardless of visibility) and T3D.Exists (that controls everything).