Thursday, November 17, 2011

Little COM smart pointer tip

Many people use CComPtr or Boost smart pointers to help with reference counting of COM/Direct3D objects, like vertex/index buffers, textures, etc. (see here for a good overview on the topic).

However CComPtr requires ATL and doesn't work with VS Express.

An alternative is to use _com_ptr_t which also is available in VS Express, with a little macro help you can wrap things up quite nicely:

#include "comip.h"

#define DECLARE_COM_REF(x) typedef \ 
_com_ptr_t< _com_IIID< IDirect3D##x##9, &IID_IDirect3D##x##9 > > \
x##Ref;

DECLARE_COM_REF(VertexBuffer);
DECLARE_COM_REF(IndexBuffer);
DECLARE_COM_REF(CubeTexture);
// etc.

With this you can then create some nice wrapper classes like this e.g.:

class VertexBuffer : public VertexBufferRef {
public:
    VertexBuffer(IDirect3DVertexBuffer9* vertex_buffer = NULL) { 
        Attach(vertex_buffer);
    }

    void* lock(UINT offset, UINT size, DWORD flags)
    {
        IDirect3DVertexBuffer9* p = GetInterfacePtr();
        assert(NULL != p);
        void* mem = 0;
        p->Lock(offset, size, &mem, flags);
        assert(NULL != mem);
        return mem;
    }

    void unlock()
    {
        GetInterfacePtr()->Unlock();
    }
};