Wednesday, June 6, 2012

DX(t)UT – 02 – Simple trolling

In this second lesson we will be going over the second “simple” sample application from the DirectX SDK, called “SimpleProject”. And let me tell you this: it is not that simple. Not at all! It pretty much throws everything in. It even loads a shader, includes the shader source code that does simple vertex lighting using a single directional light source, but in the end it does not use it to render anything. When I’ll introduce vertex lighting shaders I’ll dedicate at least a full lesson to it. Still, it is the simplest from the sample projects (except for “EmptyProject”) and provides the basis for all the other samples that each tackle a specific technique. The sample is in no way didactic and there is probably no way I can explain it in a good way in any reasonable space, so I’ll just explain it in order and split the lesson up in multiple parts. 

By this point I expect you to have your entire environment set up correctly. So if you installed everything correctly in the default locations, you will find the entire source tree for the project under: 

"c:\Program Files\Microsoft DirectX SDK (June 2010)\Samples\C++\Direct3D\SimpleSample" 

First I will tour the application and show you what it can do. Here is a screenshot of the application: 

Like the first example, this one is also an empty blue window that does not render anything, but this time we have support for text drawing with full font support and basic GUI with a display configuration and rendering dialog. In the top left corner, we have a first line of text that displays the frame information. Here you will find the framerate, but the way the program is written, the framerate is not displayed if vertical sync is on and the application is capable of maintaining a framerate equal to your refresh rate. We get information about the display size and color format. The next line gives information about the device. It tells us that we have a HAL device with software vertex processing (sw vp). 

There are two types of DirectX devices. HAL (probably Hardware Abstraction Layer) devices are devices capable of using hardware acceleration. HAL devices are not required to implement every single feature, but obviously you won’t be able to use a feature unless it is available. The other kind of devices is called a REF (reference) device. These devices are software and are meant to be very precise and support every single DirectX feature. They are completely CPU based and incredibly slow. So slow that you probably won’t be able to render a single triangle at “interactive” framerates. These devices are used purely for debugging purposes and are only available if you have the DirectX SDK installed. Because DXUT samples have support for REF devices and vertex debugging, for a while at least I’ll keep the support in, but I have no intention to debug devices or teach you how to do it. 

So back to the second line of text. It also tells us the name of the adapter. If you know a thing or two about GPU and the software vertex processing did not worry you, seeing an Intel onboard GPU should. These GPUs are very weak and very much ill suited for any kind of hardware accelerated 3D rendering, yet alone engine development or game playing. I have access to a lot of computers and most of them are extraordinarily strong. Real beasts. But they are meant for development and thus do not have powerful GPUs. When real power is needed, I’ll switch over to a computer with a dedicated GPU. 

In the top right corner, we have 3 buttons. The first one will toggle between windowed mode and fullscreen mode. By default, when switching to fullscreen it will try to use the highest resolution available, but you can fine tune this behavior. The second button toggles between HAL and REF devices. I’ll only focus on HAL devices. The third button is little more interesting, opening up the default device setting dialog: 

The dialog is a little underpowered under the Intel GPU, having some options disabled and in general fewer choices. I’ll show this dialog in the future on several GPUs when I decide describe it in further detail. Currently I do not know if you can easily extend this dialog with further options, but it is pretty good for something you get out of the box. It is also fully functional, not just an empty shell, so you can change properties and play with it around and all changes will instantly be reflected in your application. 

So that’s it for the functionality of our simple application. It is smarter than the “empty” application and even loads that shader and sets its properties behind the scenes. If it loaded a mesh and used the shader to render it, we would have a full “hello world” sample. 

So on to the code. It starts by including pretty much every single DXUT header in existence. See the code for a full list. Then we get something new: shader debugging support! 

Uncomment the lines and theoretically with a REF device you should be able to do more debugging. I will not touch upon this subject. Then we have a bunch of global variables, and here is where things start to become interesting: 

Let’s go over each variable: 

g_Camera is a DXUT camera. If you are familiar with 3D you probably have used a camera before. It is a nice abstraction mechanism that allows us to control the way we perceive the 3D scene in a way that mirrors the way a real life camera is used to film stuff. Generally it has a positions and a direction. Or it has a position and the target’s position. Using these two points, a field of view value and two cut off planes, a view frustum can be defined. Everything inside that view frustum can be seen. Let me show you an unnecessarily math infused view frustum: 

Unlike 3D modeling programs and higher level 3D toolkits, DirectX is happy with not providing you with such an abstraction in a very straight forward manner. A camera is actually just a set of matrix transformations, using the world-view-projections matrices (they also appear under other names in some literature). I’ll explain these matrices at the right moment. Suffice to say, using these matrices you can convert from object local 3D coordinates to 2D screen coordinates. 

DXUT provides a few camera classes that behave as expected (I hope) and some utility functions and widgets. 

g_DialogResourceManager is our dialog resource manager. In DXUT you need to have one such dialog resource manager than handles shared resources between dialogs and for event passing. You just need to set it up and in general you’ll focus on dialogs and widgets, not on the manager itself. 

g_SettingsDlg is the dialog you saw above, the default device setting dialog. 

g_HUD is a standard dialog. It is less specialized than g_SettingsDlg and is pretty much just a container into which you can insert widgets. It contains the 3 buttons from the top right corner I described before. 

g_SampleUI is another such empty container. While the 3 buttons will be the same in all samples from the DirectX SDK, the g_SampleUI is used for sample specific controls. Since this application is “simple”, this dialog will be left empty. 

g_pTxtHelper is a text helper object, the one we use to render text. Text rendering can be quite the obstacle. Especially when you are starting out with a toolkit. Let’s say you embark on one of the popular OpenGL tutorials. You’ll see that there is no out of the box font support and you will eventually find out that you need bitmap fonts. A readymade bitmap font utility can save you a lot of time and effort, but straight forwards static bitmap fonts have one huge problem: they are primitive. Like, 1980 came by and called a bitmap font a retarded dinosaur. You may not want real font support in your game, with Unicode and all the internationalization shabang, but still, support should be available. A bitmap font with a few hundred (at most) characters just won’t cut it. The text helper will allow you to use a font object and a sprite object to create a high performance (traditional flexible text rendering with flexible fonts can be quite the bottleneck) text display. In the end it probably creates bitmap fonts, but on the fly with any character selection. So you can use any font and render any character that it supports, allowing for Asian, Arabic and pretty much any script to be used. Even this poor integrated GPU can render a mix of scripts with hundreds of frames per second. g_pFont9 is the font object. Each font will have an object that needs to be properly initialized. And g_pSprite9 is the sprite object that is used by the text helper to render text using you font object. Hopefully things will become clearer when we see the code. 

And finally we have the effect support. In this context, a shader is often called and effect. Loading a shader file and loading an effect file are synonymous. g_pEffect9 is the variable that will hold the information about the loaded shader (I will continue to use the shader term in this series, not the effect term). Shaders are generally created by loading a shader source code that is compiled after loading into GPU machine code. Shaders generally have multiple variables that must be set each frame before that shader is use to render a model. There are multiple ways to do that. Under DXUT you will load a shader and then use the string name of the variable you want to obtain a handle for that variable. Later you’ll select the handle and the value you wish to set the shader variable to. g_hmWorldViewProjection, g_hmWorld and g_hfTime are the 3 handles/variables you will set in this sample.

And finally we have the 3 IDs for the 3 buttons we added to the g_HUD dialog: 

I don’t do as many crusades like I did back in the day, but my next one is probably going to be against GUI systems where you have manually and arbitrarily assigned numerical IDs for widgets (again!). I had a rant some posts back about this and is pretty much the sole reason I did my own GUI under Irrlicht. But DXUT is somewhat more complex in its GUI approach than the simple yet much hated ID assign scheme. I’m pretty sure I can add a pleasant callbacks system to it, but I haven’t tried it yet. So DXUT’s widgeting system should be enough. But defines? C’mon! At least use const, you wankers.

After having declared these variables and “constants”, the SimpleSample project goes into the familiar direction of implementing the DXUT callbacks and except for a few helper functions, the entire application is implemented just in those callback functions and the pretty much standard and interchangeable main function: 

This function is identical to the one from the first sample project, except that it has some extra initialization in the InitApp function: 

Here finally we have something unique to our sample: no more generic glue code! As said, if you have GUI you need a single dialog resource manager. On the first tree lines of the function you initialize all you dialogs with this resource manager. Every single such dialogue must be initialized before properly used. Additionally, each dialogue must have its callback set. This function will be called when a GUI related event occurs and the callback will allow you to identify the widget in question, in this sample using the numerical IDs we define before. The device settings dialog has its own callback that we don’t need to set, but we must do this for both our custom dialogs. We set the same callback for both, but the second dialog is empty and has no functionality. 

And finally we add the 3 buttons to the first dialog. We use the AddButton function. This function takes the following parameters, in this order: 
  • the ID of the button. This will be passed to the dialog callback to identify the widgets. 
  • the label of the button. This text will be displayed on the button. 
  • the X position in parent relative coordinates.
  • the Y position in parent relative coordinates. 
  • the width of the button. 
  • the height of the button.
  • the hotkey used to trigger the button with keyboard input. Optional.
  • if the button is a default button. Optional and false unless specified otherwise.
  • a pointer to CDXUTButton pointer ("out" parameter). This can be used to obtain the instance of the button created by this method. Optional, default NULL.
And finally we have the GUI callback for these dialogs: 

Here we get a taste for some of the utility functions from DXUT. DXUTToggleFullScreen toggles between windowed mode and fullscreen mode. The device is recreated when the switch occurs, going though the callback called when the device is lost and then the callback for when the device is reset. And before that the callback that verifies the device settings gets a chance to refuse the new settings. DXUTToggleREF toggles between a HAL and a REF device. Again, the entire flow of loose/reset callbacks is executed. And finally, we activate the device settings dialog. The SetActive method both activates and shows the dialog. By passing it the opposite of the current activation state, we create a toggle between the dialog shown and hidden. 

And this concluded the first part of this lesson. In part two we’ll go over the resource lifetime management callbacks.

Tuesday, June 5, 2012

DX(t)UT – 01.1 – OOP Preview

I had a day off from work on Monday. I’m so rested right now that I feel tired because of it.

Once in a while, especially after a longer post, I’ll come back and revisit it. I’ll do this to clarify some points, list some alternative techniques, do some natural follow ups or anything else that does not introduce a new concept.

This is what I’ll be doing right now for lesson number one. If you look over most DXUT (and even straight DirectX) examples out there, they are a huge pile of spaghetti code, with a bunch of global variables and a few functions. I would like to add a little more OOP styled structure to it. You may also notice that a large amount of code remains completely unchanged from sample to sample. I would like to both create a minimal framework that allows the reuse of these snippets and to put it into action to make my samples leaner (and meaner, but not like that macro).

But keep in mind that what I am trying to do is not a wrapper. I do not want to introduce another layer on top of what is already a layer on top of DirectX. I just want and an OOP structure to DXUT styled application and add a little code reuse. What I’ll be using will serve exactly this purpose and nothing more, so don’t expect good and flexible design, qualities that would recommend this approach for anything more than small tutorial applications or anything that hides the DXUT approach an turns it into a high(er) level abstract CG framework.

Today I am only offering a preview of this approach. I’ll take the example from my last post and show how it looks after the changes. I’ll give the same treatment to lesson 2, so I’ll explain a second official tutorial as is and in the follow up show how it can be done in a more OOP style. Only in lesson 3 will I formally introduce the classes that are involved and post full source code for them. Until then, here is a preview for the DXUTApp class:

It is a very simple class that mirrors the callback approach from DXUT and has some very basic functionality implemented for each callback. Go back to lesson number one to see what these callbacks are used for if you need to. Their name has been cleaned up a little and I hope you’ll have no problems matching things up. Let me list the default functionality of these methods:
  • IsDeviceAcceptable will simply return true, so all devices are accepted. 
  • ModifyDeviceSettings returns true, so the application will accept any settings. 
  • OnCreateDevice will return S_OK, thus not creating or modifying any resources. The same goes for the 3 other resource creation/destruction functions. 
  • OnResetDevice will return S_OK. 
  • OnLostDevice will return S_OK. 
  • OnDestroyDevice will return S_OK. 
  • OnFrameMove does nothing. 
  • OnMessage returns 0 and does not process any message. 
  • OnFrameRender will clear the back buffer with the color black and clear the Z-buffer.
These member functions take the same parameters and have the same return type as their non member counterparts, except for the void pointer used for custom data. If you need custom data just place it into your class that inherits from the DXUTApp class. In practice I have not encounter a single example yet where this would not be enough and you needed to have that extra parameter.

The class also has a Register method. You need to call this once and should be one of the first things you do in the main method.

Using this class you could simply instantiate as a local variable in your main function, call register and then proceed with the normal DXUT setup functions. You don’t need to use any of the DXUTSetCallbackXXX methods and using them after the Register call will actually break the functionality of the class. Doing this will net you with a black window that should run OK on pretty much any computer known to man (if it has DirectX 9 support).

But we are not going to do this. We are going to take it one step further and inherit from this class and override some functions so we get an example that has exactly the same functionality as the “EmptyProject” SDK sample:

We inherit from the DXUTApp class and only override the methods we need to. In practice this means that in real examples we’ll override every single method. On the other hand, after 2-3 lessons we’ll isolate some code that is repeated and stick it into a class and start inheriting from that class to reduce code repetition. Let’s take a look at the implementation of these methods:

The code for IsDeviceAcceptable is 100% identical to the one from the original sample. In fact I just copied it over, this is why I did not rename the parameters to a slightly more reasonable and uniform scheme. I did this intentionally to show that you can take existing code and fit it into my scheme. This is vital I think for beginners. Once you get the hang of DXUT you’ll have not problem switching things around as much as you please. Anyway, the function does the same alpha blending support test to exclude some devices from running this application. Soon we’ll exclude everything that does not support pixel shader 2.0 and once we target pixel shader 3.0 the pixel shader 2.0 code paths will be treated as fallback.

The second function we override is the rendering one. Since the default implementation from my class fills the frame with black and our original sample did so with blue, we need to override it. As explained earlier, this is not meant to be a full framework that you would use in let’s say the implementation of a serious project, like a commercial game. Under such circumstances you would probably add support for background colors and even a full stack of modular post processing effects. Here we just copy the code and change the color:

The final piece of the puzzle is the main function:

The function pretty much looks the same, but instead of registering a bunch of callbacks we just register our instance of the class. Even though this is not meant to be a wrapper, the base DXUTApp class will get some minor improvements as time goes by. As an example, for me personally the use of “DXUTMainLoop();” is quite jarring. Since we are doing things OOP and already have a local variable called “app”, invoking the main loop should look something like “app.MainLoop();”.

But this will be sufficient for our first preview of the OOP approach. I need to save something for later.

As I reminder, for people who skipper the first post from this series because it was too long, let me reiterate the purpose of the series: I want to share a few useful shaders that took me quite a while to piece together from dozens of sources on the Internet. Finding good and easy to understand shader information out there is quite the scavenger hunt.

Meanwhile I have decided to add about 3 more lessons on the subject of terrain rendering as a bonus. While creating the procedural terrain renderer I tried a few techniques that are reasonable and can be useful but did not fit my particular needs. I want to preserve them too.

So that’s the basic idea: if I spent hours trying to piece together a shader that in the end I did not get to use, I’ll post it here (but only if I can do it in a comprehensive way) before it gets lost somewhere on my hard drives and I forget how they actually work. 

Friday, June 1, 2012

DX(t)UT - 01 - Empty on the inside

Hi and welcome to my new and understated series! As promised quite a while ago, I will try and share some of the knowledge I have acquired in the fascinating but daunting domain of 3D engine writing. I have acquired a lot of knowledge, some useful, some that I will never use again and created a few shaders that would be a shame to waste. So I'll create a few tutorials based on DXUT to introduce some basic concepts and show how these shaders can be put into use. I have named the series DX(t)UT. See what I did there? I r wordsmith. Think of it LL3DLGLD version 2.0, with the exception that all the presented material will be fully explained, together with source snippets and even full compileable source code when needed.

Since this is the first post in the series I must stop and focus on some introductory points. First off all the tutorials will be targeting C++ with DirectX. Not the best choice. DirectX, while the best at what it does, even after multiple interface clean-ups is still quite obtuse and unpleasant to use. Before you can use DirectX you need to set up a basic window and event handling and since I am targeting low level APIs, this would end up being done directly with Windows API, which is even more unpleasant to use and understand. This is where DXUT comes in. It is a very thin wrapper over some parts of the API that takes care of initializing the main window, event handling and the nitty gritty of DirectX initialization. DXUT is an utility library and after you use it to initialize all that must be initialized you still end up using full DirectX. So you will both learn to use DirectX and generally be able to copy and paste DirectX snippets into your DXUT application without problems. We will put this to the test around lesson 5, where I'll convert some very useful DirectX samples to our DXUT application framework.

As said before, DXUT with C++ is a pretty poor choice. I think this series would be more useful if it targeted XNA 4.0. As a famous graphics programmer before me said, "that's where the shiznit is at, dawg"! This series is dual purposed. While I want to record some stuff and make it available for posterity, I will also try to teach you a few concepts and make you understand them. In consequence, a primary audience would be collage students into computing and graphics who are not taking a course on this subject. Or maybe high school students. I did a lot of graphics related programming in high school and if you are as smart as I was you'll have no problems understanding any of it. So a young and skilled but lacking experience individual, who likes games and would like to create and engine might find some very useful information here. No, you won't be available to create competitive engine. Get it out of your head. Not because the content here will be lacking (which it will), but because the number of man hours and shear effort needed to create an engine as powerful as the ones the big boys are using for commercial games is too much even for a small team to handle, yet alone one individual. But you can learn a lot of small stuff. And if this is what you want to do, I recommend XNA. It is a great platform, well documented, everybody is using it, the Internet is full of information regarding it and it can be quite pleasant to use. There is no good reason to use DirectX/DXUT directly if you want to create a game or even a high level engine capable of multiple games. But if you are interested in the low level stuff and would like to have total control of every single bit, create everything by yourself and have a playground, read on.

Boy, I sure am rusty at writing and teaching. The above paragraphs are all over the place. I promise to improve upon this in the future. So I won’t stall and dive right into it at a moment’s notice, but there is one more thing that I want to mention. I’ll start out with a few introductory lessons, but the main focus of the series is shaders! This is why I don't mind that much that I am targeting the lesser platform here. The way graphics work today, you'll end up relying on the GPU and shaders for most tasks. In a few years even more so. Even today you can do tons of stuff without invoking the CPU in a meaningful way (like fully GPU based terrains that do not create vertex buffers) and once you understand the GPU part you can easily adapt if from DXUT to XNA or some high level engine.

The shaders will be written in HLSL (duh, DirectX). I will not investigate Cg as a "cross platform" shader language and in the future I'll explain why I am not targeting OpenGL and GLSL. I will also try to make full use of shaders version 2.0, trying to push them to the limits, but some things cannot be done without version 3.0 or even 4.0. I will also be mainly targeting DirectX 9.

That's it for the introduction. Let's dive right into it!

For the first lesson I will analyze and explain one of the DirectX SDK samples: EmptyProject. This is the shortest official example that does absolutely nothing so it is well suited for explaining how DXUT works. Even so, it is relatively long and verbose for a program that does nothing except to show an empty window. But is a lot shorter that the classical DirectX/Windows API equivalent.

A huge reminder here in the middle of the post: I expect you to be comfortable with C++ and Visual Studio. In the future I'll distance myself from it, but for starting lessons this offers the path of least resistance. I won't explain step by step how to set up your environment. Try to figure it out on your own. But here are the main steps:
  • Download the Windows 7 SDK free from the Microsoft site. This includes the compiler, header files and necessary libraries. This is fully command line, so you'll need and IDE too. You only need the C++ parts, but you can fully install it to avoid problems if you don't know what you are doing. 
  • Download Visual Studio 2010 Express free from the Microsoft site. The Express edition is pretty good editor. It won't get you too far because the libraries that it ships with are very limited. This is where step one comes in. The Windows 7 SDK will have all the platform specific headers and libraries that the Express edition is missing. Or at least this is how the 2008 version worked. 
  • Download the Direct X SDK free from the Microsoft site. 
Obviously, Microsoft is paying me. I am a corporate sell out and... DIE GNU! No, seriously, these are just a few free tools that are easy to set up and have a large user base so you can Google stuff if it is broken. I have a setup where I can use MINGW as an alternative for compilation with the press of a button and have not used Visual Studio in years. But for this series, if you followed all the steps, this will get you going a lot faster.

Now that you environment is all set up (bonus points if you already had one set up or you managed to get it right on your first try) you should have all the DirectX samples installed. For simplicity I'll consider that you installed under the default paths, so navigate to "c:\Program Files\Microsoft DirectX SDK (June 2010)\Samples\C++\Direct3D" (your path may be slightly different). Here you will find all the samples. Go to the "Bin/x86" folder. Here you will find all the samples compiled. Run a few of them to see what they do and to make sure that your GPU can handle them. Up to date DirectX and drivers are a good idea.

Do the samples work? Good. Now go back to the first path and go into the "EmptyProject" folder. Double click on "EmptyProject_2010.sln" and after Visual Studio boots up, compile and run it. If everything went without an incident, you will be greeted by this lovely window:

Lovely, just lovely! I bet you are all excited and tingly on the inside about becoming a real graphics programmer!

This application is perfect to show off how DXUT works. Let's start at the end of the program, where the "main" method is located:

Above is the code for the main method. Since Blogger is not that great at formatting and spacing text, I'll use screenshots. You can find the code in the folder I mentioned above, so you don't need to type it out. When I'll post original code I'll provide download links for the full project.

So let's analyze this "main" function. Since this is Windows API application, the entry point is somewhat different from the standard main function, but is serves the same role. The first 3 lines (#if... #endif) set up some debugging utility checks which I'll leave in for now.

The next "block" sets up all the callbacks. DXUT is callback based. You need to call a set of "DXUTSetCallback..." functions. These callbacks have very specific role and meaning and do a nice job of abstracting away the glue code so you can focus on the actual part you are interested in. DXUT supports DirectX 9 and 10 callbacks (and 11, but I won't talk about 11). You have a set of functions that set up the callbacks for DirectX 9 and equivalents for other versions. As an example, the DXUTSetCallbackD3D9DeviceAcceptable function has a DXUTSetCallbackD3D10DeviceAcceptable counterpart for DirectX 10. You should set all the callbacks for the version you are targeting. If you want to support multiple versions, you should fully specify all callbacks for all versions. DXUT will pick the highest version that is available, but there are methods that give you full control.

Let's skip this block for now and see how we create our application. The first method is DXUTInit. This does the main initialization and set up tasks so that DXUT can work and is the first thing you should call after having the callbacks set up. If you do not call it, DXUT will call it when you try create the device with default parameters. The first parameter is a boolean that tells DXUT to parse the command line. DXUT supports quite a few command line arguments. You could pass "-fullscreen" as an example to any DXUT app to force fullscreen mode. These parameters work as overrides, but only the first time. Let’s say you have your application set up to start in windowed mode. If you run it with a command line to force fullscreen, it will be run in full screen. If the user than goes into a possible setting dialog your application provides and disables fullscreen, the command line argument will not override it a second time. You can find the full list of parameters in the SDK documentation. The second parameter tells DXUT if it should display error messages for possible errors it has found. This function takes more parameters that I will not describe here.

The next function that we call is DXUTSetHotkeyHandling. This sets up a few basic keyboard shortcuts. The first parameter will enable Alt-Enter as a fullscreen toggle. The second will allow Esc to be used to exit the application. The third will allow Pause to be used to pause the frame processing loop. As you can see, these are very basic features that are at most a useful little feature that you can use while prototyping something. Later you will probably enhance/replace these small touches. This is very much in line with the design philosophy of DXUT.

Next we have DXUTSetCursorSettings, the third useful features set up function. By default the application will display a cursor when in windowed mode. Setting the first parameter to true will keep that cursor visible when you switch to fullscreen mode. If you want fullscreen windows without a cursor, use false. The second parameter clips the mouse movement to the window boundaries in fullscreen mode. To be quite honest, I don't get this flag. It does not seem that useful unless you have a multiple monitor setup. On the other hand, a toggleable mouse clip for windowed mode would be very much appreciated. Get on it, DXUT authors!

Together with the callbacks, this concluded the set up step of our application. We told it to parse a few default commands line arguments, display error messages, show cursor, handle a few shortcuts and gave the window a title. All this without using Windows API or even DirectX API!

The final step is to create the device: DXUTCreateDevice. This is the first function that actually does something "important" directly. The first parameter controls windowed mode, with true meaning that the application will not run in fullscreen mode. The second parameters control the suggested width and height of the window. DXUT might adjust these values depending on your system. In fullscreen mode the width and height should describe a resolution your adapter supports for optimal functionality. Based on what callbacks are set up and what your system supports, this function will choose a DirectX version. It will take all the options your provided (and if you did not call some of the setup functions, they should be called automatically with default parameters), gather them and after some steps it will call the callback you set with DXUTSetCallbackDeviceChanging so you can inspect and review these setting before they are applied. And then it will create everything and your window should be ready to go.

The main function has still two lines left. As customary for Windows applications and games too, they have a main loop that pools events and does game logic and rendering. In DXUT you use DXUTMainLoop to run this loop. 

And finally, you return with the value provided by DXUTGetExitCode. DXUTMainLoop will exit from the main loop when your application finalizes correctly or when an unrecoverable error has occurred. DXUTGetExitCode will return zero if the application finalized as expected and a positive value if an error is encountered. I won't list the values here, but most can be described with "an error occurred when creating/initializing...".

So, that's about it for the main function. I did not go into great detail, yet still the post is quite lengthy. And it will get even longer because I did not go into the callback functions. Still, this is a lot shorter and abstract than the equivalent plain DirectX application.

After we get used to all this, I'll try and isolate the "glue code" core and only have smaller parts that you need to change from application to application. So on to the callbacks!

First, we have IsD3D9DeviceAcceptable (set by DXUTSetCallbackD3D9DeviceAcceptable):

This callback is used to test the capabilities of your GPU in order to determine if it is capable of running your application. Here you will test hardware features, shader support and other major features. You won't test parameters that are unique to you current execution of the program, like resolution or colors. In this sample it only checks to see if the device supports alpha blending and rejects it otherwise. I won't explain that since you will probably copy & paste that everywhere. If your device does not support basic blending, you probably don't have any worth-while 3D acceleration. In future samples we'll keep this check and also verify the shader versions that are supported.

Then we have ModifyDeviceSettings (set by DXUTSetCallbackDeviceChanging):

This function is called before each device settings change. DXUTCreateDevice gathers all the settings and presents them to you before it creates the device so you can review and change them. Every time you change the settings this function will be called. If the function returns true, the DXUT will try to apply the settings. If it returns false, it will keep the current settings. So it makes sense that you return true the first time, so at least you have a window here something can be displayed. More specific applications might refuse some resolutions and other combination of settings, but generally an application should be flexible because you have no way to predict what setup the user will use to run it. In this skeleton application we simply return true and accept anything.

Then we have OnD3D9CreateDevice (set by DXUTSetCallbackD3D9DeviceCreated), which initializes the resources that our application might need for rendering. There are two kinds of resources. There are persistent resources that once created can be used until the application exits (and frees the resources before the exit). Other resources do not live such a long life. These resources can depend on the buffer size or other variables. The back buffer is such a resource, that get's reset every time the size changes. Or they can get reset because of other reasons. A texture might get freed when you Alt-Tab away from your game and run another application that requires that memory. That resource needs to be reset when you switch back to your application. OnD3D9CreateDevice is used to create only persistent resources and in our empty sample we simply return success:

The counterpart to this function is OnD3D9ResetDevice (set by DXUTSetCallbackD3D9DeviceReset), which creates resources that are no persistent. It is called "reset" because the line between having to initialize a non persistent resource and having to reset it due to some event is a blurry one. In general you'll just call a "reset" on all the appropriate resources here and this is mostly a filler function. One case where you actually need it is when the reset is caused by you changing the device settings. Each time you do that this function will be called (only if the setting were accepted by ModifyDeviceSettings ) and here you will probably do some computation based on the device size and reposition you camera and GUI. Again, we return just the OK value:

The resources that are reset here and were created in OnD3D9CreateDevice must also be released somehow. These creation functions have they counterpart that releases them. As a general rule, what you create somewhere you destroy in the counterpart function. These functions can be quite confusing if you are a beginner and since the empty project example only returns a success value if needed, I can't really explain them here. I'll try to do so in the second example. Here is the body for the two functions:

This concludes my description of the second phase of the project. Phase one was initializing everything and phase two was adding the bodies for the resource creating/freeing functions. The final phase is handling frames, rendering content and handling events. This is done again by callbacks and yet again they are very simple in this example.

The first one is OnFrameMove (set by DXUTSetCallbackFrameMove). This function is called every frame before it is rendered and here you will have the bulk of your game's logic. You will update counters, timers, run animation, collision, path finding, A.I. etc. here. As long as it is a short enough task. You don't want to have a long task because this is called in single threaded mode and no new frames will be rendered before this function exits:

Next we render the frame with OnD3D9FrameRender (set by DXUTSetCallbackD3D9FrameRender):

This is the first function we actually do something that is not initialization/book keeping/glue code. Here we clear the buffer and the Z-buffer and we call BeginScene and EndScene. Between these two calls the actual 3D rendering calls would be put. "D3DCOLOR_ARGB( 0, 45, 50, 170 )" is a macro that specifies the color in ARGB format using integers. And I'll leave as homework the presence of the apparently unused "hr" local variable. Hint: it is not a type/oversight.

You are not allowed to do logic in this function. While normally for each OnFrameMove OnD3D9FrameRender will be called only once, this is not guaranteed. If you include logic here and it changes some internal state, two frames that were supposed to be rendered identically might turn out differently.

And finally, we have MsgProc (set by DXUTSetCallbackMsgProc), used as the callback for event handling. Empty as usual:

Wow! That was long and hard! Avoiding obvious default joke. But bringing attention to me avoiding it!

Putting all this together, you will find that you have 6 KiB of code that create an empty blue window that I have spent pages describing. I tried to keep it as short as possible, but giving basic information on all the elements is a must so we can get on to real task and lessons on shaders.

If you came from a Unity/other drag and drop engine background you probably left the moment you saw the WinMain function. If you came from an OpenGL/GLUT background you probably find this long and verbose. I hope you are not patting yourself on the back and saying "LOL, FAIL M$!!!". If you come from Ogre3D then...

Anyway, this is the end of part one. In part two we'll go over another simple skeleton app that does nothing (but this one is going to be a lot more complicated) from the DirectX SDK samples. In part 3 we'll try and abstract away all the glue code so we can have a nice little OOP playground for playing around with DirectX, while adding some parts from another sample application. In part 4 we'll completely recreate the before mentioned sample application using this mini-framework. In part 5 we'll take some very useful DirectX snippets as they are from the Internet and see how easy is it to integrate them into a normal DXUT app and then how easy it is to integrate them in our test framework. By lesson 7 we'll load meshes from external files and render them with lighting and CSAA antialiasing.

And if any aspiring DirectX-er reads this, please let me know what you think!

Oh, and stay tuned for status updates on Dwarves & Holes, the engine and the future of this blog.