Jump to content

  • Log In with Google      Sign In   
  • Create Account

FREE SOFTWARE GIVEAWAY

We have 4 x Pro Licences (valued at $59 each) for 2d modular animation software Spriter to give away in this Thursday's GDNet Direct email newsletter.


Read more in this forum topic or make sure you're signed up (from the right-hand sidebar on the homepage) and read Thursday's newsletter to get in the running!


Trouble resolving dependency properly


Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

  • You cannot reply to this topic
4 replies to this topic

#1 Ripiz   Members   -  Reputation: 529

Like
0Likes
Like

Posted 03 October 2012 - 09:12 AM

Hello,

firstly little background. I've seen a lot posts "Write games on engines" and I don't need this type of stuff here. I'm just trying to separate engine and game early on instead of having a lot of hardcoded things later on. This is where I encountered a problem. I'm trying to wrap DirectX into a bit more friendly classes, but they need DirectX Device and I can't think of a decent way of passing device to these objects. Roughly my code looks like this:

class VertexShader {
	ID3D11VertexShader *shdr;
  
	void Create(void *bytecode, uint32 size); // requires ID3D11Device or DXWrapper;
};

class DXWrapper {
	ID3D11Device *dvc;
	ID3D11DeviceContext *dvcc;
};

class Engine {
	DXWrapper DXW;
};

// this is how I use VertexShader class:
class SkinnedRenderer {
	VertexShader vrtShader;
  
	SkinnedRenderer() {
		auto bytecode = ResourceManager.Get("skinned_vs.cso");
		vrtShader.Create(bytecode.data(), bytecode.size());
	}
};

I managed to think of 2 possible solutions (workarounds?) but I'm not satisfied with either of them.
  • Pass D3D Device as argument in VertexShader::Create() call, but I feel it's a bit messy doing it all the time.
  • Make Engine or DXWrapper class's instance static/global, allowing global access, but I'm trying to avoid such dependency, as code re-useability decreases.

Anyone have any ideas how can I resolve this issue, or solution #1 is the right way?

Thank you in advance.

Edited by Ripiz, 03 October 2012 - 09:14 AM.


Sponsor:

#2 fastcall22   Crossbones+   -  Reputation: 4473

Like
1Likes
Like

Posted 03 October 2012 - 09:25 AM

I'm not a graphics programmer (yet), but aren't vertex buffers dependent on the device you create them from? If this is the case, then #1 makes sense assuming you mean DXWrapper& and not ID3D11Device*. However, if this isn't an option, why not pass an intermediate class, which hides the device being used to create the vertex buffers from the interface? Something like the following:

class VertexBufferContext {
public:
    VertexBuffer create( ... );

private:
    DXWrapper& context;
};

c3RhdGljIGNoYXIgeW91cl9tb21bMVVMTCA8PCA2NF07CnNwcmludGYoeW91cl9tb20sICJpcyBmYXQiKTs=

#3 Ripiz   Members   -  Reputation: 529

Like
0Likes
Like

Posted 03 October 2012 - 10:13 AM

It's VertexShader, not VertexBuffer, but doesn't matter, wrappers look almost identical.
Yes, it does depend on device.

I would still have to initialize VertexBufferContext somewhere, most likely on the DXWrapper, such class method probably would be better on DXWrapper itself, rather than dummy class with single method. However, assignment operator displeases me:

class DXWrapper {
public:
    VertexShader CreateVertexShader(...);
};

class SkinnedRenderer {
    VertexShader vrtShader;
   
    SkinnedRenderer(DXWrapper &DXW) {
	    auto bytecode = ResourceManager.Get("skinned_vs.cso");
	   
	    // this assigment feels little bit fishy and a bit wrong
	    vrtShader = DXW.CreateVertexShader(bytecode.data(), bytecode.size());
    }
};

And before someone suggests using pointer: this class also has purpose of destroying resources on it's own destruction, solves issue of missing Release() calls and some redundant typing.

#4 greenvertex   Members   -  Reputation: 510

Like
2Likes
Like

Posted 03 October 2012 - 11:17 AM

I recently came across this design problem myself and found that creating a factory responsible for the creation of game assets (shaders, textures, etc.) was a good way to go. The factory ends up maintaining the ID3D11Device creation/destruction, and you can add methods for whatever resources you need with whatever arguments you need. It's no different than the original interface for ID3D11Device really, but it ends up doing away with some creation options you don't think you'll need.

class ResourceManager {
public:
  Mesh* createMesh(const char* file);
  Texture* createTexture(const char* file);
  VShader* createVertexShader(const char* file);
  PShader* createPixelShader(const char* file);
private:
  ID3D11Device* m_device;
  ID3D11DeviceContext* m_context;
};


#5 Ripiz   Members   -  Reputation: 529

Like
0Likes
Like

Posted 04 October 2012 - 06:35 AM

Thank you both for reply. It seems some kind of factory might be the a good choice in this case.




Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.



PARTNERS