How to set texture as shader resource?

Started by
3 comments, last by L. Spiro 10 years, 1 month ago

Hey guys,

In my application I want to set a texture as shader resource, so the pixel shader can sample it using the passed in uv coordinates. Generally, I know how to do it and I have it working in another place of my application. However, for one special case it just doesn't seem to work and I can't get rid of a compilation error.

I have a class Font with this function:


ID3D11ShaderResourceView* GetTexture();

And another class trying to access that function in order to get the texture and set it as a resource for the pixel shader:


pDeviceContext -> PSSetShaderResources(0, 1, m_font.GetTexture() );

(m_font is an object of the class Font, that has that GetTexture() function)

The compiler gives me this error:

argument of type "ID3D11ShaderResourceView *" is incompatible with parameter of type "ID3D11ShaderResourceView *const *"

I think I tried all combinations of constness for the return type of the GetTexture() function and nothing changed. Also, I'm building this pretty much based on a tutorial that has pretty much the same code, so I think it should be working. Especially as it is working somewhere else in my application (although I'm not getting the texture over a get-function there but pass in the address of a member texture).

So, please help me to solve this. Thank you very much in advance.

Advertisement

PSSetShaderResources takes a pointer to a pointer as it's parameter, whereas your GetTexture is just returning a pointer. That's what the compiler error is telling you - this is actually nothing to do with constness, and the presence of a "const" in the error message is throwing you off; remove or ignore the "const" (for the purposes of troubleshooting this) and you'll see that it's just a straight-up old-fashioned type mismatch between "ID3D11ShaderResourceView *" and "ID3D11ShaderResourceView **" (note the second '*').

Your solution is:


pDeviceContext->PSSetShaderResources (0, 1, &m_font.GetTexture ()); // note the '&'

Direct3D has need of instancing, but we do not. We have plenty of glVertexAttrib calls.

To elaborate a bit more, the reason it expects a pointer to a pointer is so that it can take an array of shader resource views. So that you can do something like this:

ID3D11ShaderResourceView* srvs[3] = { texture0, texture1, texture2 };
immContext->PSSetShaderResources(0, 3, srvs);

Thanks guys for replying, but I tried that before, I mean using


pDeviceContext -> PSSetShaderResources(0, 1, &m_font.GetTexture() );

In that case the compiler will simply tell me: '&' requires l-value

Doing the following doesn't change anything about it:


pDeviceContext -> PSSetShaderResources(0, 1, &(m_font.GetTexture()) );

When I do something like this, however, it works:


ID3D11ShaderResourceView* pTex = m_font.GetTexture();
pDeviceContext -> PSSetShaderResources(0, 1, &pTex );

What's going on? What's the problem with the getter? Any ideas?

That is exactly to be expected.

What do you think “&m_font.GetTexture()” is telling the compiler?

Maybe you hope it returns an address to the temporary where the result of m_font.GetTexture() might be stored, but who said it would ever be stored as a temporary?

Functions return results in the EAX register on x86 machines (as a specific example), so does &m_font.GetTexture() mean “address of a register”?

Does it mean “address of the GetTexture() method itself”?

In your 3rd case you are explicitly creating a temporary and then passing the address of that temporary. This is what you thought the first 2 cases would do, but the compiler is not required to make a temporary at all and it won’t allow you to rely on such behavior.

L. Spiro

I restore Nintendo 64 video-game OST’s into HD! https://www.youtube.com/channel/UCCtX_wedtZ5BoyQBXEhnVZw/playlists?view=1&sort=lad&flow=grid

This topic is closed to new replies.

Advertisement