C++ Game Animation Programming - Second Edition

Book description

Build your own OpenGL or Vulkan application in C++ and learn the latest techniques in character animation for modern games with this detailed, color guide

Key Features

  • Learn how to create a game skeleton with keyboard and mouse controls along with modern graphics
  • Gain insights into model loading, character animations, inverse kinematics, and debugging techniques
  • Master the art of creating animated characters and controlling their various aspects
  • Purchase of the print or Kindle book includes a free PDF eBook

Book Description

If you‘re fascinated by the complexities of animating video game characters and are curious about the transformation of model files into 3D avatars and NPCs that can explore virtual worlds, then this book is for you. In this new edition, you’ll find expanded content on high-performance graphics and modern animation techniques, along with improved workflows and enhanced guidance on using OpenGL and Vulkan. You’ll learn everything you need to know about game animation, from a simple graphical window to a large crowd of smoothly animated characters.

First, you’ll learn how to use modern high-performance graphics, dig into the details of how virtual characters are stored, and load the models and animations into a minimalistic game-like application. Then, you’ll get an overview of the components of an animation system, how to play the animations and combine them, and how to blend from one animation into another. You’ll also get an introduction to topics that will make your programming life easier, such as debugging your code or stripping down the graphical output.

By the end of this book, you’ll have gained deep insights into all the parts of game animation programming and how they work together, revealing the magic that brings life to the virtual worlds on your screen.

What you will learn

  • Create simple OpenGL and Vulkan applications and work with shaders
  • Explore the glTF file format, including its design and data structures
  • Design an animation system with poses, clips, and skinned meshes
  • Find out how vectors, matrices, quaternions, and splines are used in game development
  • Discover and implement ways to seamlessly blend character animations
  • Implement inverse kinematics for your characters using CCD and FABRIK solvers
  • Understand how to render large, animated crowds efficiently
  • Identify and resolve performance issues

Who this book is for

This book is for curious C++ developers, game programmers, game designers, and character animators, either pursuing this as a hobby or profession, who have always wanted to look behind the curtain and see how character animation in games works. The book assumes basic C++ and math knowledge, and you should be able to read code and math formulas to get the most out of this book.

Table of contents

  1. C++ Game Animation Programming
  2. Contributors
  3. About the authors
  4. About the reviewers
  5. Preface
    1. Who this book is for
    2. What this book covers
    3. To get the most out of this book
    4. Download the example code files
    5. Conventions used
    6. Get in touch
    7. Share Your Thoughts
    8. Download a free PDF copy of this book
  6. Part 1:Building a Graphics Renderer
  7. Chapter 1: Creating the Game Window
    1. Technical requirements
      1. Getting the source code and the basic tools
      2. Code organization in this book
      3. The basic code for our application
      4. NULL versus nullptr
    2. Creating your first window
    3. Adding support for OpenGL or Vulkan to the window
      1. GLFW and OpenGL
      2. GLFW and Vulkan
    4. Event handling in GLFW
      1. The GLFW event queue handling
      2. Mixing the C++ classes and the C callbacks
    5. The mouse and keyboard input for the game window
      1. Key code, scan code, and modifiers
      2. Different styles of mouse movement
    6. Summary
    7. Practical sessions
    8. Additional resources
  8. Chapter 2: Building an OpenGL 4 Renderer
    1. Technical requirements
    2. The rendering pipeline of OpenGL 4
    3. Basic elements of the OpenGL 4 renderer
      1. The OpenGL loader generator Glad
      2. Anatomy of the OpenGL renderer
      3. The main OpenGL class
      4. Buffer types for the OpenGL renderer
    4. Loading and compiling shaders
      1. Vertex and fragment shaders
      2. Creating our shader loader
      3. Creating the simple Model class
      4. Getting an image for the texture
    5. Summary
    6. Practical sessions
    7. Additional resources
  9. Chapter 3: Building a Vulkan Renderer
    1. Technical requirements
    2. Basic anatomy of a Vulkan application
    3. Differences and similarities between OpenGL 4 and Vulkan
      1. Technical similarities
      2. Differences
    4. Using helper libraries for Vulkan
      1. Initializing Vulkan via vk-bootstrap
      2. Memory management with VMA
    5. Fitting the Vulkan nuts and bolts together
      1. General considerations about classes
      2. Changes in the Window class
      3. Passing around the VkRenderData structure
      4. Vulkan object initialization structs
      5. Required changes to the shaders
      6. Drawing the triangles on the screen
      7. Differences and similarities between OpenGL and Vulkan, reprised
    6. Summary
    7. Practical sessions
    8. Additional resources
  10. Chapter 4: Working with Shaders
    1. Technical requirements
    2. Shader basics
    3. GLM, the OpenGL Mathematics library
      1. GLM data types and basic operations
      2. GLM transformations
    4. Vertex data transfer to the GPU
    5. Switching shaders at runtime
      1. Creating a new set of shaders
      2. Binding the shader switching to a key
      3. The shader switch in the draw call
      4. Shader switching in Vulkan
    6. Sending additional data to the GPU
      1. Using uniform buffers to upload constant data
      2. Creating a uniform buffer
      3. Shader changes to use the data in the buffer
      4. Preparing and uploading data
      5. Using uniform buffers in Vulkan
      6. Using push constants in Vulkan
    7. Summary
    8. Practical sessions
    9. Additional resources
  11. Chapter 5: Adding Dear ImGui to Show Valuable Information
    1. Technical requirements
    2. What is Dear ImGui?
    3. Adding ImGui to the OpenGL and Vulkan renderers
      1. Adding the headers to the OpenGL renderer
      2. Adding the headers to the Vulkan renderer
      3. CMake adjustments needed for ImGui
      4. Moving the shared data to the OGLRenderData header
      5. Creating the UserInterface class
      6. Adding the implementation of the UserInterface class
      7. Adding the UserInterface class to the OpenGL renderer
    4. Creating an FPS counter
      1. Using GLFW as a simple timer
      2. Adding the values to the user interface
    5. Timing sections of your code and showing the results
      1. Adding the Timer class
      2. Integrating the new Timer class into the renderer
    6. Adding UI elements to control the application
      1. Adding a checkbox
      2. Adding a button to switch between the shaders
      3. Adding a slider to control the field of view
    7. Summary
    8. Practical sessions
    9. Additional resources
  12. Part 2: Mathematics Roundup
  13. Chapter 6: Understanding Vector and Matrix
    1. Technical requirements
    2. A review of the vector and its operations
      1. Representations of vectors
      2. Adding and subtracting vectors
      3. Calculating the length of a vector
      4. Zero and unit vectors
      5. Vector normalization
      6. Vector multiplication
    3. A review of the matrix and its operations
      1. Matrix representation
      2. Null matrix and identity matrix
      3. Matrix addition and subtraction
      4. Matrix multiplication
      5. Transposed and inverse matrices
      6. Matrix/vector multiplication
    4. Adding a camera to the renderer
      1. Creating the new Camera class
      2. Integrating the new camera into the Renderer class
      3. Implementing mouse control in the Window class
      4. Showing the camera values in the user interface
    5. Adding camera movement
      1. Using new variables to change the camera position
      2. Moving the camera around
      3. Adding the camera position to the user interface
    6. Summary
    7. Practical sessions
    8. Additional resources
  14. Chapter 7: A Primer on Quaternions and Splines
    1. Technical requirements
    2. What are quaternions?
      1. Imaginary and complex numbers
      2. The discovery of the quaternion
      3. Creating a quaternion
      4. Quaternion operations and transformations
    3. Exploring vector rotation
      1. The Euler rotations
      2. The gimbal lock
      3. Rotating using quaternions
      4. Incremental rotations
    4. Using quaternions for smooth rotations
    5. A quick take on splines
    6. Constructing a Hermite spline
      1. Spline continuity
      2. Hermite polynomials
      3. Combining quaternions and splines
    7. Summary
    8. Practical sessions
    9. Additional resources
  15. Part 3: Working with Models and Animations
  16. Chapter 8: Loading Models in the glTF Format
    1. Technical requirements
    2. An analysis of the glTF file format
    3. Exploring an example glTF file
      1. Understanding the scenes element
      2. Finding the nodes and meshes
      3. Decoding the raw data in the buffers element
      4. Understanding the accessor element
      5. Translating data using the buffer views
      6. Checking the glTF version in the asset element
    4. Using a C++ glTF loader to get the model data
    5. Adding new glTF shaders
    6. Organizing the loaded data into a C++ class
      1. Learning about the design and implementation of the C++ class
      2. Adding the new model class to the renderer
      3. Adding the glTF loader and model to the Vulkan renderer
    7. Summary
    8. Practical sessions
    9. Additional resources
  17. Chapter 9: The Model Skeleton and Skin
    1. Technical requirements
    2. These skeletons are not spooky
      1. Why do we create a node tree of the skeleton?
      2. Adding the node class
      3. Filling the skeleton tree in the Gltf model class
      4. The inverse bind matrices and the binding pose
    3. How (not) to apply a skin to a skeleton
      1. Naive model skinning
      2. Vertex skinning in glTF
      3. Connecting joints and nodes
      4. Joints and weights for the vertices
      5. Creating the joint transformation matrices
      6. Applying vertex skinning
    4. Implementing GPU-based skinning
      1. Moving the joints and weights to the vertex shader
      2. Getting rid of the UBO fixed array size
    5. Identifying linear skinning problems
      1. The dual quaternion
      2. Using dual quaternions as data storage
      3. Dual quaternions in GLM
      4. Adding dual quaternions to the glTF model
      5. Adding a dual quaternion shader
      6. Adjusting the renderer
    6. Summary
    7. Practical sessions
    8. Additional resources
  18. Chapter 10: About Poses, Frames, and Clips
    1. Technical requirements
    2. A brief overview of animations
      1. What is a pose and how do we represent it?
      2. From a single frame to an entire animation clip
    3. Pouring the knowledge into C++ classes
      1. Storing the channel data in a class
      2. Adding the class for the animation clips
      3. Loading the animation data from the glTF model file
      4. Adding new control variables for the animations
      5. Managing the animations in the user interface
      6. Adding the animation replay to the renderer
    4. Summary
    5. Practical sessions
    6. Additional resources
  19. Chapter 11: Blending between Animations
    1. Technical requirements
    2. Does it blend?
      1. Fading animation clips in and out
      2. Crossfading between animation clips
      3. Adding multiple animation clips into one clip
    3. Blending between the binding pose and animation clip
      1. Enhancing the node class
      2. Updating the model class
      3. Adding the blend to the animation clip class
      4. Implementing animation blending in the OpenGL renderer
    4. Crossfading animations
      1. Upgrading the model classes
      2. Adjusting the OpenGL renderer
      3. Adding new controls to the user interface
    5. How to do additive blending
      1. Splitting the node skeleton – part I
      2. Splitting the node skeleton – part II
      3. Updating the animation clip class
      4. Finalizing additive blending in the OpenGL renderer
      5. Exposing the additive blending parameters in the user interface
    6. Summary
    7. Practical sessions
  20. Part 4: Advancing Your Code to the Next Level
  21. Chapter 12: Cleaning Up the User Interface
    1. Technical requirements
    2. UI controls are cool
    3. Creating combo boxes and radio buttons
      1. Implementing a combo box the C++ way
      2. Swapping the data types
      3. Filling the arrays for the combo boxes
      4. Fine-tuning selections with radio buttons
      5. Adjusting the renderer code
      6. Updating the model class
      7. Switching the control elements in the user interface
    4. Drawing time series with ImGui
      1. One ring buffer to rule them all
      2. Creating plots in ImGui
      3. Adding plots to the user interface
      4. Popping up a tooltip with the plot
    5. The sky is the limit
    6. Summary
    7. Practical sessions
    8. Additional resources
  22. Chapter 13: Implementing Inverse Kinematics
    1. Technical requirements
    2. What is Inverse Kinematics, and why do we need it?
      1. The two types of Kinematics
      2. Choosing a path to reach the target
    3. Building a CCD solver
      1. Understanding the CCD basics
      2. Updating the code of the node class
      3. Updating the model class
      4. Outlining the new solver class
      5. Implementing the Inverse Kinematics solver class and the CCD solver
      6. Adding Inverse Kinematics to the renderer
      7. Extending the user interface
    4. Building a FABRIK solver
      1. Understanding the FABRIK basics
      2. Adding the methods for the FABRIK algorithm
      3. Implementing the FABRIK solving methods
      4. Completing the FABRIK solver
      5. Updating the renderer
      6. Allowing the selection of FABRIK in the user interface
    5. Summary
    6. Practical sessions
    7. Additional resources
  23. Chapter 14: Creating Instanced Crowds
    1. Technical requirements
    2. Splitting the model class into two parts
      1. Deciding which data to keep in the model class
      2. Collecting the data to move
      3. Adding a new ModelSettings struct to store the instance data
      4. Adjusting the OGLRenderData struct
      5. Cutting the model class into two pieces
      6. Implementing the logic in the new instance class
      7. Enhancing the shader code
      8. Preparing the renderer class
      9. Changing the renderer to create and manage instances
      10. Displaying the instance data in the user interface
      11. What about Vulkan?
      12. The need for application speed
    3. Rendering instances of different models
    4. Using GPU instancing to reduce data transfers
      1. Changing the model class to use instanced drawing
      2. Firing the turbo boost in the renderer
    5. Textures are not just for pictures
      1. YABT – Yet Another Buffer Type
      2. Updating the vertex shader one last time
    6. Summary
    7. Practical sessions
    8. Additional resources
  24. Chapter 15: Measuring Performance and Optimizing the Code
    1. Technical requirements
    2. Measure twice, cut once!
      1. Always measure before you take actions
      2. Three steps of code optimization
      3. Avoid premature optimizations
    3. Moving computations to different places
      1. Recalculate only when necessary
      2. Utilize compile time over runtime
      3. Convert your data as soon as possible
      4. Split the calculations into multiple threads
      5. Use compute shaders on your graphics card
    4. Profiling the code to find hotspots
      1. Profiling code using Visual Studio
      2. Profiling code using GCC or Clang on Linux
      3. Profiling code using Eclipse
      4. Analyzing the code and planning the optimizations
      5. Promoting the local matrices to member variables
      6. Moving the matrix calculations
      7. Fixing the getNodeMatrix() method
      8. Re-profiling the application
    5. Using RenderDoc to analyze a GPU frame
      1. Downloading and installing RenderDoc
      2. Analyzing frames of an application
      3. Comparing the results of different versions of our application
    6. Scale it up and do A/B tests
      1. Scale up to get better results
      2. Make one change at a time and profile again
    7. Summary
    8. Practical sessions
    9. Additional resources
  25. Index
    1. Why subscribe?
  26. Other Books You May Enjoy
    1. Packt is searching for authors like you
    2. Download a free PDF copy of this book

Product information

  • Title: C++ Game Animation Programming - Second Edition
  • Author(s): Michael Dunsky, Gabor Szauer
  • Release date: December 2023
  • Publisher(s): Packt Publishing
  • ISBN: 9781803246529