OK, I will try to give as much info as I can to this problem. Hopefully people will be able to follow my logic (I'm not saying it's too complicated for you to understand, I'm saying that I don't always explain my self exactly as I should and that causes headaches for both parties...(or multiple parties seeing as there's one of me and about a million of you...) Anyway, on to the problem at hand:
What I'm basically doing is this:
(I'm going to start with the classes I think are more important such as the Device class.)
DemDeviceD3D9.h
class DemDeviceD3D9
{
private:
IDirect3D9* m_D3D9; // this is the "mother" of Direct3D
IDirect3DDevice9* m_Device9; // this is the actual device.
DemDisplayAdapter* m_displayAdapter; // the display adapter.
public:
DemDeviceD3D9(); // default constructor.
~DemDeviceD3D9(); // destructor.
// initialize the device.
bool init_device(); // this acquire Direct3D9 and makes sure all the files exist.
// get total adapter count.
unsigned int getAdaptorCount();
// check if the current format it supported.
bool isFormatSupported(DEM_IMAGE_FORMATS imFmt);
// get the device name.
char* getDeviceName() const;
// get the adapter description.
char* getAdapterDriver() const;
char* getDeviceDescription() const;
// return Direct3D9 interface.
IDirect3D9* getD3D9() const { return m_D3D9; }
// return the device.
IDirect3DDevice9* getDirect3DDevice9() const { return m_Device9; }
DisplayModes getDisplayModes() { return m_displayAdapter->getDisplayModes(); }
OK (now you are wondering about the display adapter class? that is coming. the device first.
DemDevinceD3D9.cpp
DemDeviceD3D9::DemDeviceD3D9()
{
this->m_D3D9 = NULL;
this->m_Device9 = NULL;
this->m_displayAdapter = new DemDisplayAdapter(*m_D3D9,*m_Device9);
}
/* D3DFORMAT DemDeviceD3D9::convertDIFTOD3DFMT(DEM_IMAGE_FORMATS form)
{
switch(form)
{
case DIF_UNKNOWN:
return D3DFMT_UNKNOWN;
break;
case DIF_A8R8G8B8:
return D3DFMT_A8R8G8B8;
break;
case DIF_X8R8G8B8:
return D3DFMT_X8B8G8R8;
break;
}
return D3DFMT_UNKNOWN;
}
DEM_IMAGE_FORMATS DemDeviceD3D9::convertD3DFMTToDIF(D3DFORMAT form)
{
// just these formats for now.
switch(form)
{
case D3DFMT_UNKNOWN:
return DIF_UNKNOWN; // unknown format;
break;
case D3DFMT_A8R8G8B8:
return DIF_A8R8G8B8; // return an unsigned format (32 bit).
break;
case D3DFMT_X8B8G8R8:
return DIF_X8R8G8B8; // 32-bit channels but not alpha.
break;
case D3DFMT_R5G6B5:
return DIF_R5G6B5;
break;
}
return D3DFMT_UNKNOWN;
}*/
DemDeviceD3D9::~DemDeviceD3D9()
{
if(m_Device9 != NULL)
{
m_Device9->Release();
m_Device9 = 0;
}
if(m_D3D9 != NULL)
{
m_D3D9->Release();
m_D3D9 = 0;
}
}
unsigned int DemDeviceD3D9::getAdaptorCount()
{
unsigned int count = 0;
if(m_D3D9)
{
count = m_D3D9->GetAdapterCount();
}
else
{
count = -1;
}
return count;
}
char* DemDeviceD3D9::getDeviceName() const
{
return m_displayAdapter->getDeviceName();
// return m_Adapter->DeviceName;
}
char* DemDeviceD3D9::getAdapterDriver() const
{
return "";
// return m_Adapter->Driver;
}
bool DemDeviceD3D9::init_device()
{
// create Direct3D9
m_D3D9 = Direct3DCreate9(D3D_SDK_VERSION);
if(m_D3D9 == NULL)
{
MessageBoxA(NULL,"Direct3D9 not initialized.....sorry",NULL,MB_OK);
return false;
}
else
{
return true;
}
return false;
}
OK, now for the display adapter.
DemDisplayAdapter.h
typedef std::vector<DemDisplayMode*> DisplayModes;
// class for handling a display adapter.
class DemDisplayAdapter
{
private:
IDirect3D9* m_direct3D9; // Direct3D 9
IDirect3DDevice9* m_D3DDev9;
D3DDISPLAYMODE m_displayMode; // this is the display mode used.
D3DADAPTER_IDENTIFIER9* m_Adapter; // the adapter.
DemDisplayMode* m_displayModes;
DEM_IMAGE_FORMATS convertD3DFMTToDIF(D3DFORMAT form);
D3DFORMAT convertDIFTOD3DFMT(DEM_IMAGE_FORMATS form);
public:
// constructor.
DemDisplayAdapter(IDirect3D9& d3d9,
IDirect3DDevice9& dev9);
~DemDisplayAdapter();
// check if the current format it supported.
bool isFormatSupported(DEM_IMAGE_FORMATS imFmt);
// get a list of all supported display modes.
DisplayModes getDisplayModes();
char* getDeviceName() const {
if(m_direct3D9 != NULL)
{
return m_Adapter->DeviceName;
}
else
{
return " ";
}
return " ";
}
};
the DemDisplayMode is just a helper class, it has nothing to do with Direct3D9.
DemDisplayAdapter.cpp
DemDisplayAdapter::DemDisplayAdapter(IDirect3D9& d3d9, IDirect3DDevice9& dev9)
{
m_direct3D9 = &d3d9;
m_D3DDev9 = &dev9;
if(m_direct3D9 != NULL)
{
m_direct3D9->GetAdapterDisplayMode(m_direct3D9->GetAdapterCount(),&m_displayMode);
}
}
DemDisplayAdapter::~DemDisplayAdapter()
{
if(m_D3DDev9 != NULL)
{
m_D3DDev9->Release();
m_D3DDev9 = 0;
}
if (m_direct3D9 != NULL)
{
m_direct3D9->Release();
m_direct3D9 = 0;
}
}
// get the list of display modes.
DisplayModes DemDisplayAdapter::getDisplayModes()
{
DisplayModes modes;
if(m_direct3D9 != NULL)
{
for(unsigned int i = 0; i < m_direct3D9->GetAdapterCount(); i++)
{
unsigned int mode = m_direct3D9->GetAdapterModeCount(i,D3DFMT_A8R8G8B8);
for(unsigned int x = 0; x < mode; x++)
{
m_direct3D9->EnumAdapterModes(i,D3DFMT_A8R8G8B8,x,&m_displayMode);
m_displayModes = new DemDisplayMode(m_displayMode.Width,m_displayMode.Height,m_displayMode.RefreshRate);
modes.push_back(m_displayModes);
}
}
return modes;
}
return modes;
}
now.....for the render window.......
DemRenderWindowD3D9.h
class DemRenderWindowD3D9 : public DemRenderWindow
{
private:
DemDeviceD3D9* m_demDevice;
public:
DemRenderWindowD3D9(DemString winName,
DemString winTitle,
DemUInt width,
DemUInt height,
bool fullScreen,
bool Stencil,
bool VSync,
DemUInt vSyncVal = 0,
DemUInt bits = 32,
DemUInt MultiSample = 0,
DWORD Quality = 0);
DemRenderWindowD3D9();
~DemRenderWindowD3D9();
bool createWindow(DemString winName, DemString winTitle, DemUInt winWidth, DemUInt winHeight,
bool fullscreen,
bool Stencil,
bool vSync,
ExtraParameters& params );
void _beginRender();
void _endRender();
void _setClearColor(float a, float r, float g, float b);
};
OK, I hope someone is seeing a pattern here, if not, don't worry I'll explain the problem I'm having and WHY I did things this way.
DemRenderWindowD3D9.cpp
DemRenderWindowD3D9::DemRenderWindowD3D9(DemString winName, DemString winTitle, DemUInt width, DemUInt height, bool fullScreen, bool Stencil, bool VSync, DemUInt vSyncVal /* = 0 */, DemUInt bits /* = 32 */, DemUInt MultiSample /* = 0 */, DWORD Quality /* = 0 */)
: DemRenderWindow(winName,winTitle,width,height,fullScreen,Stencil,VSync,vSyncVal,bits,MultiSample,Quality)
{
this->m_demDevice = new DemDeviceD3D9();
}
DemRenderWindowD3D9::DemRenderWindowD3D9()
: DemRenderWindow()
{
this->m_demDevice = new DemDeviceD3D9();
}
DemRenderWindowD3D9::~DemRenderWindowD3D9()
{
IDirect3D9* d = m_demDevice->getD3D9();
IDirect3DDevice9* dev = m_demDevice->getDirect3DDevice9();
if(dev != NULL)
{
dev->Release();
dev = 0;
}
if(d != NULL)
{
d->Release();
d = 0;
}
delete m_demDevice;
m_demDevice = 0;
}
bool DemRenderWindowD3D9::createWindow(DemString winName, DemString winTitle, DemUInt winWidth, DemUInt winHeight,
bool fullscreen,
bool Stencil,
bool vSync,
ExtraParameters& params )
{
this->createWindowImp(winName,winTitle,winWidth,winHeight,params);
if(m_demDevice->init_device())
{
IDirect3DDevice9* dev = m_demDevice->getDirect3DDevice9();
D3DPRESENT_PARAMETERS present_params;
ZeroMemory(&present_params,sizeof(present_params));
present_params.BackBufferCount = 3;
present_params.BackBufferFormat = D3DFMT_X8R8G8B8;
present_params.SwapEffect = D3DSWAPEFFECT_DISCARD;
present_params.BackBufferWidth = m_width;
present_params.BackBufferHeight = m_height;
present_params.Windowed = (!fullscreen);
present_params.hDeviceWindow = m_winHandle;
HRESULT hr = m_demDevice->getD3D9()->CreateDevice(0,
D3DDEVTYPE_HAL,
m_winHandle,
D3DCREATE_HARDWARE_VERTEXPROCESSING,
&present_params,
&dev);
if(FAILED(hr))
{
const char* error = DXGetErrorDescriptionA(hr);
char buffer[256];
sprintf(buffer,"%s",error);
MessageBoxA(NULL,buffer,NULL,MB_OK);
return false;
}
else
{
return true;
}
// dev->Release();
}
else
{
}
return false;
}
void DemRenderWindowD3D9::_beginRender()
{
if(m_demDevice->getDirect3DDevice9())
{
HRESULT hr = m_demDevice->getDirect3DDevice9()->BeginScene();
if(FAILED(hr))
{
const char* err = DXGetErrorDescriptionA(hr);
MessageBoxA(NULL,err,"",MB_OK);
}
}
}
void DemRenderWindowD3D9::_endRender()
{
if(m_demDevice->getDirect3DDevice9() )
{
m_demDevice->getDirect3DDevice9()->EndScene();
m_demDevice->getDirect3DDevice9()->Present(0,0,0,0);
}
}
void DemRenderWindowD3D9::_setClearColor(float a, float r, float g, float b)
{
if(m_demDevice->getDirect3DDevice9())
{
m_demDevice->getDirect3DDevice9()->Clear(0,0,D3DCLEAR_TARGET,D3DCOLOR_ARGB(255,0,0,255),1.0f,1);
}
}
OK, now, you see how in every destructer I'm releasing Direct3D9? but I'm still getting Direct3D memory leaks, especially at Alloc count = 113.
Now, as you'll see from the main function that I am releasing the data by deleting the classes that are releasing the Direct3D Interfaces.....(I can't get anything to render but that is probably because there is a problem in createWindowImp()....(I was trying for an Ogre3D approach with the extra parameters but that didn't quite work out....I'll fix that after I manage to get rid of these stupid memory leaks....) *sigh* I don't suppose anyone has a very, very,very good tutorial on IUnknown interfaces right? One that will guarantee the memory is ALWAYS released?) Ok, I've ranted enough. This has to be my longest post ever....and I'm off on a tangent....bye.