Design and architecture of a portable and extensible multiplayer 3d game engine thesis

147 40 0
Design and architecture of a portable and extensible multiplayer 3d game engine thesis

Đang tải... (xem toàn văn)

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

Thông tin tài liệu

CONTENTS Introduction 1.1 1.2 1.3 1.4 3D Computer game engines and graphics research What this thesis is about How this thesis is structured Overview of implementation 3 PART I: Foundations and Related Work Algorithms 2.1 2.2 Hierarchical subdivision Occlusion culling High-performance Low-level Graphics APIs 10 3.1 3.2 3.3 3.4 Glide OpenGL Direct3D Geometry processing Game Technology Evolution 13 4.1 4.2 Seminal 3D computer games Consumer 3D hardware 10 11 11 11 13 21 PART II: Design and Architecture of Parsec Overview 26 5.1 5.2 5.3 5.4 5.5 5.6 The engine The game The vision How to build a game How to build an engine Chapters outline Architecture Overview 33 6.1 6.2 6.3 6.4 The game code The engine code Engine core Low-level subsystems Architecture Details 41 7.1 7.2 7.3 7.4 7.5 7.6 Code structure and conventions Dynamic vs static subsystem binding Abstract rendering and shaders Portability Extensibility The game loop 26 28 29 29 30 31 33 34 35 37 41 43 45 46 48 48 Low-level Subsystem Specifications 50 8.1 8.2 Host system encapsulation Graphics API encapsulation Managing Objects 58 9.1 9.2 9.3 9.4 Object types and classes The world Generic graphical object Object API 10 The ITER Interface 70 10.1 10.2 10.3 Specifying how primitives should be rendered ITER rendering primitives ITER rendering functions 11 Shaders 90 11.1 11.2 11.3 11.4 11.5 11.6 11.7 Components of a shader Shader definition Shader implementation Color animations Texture animations Attaching a shader The art of writing a shader 12 The Particle System 100 12.1 12.2 12.3 12.4 12.5 12.6 12.7 Basic definition of a particle Particle clusters Particle appearance animation Particle behavior animation How the particle system uses particle clusters Derived particle cluster types Particle system API 13 Networking 121 13.1 13.2 13.3 Game-code interface Parsec protocol layer Packet API layer 14 The Command Console 127 14.1 14.2 User command registration Console API 50 55 58 59 60 65 70 80 87 92 92 94 94 96 98 99 101 102 103 103 107 108 111 123 125 126 128 131 PART III: Conclusion 15 Concluding Remarks 136 16 Bibliography 138 Design and Architecture of a Portable and Extensible Multiplayer 3D Game Engine by Markus Hadwiger Institute of Computer Graphics Vienna University of Technology I would like to dedicate this thesis and corresponding work to my parents, Dr Alois and Ingrid Hadwiger, without whom nothing of this would have been possible Abstract This thesis is about the design and architecture of a 3D game engine – the technology behind a computer game featuring three-dimensional graphics Over the last couple of years, the development of 3D computer games and graphics research have come ever closer to each other and already merged in many respects Game developers are increasingly utilizing the scientific output of the research community, and graphics researchers have discovered computer games to have become an important application area of their scientific work As the technology employed by computer games becomes more and more involved, the design and architecture of the underlying engines attains a crucial role Increasingly, extremely modular designs encapsulating system-dependencies are chosen in order to allow for portability from one target platform to another Extensibility has also become important, since many game engines are used for more than one game It also helps foster a community of game players that develops extensions for their favorite game and keeps the game alive for a much longer period of time The topic of this thesis is a particular game engine – the Parsec Engine –, focusing on architectural and design aspects This engine emphasizes and allows for portability by employing a very modular architecture It is also a multiplayer game engine, i.e., it contains a powerful networking component through which multiple players can play together Extensibility is achieved in many respects, although the Parsec Engine is not a completely general game engine aiming to be a framework for every kind of game imaginable, but rather attempts to achieve high performance for a specific type of game Since it has been developed in close conjunction with an actual computer game – Parsec, a multiplayer 3D space combat game – it favors outer space settings with spacecraft While the focus is on architecture and design, another goal has been to describe crucial aspects at a level of detail that allows for using the engine to develop new game play features and special effects, as well as extending the engine itself Kurzfassung Diese Diplomarbeit handelt von Design und Architektur einer 3D Computerspiele-Engine – jener Technologie, die hinter einem Computerspiel steht, das dreidimensionale Graphik einsetzt In den letzten Jahren haben sich die Entwicklung von 3D Computerspielen und die Computergraphik-Forschung immer mehr angenähert und sind in vielerlei Hinsicht bereits verschmolzen Spieleentwickler nutzen in zunehmendem Ausmaß die wissenschaftlichen Resultate der Forschergemeinschaft, und auch die Forscher in der Computergraphik haben entdeckt, daß Computerspiele mittlerweile ein wichtiges Anwendungsgebiet ihrer Arbeit geworden sind Da die Technologie die in Computerspielen eingesetzt wird immer komplexer wird, kommt dem Design und der Architektur der zugrundeliegenden Engines eine immer bedeutendere Rolle zu Zusehends werden extrem modulare Designs gewählt, die Abhängigkeiten vom eigentlichen Computersystem kapseln und so Portierbarkeit von einer Zielplattform zu einer anderen ermöglichen Erweiterbarkeit ist ebenso wichtig geworden, da viele Spiele-Engines für mehr als nur ein Spiel eingesetzt werden Diese Eigenschaft hilft ebenso beim Aufbau von Spielergemeinschaften, in denen Spieler Erweiterungen für ihr Lieblingsspiel entwickeln und es so für einen wesentlich längeren Zeitraum am Leben erhalten Das Thema dieser Diplomarbeit ist eine ganz bestimmte Spiele-Engine, die „Parsec Engine“, wobei sie sich auf Architektur und Design konzentriert Diese Engine betont und erlaubt Portabilität, indem sie eine sehr modulare Architektur einsetzt Weiters handelt es sich um eine Mehrspieler-Engine, d.h sie enthält eine leistungsfähige Netzwerkkomponente, durch die mehrere Spieler miteinander spielen können Erweiterbarkeit wurde in vielerlei Hinsicht erreicht, obwohl die Parsec Engine keine komplett allgemeine Engine mit dem Ziel, für alle möglichen Arten von Spielen verwendbar zu sein, ist, sondern versucht, hohe Leistung bei einem bestimmten Spieltyp zu erzielen Da sie eng zusammen mit einem vollständigen Computerspiel entwickelt wurde – Parsec, ein Mehrspieler-3D-Weltraumkampf-Spiel – bevorzugt sie Weltraum-Szenen mit Raumschiffen Obwohl das Hauptaugenmerk auf Architektur und Design liegt, war es ebenso ein Ziel die wesentlichsten Aspekte in einem Detailgrad zu beschreiben, der es erlaubt, die Engine zur Entwicklung neuer Spielfeatures und Spezialeffekte zu verwenden und auch die Engine selbst zu erweitern Acknowledgments I would like to express a very special thank you to my “coach” Dieter Schmalstieg for supervising this thesis, supporting my vision and approach to it, many helpful comments and remarks, and putting up with me as a student in general And – I will not forget my promise of an extended session of playing Parsec Since Parsec has become a real team effort over the years, I would like to express my thanks and admiration to all the talented members of the Parsec team for their great work and dedication: Andreas Varga, Clemens Beer, and Michael Wögerbauer, who are all great programmers and have contributed a lot to the spirit of the Parsec project Alex Mastny, who has truly astounded me with his ability to create ever more impressive artwork and designs Stefan Poiss, whose musical abilities are still a miracle to me after all those years, and the resulting music always managed to cheer me up and motivate me Karin Baier, for giving voice to an entire universe Thanks to Thomas Bauer for support in numerous and invaluable ways, and Uli Haböck for many insightful discussions on mathematics late at night Thanks to Thomas Theußl for tolerating the presence of gametech-talking nerds invading his office, occupying his machine, and for always being there to share a cup of hot chocolate Thanks to Karin Kosina for a fine sense of humor, her spirit, and her outstanding tastes in music – Kaos Keraunos Kybernetos! Thanks to Helwig Hauser for prodding me to give numerous talks, CESCG, and the Computer Graphics Group – la tante est morte, vive la tante ! Thanks to Gerd Hesina for a lot of help on numerous occasions Thanks to Anna Vilanova i Bartrolí and Zsolt Szalavári for being a lot of fun Last, but not least, I would like to thank all the Parsec fans out there, who are eagerly awaiting the final release we are working on it! Introduction 1.1 3D Computer game engines and graphics research About ten years ago computer graphics research and computer games development were two totally separate areas with not much common ground Computer games have always been almost exclusively targeted at the consumer market, and the graphics capabilities of consumer hardware at that time were practically non-existent from the point of view of computer graphics researchers Thus, researchers were using expensive high-end graphics workstations, and game developers were targeting entirely different platforms This had the implication that algorithms and techniques developed and used by the computer graphics research community could not really be employed by game developers Graphics researchers, on the other hand, also did not view computer games as an application area of their scientific work However, the last decade, and the last couple of years in particular, have seen low-cost consumer graphics hardware reach – and in many areas even surpass – the capabilities of extremely expensive high-end graphics hardware from just a short time ago This has led to computer game developers increasingly utilizing the scientific output of the research community, with an ever diminishing delay between introduction of a new technique and its actual use in a consumer product Computer games research and development has thus become a very important application area for graphics researchers The game engines driving today’s 3D computer games are indeed an incredibly interesting venue where computer graphics research and engineering meet However, although the graphics component of current game engines is probably the most visible one, a game engine is not only graphics One could say that the term game engine subsumes all the technology behind a game, the framework which allows an actual game to be created, but viewed separately from the game’s content This also includes networking, AI, scripting languages, sound, and other technologies Figure 1.1: Two highly successful game engines Left: Quake Right: Unreal In addition to driving highly successful games in their own right, the most prominent game engines of the last several years, like the Quake [Quake] and Unreal [Unreal] engines, have been remarkable licensing successes Although both were originally created for a particular game, these engines are ideal to be used for the creation of other games with entirely new content like game play, graphics, sound, and so forth In fact, the effort necessary to create a top-notch game engine has become so tremendous, that it is also very sensible from a business point of view to make one’s engine available for licensing to other companies, allowing them to focus more on actual content creation than on the technology itself This is even more important for companies that are simply not able to develop an entire engine and a game from scratch at the same time, than for the company allowing licensing of its engine In contrast to game engines that have been developed for a specific game or series of games, a small number of companies focus on developing only an engine, without also creating a game at the same time An example for this approach of creating flexible game engine technology exclusively for licensing, is Numerical Design Ltd.’s NetImmerse [NetImm] Due to its flexibility such an engine could be called a generic game engine, whereas the Quake engine, for instance, is definitely more bound to an actual type of game, or at least a specific gaming Introduction genre On the other hand, this flexibility is also one of the major problems inherent in generic engines Since they are not tightly focused on a rather narrowly defined type of game, they are not easily able to achieve the levels of performance of engines specifically tailored to a certain genre Another problem of generic engines is that most game development houses prefer licensing an engine with already proven technology, i.e., a highly successful game that has sold at least on the order of one million units 1.2 What this thesis is about This thesis contains a lot of material pertaining to the architecture of computer game engines in general, but most of all it is about the design and architecture of a specific engine This engine – the Parsec engine – is a highly portable and extensible multiplayer game engine The design of this engine was guided by certain key design criteria like modularity, flexibility, extensibility, and – most of all – portability As opposed to generic game engines, the Parsec engine belongs to the class of game or genre-bound engines This is also to say that it has been developed in parallel with an actual computer game, not coincidentally called Parsec – there is no safe distance [Parsec] Figure 1.2: Parsec – there is no safe distance Parsec is a multiplayer 3D space combat game, specifically targeted at Internet game play Basically, players can join game play sessions in solar systems, and also jump from solar system to solar system using so-called stargates, interconnecting them The emphasis is on fast-paced action, spectacular graphics, and background sound and music supporting the mood of the vast outer space setting Chapter contains a detailed overview of the game and its underlying concepts The Parsec engine offers high performance graphics utilizing an abstract rendering API, and a modular subsystem architecture encapsulating system-dependencies in order to achieve high portability The networking subsystem is also independent from the underlying host system and transport protocol used The current implementation supports Win32, Linux, and the MacOS as host systems, OpenGL and Glide as graphics APIs, and TCP/IP and IPX as networking protocols Since one of the major goals in the development of the Parsec engine was to achieve high portability, porting to additional host systems, graphics APIs, and networking protocols is a rather straightforward process In the description of the Parsec engine we will emphasize architectural and design aspects Nevertheless, we have also tried to provide sufficient detail in order to support developers interested in using, extending, and adding to Parsec, the game, as well as the Parsec engine itself Introduction 1.3 How this thesis is structured This thesis consists of three major parts Part One – Foundations and Related Work – covers fundamental issues like some very important graphics algorithms used in many game engines It also contains a short review and introduction to the most important low-level graphics APIs used in 3D computer games, like OpenGL and Glide The related work aspect is most prevalent in an overview of the evolution of 3D computer games and consumer 3D hardware over the last decade In this part we will cover a lot of background material about computer games and the algorithms and techniques they use or have used in the past Part Two – Design and Architecture of Parsec – covers the main topic of this thesis, the design and architecture of the Parsec engine Although the focus is on architectural and design aspects, many implementation issues are covered in detail The key design goal of portability is central to the entire architecture of the engine We will first review the game Parsec, then give an overview of its architecture and continue with more details about the architecture and its implementation After these more general parts we will be devoting a single chapter to each of the major engine components Part Three – Conclusion – concludes with a comprehensive bibliography and offers some concluding remarks 1.4 Overview of implementation The implementation of the work described in this thesis is Parsec, the Parsec engine, and the Parsec SDK (Software Development Kit) Parsec is the space combat computer game employing the accordingly named engine in order to present an interactive gaming experience to the player The Parsec SDK is a subset of the Parsec engine and game code, which will be made available on the Internet in source code form, in order to allow development of user modifications and additions, like new weapons and special effects, modes of game play, or even total conversions, i.e., an almost entirely different game This thesis is also intended for providing background and reference information to developers intending to work with the Parsec SDK The implementation of all of these components currently consists of about 180,000 lines of code, written in a Clike subset of C++, contained in about 900 source files, which amount to about 7MB of code Supported host systems are Win32, MacOS, and Linux Both OpenGL and Glide (3dfx) are supported as target graphics APIs on all of these host systems The available implementations of the networking component support the TCP/IP suite of protocols and Novell’s IPX The code is very modular, especially with respect to portability between different host systems and graphics APIs It transparently supports both little-endian (e.g., Intel x86) and big-endian (e.g., PowerPC) systems, and encapsulates many other details differing between target platforms It is contained in a hierarchically structured source tree, whose layout corresponds to the subsystem architecture, and host system and graphics API targets, as will be described in the main part of the thesis (Part Two) Since the system-dependent parts are cleanly separated and isolated, it is easily possible to extract only those source files needed for a specific target platform and/or graphics API A more detailed overview of the implementation is contained in chapter 5, as well as the following chapters on architecture, and the chapters devoted to specific subsystems Introduction Slotserver protocol The slotserver protocol already needs a server Nevertheless, this protocol is no client-server model for game play Instead, the server is only used to substitute the broadcast, by unicasting to the server in order to find other clients currently connected The game itself then still uses the peer-to-peer protocol, after the connection has been established Gameserver protocol This is the full-blown client-server protocol of Parsec Clients only communicate with the server, which tries to perform some load balancing and is responsible for forwarding this message to all the other clients The gameserver protocol is the standard mode of play on the Internet 13.3 Packet API layer This layer encapsulates the networking protocol (transport protocol) provided by the host system First, this means abstract functions for sending and receiving packets Second, this layer must also encapsulate the physical network address format For example, for UDP this means IP addresses (even though these will be mapped to MAC addresses by the host system, e.g., ethernet addresses) IPX uses ethernet addresses directly Network addresses are encapsulated using the abstract node_t type Variables of type node_t may be copied and stored, but their actual meaning is only known by functions of the Packet API layer which take parameters of type node_t User Datagram Protocol (UDP) The current implementation of the Parsec engine supports UDP on Win32, MacOS, and Linux At the moment, the client-server connection also uses TCP for a limited number of critical tasks Connections are established and broken using TCP Mostly, though, we use connection-less unreliable transport for performance reasons, especially for everything that must be sent periodically (PKTP_GAME_STATE, PKTP_NODE_ALIVE) If UDP is selected as Packet API this actually means using the TCP/IP protocol suite As already mentioned, we use both UDP and TCP This slight inconsistency in terminology is due to the fact that UDP is used ninety-nine per cent of the time (i.e., after the connection is established until it is broken once again) Internetwork Packet Exchange (IPX) On Win32 and MacOS we also support Novell's IPX (internetwork packet exchange) protocol IPX uses a fourbyte network address to identify the destination network along with the six-byte ethernet address of the destination host to identify a specific node Currently it's only possible to play using IPX if all clients are connected to the same physical network (subnet) A very important restriction of the IPX support is that it does not support client-server protocols The peer-to-peer protocol must be used if IPX transport is desired Networking 126 14 The Command Console The command console offered by the Parsec engine is a very powerful tool both for developers and power users Basically, the console is a translucent text-window that can be overlayed onto the screen at any time When it is active, commands can be entered at a command prompt By and large it is very similar to a standard Unix command line interface It offers tab-completion of partially typed commands, a history list of several hundred commands entered previously, scroll-back with page and line granularity, and so on Figure 14.1 shows the command console overlayed on top of the cockpit Figure 14.1: Parsec’s command console Console commands can immediately cause an action, be used to view and set the value of console variables, or be the name of a console script that should be executed Accordingly, we distinguish the following three fundamental types of commands that can be executed by the console: • • • Console commands Console variables Console scripts Console scripts are simple text files containing further console commands These commands may also be scripts themselves, up to a certain level of recursion Unix-like “ls” and “cat” commands are available for listing all scripts in the search path and viewing their contents, respectively Although originally many things like loading data and setting default values for game play variables were the domain of special scripts or even hard-coded, with the addition of the command console all of these functions were progressively moved to the consistent framework of console scripts The engine automatically executes a specifically name script on startup (boot.con), and the rest of the engine boot process will be controlled from there There are numerous commands for loading data (geometric objects, textures, fonts, sound samples, etc.), and listing currently loaded data and displaying corresponding information Since the console commands for loading data are not restricted to the startup phase, all different kinds of data may be overloaded on-the-fly at run-time For example, it is a matter of a short command entered in the console to exchange a certain texture used by a specific object, exchanging that object’s geometry, and so on The Command Console 127 As detailed in chapter 11, the shading language is also accessible interactively from the console Shaders can be defined and attached to objects entirely on-the-fly Usually, this is done during development of a shader As soon as the shader is finished, the resulting console code is stored into the console script responsible for loading the corresponding object The console also offers a talk feature, where players can type and send messages to each other In the normal console mode, messages can be sent by using the “say” command If messages are sent very often, however, the console can be switched into talk mode, where every line typed will be sent automatically, without the need for a special command In this mode, commands can still be executed by prepending a slash character (‘/’) This is intentionally very similar to the syntax of irc (Internet relay chat) The Parsec engine’s demo recording feature also makes heavy use of console commands During recording of a demo, console commands are continuously written to an output script On subsequent execution, these commands are able to exactly reproduce what happened on screen during recording Since this output script is a standard text file simply containing console commands, it can easily be edited and modified Additionally, multiple demo scripts may be included by other scripts for back-to-back replay The console also offers a feature for cutting demos, allowing for the creation of directed movies As soon as a demo script or set of scripts is finished, it can be compiled into a single binary file These binary demo files allow for faster execution, are a lot smaller than their text file counterparts, and have the advantage that they are single files, where the source scripts might have been many files originating from different recording sessions The console is able to play back demos in both text and binary form One of the most powerful features of the command console is the ease with which it is possible to register new commands and variables at the source code-level For example, if a new special effect is added it is a matter of a view lines of code to register commands that can then be used to control the effect’s behavior It is also possible to register sophisticated data structures with the console, in order to allow the structure’s fields to be viewed and manipulated interactively The next section covers this registration of console commands and variables in detail 14.1 User command registration This section describes what kinds of console commands can be registered to be automatically integrated into the console, along with the corresponding data structures needed There are three major types of console commands that can be registered, a very general type where parsing has to be done by the user, a special type for integer console variables, and a special type for on-the-fly manipulation and display of custom object properties Parsing for the latter two types of commands is performed automatically, since in contrast to completely general user commands the console code knows exactly what to with them The following paragraphs cover each of these types in detail For each type exists a corresponding registration function, which basically simply takes a pointer to a registration data structure These data structures will also be described in detail in the following paragraphs, whereas the actual declarations of the corresponding registration functions will only be covered in the next section General user commands This is the most general type of command that can be registered with the command console Basically, for this type of command the console itself only knows the command’s name and a callback function that is responsible for parsing its arguments and executing the appropriate actions That is, a user-supplied callback function will be called when the console encounters the corresponding command, which is then responsible for everything else See figure 14.2 for the structure that has to be filled in and submitted to CON_RegisterUserCommand() in order to register the command The Command Console 128 struct user_command_s { char* short short int char* command; commlen; numparams; (*execute)(char*); (*statedump)(); // // // // // command string length of string num of parameters (used by tab-completion) command function returns statedump string; (NULL==volatile) }; Figure 14.2: General user command registration structure The callback function that will be called to parse parameters and actually execute the command (field execute) gets access to the entire command string and has to return whether the command could be parsec successfully or contained syntactic or semantic errors There is also an optional callback (statedump), which can be used for commands that desire to save persistent state information There is a central console script for all such state information and the statedump callback is allowed to return an arbitrary string that it wants to have stored in that script, in order to be able to restore its previous state later on The number of parameters will not be used for parsing purposes or anything in this vein It is simply an information for the command completion code to determine whether to automatically append a space character after the completed command or not Example 14.1 shows a code fragment that could be used to register the command my_user_command extern int MyUserParseFunction( char *command ); static char *my_user_string = “my_user_command”; user_command_s my_user_command; memset( my_user_command, 0, sizeof( my_user_command ) ); my_user_command.command my_user_command.commlen my_user_command.numparams my_user_command.execute my_user_command.statedump = = = = = my_user_string; strlen( my_user_string ); 1; MyUserParseFunction; NULL; Example 14.1: General user command registration Integer variable commands This command type can be used to provide access to integer variables from the console with a minimum amount of code All parsing will be done by the console code itself In the simplest case, all that is needed is the name of the command and a pointer to the integer variable it corresponds to The name of the command will be perceived by the console user to be the name of the corresponding variable, regardless of its actual name in the code See figure 14.3 for the structure that has to be filled in and submitted to CON_RegisterIntCommand() in order to register the command struct int_command_s { int char* int int int* void int persistence; command; bmin; bmax; intref; (*realize)(); (*fetch)(); // // // // // // // persistent int commands are saved on exit name of command lower bound upper bound pointer to actual int var will be called after modification (optional) will be called before reading (optional) }; Figure 14.3: Integer variable command registration structure The Command Console 129 If the persistence field is set to true, the value of the integer variable will automatically be saved to file on program exit, and be restored on next startup The console can be asked to automatically check whether the supplied value is in the allowed range for the corresponding variable Minimum and maximum bounds can be specified in the bmin and bmax fields, respectively Optionally, one or two callback functions may be supplied The first one (realize) will be called immediately after the integer variable has been set to its new value This is needed for variables where simply changing their value is not enough, i.e., which have to be realized by executing appropriate code The second one (fetch) will be called immediately before the variable will be modified, i.e., can be used to act upon or remember the old value if needed Example 14.2 shows a code fragment that could be used to register the command my_int_command static int my_int_variable; int_command_s my_int_command; memset( my_int_command, 0, sizeof( my_int_command ) ); my_int_command.persistence my_int_command.command my_int_command.bmin my_int_command.bmax my_int_command.intref my_int_command.realize my_int_command.fetch = = = = = = = 1; “my_int_command”; 0; 255; &my_int_variable; NULL; NULL; Example 14.2: Integer command registration Custom object type commands The command console offers a powerful facility to allow properties of custom object types to be displayed and modified without writing any special-purpose code See chapter for a detailed description of custom object types For each property that should be made accessible a data structure has to be filled with the appropriate information For a single object type an array of such data structures has to be built and submitted to the CON_RegisterCustomType() function The last entry in this array must contain a NULL pointer as property name, in order to terminate the list of properties Figure 14.4 shows the structure used to describe a single custom object type property struct proplist_s { char* size_t int int int int propname; propoffset; bmin; bmax; fieldtype; (*notify_callback)(GenObject*); // // // // // // name property can be accessed by offset of property in obj structure minimum value of property maximum value of property field's data type callback on field value changes }; Figure 14.4: Custom object type property structure The specified name of the property (propname) has to be used in the console in order to identify what should be displayed or modified To allow the console code to locate the corresponding field in the object type structure, a byte offset from the structure’s beginning must be known (propoffset) The Command Console 130 In contrast to simple integer variable commands, the properties of custom object types may be of one of several different data types Figure 14.5 lists symbolic constants for each of these data types PROPTYPE_INT PROPTYPE_FLOAT PROPTYPE_GEOMV PROPTYPE_FIXED PROPTYPE_STRING PROPTYPE_CHARPTR Figure 14.5: Custom object type property data types If the value of a property of an already instanced object class has been modified, an optional callback (notify_callback) will be called, in order to allow the object to act upon the new value if so desired This callback function will be passed a pointer to the object class instance affected Example 14.3 shows a code fragment that registers several fields of a custom object type with the console directly after registration of the type itself struct ShockWave : CustomObject { // other fields int int int int int delay; red; green; blue; alpha; }; #define #define #define #define #define OFS_DELAY OFS_RED OFS_GREEN OFS_BLUE OFS_ALPHA offsetof( offsetof( offsetof( offsetof( offsetof( ShockWave, ShockWave, ShockWave, ShockWave, ShockWave, delay ) red ) green ) blue ) alpha ) proplist_s ShockWave_PropList[] = { { { { { { "delay", "red", "green", "blue", "alpha", { NULL, OFS_DELAY, OFS_RED, OFS_GREEN, OFS_BLUE, OFS_ALPHA, 0, 0, 0, 0, 0, NULL, 0, 0xffff, 0xff, 0xff, 0xff, 0xff, 0, PROPTYPE_INT PROPTYPE_INT PROPTYPE_INT PROPTYPE_INT PROPTYPE_INT }, }, }, }, }, } }; custom_type_info_s info; memset( &info, 0, sizeof( info ) ); // fill custom type info; see chapter static dword shockwave_type_id; shockwave_type_id = OBJ_RegisterCustomType( &info ); CON_RegisterCustomType( info.type_id, ShockWave_PropList ); Example 14.3: Custom object type console registration 14.2 Console API This section provides an overview of the API functions offered by the console Not all of these functions will be discussed in detail, since many of them are parameter parsing convenience functions For these functions we will only briefly outline what functionality is available to ease implementation of console command parsing The Command Console 131 Console command registration functions Figure 14.6 shows the declaration of the functions that have to be used in order to register one of three different types of console commands The first two functions each take a pointer to a structure containing all necessary information about the respective console command For details of these structures see the previous section on user command registration The third function takes an entire array of property info structures, along with the id of the custom object type these properties belong to For details on registration of console commands for custom object types see also the previous section int void void CON_RegisterUserCommand( user_command_s *regcom ); CON_RegisterIntCommand( int_command_s *regcom ); CON_RegisterCustomType( dword objtypeid, proplist_s *proplist ); Figure 14.6: Console registration functions Console output Naturally, the implementation of console commands very often desires to output text on the console In fact, not only console commands want to this There are lots of occasions when non-intrusive information has to be displayed For example, status messages, debugging output, and the like Correspondingly, there are several console API functions offered for text output or related functions, listed in figure 14.7 void void void void void void char* CON_AddLine( char *text ); CON_AddMessage( char *text ); CON_AddLineFeed(); CON_EnableLineFeed(); CON_DisableLineFeed(); CON_DelLine(); CON_GetLine(); Figure 14.7: Console output-related functions CON_AddLine() and CON_AddMessage() output a single line of text in the console The former function is used most often and closes the current console line containing the command prompt, before writing the supplied string into its own line immediately below, and then displaying a fresh command prompt This is usually used in response to console commands In contrast to this behavior, the latter function preserves the current console line and command prompt and inserts the supplied string as message immediately above it It is very convenient to display auxiliary information without disturbing the current input line Such auxiliary information usually arises asynchronously to normal console operation, i.e., is not the immediate response to a console command The next three API functions are concerned with details of line feed in the console, adding a line feed and thus a new line, and enabling or disabling line feed for the next output, respectively CON_DelLine() erases the current line, which contains the command prompt, and CON_GetLine() retrieves its content, which usually is not necessary, since all console command functions automatically are passed a pointer to it anyway Console command parsing This section gives a brief overview of the utility functions provided by the console that can be used to ease the implementation of parameter parsing Figure 14.8 shows a list of these functions The Command Console 132 ScanKeyValuePairs(); ScanKeyValueInt(); ScanKeyValueIntList(); ScanKeyValueIntListBounded(); ScanKeyValueFloat(); ScanKeyValueFloatList(); ScanKeyValueFloatListBounded(); ScanKeyValueFlagList(); GetParenthesizedName(); GetIntBehindCommand(); GetStringBehindCommand(); SetSingleStringCommand(); QueryIntArgument(); QueryFltArgument(); QueryIntArgumentEx(); QueryFltArgumentEx(); CheckSetIntArgument(); CheckSetFltArgument(); CheckSetIntArgBounded(); CheckSetIntArray(); CheckSetStrArgument(); Figure 14.8: Console parsing utility functions There is a function for parsing names which are allowed to contain whitespace when enclosed between parentheses, functions for parsing int and float parameters in several flavors and with different behavior, parsing arrays of integers, with and without checking values for validity, string arguments, and so on A very important and powerful set of functions deal with parameters in key-value format This refers to a list of pairs of strings, the first being the key identifying what should be set, the second being the value it should be set to Value strings may themselves describe data in one of several possible formats, integers, floats, or strings, for instance In fact, the infrastructure for key-value parameter lists offered by the console code is so powerful that it is employed for a large number of console commands, and makes the addition of new and quite complex commands as easy as possible A list of key-value pairs is simple an array of the data structure shown in figure 14.9 struct key_value_s { char* char* dword key; value; flags; }; Figure 14.9: Key-value pair description Every key is simply a string that has to be unique among all the keys of a single console command After ScanKeyValuePairs() has been invoked, the value will be set to the string argument specified after the respective key If the value is not actually a string, but an int or float, for instance, several parsing functions for arguments of this type are also offered The flags field allows to specifiy additional desired behavior while parsing the value for a specific key The possible symbolic values are shown in figure 14.10 The Command Console 133 KEYVALFLAG_NONE KEYVALFLAG_DISALLOW KEYVALFLAG_IGNORE KEYVALFLAG_MANDATORY KEYVALFLAG_PARENTHESIZE Figure 14.10: Key-value pair parsing flags Keys may be disallowed (KEYVALFLAG_DISALLOW), or ignored transparently (KEYVALFLAG_IGNORE) The may also be specified as being mandatory (KEYVALFLAG_MANDATORY) Otherwise, the default behavior is that missing keys will have values simply set to NULL If values are allowed to contain whitespace, they have to be parenthesized with ‘(‘ and ‘)’ The parser has to be informed of this by setting the corresponding flag (KEYVALFLAG_PARENTHESIZE) The outer level of parentheses will then automatically be stripped, and everything enclosed between them will be the value for the respective key Parenthesized values are important for names containing whitespace, as well as lists of arguments, e.g., lists of integers, or lists of floating point values Lists of key-value pairs may also be used hierarchically, by using the parser functions in an appropriate manner That is, a parenthesized value might itself be a list of key-value pairs, and so on The Command Console 134 PART III: Conclusion 15 Concluding Remarks This section is going to conclude by briefly reviewing what we have covered in this thesis, as well as a tentative look into the future of the technology employed by computer games So far, so good This thesis has covered a lot of ground Its main topic has been the design and architecture of the Parsec game engine This engine is extremely portable between different host systems, as well as graphics APIs, and nevertheless offers high performance and smooth game play A major part of the work corresponding to this thesis was also the Parsec SDK, which is intended to allow interested parties to develop their own extensions of the game, maybe even of the engine itself Therefore, another emphasis of this work was to cover the Parsec architecture and code-base in sufficient detail, in order to facilitate proper and painless use of the Parsec SDK – if this is at all possible In hindsight, the Parsec project began over four years ago, in 1996, although it was not called thus at the time We began developing exclusively for DOS and the only renderer of the initial version was a software renderer, although supporting resolutions up to 640x480 right from the start, which was by no means standard in those days In the following years, the present subsystems architecture was designed and incorporated, always ensuring backwards compatibility The first 3D hardware supported by Parsec was the Voodoo Graphics chipset by 3dfx Interactive, using the Glide API After support for the first 3D hardware accelerator came ports to other operating systems than DOS First Win32, then the MacOS, finally Linux Another important step forward was the addition of another implementation of the rendering subsystem, this time for OpenGL Subsequently, support for DOS and software rendering were dropped due to the fact that both had essentially gone the way of time These days, the Parsec code-base has attained considerable size, but also an appropriate lot to offer Nevertheless, the entire vision of the Parsec project is still not finished There are certain essential parts missing from the Internet networking component So, as always, there’s still a lot to The future of 3D computer game technology So, what can we expect from consumer 3D technology and computer games in the future? With the recent addition of hardware geometry accelerators and upcoming consoles like the Playstation 2, triangle counts will definitely skyrocket in the immediate future On the other hand, high polygon counts not make much sense when the actual image quality is not being increased at the same time, for instance by using a larger number of rendering passes, advanced lighting and shading models, and the like Thus, geometry acceleration in conjunction with extremely high fill rates to allow a high number of passes should be able to provide the basis for much more realistic lighting and special effects in the future What has been tried a number of times in the past, but has not really worked out yet is the rendering of really large and realistic outdoor areas and terrain Advanced progressive and adaptive level of detail algorithms combined with high polygon throughput should allow for truly impressive outdoor rendering in the not-toodistant future Increased polygon counts and hardware accelerators taking over more and more of the repetitive graphics work from the CPU, will allow game developers to focus on a lot of aspects for which there was not enough processing power left up to now Advanced artificial intelligence algorithms and realistic physics simulation come to mind immediately Other interesting improvements will be possible in rendering more and, most of all, more lifelike characters, using high polygon counts Characters with explicitly modeled lips in conjunction with Concluding Remarks 136 real-time lip-synching will make artificial characters, as well as avatars representing real-life people, much more convincing One of the most important keywords in all of these developments is scalability Although graphics hardware gets more and more powerful at an ever increasing rate, the average user will not be able to upgrade every six months Computer games will therefore be required to run satisfactorily on a wider range of hardware than ever before Therefore, a trend of moving towards scalable, adaptive, and progressive algorithms and representations can already be observed In the not-so-immediate future another question is where the entire field of real-time graphics is headed, with respect to fundamental issues The current primitive used by virtually all contemporary 3D graphics hardware is the texture-mapped triangle Of course there have been tremendous improvements, but in a way these have mostly been in terms of performance, and been more on a detail than on a fundamental level However, if everybody is forced to use the same fundamental primitives, creativity and flexibility is quite constrained and this will become extremely apparent in the future So, sometime in the future a paradigm shift away from polygons to an alternative and more powerful approach is very likely to happen Maybe the voxel is going to become the fundamental primitive even for real-time graphics, maybe higher order surfaces, or maybe even a resurgence of software rendering will happen when CPUs have become so much more powerful that they are once again able to take over at least some of the work done by hardware accelerators these days, to trade off CPU consumption for flexibility If you remember that in the beginning we have reviewed the last decade of technology used in computer games, there’s certainly going to be an even more interesting decade yet to come Concluding Remarks 137 16 Bibliography [Air90] John M Airey, John H Rohlf, and Frederick P Brooks, Jr Towards Image Realism with Interactive Update Rates in Complex Virtual Building Environments In Proceedings 1990 Symposium on Interactive 3D Graphics pp 41-50, 1990 [AMD] AMD Web Site http://www.amd.com [Ash94] Ian Ashdown Radiosity: A Programmer’s Perspective John Wiley & Sons, 1994 [Ben75] Jon Bentley Multidimensional binary search trees used for associative searching In Communications of the ACM Vol 18, pp 509-517, 1975 [Ber97] Mark De Berg, et al Computational Geometry: Algorithms & Applications Springer-Verlag, 1997 [Chi95] Norman Chin A Walk through BSP trees In Graphics Gems V, edited by Alan W Paeth pp 121138, Academic Press, Inc., 1995 [Coo84] Robert L Cook Shade Trees In SIGGRAPH ’84 Conference Proceedings pp 223-231, 1984 [Cox69] H S M Coxeter Introduction to Geometry 2nd edition John Wiley and Sons, 1969 [DeL00] Mark DeLoura, ed Game Programming Gems Charles River Media, 2000 [DirectX] DirectX and Direct3D See http://www.microsoft.com/directx/ [Fol90] James D Foley, Andries van Dam, Steven K Feiner, and John F Hughes Computer Graphics: Principles and Practice 2nd edition Addison-Wesley, 1990 [Fuc80] Henry Fuchs, Zvi M Kedem, and Bruce F Naylor On Visible Surface Generation by A Priori Tree Structures In SIGGRAPH ’80 Conference Proceedings pp 124-133, 1980 [Fun96] Thomas Funkhouser, Seth Teller, Carlo Séquin, and Delnaz Khorramabadi The UC Berkeley System for Interactive Visualization of Large Architectural Models In Presence, 5(1) (1996) pp 13-44 [Gam95] Erich Gamma, Richard Helm, Ralph Johnson, and John Vlissides Design Patterns – Elements of Reusable Object-Oriented Software Addison-Wesley, 1995 [Glide] Glide Rasterization Library 3dfx Interactive See http://www.3dfx.com, http://linux.3dfx.com, and http://sourceforge.net/projects/glide [Gre94] Ned Greene Detecting Intersection of a Rectangular Solid and a Convex Polyhedron In Graphics Gems IV, edited by Paul S Heckbert pp 74-82, Academic Press, Inc., 1994 [Had98] Markus Hadwiger PARSEC: Enhancing Realism of Real-Time Graphics Through Multiple Layer Rendering and Particle Systems In Proceedings of the 2nd Central European Seminar on Computer Graphics (CESCG ‘98), pp 155-164, 1998 [Had99] Markus Hadwiger Developing for Multiple Graphics APIs Simultaneously: A Case Study In Proceedings of the 3rd Central European Seminar on Computer Graphics (CESCG ‘99), pp 215224, 1999 [HalfLife] Half-Life Valve Software See http://www.valvesoftware.com [Hec89] Paul S Heckbert Fundamentals of Texture Mapping and Image Warping Masters thesis University of California at Berkeley, 1989 Bibliography 138 [Hec91] Paul S Heckbert and Henry P Moreton Interpolation for Polygon Texture Mapping and Shading In David F Rogers and Rae A Earnshaw, ed State of the Art in Computer Graphics: Visualization and Modeling pp 101-111 Springer-Verlag, 1991 [Hop98] Hugues Hoppe Efficient Implementation of Progressive Meshes In Computers & Graphics, Vol 22, No 1, pp 27-36, 1998 [Intel] Intel’s Developer Site http://developer.intel.com [Lue95] David Luebke and Chris Georges Portals and Mirrors: Simple, Fast Evaluation of Potentially Visible Sets In Proceedings 1995 Symposium on Interactive 3D Graphics pp 105-106, 1995 [Lue00] David Luebke, Jon Cohen, Martin Reddy, Amitabh Varshney, and Ben Watson Advanced Issues in Level of Detail SIGGRAPH 2000 Course 41, Course Notes, 2000 [Mag93] Steve Maguire Writing Solid Code Microsoft Press, 1993 [McC93] Steve McConnell Code Complete: A Practical Handbook of Software Construction Microsoft Press, 1993 [McR00] Tom McReynolds and David Blythe Advanced Graphics Programming Techniques Using OpenGL SIGGRAPH 2000 Course 32, Course Notes, 2000 [Möl99] Tomas Möller and Eric Haines Real-Time Rendering A K Peters, 1999 [Nay97] Bruce F Naylor Interactive Playing with Large Synthetic Environments In Proceedings 1997 Symposium on Interactive 3D Graphics pp 107-108, 1997 [NetImm] The NetImmerse 3D Game Engine Numerical Design Ltd See http://www.ndl.com/ni.html [OGL] OpenGL – High Performance 2D/3D Graphics See http://www.opengl.org [Ola00] Marc Olano, John C Hart, Wolfgang Heidrich, Michael McCool, Bill Mark, and Kekoa Proudfoot Approaches for Procedural Shading on Graphics Hardware SIGGRAPH 2000 Course 27, Course Notes, 2000 [Parsec] Parsec – Fast-paced multiplayer cross-platform 3D Internet space combat The Parsec Project See http://www.parsec.org [Pee00] Mark S Peercy, Marc Olano, John Airey, P Jeffrey Ungar Interactive Multi-Pass Programmable Shading In SIGGRAPH 2000 Conference Proceedings pp 425-432, 2000 [Por84] Thomas Porter and Tom Duff Compositing Digital Images In SIGGRAPH ’84 Conference Proceedings pp 253-259, 1984 [Quake] Quake, Quake II, Quake Arena Id Software See http://www.idsoftware.com [Reed94] Todd Reed and Brian Wyvill Visual Simulation of Lightning In SIGGRAPH ’94 Conference Proceedings pp 359-363, 1994 [Reev83] William T Reeves Particle Systems - A Technique for Modeling a Class of Fuzzy Objects In SIGGRAPH ’83 Conference Proceedings pp 359-376, 1983 [Rog98] David F Rogers Procedural Elements for Computer Graphics McGraw-Hill, second edition, 1998 [Rol00] Andrew Rollings and Dave Morris Game Architecture and Design Coriolis Group, 2000 [Sal99] Marc Saltzman, ed Game Design – Secrets of the Sages Robert J Brady, Co., 1999 [Sam90a] Hanan Samet The Design and Analysis of Spatial Data Structures Addison-Wesley, 1990 Bibliography 139 [Sam90b] Hanan Samet Applications of Spatial Data Structures Addison-Wesley, 1990 [Seg98] Mark Segal and Kurt Akeley The OpenGL Graphics System: A Specification (Version 1.2.1) Silicon Graphics, Inc., 1998 See ftp://sgigate.sgi.com/pub/opengl/doc/opengl1.2/opengl1.2.1.pdf [Sin99] Sandeep Singhal and Michael Zyda Networked Virtual Environments Addison-Wesley, 1999 [Sud96] Oded Sudarsky and Craig Gotsman Output-Sensitive Visibility Algorithms for Dynamic Scenes with Applications to Virtual Reality In Proceedings of Eurographics ’96 Conference pp 249258, 1996 [Tel91] Seth J Teller and Carlo H Séquin Visibility Preprocessing For Interactive Walkthroughs In SIGGRAPH ’91 Conference Proceedings pp 61-69, 1991 [Tel92a] Seth J Teller Computing the Antipenumbra of an Area Light Source In SIGGRAPH ’92 Conference Proceedings (1992) pp 139-148 [Tel92b] Seth J Teller Visibility Computations in Densely Occluded Polyhedral Environments PhD thesis University of California at Berkeley, 1992 [Unreal] Unreal and Unreal Tournament Epic Games See the Unreal Technology Page at http://unreal.epicgames.com [Ups90] Steve Upstill The RenderMan Companion Addison-Wesley, 1990 [Var99] Andreas Varga PARSEC: Building the networking architecture for a distributed virtual universe In Proceedings of the 3rd Central European Seminar on Computer Graphics (CESCG ‘99), pp 205-214, 1999 [Wat92] Alan Watt and Mark Watt Advanced Animation and Rendering Techniques Addison-Wesley, 1992 [Wol90] George Wolberg Digital Image Warping IEEE Computer Society Press, 1990 [Woo99] Mason Woo, Jackie Neider, Tom Davis, and Dave Shreiner, OpenGL Architecture Review Board OpenGL Programming Guide Third Edition Addison-Wesley, 1999 Bibliography 140 ... however, since it wasn’t a fast-paced action game after all, emphasizing game play and design much more than many 3D action games of the following years Characters and objects in Ultima Underworld... distance Parsec is a multiplayer 3D space combat game, specifically targeted at Internet game play Basically, players can join game play sessions in solar systems, and also jump from solar system... at least alternative graphics API by many computer games for several years Glide has several key advantages, foremost of all its high performance and ease of use In fact, the API is so hardware-oriented

Ngày đăng: 14/12/2018, 11:49

Từ khóa liên quan

Mục lục

  • Introduction

  • 3D Computer game engines and graphics research

  • What this thesis is about

  • How this thesis is structured

  • Overview of implementation

Tài liệu cùng người dùng

Tài liệu liên quan