Nov
5

Creating and Configuring a DirectX 11 Project in Visual Studio 2010 Jon Keon

C++, Visual Studio 2010

After working with Visual Studio 2010 for a while, there are quite a few settings and choices you can make that will enable your projects to be easier to work with and also allow others to work on your project with you with minimal hassle. This is how I’ve ended up configuring Visual Studio 2010 to work with DirectX 11. I’d be curious as to what others in the industry currently do.

Prereqs:

First a couple prerequisites:

  • Download and Install Visual Studio 2010
    • There’s a 90 Trial for all versions or a Free Edition of Visual Studio C++ Express
    • Download Links
  • Download and Install the June 2010 DirectX SDK

Once everything is installed you can start setting up your project.

Creating a Project:

The first thing to do is setup your project’s directory structure on your harddrive. It’s a good idea to prepare in advance for dealing with whatever source versioning system you’re going to use as well. I’ll be using SVN through Assembla. It’s free until you start going over a 1 GB or getting into the advance features but if you’re looking for an easy private place to store your code I’d recommend it.

Not too much to say here, just your standard versioning directory structure.

Now you can open Visual Studio and select File > New > Project…

This will bring up the New Project Dialog and you can configure it to look like this:

Essentially you’ll just want Visual C++ > Empty Project with the .NET Framework 4 selected at the top.

You can enter whatever name you want for the project/solution but the location is somewhat important. When Visual Studio creates a project and solution it uses that directory as the working directory for placing new files and running your builds. This leads to a lot of clutter if you aren’t customizing things and ideally you want to be able to log onto any computer and just pull down your SVN repo and have everything ready to go.

In my project, in my trunk directory on my harddrive, I’ve created the following directories:

  • bin
    • This is where all the executables will be built and where all the runtime data will be stored. You could just send someone the bin folder and they could run the final version of your project (not compile it though!)
  • docs
    • All the supplemental material relating to the project. Blog posts, architecture diagrams etc.
  • obj
    • When Visual Studio compiles your projects it will create .obj files for debugging. These files are often pretty large and change all the time. We want to store them in a separate directory so we can ignore them in SVN and if for some reason we have some weirdness in compiling a build, we can just delete the directory to force a recompile of the whole project.
  • raw
    • The raw directory is where all the raw assets for your project would live. PSD’s, Maya files etc. Files in this directory are where your artists would work and the final work that gets used by your program (png sequences or model files) would get put in the bin/data/ directory as you’ll want to use those final produced assets at runtime.
  • src
    • This is where all your source code will code and where your programmers will spend the majority of their time.
  • tools
    • This directory is for any special tools or scripts that might help your project along. Such as taking a generic OBJ 3D Model file and converting it to some proprietary format your program uses.
  • vs
    • This is where I’ve chosen to store all the Visual Studio specific files. It keeps them out of the way and allows for the possibility of members of a team using a different IDE if they so chose.

So naturally, when I’m creating a new project I want to choose the trunk/vs directory for where to store my project.

Customizing Filters:

Once you’ve created your project you’ll be greeted with a blank slate and a pre-populated Solution Explorer.

If you’ve come from a Java or ActionScript background this will be reminiscent of a Package Explorer. The MAJOR DIFFERENCE though is that with C++, these are just filters and are virtual. They have no reflection of the file structure on the hard drive where as in Java or ActionScript, classes must be placed in a folder tree that represents their package structure.

The default filters are one for Header files, Resource files and Source files. I’ve looked at quite a few Open Source C++ projects and they all seem to roll their own structure depending on their needs so personally I’m going to do the same.

I’ve deleted the three default filters for Header files, Resource files and Source files and added a new one by right-clicking on my solution name and selecting Add > New Filter… and calling it src

This will be the root directory for all source files and then I will create a new folder on the hard drive for every new filter I create in Visual Studio. In this manner we have the concept of “packages” as they exist in AS3 or Java which I find just makes things easier to read and understand what functionality a class may contain.

After a bit of development you’d have something similar to this:

As you can see, the filters match the folders on the harddrive making it easy to see what concepts classes belong to.

Configuration:

Now we’ll need to configure Visual Studio so it knows where to get the proper libraries and include files to build DirectX and to make sure it knows where to place all of our files in our custom directory structure.

Selecting your project name in the Solution Explorer go to the menu bar and select Project > Properties

This will bring up the Property Pages screen for your projects. At the top right there is a button called Configuration Manager… We’ll want to open that so we can customize our builds.

By default, Visual Studio will create two builds for you. A Debug one and a Release one. The Debug build will allow you to debug and step through your code but it will run slower. The Release build is the one you’ll want to ship to your customers or end users and will run at the proper speed but you can’t debug it to check for errors.

Ultimately in development you’ll want to test your program under various conditions. Sometimes in tracking down a bug you’ll want as much information as possible and you won’t care how slow everything is running. Other times you’ll want to test performance and you want everything running as fast as possible. You can create as many builds as you see fit but for now I’m going with just three of them.

First I’ll need to create a new build by selecting <New…> from the drop down for Active Solution configuration.

I’ll give it the name Development. This will be the build that I’ll normally be using. I can still debug, but it should run at a decent speed. Debug I’ll reserve for heavy debugging where everything is checked and logged and Release will be the fast build I’ll send out to users etc. I’ll base this build off of the current Debug build to make it easier.

Now we can start editing the properties of our Build Configurations. Note: Make sure you have All Configurations selected!

Below are the default properties:

With All Configurations selected we’re going to change Output Directory, Intermediate Directory and Build Log File.

The Output Directory is where your program will be compiled to and where the end .exe that you click on lives. The macro $(SolutionDir) refers to where your Solution file is stored. In our case it will be in trunk/vs/<project_name>/<solution_name>. We simply jump up two directories so we’re in trunk and then select bin.

Now we could put the absolute path instead and have something like C:\work\code\cpp\athena\trunk\bin but this assumes that everyone using the project will have placed the project in the exact same file path which is rarely the case so relative pathing is ideal.

The Intermediate Directory is where the debug obj files are created and stored. Again we just jump up two directories and choose the obj directory. This time we’re also going to append another macro called $(Configuration) which is the name of your Configuration (Debug, Deployment, or Release). This will keep the obj files separate from the different builds so we’re no overwriting files all the time.

Finally the build log file just gets chucked into the same folder as the Intermediate Directory.

You’ll notice that the Target Name is blank. This is because we want the Target to be different across the different configurations. So you’ll have to change from All Configurations to Debug, Deployment, and Release respectively and choose a name. I’ve chosen:

  • Debug: $(ProjectName)_Debug
  • Deployment: $(ProjectName)_Deployment
  • Release: $(ProjectName)

This will allow for three separate exe’s to be created based on the configuration.
Next we’ll want to select the VC++ Directories tab and make sure that All Configurations is selected again.

Select the Include Directories and click on Edit… Then add the DirectX include directory from C:\Program Files (x86)\Microsoft DirectX SDK (June 2010)\Include
Also include your source directory! So add $(SolutionDir)..\..\src\ as well.

Then do the same thing for the Library Directories and add the DirectX lib directory from C:\Program Files (x86)\Microsoft DirectX SDK (June 2010)\Lib\x86

Now Visual Studio will know where to find the Header files it needs to compile and the Linker will know where to find the various libraries it needs.

Debug Specific Configuration Settings:

Now we’ll want to go through and set up the specific configuration settings for our various deployments. We’ll start with Debug.

Choose the C/C++ tab and choose General. Make sure you have Debug selected as your Configuration!

By default the Debug Information Format should be set to Program Database for Edit and Continue (/ZI) which will let us edit the code while debugging and have changes update in real time.

I’ve upped the Warning Level to Level3(/W3). I tried to enable all Warnings or go to W4 but it found a ton of them in the Windows code and that was just annoying.

I also set the compiler to treat Warnings as errors. While a warning won’t break your program, it’s a good idea to fix any warnings immediately before they get out of hand.

 

Next select the Optimization tab. There shouldn’t be anything to modify as we don’t want any optimization while debugging. It should look like this:

Next select the Preprocessor tab. We’re just going to add our own Preprocessor Definition so we know the difference between our Debug and Deployment builds.

Finally select the Code Generation tab. The defaults should be fine but for Edit and Continue to work properly, the setting Enable Function-Level Linking should be set to Yes.

The rest of the settings should be fine as the defaults.

 

Development Specific Configuration Settings:

The Development configuration settings are the exact same as the Debug ones except that the preprocessor definition is ATHENA_DEVELOPMENT instead of ATHENA_DEBUG.

Release Specific Configuration Settings:

With Release mode, the settings are largely the same but we’ll make a few changes to a couple of the screens and turn on Optimizations.

In the General screen, we don’t need Edit and Continue functionality and we can also use Multi-Processor Compilation for faster compiling.

 

In the Optimization screen, we want to enable as much as possible to make our program run as fast as possible. NOTE: When optimizations are enabled, even if you happen to be debugging, the information you’ll see on screen will not be accurate due to the changes the compiler makes to your code when compiling.

The defaults for the rest of the screens are fine for Release mode.

 

Building:

Now that everything is set up you should be able to build and run your program using the three configurations and all of the files will be created at the correct locations on the harddrive.

 

Additional Visual Studio 2010 Plugins:

At this point there are a few Visual Studio 2010 Plugins that are great for helping you code.

  • Visual Assist X 
    • Great plugin for intellisense among other things. Has a 30 day trial and then a personal licence is only $90. Could be cheaper but it’s still pretty good.
  • Productivity Power Tools
    • Getting this free plugin for the CTRL-Click ability alone is worth it. Also comes with some neat features like a scrollbar that is a smaller version of your code.

Additional Visual Studio 2010 Configurations:

Custom Tasks are sometimes something you’ll want to add to your comments to let you know why something was done a certain way and to come back to it.

To add your own custom tasks go to Tools > Options. When the Options screen comes up select Environment > Task List. Then to add a new one simply type in the name and choose a priority and then select Add.


To actually enable these Tasks to be shown in your Task Window, you need to enable it by going to Text Editor > C/C++ > Formatting and then selecting Enumerate Comment Tasks to true.

Committing to Source Control:

Now that everything is all setup, we’ll want to save this to our Source Control server so that no matter where we are, we can always pull the project down and build it.

Ideally you’ll want to version control everything that is necessary to build your program. This includes assets and the like but it depends on how much space you need. Version controlling 4GB+ raw video files may not be the wisest of solutions.

At the very least we need the source code and project settings.

I’ll go through the directories we created earlier for what should and should not be committed.

  • bin
    • We’ll want to commit anything in the data folder as those are final assets that the program needs at runtime. I’ve committed my logs folder so it exists, but everything inside that folder gets added to SVN Ignore.
    • All of the exe’s and their corresponding pdb and ilk files get added to SVN Ignore as well since we’ll be building those again and frequently.

  • docs
    • Everything in here gets committed.
  • obj
    • Everything inside the obj folder gets added to SVN Ignore. These files get recreated on every build and are not necessary to save.
  • raw
    • Judgement call based on your raw assets. Better to be safe than sorry.
  • src
    • Without a doubt yes! Everything gets committed.
  • tools
    • Same here, all the tools should get committed.
  • vs
    • We only want to commit the .sln file in the Solution Directory.
    • And only the .vcxproj and .vcxproj.filters files in the Project Directory.
    • This way only the settings that work across different computers get saved and all the user information and custom aspects are unique from user to user.



Now you can commit and update as much as you like. It’s a bit of a process but getting Visual Studio configured in this way makes development much easier across the board.

This entry was posted on Saturday, November 5th, 2011 at 6:34 pm and is filed under C++, Visual Studio 2010. You can follow any responses to this entry through the RSS 2.0 feed. You can leave a response, or trackback from your own site.