Fly2 Training (NTU) 王銓彰 cwang001@mac.com kevin.cwang3@gmail.com 2014 Build 1 Contents ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ Setup Working Environment The Game Loop Hello World Basics in Coding Using Fly2 Viewports & Scenes Objects Cameras & Lights Materials Characters Movements and Terrain Following Sprites Write Shaders Rendering More Functions (Text, Audio) File Formats Game FX System Introduction Before Doing Anything ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ Chuan-Chang Wang. (王銓彰, Kevin) BlackSmith Technology (墨匠科技) 壹傳媒動畫多媒體實驗室;昱泉國際;西基電腦動畫;數位內容學院;國 家高速電腦與網路中心;台大土木系 Game Engine Training (2) Game System Analysis Terrain & Game Control Character Motion Scene Management Game Physics Game FXs (2) Development Environment ■ Development Environment : ■ Use Visual Studio 2010 & C/C++ ■ Create a “Win32 Application” project ■ Install APIs ■ Win32 + DirectX 9.0c ■ DirectX 9.0c SDK ■ OpenAL 1.1 SDK Setup Working Environment (1) ■ Configuration Properties (DirectX 9.0c as example) ■ General ■ Character Set ■ Use Multi-Byte Character Set ■ C/C++ ■ General ■ Additional Include Directories ■ Add Fly2 API “Include” folder location Setup Working Environment (2) ■ Linker ■ General ■ Additional Library Directories ■ Add OpenAL & DirectX9.0c API library location ■ Add Fly2 API “LibWin32” folder location ■ Input ■ Additional Dependencies ■ d3d9.lib / d3dx9.lib / OpenAL32.lib / XInput.lib ■ LibFly2DX9W32.lib Game Loop (1) ■ ■ ■ We always implement an infinitive loop as the game main loop. Two types of jobs must be doing in the loop : ■ Check if there are incoming events from system ■ Then handle the events and do the necessary jobs ■ Check the timing and do something in regular time step. ■ Timers Incoming events ■ Keyboard input ■ Mouse movement or dragging ■ Losing/getting the input focus ■ Language input method changed ■ Someone insert CD ■ Window re-draw flag is dirty ■ Gamepad input ■ … Game Loop (2) ■ ■ Timers ■ The sub-system to handle timing. ■ It must be precise to at least 1ms or less. ■ 30 frames per second = 30 fps = 33.33333 ms ■ We need to complete the main game loop for each frame within 33 ms. Typical main game loop : Check inputs Game Logics Computation Graphics Update within 33 ms Rendering Callbacks ■ Two types of callbacks ■ In regular time step ■ Timer callbacks ■ It will be called once every 1/30 or 1/60 second. ■ A game is time-bound. ■ We lock the game running in 30 fps or 60 fps. ■ By request from system ■ Event callbacks ■ It will be called when happening. ■ A game is interactive. ■ Game interface to humans. Typical Jobs Doing in Timer Callback ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ Check “win or lose” Check “quit” flag Control objects’ movement Play character’s motion to next frame Play animation to next frame ■ Vertex animation / texture animation / object’s animation / … Perform game logic calculation Perform NPC AI (finite state machine, steering behavior, path finding, …) Perform geometry associated computation (LOD, collision detection, …) Play game FXs (particle system, dynamics simulation, …) … 3D rendering ■ Last step Introduction to Fly2 Game Engine ■ ■ Fly2 is a cross-platform real-time 3D game engine. ■ Fly Engine version 2 ■ Cross-platform ■ Win32 ■ DirectX 9.0c / DirectX 11 / OpenGL 4.0 / OpenGL/ES 2.0 ■ iOS ■ Android ■ SONY PSP2 Vita ■ Owned by BlackSmith Technology Inc. Current version 2.0 Build 1004 (1/6, 2013) Hello World – 1st Fly2 Program ■ Steps ■ Initialize the Fly2 ■ Create a viewport ■ Create a scene ■ Create 3D objects ■ A camera ■ A light source ■ A 3d object loading a teapot object ■ Setup the scene ■ Move the camera and light source ■ Bind callbacks for keyboard and mouse ■ Control the camera ■ Hotkey to quit the program ■ Setup a timer to run the program in 30fps ■ Render the scene in timer callback Hello World – Main Program #include “FlyWin32.h” Main Program name void FyMain(int argc, char **argv) { // create a new world FyStartFlyWin32("Hello Fly2 !", 0, 0, 800, 600, FALSE); // create a viewport, a 3D scene and the 3D objects … 1st line for Fly2 Hotkey callbacks // set Hotkeys FyDefineHotKey(FY_ESCAPE, QuitGame, FALSE); // define some mouse functions FyBindMouseFunction(LEFT_MOUSE, InitPivot, PivotCam, NULL, NULL); FyBindMouseFunction(MIDDLE_MOUSE, InitZoom, ZoomCam, NULL, NULL); FyBindMouseFunction(RIGHT_MOUSE, InitMove, MoveCam, NULL, NULL); // bind a timer, frame rate = 30 fps FyBindTimer(0, 30.0f, GameAI, TRUE); Timer callbacks Mouse callbacks // invoke the Fly2 and give program control to Fly2 FyInvokeFly(TRUE); } Give the program control to Fly2 and timers are ON Hello World – Create 3D void FyMain(int argc, char **argv) { // create a new world ... Create a viewport for displaying 3D result // create a viewport vID = FyCreateViewport(0, 0, 800, 600); // create a scene sID = FyCreateScene(1); // create 3D objects FnScene scene; scene.ID(sID); nID = scene.CreateObject(OBJECT); cID = scene.CreateObject(CAMERA); lID = scene.CreateObject(LIGHT); // set Hotkeys // define some mouse functions // bind a timer, frame rate = 30 fps … } Create a scene object to manage 3D objects Create 3D objects by a scene Hello World – Hotkey Callback /*-----------------quit the program -------------------*/ void QuitGame(BYTE code, // the key code BOOL4 value) // TRUE for pressing the hotkey, FALSE for releasing { if (code == FY_ESCAPE) { if (value) { // press Escape key to quit the Fly2 FyQuitFlyWin32(); } } } Hello World – Mouse Callback /*-------------------------initialize camera’s pivot ----------------------------*/ void InitPivot(int x, int y) // mouse position { oldX = x; oldY = y; } /*-----------------pivot the camera -------------------*/ void PivotCam(int x, int y) { FnObject model; if (x != oldX) { model.ID(cID); model.Rotate(Z_AXIS, (float) (x - oldX), GLOBAL); oldX = x; } if (y != oldY) { model.ID(cID); model.Rotate(X_AXIS, (float) (y - oldY), GLOBAL); oldY = y; } } Hello World – Timer Callback /*---------------------------------------------------------------timer callback function called by Fly2 System every 1/30 second C.Wang 0308, 2004 -----------------------------------------------------------------*/ void GameAI(int skip) { // render the scene FnViewport vp; vp.ID(vID); vp.Render3D(cID, TRUE, TRUE); // perform double-buffering FySwapBuffers(); } Basics in Using Fly2 (1) ■ No Win32 or DirectX background needed for programmers ■ Fly2 is cross-platform ■ Standard ANSI C/C++ ■ SDK / DDK design ■ DDK ■ Platform dependency ■ Win32, Linux, iOS, Android, SONY PSP2 ■ Graphics APIs ■ DirectX 9.0c, DirectX 11 ■ OpenGL 4.0, OpenGL/ES 2.0 (1.1 included) ■ SONY libgxm ■ Multi-threading ■ Audio ■ OpenAL (most platforms) ■ SONY PSP2 audio Basics in Using Fly2 (2) Main program entry is ■ void FyMain(int argc, char *argv[]) Take Win32 platform as an example ■ Only one Fly2 header file included in most cases ■ #include "FlyWin32.h“ ■ But “Fly2.h” is major include file The 1st Fly2 function to call on Win32 ■ FyStartFlyWin32(caption, ox, oy, width, height, beFullScreen) ■ char *Caption is the window’s caption ■ (int ox, int oy) is the window position ■ (int width, int height) is the window size ■ In full screen mode, width/height should be supported by hardware driver ■ ■ ■ Basics in Using Fly2 (3) To render the program in fullscreen mode, set BOOL4 beFullScreen to TRUE, otherwise it runs on window mode. ■ BOOL4 is a boolean variable type in 32-bit. The last function to call using Fly2 on Win32 ■ FyQuitFlyWin32(); ■ ■ Basics in Using Fly2 (4) ■ ID and Function Class ■ Fly2 uses function class to hide the internal data structure of the engine to programmers to keep the usage of Fly2 clear and well-defined. ■ All entities created by Fly2 are returned to users’ program with an ID. ■ ID has the naming rule : XXXXXid ■ XXXXX is the name/type of the entity. ■ For examples: ■ OBJECTid, SCENEid, GAMEFXid, … ■ All entities created by Fly2 are owned by Fly2. ■ The game program owns rights to use it. ■ To manipulate the entity, use the associated function class. ■ Function class is the same idea as Microsoft COM object. ■ Only release member functions to game program ■ FnObject is the function class for OBJECTid. ■ FnScene is the function class for SCENEid. ■ Function class with the naming rule : FnXXXXX Basics in Using Fly2 (5) The usage of ID and function class, taking FnScene as example ■ To Create a scene by Fly2 system ■ SCENEid mainSceneID = FyCreateScene(); ■ And use it by a FnScene function class ■ FnScene scene(mainSceneID); ■ Or ■ FnScene scene; ■ scene.ID(mainSceneID); For most of entities have the dedicated host entity to create it : ■ For examples : ■ A camera is created by a scene ■ FnScene scene; ■ Scene.ID(mainSceneID); ■ OBJECTid cameraID = scene.CreateObject(CAMERA); ■ A camera is a 3D object with camera features, so it uses OBJECTid. ■ ■ Basics in Using Fly2 (6) To control a camera, we design FnCamera function class to inherit FnObject function class ■ class FnCamera : public FnObject ■ Only the host scene creating the camera can delete the camera. ■ scene.DeleteObject(cameraID); But some entities are created by Fly2 system directly ■ Scenes ■ FyCreateScene() / FyDeleteScene() ■ Viewports ■ FyCreateViewport() / FyDeleteViewport() ■ Materials ■ FyCreateMaterial() / FyDeleteMaterial() ■ Text objects ■ FyCreateText() / FyDeleteText() ■ Audio ■ FyCreateAudio() / FyDeleteAudio() ■ ■ Basics in Using Fly2 (7) ■ You can inherit FnXXXXX to create your own class using in your game. ■ For example: ■ class MyCharacter : public FnCharacter ■ Then your character is acting as the standard Fly2 character but with your own data and member function Viewports (1) origin (ox, oy) width height viewport window ■ ■ ■ ■ A viewport is a 2D area for a 3D scene to render on. A viewport is in the size of (width, height) and located at (ox, oy) which is the upper-left corner of the viewport. The unit for viewport is in pixels Viewports are created/deleted by Fly2 system by VIEWPORTid vID = FyCreateViewport(ox, oy, width, height); FyDeleteViewport(vID); Viewports (2) ■ ■ ■ After success to create the viewport, Fly2 will return the viewport ID to game program. Use FnViewport() to use the viewport. Fly2 supports multiple viewports and is no limits for the number of viewports. To render a 3D scene, use FnViewport::Render3D() ■ To render the 3D scene, you need a camera FnViewport vp(vID); // camID is the camera ID (OBJECTid camID) // 2nd argument is TRUE to clear viewport background // 3rd argument is TRUE to clear z buffer vp.Render3D(camID, beClearBackground, beClearZBuffer); To render the depth only, use FnViewport::RenderDepth(); ■ To render sprite system, use FnViewport::RenderSprites(); Use FnViewport::GetSize() to get the viewport size Use FnViewport::SetSize() & FnViewport::SetPosition() to position and size the viewport. ■ ■ ■ Viewports (3) ■ ■ ■ The viewport is rendering to backbuffer in default. But Fly2 supports rendering to multiple rendering targets (textures). ■ You can set the rendering target by : ■ FnViewport::SetRenderTarget(int iOne, TEXTUREid tID); ■ If you are using DX9 version of Fly2, maximum number of rendering targets is 4 (for DirectX11 it’s 8) ■ iOne = 0 ~ 3 for DX9 version Use FnViewport::SetBackgroundColor(r, g, b, a = 1.0f); ■ (float r, float g, float b, float a) is the background color, (r,g,b,a) is in the range (0.0 – 1.0) Scenes (1) ■ A 3D scene is a set of 3D objects including ■ 3D models ■ Light sources ■ Cameras ■ 3D audios ■ Force Backdrop Lights Camera 3D Models Board A 3D Scene ■ To create a scene, use FyCreateScene(int max_renderGroup) system function SCENEid sID = FyCreateScene(max_renderGroup); FyDeleteScene(sID); ■ ■ ■ You can specify the number of rendering groups defined in the scene. The objects in the scene can be assigned a rendering group ID. Objects are rendered in order from 0 to (maximum – 1) rendering group ID Scenes (2) ■ ■ There are four object lists in each rendering group: ■ Opaque object list ■ Rendered at the first. ■ Alpha object list (semi-transparent objects) ■ Sorted from back to front before rendered to make sure alpha blending effect us correct. ■ Invisible object list ■ The objects are invisible and not rendered. ■ Trash object list ■ Objects are temporarily deleted. ■ Used for tool development There is a current rendering group in any scene. The objects are assigned to current rendering group when created and not specified any rendering group. ■ Use FnScene::SetCurrentRenderGroup() to assign the ID. Scenes (3) ■ ■ ■ ■ ■ ■ ■ ■ ■ After success to create a scene, Fly2 will return a SCENEid to the game. Then you can use FnScene() function class to access the scene. Fly2 can create multiple scenes but only one scene rendered simultaneously. Use the scene to create all 3D objects used in the game. ■ FnScene::CreateObject(DWORD type, int renderGroupID = NONE) ■ DWORD type can be OBJECT, CAMERA, LIGHT, AUDIO, FORCE, SPRITE ■ NONE means no specified which rendering group Fly2 uses z-up as default upward direction. (you can change it) Fly2 has the file formats to save the scene in ASCII (.cwn) and in binary (.cw4) A scene can create rooms for collision calculation, dynamics simulation, and space partition. It will be discussed in later chapters. A scene can create the particle system and game FX system which will be discussed in the game FX chapter. A scene can create characters by loading from the character files. This will be discussed in the character chapter. Double Buffering ■ ■ ■ ■ The real-time 3D rendering is using double-buffering technique to make the 3D rendering in smooth visually on graphics hardware. There are two frame buffers : ■ Front buffer for displaying on screen ■ Back buffer for rendering Switch them when all renderings are finished ■ We call this process, the swap-buffer! On Fly2, just simply call FySwapBuffers() to do it. Searching Paths for Loading Data ■ ■ ■ ■ Fly2 supports global paths for searching 3D models, textures, audio, shaders, characters, game FXs and so on. Fly2 will search a common global path, named extra data path, and then search the defined associated path. ■ To set/get the extra data path use : ■ void FySetDataPath(char *path); ■ char *FyGetDataPath(void); Fly2 searches binary file format before search the ASCII format. To set the path : ■ For 3D models : void FySetModelPath(char *path); ■ For audio files : void FySetAudioPath(char *path); ■ For scene files : void FySetScenePath(char *path); ■ For textures : void FySetTexturePath(char *path); ■ For shaders: void FySetShaderPath(char *path); ■ For system shaders: void FySetSystemShaderPath(*path); ■ For characters: void FySetCharacterPath(char *path); ■ For game FXs: void FySetGameFXPath(char *path); Introduction to Fly2 Objects ■ ■ Fly2 objects are major 3D data used in games. An object has the following features : ■ With geometric data ■ Keep an hierarchical relationship with the objects ■ Fly2 Scene Tree ■ Can be transformed (translation, scaling, and rotation) ■ Can be cloned ■ With animation data ■ Skin deformation (with skin weights on vertices) ■ Visibility culling (viewing check) ■ Multiple materials ■ Level-of-detail ■ Temporarily show and hide ■ Movement control on terrains ■ Can be modified in-game Fly2 Coordinate system ■ ■ ■ Fly2 uses right-handed coordinate space Z axis is the up direction in default. Coordinate system ■ Local space (model space) ■ All geometric data are in local space. ■ Global space ■ The parent object’s local space. ■ World space ■ The unique coordinate system used in game. ■ View space (eye space) ■ The camera’s local space ■ Screen space ■ Physical screen space = viewport (left-handed) ■ Logical screen space = camera projection space z y x Fly2 Transformations ■ ■ ■ ■ There are three affine transformations used in Fly2 to control object’s movement in 3D space. ■ Translation ■ Rotation ■ Scale The transformation in Fly2 is in matrix form. Every object in Fly2 keeps one 4x3 matrix to save its transformation in its parent’s space. In Fly2 documents, we call this type of matrix, M12, an 12-element transformation matrix. a0 a3 a6 a9 ■ a1 a4 a7 a10 a2 a5 a8 a11 0 0 0 1 4x3 Fly2 use the following matrix multiplication rule : ■ v’ = v M0 M1 … Translation ■ The translation matrix ■ FnObject::Translate(x, y, z, op, beLocalOnly = FALSE) ■ Translation vector (float x, float y, float z) ■ DWORD op is the matrix multiplication operator ■ op = REPLACE ■ Use the translation matrix to replace the current matrix of the object ■ op = LOCAL ■ The translation is in local space. ■ op = GLOBAL ■ The translation is in global space. ■ BOOL4 beLocalOnly = TRUE means the matrix will not influence the object’s child objects. 1 0 0 x 0 1 0 y 0 0 0 0 1 0 z 1 Rotation with X, Y, or Z Axis ■ FnObject::Rotate(axis, angle, op, beLocalOnly = FALSE) ■ DWORD axis is the axis ID of rotation ■ axis = X_AXIS, Y_AXIS, or Z_AXIS ■ float angle is the rotation angle in degree unit ■ Fly2 uses degree unit in all rotations. ■ DWORD op is the matrix multiplication operator ■ op = REPLACE ■ Use the rotation matrix to replace the current matrix of the object ■ op = LOCAL ■ The rotation is in local space. ■ op = GLOBAL ■ The rotation is in global space. ■ BOOL4 beLocalOnly = TRUE means the matrix will not influence its child objects. Rotation with Quaternion ■ FnObject::Quaternion(w, x, y, z, op, beLocalOnly = FALSE) ■ Fly2 can use a quaternion to perform the rotation with an arbitrary axis. ■ float w is the scalar part of the quaternion vector. ■ (float x, float y, float z) is the vector part of the quaternion vector. ■ DWORD op is the matrix multiplication operator ■ op = REPLACE ■ Use the rotation matrix to replace the current matrix of the object ■ op = LOCAL ■ The rotation is in local space. ■ op = GLOBAL ■ The rotation is in global space. ■ BOOL4 beLocalOnly = TRUE means the matrix will not influence its child objects. Linear Scale ■ FnObject::Scale(sx, sy, sz, op, beLocalOnly = FALSE) ■ (float sx, float sy, float sz) is the scale factor in x, y, z axes. ■ DWORD op is the matrix multiplication operator ■ op = REPLACE ■ Use the scaling matrix to replace the current matrix of the object ■ op = LOCAL ■ The rotation is in local space. ■ op = GLOBAL ■ The rotation is in global space. ■ BOOL4 beLocalOnly = TRUE means the matrix will not influence its child objects. Apply a Transformation Matrix Directly to Fly2 Object ■ ■ ■ We can apply a transformation directly to an object. The matrix is a M12 matrix. FnObject::SetMatrix(M12, op, beLocalOnly = FALSE) ■ float *M12 is the 12-element floating-point array ■ DWORD op is the matrix multiplication operator ■ op = REPLACE ■ Use the matrix to replace the current matrix of the object ■ op = LOCAL ■ The rotation is in local space. ■ op = GLOBAL ■ The rotation is in global space. ■ BOOL4 beLocalOnly = TRUE means the matrix will not influence its child objects. Get the Transformation Matrix from Fly2 Object ■ ■ We can get the transformation matrix from an object. FnObject::GetMatrix(M, beGlobal = FALSE, beWithObjectLocal = FALSE) ■ float *M is the 12-element or 16-element floating-point array. ■ If beGlobal = TRUE, M is the 16-element world matrix of the object. ■ If beGlobal = FALSE, M is the 12-element local matrix of the object. ■ The game programmer must prepare the matrix before calling this function. ■ BOOL4 beGlobal = TRUE mean the returned matrix is a world matrix, otherwise it is a local matrix. ■ BOOL4 beWithObjectLocal = TRUE means the returned matrix will multiply the private local matrix which affects the object only. Fly2 Scene Tree ■ ■ ■ ■ ■ Each scene in Fly2 is a scene tree. Use FnObject::SetParent(OBJECTid pID) function to control the scene tree. ■ OBJECTid pID is the object ID of the parent object. Use OBJECTid FnObject::GetParent() to know the parent object. ■ The function will return the parent’s object ID. An object has its host scene which creates the object. But you can change the host scene in the game. ■ Use FnObject::ChangeScene(SCENEid newSceneID); ■ SCENEid newSceneID is new host scene’s ID. pID nID Object Cloning (1) ■ ■ ■ ■ You can clone an object. Use FnObject::Clone() to clone an object The cloned object should look the same as the original one but can be accessed independently. In default, the cloned object shares the geometric data, materials, textures, and motion data with its host object. Clone nID geometry ■ nID1 motion OBJECTid FnObject::Clone(beGeoCopy = FALSE, beMatCopy = FALSE, beTexCopy = FALSE); ■ The function will return the cloned object’s ID. Object Cloning (2) ■ There are three flags to specify the cloning : ■ BOOL4 beGeoCopy is TRUE to duplicate the geometric data when cloning (not sharing). Then you can modify the geometric data individually. The default is FALSE. ■ BOOL4 beMatCopy is TRUE to duplicate the material data when cloning (not sharing). Then you can modify the material data individually. The default is FALSE. ■ BOOL4 beTexCopy is TRUE to duplicate the texture data when cloning (not sharing). Then you can modify the texture data individually. The default is FALSE. Object with Motion Data ■ ■ ■ ■ ■ ■ The motion data are the animation data prepared by the graphic artists using 3D animation tool. The motion data are saved in object’s file in CW3 (.cw3, ASCII format) or CW4 (.cw4, binary format). In object cloning, motion data are shared by cloned objects. You can play the motion data in-game. ■ “Play motion data” means convert motion data to transformation matrix and apply to the object run-timely. ■ Besides motion, Fly2 can have the other types of “animation” : ■ Vertex animation Fly2 has a simple scheme to play object motion. ■ If you need a more complicated solution to control the motion playing, export the object in character format and load the object as a character in Fly2. For more details, please reference the character chapter. The basic unit for playing motion is “frame”. ■ Basically we use 30 frames per second for the game. This means 30 frames = one second. The artists are following 30 fps to prepare the motion data. Play Object’s Motion ■ ■ Use BOOL4 FnObject::PlayFrame(float frame, float *M12 = NULL) to play object’s motion ■ This function will return the playing result. ■ TRUE for success to play the frame. FALSE for failed to play it. ■ float frame is the frame that needs to play. If frame is in between the data of artists prepared. Fly2 will interpolate it. ■ You can apply an M12 matrix to get the transformation matrix of the motion data to be played if you give the matrix. The default is NULL for the matrix. This mean the motion data will apply to the object directly. After the playing, Fly2 will keep on tracking the playing by save the frame as the current frame. You can retrieve it in the game by : ■ float FnObject::GetCurrentFrame(); Object with Vertex Animation ■ ■ ■ ■ Fly2 can assign multiple vertex dataset for one model. Use this technique to achieve complicated animation data that can be prepared by the artists but can not be performing in-game. To query if the object has multiple vertex dataset : ■ BOOL4 FnObject::CheckVertexAnimation(); If the object has the multiple vertex dataset, use the following function to play the animation. ■ BOOL4 FnObject::NextVertexArray(int skipFrame, DWORD playMode); ■ This function will return TRUE if playing is successful. FALSE means failed to play. Most of failure is playing to the end. ■ int skipFrame is the frame count for this playing to progress. This number should be a positive number. But if you set skipFrame = 0, Fly2 will reset the playing from the first frame. Vertex animation can not be interpolated. ■ DWORD playMode is the playing mode. ■ playMode = LOOP means the playing will loop again if the playing to the end. ■ playMode = ONCE means the playing will end if playing to the last vertex array. More Object Functions (1) ■ ■ ■ ■ ■ Show/hide the object ■ void FnObject::Show(BOOL4 beShow); Set object’s opacity ■ void FnObject::SetOpacity(float o); ■ Fly2 will automatically set alpha blending ON/OFF according to the opacity value. ■ For semi-transparent object, the z-buffer-writing rendering option will be off during the rendering Change rendering group ■ void FnObject::ChangeRenderGroup(int rg); Set rendering mode ■ void FnObject::SetRenderMode(DWORD mode); ■ DWORD mode can be WIREFRAME, POINT_CLOUD or SOLID. Load the model from files ■ BOOL4 FnObject::Load(char *fileName, int LOD_level = NONE); ■ No file extension is need for the file name, fileName. ■ LOD_level is the LOD level assigned to the loaded data More Object Functions (2) ■ ■ Force to set alpha blending ON/OFF ■ void FnObject::SetAlphaFlag(BOOL4 beAlpha, BOOL4 beChangeZBufferWrite = TRUE); ■ BOOL4 beAlpha = alpha blending ON/OFF ■ BOOL4 beChangeZBufferWrite is used to specify whether we will update zbuffer-write render option when alpha flag is changed. TRUE is for changing automatically. Basically when alpha blending is ON, we will turn off the z-buffer-write flag for semi-transparent objects. Set rendering options ■ void FnObject::SetRenderOption(DWORD item, DWORD value); ■ Some rendering options can be setup with this function ■ item = Z_BUFFER ■ Turn ON/OFF z buffer checking ■ item = Z_BUFFER_WRITE ■ Turn ON/OFF z buffer update when rendering More Object Functions (3) ■ ■ ■ ■ ■ item = FOG ■ Turn ON/OFF fog (only valid in fixed function rendering pipeline) item = SPECULAR ■ Turn ON/OFF the specular lighting (only valid in fixed function rendering pipeline) item = LIGHTING ■ Turn ON/OFF the lighting (only valid in fixed function rendering pipeline) item = VIEWING_CHECK ■ Turn ON/OFF the visibility culling flag during the rendering item = SOURCE_BLEND_MODE ■ Setup the blending method of front pixels during the alpha blending ■ The value can be BLEND_ZERO, BLEND_ONE, BLEND_SRC_COLOR, BLEND_INV_SRC_COLOR, BLEND_SRC_ALPHA, BLEND_INV_SRC_ALPHA, BLEND_DEST_ALPHA, BLEND_INV_DEST_ALPHA, BLEND_DEST_COLOR, BLEND_INV_DEST_COLOR, or BLEND_SRC_ALPHA_SAT More Object Functions (4) item = DESTINATION_BLEND_MODE ■ Setup the blending method of backbuffer pixels during the alpha blending ■ The value can be BLEND_ZERO, BLEND_ONE, BLEND_SRC_COLOR, BLEND_INV_SRC_COLOR, BLEND_SRC_ALPHA, BLEND_INV_SRC_ALPHA, BLEND_DEST_ALPHA, BLEND_INV_DEST_ALPHA, BLEND_DEST_COLOR, BLEND_INV_DEST_COLOR, or BLEND_SRC_ALPHA_SAT ■ item = CULLING_MODE ■ Setup the back-face culling mode ■ The value can be CULL_NONE, CULL_CW, or CULL_CCW Load the model from files ■ BOOL4 FnObject::Load(char *fileName, int LOD_level = NONE); ■ No file extension is need for the file name, fileName. ■ Fly2 will search binary file (.cw4) at first and then ASCII file (.cw3) from extra data path to model data path. ■ ■ More Object Functions (5) int LOD_level is the LOD level assigned to the loaded data. The default value is no LOD. LOD technology will be discussed in the later chapter. ■ The loaded data will be appended to the object. Save the model to a file ■ void FnObject::Save(char *fileName); ■ char *fileName should specify with file extension (.cw3 or .cw4). Another easy way to show/hide the object : ■ void FnObject::Twiddle(BOOL4 beON); ■ This function will keep the object in visible list but no rendering in runtime. It’s designed for show/hide the object frequently. An object can be dropped to trashcan to discard. The objects in scene trashcan will not be accessed and not be saved when saving the scene. We can say that they are “deleted” but not really removed from memory. You can restore objects from the scene trashcan. ■ FnObject::DropToTrashCan(BOOL4 beDrop); ■ TRUE for drop to trashcan. ■ FALSE for restore from trashcan ■ ■ ■ ■ Fly2 Camera Objects ■ ■ ■ ■ ■ A camera is a 3D object with camera features. A camera object is using OBJECTid. FnCamera is the camera function class inheriting from FnObject. A camera has full functions of an object besides the camera features. To create a camera, use : ■ OBJECTid FnScene::CreateObject(CAMERA); Far plane View space camera Near plane Fly2 Camera Features (1) ■ ■ ■ ■ There are two projection types supported by Fly2 cameras. ■ PERSPECTIVE and ORTHOGONAL ■ PERSPECTIVE is the default. ■ ORTHOGONAL is used for 2D objects (for example, the sprites). ■ Use FnCamera::SetProjectionType(DWORD type) to change the it. For a perspective projection camera, you can change the rate of perspective by change its FOV angle (field-of-view) ■ void FnCamera::SetFOV(float fov) ■ float fov is the fov angle in degree unit. You can change the near and far plane distances by ■ void FnCamera::SetNearPlane(float d); ■ void FnCamera::SetFarPlane(float d); Setup the aspect rate of rendering area : ■ void FnCamera::SetAspectRatio(float rate) ■ float rate is the ratio of width/height. ■ The default value is 1.333 for NTSC format. Fly2 Camera Features (2) ■ ■ For an orthogonal camera, you can change the scale factor to do the zoom in/out : ■ void FnCamera::SetScaleFactor(float *scaleFactor); ■ float *scaleFactor is a 2-element floating-point array for width and height scaling. ■ This function is only working for an orthogonal projection camera. The default rendering screen range is area centered at camera with (-1.0, 1.0) in range. We define the range in (ox, oy) = (-1.0, -1.0) and size = (2.0, 2.0). ■ You can change with 1 1 -1 (ox, oy) ■ ■ ■ (0, 0) -1 h w void FnCamera::SetScreenRange(float ox, float oy, float w, float h); (float ox, float oy) is the left-corner of the rendering area (float w, float h) is the size of the rendering area. Fly2 Camera Features (3) ■ There are two transformation matrices from the camera. ■ Viewing matrix and projection matrix ■ Use void FnCamera::GetProjectionMatrix(float *P) to get the projection matrix. ■ float *P is a 16-element (4x4) floating-point array to get the matrix back to game program. ■ Use void FnCamera::ReplaceProjectionMatrix(float *P) to replace it. ■ float *P is a 16-element (4x4) floating-point array to set the new matrix ■ Use void FnCamera::GetViewingMatrix(float *V) to get the viewing matrix. ■ float *V is a 16-element (4x4)floating-point array to get the matrix back to game program. Fly2 Light Objects ■ ■ ■ ■ ■ ■ ■ A light is a 3D object with lighting features. A light object is using OBJECTid. FnLight is the light function class inheriting from FnObject. A light has full functions of an object besides the lighting features. To create a light, use : ■ OBJECTid FnScene::CreateObject(LIGHT); Most of the light functions are designed for fixed function rendering pipeline. If you are using shaders for material rendering, you need to import the lighting data to shaders and do the lighting in shaders by your shader code. The fixed function rendering pipeline supports only at maximum 8 light sources can be used at the same time but no limits in programmable rendering pipeline. Fly2 Light Features (1) ■ ■ ■ ■ There are three geometric lighting types supported in Fly2 : ■ POINT_LIGHT, PARALLEL_POINT, and SOPT_LIGHT ■ These three lighting types are corresponding to most fixed function rendering pipelines. But they are meaningless in shaders. ■ Use FnLight::SetLightType(DWORD type) to change the lighting type with the above values. Set light source color ■ void FnLight::SetColor(float r, float g, float b) ■ (float r, float g, float b) is light color. ■ For fixed function rendering pipeline the range for RGB value is from 0.0 to 1.0, but for shader, it’s no limit. Set light source intensity ■ void FnLight::SetIntensity(float intensity); Set lighting range ■ void FnLight::SetRange(float range); Fly2 Light Features (2) ■ ■ ■ Set spot light data ■ void FnLight::SetSpotCone(float innerAngle, float outerAngle, float fallOff); ■ float innerAngle is inner angle of cone of the spot light. From here the lighting is starting to fall off to outer angle. ■ float outerAngle is the maximum angle for the spot light area. ■ float fallOff is the fall off rate of the soft-lighting area of the spot light. Turn ON/OFF a light source ■ void FnLight::TurnLight(BOOL4 beON); Use FnObject’s function of transformation to control lighting position and directions. Property on 3D Model Surface ■ ■ ■ Materials Textures Shaders Fly2 Materials ■ ■ ■ ■ A material in Fly2 is a data structure to define how the looks and the lighting behavior of the object will be. ■ Material components related with lighting ■ Ambient ■ Diffuse ■ Specular and shininess ■ Emissive ■ Texture slots ■ Shaders ■ Opacity Only local illumination Compatible with fixed function rendering pipeline Material data can be passed to shaders Create a Material ■ To create a material use : ■ MATERIALid FyCreateMaterial(float *ambient = NULL, float *diffuse = NULL, float *specular = NULL, float shininess = 100.0f, float *emissive = NULL, float opacity = NONE); ambient, diffuse, specular and emissive all are 3-element floating-point array defined the color components (r, g, b) of the component. ■ Just pass NULL to the components that you are not going to specify. Fly2 will use the default values. ■ When success to define a material, material ID will be returned. Use FyDeleteMaterial(MATERIALid mID) to delete a material. Use FnMaterial() to manipulate the material. ■ ■ ■ Textures ■ ■ ■ A texture is used to describe model surface color and property. ■ On modern hardware, a texture is a buffer/data array in video memory. A texture = an image + addressing + filtering ■ Fragment processing A texture can be saved in system memory, video memory or “managed” memory ■ A “managed” memory = a system memory (for editing/restoring) + a video memory (for rendering) Base color texture Material or vertex colors Texture Issues in Games (1) ■ ■ ■ ■ ■ Multiple layers of textures ■ Texture blending ■ Cost of multi-texturing = cost of single texturing Texture coordinate system ■ Texture coordinate animation ■ Texture transformation matrix Texture animation ■ “texture slot” in Fly2, introduced later Alpha channel in texture : (r, g, b, a) Texture formats ■ Texture size in 2mx2n (not necessary but for optimization) ■ Un-compressed format ■ A8R8G8B8 ■ Compressed (for win32 platform) ■ DirectX DDS format (DirectDraw Surface) ■ Floating-point texture data Texture Issues in Games (2) ■ ■ Colorkeying ■ Alpha blending ON + alpha test ON + Z-buffer Write ON Mipmap ■ Reduce aliasing or Moire effect when rendering Texture Slots in Fly2 Material ■ ■ ■ Fly2 designs a texture slot system for managing texture animation. There is only one texture slot for rendering (current texture) In one texture slot, there are textures in layers for multiple texture blending. layers slot slot slot Textures As Material’s Components (1) ■ ■ ■ Fly2 uses material function class to manage textures. To initialize texture slot system use FnMaterial::InitializeTextures(nSlot, nLayer); ■ int nSlot : number of slots ■ int nLayer : number of layers for each slot Use TEXTUREid FnMaterial::LoadTexture(int slot, int layer, char *texName, BOOL4 beColorkey = FALSE, BYTE *keyValue = NULL, int mipMap = 0, DWORD pool = MANAGED_MEMORY) to load a texture from a file. ■ (int slot, int layer) : texture slot and layer ■ char *texName : texture file name (no extension). On win32 platform, Fly2 will search a texture in the following file formats: DDS, BMP, JPG, TGA ■ BOOL4 beColorkey = TRUE for specifying the texture has a colorkeying value in BYTE array, keyValue. The loader is no colorkeying in default. ■ int mipMap setups the mipmap level. mipMap = 0 is the default value that means all mipmap levels will be generated when loading the texture. ■ DWORD pool specifies the memory pool that texture will be in. There are three memory pools, MANAGED_MEMORY (default), SYSTEM_MEMORY and VIDEO_MEMORY. Textures As Material’s Components (2) After success to load the texture, a texture ID (in TEXTUREid) is returned for game programmers to use FnTexture function class to access the texture. Before loading a texture, Fly2 will check the texture whether it was loaded or not by checking the texture name. In default if the texture has been loaded, Fly2 will not load it but share the texture with the other material. To get a texture from material, use TEXTUREid FnMaterial::GetTexture(int slot, int number); To share a texture with the other material, use FnMaterial::AddTexture(slot, layer, TEXTUREid tID) or FnMaterial::AddTexture(sloat, layer, char *texName) To remove a texture from material, use FnMaterial::RemoveTexture(slot, layer, BOOL4 beDelete = TRUE); ■ (int slot, int layer) specifies the texture to be removed. ■ BOOL4 beDelete = TRUE (default value) means that Fly2 will check whether there are materials share the texture after removing the texture form the material. If no materials use the texture, the texture will be deleted. You can use BOOL4 FnMaterial::SetCurrentTexture(int iFrame) to set current texture. Fly2 will return TRUE if success. iFrame is the frame number of new current texture. ■ ■ ■ ■ ■ ■ Textures As Material’s Components (3) ■ ■ Another method to set current texture is BOOL4 FnMaterial::NextTexture(int skip, DWORD mode). Use this function to do texture animation. ■ int skip is the skip frame from last calling of this function. skip is always larger than 1. But if you set skip to 0, Fly2 will reset the current texture slot to frame 0. ■ DWORD mode is the playing mode : ONCE or LOOP. In LOOP mode, when the texture animation to the last frame, the system will reset to first frame as the next frame. The return value of this function will be always TRUE. If the playing mode is ONCE, the function return value will be FALSE if the system is to the last frame. Use int FnMaterial::GetTextureSlotNumber() to check number of texture slots. Textures As Rendering Targets ■ ■ A texture can be a rendering target of 3D rendering. By assigning textures to a viewport we can render the 3D results on textures. To create a texture as a rendering target, use TEXTUREid FnMaterial::AddRenderTarget(in slot, int layer, char *texName, DWORD format, int w, int h, BOOL4 beAlpha = FALSE, BOOL4 beZ = FALSE); ■ The function will return a texture ID if success. ■ (int slot, int layer) is the texture position in texture slots. ■ char *texName is the texture name used by the rendering target texture. ■ DWORD format is the texture format. (check next page for details) ■ (int w, int h) is the texture size. ■ BOOL4 beAlpha indicates the texture is in semi-transparent or not. FALSE is default. ■ BOOL4 beZ = TRUE will create a z buffer with the rendering target. FALSE is default. Fly2 uses default z buffer for rendering each time. The size of default z buffer is the same as the back buffer. But if the size of rendering target is larger than back buffer, you need a z buffer in larger size. Use this flag to solve this problem. Texture Format Supported in Fly2 ■ Fly2 supports the following texture formats : ■ TEXTURE_32 : true color, A8R8G8B8 ■ TEXTURE_16 : hi-color in 16-bit ■ TEXTURE_COMPRESSED_1 : DDS DXT1 ■ TEXTURE_COMPRESSED_3 : DDS DXT3 ■ TEXTURE_L16I : luminance in 16-bit integer ■ TEXTURE_1F32 : R channel only in 32-bit floating-point ■ TEXTURE_FP16 : R16B16G16A16 RGBA color in 16-bit floating-point each ■ TEXTURE_2F16 : G & R channels in 16-bit floating-point each ■ TEXTURE_64 : R16G16B16A16 RGBA color in 16-bit unsigned integer each ■ TEXTURE_32A : true color : A8R8G8B8 (alpha blending ON) ■ TEXTURE_2F32 : G & R channels in 32-bit floating-point each ■ TEXTURE_COMPRESSD_5 : DDS DXT5 ■ TEXTURE_FP32 : R32B32G32A32 RGBA color in 32-bit floating-point each Shaders As Material’s Components ■ ■ ■ ■ You can assign a shader to a material. Fly2 will use this shader to render the objects that use this material. For more details about shaders, please reference the shader chapter. SHADERid FnMaterial::AddShaderEffect(char *cwsFile, char *techName = NULL); ■ char *cwsFile is the file name of shader description file with .cws extension ■ char *techName is the shader effect name. If you use nVidia Cg, DX11 HLSL, or OpenGL GLSL, please set this argument to NULL. ■ This function will return the shader ID (SHADERId). ■ You can use FnShader function class to access the shader. SHADERid FnMaterial::ReplaceShaderEffect(SHADERid newShader, BOOL4 beD = TRUE); ■ Use this function to change the shader used by the material. ■ SHADERid newShader is the new shader ID. ■ BOOL4 beD = TRUE for deleting the shader being replaced. More Material Functions (1) ■ ■ ■ ■ ■ Get/Set material name : ■ char *FnMaterial::GetName(); ■ void FnMaterial::SetName(char *name); Get/Set ambient component value : ■ float *FnMaterial::GetAmbient(); ■ void FnMaterial::SetAmbient(float *amb); Get/Set diffuse component value : ■ float *FnMaterial::GetDiffuse(); ■ void FnMaterial::SetDiffuse(float *dif); Get/Set specular component value : ■ float *FnMaterial::GetSpecular(); ■ void FnMaterial::SetSpecular(float *spe); Get/Set specular shininess value ■ float FnMaterial::GetShininess(); ■ void FnMaterial::SetShininess(float s); More Material Functions (2) ■ ■ Get/Set emissive component value : ■ float *FnMaterial::GetEmissive(); ■ void FnMaterial::SetEmissive(float *emi); Clone a material : ■ MATERIALid FnMaterial::Clone(BOOL4 beTexCopy = FALSE); ■ BOOL4 beTexCopy = TRUE for duplicating the textures when cloning the material. FALSE is the default. Texture Functions (1) ■ ■ We will add more FnTexture function class member functions very soon. Now we have the following functions ■ Get texture size : ■ void FnTexture::GetTextureSize(int *w, int *h); ■ (int *w, int *h) is the returned result. ■ Set texture addressing mode ■ void FnTexture::SetAddressMode(DWORD mode); ■ DWORD mode can be WRAP_TEXTURE, MIRROR_TEXTURE, CLAMP_TEXTURE, MIRROR_ONCE_TEXTURE or BORDER_TEXTURE ■ Set texture filter ■ void FnTexture::SetFilterType(DWORD type); ■ DWORD type can be FILTER_NONE, FILTER_POINT, FILTER_LINEAR, FILTER_ANSOTROPIC, FILER_FLAT_CUBIC, FILTER_GAUSSIAN_CUBIC ■ Save a texture to a file ■ BOOL4 Save(char *texName, DWORD fileFormat) ■ This texture will be saved to the current texture folder. Texture Functions (2) ■ ■ char *texName is the texture file name. DWORD format is the file format in FILE_BMP, FILE_JPG, FILE_PNG or FILE_DDS. Fly2 Characters ■ A character in Fly2 is a set of objects in hierarchical structure and can be controlled by playing its motion data to perform its behavior in game. ■ A character is a skeleton with some skins and attachments. All components of a character are objects. Programmers can control each object by FnObject function class. A character is loaded via FnScene()::LoadCharacter() from an ASCII character description file (.cwa). A character ID is returned if the loading is successful. Use FnCharacter() function class to access the character. A skeleton can have geometric data. ■ ■ ■ ■ A character in Fly2 uses the root-base scheme. This is based on a biped character concept. Fly2 adds a dummy object (base object of the character, the blue box of the picture above) as the parent object of whole skeleton to control the character’s movement. The Skeleton ■ ■ ■ ■ ■ A skeleton is a tree of objects to construct the “bones” of the character. A bone is an object to construct the skeleton. ■ A bone can have geometric data to construct a rigid character (ie., a car) Each bone of the character has the motion data. Fly2 defines the motion data in poses. (raw poses) ■ For example, the idle pose, walk pose, attack pose, … Fly2 uses frame 0 as the natural pose (or reset pose, T pose). ■ The natural pose is matching to the skin geometry. Base Root (groin) Base Fly2 Skeleton Functions ■ ■ ■ Get number of bones and object ID of each bone : ■ int FnCharacter::GetBoneNumber(); ■ This function will return the bone number. Use this number to run a loop to get the object ID of each bone by calling ■ char *FnCharacter::FindBoneName(int i); ■ OBJECTid FnCharacter::GetBoneObject(char *name); Get number of skins and object ID of each skin : ■ int FnCharacter::GetSkinNumber(); ■ This function will return the number of skin. Use this number to run a loop to get all skins’ object ID. ■ OBJECTid FnCharacter::GetSkin(int i); Get number of attachments and object ID of each attachment : ■ int FnCharacter::GetAttachmentNumber(); ■ This function will return the number of attachment. Use this number to run a loop to get all attachments’ object ID. ■ OBJECTid FnCharacter::GetAttachment(int i); Root-base Scheme ■ ■ ■ ■ ■ ■ ■ A character has several root objects that can move individually. Except the root objects, the other bones will join together. We design a single object, the base object, to be the parents of all roots. The skeleton will perform the animation created by artists or procedurally. The base object will do the movement controls of the character. The easiest way to control the character : ■ Call FnCharacter::Play() to play character animation. ■ Call FnCharacter::MoveForward() to move the character. Use OBJECTid FnCharacter::GetBaseObject() to get object ID of the base. The Body and the Bones ■ ■ ■ ■ A body is a set of bones. We can assign the motion to play for each body. Bodies are constructed in a hierarchical form. (body tree) Body functions : ■ Get number of bodies : ■ int FnCharacter::GetBodyNumber(); ■ Create a body ■ int FnCharacter::CreateBody(char *bodyName, char *boneName); ■ This function returns an integer as a reference number for the body. ■ char *bodyName is the name of body. ■ char *boneName is the first bone of the body. Fly2 Action System ■ ■ Fly2 action system is a system to manage the playing of the character motion. There are four types of actions supported now : ■ SIMPLE_ACTION ■ Play a pose ■ CROSS_BLEND_ACTION ■ Play two poses with a zone of overlapping len fNode rNode ■ ■ FULL_BLEND_ACTION ■ Play two poses as layers with weight for each other CONNECTION_ACTION ■ Play two poses with a length of gap between these poses fNode len rNode Create an Action (1) ■ ■ ■ An action has an action ID and can be accessed with FnAction() . Create a simple action ■ ACTIONid FnCharacter::CreateAction(char *bodyName, char *actionName, char *poseName, BOOL4 beDelete = TRUE); ■ This function returns an action ID if success. ■ char *bodyName is the body using this action. Set NULL for first root body. ■ char *actionName is the name of the action. ■ char *poseName is the pose that will be playing by this action. ■ BOOL4 beDelete = TRUE will delete the action that uses the same action name. TRUE is the default value. Create a cross-fade action ■ ACTIONid FnCharacter::CreateCrossBlendAction(char *bodyName, char *actionName, char *frontPoseName, char *rearPoseName, float length, BOOL4 beDelete = TRUE); ■ This function returns an action ID if success. ■ char *bodyName is the body using this action. Set NULL for first root body. Create an Action (2) char *actionName is the name of the action. ■ char *frontPoseName is the front pose. ■ char *rearPoseName is the rear pose. ■ float length is the length of overlapping. ■ BOOL4 beDelete = TRUE will delete the action that uses the same action name. TRUE is the default value. Create a connected pose action ■ ACTIONid FnCharacter::CreateConnectAction(char *bodyName, char *actionName, char *frontPoseName, char *rearPoseName, int length, BOOL4 beDelete = TRUE); ■ This function returns an action ID if success. ■ char *bodyName is the body using this action. Set NULL for first root body. ■ char *actionName is the name of the action. ■ char *frontPoseName is the front pose. ■ char *rearPoseName is the rear pose. ■ float length is the length of the time gap. ■ ■ Create an Action (3) BOOL4 beDelete = TRUE will delete the action that uses the same action name. TRUE is the default value. Create a full blended action ■ ACTIONid FnCharacter::CreateFullBlendAction(char *bodyName, char *actionName, char *poseName0, char *poseName1, float w0, float w1, BOOL4 beDelete = TRUE); ■ This function returns an action ID if success. ■ char *bodyName is the body using this action. Set NULL for first root body. ■ char *actionName is the name of the action. ■ char *poseName0 is the first pose. ■ char *poseName1 is the second pose. ■ float w0 is the blending weight of first pose. ■ float w1 is the blending weight of second pose. ■ BOOL4 beDelete = TRUE will delete the action that uses the same action name. TRUE is the default value. Delete an action. ■ void FnCharacter::DeleteAction(ACTIONid actionID); ■ ■ ■ Play an Action (1) ■ ■ ■ ■ Fly2 designs multiple channels for the body to play motions. But most of the cases only one channel is enough (channel 0). We can assign current actions for each body to play : ■ ACTIONid FnCharacter::SetCurrentAction(char *bodyName, int channel, ACTIONid actionID, float length = 0.0f, BOOL4 bePlay = TRUE); ■ This function will return the action ID that has been replaced. ■ char *bodyName is the body name. Set NULL for the first root body. ■ int channel is the channel ID. ■ ACTIONid actionID is the action to play. ■ float length is the blending length from last current action. ■ BOOL4 bePlay = TRUE means Fly2 will play the action immediately. TRUE is the default value. Use ACTIONid FnCharacter::GetCurrentAction(char *bodyName, int channel = 0) to get current action of the body. Play an Action (2) ■ Use FnCharacater::Play() to play actions. ■ BOOL4 FnCharacter::Play(DWORD mode, float frame, BOOL4 beBase = TRUE, BOOL4 beSkinDeform = FALSE, BOOL4 beCollide = FALSE); ■ This function returns TRUE for playing successfully. Otherwise it returns FALSE. ■ DWORD mode has three selections : ■ START ■ Start to play the actions. Next argument, frame, is the exact frame position to start. ■ ONCE ■ Play the action once and then stop. ■ LOOP ■ Play the action in loop. ■ float frame ■ If mode = START, frame is the exact frame position to start. ■ Otherwise, frame is the number of skip frames from last play. Play an Action (3) ■ ■ ■ BOOL4 beBase = TRUE to play base object’s animation. TRUE is default. BOOL4 beSkinDeform = TRUE will make skin deformation just right after playing the actions. FALSE is the default. If this value is FALSE, skin deformation will be performed when this character is in rendering. BOOL4 beCollide = TRUE will check collision detection with the other objects. FALSE is the default value. More Character Functions (1) ■ ■ Clone a character ■ CHARACTERid FnCharacter::Clone(BOOL4 beGeoCopy = FALSE, BOOL4 beMatCopy = FALSE, BOOL4 beTexCopy = FALSE); ■ The function will return the cloned character’s ID. ■ There are three flags to specify the cloning : ■ BOOL4 beGeoCopy is TRUE to duplicate the geometric data when cloning (not sharing). Then you can modify the geometric data individually. The default is FALSE. ■ BOOL4 beMatCopy is TRUE to duplicate the material data when cloning (not sharing). Then you can modify the material data individually. The default is FALSE. ■ BOOL4 beTexCopy is TRUE to duplicate the texture data when cloning (not sharing). Then you can modify the texture data individually. The default is FALSE. Change scene ■ We can move the character to another scene. ■ void FnCharacter::ChangeScene(SCENEid newSceneID); More Character Functions (2) ■ ■ Define a pose for whole character ■ int FnCharacter::DefinePose(const char *poseName, int startFrame, int endFrame, int cutFrame, char *motionDatabaseName = NULL); ■ The function will return an integer for reference. ■ const char *poseName is the pose name. ■ int startFrame is starting frame of the pose. ■ int endFrame is the ending frame of the pose. ■ int cutFrame is the cut frame when using motion blending. This number is not using any more. ■ char *motionDatabaseName is the motion database name and set NULL as default. The default motion database is the one coming with the character file. Define a pose for a body ■ void FnCharacter::DefineBodyPose(const char *bodyName, const char *poseName, int startFrame, int endFrame, int cutFrame, char *motionDatabaseName = NULL); More Character Functions (3) char *bodyName is the body name. Set NULL for the first root body. ■ const char *poseName is the pose name. ■ int startFrame is starting frame of the pose. ■ int endFrame is the ending frame of the pose. ■ int cutFrame is the cut frame when using motion blending. This number is not using any more. ■ char *motionDatabaseName is the motion database name and set NULL as default. The default motion database is the one coming with the character file. Delete a body pose ■ BOOL4 FnCharacter::DeleteBodyPose(const char *bodyName, const char *poseName); ■ ■ Movements ■ ■ ■ The transformation is the term used for 3D computer graphics but not friendly to control an object’s movement for the games. Movement : ■ Move forward / move right / Move up ■ Turn right / turn left / tilt We need to define the orientation of an object : ■ Object position Turn right / left ■ Its facing direction ■ Its up direction Move up Move right Move forward Facing Direction and Up Direction ■ ■ ■ ■ Facing direction is used for moving forward The default facing direction of a Fly2 object is local “-y” axis. ■ Except that the camera faces to local “-z” axis The default up direction of a Fly2 object is local “z” axis. ■ Except that the camera uses local “y” axis as up direction. The character’s orientation is the same as the object. Turn right / left Move up Move right Move forward Position Functions (1) ■ ■ For objects ■ Use FnObject::SetPosition(float *pos, BOOL4 beWorld = TRUE) to set object’s position. ■ float *pos is the position. ■ BOOL4 beWorld = TRUE means the position is in world space. FALSE means in local space. TRUE is the default value. ■ Use FnObject::GetPosition(float *pos, BOOL4 beWorld = TRUE) to get object’s position. ■ float *pos is the returned object’s position ■ BOOL4 beWorld = TRUE means to get the position in world space. FALSE is for local space. TRUE is the default value. For characters ■ Use FnCharacter::SetPosition(float *pos, BOOL4 beWorld = TRUE) to set character’s position. ■ float *pos is the position. ■ BOOL4 beWorld = TRUE means the position is in world space. FALSE means in local space. TRUE is the default value. Position Functions (2) ■ Use FnCharacter::GetPosition(float *pos, BOOL4 beWorld = TRUE) to get character’s position. ■ float *pos is the returned character’s position ■ BOOL4 beWorld = TRUE means to get the position in world space. FALSE is for local space. TRUE is the default value. Orientation Functions (1) ■ For objects ■ Use FnObject::SetDirection(float *fDIr, float *uDir, BOOL4 beWorld = TRUE) to set object’s facing and up directions. ■ float *fDir is the facing direction. ■ float *uDir is the up direction. ■ BOOL4 beWorld = TRUE means the directions are in world space. FALSE means in local space. TRUE is the default value. ■ Facing direction doesn’t need to perfectly perpendicular. ■ With this function, Fly2 will set the facing direction at first and then set the up direction. If the programmers need to set the up direction first and then the facing direction. Please call this function twice in the following order : ■ FnObject::SetDirection(NULL, uDir); ■ FnObject::SetDirection(fDir, NULL); Orientation Functions (2) Use FnObject::GetDirection(float *fDir, float *uDir, BOOL4 beWorld = TRUE) to get object’s facing and up directions. ■ float *fDir is the returned object’s facing direction ■ float *uDir is the returned object’s up direction ■ BOOL4 beWorld = TRUE means to get the directions in world space. FALSE is for local space. TRUE is the default value. For characters ■ Use FnCharacter::SetDirection(float *fDir, float *uDir, , BOOL4 beWorld = TRUE) to set character’s facing and up directions. ■ float *fDir is the facing direction. ■ float *uDir is the up direction. ■ BOOL4 beWorld = TRUE means the directions are in world space. FALSE means in local space. TRUE is the default value. ■ ■ Orientation Functions (3) ■ Use FnCharacter::GetDirection(float *fDir, float *uDir, BOOL4 beWorld = TRUE) to get character’s facing and up directions. ■ float *fDir is the returned character’s facing direction ■ float *uDir is the returned character’s up direction ■ BOOL4 beWorld = TRUE means to get the directions in world space. FALSE is for local space. TRUE is the default value. Rooms ■ ■ ■ ■ ■ A scene can create rooms to group objects together for the following purposes : ■ Collision detection ■ Terrain following ■ Implement BSP tree (in developing) Use ROOMid FnScene::CreateRoom(type, numObject) to create a room ■ DWORD type is the room type. Currently Fly2 has two types of rooms : SIMPLE_ROOM and BSP_ROOM. BSP_ROOM is in development for binary space partition. ■ int numObject is the maximum number of objects in the room. ■ When success to create the room, a room ID (ROOMid) is returned. ■ Use FnRoom function class to access the room To delete a room, use void FnScene::DeleteRoom(ROOMid roomID). To add an object to the room, use FnRoom::AddObject(OBJECTid oID); To remove an object from a room, use FnRoom::RemoveObject(OBJECTid oID); Terrain Following (1) ■ ■ ■ A terrain is a place for 3D objects or characters to walk on. Add all terrain objects into a room. Use this room as the “terrain room” for the characters or the objects to walk on. ■ Steps : (for an object) ■ Create a room ■ Insert all terrains to the room ■ Call FnObject::SetTerrainRoom() to assign the object walking on the terrains in the room. ■ Put the object on terrain with FnObject::PutOnTerrain(); ■ void FnObject::SetTerrainRoom(ROOMid rID, float heightLimit, float angle, float frontDIstance, float backDistance); ■ ROOMid rID is the room ID with all terrains. ■ float heightLimit is the relative height limit that the object can move on. ■ float angle is the probe angle for the object to check terrain. ■ float frontDIstance is the probe length in the front of the object. Terrain Following (2) float backDistance is the probe length in the back of the object. ■ These two distances are calculated from the local center of the objects. BOOL4 FnObject::PutOnTerrain(float *pos = NULL, float height = 100.0f, BOOL4 be3D); ■ This function will return the result to put the object on terrains. TRUE for success. ■ float *pos is the position that programmers want to start to put on terrain. The position should be above the terrain. ■ float height is the height of the object above the terrain before putting on terrain. ■ BOOL4 be3D specifies the object is on terrain in 2D or 3D form. ■ ■ Terrain Following (3D) offset Terrain Following (2D) offset Terrain Following (3) For a character, the steps are the same: ■ void FnCharacter::SetTerrainRoom(ROOMid rID, float heightLimit, float angle, float frontDIstance, float backDistance); ■ BOOL4 FnCharacter::PutOnTerrain(float *pos, float height, BOOL4 be3D); To make an object move on terrain : ■ Move forward : ■ int FnObject::MoveForward(float dist, BOOL4 beTF = FALSE, BOOL4 be3D = FALSE, float offset = 0.0f, BOOL4 beCollide = FALSE); ■ This function returns the move result in ■ WALK : success to move ■ BOUNDARY : hit the terrain boundary and fail to move ■ BLOCK : hit another object and blocked ■ DO_NOTHING : something wrong ■ float dist is the moving distance. ■ BOOL4 beTF = TRUE for terrain following, FALSE is default. ■ ■ Terrain Following (3) BOOL4 be3D indicates it’s 2D or 3D terrain following. FALSE (2D) is the default. ■ float offset is the height offset from the terrain if the object is doing terrain following. FALSE is the default. ■ BOOL4 beCollide indicates the object will perform collision detection during the moving. This flag works only when the object is in a collision room. FALSE is the default. Move right : ■ int FnObject::MoveRight(float dist, BOOL4 beTF = FALSE, BOOL4 be3D = FALSE, float offset = 0.0f, BOOL4 beCollide = FALSE); ■ Same arguments as the move forward except moving to the right. Move up : ■ int FnObject::MoveUp(float dist, BOOL4 beCollide = FALSE); ■ This function returns the move result in ■ WALK : success to move ■ BLOCK : hit another object and blocked ■ DO_NOTHING : something wrong ■ ■ ■ Terrain Following (4) float dist is the moving distance. ■ BOOL4 beCollide indicates the object will perform collision detection during the moving. This flag works only when the object is in a collision room. FALSE is the default. ■ Turn the object to its right side ■ int FnObject::TurnRight(float angle); ■ This function returns the move result in ■ WALK : success to move ■ DO_NOTHING : something wrong ■ float angle is the turning angle in degree. Given negative value to turn the object to the left side. For a character to move, the methods are the same ■ FnCharacter::MoveForward(); ■ FnCharacter::MoveRight(); ■ FnCharacter::MoveUp(); ■ FnCharacter::TurnRight(); ■ ■ A Special Issue about a Character’s Movement ■ ■ ■ ■ ■ ■ ■ Usually we ask artists to create characters’ animation with no movements. And use move forward command to move the character. But with this method, the character will not move on terrain without slipping. We can ask artists to create no slipping movement of the characters. And use FnCharacter::MakeBaseMove() function to transfer the root’s movements to the base object (usually in the preprocessing using the tool). Then we don’t need to move the character. Just turn on the base object’s animation flag to on when calling FnCharacter::Play(). In default, Fly2 will move the character using artists’ setting in 3D animation tool. But you can scale the movement with FnCharacter::SetTerrainParameters(sF, sR, sU); ■ (floa sF, float sR, float sU) is the scale factors in facing, right, and up directions. With this method, you can call FnCharacter::QueryLastMoveResult(int *f, int *r, int *u) to check the movement result. Sprites (1) ■ ■ ■ A sprite is a primitive designed for 2D user interface. A sprite can display a set of image sequence to perform as a character’s animation. In Fly2, a sprite object is implemented by inheriting from an object except that : ■ They are using a built-in orthogonal camera for sprite rendering. ■ The sprites have an origin located in the left-bottom corner of the viewport. ■ The size of the sprite world (sprite scene) is defined with FnScene::SetSpriteWorldSize(int w, int h, int z = 1000); ■ (int w, int h) is the size of sprite space. We suggest that the size should be the same as the one of viewport for sprite rendering. ■ int z is the maximum z value. The default value is 1000. ■ The sprites should be rendered using FnViewport::RenderSprites(SCENEid sID, BOOL4 beClear = TRUE. BOOL4 beClearZ = TRUE); ■ SCENEid sID is the scene that creates the sprites. ■ BOOL4 beClear = TRUE indicates to clear the viewport background before rendering the sprites. TRUE is the default. Sprites (2) BOOL4 beClearZ = TRUE indicates to clear the z buffer before rendering the sprites. TRUE is the default. We will not sort sprites before rendering (most of 2D game engine do sorting). ■ We utilize the hardware z buffering to make the sprite rendering in correct order. Therefore the sprite position is defined in 3D (x, y, z); ■ Semi-transparent sprites will be sorted from far to near position to the camera. A sprite is created by a scene with ■ OBJECTid FnScene::CreateObject(SPRITE); ■ This function will return an object ID for the sprite. (OBJECTid) ■ A sprite uses FnSprite function class to access a sprite object. FnSprite inherits from FnObject. We can treat a sprite as an object with sprite features. ■ ■ ■ A sprite Sprite World Sprite Functions (1) ■ ■ ■ ■ Set sprite position ■ void FnSprite::SetPosition(int ox, int oy, int z); ■ (int ox, int oy) is the position of the sprite. ■ int z is the layer of the sprite. Set sprite size ■ void FnSprite::SetSize(int w, int h); ■ (int w, int h) is the sprite size. Set sprite background color ■ void FnSprite::SetColor(float *rgbColor); ■ float *rgbColor is the background color of the sprite in (r, g, b). Set the image displaying on the sprite : ■ TEXTUREid FnSprite::SetImage(char *texName, int nTex = 0, float *uv = NULL, BOOL4 beColorkey = FALSE, BYTE *keyValue = NULL, DWORD poolType = MANAGED_MEMORY, BOOL4 beAlpha = FALSE, DWORD filter = FILETER_NONE, BOOL4 beInvUV = FALSE); Sprite Functions (2) ■ ■ ■ ■ ■ ■ char *texName : texture file name or file header (no extension). int nTex is the number of textures. If nTex = 0, texName is the full file name of the texture and only one image on the sprite. If nTex is larger than 0, there are textures in sequence on the sprite (texture animation). The textures are in name of “texName0000, texName0001, …) BOOL4 beColorkey = TRUE for specifying the texture has a colorkeying value in BYTE array, keyValue. The loader is no color-keying in default. DWORD poolType specifies the memory pool that textures will be in. There are three memory pools, MANAGED_MEMORY (default), SYSTEM_MEMORY and VIDEO_MEMORY. BOOL4 beAlpha indicates the sprite is in semi-transparent or not. FALSE is default. DWORD filter can be FILTER_NONE, FILTER_POINT, FILTER_LINEAR, FILTER_ANSOTROPIC, FILER_FLAT_CUBIC, FILTER_GAUSSIAN_CUBIC. FILTER_NONE is the default value. Shader ■ ■ ■ Fly2 is designed to use programmable rendering pipeline with multi-pass rendering management. Fly2 supports DX9 HLSL, DX11 HLSL, nVidia cg, OpenGL GLSL on different platforms. To make it easier to communicate between Fly2 with shader programs, Fly2 has an ASCII shader description file with file extension .cws to control multipass shader effect and to pass the engine data to shader code. Fly2 Game Engine Shader Descriptor .cws Shader Code Shader Description (.cws) Structure for HLSL Shader Effect PhongTex1.fx HLSL in D3D effect file (.fx) VertexType position normal texture 1 2 Vertex type used in shader Technique 3 0 PhongTex1 1 colorMap 0 0 1 PhongTex1Alpha 1 colorMap 0 0 Technique declaration Constant 14 0 E Matrix LocalToScreen mWVP 1 E Matrix Global mWorld 2 E Light Position MainLight mainLightPosition 3 E Light Color MainLight mainLightColor 4 … … 13 E BeTexture 0 beColormap Constants definition for shaders Shader Technique Declaration in CWS File Technique 2 0 1 PhongTex1 Phongtex2 1 colorMap 2 colorMap Technique name In .fx file C 0 0 1 Texture name in the shader Texture layer Texture layers Used in the technique Technique ID Technique Slot C = current texture Shader Constants in CWS File Constant 4 0 1 2 3 E E E E Matrix Matrix Light Light LocalToScreen Global Position Color Object Name In Fly2 Constant Category Shader Type Constant ID MainLight MainLight Constant Type mWVP mWorld mainLightPosition mainLightColor Variable Name In Shader Use HLSL Effect Shader in Fly2 ■ ■ In the code, call FnMaterial::AddShaderEffect(char *cwsFileName); In the material definition in the CW3 model file : Material 2 ShaderEffect ShaderEffect Keyword To Use Shader Phong_tex1 Phong Texture box Ambient 0.3 0.3 0.3 … Phong_texNo Phong2 Ambient 0.3 0.4 0.3 … CWS File Name Technique used Multi-pass Rendering in Fly2 ■ ■ Fly2 supports hybrid rendering pipeline if the hardware platform supports both fixed rendering pipeline and programmable rendering pipeline. ■ On Win32 + DX9 and Win32 + OpenGL, Fly2 supports hybrid rendering. ■ On Win32 + DX11, Fly2 supports programmable rendering only. ■ On Linux, Fly2 supports hybrid rendering. ■ On iOS, Fly2 supports programmable rendering only. ■ On Android, Fly2 supports programmable rendering only. ■ On SONY PSP2, Fly2 supports programmable rendering only. To do multi-pass rendering with Fly2, you need ■ Create multiple rendering targets ■ Output for rendering ■ Input for next rendering ■ Set rendering targets to a viewport Rendering Functions in Fly2 ■ ■ ■ For different rendering purpose, FnViewport supports several rendering functions : ■ General 3D rendering : ■ FnViewport::Render3D(OBJECTid cameraID, BOOL4 beC, BOOL4 beCZ); ■ Sprite rendering : ■ FnViewport::RenderSprites(SCENEid sceneID, BOOL4 beC, BOOL4 beCZ); If you want to use one specific shader to render your data : ■ FnShader::Render(VIEWPORTid vID, OBJECT cameraID, int numObj, OBJECTid *allObj, BOOL4 beC, BOOL4 beCZ, MATERIALid inputMaterialID = FAILED_ID); Render Textures to textures ■ FnShader::Rdner(VIEWPOTRid vID, MATERIALid inputMaterialID); Fly2 Geometric Data (1) ■ ■ ■ ■ ■ You can create geometric elements in Fly2 : ■ Lines ■ Indexed triangles ■ NURBS curves and surfaces ■ Billboard ■ Label ■ Label is an integer to mark the geometric element in FnObject. When successfully creating a geometric element, FnObject will return a geometry ID (GEOMETRYid). You can use this id with FnGeometry / FnLine / FnTriangle to access it. (We will add FnBillboard in the near future) Each geometric element uses one material. If you load a model file with multiple materials, Fly2 will sort the geometric data into several geometric elements and each element has one material. You can call FnObject::GetGeometryNumber() to know the number of geometric element. ■ Then write a loop to use GEOMETRYid FnObject::GetGeometryID(int i) to get all geometric element. Fly2 Geometric Data (2) Or prepare an array (in GEOMETRYid type) to get the all geometries. ■ int FnObject::GetGeometries(GEOMETRYid *geo, int length_of_geo); ■ This function returns the number of geometries in geo array. ■ GEOMETRYid *geo is the geometry id array to get the result. ■ int length_of_geo is the length of geo array. Call void FnObject::RemoveAllGeometries() to delete all geometric data. Call BOOL4 FnObject::RemoveGeometry(GEOMETRYid gID) to remove one geometric element. ■ ■ ■ Fly2 Lines ■ GEOMETRYid FnObject::Lines(int type, MATERIALid mID, float *v, int nV, BOOL4 beUpdate = TRUE, BOOL4 *beVC = FALSE) ■ This function returns the geometry id of the lines. ■ int type is type of lines: LINE_SEGMENTS, OPEN_POLYLINE, or CLOSE_POLYLINE LINE_SEGMENTS ■ ■ ■ ■ ■ OPEN_POLYLINE CLOSE_POLYLINE MATERIALid mID is the material id for the lines float *v is the vertex data. int nV is the number of vertices. BOOL4 beUpdate = TRUE means this function will update object’s bounding box after generating the lines. TRUE is the default. BOOL4 beVC = TRUE means the vertex with vertex color in (r, g, b). FALSE is the default. Fly2 Indexed Triangles (1) ■ GEOMETRYid FnObject::Triangles(int vType, MATERIALid mID, int nVA, int nV, int nTex, int *texLen, float *v, int nT, int *triTable, int tangent = 0, BOOL4 beUpdate = TRUE, BOOL4 *beRV = NULL) ■ This function returns the geometry id of the triangles. ■ int vType is type of vertices: XYZ, XYZ_RGB, XYZ_NORM ■ XYZ is the vertex with vertex position (x, y, z) only ■ XYZ_RGB is the vertex with vertex position (x, y, z) and vertex color (r, g, b) ■ XYZ_NORM is the vertex with vertex position (x, y, z) and vertex normal (nx, ny, nz) ■ MATERIALid mID is the material id for the lines ■ int nVA is the number of vertex arrays. nVA > 1 means the object has vertex animation. ■ int nV is the number of vertices in each vertex array ■ int nTex is number of texture coordinates for each vertex. ■ int *texLen is the array saving the vector length for each texture coordinate. ■ float *v is the vertex data. Fly2 Indexed Triangles (2) ■ ■ ■ ■ ■ int nT is number of triangles. int *triTable is the index table of triangles. Its length is nT*3. int tangent is a number to indicate if there’re tangent and bi-normal data with the vertex. tangent = 0 is no tangent and bi-normal vectors. tangent = 1 is tangent vector only. tangent = 2 is tangent and bi-normal vectors. Tangent and bi-normal vectors are used for tangent-based normal map rendering. BOOL4 beUpdate = TRUE means this function will update object’s bounding box after generating the triangles. TRUE is the default. BOOL4 *beRV is the boolean array saving if we need to reverse the vcomponent for texture coordinates. NULL is the default. ■ Fly2 uses right-handed coordinate system for texture mapping as the same as the most 3D animation software but DirectX does not (lefthanded). To make the texture mapping rendering correct, we need to reverse the v-component of the texture coordinates. (v = 1 – v) ■ But if the texture coordinate is not used for rendering, we don’t need to reverse it. Fly2 Billboards (1) ■ ■ Fly2 Billboards are always facing to the camera and in rectangle form. GEOMETRYid FnObject::Billboard(float *pos, float *size, char *tex, int nTex = 0, float *color = NULL, BOOL4 beKey = FALSE, BYTE *rgb = NULL, int bType = INDEPENDENT, BOOL4 beUpdate = TRUE) ■ This function returns a geometry id of the billboard. ■ float *pos is the local origin of the billboard. The default is the center. ■ float *size is the billboard size (width, height). ■ char *tex is the texture file name (with no file extension) ■ int nTex is the number of textures. nTex = 0 means “tex” is the full file name of the texture. If nTex >= 1, the texture files are in the naming format : tex0000, tex0001, … ■ float *color is the background color of the board in (r, g, b) format. ■ BOOL4 beKey = TRUE means the billboard with color-keying. FALSE is the default. ■ BYTE *rgb is the color-keying value. NULL is the default. ■ int bType is the billboard type : INDEPENDENT or DEPENDENT. INDEPENDENT is the default. Fly2 Billboards (2) Basically a billboard will rotate itself to facing camera independently. If you need to make all billboards rotate with the first billboard in the same object. Please assign the first billboard of the object as INDEPENDENT and the other billboards in the same object as DEPENDENT. ■ BOOL4 beUpdate = TRUE means this function will update object’s bounding box after generating the billboard. TRUE is the default. Fly2 has another type of billboard, “billboard cloud”, which is used for particle rendering. ■ ■ Fly2 Label ■ ■ ■ A label geometric element is an integer inserted into geometric elements for game programmers to control the structure of the object geometry. GEOMETRYid FnObject::Label(int lable); You can remove or show/hide some geometric elements in game by: ■ FnObject::RemoveGeometryBetweenLabel(int label1, int label2); ■ FnObject::ShowGeometryBetweenLabel(int label1, int label2, BOOL4 beShow); Access the Geometry (1) ■ ■ ■ ■ You can use FnGeometry() function class to access all geometric data. Get geometric element type : ■ DWORD FnGeometry::Type(); ■ The return values will be INDEXED_TRIANGLES, BILLBOARD, LINES, NURBS_CURVE, NURBS_SURFACE, BILLBOARD_CLOUD or LABEL Show/hide a geometric element individually ■ void FnGeometry::Show(BOOL4 beShow); Get material used by the element ■ MATERIALid FnGeometry::GetMaterial(); Access the Geometry (2) ■ Lock the vertex array to get the vertex data from rendering engine ■ You need to lock the vertex array before access the vertex data. ■ float *FnGeometry::LockVertexArray(int *vLen = NULL, int *nV = NULL, int vID = 0, BOOL4 beReadOnly = FALSE); ■ This function will return the address of vertex array for editing. If Fly2 fails to lock the vertex array, NULL will be returned. ■ int *vLen is the variable pointer to get the returned vertex length. ■ int *nV is the variable pointer to get the returned number of vertices. ■ int vID indicates which vertex buffer will be locked. 0 is the default. ■ BOOL4 beReadOnly = TRUE means the lock operation is going to read the vertex data only. FALSE is the default. ■ Use FnGeometry::UnlockVertexArray() to finish the access to the vertices. ■ You must unlock the vertex array when finishing the job. Access the Geometry (3) ■ Lock the index array to get the primitive data from rendering engine ■ You need to lock the index array before access the topology data. ■ int *FnGeometry::LockIndexArray(int *tLen = NULL, int *nT = NULL, BOOL4 beReadOnly = FALSE, BOOL4 *beRV = NULL); ■ This function will return the address of index array for editing. If Fly2 fails to lock the index array, NULL will be returned. ■ int *tLen is the variable pointer to get the returned primitive length. ■ int *nT is the variable pointer to get the returned number of primitives. ■ BOOL4 beReadOnly = TRUE means the lock operation is going to read the index data only. FALSE is the default. ■ BOOL4 *beRV is a variable pointer to check the index table is in righthanded or left-handed. Since Fly2 is using right-handed, you need to reverse the index table if *beRV = FALSE for a left-handed rendering API, for example, Direct3D. ■ Use FnGeometry::UnlockIndexArray() to finish the access to the primitives. ■ You must unlock the index array when finishing the job. Fly2 Text (1) ■ ■ ■ ■ ■ ■ Fly2 can utilize the hardware supported true type font to render text. You can use TEXTid FyCreateText(const char *fontName, int size, BOOL4 beBold, BOOL4 beItalic) to create the font for rendering. ■ This function returns an id for programmers to show text on screen. ■ Use FnText() member function to access the text object. ■ const char *fontName is the name of the font ■ int size is the font size ■ BOOL4 beBold = TRUE for bolded font ■ BOOL4 beItalic = TRUE for italic font Use FyDeleteText(TEXTid textID) to delete a font object. Use void FnText::Begin(VIEWPORTid vID) to start the rendering of the text ■ vID is the viewport for text rendering Use void FnText::End() to finish the text rendering Use int FnText::Write(char *text, int ox, int oy, BYTE r, BYTE g, BYTE b, BYTE a = 255) to render the text. ■ A text must be rendered between the Begin() and End() commands. Fly2 Text (2) ■ ■ ■ ■ ■ Use int FnText::Write(char *text, int ox, int oy, BYTE r, BYTE g, BYTE b, BYTE a = 255) to render the text. char *text is the string to be rendered. (int ox, int oy) is the position to render, which the left-bottom corner of the text block. (r, g, b, a) is the font color used, which is ranging from 0 – 255. a is the alpha value with default value 255 (opaque). This function will return the x position of the last pixel of the text block for next writing reference. Fly2 Audio (1) ■ ■ ■ ■ Fly2 supports playing the WAV audio in game. To create an audio object, use ■ AUDIOid FyCreateAudio(void) ■ This function returns an audio ID (in AUDIOid). ■ Use FnAudio() function class to access the audio object. ■ Use void FyDeleteAudio(AUDIOid aID) to delete an audio object. To load a WAV sound file: ■ BOOL4 FnAudio::Load(char fileName); ■ This function will search current audio path to find the audio file. ■ And return TRUE if the loading is successful. To play the audio : ■ void FnAudio::Play(DWORD mode) ■ DWORD mode can be ONCE or LOOP. ■ void FnAudio::Stop() to stop the audio playing ■ void FnAudio::Pause() to pause the playing ■ BOOL4 FnAudio::IsPlaying() to check if the audio is playing or not. Fly2 Audio (2) ■ ■ ■ Use FnAudio::SetVolume(float v) to set the sound volume. float v is volume value. This value should be different in unit and range on different hardware platforms. Be careful to use it. An audio object can clone another audio object to share the same audio buffer. ■ AUDIOid FnAudio::Clone(); Fly2 supports 3D audio. These functions will be released in next build version. Fly2 Object Data ■ Fly2 object can keep customer-defined data structure inside the object : ■ Initialize a block of memory inside the object : ■ void *FnObject::InitData(int length_in_byte); For example : Struct MyData { … }; ■ ■ MyData *data = (MyData *) object.InitData(sizeof(MyData)); memset(data, 0, sizeof(MyData)); … Get data pointer : ■ void *FnObject::GetData(); Release the data ■ void FnObject::ReleaseData(); ■ When deleting the object, the data will be deleted automatically. Fly2 LOD (Level-Of-Detail) ■ ■ ■ ■ ■ Fly2 builds discrete LOD in the Fly2 object : To define the LOD levels : ■ void FnObject::UseLOD(int numberLevel); ■ int numberLevel is the number of LOD levels To assign the LOD level to the model when loading the model file : ■ BOOL4 FnObject::Load(char *file, int lodLevel = NONE); To set the distance for LOD level switching : ■ void FnObject::SetLODData(int level, float distance); Perform the LOD checking before rendering ■ void FnObject::PerformLOD(float *camera_position); ■ float *camera_position is the position of the camera used for rendering. Fly2 Files ■ ■ ASCII files ■ 3D models ■ Fly2 model file .cw3 ■ Wavefront OBJ file .obj ■ Fly2 scene file .cwn ■ Characters ■ Fly2 character files .cwa/.cwc/.cwk/.cw3 ■ Shader description file .cws ■ Game FX file .cwf (.cfx is old version) Binary files ■ .cw4 is the only one binary file format ■ For 3D models, scenes, characters(.cwc + .cwk + all .cw3) ■ Backward compatibility Fly2 CW3 Model File ■ Comments For 3D models # CW3 model file, designed by Chuan-Chang Wang # Created : 0616, 2004 # Version Model v 1 Vertex type Materials Vertices Primitives VertexType position normal texture 1 2 Material 1 ShaderEffect Phong_tex1 Phong Texture bbb02 Vertex 1 6 -20.0 20.0 0.0 0.0 0.0 1.0 0.0 1.0 -20.0 -20.0 0.0 0.0 0.0 1.0 0.0 0.0 0.0 -20.0 0.0 0.0 0.0 1.0 0.5 0.0 20.0 -20.0 0.0 0.0 0.0 1.0 1.0 0.0 20.0 20.0 0.0 0.0 0.0 1.0 1.0 1.0 0.0 20.0 0.0 0.0 0.0 1.0 0.5 1.0 Polygon 2 400125 402345 Fly2 CWN Scene File – Simplified Version ■ For a 3D Scene : Comments # TheFly3D 3D scene log file - exported from 3dsMax, Chuan-Chang Wang # Date : 1027, 2005 # Version Scene v 1.0 Object 7 ObjectFile 1 Cylinder01 ObjectFile 2 Bone01 ObjectFile 3 Bone02 ObjectFile 4 Bone03 ObjectFile 5 Bone04 ObjectFile 6 Bone05 ObjectFile 7 Bone06 All models in the scene Saved in cw3 files Fly2 CWN Scene File – Full Version Comments Version # TheFly3D 3D scene log file - exported from 3dsMax, Chuan-Chang Wang # Date : 1027, 2005 # Scene v 1.0 Object number Object 7 BeginObject 1 Model … EndObject … BeginRelationship o 1 0 o 2 1 … EndRelationship Object block with the same format as CW3 All objects Scene tree Fly2 Character Files (1) ■ ■ CWA (.cwa) ■ A character description file ■ Body and bone structure ■ Actions and poses used by bodies ■ Character file (.cwc or .cw4) ■ Skin and attachment files (.cw3 or .cw4) ■ Game FXs linked to the character (in development) ■ Character behavior (in development) CWC (.cwc) ■ Old version character file ■ Graphics only ■ A skeleton (.cwk) ■ Skin and attachment files (.cw3 or .cw4) Fly2 Character Files (2) ■ ■ CWK (.cwk) ■ A character skeleton file used by .cwc ■ Skeleton structure ■ Poses exported from 3D animation tools ■ All motion data for each bone in the skeleton CW4 (.cw4) ■ The binary version of (.cwc + .cwk + all skins and attachments) Fly2 Binary Files ■ ■ ■ Fly2 binary files use the same file extension .cw4. Fly2 uses data chunk to manage the data type and version : Data chunk header : struct iFDataChunkHead { DWORD type; DWORD id; int len; }; ■ Data chunk type reserved for Fly2 system : ■ From 0 - 65535 Introduction to Fly2 GameFX ■ ■ ■ ■ ■ Fly2 built-in Game FX system including (Fly2 Build version 1004) ■ Plate FX ■ Particle FX ■ Audio FX ■ Force FX ■ Geometry FX ■ Force FX A game FX system is a combination of FXs. Use Fly2 “Fly2Toolkit” Toolkit to edit the FXs. Fly2 data searching path for game FXs is FySetGameFXPath(char *path). A game FX system is managed by a scene object. ■ To create a game FX, use FnScene::CreateGameFXSystem(). Fly2 will return a gameFX ID (type = GAMEFX_SYSTEMid). ■ Use FnGameFXSystem() function class to access the game FX system object. ■ To delete a game FX, use FnScene::DeleteGameFXSystem(GAMEFX_SYSTEMid gxID); Use Fly2 Game FX (1) – Load FX ■ ■ ■ ■ A game FX system is always using Fly2 Toolkit to create/edit the FXs. .cwf is the file extension for a game FX file. We suggest (at least current version) all assets for a game FX system should be located at the same file folder. To load a game FX file (.cwf), please use FnGameFXSystem::Load(). ■ BOOL4 FnGameFXSystem::Load(char *fileName, BOOL4 beReset, GAMEFXid *fxArray = NULL, int numFX = 0); ■ This function will return TRUE if loading is successful. ■ char *fileName is the name of the game FXs. ■ BOOL4 beReset = TRUE to reset the game FXs after the loading. ■ GAMEFXid *fxArray is an array (in GAMEFXid) to get all game FX IDs in the game FX file. The default value is NULL means no return. ■ int numFX is the array length of fxArray. ■ Basically, if you want to get all FXs during the loading, you can call FnGameFXSystem::QueryFXNumberInFile(char *fileName) to get number of FXs saving in the FX file. Then provide an game FX ID array to get all of them when calling FnGameFXSystem::Load(). Use Fly2 Game FX (2) - Play ■ ■ ■ ■ Use FnGameFXSystem::Play() to play FXs continuously. ■ BOOL4 FnGameFXSystem::Play(float skipFrame, DWORD playMode); ■ This function will return FALSE if playing to the end of all FXs. ■ float skipFrame is the skip frame count after last playing. ■ DWORD mode is the playing mode : ONCE or LOOP. In LOOP mode, FXs will playing in loop. ■ Basically if you stop calling this function, all FXs will be paused except that the audio FXs. To pause the audio FXs’ playing, use FnGameFXSystem::Pause(). Call Play() to continue the playing. Use FnGameFXSystem::Reset() to reset the playing to the 1st frame (frame 0). Use FnGameFXSystem::PlayFrame() to play the FXs in a specific frame. ■ BOOL4 FnGameFXSystem::PlayFrame(float iFrame); ■ This function will return FALSE if the playing is failed. ■ float iFrame is the absolute frame position. Use FnGameFXSystem::SetParentObjectForAll(OBJECTid pID) to assign the parent object all FXs. Then the FXs will follow the parent object’s transformation. Use Fly2 Game FX (3) – Get FX ■ ■ Use FnGameFXSystem::GetFXNumber() to get number of FXs in a game FX system. ■ int FnGameFXSystem::GetFXNumber() will return the number of FXs. Use FnGameFXSystem::GetFX() or FnGameFXSystem::GetFXByName(). These functions will return the GAMEFXid of the game FX. For example, GAMEFXSYSTEMid gxID; … int i; FnGameFXSystem gx(gxID); GAMEFXid allFX[1024]; int numFX = gx.GetFXNumber(); for (i = 0; i < numFX; i++) { allFX[i] = gx.GetFX(i); } ■ GAMEFXid is the ID of a game FX. Use FnBaseGameFX() to access the general functions of the game FX and use the associated function class (inherited from FnBaseGameFX()) to access the other FX functions. FnBaseGameFX() (1) ■ The common used functions of FnBaseGameFX() are ■ To get the FX’s parent object’s name, use ■ char *FnBaseGameFX::GetParentObjectName() ■ Basically in FX editing tool, the tool can assign the parent object name to the FX and temporary link the FX to that object (in the tool) to show the result. But in your game, you need to link the FX to the object by your code. The method to do it is that if the FX has a parent object, use this function to get the name of the FX’s parent object. Use the name with FnScene or FnCharacter associated member function to get the object ID. Then use FnBaseGameFX::SetParentObject(OBJECTid pID) to finish the linking. ■ To Check the FX type, use ■ DWORD FnBaseGameFX::GetFXType(); ■ There’re six types of FX supporting by Fly2 (Build 1004) : ■ PLATE_FX : playing texture animation on plate on the ground or billboard. ■ AUDIO_FX : sound FX FnBaseGameFX() (2) PARTICLES_FX : particle system and can be controlled by FORCE_FX ■ FORCE_FX : create force fields to control the particles ■ GEOMETRY_FX : use the geometry objects (with animation) created by the artists in animation tools(for example, the 3ds Max) to playing the texture animation. ■ SWORD_FX : tracking two dummy objects in game to simulate the weapon motion blur effect. To get the FX Type of the FX, use ■ DWORD FnBaseGameFX::GetFXType(); There is one dummy object as the parent of the game FX. You can get its object ID and control manually in game : ■ OBJECTid FnBaseGameFX::GetBaseObject(); Each FX has its life which should be edited in Fly2 FX editing tool (cwViewer). You can adjust it in game by using : ■ float FnBaseGameFX::GetLife(); to get the FX’s life. ■ FnBaseGameFX::AdjustLife(float newLifeValue) to adjust the life. This function in default will automatically adjust the FX’s key-frame . ■ ■ ■ ■ FnPlateGameFX() ■ ■ ■ PLATE_FX is a plate on the ground or billboard object to playing texture animation. To check the plate type use : DWORD FnPlateGameFX::GetPlateType(). ■ Return value should be BILLBOARD, PLATE_ZUP, or PLATE_YUP. Use OBJECTid FnPlateGameFX::GetPlateObject() to get the object ID of the plate. FnGeometryGameFX() ■ ■ GEOMETRY_FX is a FX type to playing texture animation on a geometric model. The model is created by the artists with animation tools (for example, Autodesk 3ds Max) and exported by Fly2 exporters. To get the model, use OBJECTid FnGeometryGameFX::GetModelObject(); FnParticlesGameFX() ■ ■ ■ PARTICLES_FX is a FX type to generate particles as game FXs. All features and functions of particle system can be edited in Fly2 tool. But you still can use FnParticlesGameFX::GetParticleSystem() to get the particle system in the FX. This function will get the ID of the particle system in PARTICLE_SYSTEMid. You can use FnParticleSystem function class to use more advanced features and functions. FnForceGameFX() ■ ■ ■ FORCE_FX is a FX type to generate the force field data for particle system. Fly2 provides gravity, parallel forces, sinking forces, vortex forces, and viscosity in the following types : ■ GRAVITY, PARALLEL, SINK, SPHERE, VORTEX, VORTEX_2D, VISCOSITY The best way to experience these force types is learning the Fly2 FX editing tool. FnAudioGameFX() ■ ■ ■ ■ ■ ■ ■ ■ AUDIO_FX is a FX type to simulate the weapon effect in motion blur. We implement this motion blur effect in geometry solution. This effect needs two dummy objects existing in the scene and moving in-game. This FX will trace the positions of these two dummies and form a ribbon in fading transparency. In the Fly2 FX editing, you can assign the names of these two dummy objects and save in the FX file. In the game when you need to use the sword FX, you should have the dummy objects in games and connect them to the FX manually. The dummy objects can be attachments of a character or some objects in the scenes. If the dummy objects are attachments of a character, you can use FnSwordGameFX::GetCharacterName() to get the name of the character. Use FnSwordGameFX::GetDummyObject1Name() to get the name of the 1st dummy object. Use FnSwordGameFX::GetDummyObject2Name() to get the name of the 2nd dummy object. In game, you can use these two names to find the object IDs of the dummy objects. And use FnSwordGameFX::SetDummyObject1(OBJECTid oID) and FnSwordGameFX::SetDummyObject2() to link the FX to game objects. FnAudioGameFX() ■ ■ AUDIO_FX is a FX type to play sound FX in game. Fly2 plays WAV sound FX in almost game platform.