Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống
1
/ 20 trang
THÔNG TIN TÀI LIỆU
Thông tin cơ bản
Định dạng
Số trang
20
Dung lượng
727,12 KB
Nội dung
Fast-forwarding in time again brings us to 1998, when Sierra Studios released the game Half-Life (developed by Valve). Half-Life was built on top of a highly modified version of the Quake engine. Most notably, the game developers added a new skeletal animation system, allowing them to reuse animations on different characters. As the name implies, skeletal animation is closely linked to the workings of a skeleton. An average human body has about 206 bones. The states and locations of all these bones define the pose of a person. As the bones move from one location in space to another, the surrounding muscles, tissue, and the outer skin move with it. This basic idea is the key to skeletal animation. The only difference is that for computer games you are just interested in the skin layer (i.e., what the player sees). In Chapter 3, you will learn how to “skin a character.” See Figure 1.6 for an example of the wireframe rendering of a skinned character. Notice how the skin (mesh) follows the bones as they move. Since the days of the first Half-Life game, characters have been getting more polygons, larger textures, normal maps, advanced shaders, and more to make them look better and better every year. However, the basic underlying technologies haven’t changed much. These two techniques—skeletal animation and morphing animation—are widely used today in game development, and this book will cover both. They both have their advantages and disadvantages. At the end of this book, you will know how to create characters that make use of both techniques—e.g., skeletal animation for overall movement, and morphing animation for more subtle things like facial expressions. 6 Character Animation with Direct3D FIGURE 1.5 An example of morphing animation. Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark. THE SOLDIER I will refer to the example character used throughout this book as “the Soldier.” What looks like yet another futuristic-hero-figure-in-power-armor is…well, actually just that: another futuristic-hero-figure-in-power-armor. The design for the Soldier was based on old roman soldiers, which you might detect from the shoulder pads and helmet. Design and texturing for the Soldier was done by Markus Tuppurainen for our adventure game, Day of Wrath. Although that game was never finished (yes, yes, I don’t manage to finish all the games I start either), the model still has its uses for this book. The important thing is that he has all the necessary limbs, some animations, skinned meshes (body and face), and some static meshes (helmet and pulse rifle). The model complexity ranges somewhere in the low to medium range by today’s standards: Body Mesh: 2100 Polygons Head Mesh: 1000 Polygons Num Bones: 26 Height: 1.8 Units Chapter 1 Introduction to Character Animation 7 FIGURE 1.6 Three frames of a character animation using skeletal animation. Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark. CODING CONVENTIONS Throughout this book I will use a subset of the Hungarian notation standard (and I’ll try to be consistent). The High Level Shading Language (HLSL) effects in this book will depart slightly from this standard and use the notation used in Engel’s shader books. See Table 1.1 for the coding conventions used in the C++ examples of this book. 8 Character Animation with Direct3D FIGURE 1.7 The Soldier. Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark. So your average C++ class would look something like the following: class SomeClass { public: SomeClass(); ~SomeClass(); void SomeFunction1(int someParameter); bool SomeFunction2(); private: int m_memberVariable; float* m_pMemberPointer; }; Chapter 1 Introduction to Character Animation 9 TABLE 1.1 CODING CONVENTIONS Type Prefix Example Class Names N/A class SomeClass{ … }; Function Names N/A void SomeFunction(int someParameter){ … } Constant Names N/A const int CONSTANT_INTEGER = 32; Member Variables m_ int m_someInteger; Global Variables g_ float g_globalFloat; Static Variables s_ char s_staticChar; Pointer Variable p SomeClass* pPointerToObject; Member Pointer m_p float* m_pMemberPointerToFloat; Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark. 10 Character Animation with Direct3D CONCLUSIONS Hopefully after reading this chapter you’ve gained some perspective on the topic of character animation and the work in this field that has come before us. However, after this brief warm-up, it is time to get started and to get your hands dirty. In the next chapter, you’ll be briefly introduced to Direct3D as well as the necessary steps to create a 3D application, most of which will probably be repetition for you. At the end of the next chapter, you will have a character rendered to your screen (albeit a very stiff one). Then, after Chapter 2, more functionality will be added to our now somewhat inanimate Soldier in each chapter, bringing him more and more to life. FURTHER READING [Schoenblum07] Schoenblum, Daniel E. “.md2 File Format Specification.” Available online at http://www.linux.ucla.edu/~phaethon/q3/formats/md2-schoenblum.html, 2007. [Leimbach02] Leimbach, Johannes. “Character Animation with DirectX 8.0.” Available online at http://www.gamedev.net/reference/articles/article1653.asp, 2002. Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark. 11 A Direct3D Primer2 This chapter covers what you need to know before continuing with the rest of this book, or, in other words…the groundwork. I’ll offer a quick glance at the things you should already know (setting up Direct3D, the windows loop, and more). If any of the concepts covered in this chapter don’t make sense, well, then you need to take a break and brush up on these. As mentioned earlier, you will need to be comfortable with both object-oriented C++ as well as DirectX 9. So before you tackle the more savory subjects of this book, let’s look at the basics first. In this chapter I’ll cover the application framework, creating the window, setting up the Direct3D device, and more. However, since these subjects don’t really belong to the Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark. core of this book, I will just brush past them and show you the minimum amount of code required to get up and running. Pay special attention to the application framework though, since this is the skeleton class upon which all the other examples in this book are built. This chapter includes the following: Getting started Application framework Rendering with Direct3D Please note that all code throughout this book is written with clarity in mind, not optimization (or stability). Also to keep things brief, no error checking is done. For example, I rarely check the return values of Direct3D/D3DX functions but simply assume that they completed successfully. Similarly I assume that there is enough memory to create new classes, meshes, textures, etc. So please be mindful of this fact if you plan to use the code from this book in your own projects. DIRECTX 9 VERSUS DIRECTX 10 In this book I will use DirectX 9 to do all rendering and resource management. You might ask, why?—the newer DirectX 10 is already out! Well, to be honest the amount of extra work and support code required to cover the same topics in DirectX 10 simply makes it too grand a job to attempt. In DX9 a lot of support code exists in the D3DX library, much of which has been deprecated in DX10 (to the disappointment of us hobby programmers). The biggest missing piece needed for this book is the loading of .x files (no, not the TV series, but the file format used by DX9 to store models). At the writing of this book, there’s still not any easy way of doing this with DX10. Anyway, if you can write your own mesh importer, you probably don’t need my help to port the examples in this book anyway, and if not, well, then DX9 will have to serve. Another reason to stick with DX9 is that the majority of computers out there still don’t have a DX10-compatible graphics card and probably won’t for at least another couple of years. However, no matter which version of DirectX you use to do your rendering, you will still benefit from the lessons in this book. The classes and structures presented in this book are nonspecific to DX9 and can easily be ported to other rendering systems such as DX10 or even OpenGL. 12 Character Animation with Direct3D Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark. STL AND THE D3DX LIBRARY Reinventing the wheel is something that I greatly enjoy doing myself. I’ll spare you this, however, since you might not have the same fetish. I’ll therefore rely heavily on the Standard Template Library (STL) for all my data container classes and the Direct3D eXtension (D3DX) Library for math functions, resource loading functions, etc. Here’s a simple use of the stl::vector class, if you haven’t seen it before: //Create a vector of integers vector<int> intVector; //push some numbers intVector.push_back(3); intVector.push_back(1); intVector.push_back(2); //Sum up the numbers in the vector int sum = 0; for(int i=0; i<intVector.size(); i++) { sum += intVector[i]; //Access each int with the [] operator } This is a pretty simple example demonstrating a vector of integers. It’s not very useful in practice, however; it’s more common that you have a vector of pointers to a user-defined class. Take a look at the following three classes: //Monster Interface class IMonster { public: IMonster(); virtual void Update(float deltaTime) = 0; virtual void Render() = 0; protected: D3DXVECTOR2 m_position; }; //Your run o’ the mill savage goblin class Goblin : public IMonster { Chapter 2 A Direct3D Primer 13 Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark. public: Goblin(float startHealth); void Update(float deltaTime); void Render(); private: float m_health; }; //Your ghost on the attic (can be friendly or unfriendly) class Ghost : public IMonster { public: Ghost(bool isFriendly); void Update(float deltaTime); void Render(); private: bool m_friendly; }; The Ghost and the Goblin classes both inherit from the IMonster interface. The functions Update() and Render() are declared in the IMonster class as purely virtual functions that have to be implemented in the classes inheriting from it. But you should know all this already. If not, you might want to brush up on some basic object-oriented concepts like inheritance, polymorphism, etc. [Llopis03]. Anyway, getting back to the STL vector, here’s how you would create, update, and render a bunch of monsters: //Create a vector of monster pointers vector<IMonster*> monsters; //create some monsters monsters.push_back(new Goblin(55.0f)); monsters.push_back(new Goblin(35.0f)); monsters.push_back(new Ghost(true)); monsters.push_back(new Ghost(false)); monsters.push_back(new Goblin(62.0f)); //Iterate through the monsters and call update and render for(int i=0; i<monsters.size(); i++) 14 Character Animation with Direct3D Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark. { monsters[i]->Update(deltaTime); monsters[i]->Render(); } The ghost and the goblin can have completely different updating and rendering functions. However, since they both implement the IMonster interface, the monster vector doesn’t care which exact class each item in the vector represents. You’ll see a lot of STL containers used in similar ways throughout this book (vector, queue, map, etc.). That pretty much covers how I’ll be using the STL library. The D3DX library, on the other hand, is a collection of functions, structures, and classes that will also be richly used throughout this book. You can recognize the D3DX functions, etc. by their prefix (yep, you guessed it) D3DX as seen in: D3DXMATRIX, D3DXVECTOR3, D3DXVec3Normalize(), D3DXMatrixIdentity(), and much more. I’ll try to introduce all these new functions as they are used in the book (instead of covering them all here). Remember that you always have the DirectX SDK documentation where all these functions and structures are covered in great detail. SETTING UPAPROJECT IN VISUAL STUDIO EXPRESS 2008 If you already know how to set up a project in Visual Studio and get up and run- ning with it, then feel free to skip this section. DirectX applications are now quite simple to make for free with Visual Studio Express 2008. If you have other versions of Visual Studio, the steps to set up a DirectX project are the same. Note, however, that earlier versions of Visual Studio Express such as 2005, etc. can’t build Win32 applications without some extra hassle. So unless you own a copy of Visual Studio, you’re better off sticking to VS Express 2008. You can download VS Express 2008 from: http://www.microsoft.com/express/vc/. Go ahead and install it. Next you need the DirectX SDK, found here: http://msdn.microsoft.com/en-gb/directx/default.aspx. Follow the DirectX SDK links and install this as well. VC++ D IRECTORIES When you build you’re project you’ll need header and library files from the Direct SDK. To ensure that Visual Studio can find and link these files, follow these steps: Chapter 2 A Direct3D Primer 15 Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark. [...]... a Win32 application to run your game through, you’ll need a class to deal with the main program loop, initialization of the graphics device, and more For this purpose I’ll use the Application class Once again, keep in mind that I ease purchase PDF Split-Merge on www.verypdf.com to remove this watermark 20 Character Animation with Direct3D do a minimum of error checking in this class to keep it light,... 0, 0, PM_REMOVE)) { //If there's a message, deal with it and send it onward TranslateMessage(&msg); DispatchMessage(&msg); } else //Otherwise update the game { //Calculate the delta time DWORD t = GetTickCount(); float deltaTime = (t - startTime) * 0.001f; ease purchase PDF Split-Merge on www.verypdf.com to remove this watermark 22 Character Animation with Direct3D //Update the application app.Update(deltaTime);... DefWindowProc() function, ease purchase PDF Split-Merge on www.verypdf.com to remove this watermark 24 Character Animation with Direct3D which is basically the default procedure for all window events After registering your window class and assigning it a window procedure, you can create an instance of this window type with the CreateWindow() function: m_mainWindow = CreateWindow("D3DWND", "Window Title", WS_EX_TOPMOST,... Next Select Windows Application as the Application Type Click “Empty Project” in Additional Options Click Finish ease purchase PDF Split-Merge on www.verypdf.com to remove this watermark 17 18 Character Animation with Direct3D FIGURE 2.3 The Application Wizard You have now created a new project Before you can start to compile and build DirectX applications, however, you need to link the DirectX libraries...16 Character Animation with Direct3D 1 Open up Visual Studio Express 2 Click Tools, and then select Options 3 Select “VC++ Directories” from the list at the left (under Project and Solutions) 4 Select “Include Files”... more Since I do expect you to have some experience with Direct3D before tackling this book, I will keep this section brief Refer instead to the DirectX SDK documentation or one of the many introductory books available if something is unclear For an introductory book on Direct3D game programming, I recommend Frank Luna’s Introduction to 3D Game Programing with Direct X 9.0c: A Shader Approach [Luna06] Please... are released So how is the Application class used? Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark Chapter 2 A Direct3D Primer 21 WINMAIN For those who are already familiar with the basics of windows programming, I apologize for the upcoming sections and beg you to skip ahead For the rest of you…read on The WinMain() function is the entry point of your Win32 program It is... do After an Application class has been created, the Init() function must be called In this function, resources are loaded and the graphics device is created Each frame the Update() function is called with the delta time since the previous frame, before the Render() function is called The Update() function takes care of updating the world (i.e., the game), moving objects, updating the physics engine,... A Shader Approach [Luna06] Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark Chapter 2 A Direct3D Primer CREATING THE DIRECTX DEVICE Initializing the Direct3D device is done with the following steps: 1 Create the Direct3D interface 2 Fill out the D3DPRESENT_PARAMETERS structure 3 Create the Direct3D Device Here’s the code for these steps: //Create IDirect3D9 Interface IDirect3D9* . create characters that make use of both techniques—e.g., skeletal animation for overall movement, and morphing animation for more subtle things like facial expressions. 6 Character Animation with. Bones: 26 Height: 1.8 Units Chapter 1 Introduction to Character Animation 7 FIGURE 1.6 Three frames of a character animation using skeletal animation. Please purchase PDF Split-Merge on www.verypdf.com. remove this watermark. 10 Character Animation with Direct3D CONCLUSIONS Hopefully after reading this chapter you’ve gained some perspective on the topic of character animation and the work in