Sign in to follow this  
Prot

How to pass DeviceContext to other classes?

Recommended Posts

Hi there,

 

I've been following this tutorial on how to render a texture with DirectX tool Kit. It's all clear.

In the example everything is created and executed inside the Game.cpp. I am still new to C++ so I was wondering, how would I transfer all the logic for rendering a sprite to a separate class. So I came Up with this:

#pragma once

#include "SpriteBatch.h"

class MyTexture
{
public:
	MyTexture();
	~MyTexture();

	void Create();
	void OnDeviceLost();
	void Render();
private:
	Microsoft::WRL::ComPtr<ID3D11ShaderResourceView> m_texture;
	Microsoft::WRL::ComPtr<ID3D11ShaderResourceView> m_texture;
	std::unique_ptr<DirectX::SpriteBatch> m_spriteBatch;
	DirectX::SimpleMath::Vector2 m_screenPos;
	DirectX::SimpleMath::Vector2 m_origin;
	UINT backBufferWidth;
	UINT backBufferHeight;
};
#include "pch.h"
#include "Grid.h"
#include "SpriteBatch.h"

using namespace DirectX;

using Microsoft::WRL::ComPtr;
using namespace DirectX::SimpleMath;

MyTexture::MyTexture()
{
	m_screenPos.x = backBufferWidth / 2.f;
	m_screenPos.y = backBufferHeight / 2.f;
}


MyTexture::~MyTexture()
{
}


void MyTexture::Create()
{
	m_spriteBatch.reset(new SpriteBatch(m_d3dContext.Get()));

	ComPtr<ID3D11Resource> resource;
	DX::ThrowIfFailed(
		CreateWICTextureFromFile(m_d3dDevice.Get(), L"cat.png", resource.GetAddressOf(),
		m_texture.ReleaseAndGetAddressOf()));

	ComPtr<ID3D11Texture2D> cat;
	DX::ThrowIfFailed(resource.As(&cat));

	CD3D11_TEXTURE2D_DESC catDesc;
	cat->GetDesc(&catDesc);

	m_origin.x = float(catDesc.Width / 2);
	m_origin.y = float(catDesc.Height / 2);
}

void MyTexture::OnDeviceLost()
{
	m_texture.Reset();
	m_spriteBatch.reset();
}

void MyTexture::Render()
{
	m_spriteBatch->Begin();

	m_spriteBatch->Draw(m_texture.Get(), m_screenPos, nullptr, Colors::White, 0.f, m_origin);

	m_spriteBatch->End();
}

But in this class I still need a reference to the m_d3dDevice and m_d3dContext. As i said I am pretty new to C++. So what would be the best way to do this? Something like passing a pointer or something? Maybe somebody can show me some example code.

 

Btw in Game.h the variables are declared like this:

    Microsoft::WRL::ComPtr<ID3D11Device>            m_d3dDevice;
    Microsoft::WRL::ComPtr<ID3D11DeviceContext>     m_d3dContext;
Edited by Prot

Share this post


Link to post
Share on other sites

Pass a pointer to the device in the Texture constructor and/or the "create" function (depending on your design). This makes the dependency on the device clear and explicit.

Edited by Josh Petrie

Share this post


Link to post
Share on other sites

Pass a pointer to the device in the Texture constructor and/or the "create" function (depending on your design). This makes the dependency on the device clear and explicit.

 

I know this is kind of lazy, but would you please show me how I would do this?

Share this post


Link to post
Share on other sites

I asked a very similar question here: https://directxtk.codeplex.com/discussions/611607

 

Basically when you create your device and deviceContext, these initialized objects "live" in the private member section of your game class as you wrote. Now you want to load a texture, and you see you need the device and/or deviceContext for that, so you need to have a place for them in your MyTexture class. You can either just create temporary objects of the device and device context in the constructor as Josh suggested, or store them in your MyTexture as private members.

Edited by SteveHatcher

Share this post


Link to post
Share on other sites

Usually there is an explicit relationship between the resource and its creator ( ID3D11Device ) and during its lifetime is very unlikely to change, and in case it might need to change ( creation / destruction ) is way better ( IMHO ) to directly create a new instance. Thus i would approach the problem this way :

class IResource
{
    IResource(GraphicsContext& graphics_context) : m_graphics_context { graphics_context } { }

protected:
    GraphicsContext& m_graphics_context;
};

obviously the GraphicsContext& contains Device, immediate context, feature levels and more ( it can also be a POD ). Since you directly manipulate resources w/ no handles inbetween copying resources is debatable smile.png.

 

I´m personally a big fan of references, but still you might go aswell with pointers. References disallow invalid ( null ) instances but at the same time they do have some ¨¨problems¨¨ ( if you wanna call them that way ) with copy constructors.

 

If you think the resource is going to be recreated different times by different devices, just ( as said already ) pass the graphics context or the device to the create() method. Since i´m sort of promoting references, pass the parameter as reference <3 and keep it as a pointer inside. ( we are using C++ afterall )

 

Happy coding smile.png

Edited by Sparkon

Share this post


Link to post
Share on other sites

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