1/12/09

How to Use D3Dx and OpenGL together : Part 1

I love OGL but the OGL SDK is a shoddy collection of web links. Worse, although as size coders we have GLU, DX coders have a lot of advantages in the standard libraries they have access to. Fortunately, DirectX is quite well designed in the way libraries are broken down and from OGL its possible to use the d3dx support library without rendering using D3d. Its a little overhead of course compared to rendering everything in d3d, but in terms of bytes at 4k its almost nothing.

Inside d3dx are cool routines for getting normals to a mesh, smoothing meshes, raytracing (!) which can be used for collisions, splines for motion and camera paths, the elusive cube and torus, neither of which for some inexplicable reason appear in GLU, and a whole range of maths functions. In this little blog I'll show code to set up OGL and d3d together.


LPDIRECT3D9 pD3D;
LPDIRECT3DDEVICE9 pd3dDevice;

void initD3D(HWND hWnd)
{
D3DPRESENT_PARAMETERS d3dpp;

pD3D = Direct3DCreate9 (D3D_SDK_VERSION);
d3dpp.Windowed = TRUE;
d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
pD3D->CreateDevice( 0, D3DDEVTYPE_HAL, hWnd,
D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &pd3dDevice );
}

The code above sets up D3D. To be precise, it initialises D3D enough so that we can use functions from d3dx. To be more precise, DirectX 9 functions. It may be possible to get smaller but I'm a beginner with d3d, so send me an email if you can beat it. As both pD3D and pd3dDevice are required by d3dx routines, we make them global. It may be possible to use a static declaration for d3dpp to make this smaller byt a few bytes.

Now we need some code to initialise windows and opengl and use this routine to initialise D3D:


static PIXELFORMATDESCRIPTOR pfd={
0, // Size Of PFD... BAD coding, saves bytes
1, PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER, 32, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0
};

void WINAPI WinMainCRTStartup()
{
HWND hWnd = CreateWindow( "EDIT", NULL, WS_POPUP|WS_VISIBLE|WS_MAXIMIZE,
0, 0, 0, 0, 0, 0, 0, 0 );
initD3D(hWnd);
HDC hDC = GetDC( hWnd );
SetPixelFormat ( hDC, ChoosePixelFormat ( hDC, &pfd) , &pfd );
wglMakeCurrent ( hDC, wglCreateContext (hDC) );
ShowCursor(FALSE);
.
.
}

The code above is a little larger than normal because the d3d initialisation requires the window handle as well as the GetDC call, so we have to store it in hWnd variable.

In this blog then, I've presented a tiny framework that initialises win32, opens a window, initialises d3d and initialises opengl. In the next Blog, I'll describe how to use mesh functions in d3dx and render using OpenGL.