DirectX 9 C++ Graphics Tutorial 1: Getting Started
Posted by gregd1024 on February 20, 2008
In this post I’m going to cover writing the most basic DirectX 9 application in native C++. You’ll see how to paint a solid color on a form as well as the minimum amount of code all DirectX 9 applications must have. Note: when I refer to DirectX, unless otherwise specified, I’m strictly referring to the graphics portion of it – Direct3D.
This post is going to be one of a series. I’m going to cover writing simple DirectX 9 applications in C++ and I’ll also cover how to write those same applications with Managed DirectX (MDX 1.1) in C#. These posts will alternate – one in C++, one in C#, back to C++, and so on. After this, I’ll eventually cover some DirectX 10 stuff in C++ (which can be vastly different from DirectX 9 in certain areas). There is no MDX equivalent of the C++ DX10 API – the XNA Framework is meant to replace MDX since Microsoft dropped support for the MDX 2.0 Beta project. However, I’m not sure if XNA is mature enough yet to be able to do all of things originally included in MDX 2.0. I’ll explore that issue in a future post.
Requirements
The steps and screenshots in this tutorial are based on Visual Studio 2008 Express. However, everything was also tested in Visual Studio 2005 Professional.
You’ll need the DirectX SDK to run the sample programs. You can download it from Microsoft’s site with this link. Note, however, that their latest release (which is November 2007 at the time of this writing) took out the MDX 1.1 samples and documentation. If you still want those, download the August 2007 release or earlier (I use the June release).
Tutorial Source and Project Files
To get the finished result of what this tutorial teaches – project files, binaries, and source – use this link:
If you follow this tutorial’s instructions exactly as specified, you should end up with the same code and output. However, copying and pasting from a web page to Visual Studio sometimes results in double spaces between lines where it wasn’t intended. In almost all cases C++ doesn’t care and your code will still compile perfectly fine (a multi-line macro is one of those rare exceptions).
Setting Up the Project
Start out by performing the following steps:
Create an empty project and add one source file called “main.cpp” (you can actually name it anything you want, but I’m going to refer to this file as “main.cpp” throughout the text).
Go into the Project Properties dialog and add the following include directory, “$(DXSDK_DIR)\Include”:
Add the following preprocessor directives, “WIN32;_DEBUG;_WINDOWS”:
Add the following library dependency, “d3d9.lib”:
All the other defaults are fine. Save these settings and move on to the next step.
Creating the Form
Drop the following code snippet into your main.cpp file. This is the smallest amount of code that all C++ Windows form applications must have:
#include <windows.h>
LRESULT WINAPI WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInst, LPSTR lpCmdLine,
int nShow)
{
MSG msg;
WNDCLASSEX wc = {sizeof(WNDCLASSEX), CS_VREDRAW|CS_HREDRAW|CS_OWNDC,
WndProc, 0, 0, hInstance, NULL, NULL, (HBRUSH)(COLOR_WINDOW+1),
NULL, “DX9_TUTORIAL1_CLASS”, NULL};RegisterClassEx(&wc);
HWND hMainWnd = CreateWindow(“DX9_TUTORIAL1_CLASS”,
“DirectX 9 Bare Bones Tutorial 1”,
WS_OVERLAPPEDWINDOW, 100, 100, 300, 300,NULL, NULL, hInstance, NULL);
ShowWindow(hMainWnd, nShow);
UpdateWindow(hMainWnd);while(GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return(0);
}
LRESULT WINAPI WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch(msg)
{
case WM_DESTROY:
PostQuitMessage(0);
return(0);
}return(DefWindowProc(hwnd, msg, wParam, lParam));
}
Since the purpose of this tutorial is to go over DirectX and not basic Win32 programming, I’m going to keep the following description of the code brief. There are many Win32 tutorials on the internet that explain in extreme detail the low-level aspects of Win32.
First we must define a WinMain() function and include <windows.h>. The windows.h header file includes most of the definitions needed to access the Win32 API. In order to run any Win32 program, the following three steps must be performed:
- Create a windows class.
- Create a window object.
- Show the window.
In addition to these steps, all Windows programs must have something called a “message pump.” This is the mechanism in which the Win32 subsystem sends your application events about what is happening on the outside (i.e., what the user is doing in your app, global events of the operating system – such as starting to reboot, etc.). Your application must either respond to these events or must pass them to the default Win32 event handler.
For the first step, create a Windows class – this doesn’t have anything to do with a C++ class. It is a Win32 specific term that tells Windows about your program. It needs some minimal information in order to setup your application to run in the Windows environment. It needs to know:
- How GDI should handle your application’s main window.
- A function pointer to your program’s message handler.
- The instance handle of your program.
- A background brush (this represents the background color, but technically it’s not required – your window will appear transparent if omitted).
- Class string (a unique string that identifies your Win32 class object to the rest of Windows).
The WNDCLASSEX structure is used to hold this information. While there are more than five members in WNDCLASSEX, the code above specifies NULL or “0” for the properties in which Windows will take the default. The RegisterClassEx() function is used to send this information to the Win32 subsystem.
The next step is to create the actual window object. This object turns into the application’s main form. The CreateWindow() function, like its name implies, is used to create a window object. This function needs at least the following information:
- The same class string used when calling RegisterClassEx().
- The title of the form.
- The style of the form (dialog, tool window, etc.).
- The (x, y) position of the form and its size.
- The instance handle of your program (this should match the instance handle used when creating the class object).
As long as no error is generated, the CreateWindow() function returns a handle to your window. NULL will be returned if an error occurred. The next step is take that window handle and call ShowWindow(). The first parameter specifies the window handle and the second parameter represents how the window is to be shown by default. We used the “nShow” variable as the second parameter – the forth argument to WinMain(). This allows Windows to tell us how the window should be shown based on how the application was launched. The next line calls UpdateWindow(), which is technically not required by a program this simple. It allows any post-updates to occur after the window is first drawn.
We now get to the while() loop at the end of the main function. This loop is part of the “message pump” discussed earlier. If this loop wasn’t there your application would simply start and stop right away. There needs to be something that keeps your program running until it’s time to close. The “message pump” loop does exactly this. It continually checks for events from the Win32 subsystem by calling GetMessage() and subsequently passes them down to TranslateMessage() and DispatchMessage(). These two functions eventually route the events to WndProc() – your callback function specified in the windows class object. This function allows your program to execute whatever code is necessary in response to these events. If your application doesn’t need to respond to an event, it should pass it down to the default Win32 handler by calling DefWindowProc().
Creating the DirectX Object and Device
Now we must create two objects: the main DirectX object that allows us to interface with the API and the “device” object which allows interaction with the 3D hardware. Begin doing this, you’ll need to include the Direct3D header file and declare a couple global pointers to the DirectX object and device object:
#include <d3d9.h>
// globals
LPDIRECT3D9 g_pDirect3D = NULL;
LPDIRECT3DDEVICE9 g_pDirect3D_Device = NULL;
In order to create the DirectX object and device object, we add the following code directly under the call to CreateWindow() right above ShowWindow():
g_pDirect3D = Direct3DCreate9(D3D_SDK_VERSION);
D3DPRESENT_PARAMETERS PresentParams;
memset(&PresentParams, 0, sizeof(D3DPRESENT_PARAMETERS));PresentParams.Windowed = TRUE;
PresentParams.SwapEffect = D3DSWAPEFFECT_DISCARD;
g_pDirect3D->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hMainWnd,
D3DCREATE_SOFTWARE_VERTEXPROCESSING, &PresentParams,
&g_pDirect3D_Device);
Let’s go through this line by line. First we create the DirectX object by calling Direct3DCreate9(). The first parameter, D3D_SDK_VERSION, is a special number that ensures an application was built against the correct header files. If the number doesn’t match, the call will fail.
Next we declare and fill in a D3DPRESENT_PARAMETERS structure. This object holds properties about how an application should behave. In our sample, we want it to run in windowed mode and we want the video hardware to handle the back buffer instead of handling it ourselves (the full meaning of D3DSWAPEFFECT_DISCARD is beyond the scope of this tutorial, but basically it tells the device driver to select the most efficient way of handling swap chains).
We then use the main DirectX object to call CreateDevice(). This function does the work of allocating the device object and associating that object with the 3D hardware (or software – depending on what parameters are specified). The first parameter, D3DADAPTER_DEFAULT, tells DirectX to take whatever graphics card is the default (typically the one and only piece of active video hardware connected to your motherboard). The second parameter, D3DDEVTYPE_HAL, tells DirectX to use 3D hardware, instead of a software emulator, for rendering. A software emulator becomes useful only for low-level debugging – don’t worry about it for now. The third parameter specifies the window handle that will receive the rendered output. D3DCREATE_SOFTWARE_VERTEXPROCESSING tells DirectX to use software for transformation calculations instead of hardware HTL (Hardware Transform & Lighting). If you had specified hardware transformation calculations instead, and the video card didn’t support HTL, then this function would fail. All new cards on the market today support HTL, and most have for quite a while. So unless your card is really old you can select hardware processing without any worries – just replace the existing constant with D3DCREATE_HARDWARE_VERTEXPROCESSING. The fifth parameter is a pointer to the D3DPRESENT_PARAMETERS object that we filled in right above the call. Lastly, the sixth parameter holds a pointer to the device object that will be created and returned by the function.
Now that the device object is created, we can call its functions to control the video card! The next section will explain exactly how to do this.
Draw on the Window
In this section we’ll see where the magic happens. While it’s not much – drawing a solid color in the window – you’ll see how to do more advanced stuff in the next few tutorials.
Before we begin, we must first handle the WM_PAINT event inside our WndProc() message handler function. The WM_PAINT event is fired whenever the interior of a window needs its contents redrawn. We capture the event by enumerating the WM_PAINT constant inside WndProc’s switch statement:
switch(msg)
{
case WM_DESTROY:
PostQuitMessage(0);
return(0);
case WM_PAINT: // <— ADD THIS BLOCK
// drawing code goes here…
ValidateRect(hwnd, NULL);
return(0);
}
ValidateRect() is called in order to tell Win32 that we’ve handled all of the rendering ourselves.
Now for the fun part – filling in the drawing code. Add the following two lines directly below the “case WM_PAINT” statement (where it says, “drawing code goes here…”):
g_pDirect3D_Device->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0, 0, 255),
1.0f, 0);
g_pDirect3D_Device->Present(NULL, NULL, NULL, NULL);
The first call to Clear() tells DirectX to fill a specific rectangle, or set of rectangles, with a certain color. The first two parameters represent the number of rectangles and the address of where those rectangles are stored. If “0” and “NULL” are specified instead, DirectX will fill the entire rendering target. The third parameter, D3DCLEAR_TARGET, means we want to clear the actual pixel buffer as opposed to the depth buffer or stencil buffer. This parameter could also be used to clear a combination of those buffers at the same time. The last three parameters tell DirectX what values to use for clearing the pixel buffer, depth buffer, and stencil buffer. Since we’re not clearing the depth buffer or stencil buffer, the values for the last two parameters have no effect.
Once everything has been rendered to the back buffer you display it on the screen by calling Present(). Parameters one and two represent the source and destination rectangles, respectively. Since we want the entire back buffer to get copied to the entire screen, we pass in NULL. The third parameter specifies which window to use for the display. When this parameter is NULL, Present() looks at what was originally set when creating the D3DPRESENT_PARAMETERS object (specifically the hDeviceWindow member). Since we didn’t specify anything in the beginning of our program, the memset() call would have set this member to NULL. When this happens, and windowed mode is set, Present() takes the focus window as its destination.
Shutting Down
We allocated two DirectX objects in our program – the main interface object and the device object. These objects must eventually be freed. Since we aren’t doing anything fancy that requires destruction and reallocation of these objects, we can simply put the clean up code right above the “return” statement in WinMain():
g_pDirect3D_Device->Release();
g_pDirect3D->Release();
We call Release() because these objects were given to us by DirectX via COM as opposed to being allocated with the “new” keyword or created with some memory allocation function. Therefore we must delete them through COM’s Release() function.
Run the Program!
You can now compile and run the program. Here’s what the output looks like:
OK, it’s not much at this point, but in the next few tutorials we’ll get into more exciting things.
Conclusion
OK, I admit, the final output of this tutorial wasn’t too exciting, but it only strived to cover the absolute minimum – nothing more, nothing less. All 3D DirectX applications start off this way. If someone made a DirectX project template for Visual Studio, the wizard would more than likely generate very similar code to what you see here.
In the next tutorial, we’ll see how to do the same thing in managed DirectX (MDX 1.1).
-Greg Dolley
*Get new posts automatically! Grab the RSS feed here. Want email updates instead? Click here.
Managed DirectX C# Graphics Tutorial 1: Getting Started « Greg Dolley’s Weblog said
[…] WordPress.org « DirectX 9 C++ Graphics Tutorial 1: Getting Started […]
Paul said
Great tutorial, Greg! I look forward to reading more. Keep ’em coming!
gregd1024 said
Thanks Paul! 🙂
Jone said
error C2065: ‘WndProc’ : undeclared identifier
error C2065: ‘g_pDirect3D’ : undeclared identifier
error C2065: ‘g_pDirect3D’ : undeclared identifier
error C2227: left of ‘->CreateDevice’ must point to class/struct/union/generic type
type is ”unknown-type”
error C2065: ‘g_pDirect3D_Device’ : undeclared identifier
error C2065: ‘g_pDirect3D_Device’ : undeclared identifier
error C2227: left of ‘->Clear’ must point to class/struct/union/generic type
type is ”unknown-type”
I think its just repeating. but yeah got these errors
gregd1024 said
Hi Jone,
This is because the project isn’t pointing to your DirectX SDK or you don’t have it installed. Since the project uses an environment variable to find the install directory, it’s more likely you just haven’t installed it. That’s why all the DirectX symbols are undefined. See the article for more information on how to point your project to the DirectX SDK location if you already have it. If not, see the beginning of the article for a link on where to download the SDK.
-Greg Dolley
Bill said
Excellent tutorial, Greg!
I have finally decided to brush up on my C++ and decided to learn to use DirectX at the same time and your effort has helped immensely. Thank you!
– Bill
gregd1024 said
Bill – Awesome, I’m glad the tutorial was helpful! 🙂
-Greg
Tito said
Hey Greg really neat stuff man!
I actually understood all of it.
Ive tried reading many tutorials on direct 3d but i must say this is the best as far as a beginner is concerned! Really comprehensive!
gregd1024 said
Tito – Thanks for the kind words! 😉
-Greg
Alex said
Greg,
Thanks for opening the door to DirectX and Visual C++ by this easy start! I had both DirectX, Visual C++ and your program running in no time. I hope to learn more from your other tutorials. Much appreceated.
Greetz,
Alex
gregd1024 said
Hi Alex,
Thank you for the kind words. 😉 I’m glad it was easy to understand and setup.
-Greg
Rob said
C:\Users\xsuicidesn0wmanx\Desktop\main.o:main.cpp:(.text+0xbf)||undefined reference to `_Direct3DCreate9@4’|
||=== Build finished: 1 errors, 0 warnings ===|
got this error when i tried it, although i use vista and the d3d10 sdk. the d3d9 sdk files are all in the d3d10 sdk also so i dont think that is the problem but havent ruled it out.
any ideas?
gregd1024 said
Rob,
DirectX 10 won’t work. They changed DX10 a lot from DX9.
-Greg
Greg said
I decided to learn DirectX programming about a month ago, and after going through a handful of books and other tutorials on the web, this has been the easiest and simplest to understand.
I’m going onto the next one now!
Thanks,
Greg
Ravi said
hi greg,
the tutorial you have provided is simple and pretty straight-forward, thanks for it.
still i managed to mess it up:
—— Build started: Project: asdd, Configuration: Debug Win32 ——
Compiling…
main.cpp
e:\ravi\c++\asdd\asdd\main.cpp(21) : error C2065: ‘“DX9_TUTORIAL1_CLASS”’ : undeclared identifier
e:\ravi\c++\asdd\asdd\main.cpp(30) : error C2065: ‘”DX9_TUTORIAL1_CLASS”’ : undeclared identifier
e:\ravi\c++\asdd\asdd\main.cpp(30) : error C2065: ‘“DirectX’ : undeclared identifier
e:\ravi\c++\asdd\asdd\main.cpp(30) : error C2143: syntax error : missing ‘)’ before ‘constant’
e:\ravi\c++\asdd\asdd\main.cpp(30) : error C2059: syntax error : ‘)’
e:\ravi\c++\asdd\asdd\main.cpp(64) : error C2143: syntax error : missing ‘;’ before ‘{‘
e:\ravi\c++\asdd\asdd\main.cpp(63) : error C3861: ‘sswitch’: identifier not found
e:\ravi\c++\asdd\asdd\main.cpp(65) : error C2046: illegal case
e:\ravi\c++\asdd\asdd\main.cpp(68) : error C2046: illegal case
e:\ravi\c++\asdd\asdd\main.cpp(73) : fatal error C1075: end of file found before the left brace ‘{‘ at ‘e:\ravi\c++\asdd\asdd\main.cpp(62)’ was matched
Build log was saved at “file://e:\Ravi\C++\asdd\asdd\Debug\BuildLog.htm”
asdd – 10 error(s), 0 warning(s)
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
i tried building the sample code that is available on this page and it worked fine, but when i compiled it following the procedure i got this error. feel i am missing something trivial.
thanks in advance.
gregd1024 said
Ravi — looks like there’s some copy/paste issues from the web page into Visual Studio. If you look at the errors, you’ll see stuff that doesn’t make sense, like “sswitch” (two “s” in the beginning – not good). I think DX9_TUTORIAL1_CLASS isn’t quoted correctly. ‘”DirectX’ <– only one beginning quote and no ending quote. Definitely there’s something different from what the web page reads and what was pasted. Do you have syntax highlighting turned on? If so, look for inconsistent string highlighting. I think this caused the first three errors. Fix those and I think most of the others will go away. But the double “s” in “sswitch” is just wrong – fix that one manually. Let me know how it goes.
-Greg Dolley
Dan said
When you copy and paste it pastes the “s as a different type of quote than C++ recognizes. They are slanted at an angle where as the ones c++ (atleast Visual c++) uses/recognizes are more vertical.
Hope this makes sense. Basically if you delete and retype the double quotes below you should be gtg.
example:
“DX9_TUTORIAL1_CLASS” should be “DX9_TUTORIAL1_CLASS”
Dan said
LOL ok, css on this page is reformating the double quotes so they both look the same in my ‘example’
gregd1024 said
Don’t worry, I know what you meant about the quotes. 😉
Ravi said
thanks for the quick response 🙂
turned out that when i copy pasted the code from code-box and built the solution there was some unicode text conversion error, so i couldnt see the errors in the program but they were there.
also 1 more error from another similar prg i tried running, if you dont mind:
#include // include the basic windows header file
// the entry point for any Windows program
int WINAPI WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nShowCmd)
{
// create a “Hello World” message box using MessageBox()
MessageBox(NULL,
L”Hello World!”,
L”Just another Hello World program!”,
MB_ICONEXCLAMATION | MB_OK);
// return 0 to Windows
return 0;
}
the error i get is :
fd.cpp
Linking…
MSVCRTD.lib(crtexe.obj) : error LNK2019: unresolved external symbol _main referenced in function ___tmainCRTStartup
E:\Ravi\C++\test2\Debug\test2.exe : fatal error LNK1120: 1 unresolved externals
Build log was saved at “file://e:\Ravi\C++\test2\test2\Debug\BuildLog.htm”
test2 – 2 error(s), 0 warning(s)
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
now i THINK it has got something to do with the winmain but cant seem to resolve it.
thank you very much again.
gregd1024 said
Ravi — your project type is wrong. It needs to be Win32. From the error, I think it’s set to a console app since the compiler is trying to find regular main() instead of WinMain(). I think changing the linker settings to output a Win32 executable is all that’s needed to fix this type of project. If that doesn’t do it, also set the program entry point to WinMain (this option should also be under the link settings).
-Greg Dolley
Daniel Scott said
Greg,
I too want to say thank you very much for the tutorials and for your patience helping people through some of their compiling and linking issues.
I am an engineer, but not from the CS side of things. I’ve programmed for years, but never professionally and not yet in Win32 and DirectX. I’m trying to learn DirectX for the first time to write a couple PC games for my kids. While waiting for my DirectX books to come I thought I would do a quick online tutorial and came across yours.
I’m trying to do your first tutorial (with the Visual Studio 2008 command prompt) and was wondering, if a person has but doesn’t like using the Visual C++ 9.0 Express Edition GUI, is there another way to complete the three preliminary steps of adding the $(DXSDK_DIR) include directory, the WIN32;_DEBUG;_WINDOWS preprocessor definitions, and the d3d9.lib library dependency? I can’t figure out a manual way to do what the Visual Studio Express Edition GUI is doing when the user sets those values in the project properties.
I’m using XP, Microsoft Visual C++ 9.0 Express Edition, and Microsoft DirectX 9.0c SDK (November 2008).
I would really really appreciate any light you can shed on the topic. I’ve been trying and trying all weekend to figure this out and can’t.
Sincerely,
Daniel Scott
gregd1024 said
Hi Daniel,
You can do everything from the command line if you want and use your own editor. In the project settings, under C/C++ Properties and Link Properties, there’s an item in the tree called Command Line. You can get the command line arguments for the compiler and linker from there. You’ll need to run the “Visual Studio 2008 Command Prompt” shortcut which is under your VS Express folder in the Start Menu. This is really a batch file which conveniently sets up the correct paths and environment variables in DOS so you can run the compiler and linker exe’s without worrying about what directory you’re in. The compiler exe is called “lcc.exe” and the linker is called “link.exe.”
Adding the $(DXSDK_DIR) include directory is really just setting up an environment variable in DOS. If you haven’t set environment variables in DOS, here’s how to do it: type “SET $(DXSDK_DIR)=” then add your path after the equals sign. Adding the preprocessor defs from the command line is a simple matter of feeding a “-D” command line argument to the compiler. For example, to set the preprocessor directive called “_WINDOWS” do this:
“lcc -D_WINDOWS ”
For a series of preprocessors, just do multiple “-D” options, like this: “lcc -D_WINDOWS -D_DEBUG -DWIN32 …”
Hope this helps.
-Greg
Darrick said
You did a great job of making a difficult subject easy to understand.
I’ve been spending days searching through tutorials, and this was the one that made things click for me.
Great job, Thankyou so much!
gregd1024 said
Darrick – that’s awesome. Glad it helped! 😉
Christian said
I have downloaded all the project & the directx sdk
when i go to compile it, it give me some errors
1>main.obj : error LNK2019: riferimento al simbolo esterno _Direct3DCreate9@4 non risolto nella funzione _WinMain@16
1>C:\Documents and Settings\dypster\Desktop\DirectX9_Tutorial1_AbsoluteBasics\Debug\DirectX9_Tutorial1_AbsoluteBasics.exe : fatal error LNK1120: 1 esterni non risolti
(IS ITALIAN SO TRANSLATE IT SORRY :S)
Please Help Me
tyler said
Hi Greg,
Excellent tutorial for someone starting out with graphics in C++ like me.
Please see below error log, any idea what I’ve done wrong, I’m using your source code downloaded, so not possible to be syntax or copy error.
1>—— Build started: Project: SimpleDirectX, Configuration: Debug Win32 ——
1>Compiling…
1>main.cpp
1>c:\users\pins\documents\visual studio 2008\projects\simpledirectx\simpledirectx\main.cpp(16) : error C2440: ‘initializing’ : cannot convert from ‘const char [20]’ to ‘LPCWSTR’
1> Types pointed to are unrelated; conversion requires reinterpret_cast, C-style cast
or function-style cast
1>c:\users\pins\documents\visual studio 2008\projects\simpledirectx\simpledirectx\main.cpp(21) : error C2664: ‘CreateWindowExW’ : cannot convert parameter 2 from ‘const char [20]’ to ‘LPCWSTR’
1> Types pointed to are unrelated; conversion requires reinterpret_cast, C-style cast
or function-style cast
1>Build log was saved at “file://c:\Users\Pins\Documents\Visual Studio 2008\Projects\SimpleDirectX\SimpleDirectX\Debug\BuildLog.htm”
1>SimpleDirectX – 2 error(s), 0 warning(s)
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
gregd1024 said
Tyler – looks like your project defaulted to using Unicode strings instead of ASCII. Try turning off unicode.
Synchronizer said
Dang it, I’m asleep again, because I can’t really be at a site that finally explains something useful about Direct X in a clear and simple process. I copied, disabled Unicode, compiled, and presto -> it worked!
Thanks Greg! =)
gregd1024 said
Synchronizer – thanks! 😉
bob said
🙂 Thanks, thats excatly what i needed to get my proj. started “_
Ibanezx123 said
Great tutorial! My program compiles fine and everything with no errors, Although there is no output. No blue square. Anyone have any ideas? Im usuing visual c++ 2008, and i just installed the latest direct x SDK
Mantoo said said
Hi, Greg, your article is very nice and helpful.
I’m a beginer to DirectX.
I get stopped, because of two error in compilling, these are as follows …
—— Build started: Project: mn2_test2, Configuration: Debug Win32 ——
Compiling…
test2.cpp
c:\documents and settings\man2\my documents\visual studio 2008\projects\mn2_test2\mn2_test2\test2.cpp(25) : error C2440: ‘initializing’ : cannot convert from ‘const char [20]’ to ‘LPCWSTR’
Types pointed to are unrelated; conversion requires reinterpret_cast, C-style cast or function-style cast
c:\documents and settings\man2\my documents\visual studio 2008\projects\mn2_test2\mn2_test2\test2.cpp(41) : error C2664: ‘CreateWindowExW’ : cannot convert parameter 2 from ‘const char [20]’ to ‘LPCWSTR’
Types pointed to are unrelated; conversion requires reinterpret_cast, C-style cast or function-style cast
Build log was saved at “file://c:\Documents and Settings\Man2\My Documents\Visual Studio 2008\Projects\mn2_test2\mn2_test2\Debug\BuildLog.htm”
mn2_test2 – 2 error(s), 0 warning(s)
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
I uses
1. Microsoft Visual Studio Express Edition 2008
2. Microsoft DirectX SDK nov 2007
Please, reply…
gregd1024 said
Mantoo – make sure you have these preprocessor directives set:
“WIN32;_DEBUG;_WINDOWS” (you find this under “Project->Properties…” then “Configuration Properties->C/C++->Preprocessor->Preprocessor Definitions”)
Notice how the compiler sees “CreateWindowExW” instead of “CreateWindowEx” (the function you really called)? This is because CreateWindowEx gets “#define’ed” into CreateWindowExW by one of the header files if a project setting is set to unicode or the “_UNICODE” preprocessor directive is declared.
If this doesn’t solve the problem, post another comment or send me an email through my contact page.
-Greg Dolley
Andalib said
ok, I came across the same problem as Mantoo faced. Only setting derivatives to: “WIN32;_DEBUG;_WINDOWS” doesnt solve the problem. from the preprocessor definitions, after clicking the “…” button on the right, a new box appears, where you have to uncheck the “inherit from parent of project default” check box. Then the text in the prprocessor definition will look like this: “WIN32;_DEBUG;_WINDOWS;$(NOINHERIT)” and then these build errors wont appear anymore.
This helped solving my problem and will solve yours, I am positive about it.
gregd1024 said
Andalib – ah, I was too late! 😉 Good job in figuring out the problem. Probably the implied “project default” settings had something which kept unicode turned on.
-Greg Dolley
chinmay said
sorry , but it gives this error . pls help
1>—— Build started: Project: cinmay, Configuration: Debug Win32 ——
1>Compiling…
1>main.cpp
1>c:\users\keyur\documents\visual studio 2008\projects\cinmay\main.cpp(15) : error C2440: ‘initializing’ : cannot convert from ‘const char [20]’ to ‘LPCWSTR’
1> Types pointed to are unrelated; conversion requires reinterpret_cast, C-style cast or function-style cast
1>c:\users\keyur\documents\visual studio 2008\projects\cinmay\main.cpp(19) : error C2664: ‘CreateWindowExW’ : cannot convert parameter 2 from ‘const char [20]’ to ‘LPCWSTR’
1> Types pointed to are unrelated; conversion requires reinterpret_cast, C-style cast or function-style cast
1>c:\users\keyur\documents\visual studio 2008\projects\cinmay\main.cpp(20) : error C2065: ‘g_pDirect3D’ : undeclared identifier
1>c:\users\keyur\documents\visual studio 2008\projects\cinmay\main.cpp(20) : error C2065: ‘D3D_SDK_VERSION’ : undeclared identifier
1>c:\users\keyur\documents\visual studio 2008\projects\cinmay\main.cpp(20) : error C3861: ‘Direct3DCreate9’: identifier not found
1>c:\users\keyur\documents\visual studio 2008\projects\cinmay\main.cpp(22) : error C2065: ‘D3DPRESENT_PARAMETERS’ : undeclared identifier
1>c:\users\keyur\documents\visual studio 2008\projects\cinmay\main.cpp(22) : error C2146: syntax error : missing ‘;’ before identifier ‘PresentParams’
1>c:\users\keyur\documents\visual studio 2008\projects\cinmay\main.cpp(22) : error C2065: ‘PresentParams’ : undeclared identifier
1>c:\users\keyur\documents\visual studio 2008\projects\cinmay\main.cpp(23) : error C2065: ‘PresentParams’ : undeclared identifier
1>c:\users\keyur\documents\visual studio 2008\projects\cinmay\main.cpp(23) : error C2065: ‘D3DPRESENT_PARAMETERS’ : undeclared identifier
1>c:\users\keyur\documents\visual studio 2008\projects\cinmay\main.cpp(23) : error C2070: ”unknown-type”: illegal sizeof operand
1>c:\users\keyur\documents\visual studio 2008\projects\cinmay\main.cpp(25) : error C2065: ‘PresentParams’ : undeclared identifier
1>c:\users\keyur\documents\visual studio 2008\projects\cinmay\main.cpp(25) : error C2228: left of ‘.Windowed’ must have class/struct/union
1> type is ”unknown-type”
1>c:\users\keyur\documents\visual studio 2008\projects\cinmay\main.cpp(26) : error C2065: ‘PresentParams’ : undeclared identifier
1>c:\users\keyur\documents\visual studio 2008\projects\cinmay\main.cpp(26) : error C2228: left of ‘.SwapEffect’ must have class/struct/union
1> type is ”unknown-type”
1>c:\users\keyur\documents\visual studio 2008\projects\cinmay\main.cpp(26) : error C2065: ‘D3DSWAPEFFECT_DISCARD’ : undeclared identifier
1>c:\users\keyur\documents\visual studio 2008\projects\cinmay\main.cpp(28) : error C2065: ‘g_pDirect3D’ : undeclared identifier
1>c:\users\keyur\documents\visual studio 2008\projects\cinmay\main.cpp(28) : error C2227: left of ‘->CreateDevice’ must point to class/struct/union/generic type
1> type is ”unknown-type”
1>c:\users\keyur\documents\visual studio 2008\projects\cinmay\main.cpp(28) : error C2065: ‘D3DADAPTER_DEFAULT’ : undeclared identifier
1>c:\users\keyur\documents\visual studio 2008\projects\cinmay\main.cpp(28) : error C2065: ‘D3DDEVTYPE_HAL’ : undeclared identifier
1>c:\users\keyur\documents\visual studio 2008\projects\cinmay\main.cpp(28) : error C2065: ‘D3DCREATE_SOFTWARE_VERTEXPROCESSING’ : undeclared identifier
1>c:\users\keyur\documents\visual studio 2008\projects\cinmay\main.cpp(28) : error C2065: ‘PresentParams’ : undeclared identifier
1>c:\users\keyur\documents\visual studio 2008\projects\cinmay\main.cpp(28) : error C2065: ‘g_pDirect3D_Device’ : undeclared identifier
1>c:\users\keyur\documents\visual studio 2008\projects\cinmay\main.cpp(38) : error C2065: ‘g_pDirect3D_Device’ : undeclared identifier
1>c:\users\keyur\documents\visual studio 2008\projects\cinmay\main.cpp(38) : error C2227: left of ‘->Release’ must point to class/struct/union/generic type
1> type is ”unknown-type”
1>c:\users\keyur\documents\visual studio 2008\projects\cinmay\main.cpp(39) : error C2065: ‘g_pDirect3D’ : undeclared identifier
1>c:\users\keyur\documents\visual studio 2008\projects\cinmay\main.cpp(39) : error C2227: left of ‘->Release’ must point to class/struct/union/generic type
1> type is ”unknown-type”
1>c:\users\keyur\documents\visual studio 2008\projects\cinmay\main.cpp(54) : error C2065: ‘g_pDirect3D_Device’ : undeclared identifier
1>c:\users\keyur\documents\visual studio 2008\projects\cinmay\main.cpp(54) : error C2227: left of ‘->Clear’ must point to class/struct/union/generic type
1> type is ”unknown-type”
1>c:\users\keyur\documents\visual studio 2008\projects\cinmay\main.cpp(54) : error C2065: ‘D3DCLEAR_TARGET’ : undeclared identifier
1>c:\users\keyur\documents\visual studio 2008\projects\cinmay\main.cpp(54) : error C3861: ‘D3DCOLOR_XRGB’: identifier not found
1>c:\users\keyur\documents\visual studio 2008\projects\cinmay\main.cpp(55) : error C2065: ‘g_pDirect3D_Device’ : undeclared identifier
1>c:\users\keyur\documents\visual studio 2008\projects\cinmay\main.cpp(55) : error C2227: left of ‘->Present’ must point to class/struct/union/generic type
1> type is ”unknown-type”
1>Project : warning PRJ0018 : The following environment variables were not found:
1>$(DXSDK_DIR)
1>Build log was saved at “file://c:\Users\keyur\Documents\Visual Studio 2008\Projects\cinmay\Debug\BuildLog.htm”
1>cinmay – 33 error(s), 0 warning(s)
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
so what should i do ?
gregd1024 said
Turn off unicode.
-Greg
Andalib said
I am absolute beginner at DirectX programming. I just copied the first block of the code and tried to build, and got the following error (I am using visual C++ express edition, DirectX SDK nov 2008):
error C2664: ‘CreateWindowExW’ : cannot convert parameter 2 from ‘const char [20]’ to ‘LPCWSTR’ d:\cppfiles\try1\try1\winmain.cpp (line:18)
I will greatly appreciate any help. I have been trying to learn DirectX programming, but so far havent been able to run a single program.
gregd1024 said
Andalib – You need to turn off unicode in your project. If that doesn’t work, send me an email through my Contact page.
-Greg
Sodrohu said
I tried to compile your program today. It almost worked. Well, when I built it there are no errors, but when I tried to run it, there is an error.
‘Unhandled exception at 0x00401021 in Dairek Eks.exe: 0xC0000005: Access violation reading location 0x00000000.’
I tried to use breakpoints to determine which part of the code is faulty, but I can’t find out where. The program immediately get the error even if I break at the first line at #include
I can’t point out what’s the problem here. BTW I’m using Visual Studio 2005, on an XP SP2 machine. I’m using the latest SDK (March 2009). Maybe because March 2009 doesn’t have the MDX 1.1 samples and docs, but they’re not used for compiling is it? Hold on, I’ll try to DL and use the August 07 version 1st…
gregd1024 said
Sodrohu – try putting a breakpoint on the first line of the main() function and see if it gets in there. If not, there’s a conflict in some dependency. Trying the August ’07 version is a good idea. Let us know how it goes.
-Greg
Heeskyr said
Thx.
First Time i found a Tutorial with all settings… and it works =D
SAMPREETH said
hey excellent tutorial……..just got started with a simulation company and this kind of stuff is exactly what i was looking for although i have gone a lot furthur but never had clarity about every damn thing……….great stuff, Thanks
gregd1024 said
Heeskyr and SAMPREETH – thanks guys for your kind words! 😉 Glad things worked well.
sandrar said
Hi! I was surfing and found your blog post… nice! I love your blog. 🙂 Cheers! Sandra. R.
gregd1024 said
Sandra – Thank you! 😉
David Lipman said
okay – i’m using vis.studio 2005 with DX9SDK installed. i created an empty project and cut and paste the code. but i can’t get it to compile right, when i try to compile my output window comes back with the following:
1>—— Build started: Project: sample02, Configuration: Debug Win32 ——
1>Compiling…
1>sample03.cpp
1>c:\program files\microsoft visual studio 8\vc\platformsdk\include\winnt.h(222) : error C2146: syntax error : missing ‘;’ before identifier ‘PVOID64’
1>c:\program files\microsoft visual studio 8\vc\platformsdk\include\winnt.h(222) : error C4430: missing type specifier – int assumed. Note: C++ does not support default-int
1>c:\program files\microsoft visual studio 8\vc\platformsdk\include\winnt.h(5940) : error C2146: syntax error : missing ‘;’ before identifier ‘Buffer’
1>c:\program files\microsoft visual studio 8\vc\platformsdk\include\winnt.h(5940) : error C4430: missing type specifier – int assumed. Note: C++ does not support default-int
1>c:\program files\microsoft visual studio 8\vc\platformsdk\include\winnt.h(5940) : error C4430: missing type specifier – int assumed. Note: C++ does not support default-int
1>Project : warning PRJ0018 : The following environment variables were not found:
1>$(DXSDK_DIR)
1>Build log was saved at “file://e:\code\docs\Game Development\DirectX9_Tutorial1_AbsoluteBasics\Sample01\sample02\sample02\Debug\BuildLog.htm”
1>sample02 – 5 error(s), 0 warning(s)
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
i don’t understand why it keeps calling back errors in this file ‘winnt.h’ – which isn’t even included in my project. anyway, any help for advice you can provide would be appreciated.
-david
David Lipman said
regarding my problem – turns out i was able to figure it out. apparently some older versions of the dxdsk have problem with definitions in the file ‘basetsd.h’. as per some recommedation i found online, i replaced the copy of ‘basetsd.h’ (in the dxsdk/include folder) with the copy contained in the visual studio folder (../program files/visual studio/..) and this allowed the code to compile and link smoothly. thanks for the code.
-david
gregd1024 said
David – ah, very nice. Thanks for the tip. 🙂
Adam said
i tried compiling the program but got this error.
MSVCRTD.lib(crtexe.obj) : error LNK2019: unresolved external symbol _main referenced in function ___tmainCRTStartup
1>C:\Users\Adam\Documents\Visual Studio 2008\Projects\Dx\Debug\Dx.exe : fatal error LNK1120: 1 unresolved externals
I cant figure out whats wrong.
Skyler said
First of all, thanks a lot for this awesome tutorial!
I have been having trouble. The code compiles just fine and a window is displayed, but when it is closed, it looks like the process is still there and when I go to compile again Visual Studio has trouble linking to the exe because it write protected (because it’s open). I stopped after I put in the minimal Windows Application source code.
I know it’s been a while since someone posted on this tutorial, but I thought I’d still check to see if I could get a response!
Luke said
Excellent tutorial for beginners looking to get started with DirectX! This is one of the best resources on the net.
gregd1024 said
Thank you, Luke, for your kind words! 😉 I really appreciate it. 🙂
-Greg Dolley
Otreum said
Hi Greg, nice tutorial you have here, I notice just about every other tutorial skips over the important steps…the main one being how to set up directX with Visual Studio.
But thanks aside, I got through the tutorial, figured out that the stuff in quotation marks wasn’t showing up red like it should, and noticed the quotation marks seemed to be in italics, so I changed that, and the program COMPILES ok….
HOWEVER, when I actually try to run it, the program crashes.
When I debug the program, I get to:
g_pDirect3D = Direct3DCreate9(D3D_SDK_VERSION);
Which skips the yellow arrow down to:
g_pDirect3D_Device->Release();
And shows an unhandled exception error saying:
Unhandled exception at 0x0122178a in compiler_setup.exe: 0xC0000005: Access violation reading location 0x00000000.
I figured it had something to do with the argument passed to Direct3Dcreate9, but i’m really not too sure whats going on.
Thanks in advance.
Otreum said
Ah, I got it solved, I deleted:
g_pDirect3D_Device->Release();
g_pDirect3D->Release();
I don’t think that is the be all to end all solution, I think maybe I need to edit those lines as opposed to deleting them, but right now it seems as though those lines are doing more harm than good, especially since the program now works.
Simon said
Hi Greg, another problem:)
I got these errors :
‘initializing’ : cannot convert from ‘const char [20]’ to ‘LPCWSTR’
Types pointed to are unrelated; conversion requires reinterpret_cast, C-style cast or function-style cast
‘CreateWindowExW’ : cannot convert parameter 2 from ‘const char [20]’ to ‘LPCWSTR’
Types pointed to are unrelated; conversion requires reinterpret_cast, C-style cast or function-style cast
and also after debuging prompts an error wich says: “unable to start program …/main.exe the system cannot find the path specified”
I did exactly as your article says, I have downloaded Directx SDK and I use Visual Studio 2008 Express.
Simon said
i turned off unicode and it worked
Jason said
Hello, when I tried to compile the code I received the errors:
1>c:\documents and settings\home\my documents\visual studio 2010\projects\win\win\win.cpp(26): error C2065: ‘“DX9_TUTORIAL1_CLASS”’ : undeclared identifier
1>c:\documents and settings\home\my documents\visual studio 2010\projects\win\win\win.cpp(35): error C2065: ‘“DX9_TUTORIAL1_CLASS”’ : undeclared identifier
1>c:\documents and settings\home\my documents\visual studio 2010\projects\win\win\win.cpp(35): error C2065: ‘“DirectX’ : undeclared identifier
1>c:\documents and settings\home\my documents\visual studio 2010\projects\win\win\win.cpp(35): error C2143: syntax error : missing ‘)’ before ‘constant’
1>c:\documents and settings\home\my documents\visual studio 2010\projects\win\win\win.cpp(35): error C2059: syntax error : ‘)’
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
I looked at one of the earlier posts which mentions the error “DX9_TUTORIAL1_CLASS”’ : undeclared identifier and the “directx” error but changing the code didn’t help. What’s wrong?
Jason said
OK i changed some code, got the errors: error C2664: ‘CreateWindowExW’ : cannot convert parameter 2 from ‘const char [20]‘ to ‘LPCWSTR’ d:\cppfiles\try1\try1\winmain.cpp (line:18),
turned off unicode and know the project compiles and then crashes on start up, with the error message “main.cpp has encountered an error and needs to close”
Help?
sharavsambuu said
Thank you very much! It works
Etni said
A blue window is born! :p
I like to get to the drawing and coding without having to first understand everything about the mechanics of windows, so this tutorial was very helpful. Much appreciated!
tutoriale cs said
pluginuri CS…
DirectX 9 C++ Graphics Tutorial 1: Getting Started « Greg Dolley’s Weblog…
YDLU said
source code link looklike broke!