Sign in to follow this  

C++ with DirectX...

This topic is 3729 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Wow, I just got a book on this subject called "Beginning Game Programming Second Edition" by Jonathan S. Harbour, and after covering the first few sections on Win32, it makes me want to cry. The Win32 API stuff is so freakin confusing. @_@ I just don't understand all the HINSTANCE stuff, etc. I'm just wondering, is XNA with C# a better choice than DirectX/c++? I know a bit of C++, and I was thinking of picking up C# eventually. I just want to get started with developing games. All these options that are available just confuse me and leave me undecided, so I really don't know which to pick. I don't care about portability, else I wouldn't be using DirectX.

Share this post


Link to post
Share on other sites
You can use the C++/unmanaged version of DirectX without the Win32 API. All the device needs is a HWND to a control to render to, you can use any GUI API for that(Win32,SDL,WxWidgets,etc..).

I would recommend switching to C# though. For DirectX you can use Managed DX(not updated anymore, but you can still use it), SlimDX( similar to MDX, created by people here on GD.Net) or XNA.

Share this post


Link to post
Share on other sites
stick with it, that was the book that finally made me understand what I was doing with DirectX. Really if you're just making games, the Windows stuff doesn't matter to much aslong as you have a window you'll be just fine.

How 'bout telling us the parts that are getting you confused?

Share this post


Link to post
Share on other sites
This is all the crap I don't understand. I really want to learn how all of this works, hence why I picked C++. I don't just want to make stuff, I want to know how it works, and why it works the way it does. But right now that seems quite a hard feat.

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd)
{
MSG msg;

MyRegisterClass(hInstance);

if(!InitInstance(hInstance, nCmdShow))
return false;

while(GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
}

Share this post


Link to post
Share on other sites
I'm no guru but I'll take a shot at explaining it the best I can.


// WinMain is the access point to any windows based application like Main is to // an dos/console based application. The arguments being passed into it are
// automatically supplide by the OS when the app starts up.
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd)
{
// this is just a message variable
MSG msg;

// you'll have to look at the code for this function but
// in it he's setting up all the variables for the desired
// window
MyRegisterClass(hInstance);

// once again you'll have to look at the code for this function
// but hes trying to create the window here and if that fails it
// exits winmain there by closeing the app.
if(!InitInstance(hInstance, nCmdShow))
return false;

// this is the loop of the app, I've never really paid much attention
// to this area of windows, as I really only make fullscreen games
// so the only message I care about is WM_QUIT, tho some
// use the message pump to handle input.

while(GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
}



Make a search on msdn.com too for more detailed info on various functions.

Share this post


Link to post
Share on other sites
The GetMessage gets messages from Windows like "window has been resized" "window needs to be redrawn" "program is being closed".
Which you pick up in your WndProc function, once they've been dispatched.
(ex WM_KEYDOWN means the user has pressed a button, all handled in the WndProc())

myRegisterClass you're likely filling in the parameters for creating the program window, such as what icon and mouse pointer you would like, the color etc..

As for InitInstance().. i have no idea..

Share this post


Link to post
Share on other sites
Whenever I encounter an area that I have trouble with I find that it helps to look at how several different sources try to explain it. Try reading some things at winprog and see if that helps any. If after reading several different sources you still don't get it, don't get discouraged, just back up a little bit. You may just be a little over your head. If thats the case work on things that you do understand for a bit and come back to it later. You don't need to burn yourself out trying to force something to click. You might need more experience with C++. I do not know how much you already know. You say you know a bit of C++. That might not be enough. I'd suggest having a good bit of practice with classes and pointers before starting to learn WinAPI. I hope this helps. And remember, don't stress yourself too much.

Share this post


Link to post
Share on other sites
Quote:
Original post by Exershio
This is all the crap I don't understand. I really want to learn how all of this works, hence why I picked C++. I don't just want to make stuff, I want to know how it works, and why it works the way it does. But right now that seems quite a hard feat.

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd)
{
MSG msg;

MyRegisterClass(hInstance);

if(!InitInstance(hInstance, nCmdShow))
return false;

while(GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
}

Well if you really want to know what all this stuff is doing get yourself a copy of Petzold's "Programming Windows" since he explains all this stuff to death!
Thing is once you do understand it you will just copy and paste this stuff in most of your DX apps since it doesn't change much if any!

Share this post


Link to post
Share on other sites
Quote:
Original post by Exershio
This is all the crap I don't understand. I really want to learn how all of this works, hence why I picked C++. I don't just want to make stuff, I want to know how it works, and why it works the way it does. But right now that seems quite a hard feat.

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd)
{
MSG msg;

MyRegisterClass(hInstance);

if(!InitInstance(hInstance, nCmdShow))
return false;

while(GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
}
In addition to what freeworld said:
A HINSTANCE is a handle to your EXE in memory, which is what the hInstance parameter is. Various Windows functions need this handle so they can communicate with your app. hPrevInstance is always NULL, and is a relic from 16-bit windows days. lpCmdLine is the command line - basically argv from a console app, but without the command line split into it's component parts. nShowCmd is the value you should pass to ShowWindow() after creating your window, it's the state the OS requests you put your window into when you create it. That lets you use the "Start application maximized" and "Start application minimized" options when you create a shortcut to a windows exe - Windows will set this parameter to SW_SHOWMAXIMIZED or whatever. You may find that some tutorials don't use this parameter, but they really should to be correct. It appears that your code does, which is good.

When you create a window, you need to register a "window class" with the OS. The window class is a struct (WNDCLASS or WNDCLASSEX) which contains a classname, the address of a message handler (WndProc), default icon to use for the window, default cursor to use for it, and a few other bits and bobs. You can think of a window class as a template for a window.

Once you've registered your window class - which is presumably what the MyRegisterClass function does - you need to actually create a window. The CreateWindow() or CreateWindowEx() functions do this. You pass them the name of the window class (The template), the name of the window, it's size, and a few other parameters. While in the CreateWindow() function, Windows will call your WndProc, so bear that in mind (I'll go onto the WndProc in a sec).

Once you have your window created, you need to tell Windows to send messages to your window, so you can respond to things like the user moving the window, the user clicking minimize, maximize and close, and so on. You do that with your message pump, which is this chunk of code:

while(GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}

GetGessage() says to the OS "Give me the next window message in the queue. If there's none there, wait for one to arrive". That causes your app to block there, and use up almost zero CPU, which is good for most apps, but not what you want for a DirectX game (I'll cover that in a sec). GetMessage() will return 0 when it picks up a WM_QUIT message, which is a request for your app to exit.
TranslateMessage() is a little complicated, but it handles key presses, so if you press "shift" and "i", you'll get "I". DispatchMessage() actually sends the message off to your WndProc() for processing. I'm not sure why it's done in this way, it just is [smile]

Your WndProc is called from DispatchMessage(), and is passed various messages. There minimum you want to handle is WM_DESTROY. That's an indication that Windows has destroyed your window (The default behaviour for clicking the "close window" button is to send a WM_DESTROY message to your window). Usually you want to set some global "quit now" variable, or call PostQuitMessage(), which will put a WM_QUIT message into the queue of messages to be picked up by GetMessage(), which will cause GetMessage() to return 0, which will break out of your main loop and exit WinMain().
Any messages that you don't handle (and even some you do) should get passed on to DefWindowProc(). That's the default handler for all messages - E.g. WM_CLOSE (The message sent when the user clicks the close button on your window) in DefWindowProc() just calls DestroyWindow(), which kills the window and sends a WM_DESTROY notification. There's hundreds of window messages, and you want make sure you handle them all properly, so you need to call DefWindowProc().

Finally, as I was saying earlier - GetMessage() is good for background apps and most windows, but not so good for an interactive game. Since GetMessage() blocks till you get a message sent, you need to either set up a timer to constantly send messages to your window, or keep moving the window to keep messages flowing and to keep your main loop going.
An alternative to GetMessage() is PeekMessage(). It works exactly the same, but returns immediately if there's no messages pending. That lets you do other processing, such as rendering your scene. My message loop in my engine looks like this:

void PApp::PumpWindowMessages()
{
MSG msg;
while(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
{
if(msg.message == WM_QUIT)
m_bShouldExit = true;
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}


Then I just call that function once every main loop, and then render. That makes sure all my window messages are processed, and then I can render a frame.


I appreciate all this is a bit overwhelming, I had the exact same issues when I started doing this stuff. It might be worthwhile making some very simple Win32 applications first, just so you get to grips with the window handling, then you can move onto the DirectX stuff when you're more comfortable.

Hope this helps,
Steve

Share this post


Link to post
Share on other sites

This topic is 3729 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this