Sign in to follow this  

creating wrapping class in c++

This topic is 4199 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi, i've recently been reading a book, Introduction to 3D Game Programming with DirectX 9 0. i've read the first 8 chapters, Drawing, colour, lighting, texturing, blending and stenciling. i have written 6 different applications utilising these 8 techniques, and i decided to write a wrapper class that i could use to utilize these. however i cant find any information on the forum about writting a wrapper class, could anyone point me to any information about programming wrapper classes, i did find some on the forum but had dead links :( thanks for any advice.

Share this post


Link to post
Share on other sites
Just create a class, for example "CDirect3D", and make your own functions. The class could hold the D3D device, etc. And you could make functions like:

CreateDevice(HWND hDeviceWnd, bool Hardware, bool ZBuffer)

and other functions that make it easier to call D3D functions. And to access the device outside the class, create a method inside called something like:

'LPDIRECT3DDEVICE9 GetDevice()'

Which simply returns the class's 'm_pDevice' object.

That's what I'm doing for my engine's 'cGraphics' class. It just wraps basic graphics functions. And I'm going to add a camera class, and a mesh class. And I already have the texture class, which is another wrapper, but for D3D textures. I did this:

(inside 'cTexture')
Member Function: 'bool LoadTexture(LPDIRECT3DDEVICE9 device, std::string file)'
-- Just loads a texture on the specified D3D device

Then:

void cTexture::EnableTexture(int stageNumber)
{
LPDIRECT3DDEVICE9 device = m_d3dTexture->GetDevice();
if (device == NULL)
return; // Device is 'NULL' do not continue

device->SetTexture(stageNumber, &m_d3dTexture);
m_stageNum = stageNum; // So we can disable this texture in 'Disable'
}

void cTexture::Disable()
{
LPDIRECT3DDEVICE9 device = m_d3dTexture->GetDevice();
if (device == NULL)
return; // Device is 'NULL' do not continue

device->SetTexture(m_stageNum, NULL);
}

That's all I did. Just make member functions that you can call, so that it shortens the actual application code.

That's the best I can explain it. =P

Share this post


Link to post
Share on other sites
Quote:
Original post by TFS_Waldo

void cTexture::EnableTexture(int stageNumber)
{
LPDIRECT3DDEVICE9 device = m_d3dTexture->GetDevice();
if (device == NULL)
return; // Device is 'NULL' do not continue

device->SetTexture(stageNumber, &m_d3dTexture);
m_stageNum = stageNum; // So we can disable this texture in 'Disable'
}

void cTexture::Disable()
{
LPDIRECT3DDEVICE9 device = m_d3dTexture->GetDevice();
if (device == NULL)
return; // Device is 'NULL' do not continue

device->SetTexture(m_stageNum, NULL);
}




You have to be more careful than that with your EnableTexture function:

tx.EnableTexture(0); // It's just an example, I don't care whether 0 and 1 are valid parameters.
tx.EnableTexture(1);
tx.Disable(); // Only disabled stage 1!



Anyway, the fundamental question to ponder is why do you want to write wrappers, and what are they supposed to do. That is what will guide your design.

Share this post


Link to post
Share on other sites
Eew. Eew. Eeeew!

Do not create a class called CDirect3D. First, the C prefix is useless, so it's just bad naming. Second, how does a Direct3D class abstract the IDirect3D interface that already exists? Unless your class adds value by building abstractions, don't do it.

Create a Renderer class instead. Create a SceneManager class and a InputSystem class. Create classes that do something worthwhile in the context of your application. The truth is that figuring that out is the hardest part of software design, and it's an ability acquired with experience - you have to fail at it first to succeed at it later.

Also, Microsoft's ATL already provides certain COM resource management abstractions, like the CComPtr template that performs automatic reference counting (good bye, SAFE_RELEASE!)

Share this post


Link to post
Share on other sites
Well, having a 'c/C' before class names, and 's' before struct's, helps me know what's what. And it doesn't really matter. No one is going to see my code but me. =P That sounds kind of smart ass-like. But that wasn't intended -- I promise. =P

Share this post


Link to post
Share on other sites
i am only trying to write a wrapper class for experience and trying to make my main code smaller, no other reasons and i haven't learnt anything about input or anything else, the wrapper class was supposed to make using directx easier for me to use and i planned to add to it as i read more of the way through the book im reading, anyway thanks for your responses.

Share this post


Link to post
Share on other sites
Quote:
But what could I do to fix that?


Depends on how yo uwant your texture to behave. On whether you want to support the texture being enabled in multiple stages (you need to keep track of them all), or not (enabling a texture in a stage disables it in any other stage). The decision is yours. But if you're going to encapsulate a critical piece of information (the stage) rather than make the user of the code need to specify it each time, you need to make sure nothing wrong can happen.

I also suspect you're going to have troubles with copy-construction and destruction: when the texture object is destroyed, the texture gets disabled, right?

Have you considered using RAII?

class TextureBinder;

class ScopedRenderer
{
IDirect3DDevice9* device;
public:
ScopedTextureBinder BindTexture(int stage, IDirect3DBaseTexture9* tex);
};

class ScopedTextureBinder
{
private:
IDirect3DDevice9* device;
IDirect3DBaseTexture9* old_texture;
IDirect3DBaseTexture9* new_texture;
int stage;

private:
friend class Renderer;

ScopedTextureBinder(IDirect3DDevice9* device, int stage, IDirect3DBaseTexture9* tex) :
device(device), stage(stage), new_texture(tex)
{
device->GetTexture(stage, &old_texture);
device->SetTexture(stage, new_texture);
}

public:
~ScopedTextureBinder()
{
device->SetTexture(stage, old_texture);
if (old_texture) old_texture->Release();
}

private:
// Disable copying
ScopedTextureBinder(const ScopedTextureBinder&);
ScopedTextureBinder& operator=(const ScopedTextureBinder&);
};

ScopedTextureBinder Renderer::BindTexture(int stage, IDirect3DBaseTexture9* tex)
{
return ScopedTextureBinder(device, stage, tex);
}

#define BIND_TEXTURE(RENDERER, STAGE, TEXTURE) \
ScopedTextureBinder& SCOPEDTEXTUREBINDER_##__LINE__ = \
RENDERER.BindTexture(STAGE, TEXTURE)




Now you can do BIND_TEXTURE(renderer, 5, some_texture); and the texture will automatically be unbound when you leave the current scope, restoring whichever texture was bound before. There probably still is much wrong with that code, but it does provide some actual functionality.




Go back and ponder what benefits, if any, your wrapper provides you. As Oluseyi rightfully points out, such wrappers are not always useful.

Quote:
Well, having a 'c/C' before class names, and 's' before struct's, helps me know what's what.


A struct is a class.

Share this post


Link to post
Share on other sites
Well, I don't plan on using a texture at multiple stages. What I have will work for me. =P And I know a 'struct' is a class, but I put 's' before a struct. name, and 'c' before a class name, though I don't use struct's as much.

Share this post


Link to post
Share on other sites

This topic is 4199 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this