After studying lots of DirectX tutorials I noticed a tendency to keep many pointers as globals, which is a quick and dirty way to get started but after a while I wondered how one could create these, say, in WinMain and pass a reference to them in functions, and allow the callee to modify/create them. I've sweated and struggled a whole afternoon but finally came up with a solution, after careful analysis of the ASM output
Say I have the following in winmain, rather than as globals:
LPDIRECT3D9 d3d=NULL; // pointer to interface
LPDIRECT3DDEVICE9 d3ddev=NULL; // pointer to device class
Then I would call an init() function, actually declared as VOID init(HWND hwnd, LPDIRECT3D9 *d3d, LPDIRECT3DDEVICE9 *d3ddev);
Inside the init I would then do the following:
*d3d = Direct3DCreate9(D3D_SDK_VERSION); // notice the asterisk here
fill in D3DPRESENT_PARAMETERS struct d3dpp
(*d3d)->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, d3ddev); // dereference it first
From now on you can use the device like so:
(*d3ddev)->CreateVertexBuffer(3*sizeof(CUSTOMVERTEX), 0, CUSTOMFVF, D3DPOOL_MANAGED, &v_buffer, NULL); //v_buffer is still a global with this example
As you can see not using globals adds lots of overhead and mind-bending pointer logic.
Every function you call needs to be passed the address of the pointer(s) to the object(s) you will use.
These functions need to be declared correctly with a ptr-to-ptr (LP prefixed variables are ALREADY pointers so only one asterisk!)
Not sure if this is helpful but it sure was a good pointer exercise for me :dazzled:
In assembler, you would typically pass a pointer to a global structure:
include \masm32\include\masm32rt.inc
.code
rc RECT <12, 34, 56, 78>
MyTest proc argRc:DWORD
mov eax, argRc
MsgBox 0, str$([eax.RECT.right]), "rc.right:", MB_OK
ret
MyTest endp
start:
invoke MyTest, offset rc
exit
end start