![]() |
![]() |
![]() |
Contents:
X3D (and it's older version, VRML) is a file format for 3D models. Various 3D modeling applications can export to it, for example Blender includes an X3D exporter (see also our Blender exporting notes -- although now we advise using more feature-rich glTF exporter).
To try it out, just create some X3D models (or download them from the Internet, or grab our demo models) and open them with our view3dscene.
As a 3D file format, X3D is quite unique, as
It's not only a file format. It's actually a very flexible scene graph for 3D applications. Every X3D node corresponds to a Pascal class with appropriate fields, and you can freely create and modify X3D nodes at runtime.
It's designed to describe virtual 3D worlds, not just static scenes. So you can express animations, interactive behaviors (e.g. open the door when user presses a handle), and scripting right inside the X3D file. Many advanced graphic effects are also possible, like mirrors by generated cube map textures, screen effects, shadow maps, shadow volumes, effects using GLSL shaders and much more.
Note that our engine supports many other 3D and 2D file formats too, like glTF, Collada, Wavefront OBJ, Spine JSON... They are all loaded into a graph of X3D nodes. So X3D is our scene graph, but it's absolutely not the only file format that we support.
Learning X3D: Use this part of the documentation to learn about the available X3D nodes and their fields.
The nodes in the official X3D specification are divided into components. We list all the supported nodes, with links to their X3D specification. For some nodes, we also mention eventual caveats or simple extensions that we have implemented.
The unofficial nodes that we add documents some cool graphic effects available in our engine through special X3D nodes.
The X3D specifications are your ultimate resource to learn X3D. You will most likely want to browse X3D Architecture and base components specification, which describes the available X3D nodes. The nodes are grouped into components.
When we say that "X3D is our scene graph",
what it means in practice is that you have a graph of X3D nodes
inside the
TCastleSceneCore.RootNode
property of any
TCastleScene
instance.
The TCastleScene
is our central class to render and animate 3D and 2D content,
see the manual about TCastleScene.
This way you can edit (or even build from scratch) a graph of X3D nodes using Pascal, to create any content you like. You are not limited to only loading the content from X3D files (or Collada, or Wavefront OBJ...).
For example, consider an X3D node
Box
(Pascal API: TBoxNode
).
This node in X3D has fields size
(the X3D type is SFVec3f
)
and solid
(the X3D type is SFBool
).
In Pascal, this node corresponds to the class
TBoxNode
,
with properties
Size: TVector3
and
Solid: Boolean
.
You can create and edit instances of
TBoxNode
and use
TCastleScene
to render them.
This section of the Castle Game Engine documentation describes all X3D nodes (often by referring you to the X3D specification for details), and it shows various examples how to create and edit X3D graph using Pascal. See for example:
You can also pre-process the loaded scene (e.g. change the texture), by changing the X3D nodes graph (see this forum post for details).
The X3D nodes have a reference-counting mechanism. The node (TX3DNode
or any descendant) is freed when the reference count of it changes from non-zero to zero.
So in the usual case, if you set the node as a value of some propery of the other node, then you no longer need to think about releasing this node — it will be released along with the parent. For example:
var Geometry: TBoxNode; Shape: TShapeNode; Root: TX3DRootNode; begin Geometry := TBoxNode.Create; Shape := TShapeNode.Create; Shape.Geometry := Geometry; { Now you no longer need to worry about freeing Geometry. It will be freed along with Shape. Note that there's a shortcut for above 3 lines: Geometry := TBoxNode.CreateWithShape(Shape); } Root := TX3DRootNode.Create; Root.AddChildren(Shape); { Now you no longer need to worry about freeing Shape. It will be freed along with Root. } // to be continued ...
Moreover, when you load nodes into TCastleScene
using Scene.Load(MyNodes, true)
— the 2nd parameter means that Scene
takes ownership of the whole nodes tree. So the whole TX3DRootNode
instance will be freed along with Scene
.
So we can continue the example above:
Scene := TCastleScene.Create(Application); Scene.Load(Root, true); { Now you no longer need to worry about freeing Root. It will be freed along with Scene. }
And Scene
is a regular Pascal TComponent, with usual component ownership. In the above example, it is owned by the Application
singleton. In larger application, when using views, it will often be owned by TCastleView.FreeAtStop
. And you can always free the scene explicitly too, like FreeAndNil(Scene);
.
Notes:
If a node is not referenced from anywhere, you are responsible for freeing it manually as usual. For example, if we would not load Root
into Scene
(if we remove the line Scene.Load(Root, true)
from above example) then at some point you should call FreeAndNil(Root);
.
If for some reason you do want the node to not be automatically freed, you can use TX3DNode.KeepExistingBegin
and TX3DNode.KeepExistingEnd
.
Copyright Michalis Kamburelis and Castle Game Engine Contributors.
This webpage is also open-source and we welcome pull requests to improve it.
We use cookies for analytics. See our privacy policy.