Jump to content

  • Log In with Google      Sign In   
  • Create Account

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   Members   

538
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.


#2   Moderators   

9747
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;
};

zlib: eJzVVLsSAiEQ6/1qCwoK i7PxA/2S2zMOZljYB1TO ZG7OhUtiduH9egZQCJH9 KcJyo4Wq9t0/RXkKmjx+ cgU4FIMWHhKCU+o/Nx2R LEPgQWLtnfcErbiEl0u4 0UrMghhZewgYcptoEF42 YMj+Z1kg+bVvqxhyo17h nUf+h4b2W4bR4XO01TJ7 qFNzA7jjbxyL71Avh6Tv odnFk4hnxxAf4w6496Kd OgH7/RxC

#3   Members   

538
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   Members   

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   Members   

538
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.