Cross-Platform Game Programming with gameplay3d/Creating a Scene
Overview of the scene graph
editA scene graph is a data structure that defines the spatial (and often also logical) relationship of a graphical scene for efficient management and rendering of graphics data.
It is typically represented as a hierarchical structure, which contains a collection of nodes including a top-level "root" node, a number of parent nodes each of which can have any number of child nodes, and a set of leaf nodes each of which has no child nodes and which therefore serve together as the bottom layer of the tree.
In gameplay3d:
- the scene graph is represented by the Scene class;
- instances of the Node class can be attached to a scene object;
- further instances of the Node class can be added as children of existing nodes; and
- various other attachments (such as models, lights, cameras, physics objects) can be attached to any node; and
- an operation performed on a parent node affects all of its children.
An example of creating a scene, adding two nodes and attaching a camera and a light programatically (i.e. not using a .scene file) is as follows. The example is taken from "CreateSceneSample.cpp" in the "sample-browser" project:
// In your game class's initialize() method
// Create a new empty scene.
_scene = Scene::create();
// Create the camera.
Camera* camera = Camera::createPerspective(45.0f, getAspectRatio(), 1.0f, 10.0f);
Node* cameraNode = _scene->addNode("camera");
// Attach the camera to a node. This determines the position of the camera.
cameraNode->setCamera(camera);
// Make this the active camera of the scene.
_scene->setActiveCamera(camera);
SAFE_RELEASE(camera);
// Move the camera to look at the origin.
cameraNode->translate(0, 1, 5);
cameraNode->rotateX(MATH_DEG_TO_RAD(-11.25f));
// Create a white light.
Light* light = Light::createDirectional(0.75f, 0.75f, 0.75f);
Node* lightNode = _scene->addNode("light");
lightNode->setLight(light);
// Release the light because the node now holds a reference to it.
SAFE_RELEASE(light);
// Rotate the camera downwards.
lightNode->rotateX(MATH_DEG_TO_RAD(-45.0f));
Generally, when making a game in gameplay3d:
- you will begin by loading/building a large scene representing all the components needed in the game level. This is done once during
Game::initialize()
; - during each call to the
Game::update()
method, your code will update changes to the nodes, and attached components, based on events such as user input; - during each call to the
Game::render()
method, your code will traverse the scene and render the parts in the scene that are visible from scene's active camera; and - on exit, the
Game::finalize()
method will be called, during which you will release any outstanding dynamically-allocated resources (see Cross-Platform Game Programming with gameplay3d/gameplay3d_Design_Concepts#Managing_shared_objects).
Nodes
editThe following components can be attached to the gameplay::Node
class:
Component | Description |
---|---|
gameplay::Model |
Used to represent the mesh/geometry in the scene. |
gameplay::Camera |
Used to represent a view/perspective into the scene. |
gameplay::Light |
Used to hold lighting information that can affect how a Model is rendered. |
gameplay::PhysicsCollisionObject |
Used to define the basic physics dynamics that will be simulated. |
gameplay::ParticleEmitter |
Used to represent smoke, steam, fire and other atmospheric effects. |
gameplay::Terrain |
Used to represent a height map based terrain. |
gameplay::AudioSource |
Used to represent a source where audio is being played from. |
gameplay::Form |
Used to represent a user interface that can be in a scene. |
A note about order of transformations
editModels and meshes
editLights
editCameras
editTerrain
editOther node attachments
editCreating Scene Assets in Modeling Software
editYou can use any modeling software capable of creating FBX files. Support for Collada files was removed in gameplay 2.0.0 owing to the relatively poor level of support for the format by some 3d modelling packages, but may be added back in future if adoption improves.
Creating Scene Assets with Maya
editCreating Scene Assets with Blender
editBlender can export FBX (and Collada) files. We recommend using at least version 2.70. The upcoming version 2.71 has an improved FBX export capability including tangents and binormals.
Exporting an FBX file
editBlender has a built in FBX exporter. Version 2.70 works. Do take note of these two important notes, particularly if you have animations:
- Blender and Gameplay have a different up axis. When exporting FBX file, select the up axis to be Y axis and the forward axis to be Z axis. Without this animation will be totally distorted
- The FBX exporter can create empty animation channel. You have to use the
-oa
option to transform the file for gameplay
Encoding your asset to .GPB
editNow that your model has been exported to a known format, there is one more step to complete in order to get it ready for use. Your model needs to be converted from the exported interchange format .FBX into an efficient binary bundle format that the gameplay framework can use. To do this run gameplay-encoder with the required parameters.
Encoding from FBX (.FBX)
editTo encode your FBX scene file(.fbx) into the gameplay binary format (.gpb), run the following command:
gameplay-encoder -oa -g HIKCharacterNode_boy_Reference animations "../../gameplay-samples/sample-character/res/boy.fbx"
Let's take a look at some of the extra parameters passed into the encoder.
The -g
parameter says that you want to group all animations on HIKCharacterNode_boy_reference, and its children node into an animation called 'animations'. The -oa
option says that you want optimize the animations. This is important if you import complex file from Blender as it otherwise may lead to unreadable files due to empty animation channels.
This encoding is necessary because the FBX, or, in the case of fonts, TrueType files are really just interchange formats, and are huge ascii files that are not recommended for runtime format. Encoding them packs them into a more efficient binary bundle and only takes the data that is needed by the gameplay framework.
Working with .scene files
editIn order to assemble a scene in gameplay3d using a .scene file, there are two main steps:
- create a .scene text file describing your scene; and
- load the scene in your game code by calling the
Scene::load()
static method.
Creating your .scene file
editLoading the scene in your game code
editThe scene file can be loaded into your game as follows:
// Load the scene
_scene = Scene::load("res/myscene.scene");