-
Classes
Hi all.
I have been reading a book lately called Introduction to Game Programming with DirectX 9.0.
When i look at the code from there i don't see any classes or anything to lay out the program if you get my meaning.
But when i look at the posts people post on here i see that they have all of their functions inside classes and other things.
Can anyone give any hints on how to make my own class similar.
Tell me if i need to post my code.
-
I'd recommend getting information on basic object-oriented design. There's nothing special about games, except that in cases where there is a trade-off with speed, speed has somewhat greater weight than in other applications.
-
I can already create classes, i just don't quite know how to make a class with all of the DirectX info in if you get my meaning.
-
As I said, object-oriented design. Think about what you have to do now, then combine that with knowledge of how to design classes. (Not just creating. Designing.)
-
I have tried and tried but still no avail... Can someone please not help me?
-
First put the code in exactly as the book shows. Most of us, however, read that book long after we understood C++ and OO design (or at least thought we did). So for me I did not enter the code as is because I figured out a framework of classes while reading the book.
You don't have to have classes for the code to work, but it makes things so much easier when you work with objects instead of just functions sitting out in open space with no relation to each other whatsoever.
Showing you my framework won't help you because you may approach it differently than I. I recommend getting a book on object oriented design methods to help you.
-
Right. By the way Bubba, did you get my P.M?
-
the directx stuff will just be like how other functions go in the class as members ,,,
Code:
class Dx
{
public:
HRESULT InitDirectX();
};
HRESULT Dx::InitDirectX()
{
}
just because a book shows you without classes it dosent mean it wont allow it...
the book probably didnt do it in clasess's as that book wasnt about c++ so there for just did it in global functions etc..
-
Hi again.
I have a class called CRenderDevice. It's not completed yet. But i'm thinking that i may need this as a base class. So i thought i would post here to see what variables i might need.
Here is the code:
(Again, it's not completed)
Code:
class CRenderDevice
{
public:
HRESULT CInitDirectX(
HINSTANCE hInstance,
int width, int height,
bool windowed,
D3DDEVTYPE deviceType,
IDirect3DDevice9** device);
};
It's not much, but it's all i got.
Can someone help me please?
-
So, can no-one help me out or is it because you don't want to help me out?
-
Right i attempted it again and i think i got a bit further, but before i go any further.... i've got an error.
Code:
CInitDirectX.cpp(12) : error C2440: 'type cast' : cannot convert from 'overloaded-function' to 'WNDPROC'
None of the functions with this name in scope match the target type
I don't know how to fix this error... here is the code:
CRenderDevice.h
Code:
#include <d3dx9.h>
class CRenderDevice
{
public:
HRESULT CInitDirectX(
HINSTANCE hInstance,
int width, int height,
bool windowed,
D3DDEVTYPE deviceType,
IDirect3DDevice9** device);
LRESULT CALLBACK WndProc(
HWND hwnd,
UINT Msg,
WPARAM wParam,
LPARAM lParam);
template<class T>
void Release(T t)
{
if(t)
{
t->Release();
t = 0;
}
}
template<class T>
void Delete(T t)
{
if(t)
{
delete t;
t = 0;
}
}
protected:
int width;
int height;
int vp;
bool windowed;
D3DCAPS9 caps;
IDirect3D9* d3d9;
HRESULT hr;
HINSTANCE hInstance;
HWND hwnd;
UINT Msg;
D3DDEVTYPE deviceType;
IDirect3DDevice9** device;
};
CInitDirectX.cpp
Code:
#include "CRenderDevice.h"
HRESULT CRenderDevice::CInitDirectX(
HINSTANCE hInstance,
int width, int height,
bool windowed,
D3DDEVTYPE deviceType,
IDirect3DDevice9** device)
{
WNDCLASS wc;
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = (WNDPROC)WndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInstance;
wc.hIcon = LoadIcon(0, IDI_APPLICATION);
wc.hCursor = LoadCursor(0, IDC_ARROW);
wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
wc.lpszMenuName = 0;
wc.lpszClassName = "Direct3DApp";
if(!RegisterClass(&wc))
{
MessageBox(0, "RgisterClass() - FAILED!", "Error", 0);
return 0;
}
hwnd = CreateWindowEx(
0,
"Direct£DApp",
"Direct3DApp",
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,
CW_USEDEFAULT,
width,
height,
hwnd,
NULL,
hInstance,
NULL);
if(!hwnd)
{
MessageBox(0, "CreateWindowEx() - FAILED!", "Error", 0);
return 0;
}
ShowWindow(hwnd, SW_SHOW);
UpdateWindow(hwnd);
d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
if(!d3d9)
{
MessageBox(0, "Direct3DCreate9() - FAILED!", "Error", 0);
return 0;
}
d3d9->GetDeviceCaps(D3DADAPTER_DEFAULT, deviceType, &caps);
if(caps.DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT)
{
vp = D3DCREATE_HARDWARE_VERTEXPROCESSING;
}
else
{
vp = D3DCREATE_SOFTWARE_VERTEXPROCESSING;
}
D3DPRESENT_PARAMETERS d3dpp;
d3dpp.BackBufferWidth = width;
d3dpp.BackBufferHeight = height;
d3dpp.BackBufferFormat = D3DFMT_A8R8G8B8;
d3dpp.BackBufferCount = 1;
d3dpp.MultiSampleType = D3DMULTISAMPLE_NONE;
d3dpp.MultiSampleQuality = 0;
d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
d3dpp.hDeviceWindow = hwnd;
d3dpp.Windowed = windowed;
d3dpp.EnableAutoDepthStencil = true;
d3dpp.AutoDepthStencilFormat = D3DFMT_D24S8;
d3dpp.Flags = 0;
d3dpp.FullScreen_RefreshRateInHz = D3DPRESENT_RATE_DEFAULT;
d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;
hr = d3d9->CreateDevice(
D3DADAPTER_DEFAULT,
deviceType,
hwnd,
vp,
&d3dpp,
device);
if(FAILED(hr))
{
d3dpp.AutoDepthStencilFormat = D3DFMT_D16;
hr = d3d9->CreateDevice(
D3DADAPTER_DEFAULT,
deviceType,
hwnd,
vp,
&d3dpp,
device);
}
if(FAILED(hr))
{
d3d9->Release();
MessageBox(0, "CreateDevice() - FAILED!", "Error", 0);
return 0;
}
d3d9->Release();
return 1;
}
-
WNDPROC is a pointer to a normal function, but you're trying to pass a member function for it. These two are fundamentally different.
Working around this problem is a common and interesting problem. There are many approaches to it, and I'm sure searching the Windows board for the topic will yield something useful.
-
Thanks..... I've fixed it... all i needed to do is declare it static.
-
Yes, but then you can't access the instance from it anymore. If you need that, you need to be trickier. (User data is the simplest way of implementing it.)
-
Here is how I worked around it. Note that you can approach this other ways.
Code:
int WINAPI WinMain(HINSTANCE hInstance,
HINSTANCE prevInstance,
PSTR cmdLine,
int showCmd)
{
//Create window for app
if(!g_TerrainApp.InitD3D(hInstance,
WIDTH,
HEIGHT,
false,
D3DDEVTYPE_HAL,
"Terrain app",true))
{
::MessageBox(0, "InitD3D() - FAILED", 0, 0);
return 0;
}
g_TerrainApp.Setup();
g_TerrainApp.EnterMsgLoop();
//We are done so clean up the memory and COM objects
g_TerrainApp.Cleanup();
return 0;
}
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch( msg )
{
//case WM_PAINT: return(0);break;
case WM_DESTROY:
::PostQuitMessage(0);
return(0);
break;
case WM_KEYDOWN:
if( wParam == VK_ESCAPE )
{
g_TerrainApp.ShutDown();
::DestroyWindow(hwnd);
return(0);
break;
}
}
return ::DefWindowProc(hwnd, msg, wParam, lParam);
}
After this is executed it's all C++ objects from here on out. As you can see g_TerrainApp is the one and only global in the entire engine and while I dislike globals it seemed the easiest approach. CTerrainApp is derived from CD3DApp which is the main Direct3D application class. That base class sets up the sound (using CDXAudio), music system (CDXMusic), input (CDXInput,CMouse,CKeyboard, and CGameDevice). But there is a lot more going on like reading INI files for level data, reading in model/texture data, creating objects, etc, etc.
Once you get your basic framework down you should be able to derive from it's classes for just about all your projects. My base class framework is used in all of my projects.