[SlimDX] DX11 - Load cube texture from dds-file

Started by
4 comments, last by Starnick 12 years, 8 months ago
Hi! Is there a way to load a cube-texture from a dds-file into SlimDX (at Direct3D11)? At the moment, I'm forced to use a self-modified SlimDX version that can create a ShaderResourceView using D3DX11CreateShaderResourceViewFromFile from the unmanaged API. But now I'm wondering if there's an "official" way to do this ( that I just haven't found ) or whether this functionality might be integrated into the next official release? Thanks! Fabian
Advertisement
ShaderResourceView.FromFile was added in a recent commit to the repository. The alternative is to load the texture separately and then create the resource view from that.

Cube textures in D3D10 and D3D11 are supported through the more generic "texture arrays". Loading your image as an array of 2D textures will allow you to achieve the same result.
Mike Popoloski | Journal | SlimDX
I am having the same problem. I can't figure out how would I go about loading a DDS file into a texture array. Could you elaborate a little bit more on this topic? Would you perhaps be willing to post a code snippet demonstrating how to load a texture cube from a DDS file and pass it on to the pixel shader? I have to say, the transition from DX9 is not a cakewalk...
Loading a DDS Cubemap from file using the API or loading it yourself? If from the API:



Device device;
String fileName;

...

ImageLoadInformation loadInfo = new ImageLoadInformation();
loadInfo.OptionFlags = ResourceOptionFlags.TextureCube;

Texture2D tex2D = Texture2D.FromFile(device, fileName);
ShaderResourceView srView = new ShaderResourceView(device, tex2D);


Notice, just like Mike said, Cube maps are really just texture2d arrays (so there's no special texture cube object), where the array has 6 textures representing each face. If you're loading the DDS file yourself, you can create an empty cube texture like so:


Texture2DDescription descTex = new Texture2DDescription();
descTex.ArraySize = 6;
descTex.Width = 512;
descTex.Height = 512;
descTex.Usage = ResourceUsage.Default;
descTex.CpuAccessFlags = CpuAccessFlags.None;
descTex.Format = Format.R8G8B8A8_UNorm;
descTex.SampleDescription = new SampleDescription(1, 0);
descTex.MipLevels = 1;
descTex.BindFlags = D3D.BindFlags.ShaderResource;
descTex.OptionFlags = D3D.ResourceOptionFlags.TextureCube;

Texture2D texture2D = new Texture2D(graphicsDevice, descTex);
ShaderResourceView shaderResourceView = new ShaderResourceView(graphicsDevice, texture2D);
Thanks!

I've managed to render my scene, but there's one thing I'm still trying to figure out - is there a way to bind the texture to the shader using the shader variable name? For now, I've just typed:

Device device;

String texturePath;


...

ImageLoadInformation loadInfo = new ImageLoadInformation();

loadInfo.OptionFlags = ResourceOptionFlags.TextureCube;

texture = Texture2D.FromFile(device, texturePath);

textureResourceView = new ShaderResourceView(device, texture);

device.ImmediateContext.PixelShader.SetShaderResource(textureResourceView, 0);



I've found someone else's solution here: [slimDX] textures on the simpletriangle but the code seems kind of messy with the shaders being compiled twice...
You pretty much have two options:

1. Use the effects framework (write FX files and not individual vertex/pixel HLSL fragments). Then, you can query an EffectResourceVariable from the Effect by index, by name or by semantic, so if you have "DiffuseMap" as your texture resource name, then myEffect.GetVariableByName("DiffuseMap") would return an EffectVariable. Then you'd call AsResource() to cast it into an EffectResourceVariable, which has a SetResource(ShaderResourceView) method. I'd strongly advise reviewing the official SlimDX docs as you they would help in following/understanding this progression.

Note: The effects framework is built ontop of all the regular shader API, you can choose not to use it and set your shaders and their variables manually (or create a replacement of the effects framework even), just like what you're doing.

2. Use shader reflection classes from the SlimDX.D3DCompiler namespace. You can create a ShaderReflection object by using your shader's byte code, which allows you to query info about your shader. What you're looking for is the shaderReflection.GetResourceBindingDescription(int) method. Loop over each resource (the shader reflection description will have a resource count), and the resource binding description will have a name you can use.

The shader reflection API is pretty powerful, albeit in my opinion a bit cumbersome to navigate if you haven't touched it before. But it can be a useful tool as you can query all sorts of things about your variables and shaders. Although I use the effects framework, I do use shader reflection to build an input layout when I load my shaders, for an example.

Edit: I should also mention, with option #2 you still will be setting the shader resource views via an index in the *ShaderWrapper classes. But you can use what you find out from the shader reflection queries in a custom setup where you associate those indices with resource names. This is why using the effects framework is easier, as it does this sort of book keeping for you automatically.

This topic is closed to new replies.

Advertisement